import hashlib import secrets from argon2 import PasswordHasher from argon2.exceptions import InvalidHashError, VerificationError, VerifyMismatchError _password_hasher = PasswordHasher() def hash_password(password: str) -> str: return _password_hasher.hash(password) def verify_password(password_hash: str, password: str) -> bool: try: return _password_hasher.verify(password_hash, password) except (VerifyMismatchError, VerificationError, InvalidHashError): return False def new_token() -> str: return secrets.token_urlsafe(32) def token_digest(token: str) -> str: return hashlib.sha256(token.encode("utf-8")).hexdigest() def constant_time_equals(left: str, right: str) -> bool: return secrets.compare_digest(left.encode("utf-8"), right.encode("utf-8"))