diff --git a/internal/commands/root.go b/internal/commands/root.go index 4ecebedb3..3fca235e7 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -242,6 +242,7 @@ func NewAstCLI( ) configCmd := util.NewConfigCommand() + whoamiCmd := NewWhoamiCommand() triageCmd := NewResultsPredicatesCommand(resultsPredicatesWrapper, featureFlagsWrapper, customStatesWrapper) chatCmd := NewChatCommand(chatWrapper, tenantWrapper) @@ -257,6 +258,7 @@ func NewAstCLI( authCmd, utilsCmd, configCmd, + whoamiCmd, chatCmd, hooksCmd, telemetryCmd, diff --git a/internal/commands/whoami.go b/internal/commands/whoami.go new file mode 100644 index 000000000..662f2928f --- /dev/null +++ b/internal/commands/whoami.go @@ -0,0 +1,72 @@ +package commands + +import ( + "github.com/MakeNowJust/heredoc" + "github.com/checkmarx/ast-cli/internal/commands/util/printer" + "github.com/checkmarx/ast-cli/internal/wrappers" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +const ( + whoamiTenantClaimKey = "tenant_name" + whoamiUserClaimKey = "name" + whoamiUserFallbackClaimKey = "sub" +) + +type whoamiView struct { + User string `json:"user" format:"name:User"` + Tenant string `json:"tenant" format:"name:Tenant"` +} + +func NewWhoamiCommand() *cobra.Command { + whoamiCmd := &cobra.Command{ + Use: "whoami", + Short: "Show authenticated user and tenant information", + Long: "The whoami command shows authenticated user and tenant information from the current access token", + Example: heredoc.Doc( + ` + $ cx whoami + `, + ), + RunE: runWhoami, + } + + addFormatFlag(whoamiCmd, printer.FormatList, printer.FormatJSON, printer.FormatTable) + return whoamiCmd +} + +func runWhoami(cmd *cobra.Command, _ []string) error { + accessToken, err := wrappers.GetAccessToken() + if err != nil { + return err + } + + user, err := extractWhoamiUser(accessToken) + if err != nil { + return errors.Wrap(err, "failed to extract authenticated user from token") + } + + tenant, err := wrappers.ExtractFromTokenClaims(accessToken, whoamiTenantClaimKey) + if err != nil { + return errors.Wrap(err, "failed to extract tenant from token") + } + + return printByFormat(cmd, whoamiView{ + User: user, + Tenant: tenant, + }) +} + +func extractWhoamiUser(accessToken string) (string, error) { + claimKeys := []string{whoamiUserClaimKey, whoamiUserFallbackClaimKey} + var err error + for _, claimKey := range claimKeys { + var user string + user, err = wrappers.ExtractFromTokenClaims(accessToken, claimKey) + if err == nil { + return user, nil + } + } + return "", err +}