[v10.0/forgejo] fix: check for webauthn in 2fa user search (#6730)

**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6726

- Check for webauthn credentials in the user search when the two factor
filter is enabled.
- Resolves forgejo/forgejo#6524

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6730
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
This commit is contained in:
forgejo-backport-action 2025-01-29 19:28:12 +00:00 committed by Gusted
parent 4016f2890d
commit 0db9a24a4b
2 changed files with 5 additions and 7 deletions

View file

@ -126,17 +126,15 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess
return e.Where(cond)
}
// 2fa filter uses LEFT JOIN to check whether a user has a 2fa record
// While using LEFT JOIN, sometimes the performance might not be good, but it won't be a problem now, such SQL is seldom executed.
// There are some possible methods to refactor this SQL in future when we really need to optimize the performance (but not now):
// (1) add a column in user table (2) add a setting value in user_setting table (3) use search engines (bleve/elasticsearch)
// Check if the user has two factor enabled, which is TOTP or Webauthn.
if opts.IsTwoFactorEnabled.Value() {
cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL"))
cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL OR webauthn_credential.user_id IS NOT NULL"))
} else {
cond = cond.And(builder.Expr("two_factor.uid IS NULL"))
cond = cond.And(builder.Expr("two_factor.uid IS NULL AND webauthn_credential.user_id IS NULL"))
}
return e.Join("LEFT OUTER", "two_factor", "two_factor.uid = `user`.id").
Join("LEFT OUTER", "webauthn_credential", "webauthn_credential.user_id = `user`.id").
Where(cond)
}

View file

@ -222,7 +222,7 @@ func TestSearchUsers(t *testing.T) {
[]int64{1041, 37})
testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsTwoFactorEnabled: optional.Some(true)},
[]int64{24})
[]int64{24, 32})
}
func TestEmailNotificationPreferences(t *testing.T) {