from datetime import datetime, timedelta, timezone from typing import Optional, Dict, Any, Tuple from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from jose import JWTError, jwt import logging from modules.gateway_interface import get_gateway_interface from modules.gateway_model import User, Token import configload # Get Config Data config=configload.load_config() SECRET_KEY = config.get('Auth', 'SECRET_KEY') ALGORITHM = config.get('Auth', 'ALGORITHM') ACCESS_TOKEN_EXPIRE_MINUTES = int(config.get('Auth', 'ACCESS_TOKEN_EXPIRE_MINUTES')) # OAuth2 Setup oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") # Logger logger = logging.getLogger(__name__) def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str: """ Erstellt ein JWT Access Token. Args: data: Zu kodierende Daten (meist Benutzer-ID oder Benutzername) expires_delta: Gültigkeitsdauer des Tokens (optional) Returns: JWT Token als String """ to_encode = data.copy() if expires_delta: expire = datetime.now(timezone.utc) + expires_delta else: expire = datetime.now(timezone.utc) + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) to_encode.update({"exp": expire}) encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt async def get_current_user(token: str = Depends(oauth2_scheme)) -> Dict[str, Any]: """ Extrahiert und validiert den aktuellen Benutzer aus dem JWT Token. Args: token: JWT Token aus dem Authorization-Header Returns: Benutzerdaten Raises: HTTPException: Bei ungültigem Token oder Benutzer """ credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Ungültige Authentifizierungsdaten", headers={"WWW-Authenticate": "Bearer"}, ) try: # Token dekodieren payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) # Benutzername aus dem Token extrahieren username: str = payload.get("sub") if username is None: raise credentials_exception # Mandanten-ID aus dem Token extrahieren (falls vorhanden) mandate_id: int = payload.get("mandate_id", 1) # Standard: Root-Mandant except JWTError: logger.warning("Ungültiges JWT Token") raise credentials_exception # Gateway-Interface ohne Kontext initialisieren gateway = get_gateway_interface() # Benutzer aus der Datenbank abrufen user = gateway.get_user_by_username(username) if user is None: logger.warning(f"Benutzer {username} nicht gefunden") raise credentials_exception if user.get("disabled", False): logger.warning(f"Benutzer {username} ist deaktiviert") raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Benutzer ist deaktiviert") return user async def get_current_active_user(current_user: Dict[str, Any] = Depends(get_current_user)) -> Dict[str, Any]: """ Stellt sicher, dass der Benutzer aktiv ist. Args: current_user: Aktuelle Benutzerdaten Returns: Benutzerdaten Raises: HTTPException: Wenn der Benutzer deaktiviert ist """ if current_user.get("disabled", False): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Benutzer ist deaktiviert") return current_user async def get_user_context(current_user: Dict[str, Any]) -> Tuple[int, int]: """ Extrahiert die Mandanten-ID und Benutzer-ID aus dem aktuellen Benutzer. Enhanced with better logging. Args: current_user: Der aktuelle Benutzer Returns: Tuple von (mandate_id, user_id) """ # Default values default_mandate_id = 0 default_user_id = 0 # Extract mandate_id mandate_id = current_user.get("mandate_id", None) if mandate_id is None: logger.warning(f"No mandate_id found in current_user, using default: {default_mandate_id}") mandate_id = default_mandate_id else: try: mandate_id = int(mandate_id) except (ValueError, TypeError): logger.error(f"Invalid mandate_id value: {mandate_id}, using default: {default_mandate_id}") mandate_id = default_mandate_id # Extract user_id user_id = current_user.get("id", None) if user_id is None: logger.warning(f"No user_id found in current_user, using default: {default_user_id}") user_id = default_user_id else: try: user_id = int(user_id) except (ValueError, TypeError): logger.error(f"Invalid user_id value: {user_id}, using default: {default_user_id}") user_id = default_user_id # logger.info(f"User context: mandate_id={mandate_id}, user_id={user_id}") return mandate_id, user_id