Files
2024-11-03 12:51:32 +00:00

41 lines
1.3 KiB
Python

import secrets
from typing import Optional, Protocol, Union
from pwdlib import PasswordHash
from pwdlib.hashers.argon2 import Argon2Hasher
from pwdlib.hashers.bcrypt import BcryptHasher
class PasswordHelperProtocol(Protocol):
def verify_and_update(
self, plain_password: str, hashed_password: str
) -> tuple[bool, Union[str, None]]: ... # pragma: no cover
def hash(self, password: str) -> str: ... # pragma: no cover
def generate(self) -> str: ... # pragma: no cover
class PasswordHelper(PasswordHelperProtocol):
def __init__(self, password_hash: Optional[PasswordHash] = None) -> None:
if password_hash is None:
self.password_hash = PasswordHash(
(
Argon2Hasher(),
BcryptHasher(),
)
)
else:
self.password_hash = password_hash # pragma: no cover
def verify_and_update(
self, plain_password: str, hashed_password: str
) -> tuple[bool, Union[str, None]]:
return self.password_hash.verify_and_update(plain_password, hashed_password)
def hash(self, password: str) -> str:
return self.password_hash.hash(password)
def generate(self) -> str:
return secrets.token_urlsafe()