github.com/google/go-github/v71@v71.0.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/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/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/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/rest/apps/oauth-applications#check-a-token
   147  //
   148  //meta:operation POST /applications/{client_id}/token
   149  func (s *AuthorizationsService) Check(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) {
   150  	u := fmt.Sprintf("applications/%v/token", clientID)
   151  
   152  	reqBody := &struct {
   153  		AccessToken string `json:"access_token"`
   154  	}{AccessToken: accessToken}
   155  
   156  	req, err := s.client.NewRequest("POST", u, reqBody)
   157  	if err != nil {
   158  		return nil, nil, err
   159  	}
   160  	req.Header.Set("Accept", mediaTypeOAuthAppPreview)
   161  
   162  	a := new(Authorization)
   163  	resp, err := s.client.Do(ctx, req, a)
   164  	if err != nil {
   165  		return nil, resp, err
   166  	}
   167  
   168  	return a, resp, nil
   169  }
   170  
   171  // Reset is used to reset a valid OAuth token without end user involvement.
   172  // Applications must save the "token" property in the response, because changes
   173  // take effect immediately.
   174  //
   175  // Note that this operation requires the use of BasicAuth, but where the
   176  // username is the OAuth application clientID, and the password is its
   177  // clientSecret. Invalid tokens will return a 404 Not Found.
   178  //
   179  // The returned Authorization.User field will be populated.
   180  //
   181  // GitHub API docs: https://docs.github.com/rest/apps/oauth-applications#reset-a-token
   182  //
   183  //meta:operation PATCH /applications/{client_id}/token
   184  func (s *AuthorizationsService) Reset(ctx context.Context, clientID, accessToken string) (*Authorization, *Response, error) {
   185  	u := fmt.Sprintf("applications/%v/token", clientID)
   186  
   187  	reqBody := &struct {
   188  		AccessToken string `json:"access_token"`
   189  	}{AccessToken: accessToken}
   190  
   191  	req, err := s.client.NewRequest("PATCH", u, reqBody)
   192  	if err != nil {
   193  		return nil, nil, err
   194  	}
   195  	req.Header.Set("Accept", mediaTypeOAuthAppPreview)
   196  
   197  	a := new(Authorization)
   198  	resp, err := s.client.Do(ctx, req, a)
   199  	if err != nil {
   200  		return nil, resp, err
   201  	}
   202  
   203  	return a, resp, nil
   204  }
   205  
   206  // Revoke an authorization for an application.
   207  //
   208  // Note that this operation requires the use of BasicAuth, but where the
   209  // username is the OAuth application clientID, and the password is its
   210  // clientSecret. Invalid tokens will return a 404 Not Found.
   211  //
   212  // GitHub API docs: https://docs.github.com/rest/apps/oauth-applications#delete-an-app-token
   213  //
   214  //meta:operation DELETE /applications/{client_id}/token
   215  func (s *AuthorizationsService) Revoke(ctx context.Context, clientID, accessToken string) (*Response, error) {
   216  	u := fmt.Sprintf("applications/%v/token", clientID)
   217  
   218  	reqBody := &struct {
   219  		AccessToken string `json:"access_token"`
   220  	}{AccessToken: accessToken}
   221  
   222  	req, err := s.client.NewRequest("DELETE", u, reqBody)
   223  	if err != nil {
   224  		return nil, err
   225  	}
   226  	req.Header.Set("Accept", mediaTypeOAuthAppPreview)
   227  
   228  	return s.client.Do(ctx, req, nil)
   229  }
   230  
   231  // DeleteGrant deletes an OAuth application grant. Deleting an application's
   232  // grant will also delete all OAuth tokens associated with the application for
   233  // the user.
   234  //
   235  // GitHub API docs: https://docs.github.com/rest/apps/oauth-applications#delete-an-app-authorization
   236  //
   237  //meta:operation DELETE /applications/{client_id}/grant
   238  func (s *AuthorizationsService) DeleteGrant(ctx context.Context, clientID, accessToken string) (*Response, error) {
   239  	u := fmt.Sprintf("applications/%v/grant", clientID)
   240  
   241  	reqBody := &struct {
   242  		AccessToken string `json:"access_token"`
   243  	}{AccessToken: accessToken}
   244  
   245  	req, err := s.client.NewRequest("DELETE", u, reqBody)
   246  	if err != nil {
   247  		return nil, err
   248  	}
   249  	req.Header.Set("Accept", mediaTypeOAuthAppPreview)
   250  
   251  	return s.client.Do(ctx, req, nil)
   252  }
   253  
   254  // CreateImpersonation creates an impersonation OAuth token.
   255  //
   256  // This requires admin permissions. With the returned Authorization.Token
   257  // you can e.g. create or delete a user's public SSH key. NOTE: creating a
   258  // new token automatically revokes an existing one.
   259  //
   260  // GitHub API docs: https://docs.github.com/enterprise-server@3.16/rest/enterprise-admin/users#create-an-impersonation-oauth-token
   261  //
   262  //meta:operation POST /admin/users/{username}/authorizations
   263  func (s *AuthorizationsService) CreateImpersonation(ctx context.Context, username string, authReq *AuthorizationRequest) (*Authorization, *Response, error) {
   264  	u := fmt.Sprintf("admin/users/%v/authorizations", username)
   265  	req, err := s.client.NewRequest("POST", u, authReq)
   266  	if err != nil {
   267  		return nil, nil, err
   268  	}
   269  
   270  	a := new(Authorization)
   271  	resp, err := s.client.Do(ctx, req, a)
   272  	if err != nil {
   273  		return nil, resp, err
   274  	}
   275  	return a, resp, nil
   276  }
   277  
   278  // DeleteImpersonation deletes an impersonation OAuth token.
   279  //
   280  // NOTE: there can be only one at a time.
   281  //
   282  // GitHub API docs: https://docs.github.com/enterprise-server@3.16/rest/enterprise-admin/users#delete-an-impersonation-oauth-token
   283  //
   284  //meta:operation DELETE /admin/users/{username}/authorizations
   285  func (s *AuthorizationsService) DeleteImpersonation(ctx context.Context, username string) (*Response, error) {
   286  	u := fmt.Sprintf("admin/users/%v/authorizations", username)
   287  	req, err := s.client.NewRequest("DELETE", u, nil)
   288  	if err != nil {
   289  		return nil, err
   290  	}
   291  
   292  	return s.client.Do(ctx, req, nil)
   293  }