57 lines
1.5 KiB
Python
57 lines
1.5 KiB
Python
"""
|
|
Shared Utility Functions
|
|
Common helpers used across the application
|
|
"""
|
|
import uuid
|
|
import re
|
|
from typing import TYPE_CHECKING
|
|
|
|
from app import config
|
|
|
|
if TYPE_CHECKING:
|
|
from database.models import User
|
|
|
|
|
|
def generate_uuid() -> str:
|
|
"""Generate a new UUID string"""
|
|
return str(uuid.uuid4())
|
|
|
|
|
|
def is_ldap_user(user: "User") -> bool:
|
|
"""Check if user is managed by LDAP (Authelia mode with no local password)"""
|
|
return config.AUTHELIA_ENABLED and user.password_hash is None
|
|
|
|
|
|
def is_ldap_admin(user: "User") -> bool:
|
|
"""Check if user is an LDAP-managed admin"""
|
|
return is_ldap_user(user) and user.role == "admin"
|
|
|
|
|
|
def validate_password(password: str) -> list[str]:
|
|
"""
|
|
Validate password strength.
|
|
Returns list of error messages (empty if valid).
|
|
"""
|
|
errors = []
|
|
if len(password) < 8:
|
|
errors.append("at least 8 characters")
|
|
if not re.search(r'[A-Z]', password):
|
|
errors.append("one uppercase letter")
|
|
if not re.search(r'[a-z]', password):
|
|
errors.append("one lowercase letter")
|
|
if not re.search(r'[0-9]', password):
|
|
errors.append("one number")
|
|
return errors
|
|
|
|
|
|
def format_password_errors(errors: list[str]) -> str:
|
|
"""Format password validation errors into a message"""
|
|
if not errors:
|
|
return ""
|
|
return f"Password must contain: {', '.join(errors)}"
|
|
|
|
|
|
def get_notification_default(value, default):
|
|
"""Get notification setting value with default fallback"""
|
|
return value if value is not None else default
|