Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit67e03fa

Browse files
committed
chore: make cli session keys respect--session-duration
1 parent7ea8a22 commit67e03fa

File tree

14 files changed

+165
-38
lines changed

14 files changed

+165
-38
lines changed

‎cli/testdata/coder_server_--help.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ OPTIONS:
2525
systemd. This directory is NOT safe to be configured as a shared
2626
directory across coderd/provisionerd replicas.
2727

28+
--default-token-lifetime duration, $CODER_DEFAULT_TOKEN_LIFETIME (default: 168h0m0s)
29+
The default lifetime duration for API tokens. This value is used when
30+
creating a token without specifying a duration, such as when
31+
authenticating the CLI or an IDE plugin.
32+
2833
--disable-owner-workspace-access bool, $CODER_DISABLE_OWNER_WORKSPACE_ACCESS
2934
Remove the permission for the 'owner' role to have workspace execution
3035
on all workspaces. This prevents the 'owner' from ssh, apps, and

‎cli/testdata/server-config.yaml.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,11 @@ experiments: []
423423
# performed once per day.
424424
# (default: false, type: bool)
425425
updateCheck: false
426+
# The default lifetime duration for API tokens. This value is used when creating a
427+
# token without specifying a duration, such as when authenticating the CLI or an
428+
# IDE plugin.
429+
# (default: 168h0m0s, type: duration)
430+
defaultTokenLifetime: 168h0m0s
426431
# Expose the swagger endpoint via /swagger.
427432
# (default: <unset>, type: bool)
428433
enableSwagger: false

‎coderd/apidoc/docs.go

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apikey.go

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
"github.com/coder/coder/v2/codersdk"
2424
)
2525

26-
// Creates a new token API keythat effectively doesn't expire.
26+
// Creates a new token API keywith the given scope and lifetime.
2727
//
2828
// @Summary Create token API key
2929
// @ID create-token-api-key
@@ -60,36 +60,34 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
6060
scope=database.APIKeyScope(createToken.Scope)
6161
}
6262

63-
// default lifetime is 30 days
64-
lifeTime:=30*24*time.Hour
65-
ifcreateToken.Lifetime!=0 {
66-
lifeTime=createToken.Lifetime
67-
}
68-
6963
tokenName:=namesgenerator.GetRandomName(1)
7064

7165
iflen(createToken.TokenName)!=0 {
7266
tokenName=createToken.TokenName
7367
}
7468

75-
err:=api.validateAPIKeyLifetime(lifeTime)
76-
iferr!=nil {
77-
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
78-
Message:"Failed to validate create API key request.",
79-
Detail:err.Error(),
80-
})
81-
return
82-
}
83-
84-
cookie,key,err:=api.createAPIKey(ctx, apikey.CreateParams{
69+
params:= apikey.CreateParams{
8570
UserID:user.ID,
8671
LoginType:database.LoginTypeToken,
87-
DefaultLifetime:api.DeploymentValues.Sessions.DefaultDuration.Value(),
88-
ExpiresAt:dbtime.Now().Add(lifeTime),
72+
DefaultLifetime:api.DeploymentValues.Sessions.DefaultTokenDuration.Value(),
8973
Scope:scope,
90-
LifetimeSeconds:int64(lifeTime.Seconds()),
9174
TokenName:tokenName,
92-
})
75+
}
76+
77+
ifcreateToken.Lifetime!=0 {
78+
err:=api.validateAPIKeyLifetime(createToken.Lifetime)
79+
iferr!=nil {
80+
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
81+
Message:"Failed to validate create API key request.",
82+
Detail:err.Error(),
83+
})
84+
return
85+
}
86+
params.ExpiresAt=dbtime.Now().Add(createToken.Lifetime)
87+
params.LifetimeSeconds=int64(createToken.Lifetime.Seconds())
88+
}
89+
90+
cookie,key,err:=api.createAPIKey(ctx,params)
9391
iferr!=nil {
9492
ifdatabase.IsUniqueViolation(err,database.UniqueIndexAPIKeyName) {
9593
httpapi.Write(ctx,rw,http.StatusConflict, codersdk.Response{
@@ -125,16 +123,11 @@ func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) {
125123
ctx:=r.Context()
126124
user:=httpmw.UserParam(r)
127125

128-
lifeTime:=time.Hour*24*7
129126
cookie,_,err:=api.createAPIKey(ctx, apikey.CreateParams{
130127
UserID:user.ID,
131-
DefaultLifetime:api.DeploymentValues.Sessions.DefaultDuration.Value(),
128+
DefaultLifetime:api.DeploymentValues.Sessions.DefaultTokenDuration.Value(),
132129
LoginType:database.LoginTypePassword,
133130
RemoteAddr:r.RemoteAddr,
134-
// All api generated keys will last 1 week. Browser login tokens have
135-
// a shorter life.
136-
ExpiresAt:dbtime.Now().Add(lifeTime),
137-
LifetimeSeconds:int64(lifeTime.Seconds()),
138131
})
139132
iferr!=nil {
140133
httpapi.Write(ctx,rw,http.StatusInternalServerError, codersdk.Response{

‎coderd/apikey_test.go

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ func TestTokenCRUD(t *testing.T) {
4545
require.EqualValues(t,len(keys),1)
4646
require.Contains(t,res.Key,keys[0].ID)
4747
// expires_at should default to 30 days
48-
require.Greater(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*29*24))
49-
require.Less(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*31*24))
48+
require.Greater(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*24*6))
49+
require.Less(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*24*8))
5050
require.Equal(t,codersdk.APIKeyScopeAll,keys[0].Scope)
5151

5252
// no update
@@ -115,8 +115,8 @@ func TestDefaultTokenDuration(t *testing.T) {
115115
require.NoError(t,err)
116116
keys,err:=client.Tokens(ctx,codersdk.Me, codersdk.TokensFilter{})
117117
require.NoError(t,err)
118-
require.Greater(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*29*24))
119-
require.Less(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*31*24))
118+
require.Greater(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*24*6))
119+
require.Less(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*24*8))
120120
}
121121

