Skip to content

feat: add ability to name tokens #6365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2a103b3
add tokens switch
Kira-Pilot Feb 23, 2023
6402745
reorged TokensPage
Kira-Pilot Feb 23, 2023
340a9d1
using Trans component for description
Kira-Pilot Feb 23, 2023
ff2ac68
using Trans component on DeleteDialog
Kira-Pilot Feb 23, 2023
ade9548
add owner col
Kira-Pilot Feb 23, 2023
dd587e8
simplify hook return
Kira-Pilot Feb 23, 2023
2ce518c
lint
Kira-Pilot Feb 24, 2023
740c4a2
type for response
Kira-Pilot Feb 24, 2023
ef09103
added flag for name
Kira-Pilot Feb 27, 2023
20fc87c
fixed auth
Kira-Pilot Feb 27, 2023
f399fb8
lint, prettier, tests
Kira-Pilot Feb 27, 2023
eda2702
Merge remote-tracking branch 'origin/main' into name-tokens/kira-pilot
Kira-Pilot Feb 28, 2023
5963708
added unique index for login type token
Kira-Pilot Feb 28, 2023
187f812
remove tokens by name
Kira-Pilot Feb 28, 2023
3609057
better check for unique constraint
Kira-Pilot Feb 28, 2023
b824bca
docs
Kira-Pilot Mar 1, 2023
621ee44
Merge remote-tracking branch 'origin/main' into name-tokens/kira-pilot
Kira-Pilot Mar 1, 2023
269f2ba
test: Fix dbfake to insert token name
Emyrk Mar 1, 2023
dd01f53
fix doc tests
Kira-Pilot Mar 1, 2023
e8d519f
Update cli/tokens.go
Kira-Pilot Mar 2, 2023
4c974c4
Update coderd/database/migrations/000102_add_apikey_name.down.sql
Kira-Pilot Mar 2, 2023
4bf374d
add more specificity to IsUniqueViolation check
Kira-Pilot Mar 2, 2023
07acbff
fix tests
Kira-Pilot Mar 2, 2023
aa779d9
Fix AutorizeAllEndpoints
Emyrk Mar 2, 2023
c33361b
Merge remote-tracking branch 'origin/main' into name-tokens/kira-pilot
Kira-Pilot Mar 2, 2023
6cd9329
rename migration
Kira-Pilot Mar 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
added flag for name
  • Loading branch information
Kira-Pilot committed Feb 27, 2023
commit ef09103d62a93dd2859a7c0b06cd8041facb5136
15 changes: 11 additions & 4 deletions cli/tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,22 @@ func tokens() *cobra.Command {
}

