from fastapi import Depends, HTTPException, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from models.database import get_db from models.models import User from .jwt_utils import decode_access_token from .roles import can_manage_users, can_write, is_admin bearer_scheme = HTTPBearer(auto_error=False) async def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme), db: AsyncSession = Depends(get_db), ) -> User: if not credentials or not credentials.credentials: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="未登录或令牌缺失") payload = decode_access_token(credentials.credentials) if not payload or not payload.get("sub"): raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="登录已过期,请重新登录") try: user_id = int(payload["sub"]) except (TypeError, ValueError): raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="无效令牌") result = await db.execute(select(User).where(User.id == user_id)) user = result.scalar_one_or_none() if not user or not user.is_active: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户不存在或已禁用") return user async def require_admin(user: User = Depends(get_current_user)) -> User: if not is_admin(user.role): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="需要管理员权限") return user async def require_write(user: User = Depends(get_current_user)) -> User: if not can_write(user.role): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="当前角色只读,无法执行此操作") return user async def require_user_manager(user: User = Depends(get_current_user)) -> User: if not can_manage_users(user.role): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="需要管理员权限") return user