from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from jose import jwt, JWTError from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from app.database import get_db from app.config import get_settings from app.models.user import User from app.schemas.user import UserResponse, UserUpdate router = APIRouter() settings = get_settings() security = HTTPBearer() async def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(security), db: AsyncSession = Depends(get_db), ) -> User: try: payload = jwt.decode( credentials.credentials, settings.secret_key, algorithms=[settings.algorithm], ) user_id = payload.get("sub") if user_id is None: raise HTTPException(status_code=401, detail="Invalid token") except JWTError: raise HTTPException(status_code=401, detail="Invalid token") result = await db.execute(select(User).where(User.id == int(user_id))) user = result.scalar_one_or_none() if not user: raise HTTPException(status_code=404, detail="User not found") if not user.is_active: raise HTTPException(status_code=401, detail="User account is disabled") return user @router.get("/me", response_model=UserResponse) async def get_me(current_user: User = Depends(get_current_user)): return UserResponse.model_validate(current_user) @router.patch("/me", response_model=UserResponse) async def update_me( user_update: UserUpdate, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): update_data = user_update.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(current_user, field, value) await db.commit() await db.refresh(current_user) return UserResponse.model_validate(current_user)