Skip to content

Commit

Permalink
Accounts with WebAuthn only (no TOTP) now exist ... fix code to handl…
Browse files Browse the repository at this point in the history
…e that case (#18897)
  • Loading branch information
6543 committed Mar 2, 2022
1 parent 38f6322 commit 1f45d1e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 16 deletions.
26 changes: 20 additions & 6 deletions models/user/list.go
Expand Up @@ -30,13 +30,19 @@ func (users UserList) GetTwoFaStatus() map[int64]bool {
for _, user := range users {
results[user.ID] = false // Set default to false
}
tokenMaps, err := users.loadTwoFactorStatus(db.GetEngine(db.DefaultContext))
if err == nil {

if tokenMaps, err := users.loadTwoFactorStatus(db.GetEngine(db.DefaultContext)); err == nil {
for _, token := range tokenMaps {
results[token.UID] = true
}
}

if ids, err := users.userIDsWithWebAuthn(db.GetEngine(db.DefaultContext)); err == nil {
for _, id := range ids {
results[id] = true
}
}

return results
}

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

userIDs := users.GetUserIDs()
tokenMaps := make(map[int64]*auth.TwoFactor, len(userIDs))
err := e.
In("uid", userIDs).
Find(&tokenMaps)
if err != nil {
if err := e.In("uid", userIDs).Find(&tokenMaps); err != nil {
return nil, fmt.Errorf("find two factor: %v", err)
}
return tokenMaps, nil
}

func (users UserList) userIDsWithWebAuthn(e db.Engine) ([]int64, error) {
if len(users) == 0 {
return nil, nil
}
ids := make([]int64, 0, len(users))
if err := e.Table(new(auth.WebAuthnCredential)).In("user_id", users.GetUserIDs()).Select("user_id").Distinct("user_id").Find(&ids); err != nil {
return nil, fmt.Errorf("find two factor: %v", err)
}
return ids, nil
}

// GetUsersByIDs returns all resolved users from a list of Ids.
func GetUsersByIDs(ids []int64) (UserList, error) {
ous := make([]*User, 0, len(ids))
Expand Down
35 changes: 25 additions & 10 deletions routers/web/admin/users.go
Expand Up @@ -217,15 +217,17 @@ func prepareUserInfo(ctx *context.Context) *user_model.User {
}
ctx.Data["Sources"] = sources

ctx.Data["TwoFactorEnabled"] = true
_, err = auth.GetTwoFactorByUID(u.ID)
hasTOTP, err := auth.HasTwoFactorByUID(u.ID)
if err != nil {
if !auth.IsErrTwoFactorNotEnrolled(err) {
ctx.ServerError("IsErrTwoFactorNotEnrolled", err)
return nil
}
ctx.Data["TwoFactorEnabled"] = false
ctx.ServerError("auth.HasTwoFactorByUID", err)
return nil
}
hasWebAuthn, err := auth.HasWebAuthnRegistrationsByUID(u.ID)
if err != nil {
ctx.ServerError("auth.HasWebAuthnRegistrationsByUID", err)
return nil
}
ctx.Data["TwoFactorEnabled"] = hasTOTP || hasWebAuthn

return u
}
Expand Down Expand Up @@ -327,14 +329,27 @@ func EditUserPost(ctx *context.Context) {
if form.Reset2FA {
tf, err := auth.GetTwoFactorByUID(u.ID)
if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
ctx.ServerError("GetTwoFactorByUID", err)
ctx.ServerError("auth.GetTwoFactorByUID", err)
return
} else if tf != nil {
if err := auth.DeleteTwoFactorByID(tf.ID, u.ID); err != nil {
ctx.ServerError("auth.DeleteTwoFactorByID", err)
return
}
}

if err = auth.DeleteTwoFactorByID(tf.ID, u.ID); err != nil {
ctx.ServerError("DeleteTwoFactorByID", err)
wn, err := auth.GetWebAuthnCredentialsByUID(u.ID)
if err != nil {
ctx.ServerError("auth.GetTwoFactorByUID", err)
return
}
for _, cred := range wn {
if _, err := auth.DeleteCredential(cred.ID, u.ID); err != nil {
ctx.ServerError("auth.DeleteCredential", err)
return
}
}

}

u.LoginName = form.LoginName
Expand Down

0 comments on commit 1f45d1e

Please sign in to comment.