05/06/2026 Initial commit
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
"""
|
||||
forms.py
|
||||
Shared form utilities and password strength validator.
|
||||
Per-module WTForms classes live in their respective blueprint directories.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
|
||||
_PASSWORD_MIN_LENGTH = 10
|
||||
_HAS_UPPERCASE = re.compile(r"[A-Z]")
|
||||
_HAS_LOWERCASE = re.compile(r"[a-z]")
|
||||
_HAS_DIGIT = re.compile(r"\d")
|
||||
|
||||
|
||||
def validate_password_strength(password: str, confirm: str = None) -> str | None:
|
||||
"""
|
||||
Validate password strength per the security policy:
|
||||
- Minimum 10 characters
|
||||
- Must include at least one uppercase letter
|
||||
- Must include at least one lowercase letter
|
||||
- Must include at least one digit
|
||||
|
||||
Returns an error string, or None if the password is acceptable.
|
||||
If confirm is supplied, also checks they match.
|
||||
"""
|
||||
if not password:
|
||||
return "Password is required."
|
||||
if len(password) < _PASSWORD_MIN_LENGTH:
|
||||
return f"Password must be at least {_PASSWORD_MIN_LENGTH} characters."
|
||||
if not _HAS_UPPERCASE.search(password):
|
||||
return "Password must include at least one uppercase letter."
|
||||
if not _HAS_LOWERCASE.search(password):
|
||||
return "Password must include at least one lowercase letter."
|
||||
if not _HAS_DIGIT.search(password):
|
||||
return "Password must include at least one digit."
|
||||
if confirm is not None and password != confirm:
|
||||
return "Passwords do not match."
|
||||
return None
|
||||
Reference in New Issue
Block a user