github.com/google/go-github/v57@v57.0.0/github/apps.go (about)

     1  // Copyright 2016 The go-github AUTHORS. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package github
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  )
    12  
    13  // AppsService provides access to the installation related functions
    14  // in the GitHub API.
    15  //
    16  // GitHub API docs: https://docs.github.com/rest/apps/
    17  type AppsService service
    18  
    19  // App represents a GitHub App.
    20  type App struct {
    21  	ID                 *int64                   `json:"id,omitempty"`
    22  	Slug               *string                  `json:"slug,omitempty"`
    23  	NodeID             *string                  `json:"node_id,omitempty"`
    24  	Owner              *User                    `json:"owner,omitempty"`
    25  	Name               *string                  `json:"name,omitempty"`
    26  	Description        *string                  `json:"description,omitempty"`
    27  	ExternalURL        *string                  `json:"external_url,omitempty"`
    28  	HTMLURL            *string                  `json:"html_url,omitempty"`
    29  	CreatedAt          *Timestamp               `json:"created_at,omitempty"`
    30  	UpdatedAt          *Timestamp               `json:"updated_at,omitempty"`
    31  	Permissions        *InstallationPermissions `json:"permissions,omitempty"`
    32  	Events             []string                 `json:"events,omitempty"`
    33  	InstallationsCount *int                     `json:"installations_count,omitempty"`
    34  }
    35  
    36  // InstallationToken represents an installation token.
    37  type InstallationToken struct {
    38  	Token        *string                  `json:"token,omitempty"`
    39  	ExpiresAt    *Timestamp               `json:"expires_at,omitempty"`
    40  	Permissions  *InstallationPermissions `json:"permissions,omitempty"`
    41  	Repositories []*Repository            `json:"repositories,omitempty"`
    42  }
    43  
    44  // InstallationTokenOptions allow restricting a token's access to specific repositories.
    45  type InstallationTokenOptions struct {
    46  	// The IDs of the repositories that the installation token can access.
    47  	// Providing repository IDs restricts the access of an installation token to specific repositories.
    48  	RepositoryIDs []int64 `json:"repository_ids,omitempty"`
    49  
    50  	// The names of the repositories that the installation token can access.
    51  	// Providing repository names restricts the access of an installation token to specific repositories.
    52  	Repositories []string `json:"repositories,omitempty"`
    53  
    54  	// The permissions granted to the access token.
    55  	// The permissions object includes the permission names and their access type.
    56  	Permissions *InstallationPermissions `json:"permissions,omitempty"`
    57  }
    58  
    59  // InstallationPermissions lists the repository and organization permissions for an installation.
    60  //
    61  // Permission names taken from:
    62  //
    63  //	https://docs.github.com/enterprise-server@3.0/rest/apps#create-an-installation-access-token-for-an-app
    64  //	https://docs.github.com/rest/apps#create-an-installation-access-token-for-an-app
    65  type InstallationPermissions struct {
    66  	Actions                       *string `json:"actions,omitempty"`
    67  	Administration                *string `json:"administration,omitempty"`
    68  	Blocking                      *string `json:"blocking,omitempty"`
    69  	Checks                        *string `json:"checks,omitempty"`
    70  	Contents                      *string `json:"contents,omitempty"`
    71  	ContentReferences             *string `json:"content_references,omitempty"`
    72  	Deployments                   *string `json:"deployments,omitempty"`
    73  	Emails                        *string `json:"emails,omitempty"`
    74  	Environments                  *string `json:"environments,omitempty"`
    75  	Followers                     *string `json:"followers,omitempty"`
    76  	Issues                        *string `json:"issues,omitempty"`
    77  	Metadata                      *string `json:"metadata,omitempty"`
    78  	Members                       *string `json:"members,omitempty"`
    79  	OrganizationAdministration    *string `json:"organization_administration,omitempty"`
    80  	OrganizationCustomRoles       *string `json:"organization_custom_roles,omitempty"`
    81  	OrganizationHooks             *string `json:"organization_hooks,omitempty"`
    82  	OrganizationPackages          *string `json:"organization_packages,omitempty"`
    83  	OrganizationPlan              *string `json:"organization_plan,omitempty"`
    84  	OrganizationPreReceiveHooks   *string `json:"organization_pre_receive_hooks,omitempty"`
    85  	OrganizationProjects          *string `json:"organization_projects,omitempty"`
    86  	OrganizationSecrets           *string `json:"organization_secrets,omitempty"`
    87  	OrganizationSelfHostedRunners *string `json:"organization_self_hosted_runners,omitempty"`
    88  	OrganizationUserBlocking      *string `json:"organization_user_blocking,omitempty"`
    89  	Packages                      *string `json:"packages,omitempty"`
    90  	Pages                         *string `json:"pages,omitempty"`
    91  	PullRequests                  *string `json:"pull_requests,omitempty"`
    92  	RepositoryHooks               *string `json:"repository_hooks,omitempty"`
    93  	RepositoryProjects            *string `json:"repository_projects,omitempty"`
    94  	RepositoryPreReceiveHooks     *string `json:"repository_pre_receive_hooks,omitempty"`
    95  	Secrets                       *string `json:"secrets,omitempty"`
    96  	SecretScanningAlerts          *string `json:"secret_scanning_alerts,omitempty"`
    97  	SecurityEvents                *string `json:"security_events,omitempty"`
    98  	SingleFile                    *string `json:"single_file,omitempty"`
    99  	Statuses                      *string `json:"statuses,omitempty"`
   100  	TeamDiscussions               *string `json:"team_discussions,omitempty"`
   101  	VulnerabilityAlerts           *string `json:"vulnerability_alerts,omitempty"`
   102  	Workflows                     *string `json:"workflows,omitempty"`
   103  }
   104  
   105  // InstallationRequest represents a pending GitHub App installation request.
   106  type InstallationRequest struct {
   107  	ID        *int64     `json:"id,omitempty"`
   108  	NodeID    *string    `json:"node_id,omitempty"`
   109  	Account   *User      `json:"account,omitempty"`
   110  	Requester *User      `json:"requester,omitempty"`
   111  	CreatedAt *Timestamp `json:"created_at,omitempty"`
   112  }
   113  
   114  // Installation represents a GitHub Apps installation.
   115  type Installation struct {
   116  	ID                     *int64                   `json:"id,omitempty"`
   117  	NodeID                 *string                  `json:"node_id,omitempty"`
   118  	AppID                  *int64                   `json:"app_id,omitempty"`
   119  	AppSlug                *string                  `json:"app_slug,omitempty"`
   120  	TargetID               *int64                   `json:"target_id,omitempty"`
   121  	Account                *User                    `json:"account,omitempty"`
   122  	AccessTokensURL        *string                  `json:"access_tokens_url,omitempty"`
   123  	RepositoriesURL        *string                  `json:"repositories_url,omitempty"`
   124  	HTMLURL                *string                  `json:"html_url,omitempty"`
   125  	TargetType             *string                  `json:"target_type,omitempty"`
   126  	SingleFileName         *string                  `json:"single_file_name,omitempty"`
   127  	RepositorySelection    *string                  `json:"repository_selection,omitempty"`
   128  	Events                 []string                 `json:"events,omitempty"`
   129  	SingleFilePaths        []string                 `json:"single_file_paths,omitempty"`
   130  	Permissions            *InstallationPermissions `json:"permissions,omitempty"`
   131  	CreatedAt              *Timestamp               `json:"created_at,omitempty"`
   132  	UpdatedAt              *Timestamp               `json:"updated_at,omitempty"`
   133  	HasMultipleSingleFiles *bool                    `json:"has_multiple_single_files,omitempty"`
   134  	SuspendedBy            *User                    `json:"suspended_by,omitempty"`
   135  	SuspendedAt            *Timestamp               `json:"suspended_at,omitempty"`
   136  }
   137  
   138  // Attachment represents a GitHub Apps attachment.
   139  type Attachment struct {
   140  	ID    *int64  `json:"id,omitempty"`
   141  	Title *string `json:"title,omitempty"`
   142  	Body  *string `json:"body,omitempty"`
   143  }
   144  
   145  // ContentReference represents a reference to a URL in an issue or pull request.
   146  type ContentReference struct {
   147  	ID        *int64  `json:"id,omitempty"`
   148  	NodeID    *string `json:"node_id,omitempty"`
   149  	Reference *string `json:"reference,omitempty"`
   150  }
   151  
   152  func (i Installation) String() string {
   153  	return Stringify(i)
   154  }
   155  
   156  // Get a single GitHub App. Passing the empty string will get
   157  // the authenticated GitHub App.
   158  //
   159  // Note: appSlug is just the URL-friendly name of your GitHub App.
   160  // You can find this on the settings page for your GitHub App
   161  // (e.g., https://github.com/settings/apps/:app_slug).
   162  //
   163  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-an-app
   164  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-the-authenticated-app
   165  //
   166  //meta:operation GET /app
   167  //meta:operation GET /apps/{app_slug}
   168  func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) {
   169  	var u string
   170  	if appSlug != "" {
   171  		u = fmt.Sprintf("apps/%v", appSlug)
   172  	} else {
   173  		u = "app"
   174  	}
   175  
   176  	req, err := s.client.NewRequest("GET", u, nil)
   177  	if err != nil {
   178  		return nil, nil, err
   179  	}
   180  
   181  	app := new(App)
   182  	resp, err := s.client.Do(ctx, req, app)
   183  	if err != nil {
   184  		return nil, resp, err
   185  	}
   186  
   187  	return app, resp, nil
   188  }
   189  
   190  // ListInstallationRequests lists the pending installation requests that the current GitHub App has.
   191  //
   192  // GitHub API docs: https://docs.github.com/rest/apps/apps#list-installation-requests-for-the-authenticated-app
   193  //
   194  //meta:operation GET /app/installation-requests
   195  func (s *AppsService) ListInstallationRequests(ctx context.Context, opts *ListOptions) ([]*InstallationRequest, *Response, error) {
   196  	u, err := addOptions("app/installation-requests", opts)
   197  	if err != nil {
   198  		return nil, nil, err
   199  	}
   200  
   201  	req, err := s.client.NewRequest("GET", u, nil)
   202  	if err != nil {
   203  		return nil, nil, err
   204  	}
   205  
   206  	var i []*InstallationRequest
   207  	resp, err := s.client.Do(ctx, req, &i)
   208  	if err != nil {
   209  		return nil, resp, err
   210  	}
   211  
   212  	return i, resp, nil
   213  }
   214  
   215  // ListInstallations lists the installations that the current GitHub App has.
   216  //
   217  // GitHub API docs: https://docs.github.com/rest/apps/apps#list-installations-for-the-authenticated-app
   218  //
   219  //meta:operation GET /app/installations
   220  func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) {
   221  	u, err := addOptions("app/installations", opts)
   222  	if err != nil {
   223  		return nil, nil, err
   224  	}
   225  
   226  	req, err := s.client.NewRequest("GET", u, nil)
   227  	if err != nil {
   228  		return nil, nil, err
   229  	}
   230  
   231  	var i []*Installation
   232  	resp, err := s.client.Do(ctx, req, &i)
   233  	if err != nil {
   234  		return nil, resp, err
   235  	}
   236  
   237  	return i, resp, nil
   238  }
   239  
   240  // GetInstallation returns the specified installation.
   241  //
   242  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-an-installation-for-the-authenticated-app
   243  //
   244  //meta:operation GET /app/installations/{installation_id}
   245  func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) {
   246  	return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id))
   247  }
   248  
   249  // ListUserInstallations lists installations that are accessible to the authenticated user.
   250  //
   251  // GitHub API docs: https://docs.github.com/rest/apps/installations#list-app-installations-accessible-to-the-user-access-token
   252  //
   253  //meta:operation GET /user/installations
   254  func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) {
   255  	u, err := addOptions("user/installations", opts)
   256  	if err != nil {
   257  		return nil, nil, err
   258  	}
   259  
   260  	req, err := s.client.NewRequest("GET", u, nil)
   261  	if err != nil {
   262  		return nil, nil, err
   263  	}
   264  
   265  	var i struct {
   266  		Installations []*Installation `json:"installations"`
   267  	}
   268  	resp, err := s.client.Do(ctx, req, &i)
   269  	if err != nil {
   270  		return nil, resp, err
   271  	}
   272  
   273  	return i.Installations, resp, nil
   274  }
   275  
   276  // SuspendInstallation suspends the specified installation.
   277  //
   278  // GitHub API docs: https://docs.github.com/rest/apps/apps#suspend-an-app-installation
   279  //
   280  //meta:operation PUT /app/installations/{installation_id}/suspended
   281  func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Response, error) {
   282  	u := fmt.Sprintf("app/installations/%v/suspended", id)
   283  
   284  	req, err := s.client.NewRequest("PUT", u, nil)
   285  	if err != nil {
   286  		return nil, err
   287  	}
   288  
   289  	return s.client.Do(ctx, req, nil)
   290  }
   291  
   292  // UnsuspendInstallation unsuspends the specified installation.
   293  //
   294  // GitHub API docs: https://docs.github.com/rest/apps/apps#unsuspend-an-app-installation
   295  //
   296  //meta:operation DELETE /app/installations/{installation_id}/suspended
   297  func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Response, error) {
   298  	u := fmt.Sprintf("app/installations/%v/suspended", id)
   299  
   300  	req, err := s.client.NewRequest("DELETE", u, nil)
   301  	if err != nil {
   302  		return nil, err
   303  	}
   304  
   305  	return s.client.Do(ctx, req, nil)
   306  }
   307  
   308  // DeleteInstallation deletes the specified installation.
   309  //
   310  // GitHub API docs: https://docs.github.com/rest/apps/apps#delete-an-installation-for-the-authenticated-app
   311  //
   312  //meta:operation DELETE /app/installations/{installation_id}
   313  func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Response, error) {
   314  	u := fmt.Sprintf("app/installations/%v", id)
   315  
   316  	req, err := s.client.NewRequest("DELETE", u, nil)
   317  	if err != nil {
   318  		return nil, err
   319  	}
   320  
   321  	return s.client.Do(ctx, req, nil)
   322  }
   323  
   324  // CreateInstallationToken creates a new installation token.
   325  //
   326  // GitHub API docs: https://docs.github.com/rest/apps/apps#create-an-installation-access-token-for-an-app
   327  //
   328  //meta:operation POST /app/installations/{installation_id}/access_tokens
   329  func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opts *InstallationTokenOptions) (*InstallationToken, *Response, error) {
   330  	u := fmt.Sprintf("app/installations/%v/access_tokens", id)
   331  
   332  	req, err := s.client.NewRequest("POST", u, opts)
   333  	if err != nil {
   334  		return nil, nil, err
   335  	}
   336  
   337  	t := new(InstallationToken)
   338  	resp, err := s.client.Do(ctx, req, t)
   339  	if err != nil {
   340  		return nil, resp, err
   341  	}
   342  
   343  	return t, resp, nil
   344  }
   345  
   346  // CreateAttachment creates a new attachment on user comment containing a url.
   347  //
   348  // GitHub API docs: https://docs.github.com/enterprise-server@3.3/rest/reference/apps#create-a-content-attachment
   349  //
   350  //meta:operation POST /repos/{owner}/{repo}/content_references/{content_reference_id}/attachments
   351  func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID int64, title, body string) (*Attachment, *Response, error) {
   352  	u := fmt.Sprintf("content_references/%v/attachments", contentReferenceID)
   353  	payload := &Attachment{Title: String(title), Body: String(body)}
   354  	req, err := s.client.NewRequest("POST", u, payload)
   355  	if err != nil {
   356  		return nil, nil, err
   357  	}
   358  
   359  	// TODO: remove custom Accept headers when APIs fully launch.
   360  	req.Header.Set("Accept", mediaTypeContentAttachmentsPreview)
   361  
   362  	m := &Attachment{}
   363  	resp, err := s.client.Do(ctx, req, m)
   364  	if err != nil {
   365  		return nil, resp, err
   366  	}
   367  
   368  	return m, resp, nil
   369  }
   370  
   371  // FindOrganizationInstallation finds the organization's installation information.
   372  //
   373  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-an-organization-installation-for-the-authenticated-app
   374  //
   375  //meta:operation GET /orgs/{org}/installation
   376  func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) {
   377  	return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org))
   378  }
   379  
   380  // FindRepositoryInstallation finds the repository's installation information.
   381  //
   382  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-a-repository-installation-for-the-authenticated-app
   383  //
   384  //meta:operation GET /repos/{owner}/{repo}/installation
   385  func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) {
   386  	return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo))
   387  }
   388  
   389  // FindRepositoryInstallationByID finds the repository's installation information.
   390  //
   391  // Note: FindRepositoryInstallationByID uses the undocumented GitHub API endpoint "GET /repositories/{repository_id}/installation".
   392  //
   393  //meta:operation GET /repositories/{repository_id}/installation
   394  func (s *AppsService) FindRepositoryInstallationByID(ctx context.Context, id int64) (*Installation, *Response, error) {
   395  	return s.getInstallation(ctx, fmt.Sprintf("repositories/%d/installation", id))
   396  }
   397  
   398  // FindUserInstallation finds the user's installation information.
   399  //
   400  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-a-user-installation-for-the-authenticated-app
   401  //
   402  //meta:operation GET /users/{username}/installation
   403  func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) {
   404  	return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user))
   405  }
   406  
   407  func (s *AppsService) getInstallation(ctx context.Context, url string) (*Installation, *Response, error) {
   408  	req, err := s.client.NewRequest("GET", url, nil)
   409  	if err != nil {
   410  		return nil, nil, err
   411  	}
   412  
   413  	i := new(Installation)
   414  	resp, err := s.client.Do(ctx, req, i)
   415  	if err != nil {
   416  		return nil, resp, err
   417  	}
   418  
   419  	return i, resp, nil
   420  }