""" 权限控制依赖项和装饰器 基于角色的访问控制(RBAC) """ from typing import Callable from fastapi import Depends, HTTPException, status from app.domain.models.role import UserRole from app.domain.schemas.user import UserInDB from app.auth.dependencies import get_current_active_user def require_role(required_role: UserRole): """ 要求特定角色或更高权限 用法: @router.get("/admin-only") async def admin_endpoint(user: UserInDB = Depends(require_role(UserRole.ADMIN))): ... Args: required_role: 需要的最低角色 Returns: 依赖函数 """ async def role_checker( current_user: UserInDB = Depends(get_current_active_user) ) -> UserInDB: user_role = UserRole(current_user.role) if not user_role.has_permission(required_role): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail=f"Insufficient permissions. Required role: {required_role.value}, " f"Your role: {user_role.value}" ) return current_user return role_checker # 预定义的权限检查依赖 require_admin = require_role(UserRole.ADMIN) require_operator = require_role(UserRole.OPERATOR) require_user = require_role(UserRole.USER) def get_current_admin( current_user: UserInDB = Depends(require_admin) ) -> UserInDB: """ 获取当前管理员用户 等同于 Depends(require_role(UserRole.ADMIN)) """ return current_user def get_current_operator( current_user: UserInDB = Depends(require_operator) ) -> UserInDB: """ 获取当前操作员用户(或更高权限) 等同于 Depends(require_role(UserRole.OPERATOR)) """ return current_user def check_resource_owner(user_id: int, current_user: UserInDB) -> bool: """ 检查是否是资源拥有者或管理员 Args: user_id: 资源拥有者ID current_user: 当前用户 Returns: 是否有权限 """ # 管理员可以访问所有资源 if UserRole(current_user.role).has_permission(UserRole.ADMIN): return True # 检查是否是资源拥有者 return current_user.id == user_id def require_owner_or_admin(user_id: int): """ 要求是资源拥有者或管理员 Args: user_id: 资源拥有者ID Returns: 依赖函数 """ async def owner_or_admin_checker( current_user: UserInDB = Depends(get_current_active_user) ) -> UserInDB: if not check_resource_owner(user_id, current_user): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="You don't have permission to access this resource" ) return current_user return owner_or_admin_checker