from datetime import datetime, timedelta, timezone import jwt from passlib.context import CryptContext from app.core.app_settings import settings _pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") def hash_password(password: str) -> str: return _pwd_context.hash(password) def verify_password(plain_password: str, password_hash: str) -> bool: return _pwd_context.verify(plain_password, password_hash) def create_access_token(*, subject: str) -> str: # Bewusst KEINE Rollen im Token: get_current_user liest Rollen bei jedem Request # frisch aus der DB (Rollenänderung wirkt sofort, kein Token-Refresh nötig). expire = datetime.now(timezone.utc) + timedelta(minutes=settings.access_token_expire_minutes) payload = {"sub": subject, "exp": expire} return jwt.encode(payload, settings.jwt_secret_key, algorithm=settings.jwt_algorithm) class InvalidTokenError(Exception): pass def decode_access_token(token: str) -> dict: try: return jwt.decode(token, settings.jwt_secret_key, algorithms=[settings.jwt_algorithm]) except jwt.PyJWTError as exc: raise InvalidTokenError(str(exc)) from exc