Files
rag/api/auth_routes.py
lacerate551 183a57e7f1 refactor(api): 统一响应格式迁移 + 异步任务系统 + 状态码体系完善
- 将全部路由文件(12个)的 jsonify 响应迁移至 success_response/error_response 统一格式
- 修复 sync_routes.py error_response 参数错误(P0)
- 新增异步任务系统:task_registry + task_routes
- 新增状态码:TASK_NOT_FOUND(4014)、TASK_CONFLICT(4015)、REINDEX_ERROR(5040)
- 修正 task_routes/exam_pkg 中语义不匹配的状态码
- 更新 curl 测试手册、后端对接规范文档
- 添加缓存性能报告和 Redis 迁移计划
2026-06-05 22:56:00 +08:00

200 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
认证与系统状态 API
路由:
- POST /auth/login - 模拟登录(仅开发环境)
- GET /stats - 系统统计 (管理员)
- GET /health - 健康检查
- GET /auth/me - 当前用户信息
"""
from flask import Blueprint, request, jsonify
from auth.gateway import require_gateway_auth, require_role, get_user_permissions, MOCK_USERS
from core.status_codes import SUCCESS, BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, PERMISSION_DENIED, INTERNAL_ERROR
from api.response_utils import success_response, error_response
import os
from pathlib import Path
from dotenv import load_dotenv
# 加载 .env 文件(从项目根目录)
env_path = Path(__file__).parent.parent / '.env'
load_dotenv(env_path)
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/auth/login', methods=['POST'])
def mock_login():
"""
模拟登录(仅开发环境)
请求体:
{
"username": "admin",
"password": "admin123"
}
返回:
{
"token": "mock-token-admin",
"user": {
"user_id": "admin001",
"username": "admin",
"role": "admin",
"department": "管理部"
}
}
测试账号:
- admin / admin123 (管理员,管理部)
- admin2 / admin456 (管理员,技术部)
- admin3 / admin789 (管理员,运营部)
- manager / manager123 (经理,财务部)
- user / test123 (普通用户,技术部)
"""
# 默认开启开发模式(生产环境需设置 DEV_MODE=false
if os.environ.get('DEV_MODE', 'true').lower() == 'false':
return error_response("FORBIDDEN", FORBIDDEN, "仅开发环境可用,请设置 DEV_MODE=true", http_status=403)
data = request.json or {}
username = data.get('username')
password = data.get('password')
user = MOCK_USERS.get(username)
if not user or user['password'] != password:
return error_response("UNAUTHORIZED", UNAUTHORIZED, "用户名或密码错误", http_status=401)
return success_response(data={
"token": f"mock-token-{username}",
"user": {
"user_id": user['user_id'],
"username": username,
"role": user['role'],
"department": user['department']
}
})
@auth_bp.route('/stats', methods=['GET'])
@require_gateway_auth
@require_role('admin')
def get_stats():
"""获取系统统计信息(仅管理员)"""
from flask import current_app
session_manager = current_app.config['SESSION_MANAGER']
return success_response(data=session_manager.get_stats())
@auth_bp.route('/health', methods=['GET'])
def health():
"""健康检查"""
return jsonify({
"status": "ok",
"knowledge_base": "多向量库模式 (按集合提供服务)",
"bm25_index": "动态按需加载",
"mode": "Agentic RAG"
})
@auth_bp.route('/auth/me', methods=['GET'])
@require_gateway_auth
def get_current_user():
"""
获取当前用户信息
开发模式下支持模拟用户,生产模式下用户信息由后端控制。
"""
user = request.current_user
return success_response(data={
"user_id": user["user_id"],
"username": user["username"],
"role": user["role"],
"department": user["department"],
"permissions": get_user_permissions(user["role"])
})
@auth_bp.route('/auth/users', methods=['GET'])
@require_gateway_auth
def get_users():
"""
获取用户列表(仅开发环境)
返回:
{
"users": [
{
"user_id": "admin001",
"username": "admin",
"role": "admin",
"department": "管理部",
"is_active": true
}
]
}
"""
dev_mode = os.environ.get('DEV_MODE', 'true').lower() != 'false'
if not dev_mode:
return error_response("FORBIDDEN", FORBIDDEN, "仅开发环境可用", http_status=403)
users = []
for username, info in MOCK_USERS.items():
users.append({
"user_id": info["user_id"],
"username": username,
"role": info["role"],
"department": info["department"],
"is_active": True # 模拟用户默认都是活跃状态
})
return success_response(data={"users": users})
@auth_bp.route('/auth/users/<user_id>', methods=['PUT'])
@require_gateway_auth
def update_user(user_id):
"""
更新用户信息(仅开发环境,模拟操作)
请求体:
{
"is_active": false
}
"""
dev_mode = os.environ.get('DEV_MODE', 'true').lower() != 'false'
if not dev_mode:
return error_response("FORBIDDEN", FORBIDDEN, "仅开发环境可用", http_status=403)
# 模拟用户不支持真正的状态切换,直接返回成功
return success_response(data={"message": "操作成功(模拟)", "user_id": user_id})
@auth_bp.route('/auth/change-password', methods=['POST'])
@require_gateway_auth
def change_password():
"""
修改密码(仅开发环境,模拟操作)
请求体:
{
"old_password": "xxx",
"new_password": "xxx"
}
"""
dev_mode = os.environ.get('DEV_MODE', 'true').lower() != 'false'
if not dev_mode:
return error_response("FORBIDDEN", FORBIDDEN, "仅开发环境可用", http_status=403)
data = request.json or {}
old_password = data.get('old_password')
new_password = data.get('new_password')
if not old_password or not new_password:
return error_response("MISSING_PARAMS", BAD_REQUEST, "请提供旧密码和新密码", http_status=400)
if len(new_password) < 6:
return error_response("INVALID_PARAMS", BAD_REQUEST, "新密码至少6位", http_status=400)
# 模拟环境直接返回成功
return success_response(message="密码修改成功(模拟)")