github.com/google/go-github/v49@v49.1.0/github/authorizations.go (about) 1 // Copyright 2015 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 // Scope models a GitHub authorization scope. 14 // 15 // GitHub API docs: https://docs.github.com/en/rest/oauth/#scopes 16 type Scope string 17 18 // This is the set of scopes for GitHub API V3 19 const ( 20 ScopeNone Scope = "(no scope)" // REVISIT: is this actually returned, or just a documentation artifact? 21 ScopeUser Scope = "user" 22 ScopeUserEmail Scope = "user:email" 23 ScopeUserFollow Scope = "user:follow" 24 ScopePublicRepo Scope = "public_repo" 25 ScopeRepo Scope = "repo" 26 ScopeRepoDeployment Scope = "repo_deployment" 27 ScopeRepoStatus Scope = "repo:status" 28 ScopeDeleteRepo Scope = "delete_repo" 29 ScopeNotifications Scope = "notifications" 30 ScopeGist Scope = "gist" 31 ScopeReadRepoHook Scope = "read:repo_hook" 32 ScopeWriteRepoHook Scope = "write:repo_hook" 33 ScopeAdminRepoHook Scope = "admin:repo_hook" 34 ScopeAdminOrgHook Scope = "admin:org_hook" 35 ScopeReadOrg Scope = "read:org" 36 ScopeWriteOrg Scope = "write:org" 37 ScopeAdminOrg Scope = "admin:org" 38 ScopeReadPublicKey Scope = "read:public_key" 39 ScopeWritePublicKey Scope = "write:public_key" 40 ScopeAdminPublicKey Scope = "admin:public_key" 41 ScopeReadGPGKey Scope = "read:gpg_key" 42 ScopeWriteGPGKey Scope = "write:gpg_key" 43 ScopeAdminGPGKey Scope = "admin:gpg_key" 44 ScopeSecurityEvents Scope = "security_events" 45 ) 46 47 // AuthorizationsService handles communication with the authorization related 48 // methods of the GitHub API. 49 // 50 // This service requires HTTP Basic Authentication; it cannot be accessed using 51 // an OAuth token. 52 // 53 // GitHub API docs: https://docs.github.com/en/rest/oauth-authorizations 54 type AuthorizationsService service 55 56 // Authorization represents an individual GitHub authorization. 57 type Authorization struct { 58 ID *int64 `json:"id,omitempty"` 59 URL *string `json:"url,omitempty"` 60 Scopes []Scope `json:"scopes,omitempty"` 61 Token *string `json:"token,omitempty"` 62 TokenLastEight *string `json:"token_last_eight,omitempty"` 63 HashedToken *string `json:"hashed_token,omitempty"` 64 App *AuthorizationApp `json:"app,omitempty"` 65 Note *string `json:"note,omitempty"` 66 NoteURL *string `json:"note_url,omitempty"` 67 UpdatedAt *Timestamp `json:"updated_at,omitempty"` 68 CreatedAt *Timestamp `json:"created_at,omitempty"` 69 Fingerprint *string `json:"fingerprint,omitempty"` 70 71 // User is only populated by the Check and Reset methods. 72 User *User `json:"user,omitempty"` 73 } 74 75 func (a Authorization) String() string { 76 return Stringify(a) 77 } 78 79 // AuthorizationApp represents an individual GitHub app (in the context of authorization). 80 type AuthorizationApp struct { 81 URL *string `json:"url,omitempty"` 82 Name *string `json:"name,omitempty"` 83 ClientID *string `json:"client_id,omitempty"` 84 } 85 86 func (a AuthorizationApp) String() string { 87 return Stringify(a) 88 } 89 90 // Grant represents an OAuth application that has been granted access to an account. 91 type Grant struct { 92 ID *int64 `json:"id,omitempty"` 93 URL *string `json:"url,omitempty"` 94 App *AuthorizationApp `json:"app,omitempty"` 95 CreatedAt *Timestamp `json:"created_at,omitempty"` 96 UpdatedAt *Timestamp `json:"updated_at,omitempty"` 97 Scopes []string `json:"scopes,omitempty"` 98 } 99 100 func (g Grant) String() string { 101 return Stringify(g) 102 } 103 104 // AuthorizationRequest represents a request to create an authorization. 105 type AuthorizationRequest struct { 106 Scopes []Scope `json:"scopes,omitempty"` 107 Note *string `json:"note,omitempty"` 108 NoteURL *string `json:"note_url,omitempty"` 109 ClientID *string `json:"client_id,omitempty"` 110 ClientSecret *string `json:"client_secret,omitempty"` 111 Fingerprint *string `json:"fingerprint,omitempty"` 112 } 113 114 func (a AuthorizationRequest) String() string { 115 return Stringify(a) 116 } 117 118 // AuthorizationUpdateRequest represents a request to update an authorization. 119 // 120 // Note that for any one update, you must only provide one of the "scopes" 121 // fields. That is, you may provide only one of "Scopes", or "AddScopes", or 122 // "RemoveScopes". 123 // 124 // GitHub API docs: https://docs.github.com/en/rest/oauth-authorizations#update-an-existing-authorization 125 type AuthorizationUpdateRequest struct { 126 Scopes []string `json:"scopes,omitempty"` 127 AddScopes []string `json:"add_scopes,omitempty"` 128 RemoveScopes []string `json:"remove_scopes,omitempty"` 129 Note *string `json:"note,omitempty"` 130 NoteURL *string `json:"note_url,omitempty"` 131 Fingerprint *string `json:"fingerprint,omitempty"` 132 } 133 134 func (a AuthorizationUpdateRequest) String() string { 135 return Stringify(a) 136 } 137 138 // Check if an OAuth token is valid for a specific app. 139 // 140 // Note that this operation requires the use of BasicAuth, but where the 141 // username is the OAuth application clientID, and the password is its 142 // clientSecret. Invalid tokens will return a 404 Not Found. 143 // 144 // The returned Authorization.User field will be populated. 145 // 146 // GitHub API docs: https://docs.github.com/en/rest/apps/oauth-applications#check-a-token 147 func (s *AuthorizationsService) Check(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) { 148 u := fmt.Sprintf("applications/%v/token", clientID) 149 150 reqBody := &struct { 151 AccessToken string `json:"access_token"` 152 }{AccessToken: accessToken} 153 154 req, err := s.client.NewRequest("POST", u, reqBody) 155 if err != nil { 156 return nil, nil, err 157 } 158 req.Header.Set("Accept", mediaTypeOAuthAppPreview) 159 160 a := new(Authorization) 161 resp, err := s.client.Do(ctx, req, a) 162 if err != nil { 163 return nil, resp, err 164 } 165 166 return a, resp, nil 167 } 168 169 // Reset is used to reset a valid OAuth token without end user involvement. 170 // Applications must save the "token" property in the response, because changes 171 // take effect immediately. 172 // 173 // Note that this operation requires the use of BasicAuth, but where the 174 // username is the OAuth application clientID, and the password is its 175 // clientSecret. Invalid tokens will return a 404 Not Found. 176 // 177 // The returned Authorization.User field will be populated. 178 // 179 // GitHub API docs: https://docs.github.com/en/rest/apps/oauth-applications#reset-a-token 180 func (s *AuthorizationsService) Reset(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) { 181 u := fmt.Sprintf("applications/%v/token", clientID) 182 183 reqBody := &struct { 184 AccessToken string `json:"access_token"` 185 }{AccessToken: accessToken} 186 187 req, err := s.client.NewRequest("PATCH", u, reqBody) 188 if err != nil { 189 return nil, nil, err 190 } 191 req.Header.Set("Accept", mediaTypeOAuthAppPreview) 192 193 a := new(Authorization) 194 resp, err := s.client.Do(ctx, req, a) 195 if err != nil { 196 return nil, resp, err 197 } 198 199 return a, resp, nil 200 } 201 202 // Revoke an authorization for an application. 203 // 204 // Note that this operation requires the use of BasicAuth, but where the 205 // username is the OAuth application clientID, and the password is its 206 // clientSecret. Invalid tokens will return a 404 Not Found. 207 // 208 // GitHub API docs: https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-token 209 func (s *AuthorizationsService) Revoke(ctx context.Context, clientID, accessToken string) (*Response, error) { 210 u := fmt.Sprintf("applications/%v/token", clientID) 211 212 reqBody := &struct { 213 AccessToken string `json:"access_token"` 214 }{AccessToken: accessToken} 215 216 req, err := s.client.NewRequest("DELETE", u, reqBody) 217 if err != nil { 218 return nil, err 219 } 220 req.Header.Set("Accept", mediaTypeOAuthAppPreview) 221 222 return s.client.Do(ctx, req, nil) 223 } 224 225 // DeleteGrant deletes an OAuth application grant. Deleting an application's 226 // grant will also delete all OAuth tokens associated with the application for 227 // the user. 228 // 229 // GitHub API docs: https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization 230 func (s *AuthorizationsService) DeleteGrant(ctx context.Context, clientID, accessToken string) (*Response, error) { 231 u := fmt.Sprintf("applications/%v/grant", clientID) 232 233 reqBody := &struct { 234 AccessToken string `json:"access_token"` 235 }{AccessToken: accessToken} 236 237 req, err := s.client.NewRequest("DELETE", u, reqBody) 238 if err != nil { 239 return nil, err 240 } 241 req.Header.Set("Accept", mediaTypeOAuthAppPreview) 242 243 return s.client.Do(ctx, req, nil) 244 } 245 246 // CreateImpersonation creates an impersonation OAuth token. 247 // 248 // This requires admin permissions. With the returned Authorization.Token 249 // you can e.g. create or delete a user's public SSH key. NOTE: creating a 250 // new token automatically revokes an existing one. 251 // 252 // GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token 253 func (s *AuthorizationsService) CreateImpersonation(ctx context.Context, username string, authReq *AuthorizationRequest) (*Authorization, *Response, error) { 254 u := fmt.Sprintf("admin/users/%v/authorizations", username) 255 req, err := s.client.NewRequest("POST", u, authReq) 256 if err != nil { 257 return nil, nil, err 258 } 259 260 a := new(Authorization) 261 resp, err := s.client.Do(ctx, req, a) 262 if err != nil { 263 return nil, resp, err 264 } 265 return a, resp, nil 266 } 267 268 // DeleteImpersonation deletes an impersonation OAuth token. 269 // 270 // NOTE: there can be only one at a time. 271 // 272 // GitHub API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-an-impersonation-oauth-token 273 func (s *AuthorizationsService) DeleteImpersonation(ctx context.Context, username string) (*Response, error) { 274 u := fmt.Sprintf("admin/users/%v/authorizations", username) 275 req, err := s.client.NewRequest("DELETE", u, nil) 276 if err != nil { 277 return nil, err 278 } 279 280 return s.client.Do(ctx, req, nil) 281 }