From d529853b9d54f96a6169fb3a7d00ed580721ab47 Mon Sep 17 00:00:00 2001 From: Marco Slaviero Date: Thu, 16 Sep 2021 15:34:40 +0200 Subject: [PATCH] Add scope support to the tokens create command Signed-off-by: Marco Slaviero --- internal/commands/token/create.go | 22 +++++++++++++++++++++- internal/commands/token/list.go | 6 ++++++ pkg/hub/tokens.go | 19 +++++++++++++++---- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/internal/commands/token/create.go b/internal/commands/token/create.go index 57656e2..2a6afff 100644 --- a/internal/commands/token/create.go +++ b/internal/commands/token/create.go @@ -17,6 +17,7 @@ package token import ( + "errors" "fmt" "io" @@ -38,6 +39,19 @@ type createOptions struct { format.Option description string quiet bool + scope string +} + +func validScope(scope string) bool { + switch scope { + case + "admin", + "write", + "read", + "public_read": + return true + } + return false } func newCreateCmd(streams command.Streams, hubClient *hub.Client, parent string) *cobra.Command { @@ -54,17 +68,23 @@ func newCreateCmd(streams command.Streams, hubClient *hub.Client, parent string) metrics.Send(parent, createName) }, RunE: func(_ *cobra.Command, args []string) error { + return runCreate(streams, hubClient, opts) }, } opts.AddFormatFlag(cmd.Flags()) cmd.Flags().StringVar(&opts.description, "description", "", "Set token's description") cmd.Flags().BoolVar(&opts.quiet, "quiet", false, "Display only created token") + cmd.Flags().StringVar(&opts.scope, "scope", "", "Set token's repo scope (admin,write,read,public_read)") + return cmd } func runCreate(streams command.Streams, hubClient *hub.Client, opts createOptions) error { - token, err := hubClient.CreateToken(opts.description) + if len(opts.scope) > 0 && !validScope(opts.scope) { + return errors.New("scope must be one of admin,write,read,public_read") + } + token, err := hubClient.CreateToken(opts.description, opts.scope) if err != nil { return err } diff --git a/internal/commands/token/list.go b/internal/commands/token/list.go index 8a6bac3..91b6d74 100644 --- a/internal/commands/token/list.go +++ b/internal/commands/token/list.go @@ -56,6 +56,12 @@ var ( s := fmt.Sprintf("%v", t.IsActive) return s, len(s) }}, + {"SCOPE", func(t hub.Token) (string, int) { + if len(t.Scopes) == 0 { + return "", 0 + } + return t.Scopes[0][5:], len(t.Scopes[0]) - 5 + }}, } ) diff --git a/pkg/hub/tokens.go b/pkg/hub/tokens.go index a283de1..ecc5b14 100644 --- a/pkg/hub/tokens.go +++ b/pkg/hub/tokens.go @@ -46,11 +46,19 @@ type Token struct { IsActive bool Token string Description string + Scopes []string } // CreateToken creates a Personal Access Token and returns the token field only once -func (c *Client) CreateToken(description string) (*Token, error) { - data, err := json.Marshal(hubTokenRequest{Description: description}) +func (c *Client) CreateToken(description string, scope string) (*Token, error) { + tokenRequest := hubTokenRequest{Description: description} + if len(scope) > 0 { + scopes := []string{scope} + scopes[0] = "repo:" + scope + tokenRequest.Scopes = scopes + } + + data, err := json.Marshal(tokenRequest) if err != nil { return nil, err } @@ -190,8 +198,9 @@ func (c *Client) getTokensPage(url string) ([]Token, int, string, error) { } type hubTokenRequest struct { - Description string `json:"token_label,omitempty"` - IsActive bool `json:"is_active"` + Description string `json:"token_label,omitempty"` + Scopes []string `json:"scopes,omitempty"` + IsActive bool `json:"is_active"` } type hubTokenResponse struct { @@ -212,6 +221,7 @@ type hubTokenResult struct { IsActive bool `json:"is_active"` Token string `json:"token"` TokenLabel string `json:"token_label"` + Scopes []string `json:"scopes"` } func convertToken(response hubTokenResult) (Token, error) { @@ -230,5 +240,6 @@ func convertToken(response hubTokenResult) (Token, error) { IsActive: response.IsActive, Token: response.Token, Description: response.TokenLabel, + Scopes: response.Scopes, }, nil }