from typing import Annotated import redis.asyncio as redis from fastapi import Depends, Header, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from app.core.roles import ROLE_ADMIN, ROLE_OEM,ROLE_AGENT from app.core.security import decode_access_token from app.database import get_db from app.models.user import User from app.redis_client import redis_dependency from app.services import auth as auth_service DbSession = Annotated[AsyncSession, Depends(get_db)] RedisClient = Annotated[redis.Redis, Depends(redis_dependency)] async def get_current_user( db: DbSession, redis: RedisClient, authorization: Annotated[str | None, Header()] = None, ) -> User: if not authorization or not authorization.lower().startswith("bearer "): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="未提供有效的认证令牌", ) token = authorization[7:].strip() if not token: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="未提供有效的认证令牌", ) user_id = await auth_service.session_user_id(redis, token) if user_id is None: payload = decode_access_token(token) if payload is None or payload.get("sub") is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="令牌无效或已过期", ) user_id = int(payload["sub"]) user = await auth_service.get_user_by_id(db, user_id) if user is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="用户不存在", ) return user CurrentUser = Annotated[User, Depends(get_current_user)] async def require_admin(current_user: CurrentUser) -> User: if current_user.role_id != ROLE_ADMIN: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="需要管理员权限", ) return current_user async def require_oem(current_user: CurrentUser) -> User: if current_user.role_id != ROLE_OEM: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="需要 OEM 权限", ) return current_user async def require_agent(current_user: CurrentUser) -> User: if current_user.role_id != ROLE_AGENT: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="需要代理权限", ) return current_user AdminUser = Annotated[User, Depends(require_admin)] OemUser = Annotated[User, Depends(require_oem)] AgentUser = Annotated[User, Depends(require_agent)]