122122
funcTestTokenUserSetMaxLifetime(t*testing.T) {
@@ -144,6 +144,27 @@ func TestTokenUserSetMaxLifetime(t *testing.T) {
144144
require.ErrorContains(t,err,"lifetime must be less")
145145
}
146146

147+
funcTestTokenUserSetDefaultLifetime(t*testing.T) {
148+
t.Parallel()
149+
150+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
151+
defercancel()
152+
dc:=coderdtest.DeploymentValues(t)
153+
dc.Sessions.DefaultTokenDuration=serpent.Duration(time.Hour*12)
154+
client:=coderdtest.New(t,&coderdtest.Options{
155+
DeploymentValues:dc,
156+
})
157+
_=coderdtest.CreateFirstUser(t,client)
158+
159+
_,err:=client.CreateToken(ctx,codersdk.Me, codersdk.CreateTokenRequest{})
160+
require.NoError(t,err)
161+
162+
tokens,err:=client.Tokens(ctx,codersdk.Me, codersdk.TokensFilter{})
163+
require.NoError(t,err)
164+
require.Len(t,tokens,1)
165+
require.EqualValues(t,dc.Sessions.DefaultTokenDuration.Value().Seconds(),tokens[0].LifetimeSeconds)
166+
}
167+
147168
funcTestSessionExpiry(t*testing.T) {
148169
t.Parallel()
149170

@@ -224,3 +245,66 @@ func TestAPIKey_Deleted(t *testing.T) {
224245
require.ErrorAs(t,err,&apiErr)
225246
require.Equal(t,http.StatusBadRequest,apiErr.StatusCode())
226247
}
248+
249+
funcTestAPIKey_Refresh(t*testing.T) {
250+
t.Parallel()
251+
252+
db,pubsub:=dbtestutil.NewDB(t)
253+
client:=coderdtest.New(t,&coderdtest.Options{
254+
Database:db,
255+
Pubsub:pubsub,
256+
})
257+
owner:=coderdtest.CreateFirstUser(t,client)
258+
259+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
260+
defercancel()
261+
262+
token,err:=client.CreateAPIKey(ctx,owner.UserID.String())
263+
require.NoError(t,err)
264+
split:=strings.Split(token.Key,"-")
265+
apiKey1,err:=db.GetAPIKeyByID(ctx,split[0])
266+
require.NoError(t,err)
267+
require.Equal(t,int64(604800),apiKey1.LifetimeSeconds,"default should be 7 days")
268+
269+
err=db.UpdateAPIKeyByID(ctx, database.UpdateAPIKeyByIDParams{
270+
ID:apiKey1.ID,
271+
LastUsed:apiKey1.LastUsed,
272+
// Cross the no-refresh threshold
273+
ExpiresAt:apiKey1.ExpiresAt.Add(time.Hour*-2),
274+
IPAddress:apiKey1.IPAddress,
275+
})
276+
require.NoError(t,err,"update login key")
277+
278+
// Refresh the token
279+
client.SetSessionToken(token.Key)
280+
_,err=client.User(ctx,codersdk.Me)
281+
require.NoError(t,err)
282+
283+
apiKey2,err:=client.APIKeyByID(ctx,owner.UserID.String(),split[0])
284+
require.NoError(t,err)
285+
require.True(t,apiKey2.ExpiresAt.After(apiKey1.ExpiresAt),"token should have a later expiry")
286+
}
287+
288+
funcTestAPIKey_SetDefault(t*testing.T) {
289+
t.Parallel()
290+
291+
db,pubsub:=dbtestutil.NewDB(t)
292+
dc:=coderdtest.DeploymentValues(t)
293+
dc.Sessions.DefaultTokenDuration=serpent.Duration(time.Hour*12)
294+
client:=coderdtest.New(t,&coderdtest.Options{
295+
Database:db,
296+
Pubsub:pubsub,
297+
DeploymentValues:dc,
298+
})
299+
owner:=coderdtest.CreateFirstUser(t,client)
300+
301+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
302+
defercancel()
303+
304+
token,err:=client.CreateAPIKey(ctx,owner.UserID.String())
305+
require.NoError(t,err)
306+
split:=strings.Split(token.Key,"-")
307+
apiKey1,err:=db.GetAPIKeyByID(ctx,split[0])
308+
require.NoError(t,err)
309+
require.EqualValues(t,dc.Sessions.DefaultTokenDuration.Value().Seconds(),apiKey1.LifetimeSeconds)
310+
}

‎coderd/provisionerdserver/provisionerdserver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,7 @@ func (s *server) regenerateSessionToken(ctx context.Context, user database.User,
19581958
UserID:user.ID,
19591959
LoginType:user.LoginType,
19601960
TokenName:workspaceSessionTokenName(workspace),
1961-
DefaultLifetime:s.DeploymentValues.Sessions.DefaultDuration.Value(),
1961+
DefaultLifetime:s.DeploymentValues.Sessions.DefaultTokenDuration.Value(),
19621962
LifetimeSeconds:int64(s.DeploymentValues.Sessions.MaximumTokenDuration.Value().Seconds()),
19631963
})
19641964
iferr!=nil {

‎coderd/users_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,8 @@ func TestPostLogin(t *testing.T) {
299299
apiKey,err:=client.APIKeyByID(ctx,owner.UserID.String(),split[0])
300300
require.NoError(t,err,"fetch api key")
301301

302-
require.True(t,apiKey.ExpiresAt.After(time.Now().Add(time.Hour*24*29)),"default tokens lasts more than29 days")
303-
require.True(t,apiKey.ExpiresAt.Before(time.Now().Add(time.Hour*24*31)),"default tokens lasts less than31 days")
302+
require.True(t,apiKey.ExpiresAt.After(time.Now().Add(time.Hour*24*6)),"default tokens lasts more than6 days")
303+
require.True(t,apiKey.ExpiresAt.Before(time.Now().Add(time.Hour*24*8)),"default tokens lasts less than8 days")
304304
require.Greater(t,apiKey.LifetimeSeconds,key.LifetimeSeconds,"token should have longer lifetime")
305305
})
306306
}

