github.com/IBM-Cloud/bluemix-go@v0.0.0-20240423071914-9e96525baef4/api/container/registryv1/tokens.go (about)

     1  package registryv1
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/json"
     6  	"fmt"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/IBM-Cloud/bluemix-go/client"
    11  	"github.com/IBM-Cloud/bluemix-go/helpers"
    12  	"github.com/IBM-Cloud/bluemix-go/rest"
    13  )
    14  
    15  type TokenTargetHeader struct {
    16  	AccountID string
    17  }
    18  
    19  //ToMap ...
    20  func (c TokenTargetHeader) ToMap() map[string]string {
    21  	m := make(map[string]string, 1)
    22  	m[accountIDHeader] = c.AccountID
    23  	return m
    24  }
    25  
    26  //Subnets interface
    27  type Tokens interface {
    28  	GetToken(tokenUUID string, target TokenTargetHeader) (*TokenResponse, error)
    29  	GetTokens(target TokenTargetHeader) (*GetTokensResponse, error)
    30  	DeleteToken(tokenUUID string, target TokenTargetHeader) error
    31  	DeleteTokenByDescription(tokenDescription string, target TokenTargetHeader) error
    32  	IssueToken(params IssueTokenRequest, target TokenTargetHeader) (*TokenResponse, error)
    33  }
    34  
    35  type tokens struct {
    36  	client *client.Client
    37  }
    38  
    39  func newTokenAPI(c *client.Client) Tokens {
    40  	return &tokens{
    41  		client: c,
    42  	}
    43  }
    44  
    45  type GetTokensResponse struct {
    46  	Tokens []struct {
    47  		ID             string `json:"_id,omitempty"`
    48  		Owner          string `json:"owner,omitempty"`
    49  		Token          string `json:"token,omitempty"`
    50  		Description    string `json:"secondary_owner,omitempty"`
    51  		Readonly       bool   `json:"readonly,omitempty"`
    52  		Revoked        bool   `json:"revoked,omitempty"`
    53  		Expiry         int64  `json:"expiry,omitempty"`
    54  		EncryptedToken string `json:"encrypted_token,omitempty"`
    55  	} `json:"tokens,omitempty"`
    56  }
    57  type TokenResponse struct {
    58  	ID    string
    59  	Token string `json:"token,omitempty"`
    60  }
    61  
    62  /*TokenIssueParams contains all the parameters to send to the API endpoint
    63  for the token issue operation typically these are written to a http.Request
    64  */
    65  type IssueTokenRequest struct {
    66  	/*Description
    67  	  Specifies a description for the token so it can be more easily identified. If this option is specified more than once, the last parsed setting is the setting that is used.
    68  	*/
    69  	Description string
    70  	/*Permanent
    71  	  When specified, the access token does not expire. If this option is specified more than once, the last parsed setting is the setting that is used.
    72  	*/
    73  	Permanent bool
    74  	/*Write
    75  	  When specified, the token provides write access to registry namespaces in your IBM Cloud account. If this option is not specified, or is set to false, the token provides read-only access. If this option is specified more than once, the last parsed setting is the setting that is used.
    76  	*/
    77  	Write bool
    78  }
    79  
    80  func DefaultIssueTokenRequest() *IssueTokenRequest {
    81  	return &IssueTokenRequest{
    82  		Description: "",
    83  		Permanent:   false,
    84  		Write:       false,
    85  	}
    86  }
    87  
    88  //GetTokens ...
    89  func (r *tokens) GetTokens(target TokenTargetHeader) (*GetTokensResponse, error) {
    90  
    91  	var retVal GetTokensResponse
    92  	req := rest.GetRequest(helpers.GetFullURL(*r.client.Config.Endpoint, "/api/v1/tokens"))
    93  
    94  	for key, value := range target.ToMap() {
    95  		req.Set(key, value)
    96  	}
    97  
    98  	_, err := r.client.SendRequest(req, &retVal)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	return &retVal, err
   103  }
   104  
   105  func getTokID(token string) (string, error) {
   106  	parts := strings.Split(token, ".")
   107  	if len(parts) != 3 {
   108  		return "", fmt.Errorf("Corrupt Token, not enough parts")
   109  	}
   110  	decodedBytes, decerr := base64.RawStdEncoding.DecodeString(parts[1])
   111  	if decerr != nil {
   112  		return "", fmt.Errorf("Corrupt Token, could not decode, error: %v", decerr)
   113  	}
   114  	jwtID := struct {
   115  		ID string `json:"jti"`
   116  	}{""}
   117  	jerr := json.Unmarshal(decodedBytes, &jwtID)
   118  	if jerr != nil {
   119  		return "", fmt.Errorf("Corrupt Token, could not decode, error: %v", jerr)
   120  	}
   121  	return jwtID.ID, nil
   122  }
   123  
   124  //GetToken ...
   125  func (r *tokens) GetToken(tokenUUID string, target TokenTargetHeader) (*TokenResponse, error) {
   126  
   127  	var retVal TokenResponse
   128  	req := rest.GetRequest(helpers.GetFullURL(*r.client.Config.Endpoint, fmt.Sprintf("/api/v1/tokens/%s", tokenUUID)))
   129  
   130  	for key, value := range target.ToMap() {
   131  		req.Set(key, value)
   132  	}
   133  
   134  	_, err := r.client.SendRequest(req, &retVal)
   135  	if err == nil {
   136  		retVal.ID = tokenUUID
   137  	} else {
   138  		return nil, err
   139  	}
   140  	return &retVal, err
   141  }
   142  
   143  //Add ...
   144  func (r *tokens) IssueToken(params IssueTokenRequest, target TokenTargetHeader) (*TokenResponse, error) {
   145  
   146  	var retVal TokenResponse
   147  	req := rest.PostRequest(helpers.GetFullURL(*r.client.Config.Endpoint, "/api/v1/tokens")).
   148  		Query("description", params.Description).
   149  		Query("permanent", strconv.FormatBool(params.Permanent)).
   150  		Query("write", strconv.FormatBool(params.Permanent))
   151  
   152  	for key, value := range target.ToMap() {
   153  		req.Set(key, value)
   154  	}
   155  
   156  	_, err := r.client.SendRequest(req, &retVal)
   157  	if err == nil {
   158  		retVal.ID, err = getTokID(retVal.Token)
   159  	} else {
   160  		return nil, err
   161  	}
   162  	return &retVal, err
   163  }
   164  
   165  //Delete...
   166  func (r *tokens) DeleteToken(tokenUUID string, target TokenTargetHeader) error {
   167  	req := rest.DeleteRequest(helpers.GetFullURL(*r.client.Config.Endpoint, fmt.Sprintf("/api/v1/tokens/%s", tokenUUID)))
   168  
   169  	for key, value := range target.ToMap() {
   170  		req.Set(key, value)
   171  	}
   172  
   173  	_, err := r.client.SendRequest(req, nil)
   174  	return err
   175  }
   176  
   177  //Delete By Description
   178  func (r *tokens) DeleteTokenByDescription(tokenDescription string, target TokenTargetHeader) error {
   179  	req := rest.DeleteRequest(helpers.GetFullURL(*r.client.Config.Endpoint, "/api/v1/tokens")).
   180  		Query("secondaryOwner", tokenDescription)
   181  
   182  	for key, value := range target.ToMap() {
   183  		req.Set(key, value)
   184  	}
   185  
   186  	_, err := r.client.SendRequest(req, nil)
   187  	return err
   188  }