from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.orm import Session from typing import List import bcrypt from ..database import get_db from ..models import User from ..schemas import UserCreate, UserUpdate, UserResponse from ..core.audit_logger import audit_log router = APIRouter(prefix="/api/admin", tags=["admin"]) def get_current_admin(request: Request, db: Session = Depends(get_db)): """依赖项:验证管理员权限""" from .auth import verify_token auth_header = request.headers.get("Authorization") if not auth_header or not auth_header.startswith("Bearer "): raise HTTPException(status_code=401, detail="未提供认证令牌") token = auth_header.split(" ")[1] user = verify_token(token, db) if user.role != "admin": raise HTTPException(status_code=403, detail="需要管理员权限") return user @router.get("/users", response_model=List[UserResponse]) def list_users( request: Request, db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin) ): """获取用户列表(管理员)""" users = db.query(User).all() return [UserResponse.from_orm(u) for u in users] @router.post("/users", response_model=UserResponse) def create_user( user_data: UserCreate, request: Request, db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin) ): """创建新用户(管理员)""" # 检查用户名是否已存在 existing = db.query(User).filter(User.username == user_data.username).first() if existing: raise HTTPException(status_code=400, detail="用户名已存在") # bcrypt 密码哈希 hashed_password = bcrypt.hashpw(user_data.password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') user = User( username=user_data.username, password_hash=hashed_password, role=user_data.role or "user" ) db.add(user) db.commit() db.refresh(user) audit_log( action="create_user", user=admin_user, resource_type="user", resource_id=str(user.id), details={"username": user.username, "role": user.role}, ip_address=request.client.host if request.client else None, user_agent=request.headers.get("user-agent", ""), db=db ) return UserResponse.from_orm(user) @router.put("/users/{user_id}", response_model=UserResponse) def update_user( user_id: int, user_update: UserUpdate, request: Request, db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin) ): """更新用户(管理员)""" user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="用户不存在") changes = {} if user_update.username is not None: if user_update.username != user.username: existing = db.query(User).filter(User.username == user_update.username).first() if existing: raise HTTPException(status_code=400, detail="用户名已存在") changes["username"] = {"old": user.username, "new": user_update.username} user.username = user_update.username if user_update.password is not None: changes["password"] = {"changed": True} user.password_hash = bcrypt.hashpw(user_update.password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') if user_update.role is not None and user_update.role != user.role: changes["role"] = {"old": user.role, "new": user_update.role} user.role = user_update.role db.commit() db.refresh(user) audit_log( action="update_user", user=admin_user, resource_type="user", resource_id=str(user.id), details=changes, ip_address=request.client.host if request.client else None, user_agent=request.headers.get("user-agent", ""), db=db ) return UserResponse.from_orm(user) @router.delete("/users/{user_id}") def delete_user( user_id: int, request: Request, db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin) ): """删除用户(管理员)""" user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="用户不存在") if user.role == "admin": raise HTTPException(status_code=400, detail="不能删除管理员用户") username = user.username # 保存用于日志 db.delete(user) db.commit() audit_log( action="delete_user", user=admin_user, resource_type="user", resource_id=str(user_id), details={"username": username}, ip_address=request.client.host if request.client else None, user_agent=request.headers.get("user-agent", ""), db=db ) return {"message": "删除成功"}