""" 用户管理 API 接口 演示权限控制的使用 """ from typing import List from fastapi import APIRouter, Depends, HTTPException, status from app.domain.schemas.user import UserResponse, UserUpdate, UserCreate from app.domain.models.role import UserRole from app.domain.schemas.user import UserInDB from app.infra.repositories.user_repository import UserRepository from app.auth.dependencies import get_user_repository, get_current_active_user from app.auth.permissions import get_current_admin, require_role, check_resource_owner router = APIRouter() @router.get("/", response_model=List[UserResponse]) async def list_users( skip: int = 0, limit: int = 100, current_user: UserInDB = Depends(require_role(UserRole.ADMIN)), user_repo: UserRepository = Depends(get_user_repository) ) -> List[UserResponse]: """ 获取用户列表(仅管理员) """ users = await user_repo.get_all_users(skip=skip, limit=limit) return [UserResponse.model_validate(user) for user in users] @router.get("/{user_id}", response_model=UserResponse) async def get_user( user_id: int, current_user: UserInDB = Depends(get_current_active_user), user_repo: UserRepository = Depends(get_user_repository) ) -> UserResponse: """ 获取用户详情 管理员可查看所有用户,普通用户只能查看自己 """ # 检查权限 if not check_resource_owner(user_id, current_user): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="You don't have permission to view this user" ) user = await user_repo.get_user_by_id(user_id) if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) return UserResponse.model_validate(user) @router.put("/{user_id}", response_model=UserResponse) async def update_user( user_id: int, user_update: UserUpdate, current_user: UserInDB = Depends(get_current_active_user), user_repo: UserRepository = Depends(get_user_repository) ) -> UserResponse: """ 更新用户信息 管理员可更新所有用户,普通用户只能更新自己(且不能修改角色) """ # 检查用户是否存在 target_user = await user_repo.get_user_by_id(user_id) if not target_user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) # 权限检查 is_owner = current_user.id == user_id is_admin = UserRole(current_user.role).has_permission(UserRole.ADMIN) if not is_owner and not is_admin: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="You don't have permission to update this user" ) # 非管理员不能修改角色和激活状态 if not is_admin: if user_update.role is not None: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Only admins can change user roles" ) if user_update.is_active is not None: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Only admins can change user active status" ) # 更新用户 updated_user = await user_repo.update_user(user_id, user_update) if not updated_user: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to update user" ) return UserResponse.model_validate(updated_user) @router.delete("/{user_id}") async def delete_user( user_id: int, current_user: UserInDB = Depends(get_current_admin), user_repo: UserRepository = Depends(get_user_repository) ) -> dict: """ 删除用户(仅管理员) """ # 不能删除自己 if current_user.id == user_id: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="You cannot delete your own account" ) success = await user_repo.delete_user(user_id) if not success: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) return {"message": "User deleted successfully"} @router.post("/{user_id}/activate") async def activate_user( user_id: int, current_user: UserInDB = Depends(get_current_admin), user_repo: UserRepository = Depends(get_user_repository) ) -> UserResponse: """ 激活用户(仅管理员) """ user_update = UserUpdate(is_active=True) updated_user = await user_repo.update_user(user_id, user_update) if not updated_user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) return UserResponse.model_validate(updated_user) @router.post("/{user_id}/deactivate") async def deactivate_user( user_id: int, current_user: UserInDB = Depends(get_current_admin), user_repo: UserRepository = Depends(get_user_repository) ) -> UserResponse: """ 停用用户(仅管理员) """ # 不能停用自己 if current_user.id == user_id: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="You cannot deactivate your own account" ) user_update = UserUpdate(is_active=False) updated_user = await user_repo.update_user(user_id, user_update) if not updated_user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) return UserResponse.model_validate(updated_user)