""" Tool_OCR - Security Utilities JWT token generation and password hashing """ from datetime import datetime, timedelta from typing import Optional import logging from jose import JWTError, jwt from passlib.context import CryptContext from app.core.config import settings logger = logging.getLogger(__name__) # Password hashing context pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") def verify_password(plain_password: str, hashed_password: str) -> bool: """ Verify a password against a hash Args: plain_password: Plain text password hashed_password: Hashed password from database Returns: bool: True if password matches, False otherwise """ return pwd_context.verify(plain_password, hashed_password) def get_password_hash(password: str) -> str: """ Hash a password Args: password: Plain text password Returns: str: Hashed password """ return pwd_context.hash(password) def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str: """ Create JWT access token Args: data: Data to encode in token (typically {"sub": user_id}) expires_delta: Optional expiration time delta Returns: str: Encoded JWT token """ to_encode = data.copy() if expires_delta: expire = datetime.utcnow() + expires_delta else: expire = datetime.utcnow() + timedelta(minutes=settings.access_token_expire_minutes) to_encode.update({"exp": expire}) encoded_jwt = jwt.encode(to_encode, settings.secret_key, algorithm=settings.algorithm) return encoded_jwt def decode_access_token(token: str) -> Optional[dict]: """ Decode and verify JWT access token Args: token: JWT token string Returns: dict: Decoded token payload, or None if invalid """ try: payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm]) return payload except JWTError as e: logger.warning(f"JWT decode error: {e}") return None