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 }