‎codersdk/deployment.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,9 +454,11 @@ type SessionLifetime struct {
454454
// creation is the lifetime of the api key.
455455
DisableExpiryRefresh serpent.Bool`json:"disable_expiry_refresh,omitempty" typescript:",notnull"`
456456

457-
// DefaultDuration is forapi keys, not tokens.
457+
// DefaultDuration isonlyforbrowser, workspace app and oauth sessions.
458458
DefaultDuration serpent.Duration`json:"default_duration" typescript:",notnull"`
459459

460+
DefaultTokenDuration serpent.Duration`json:"default_token_lifetime,omitempty" typescript:",notnull"`
461+
460462
MaximumTokenDuration serpent.Duration`json:"max_token_lifetime,omitempty" typescript:",notnull"`
461463
}
462464

@@ -1998,6 +2000,16 @@ when required by your organization's security policy.`,
19982000
YAML:"maxTokenLifetime",
19992001
Annotations: serpent.Annotations{}.Mark(annotationFormatDuration,"true"),
20002002
},
2003+
{
2004+
Name:"Default Token Lifetime",
2005+
Description:"The default lifetime duration for API tokens. This value is used when creating a token without specifying a duration, such as when authenticating the CLI or an IDE plugin.",
2006+
Flag:"default-token-lifetime",
2007+
Env:"CODER_DEFAULT_TOKEN_LIFETIME",
2008+
Default: (7*24*time.Hour).String(),
2009+
Value:&c.Sessions.DefaultTokenDuration,
2010+
YAML:"defaultTokenLifetime",
2011+
Annotations: serpent.Annotations{}.Mark(annotationFormatDuration,"true"),
2012+
},
20012013
{
20022014
Name:"Enable swagger endpoint",
20032015
Description:"Expose the swagger endpoint via /swagger.",

‎docs/reference/api/general.md

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

‎docs/reference/api/schemas.md

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎docs/reference/cli/server.md

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

‎enterprise/cli/testdata/coder_server_--help.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ OPTIONS:
2626
systemd. This directory is NOT safe to be configured as a shared
2727
directory across coderd/provisionerd replicas.
2828

29+
--default-token-lifetime duration, $CODER_DEFAULT_TOKEN_LIFETIME (default: 168h0m0s)
30+
The default lifetime duration for API tokens. This value is used when
31+
creating a token without specifying a duration, such as when
32+
authenticating the CLI or an IDE plugin.
33+
2934
--disable-owner-workspace-access bool, $CODER_DISABLE_OWNER_WORKSPACE_ACCESS
3035
Remove the permission for the 'owner' role to have workspace execution
3136
on all workspaces. This prevents the 'owner' from ssh, apps, and

‎site/src/api/typesGenerated.ts

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp