from datetime import datetime, timedelta, timezone from fastapi import Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from jose import jwt, JWTError from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.config import settings from app.database import get_db from app.models import Usuario, Rol security = HTTPBearer() async def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(security), db: AsyncSession = Depends(get_db), ) -> Usuario: token = credentials.credentials try: payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]) user_id: str = payload.get("sub") if user_id is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token invalido") except JWTError: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token invalido o expirado") result = await db.execute(select(Usuario).where(Usuario.id == user_id)) user = result.scalar_one_or_none() if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Usuario no encontrado") if not user.activo: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Usuario inactivo") return user def create_access_token(user_id: str, rol_id: int, pais_id: int | None = None) -> str: expire = datetime.now(timezone.utc) + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) payload = { "sub": user_id, "rol": rol_id, "pais_id": pais_id, "exp": expire, } return jwt.encode(payload, settings.SECRET_KEY, algorithm=settings.ALGORITHM) async def get_user_permissions(user: Usuario, db: AsyncSession) -> list[int]: result = await db.execute( select(Rol.id, Rol.nombre).where(Rol.id == user.rol) ) return result.scalar_one_or_none()