WIP-CHECKPOINT[auth-refactor]: 固化工程师崩溃前部分成果 + 同树其他未提交WIP(仅源码,不含密钥/二进制)-- 待重激活工程师续作
This commit is contained in:
@@ -0,0 +1,367 @@
|
||||
# =============================================================================
|
||||
# 企微IT智能服务台 — 管理员用户管理 API
|
||||
# =============================================================================
|
||||
# 说明:管理员用户的 CRUD API
|
||||
# 端点:
|
||||
# GET /api/admin/users — 获取管理员列表
|
||||
# POST /api/admin/users — 创建管理员
|
||||
# GET /api/admin/users/{id} — 获取管理员详情
|
||||
# PUT /api/admin/users/{id} — 更新管理员
|
||||
# DELETE /api/admin/users/{id} — 删除管理员
|
||||
# POST /api/admin/users/{id}/reset-password — 重置密码
|
||||
# =============================================================================
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.database import get_db
|
||||
from app.dependencies import UserInfo, get_current_user, require_role
|
||||
from app.schemas.admin_user import (
|
||||
AdminUserCreateRequest,
|
||||
AdminUserListResponse,
|
||||
AdminUserResetPasswordRequest,
|
||||
AdminUserResponse,
|
||||
AdminUserUpdateRequest,
|
||||
)
|
||||
from app.services.admin_user_service import AdminUserService
|
||||
from app.utils.response import AppException, success_response
|
||||
from app.utils.error_codes import ErrorCode
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 创建路由器
|
||||
router = APIRouter(prefix="/admin/users", tags=["管理员用户管理"])
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 0. GET /api/admin/users/me — 获取当前登录用户信息
|
||||
# =============================================================================
|
||||
@router.get("/me", response_model=None)
|
||||
async def get_current_admin_user(
|
||||
current_user: UserInfo = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""获取当前登录的管理员用户信息。
|
||||
|
||||
无需额外权限,任何已登录用户都可以访问。
|
||||
|
||||
Args:
|
||||
current_user: 当前用户
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
当前用户信息
|
||||
"""
|
||||
service = AdminUserService(db)
|
||||
agent = await service.get_user_by_user_id(current_user.employee_id)
|
||||
|
||||
if not agent:
|
||||
raise AppException(ErrorCode.NOT_FOUND, "用户不存在")
|
||||
|
||||
return success_response(data=AdminUserResponse(
|
||||
id=agent.id,
|
||||
user_id=agent.user_id,
|
||||
name=agent.name,
|
||||
role=agent.role,
|
||||
is_active=agent.status == "online",
|
||||
mfa_enabled=agent.mfa_enabled,
|
||||
mfa_bound_at=agent.mfa_bound_at,
|
||||
created_at=agent.created_at,
|
||||
updated_at=agent.updated_at,
|
||||
).model_dump())
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 1. GET /api/admin/users — 获取管理员列表
|
||||
# =============================================================================
|
||||
@router.get("", response_model=None)
|
||||
async def list_admin_users(
|
||||
page: int = Query(1, ge=1, description="页码"),
|
||||
page_size: int = Query(20, ge=1, le=100, description="每页数量"),
|
||||
is_active: Optional[bool] = Query(None, description="是否激活(true=在线,false=离线)"),
|
||||
current_user: UserInfo = Depends(require_role("admin")),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""获取管理员用户列表。
|
||||
|
||||
需要 admin 或 super_admin 角色。
|
||||
|
||||
Args:
|
||||
page: 页码
|
||||
page_size: 每页数量
|
||||
is_active: 按激活状态过滤
|
||||
current_user: 当前用户
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
管理员列表
|
||||
"""
|
||||
service = AdminUserService(db)
|
||||
items, total = await service.list_admin_users(
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
is_active=is_active,
|
||||
)
|
||||
|
||||
# 转换为响应格式
|
||||
user_responses = []
|
||||
for agent in items:
|
||||
user_responses.append(AdminUserResponse(
|
||||
id=agent.id,
|
||||
user_id=agent.user_id,
|
||||
name=agent.name,
|
||||
role=agent.role,
|
||||
is_active=agent.status == "online",
|
||||
mfa_enabled=agent.mfa_enabled,
|
||||
mfa_bound_at=agent.mfa_bound_at,
|
||||
created_at=agent.created_at,
|
||||
updated_at=agent.updated_at,
|
||||
))
|
||||
|
||||
return success_response(data=AdminUserListResponse(
|
||||
items=user_responses,
|
||||
total=total,
|
||||
).model_dump())
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 2. POST /api/admin/users — 创建管理员
|
||||
# =============================================================================
|
||||
@router.post("", response_model=None)
|
||||
async def create_admin_user(
|
||||
body: AdminUserCreateRequest,
|
||||
current_user: UserInfo = Depends(require_role("super_admin")),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""创建管理员用户。
|
||||
|
||||
需要 super_admin 角色。
|
||||
|
||||
Args:
|
||||
body: 创建请求
|
||||
current_user: 当前用户
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
创建的用户信息
|
||||
"""
|
||||
service = AdminUserService(db)
|
||||
|
||||
try:
|
||||
agent = await service.create_admin_user(
|
||||
user_id=body.user_id,
|
||||
name=body.name,
|
||||
role=body.role,
|
||||
password=body.password,
|
||||
)
|
||||
await db.commit()
|
||||
|
||||
return success_response(data=AdminUserResponse(
|
||||
id=agent.id,
|
||||
user_id=agent.user_id,
|
||||
name=agent.name,
|
||||
role=agent.role,
|
||||
is_active=agent.status == "online",
|
||||
mfa_enabled=agent.mfa_enabled,
|
||||
mfa_bound_at=agent.mfa_bound_at,
|
||||
created_at=agent.created_at,
|
||||
updated_at=agent.updated_at,
|
||||
).model_dump())
|
||||
|
||||
except AppException:
|
||||
await db.rollback()
|
||||
raise
|
||||
except Exception as e:
|
||||
await db.rollback()
|
||||
logger.error(f"创建管理员失败: {e}")
|
||||
raise AppException(ErrorCode.INTERNAL_ERROR, "创建管理员失败")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 3. GET /api/admin/users/{id} — 获取管理员详情
|
||||
# =============================================================================
|
||||
@router.get("/{id}", response_model=None)
|
||||
async def get_admin_user(
|
||||
id: str,
|
||||
current_user: UserInfo = Depends(require_role("admin")),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""获取管理员用户详情。
|
||||
|
||||
需要 admin 或 super_admin 角色。
|
||||
|
||||
Args:
|
||||
id: 用户ID
|
||||
current_user: 当前用户
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
用户详情
|
||||
"""
|
||||
service = AdminUserService(db)
|
||||
agent = await service.get_user_by_id(id)
|
||||
|
||||
if not agent:
|
||||
raise AppException(ErrorCode.NOT_FOUND, "用户不存在")
|
||||
|
||||
return success_response(data=AdminUserResponse(
|
||||
id=agent.id,
|
||||
user_id=agent.user_id,
|
||||
name=agent.name,
|
||||
role=agent.role,
|
||||
is_active=agent.status == "online",
|
||||
mfa_enabled=agent.mfa_enabled,
|
||||
mfa_bound_at=agent.mfa_bound_at,
|
||||
created_at=agent.created_at,
|
||||
updated_at=agent.updated_at,
|
||||
).model_dump())
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 4. PUT /api/admin/users/{id} — 更新管理员
|
||||
# =============================================================================
|
||||
@router.put("/{id}", response_model=None)
|
||||
async def update_admin_user(
|
||||
id: str,
|
||||
body: AdminUserUpdateRequest,
|
||||
current_user: UserInfo = Depends(require_role("admin")),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""更新管理员用户。
|
||||
|
||||
需要 admin 或 super_admin 角色。
|
||||
- admin 角色只能更新普通 admin
|
||||
- super_admin 角色可以更新所有用户
|
||||
|
||||
Args:
|
||||
id: 用户ID
|
||||
body: 更新请求
|
||||
current_user: 当前用户
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
更新后的用户信息
|
||||
"""
|
||||
# 权限检查:非 super_admin 不能修改 super_admin
|
||||
if "super_admin" not in current_user.roles:
|
||||
target = await AdminUserService(db).get_user_by_id(id)
|
||||
if target and target.role == "super_admin":
|
||||
raise AppException(ErrorCode.FORBIDDEN, "无法修改超级管理员")
|
||||
|
||||
service = AdminUserService(db)
|
||||
|
||||
try:
|
||||
agent = await service.update_admin_user(
|
||||
id=id,
|
||||
name=body.name,
|
||||
role=body.role,
|
||||
is_active=body.is_active,
|
||||
)
|
||||
await db.commit()
|
||||
|
||||
return success_response(data=AdminUserResponse(
|
||||
id=agent.id,
|
||||
user_id=agent.user_id,
|
||||
name=agent.name,
|
||||
role=agent.role,
|
||||
is_active=agent.status == "online",
|
||||
mfa_enabled=agent.mfa_enabled,
|
||||
mfa_bound_at=agent.mfa_bound_at,
|
||||
created_at=agent.created_at,
|
||||
updated_at=agent.updated_at,
|
||||
).model_dump())
|
||||
|
||||
except AppException:
|
||||
await db.rollback()
|
||||
raise
|
||||
except Exception as e:
|
||||
await db.rollback()
|
||||
logger.error(f"更新管理员失败: {e}")
|
||||
raise AppException(ErrorCode.INTERNAL_ERROR, "更新管理员失败")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 5. DELETE /api/admin/users/{id} — 删除管理员
|
||||
# =============================================================================
|
||||
@router.delete("/{id}", response_model=None)
|
||||
async def delete_admin_user(
|
||||
id: str,
|
||||
current_user: UserInfo = Depends(require_role("super_admin")),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""删除管理员用户。
|
||||
|
||||
需要 super_admin 角色。
|
||||
|
||||
Args:
|
||||
id: 用户ID
|
||||
current_user: 当前用户
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
删除结果
|
||||
"""
|
||||
service = AdminUserService(db)
|
||||
|
||||
try:
|
||||
await service.delete_admin_user(id)
|
||||
await db.commit()
|
||||
|
||||
return success_response(data={"message": "删除成功"})
|
||||
|
||||
except AppException:
|
||||
await db.rollback()
|
||||
raise
|
||||
except Exception as e:
|
||||
await db.rollback()
|
||||
logger.error(f"删除管理员失败: {e}")
|
||||
raise AppException(ErrorCode.INTERNAL_ERROR, "删除管理员失败")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 6. POST /api/admin/users/{id}/reset-password — 重置密码
|
||||
# =============================================================================
|
||||
@router.post("/{id}/reset-password", response_model=None)
|
||||
async def reset_password(
|
||||
id: str,
|
||||
body: AdminUserResetPasswordRequest,
|
||||
current_user: UserInfo = Depends(require_role("admin")),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""重置管理员密码。
|
||||
|
||||
需要 admin 或 super_admin 角色。
|
||||
|
||||
Args:
|
||||
id: 用户ID
|
||||
body: 重置请求
|
||||
current_user: 当前用户
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
重置结果
|
||||
"""
|
||||
# 权限检查:非 super_admin 不能重置 super_admin 的密码
|
||||
if "super_admin" not in current_user.roles:
|
||||
target = await AdminUserService(db).get_user_by_id(id)
|
||||
if target and target.role == "super_admin":
|
||||
raise AppException(ErrorCode.FORBIDDEN, "无法重置超级管理员密码")
|
||||
|
||||
service = AdminUserService(db)
|
||||
|
||||
try:
|
||||
await service.reset_password(id, body.new_password)
|
||||
await db.commit()
|
||||
|
||||
return success_response(data={"message": "密码重置成功"})
|
||||
|
||||
except AppException:
|
||||
await db.rollback()
|
||||
raise
|
||||
except Exception as e:
|
||||
await db.rollback()
|
||||
logger.error(f"重置密码失败: {e}")
|
||||
raise AppException(ErrorCode.INTERNAL_ERROR, "重置密码失败")
|
||||
Reference in New Issue
Block a user