Files
main_backend/cpv3/infrastructure/auth.py
T
2026-02-27 23:33:56 +03:00

65 lines
2.1 KiB
Python

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, use_cache=False),
) -> User:
try:
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
finally:
# Free the auth session immediately so long-running handlers don't pin a pool slot.
await db.close()