Skip to content

Commit f9b6404

Browse files
authored
Accounts with WebAuthn only (no TOTP) now exist ... fix code to handle that case (#18897) (#18964)
1 parent 52517e3 commit f9b6404

File tree

2 files changed

+45
-16
lines changed

2 files changed

+45
-16
lines changed

models/user/list.go

+20-6
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,19 @@ func (users UserList) GetTwoFaStatus() map[int64]bool {
3030
for _, user := range users {
3131
results[user.ID] = false // Set default to false
3232
}
33-
tokenMaps, err := users.loadTwoFactorStatus(db.GetEngine(db.DefaultContext))
34-
if err == nil {
33+
34+
if tokenMaps, err := users.loadTwoFactorStatus(db.GetEngine(db.DefaultContext)); err == nil {
3535
for _, token := range tokenMaps {
3636
results[token.UID] = true
3737
}
3838
}
3939

40+
if ids, err := users.userIDsWithWebAuthn(db.GetEngine(db.DefaultContext)); err == nil {
41+
for _, id := range ids {
42+
results[id] = true
43+
}
44+
}
45+
4046
return results
4147
}
4248

@@ -47,15 +53,23 @@ func (users UserList) loadTwoFactorStatus(e db.Engine) (map[int64]*auth.TwoFacto
4753

4854
userIDs := users.GetUserIDs()
4955
tokenMaps := make(map[int64]*auth.TwoFactor, len(userIDs))
50-
err := e.
51-
In("uid", userIDs).
52-
Find(&tokenMaps)
53-
if err != nil {
56+
if err := e.In("uid", userIDs).Find(&tokenMaps); err != nil {
5457
return nil, fmt.Errorf("find two factor: %v", err)
5558
}
5659
return tokenMaps, nil
5760
}
5861

62+
func (users UserList) userIDsWithWebAuthn(e db.Engine) ([]int64, error) {
63+
if len(users) == 0 {
64+
return nil, nil
65+
}
66+
ids := make([]int64, 0, len(users))
67+
if err := e.Table(new(auth.WebAuthnCredential)).In("user_id", users.GetUserIDs()).Select("user_id").Distinct("user_id").Find(&ids); err != nil {
68+
return nil, fmt.Errorf("find two factor: %v", err)
69+
}
70+
return ids, nil
71+
}
72+
5973
// GetUsersByIDs returns all resolved users from a list of Ids.
6074
func GetUsersByIDs(ids []int64) (UserList, error) {
6175
ous := make([]*User, 0, len(ids))

routers/web/admin/users.go

+25-10
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,17 @@ func prepareUserInfo(ctx *context.Context) *user_model.User {
217217
}
218218
ctx.Data["Sources"] = sources
219219

220-
ctx.Data["TwoFactorEnabled"] = true
221-
_, err = auth.GetTwoFactorByUID(u.ID)
220+
hasTOTP, err := auth.HasTwoFactorByUID(u.ID)
222221
if err != nil {
223-
if !auth.IsErrTwoFactorNotEnrolled(err) {
224-
ctx.ServerError("IsErrTwoFactorNotEnrolled", err)
225-
return nil
226-
}
227-
ctx.Data["TwoFactorEnabled"] = false
222+
ctx.ServerError("auth.HasTwoFactorByUID", err)
223+
return nil
224+
}
225+
hasWebAuthn, err := auth.HasWebAuthnRegistrationsByUID(u.ID)
226+
if err != nil {
227+
ctx.ServerError("auth.HasWebAuthnRegistrationsByUID", err)
228+
return nil
228229
}
230+
ctx.Data["TwoFactorEnabled"] = hasTOTP || hasWebAuthn
229231

230232
return u
231233
}
@@ -327,14 +329,27 @@ func EditUserPost(ctx *context.Context) {
327329
if form.Reset2FA {
328330
tf, err := auth.GetTwoFactorByUID(u.ID)
329331
if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
330-
ctx.ServerError("GetTwoFactorByUID", err)
332+
ctx.ServerError("auth.GetTwoFactorByUID", err)
331333
return
334+
} else if tf != nil {
335+
if err := auth.DeleteTwoFactorByID(tf.ID, u.ID); err != nil {
336+
ctx.ServerError("auth.DeleteTwoFactorByID", err)
337+
return
338+
}
332339
}
333340

334-
if err = auth.DeleteTwoFactorByID(tf.ID, u.ID); err != nil {
335-
ctx.ServerError("DeleteTwoFactorByID", err)
341+
wn, err := auth.GetWebAuthnCredentialsByUID(u.ID)
342+
if err != nil {
343+
ctx.ServerError("auth.GetTwoFactorByUID", err)
336344
return
337345
}
346+
for _, cred := range wn {
347+
if _, err := auth.DeleteCredential(cred.ID, u.ID); err != nil {
348+
ctx.ServerError("auth.DeleteCredential", err)
349+
return
350+
}
351+
}
352+
338353
}
339354

340355
u.LoginName = form.LoginName

0 commit comments

Comments
 (0)