Skip to content

Commit

Permalink
Parse token on client side, add --token-only flag
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Etchells <tetchell@redhat.com>
  • Loading branch information
tetchel committed Oct 25, 2020
1 parent dd6c991 commit ffb42bc
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 161 deletions.
7 changes: 0 additions & 7 deletions assets/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -2829,13 +2829,6 @@
"description": "ProjectTokenResponse wraps the created token or returns an empty string if deleted.",
"type": "object",
"properties": {
"expiresAt": {
"type": "string",
"format": "int64"
},
"id": {
"type": "string"
},
"token": {
"type": "string"
}
Expand Down
46 changes: 36 additions & 10 deletions cmd/argocd/commands/project_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/argoproj/gitops-engine/pkg/utils/errors"
"github.com/argoproj/gitops-engine/pkg/utils/io"
timeutil "github.com/argoproj/pkg/time"
jwtgo "github.com/dgrijalva/jwt-go"
"github.com/spf13/cobra"

argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
Expand Down Expand Up @@ -196,11 +197,20 @@ func NewProjectRoleDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.
return command
}

func tokenTimeToString(t int64) string {
tokenTimeToString := "Never"
if t > 0 {
tokenTimeToString = time.Unix(t, 0).Format(time.RFC3339)
}
return tokenTimeToString
}

// NewProjectRoleCreateTokenCommand returns a new instance of an `argocd proj role create-token` command
func NewProjectRoleCreateTokenCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
expiresIn string
tokenID string
expiresIn string
outputTokenOnly bool
tokenID string
)
var command = &cobra.Command{
Use: "create-token PROJECT ROLE-NAME",
Expand All @@ -227,22 +237,38 @@ func NewProjectRoleCreateTokenCommand(clientOpts *argocdclient.ClientOptions) *c
})
errors.CheckError(err)

fmt.Printf("Created token succeeded.\n Project: %s\n Role: %s\n", projName, roleName)
token, err := jwtgo.Parse(tokenResponse.Token, nil)
if token == nil {
err = fmt.Errorf("received malformed token %v", err)
errors.CheckError(err)
return
}

if tokenResponse.Id != "" {
expiresAtString := "Never"
if tokenResponse.ExpiresAt > 0 {
expiresAtString = time.Unix(tokenResponse.ExpiresAt, 0).Format(time.RFC3339)
}
fmt.Printf(" ID: %s\n Expires At: %s\n", tokenResponse.Id, expiresAtString)
claims := token.Claims.(jwtgo.MapClaims)
issuedAt := int64(claims["iat"].(float64))
expiresAt := int64(0)
if expires, ok := claims["exp"]; ok {
expiresAt = int64(expires.(float64))
}
id := claims["jti"].(string)
subject := claims["sub"].(string)

if !outputTokenOnly {
fmt.Printf("Create token succeeded for %s.\n", subject)
fmt.Printf(" ID: %s\n Issued At: %s\n Expires At: %s\n",
id, tokenTimeToString(issuedAt), tokenTimeToString(expiresAt),
)
fmt.Println(" Token: " + tokenResponse.Token)
} else {
fmt.Println(tokenResponse.Token)
}
fmt.Println(" Token: " + tokenResponse.Token)
},
}
command.Flags().StringVarP(&expiresIn, "expires-in", "e", "",
"Duration before the token will expire, eg \"12h\", \"7d\". (Default: No expiration)",
)
command.Flags().StringVarP(&tokenID, "id", "i", "", "Token unique identifier. (Default: Random UUID)")
command.Flags().BoolVarP(&outputTokenOnly, "token-only", "t", false, "Output token only - for use in scripts.")

return command
}
Expand Down
1 change: 1 addition & 0 deletions docs/user-guide/commands/argocd_proj_role_create-token.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ argocd proj role create-token PROJECT ROLE-NAME [flags]
-e, --expires-in string Duration before the token will expire, eg "12h", "7d". (Default: No expiration)
-h, --help help for create-token
-i, --id string Token unique identifier. (Default: Random UUID)
-t, --token-only Output token only - for use in scripts.
```

### Options inherited from parent commands
Expand Down
191 changes: 52 additions & 139 deletions pkg/apiclient/project/project.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion server/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (s *Server) CreateToken(ctx context.Context, q *project.ProjectTokenCreateR
return nil, err
}
s.logEvent(prj, ctx, argo.EventReasonResourceCreated, "created token")
return &project.ProjectTokenResponse{ExpiresAt: expiresAt, Id: id, Token: jwtToken}, nil
return &project.ProjectTokenResponse{Token: jwtToken}, nil

}

Expand Down
7 changes: 3 additions & 4 deletions server/project/project.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ message ProjectTokenDeleteRequest {
string id = 4;
}

// ProjectTokenCreateRequest defines project token creation parameters.
// ProjectTokenCreateRequest defines project token creation parameters.
message ProjectTokenCreateRequest {
string project = 1;
string description = 2;
Expand All @@ -39,10 +39,9 @@ message ProjectTokenCreateRequest {
// ProjectTokenResponse wraps the created token or returns an empty string if deleted.
message ProjectTokenResponse {
string token = 1;
int64 expiresAt = 2;
string id = 3;
}


// ProjectQuery is a query for Project resources
message ProjectQuery {
string name = 1;
Expand Down Expand Up @@ -118,4 +117,4 @@ service ProjectService {
rpc GetSyncWindowsState(SyncWindowsQuery) returns (SyncWindowsResponse) {
option (google.api.http).get = "/api/v1/projects/{name}/syncwindows";
}
}
}

0 comments on commit ffb42bc

Please sign in to comment.