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 6package github 7 8import ( 9 "context" 10 "fmt" 11 "time" 12) 13 14// AppsService provides access to the installation related functions 15// in the GitHub API. 16// 17// GitHub API docs: https://developer.github.com/v3/apps/ 18type AppsService service 19 20// App represents a GitHub App. 21type App struct { 22 ID *int64 `json:"id,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 *time.Time `json:"created_at,omitempty"` 30 UpdatedAt *time.Time `json:"updated_at,omitempty"` 31} 32 33// InstallationToken represents an installation token. 34type InstallationToken struct { 35 Token *string `json:"token,omitempty"` 36 ExpiresAt *time.Time `json:"expires_at,omitempty"` 37} 38 39// InstallationPermissions lists the permissions for metadata, contents, issues and single file for an installation. 40type InstallationPermissions struct { 41 Metadata *string `json:"metadata,omitempty"` 42 Contents *string `json:"contents,omitempty"` 43 Issues *string `json:"issues,omitempty"` 44 SingleFile *string `json:"single_file,omitempty"` 45} 46 47// Installation represents a GitHub Apps installation. 48type Installation struct { 49 ID *int64 `json:"id,omitempty"` 50 AppID *int64 `json:"app_id,omitempty"` 51 TargetID *int64 `json:"target_id,omitempty"` 52 Account *User `json:"account,omitempty"` 53 AccessTokensURL *string `json:"access_tokens_url,omitempty"` 54 RepositoriesURL *string `json:"repositories_url,omitempty"` 55 HTMLURL *string `json:"html_url,omitempty"` 56 TargetType *string `json:"target_type,omitempty"` 57 SingleFileName *string `json:"single_file_name,omitempty"` 58 RepositorySelection *string `json:"repository_selection,omitempty"` 59 Events []string `json:"events,omitempty"` 60 Permissions *InstallationPermissions `json:"permissions,omitempty"` 61 CreatedAt *Timestamp `json:"created_at,omitempty"` 62 UpdatedAt *Timestamp `json:"updated_at,omitempty"` 63} 64 65func (i Installation) String() string { 66 return Stringify(i) 67} 68 69// Get a single GitHub App. Passing the empty string will get 70// the authenticated GitHub App. 71// 72// Note: appSlug is just the URL-friendly name of your GitHub App. 73// You can find this on the settings page for your GitHub App 74// (e.g., https://github.com/settings/apps/:app_slug). 75// 76// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-github-app 77func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) { 78 var u string 79 if appSlug != "" { 80 u = fmt.Sprintf("apps/%v", appSlug) 81 } else { 82 u = "app" 83 } 84 85 req, err := s.client.NewRequest("GET", u, nil) 86 if err != nil { 87 return nil, nil, err 88 } 89 90 // TODO: remove custom Accept header when this API fully launches. 91 req.Header.Set("Accept", mediaTypeIntegrationPreview) 92 93 app := new(App) 94 resp, err := s.client.Do(ctx, req, app) 95 if err != nil { 96 return nil, resp, err 97 } 98 99 return app, resp, nil 100} 101 102// ListInstallations lists the installations that the current GitHub App has. 103// 104// GitHub API docs: https://developer.github.com/v3/apps/#find-installations 105func (s *AppsService) ListInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) { 106 u, err := addOptions("app/installations", opt) 107 if err != nil { 108 return nil, nil, err 109 } 110 111 req, err := s.client.NewRequest("GET", u, nil) 112 if err != nil { 113 return nil, nil, err 114 } 115 116 // TODO: remove custom Accept header when this API fully launches. 117 req.Header.Set("Accept", mediaTypeIntegrationPreview) 118 119 var i []*Installation 120 resp, err := s.client.Do(ctx, req, &i) 121 if err != nil { 122 return nil, resp, err 123 } 124 125 return i, resp, nil 126} 127 128// GetInstallation returns the specified installation. 129// 130// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-installation 131func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) { 132 return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id)) 133} 134 135// ListUserInstallations lists installations that are accessible to the authenticated user. 136// 137// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-user 138func (s *AppsService) ListUserInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) { 139 u, err := addOptions("user/installations", opt) 140 if err != nil { 141 return nil, nil, err 142 } 143 144 req, err := s.client.NewRequest("GET", u, nil) 145 if err != nil { 146 return nil, nil, err 147 } 148 149 // TODO: remove custom Accept header when this API fully launches. 150 req.Header.Set("Accept", mediaTypeIntegrationPreview) 151 152 var i struct { 153 Installations []*Installation `json:"installations"` 154 } 155 resp, err := s.client.Do(ctx, req, &i) 156 if err != nil { 157 return nil, resp, err 158 } 159 160 return i.Installations, resp, nil 161} 162 163// CreateInstallationToken creates a new installation token. 164// 165// GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token 166func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64) (*InstallationToken, *Response, error) { 167 u := fmt.Sprintf("installations/%v/access_tokens", id) 168 169 req, err := s.client.NewRequest("POST", u, nil) 170 if err != nil { 171 return nil, nil, err 172 } 173 174 // TODO: remove custom Accept header when this API fully launches. 175 req.Header.Set("Accept", mediaTypeIntegrationPreview) 176 177 t := new(InstallationToken) 178 resp, err := s.client.Do(ctx, req, t) 179 if err != nil { 180 return nil, resp, err 181 } 182 183 return t, resp, nil 184} 185 186// FindOrganizationInstallation finds the organization's installation information. 187// 188// GitHub API docs: https://developer.github.com/v3/apps/#find-organization-installation 189func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) { 190 return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org)) 191} 192 193// FindRepositoryInstallation finds the repository's installation information. 194// 195// GitHub API docs: https://developer.github.com/v3/apps/#find-repository-installation 196func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) { 197 return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo)) 198} 199 200// FindUserInstallation finds the user's installation information. 201// 202// GitHub API docs: https://developer.github.com/v3/apps/#find-repository-installation 203func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) { 204 return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user)) 205} 206 207func (s *AppsService) getInstallation(ctx context.Context, url string) (*Installation, *Response, error) { 208 req, err := s.client.NewRequest("GET", url, nil) 209 if err != nil { 210 return nil, nil, err 211 } 212 213 // TODO: remove custom Accept header when this API fully launches. 214 req.Header.Set("Accept", mediaTypeIntegrationPreview) 215 216 i := new(Installation) 217 resp, err := s.client.Do(ctx, req, i) 218 if err != nil { 219 return nil, resp, err 220 } 221 222 return i, resp, nil 223} 224