package service import ( "context" "errors" "github.com/Tencent/WeKnora/internal/config" "github.com/Tencent/WeKnora/internal/types/interfaces" secutils "github.com/Tencent/WeKnora/internal/utils" ) const ( authComplexPasswordEnabledSettingKey = "auth.complex_password_enabled" authComplexPasswordEnabledEnvName = "WEKNORA_AUTH_COMPLEX_PASSWORD_ENABLED" upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" lowerChars = "abcdefghijklmnopqrstuvwxyz" digitChars = "0123456789" passwordSpecialChars = secutils.PasswordSpecialCharacters allChars = upperChars + lowerChars + digitChars + passwordSpecialChars ) // ResolveComplexPasswordEnabled is the shared runtime resolver for the // complex-password switch. Priority matches other auth tunables: // DB system_settings > ENV > cfg.Auth (startup YAML/env) > false. func ResolveComplexPasswordEnabled( ctx context.Context, cfg *config.Config, settings interfaces.SystemSettingService, ) bool { enabled := false if cfg != nil && cfg.Auth != nil { enabled = cfg.Auth.ComplexPasswordEnabled } if settings == nil { return enabled } return settings.GetBool( ctx, authComplexPasswordEnabledSettingKey, authComplexPasswordEnabledEnvName, enabled, ) } // IsPasswordPolicyError reports whether err is a documented password-policy // failure. Handlers map both the simple and complex sentinels to the same // machine-readable details token so the SPA can localize them. func IsPasswordPolicyError(err error) bool { return errors.Is(err, ErrPasswordPolicy) || errors.Is(err, ErrComplexPasswordPolicy) } // ValidatePasswordPolicy keeps registration, self-service rotation and // administrative password resets aligned with workspace user management. func ValidatePasswordPolicy(password string, complexPasswordEnabled bool) error { return secutils.ValidatePasswordPolicy(password, complexPasswordEnabled) }