Skip to content

Commit ef09103

Browse files
committed
added flag for name
1 parent 740c4a2 commit ef09103

21 files changed

+112
-30
lines changed

cli/tokens.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,22 @@ func tokens() *cobra.Command {
4949
}
5050

5151
func createToken() *cobra.Command {
52-
var tokenLifetime time.Duration
52+
var (
53+
tokenLifetime time.Duration
54+
name string
55+
)
5356
cmd := &cobra.Command{
5457
Use: "create",
55-
Short: "Create a tokens",
58+
Short: "Create a token",
5659
RunE: func(cmd *cobra.Command, args []string) error {
5760
client, err := CreateClient(cmd)
5861
if err != nil {
5962
return xerrors.Errorf("create codersdk client: %w", err)
6063
}
6164

6265
res, err := client.CreateToken(cmd.Context(), codersdk.Me, codersdk.CreateTokenRequest{
63-
Lifetime: tokenLifetime,
66+
Lifetime: tokenLifetime,
67+
TokenName: name,
6468
})
6569
if err != nil {
6670
return xerrors.Errorf("create tokens: %w", err)
@@ -81,6 +85,7 @@ func createToken() *cobra.Command {
8185
}
8286

8387
cliflag.DurationVarP(cmd.Flags(), &tokenLifetime, "lifetime", "", "CODER_TOKEN_LIFETIME", 30*24*time.Hour, "Specify a duration for the lifetime of the token.")
88+
cmd.Flags().StringVarP(&name, "name", "n", "", "Specify a human-readable name.")
8489

8590
return cmd
8691
}
@@ -92,6 +97,7 @@ type tokenListRow struct {
9297

9398
// For table format:
9499
ID string `json:"-" table:"id,default_sort"`
100+
TokenName string `json:"token_name" table:"name"`
95101
LastUsed time.Time `json:"-" table:"last used"`
96102
ExpiresAt time.Time `json:"-" table:"expires at"`
97103
CreatedAt time.Time `json:"-" table:"created at"`
@@ -102,6 +108,7 @@ func tokenListRowFromToken(token codersdk.ConvertedAPIKey) tokenListRow {
102108
return tokenListRow{
103109
APIKey: token.APIKey,
104110
ID: token.ID,
111+
TokenName: token.TokenName,
105112
LastUsed: token.LastUsed,
106113
ExpiresAt: token.ExpiresAt,
107114
CreatedAt: token.CreatedAt,
@@ -111,7 +118,7 @@ func tokenListRowFromToken(token codersdk.ConvertedAPIKey) tokenListRow {
111118

112119
func listTokens() *cobra.Command {
113120
// we only display the 'owner' column if the --all argument is passed in
114-
defaultCols := []string{"id", "last used", "expires at", "created at"}
121+
defaultCols := []string{"id", "name", "last used", "expires at", "created at"}
115122
if slices.Contains(os.Args, "-a") || slices.Contains(os.Args, "--all") {
116123
defaultCols = append(defaultCols, "owner")
117124
}

coderd/apidoc/docs.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apikey.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import (
99
"net"
1010
"net/http"
1111
"strconv"
12+
"strings"
1213
"time"
1314

1415
"github.com/go-chi/chi/v5"
1516
"github.com/google/uuid"
17+
"github.com/moby/moby/pkg/namesgenerator"
1618
"github.com/tabbed/pqtype"
1719
"golang.org/x/xerrors"
1820

@@ -62,6 +64,12 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
6264
lifeTime = createToken.Lifetime
6365
}
6466

67+
tokenName := namesgenerator.GetRandomName(1)
68+
69+
if len(createToken.TokenName) != 0 {
70+
tokenName = createToken.TokenName
71+
}
72+
6573
err := api.validateAPIKeyLifetime(lifeTime)
6674
if err != nil {
6775
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
@@ -77,8 +85,18 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
7785
ExpiresAt: database.Now().Add(lifeTime),
7886
Scope: scope,
7987
LifetimeSeconds: int64(lifeTime.Seconds()),
88+
TokenName: tokenName,
8089
})
8190
if err != nil {
91+
if strings.Contains(err.Error(), "duplicate key value violates unique constraint") {
92+
httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{
93+
Message: fmt.Sprintf("A token with name %q already exists.", tokenName),
94+
Validations: []codersdk.ValidationError{{
95+
Field: "name",
96+
Detail: "This value is already in use and should be unique.",
97+
}},
98+
})
99+
}
82100
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
83101
Message: "Failed to create API key.",
84102
Detail: err.Error(),
@@ -295,6 +313,7 @@ type createAPIKeyParams struct {
295313
ExpiresAt time.Time
296314
LifetimeSeconds int64
297315
Scope database.APIKeyScope
316+
TokenName string
298317
}
299318

300319
func (api *API) validateAPIKeyLifetime(lifetime time.Duration) error {
@@ -364,6 +383,7 @@ func (api *API) createAPIKey(ctx context.Context, params createAPIKeyParams) (*h
364383
HashedSecret: hashed[:],
365384
LoginType: params.LoginType,
366385
Scope: scope,
386+
TokenName: params.TokenName,
367387
})
368388
if err != nil {
369389
return nil, nil, xerrors.Errorf("insert API key: %w", err)

coderd/database/dump.sql

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE ONLY api_keys
2+
DROP COLUMN IF EXISTS token_name,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ALTER TABLE ONLY api_keys
2+
ADD COLUMN IF NOT EXISTS token_name text NOT NULL UNIQUE DEFAULT '';
3+

coderd/database/models.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 14 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/apikeys.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ INSERT INTO
3030
created_at,
3131
updated_at,
3232
login_type,
33-
scope
33+
scope,
34+
token_name
3435
)
3536
VALUES
3637
(@id,
@@ -39,7 +40,7 @@ VALUES
3940
WHEN 0 THEN 86400
4041
ELSE @lifetime_seconds::bigint
4142
END
42-
, @hashed_secret, @ip_address, @user_id, @last_used, @expires_at, @created_at, @updated_at, @login_type, @scope) RETURNING *;
43+
, @hashed_secret, @ip_address, @user_id, @last_used, @expires_at, @created_at, @updated_at, @login_type, @scope, @token_name) RETURNING *;
4344

4445
-- name: UpdateAPIKeyByID :exec
4546
UPDATE

coderd/database/unique_constraint.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/users.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,5 +1231,6 @@ func convertAPIKey(k database.APIKey) codersdk.APIKey {
12311231
LoginType: codersdk.LoginType(k.LoginType),
12321232
Scope: codersdk.APIKeyScope(k.Scope),
12331233
LifetimeSeconds: k.LifetimeSeconds,
1234+
TokenName: k.TokenName,
12341235
}
12351236
}

codersdk/apikey.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type APIKey struct {
2020
UpdatedAt time.Time `json:"updated_at" validate:"required" format:"date-time"`
2121
LoginType LoginType `json:"login_type" validate:"required" enums:"password,github,oidc,token"`
2222
Scope APIKeyScope `json:"scope" validate:"required" enums:"all,application_connect"`
23+
TokenName string `json:"token_name" validate:"required"`
2324
LifetimeSeconds int64 `json:"lifetime_seconds" validate:"required"`
2425
}
2526

@@ -44,8 +45,9 @@ const (
4445
)
4546

4647
type CreateTokenRequest struct {
47-
Lifetime time.Duration `json:"lifetime"`
48-
Scope APIKeyScope `json:"scope" enums:"all,application_connect"`
48+
Lifetime time.Duration `json:"lifetime"`
49+
Scope APIKeyScope `json:"scope" enums:"all,application_connect"`
50+
TokenName string `json:"token_name"`
4951
}
5052

5153
// GenerateAPIKeyResponse contains an API key for a user.

0 commit comments

Comments
 (0)