func createToken() *cobra.Command {
var tokenLifetime time.Duration
var (
tokenLifetime time.Duration
name string
)
cmd := &cobra.Command{
Use: "create",
Short: "Create a tokens",
Short: "Create a token",
RunE: func(cmd *cobra.Command, args []string) error {
client, err := CreateClient(cmd)
if err != nil {
return xerrors.Errorf("create codersdk client: %w", err)
}

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

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

return cmd
}
Expand All @@ -92,6 +97,7 @@ type tokenListRow struct {

// For table format:
ID string `json:"-" table:"id,default_sort"`
TokenName string `json:"token_name" table:"name"`
LastUsed time.Time `json:"-" table:"last used"`
ExpiresAt time.Time `json:"-" table:"expires at"`
CreatedAt time.Time `json:"-" table:"created at"`
Expand All @@ -102,6 +108,7 @@ func tokenListRowFromToken(token codersdk.ConvertedAPIKey) tokenListRow {
return tokenListRow{
APIKey: token.APIKey,
ID: token.ID,
TokenName: token.TokenName,
LastUsed: token.LastUsed,
ExpiresAt: token.ExpiresAt,
CreatedAt: token.CreatedAt,
Expand All @@ -111,7 +118,7 @@ func tokenListRowFromToken(token codersdk.ConvertedAPIKey) tokenListRow {

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"}
defaultCols := []string{"id", "name", "last used", "expires at", "created at"}
if slices.Contains(os.Args, "-a") || slices.Contains(os.Args, "--all") {
defaultCols = append(defaultCols, "owner")
}
Expand Down
7 changes: 7 additions & 0 deletions coderd/apidoc/docs.go

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

7 changes: 7 additions & 0 deletions coderd/apidoc/swagger.json

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

20 changes: 20 additions & 0 deletions coderd/apikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import (
"net"
"net/http"
"strconv"
"strings"
"time"

"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"github.com/moby/moby/pkg/namesgenerator"
"github.com/tabbed/pqtype"
"golang.org/x/xerrors"

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

tokenName := namesgenerator.GetRandomName(1)

if len(createToken.TokenName) != 0 {
tokenName = createToken.TokenName
}

err := api.validateAPIKeyLifetime(lifeTime)
if err != nil {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Expand All @@ -77,8 +85,18 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
ExpiresAt: database.Now().Add(lifeTime),
Scope: scope,
LifetimeSeconds: int64(lifeTime.Seconds()),
TokenName: tokenName,
})
if err != nil {
if strings.Contains(err.Error(), "duplicate key value violates unique constraint") {
httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{
Message: fmt.Sprintf("A token with name %q already exists.", tokenName),
Validations: []codersdk.ValidationError{{
Field: "name",
Detail: "This value is already in use and should be unique.",
}},
})
}
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to create API key.",
Detail: err.Error(),
Expand Down Expand Up @@ -295,6 +313,7 @@ type createAPIKeyParams struct {
ExpiresAt time.Time
LifetimeSeconds int64
Scope database.APIKeyScope
TokenName string
}

func (api *API) validateAPIKeyLifetime(lifetime time.Duration) error {
Expand Down Expand Up @@ -364,6 +383,7 @@ func (api *API) createAPIKey(ctx context.Context, params createAPIKeyParams) (*h
HashedSecret: hashed[:],
LoginType: params.LoginType,
Scope: scope,
TokenName: params.TokenName,
})
if err != nil {
return nil, nil, xerrors.Errorf("insert API key: %w", err)
Expand Down
6 changes: 5 additions & 1 deletion coderd/database/dump.sql

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

2 changes: 2 additions & 0 deletions coderd/database/migrations/000100_add_apikey_name.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE ONLY api_keys
DROP COLUMN IF EXISTS token_name,
3 changes: 3 additions & 0 deletions coderd/database/migrations/000100_add_apikey_name.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE ONLY api_keys
ADD COLUMN IF NOT EXISTS token_name text NOT NULL UNIQUE DEFAULT '';

1 change: 1 addition & 0 deletions coderd/database/models.go

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

20 changes: 14 additions & 6 deletions coderd/database/queries.sql.go

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

5 changes: 3 additions & 2 deletions coderd/database/queries/apikeys.sql
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ INSERT INTO
created_at,
updated_at,
login_type,
scope
scope,
token_name
)
VALUES
(@id,
Expand All @@ -39,7 +40,7 @@ VALUES
WHEN 0 THEN 86400
ELSE @lifetime_seconds::bigint
END
, @hashed_secret, @ip_address, @user_id, @last_used, @expires_at, @created_at, @updated_at, @login_type, @scope) RETURNING *;
, @hashed_secret, @ip_address, @user_id, @last_used, @expires_at, @created_at, @updated_at, @login_type, @scope, @token_name) RETURNING *;

-- name: UpdateAPIKeyByID :exec
UPDATE
Expand Down
1 change: 1 addition & 0 deletions coderd/database/unique_constraint.go

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

1 change: 1 addition & 0 deletions coderd/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -1231,5 +1231,6 @@ func convertAPIKey(k database.APIKey) codersdk.APIKey {
LoginType: codersdk.LoginType(k.LoginType),
Scope: codersdk.APIKeyScope(k.Scope),
LifetimeSeconds: k.LifetimeSeconds,
TokenName: k.TokenName,
}
}
6 changes: 4 additions & 2 deletions codersdk/apikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type APIKey struct {
UpdatedAt time.Time `json:"updated_at" validate:"required" format:"date-time"`
LoginType LoginType `json:"login_type" validate:"required" enums:"password,github,oidc,token"`
Scope APIKeyScope `json:"scope" validate:"required" enums:"all,application_connect"`
TokenName string `json:"token_name" validate:"required"`
LifetimeSeconds int64 `json:"lifetime_seconds" validate:"required"`
}

Expand All @@ -44,8 +45,9 @@ const (
)

type CreateTokenRequest struct {
Lifetime time.Duration `json:"lifetime"`
Scope APIKeyScope `json:"scope" enums:"all,application_connect"`
Lifetime time.Duration `json:"lifetime"`
Scope APIKeyScope `json:"scope" enums:"all,application_connect"`
TokenName string `json:"token_name"`
}

// GenerateAPIKeyResponse contains an API key for a user.
Expand Down
Loading