...

Source file src/github.com/google/go-github/v55/github/actions_secrets.go

Documentation: github.com/google/go-github/v55/github

     1  // Copyright 2020 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  	"encoding/json"
    11  	"fmt"
    12  	"strconv"
    13  )
    14  
    15  // PublicKey represents the public key that should be used to encrypt secrets.
    16  type PublicKey struct {
    17  	KeyID *string `json:"key_id"`
    18  	Key   *string `json:"key"`
    19  }
    20  
    21  // UnmarshalJSON implements the json.Unmarshaler interface.
    22  // This ensures GitHub Enterprise versions which return a numeric key id
    23  // do not error out when unmarshaling.
    24  func (p *PublicKey) UnmarshalJSON(data []byte) error {
    25  	var pk struct {
    26  		KeyID interface{} `json:"key_id,string"`
    27  		Key   *string     `json:"key"`
    28  	}
    29  
    30  	if err := json.Unmarshal(data, &pk); err != nil {
    31  		return err
    32  	}
    33  
    34  	p.Key = pk.Key
    35  
    36  	switch v := pk.KeyID.(type) {
    37  	case nil:
    38  		return nil
    39  	case string:
    40  		p.KeyID = &v
    41  	case float64:
    42  		p.KeyID = String(strconv.FormatFloat(v, 'f', -1, 64))
    43  	default:
    44  		return fmt.Errorf("unable to unmarshal %T as a string", v)
    45  	}
    46  
    47  	return nil
    48  }
    49  
    50  func (s *ActionsService) getPublicKey(ctx context.Context, url string) (*PublicKey, *Response, error) {
    51  	req, err := s.client.NewRequest("GET", url, nil)
    52  	if err != nil {
    53  		return nil, nil, err
    54  	}
    55  
    56  	pubKey := new(PublicKey)
    57  	resp, err := s.client.Do(ctx, req, pubKey)
    58  	if err != nil {
    59  		return nil, resp, err
    60  	}
    61  
    62  	return pubKey, resp, nil
    63  }
    64  
    65  // GetRepoPublicKey gets a public key that should be used for secret encryption.
    66  //
    67  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#get-a-repository-public-key
    68  func (s *ActionsService) GetRepoPublicKey(ctx context.Context, owner, repo string) (*PublicKey, *Response, error) {
    69  	url := fmt.Sprintf("repos/%v/%v/actions/secrets/public-key", owner, repo)
    70  	return s.getPublicKey(ctx, url)
    71  }
    72  
    73  // GetOrgPublicKey gets a public key that should be used for secret encryption.
    74  //
    75  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#get-an-organization-public-key
    76  func (s *ActionsService) GetOrgPublicKey(ctx context.Context, org string) (*PublicKey, *Response, error) {
    77  	url := fmt.Sprintf("orgs/%v/actions/secrets/public-key", org)
    78  	return s.getPublicKey(ctx, url)
    79  }
    80  
    81  // GetEnvPublicKey gets a public key that should be used for secret encryption.
    82  //
    83  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#get-an-environment-public-key
    84  func (s *ActionsService) GetEnvPublicKey(ctx context.Context, repoID int, env string) (*PublicKey, *Response, error) {
    85  	url := fmt.Sprintf("repositories/%v/environments/%v/secrets/public-key", repoID, env)
    86  	return s.getPublicKey(ctx, url)
    87  }
    88  
    89  // Secret represents a repository action secret.
    90  type Secret struct {
    91  	Name                    string    `json:"name"`
    92  	CreatedAt               Timestamp `json:"created_at"`
    93  	UpdatedAt               Timestamp `json:"updated_at"`
    94  	Visibility              string    `json:"visibility,omitempty"`
    95  	SelectedRepositoriesURL string    `json:"selected_repositories_url,omitempty"`
    96  }
    97  
    98  // Secrets represents one item from the ListSecrets response.
    99  type Secrets struct {
   100  	TotalCount int       `json:"total_count"`
   101  	Secrets    []*Secret `json:"secrets"`
   102  }
   103  
   104  func (s *ActionsService) listSecrets(ctx context.Context, url string, opts *ListOptions) (*Secrets, *Response, error) {
   105  	u, err := addOptions(url, opts)
   106  	if err != nil {
   107  		return nil, nil, err
   108  	}
   109  
   110  	req, err := s.client.NewRequest("GET", u, nil)
   111  	if err != nil {
   112  		return nil, nil, err
   113  	}
   114  
   115  	secrets := new(Secrets)
   116  	resp, err := s.client.Do(ctx, req, &secrets)
   117  	if err != nil {
   118  		return nil, resp, err
   119  	}
   120  
   121  	return secrets, resp, nil
   122  }
   123  
   124  // ListRepoSecrets lists all secrets available in a repository
   125  // without revealing their encrypted values.
   126  //
   127  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#list-repository-secrets
   128  func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) {
   129  	url := fmt.Sprintf("repos/%v/%v/actions/secrets", owner, repo)
   130  	return s.listSecrets(ctx, url, opts)
   131  }
   132  
   133  // ListOrgSecrets lists all secrets available in an organization
   134  // without revealing their encrypted values.
   135  //
   136  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#list-organization-secrets
   137  func (s *ActionsService) ListOrgSecrets(ctx context.Context, org string, opts *ListOptions) (*Secrets, *Response, error) {
   138  	url := fmt.Sprintf("orgs/%v/actions/secrets", org)
   139  	return s.listSecrets(ctx, url, opts)
   140  }
   141  
   142  // ListEnvSecrets lists all secrets available in an environment.
   143  //
   144  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#list-environment-secrets
   145  func (s *ActionsService) ListEnvSecrets(ctx context.Context, repoID int, env string, opts *ListOptions) (*Secrets, *Response, error) {
   146  	url := fmt.Sprintf("repositories/%v/environments/%v/secrets", repoID, env)
   147  	return s.listSecrets(ctx, url, opts)
   148  }
   149  
   150  func (s *ActionsService) getSecret(ctx context.Context, url string) (*Secret, *Response, error) {
   151  	req, err := s.client.NewRequest("GET", url, nil)
   152  	if err != nil {
   153  		return nil, nil, err
   154  	}
   155  
   156  	secret := new(Secret)
   157  	resp, err := s.client.Do(ctx, req, secret)
   158  	if err != nil {
   159  		return nil, resp, err
   160  	}
   161  
   162  	return secret, resp, nil
   163  }
   164  
   165  // GetRepoSecret gets a single repository secret without revealing its encrypted value.
   166  //
   167  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#get-a-repository-secret
   168  func (s *ActionsService) GetRepoSecret(ctx context.Context, owner, repo, name string) (*Secret, *Response, error) {
   169  	url := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name)
   170  	return s.getSecret(ctx, url)
   171  }
   172  
   173  // GetOrgSecret gets a single organization secret without revealing its encrypted value.
   174  //
   175  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#get-an-organization-secret
   176  func (s *ActionsService) GetOrgSecret(ctx context.Context, org, name string) (*Secret, *Response, error) {
   177  	url := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name)
   178  	return s.getSecret(ctx, url)
   179  }
   180  
   181  // GetEnvSecret gets a single environment secret without revealing its encrypted value.
   182  //
   183  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#get-an-environment-secret
   184  func (s *ActionsService) GetEnvSecret(ctx context.Context, repoID int, env, secretName string) (*Secret, *Response, error) {
   185  	url := fmt.Sprintf("repositories/%v/environments/%v/secrets/%v", repoID, env, secretName)
   186  	return s.getSecret(ctx, url)
   187  }
   188  
   189  // SelectedRepoIDs are the repository IDs that have access to the actions secrets.
   190  type SelectedRepoIDs []int64
   191  
   192  // EncryptedSecret represents a secret that is encrypted using a public key.
   193  //
   194  // The value of EncryptedValue must be your secret, encrypted with
   195  // LibSodium (see documentation here: https://libsodium.gitbook.io/doc/bindings_for_other_languages)
   196  // using the public key retrieved using the GetPublicKey method.
   197  type EncryptedSecret struct {
   198  	Name                  string          `json:"-"`
   199  	KeyID                 string          `json:"key_id"`
   200  	EncryptedValue        string          `json:"encrypted_value"`
   201  	Visibility            string          `json:"visibility,omitempty"`
   202  	SelectedRepositoryIDs SelectedRepoIDs `json:"selected_repository_ids,omitempty"`
   203  }
   204  
   205  func (s *ActionsService) putSecret(ctx context.Context, url string, eSecret *EncryptedSecret) (*Response, error) {
   206  	req, err := s.client.NewRequest("PUT", url, eSecret)
   207  	if err != nil {
   208  		return nil, err
   209  	}
   210  
   211  	return s.client.Do(ctx, req, nil)
   212  }
   213  
   214  // CreateOrUpdateRepoSecret creates or updates a repository secret with an encrypted value.
   215  //
   216  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#create-or-update-a-repository-secret
   217  func (s *ActionsService) CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *EncryptedSecret) (*Response, error) {
   218  	url := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, eSecret.Name)
   219  	return s.putSecret(ctx, url, eSecret)
   220  }
   221  
   222  // CreateOrUpdateOrgSecret creates or updates an organization secret with an encrypted value.
   223  //
   224  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#create-or-update-an-organization-secret
   225  func (s *ActionsService) CreateOrUpdateOrgSecret(ctx context.Context, org string, eSecret *EncryptedSecret) (*Response, error) {
   226  	url := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, eSecret.Name)
   227  	return s.putSecret(ctx, url, eSecret)
   228  }
   229  
   230  // CreateOrUpdateEnvSecret creates or updates a single environment secret with an encrypted value.
   231  //
   232  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#create-or-update-an-environment-secret
   233  func (s *ActionsService) CreateOrUpdateEnvSecret(ctx context.Context, repoID int, env string, eSecret *EncryptedSecret) (*Response, error) {
   234  	url := fmt.Sprintf("repositories/%v/environments/%v/secrets/%v", repoID, env, eSecret.Name)
   235  	return s.putSecret(ctx, url, eSecret)
   236  }
   237  
   238  func (s *ActionsService) deleteSecret(ctx context.Context, url string) (*Response, error) {
   239  	req, err := s.client.NewRequest("DELETE", url, nil)
   240  	if err != nil {
   241  		return nil, err
   242  	}
   243  
   244  	return s.client.Do(ctx, req, nil)
   245  }
   246  
   247  // DeleteRepoSecret deletes a secret in a repository using the secret name.
   248  //
   249  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#delete-a-repository-secret
   250  func (s *ActionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) (*Response, error) {
   251  	url := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name)
   252  	return s.deleteSecret(ctx, url)
   253  }
   254  
   255  // DeleteOrgSecret deletes a secret in an organization using the secret name.
   256  //
   257  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#delete-an-organization-secret
   258  func (s *ActionsService) DeleteOrgSecret(ctx context.Context, org, name string) (*Response, error) {
   259  	url := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name)
   260  	return s.deleteSecret(ctx, url)
   261  }
   262  
   263  // DeleteEnvSecret deletes a secret in an environment using the secret name.
   264  //
   265  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#delete-an-environment-secret
   266  func (s *ActionsService) DeleteEnvSecret(ctx context.Context, repoID int, env, secretName string) (*Response, error) {
   267  	url := fmt.Sprintf("repositories/%v/environments/%v/secrets/%v", repoID, env, secretName)
   268  	return s.deleteSecret(ctx, url)
   269  }
   270  
   271  // SelectedReposList represents the list of repositories selected for an organization secret.
   272  type SelectedReposList struct {
   273  	TotalCount   *int          `json:"total_count,omitempty"`
   274  	Repositories []*Repository `json:"repositories,omitempty"`
   275  }
   276  
   277  func (s *ActionsService) listSelectedReposForSecret(ctx context.Context, url string, opts *ListOptions) (*SelectedReposList, *Response, error) {
   278  	u, err := addOptions(url, opts)
   279  	if err != nil {
   280  		return nil, nil, err
   281  	}
   282  
   283  	req, err := s.client.NewRequest("GET", u, nil)
   284  	if err != nil {
   285  		return nil, nil, err
   286  	}
   287  
   288  	result := new(SelectedReposList)
   289  	resp, err := s.client.Do(ctx, req, result)
   290  	if err != nil {
   291  		return nil, resp, err
   292  	}
   293  
   294  	return result, resp, nil
   295  }
   296  
   297  // ListSelectedReposForOrgSecret lists all repositories that have access to a secret.
   298  //
   299  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#list-selected-repositories-for-an-organization-secret
   300  func (s *ActionsService) ListSelectedReposForOrgSecret(ctx context.Context, org, name string, opts *ListOptions) (*SelectedReposList, *Response, error) {
   301  	url := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name)
   302  	return s.listSelectedReposForSecret(ctx, url, opts)
   303  }
   304  
   305  func (s *ActionsService) setSelectedReposForSecret(ctx context.Context, url string, ids SelectedRepoIDs) (*Response, error) {
   306  	type repoIDs struct {
   307  		SelectedIDs SelectedRepoIDs `json:"selected_repository_ids"`
   308  	}
   309  
   310  	req, err := s.client.NewRequest("PUT", url, repoIDs{SelectedIDs: ids})
   311  	if err != nil {
   312  		return nil, err
   313  	}
   314  
   315  	return s.client.Do(ctx, req, nil)
   316  }
   317  
   318  // SetSelectedReposForOrgSecret sets the repositories that have access to a secret.
   319  //
   320  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#set-selected-repositories-for-an-organization-secret
   321  func (s *ActionsService) SetSelectedReposForOrgSecret(ctx context.Context, org, name string, ids SelectedRepoIDs) (*Response, error) {
   322  	url := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name)
   323  	return s.setSelectedReposForSecret(ctx, url, ids)
   324  }
   325  
   326  func (s *ActionsService) addSelectedRepoToSecret(ctx context.Context, url string) (*Response, error) {
   327  	req, err := s.client.NewRequest("PUT", url, nil)
   328  	if err != nil {
   329  		return nil, err
   330  	}
   331  
   332  	return s.client.Do(ctx, req, nil)
   333  }
   334  
   335  // AddSelectedRepoToOrgSecret adds a repository to an organization secret.
   336  //
   337  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#add-selected-repository-to-an-organization-secret
   338  func (s *ActionsService) AddSelectedRepoToOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) {
   339  	url := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID)
   340  	return s.addSelectedRepoToSecret(ctx, url)
   341  }
   342  
   343  func (s *ActionsService) removeSelectedRepoFromSecret(ctx context.Context, url string) (*Response, error) {
   344  	req, err := s.client.NewRequest("DELETE", url, nil)
   345  	if err != nil {
   346  		return nil, err
   347  	}
   348  
   349  	return s.client.Do(ctx, req, nil)
   350  }
   351  
   352  // RemoveSelectedRepoFromOrgSecret removes a repository from an organization secret.
   353  //
   354  // GitHub API docs: https://docs.github.com/en/rest/actions/secrets#remove-selected-repository-from-an-organization-secret
   355  func (s *ActionsService) RemoveSelectedRepoFromOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) {
   356  	url := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID)
   357  	return s.removeSelectedRepoFromSecret(ctx, url)
   358  }
   359  

View as plain text