diff --git a/packages/application/auth/password_handler.py b/packages/application/auth/password_handler.py new file mode 100644 index 000000000..2bd2da363 --- /dev/null +++ b/packages/application/auth/password_handler.py @@ -0,0 +1,126 @@ +""" +密码处理器委托层 + +此模块作为 Domain 层 (packages.domain.auth.password_hasher) 和 Application 层之间的委托层, +隔离 Domain 层对 bcrypt 库的直接依赖。 + +使用方式: + from packages.application.auth.password_handler import PasswordHandler, get_password_handler + + password_handler = PasswordHandler() + hashed = password_handler.hash_password("my_secure_password") + is_valid = password_handler.verify_password("my_secure_password", hashed) +""" + +from typing import Optional, Tuple + +from packages.domain.auth.password_hasher import PasswordHasher, PasswordValidator + + +class PasswordHandler: + """ + 密码处理器委托类 + + 委托给 packages.domain.auth.password_hasher 进行实际的密码哈希操作, + 此层仅负责配置和封装,不直接依赖 bcrypt 库。 + """ + + def __init__(self, rounds: int = 12): + """ + 初始化密码处理器 + + Args: + rounds: bcrypt cost factor(默认 12,推荐范围 10-14) + """ + self._hasher = PasswordHasher(rounds=rounds) + self._validator = PasswordValidator( + min_length=8, + require_uppercase=True, + require_lowercase=True, + require_digit=True, + require_special=False, + ) + + def hash_password(self, password: str) -> str: + """ + 哈希密码 + + Args: + password: 明文密码 + + Returns: + bcrypt 哈希字符串 + + Raises: + ValueError: 密码为空 + """ + return self._hasher.hash_password(password) + + def verify_password(self, password: str, hashed_password: str) -> bool: + """ + 验证密码 + + Args: + password: 明文密码 + hashed_password: 存储的哈希密码 + + Returns: + True 如果密码正确,否则 False + """ + return self._hasher.verify_password(password, hashed_password) + + def needs_rehash(self, hashed_password: str) -> bool: + """ + 检查哈希是否需要重新计算 + + Args: + hashed_password: 存储的哈希密码 + + Returns: + True 如果需要重新哈希 + """ + return self._hasher.needs_rehash(hashed_password) + + def validate_strength(self, password: str) -> Tuple[bool, Optional[str]]: + """ + 验证密码强度 + + Args: + password: 明文密码 + + Returns: + (是否有效, 错误信息) + """ + return self._validator.validate(password) + + +# 默认处理器实例 +_default_handler: Optional[PasswordHandler] = None + + +def configure_password_handler(rounds: int = 12) -> PasswordHandler: + """ + 配置全局密码处理器 + + Args: + rounds: bcrypt cost factor + + Returns: + 配置好的 PasswordHandler 实例 + """ + global _default_handler + _default_handler = PasswordHandler(rounds=rounds) + return _default_handler + + +def get_password_handler() -> PasswordHandler: + """ + 获取全局密码处理器 + + Returns: + PasswordHandler 实例 + """ + global _default_handler + if _default_handler is None: + _default_handler = PasswordHandler() + return _default_handler