Files
mediaplayer/sentence_api/auth.py
2026-08-30 17:07:55 +08:00

50 lines
1.1 KiB
Python

import hashlib
import hmac
import secrets
from dataclasses import dataclass
PBKDF2_ITERATIONS = 120_000
@dataclass(frozen=True)
class AuthenticatedUser:
id: str
username: str
nickname: str
def hash_password(password: str) -> str:
salt = secrets.token_hex(16)
digest = hashlib.pbkdf2_hmac(
"sha256",
password.encode("utf-8"),
salt.encode("ascii"),
PBKDF2_ITERATIONS,
).hex()
return f"pbkdf2_sha256${PBKDF2_ITERATIONS}${salt}${digest}"
def verify_password(password: str, stored: str) -> bool:
try:
algorithm, iterations, salt, digest = stored.split("$", 3)
if algorithm != "pbkdf2_sha256":
return False
calculated = hashlib.pbkdf2_hmac(
"sha256",
password.encode("utf-8"),
salt.encode("ascii"),
int(iterations),
).hex()
return hmac.compare_digest(calculated, digest)
except (TypeError, ValueError):
return False
def new_token() -> str:
return secrets.token_urlsafe(48)
def hash_token(token: str) -> str:
return hashlib.sha256(token.encode("utf-8")).hexdigest()