""" 认证与系统状态 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/', 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="密码修改成功(模拟)")