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

Commit4369f2b

Browse files
feat: implement api for "forgot password?" flow (#14915)
Relates to#14232This implements two endpoints (names subject to change):- `/api/v2/users/otp/request`- `/api/v2/users/otp/change-password`
1 parent8785a51 commit4369f2b

25 files changed

+1007
-4
lines changed

‎coderd/apidoc/docs.go

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

‎coderd/apidoc/swagger.json

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

‎coderd/coderd.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ type Options struct {
248248

249249
// IDPSync holds all configured values for syncing external IDP users into Coder.
250250
IDPSync idpsync.IDPSync
251+
252+
// OneTimePasscodeValidityPeriod specifies how long a one time passcode should be valid for.
253+
OneTimePasscodeValidityPeriod time.Duration
251254
}
252255

253256
// @title Coder API
@@ -387,6 +390,9 @@ func New(options *Options) *API {
387390
v:=schedule.NewAGPLUserQuietHoursScheduleStore()
388391
options.UserQuietHoursScheduleStore.Store(&v)
389392
}
393+
ifoptions.OneTimePasscodeValidityPeriod==0 {
394+
options.OneTimePasscodeValidityPeriod=20*time.Minute
395+
}
390396

391397
ifoptions.StatsBatcher==nil {
392398
panic("developer error: options.StatsBatcher is nil")
@@ -984,6 +990,8 @@ func New(options *Options) *API {
984990
// This value is intentionally increased during tests.
985991
r.Use(httpmw.RateLimit(options.LoginRateLimit,time.Minute))
986992
r.Post("/login",api.postLogin)
993+
r.Post("/otp/request",api.postRequestOneTimePasscode)
994+
r.Post("/otp/change-password",api.postChangePasswordWithOneTimePasscode)
987995
r.Route("/oauth2",func(r chi.Router) {
988996
r.Route("/github",func(r chi.Router) {
989997
r.Use(

‎coderd/coderdtest/coderdtest.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ type Options struct {
128128
LoginRateLimitint
129129
FilesRateLimitint
130130

131+
// OneTimePasscodeValidityPeriod specifies how long a one time passcode should be valid for.
132+
OneTimePasscodeValidityPeriod time.Duration
133+
131134
// IncludeProvisionerDaemon when true means to start an in-memory provisionerD
132135
IncludeProvisionerDaemonbool
133136
ProvisionerDaemonTagsmap[string]string
@@ -311,6 +314,10 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
311314
options.NotificationsEnqueuer=&testutil.FakeNotificationsEnqueuer{}
312315
}
313316

317+
ifoptions.OneTimePasscodeValidityPeriod==0 {
318+
options.OneTimePasscodeValidityPeriod=testutil.WaitLong
319+
}
320+
314321
vartemplateScheduleStore atomic.Pointer[schedule.TemplateScheduleStore]
315322
ifoptions.TemplateScheduleStore==nil {
316323
options.TemplateScheduleStore=schedule.NewAGPLTemplateScheduleStore()
@@ -530,6 +537,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
530537
DatabaseRolluper:options.DatabaseRolluper,
531538
WorkspaceUsageTracker:wuTracker,
532539
NotificationsEnqueuer:options.NotificationsEnqueuer,
540+
OneTimePasscodeValidityPeriod:options.OneTimePasscodeValidityPeriod,
533541
}
534542
}
535543

‎coderd/coderdtest/swaggerparser.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,9 @@ func assertSecurityDefined(t *testing.T, comment SwaggerComment) {
303303
ifcomment.router=="/updatecheck"||
304304
comment.router=="/buildinfo"||
305305
comment.router=="/"||
306-
comment.router=="/users/login" {
306+
comment.router=="/users/login"||
307+
comment.router=="/users/otp/request"||
308+
comment.router=="/users/otp/change-password" {
307309
return// endpoints do not require authorization
308310
}
309311
assert.Equal(t,"CoderSessionToken",comment.security,"@Security must be equal CoderSessionToken")

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3628,6 +3628,14 @@ func (q *querier) UpdateUserGithubComUserID(ctx context.Context, arg database.Up
36283628
returnq.db.UpdateUserGithubComUserID(ctx,arg)
36293629
}
36303630

3631+
func (q*querier)UpdateUserHashedOneTimePasscode(ctx context.Context,arg database.UpdateUserHashedOneTimePasscodeParams)error {
3632+
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,rbac.ResourceSystem);err!=nil {
3633+
returnerr
3634+
}
3635+
3636+
returnq.db.UpdateUserHashedOneTimePasscode(ctx,arg)
3637+
}
3638+
36313639
func (q*querier)UpdateUserHashedPassword(ctx context.Context,arg database.UpdateUserHashedPasswordParams)error {
36323640
user,err:=q.db.GetUserByID(ctx,arg.ID)
36333641
iferr!=nil {

‎coderd/database/dbauthz/dbauthz_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,12 @@ func (s *MethodTestSuite) TestUser() {
11871187
ID:u.ID,
11881188
}).Asserts(u,policy.ActionUpdatePersonal).Returns()
11891189
}))
1190+
s.Run("UpdateUserHashedOneTimePasscode",s.Subtest(func(db database.Store,check*expects) {
1191+
u:=dbgen.User(s.T(),db, database.User{})
1192+
check.Args(database.UpdateUserHashedOneTimePasscodeParams{
1193+
ID:u.ID,
1194+
}).Asserts(rbac.ResourceSystem,policy.ActionUpdate).Returns()
1195+
}))
11901196
s.Run("UpdateUserQuietHoursSchedule",s.Subtest(func(db database.Store,check*expects) {
11911197
u:=dbgen.User(s.T(),db, database.User{})
11921198
check.Args(database.UpdateUserQuietHoursScheduleParams{

‎coderd/database/dbmem/dbmem.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9077,6 +9077,26 @@ func (q *FakeQuerier) UpdateUserGithubComUserID(_ context.Context, arg database.
90779077
returnsql.ErrNoRows
90789078
}
90799079

9080+
func (q*FakeQuerier)UpdateUserHashedOneTimePasscode(_ context.Context,arg database.UpdateUserHashedOneTimePasscodeParams)error {
9081+
err:=validateDatabaseType(arg)
9082+
iferr!=nil {
9083+
returnerr
9084+
}
9085+
9086+
q.mutex.Lock()
9087+
deferq.mutex.Unlock()
9088+
9089+
fori,user:=rangeq.users {
9090+
ifuser.ID!=arg.ID {
9091+
continue
9092+
}
9093+
user.HashedOneTimePasscode=arg.HashedOneTimePasscode
9094+
user.OneTimePasscodeExpiresAt=arg.OneTimePasscodeExpiresAt
9095+
q.users[i]=user
9096+
}
9097+
returnnil
9098+
}
9099+
90809100
func (q*FakeQuerier)UpdateUserHashedPassword(_ context.Context,arg database.UpdateUserHashedPasswordParams)error {
90819101
iferr:=validateDatabaseType(arg);err!=nil {
90829102
returnerr
@@ -9090,6 +9110,8 @@ func (q *FakeQuerier) UpdateUserHashedPassword(_ context.Context, arg database.U
90909110
continue
90919111
}
90929112
user.HashedPassword=arg.HashedPassword
9113+
user.HashedOneTimePasscode=nil
9114+
user.OneTimePasscodeExpiresAt= sql.NullTime{}
90939115
q.users[i]=user
90949116
returnnil
90959117
}

‎coderd/database/dbmetrics/dbmetrics.go

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

‎coderd/database/dbmock/dbmock.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DELETEFROM notification_templatesWHERE id='62f86a30-2330-4b61-a26d-311ff3b608cf';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
INSERT INTO notification_templates (id, name, title_template, body_template,"group", actions)
2+
VALUES ('62f86a30-2330-4b61-a26d-311ff3b608cf','One-Time Passcode', E'Your One-Time Passcode for Coder.',
3+
E'Hi {{.UserName}},\n\nA request to reset the password for your Coder account has been made. Your one-time passcode is:\n\n**{{.Labels.one_time_passcode}}**\n\nIf you did not request to reset your password, you can ignore this message.',
4+
'User Events','[]'::jsonb);

‎coderd/database/querier.go

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