feat: 5.1-3 Создать модуль app/core/passwords.py

This commit is contained in:
2026-10-12 16:17:28 +03:00
parent 13170a4e3e
commit e7477ec468
2 changed files with 50 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
from argon2 import PasswordHasher
from argon2.exceptions import InvalidHashError, VerifyMismatchError
from argon2.low_level import Type
from zxcvbn import zxcvbn
from app.config import settings
class WeakPasswordError(ValueError):
pass
_hasher = PasswordHasher(
time_cost=3,
memory_cost=65536,
parallelism=4,
hash_len=32,
salt_len=16,
type=Type.ID,
)
def _peppered(password: str) -> str:
return password + settings.password_pepper
# возвращает хэш Argon2id от password + pepper;
def hash_password(password: str) -> str:
return _hasher.hash(_peppered(password))
# проверяет соответствие
def verify_password(password: str, hashed: str) -> bool:
try:
return _hasher.verify(hashed, _peppered(password))
except (VerifyMismatchError, InvalidHashError):
return False
# проверяет политику
def validate_policy(password: str, user_inputs: list[str] | None = None) -> None:
# длина не меньше settings.password_min_length;
if len(password) < settings.password_min_length:
raise WeakPasswordError(
f"Password must be >= {settings.password_min_length} chars"
)
result = zxcvbn(password, user_inputs=user_inputs or [])
# оценка стойкости через zxcvbn должна быть не ниже 3 (по шкале 0–4);
if result["score"] < 3:
raise WeakPasswordError("Password is too weak")