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