aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--models/user/list.go26
-rw-r--r--routers/web/admin/users.go35
2 files changed, 45 insertions, 16 deletions
diff --git a/models/user/list.go b/models/user/list.go
index 13138b3e50..06ec511375 100644
--- a/models/user/list.go
+++ b/models/user/list.go
@@ -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
}
@@ -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))
diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go
index 5cb25d8672..4358db89ba 100644
--- a/routers/web/admin/users.go
+++ b/routers/web/admin/users.go
@@ -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
}
@@ -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