from __future__ import annotations import uuid from fastapi import Depends, HTTPException, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from jwt import ExpiredSignatureError, InvalidTokenError from sqlalchemy.ext.asyncio import AsyncSession from cpv3.infrastructure.security import decode_token from cpv3.db.session import get_db from cpv3.modules.users.models import User from cpv3.modules.users.repository import UserRepository _bearer = HTTPBearer(auto_error=True) async def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(_bearer), db: AsyncSession = Depends(get_db), ) -> User: token = credentials.credentials try: payload = decode_token(token) except ExpiredSignatureError as e: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Token expired" ) from e except InvalidTokenError as e: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token" ) from e if payload.get("type") != "access": raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token" ) sub = payload.get("sub") if not sub: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token" ) try: user_id = uuid.UUID(str(sub)) except ValueError as e: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token" ) from e user_repo = UserRepository(db) user = await user_repo.get_by_id(user_id) if user is None or not user.is_active: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials" ) return user