feat: add flag to see all tokens if owner (#6227)

* added query for tokens by user id

* updated query args

* adding owner col

* fix request params

* update-golden-files

* added owners col to ls table output

* added ttoken translations

* prettier

* format table according to arg

* using slice.Contains

* refactored token state

* cleanup
This commit is contained in:
Kira Pilot
2023-02-23 07:00:27 -08:00
committed by GitHub
parent 7a52a9cfc8
commit a32169ccb5
22 changed files with 348 additions and 214 deletions
+4 -1
View File
@@ -7,8 +7,11 @@ Aliases:
list, ls
Flags:
-a, --all Specifies whether all users' tokens will be listed or not (must have
Owner role to see all tokens).
-c, --column strings Columns to display in table output. Available columns: id, last used,
expires at, created at (default [id,last used,expires at,created at])
expires at, created at, owner (default [id,last used,expires
at,created at])
-h, --help help for list
-o, --output string Output format. Available formats: table, json (default "table")
+68 -9
View File
@@ -2,10 +2,13 @@ package cli
import (
"fmt"
"os"
"strings"
"time"
"github.com/google/uuid"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"github.com/coder/coder/cli/cliflag"
@@ -83,12 +86,47 @@ func createToken() *cobra.Command {
return cmd
}
func listTokens() *cobra.Command {
formatter := cliui.NewOutputFormatter(
cliui.TableFormat([]codersdk.APIKey{}, nil),
cliui.JSONFormat(),
)
// tokenListRow is the type provided to the OutputFormatter.
type tokenListRow struct {
// For JSON format:
codersdk.APIKey `table:"-"`
// For table format:
ID string `json:"-" table:"id,default_sort"`
LastUsed time.Time `json:"-" table:"last used"`
ExpiresAt time.Time `json:"-" table:"expires at"`
CreatedAt time.Time `json:"-" table:"created at"`
Owner string `json:"-" table:"owner"`
}
func tokenListRowFromToken(token codersdk.APIKey, usersByID map[uuid.UUID]codersdk.User) tokenListRow {
user := usersByID[token.UserID]
return tokenListRow{
APIKey: token,
ID: token.ID,
LastUsed: token.LastUsed,
ExpiresAt: token.ExpiresAt,
CreatedAt: token.CreatedAt,
Owner: user.Username,
}
}
func listTokens() *cobra.Command {
// we only display the 'owner' column if the --all argument is passed in
defaultCols := []string{"id", "last used", "expires at", "created at"}
if slices.Contains(os.Args, "-a") || slices.Contains(os.Args, "--all") {
defaultCols = append(defaultCols, "owner")
}
var (
all bool
displayTokens []tokenListRow
formatter = cliui.NewOutputFormatter(
cliui.TableFormat([]tokenListRow{}, defaultCols),
cliui.JSONFormat(),
)
)
cmd := &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
@@ -99,18 +137,36 @@ func listTokens() *cobra.Command {
return xerrors.Errorf("create codersdk client: %w", err)
}
keys, err := client.Tokens(cmd.Context(), codersdk.Me)
tokens, err := client.Tokens(cmd.Context(), codersdk.Me, codersdk.TokensFilter{
IncludeAll: all,
})
if err != nil {
return xerrors.Errorf("create tokens: %w", err)
return xerrors.Errorf("list tokens: %w", err)
}
if len(keys) == 0 {
if len(tokens) == 0 {
cmd.Println(cliui.Styles.Wrap.Render(
"No tokens found.",
))
}
out, err := formatter.Format(cmd.Context(), keys)
userRes, err := client.Users(cmd.Context(), codersdk.UsersRequest{})
if err != nil {
return err
}
usersByID := map[uuid.UUID]codersdk.User{}
for _, user := range userRes.Users {
usersByID[user.ID] = user
}
displayTokens = make([]tokenListRow, len(tokens))
for i, token := range tokens {
displayTokens[i] = tokenListRowFromToken(token, usersByID)
}
out, err := formatter.Format(cmd.Context(), displayTokens)
if err != nil {
return err
}
@@ -120,6 +176,9 @@ func listTokens() *cobra.Command {
},
}
cmd.Flags().BoolVarP(&all, "all", "a", false,
"Specifies whether all users' tokens will be listed or not (must have Owner role to see all tokens).")
formatter.AttachFlags(cmd)
return cmd
}