feat(mfa): require_mfa policy, sign-in rate limit and MFA column
This commit is contained in:
@@ -47,6 +47,38 @@ func mfaCtx() (context.Context, context.CancelFunc) {
|
||||
return context.WithTimeout(context.Background(), 5*time.Second)
|
||||
}
|
||||
|
||||
// UsersWithMFA returns the set of user IDs in this instance holding a factor.
|
||||
// One query per collection, not one per member, so the member list stays
|
||||
// cheap however many users an instance has.
|
||||
func UsersWithMFA(instanceID string) (map[string]bool, error) {
|
||||
ctx, cancel := mfaCtx()
|
||||
defer cancel()
|
||||
out := map[string]bool{}
|
||||
|
||||
cur, err := db.Col("user_mfa").Find(ctx,
|
||||
bson.M{"instance_id": instanceID, "totp_confirmed_at": bson.M{"$exists": true}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var rows []models.UserMFA
|
||||
if err := cur.All(ctx, &rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, r := range rows {
|
||||
out[r.UserID] = true
|
||||
}
|
||||
|
||||
var userIDs []string
|
||||
if err := db.Col("webauthn_credentials").Distinct(ctx, "user_id",
|
||||
bson.M{"instance_id": instanceID}).Decode(&userIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, id := range userIDs {
|
||||
out[id] = true
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GenerateRecoveryCodes returns the codes to show the user once, and the
|
||||
// hashed records to store. The plaintext is never persisted.
|
||||
func GenerateRecoveryCodes() ([]string, []models.RecoveryCode, error) {
|
||||
|
||||
@@ -119,7 +119,7 @@ func ResolveSecretsReadToken(token string) (string, bool) {
|
||||
return s.InstanceID, true
|
||||
}
|
||||
|
||||
func SaveSettings(instanceID string, alerts models.AlertSettings, retentionDays *int, localLoginEnabled *bool, apiTokenMaxDays *int) error {
|
||||
func SaveSettings(instanceID string, alerts models.AlertSettings, retentionDays *int, localLoginEnabled *bool, requireMFA *bool, apiTokenMaxDays *int) error {
|
||||
if alerts.OfflineThresholdMinutes <= 0 {
|
||||
alerts.OfflineThresholdMinutes = 5
|
||||
}
|
||||
@@ -149,6 +149,9 @@ func SaveSettings(instanceID string, alerts models.AlertSettings, retentionDays
|
||||
if localLoginEnabled != nil {
|
||||
set["local_login_enabled"] = *localLoginEnabled
|
||||
}
|
||||
if requireMFA != nil {
|
||||
set["require_mfa"] = *requireMFA
|
||||
}
|
||||
if apiTokenMaxDays != nil {
|
||||
set["api_token_max_days"] = *apiTokenMaxDays
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user