from functools import lru_cache from typing import Protocol import bcrypt from fuware.core.config import get_app_settings class Hasher(Protocol): def hash(self, password: str) -> str: ... def verify(self, password: str, hashed: str) -> bool: ... class FakeHasher: def hash(self, password: str) -> str: return password def verify(self, password: str, hashed: str) -> bool: return password == hashed class BcryptHasher: def hash(self, password: str) -> str: return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') def verify(self, password: str, hashed: str) -> bool: return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8')) @lru_cache(maxsize=1) def get_hasher() -> Hasher: settings = get_app_settings() if settings.TESTING: return FakeHasher() return BcryptHasher()