Files
rag/api/session_routes.py
lacerate551 90b915232a fix(security): 代码审查安全加固 — 三批次修复(6H/13M/12L)
第一批(快速修复):
- H6: main.py --debug 默认值 True→False,防止 Werkzeug RCE
- M2+M3: /search 增加 validate_query + top_k 范围限制(1-50)
- M4: context_count 范围限制(0-10) + 异常捕获
- L3: assert → raise RuntimeError(生产环境 API Key 检查)
- H1: SSE 错误事件移除 traceback 字段

第二批(安全加固):
- H2+H3: 文档接口路径遍历 realpath 校验 + 文件类型/大小限制
- H4+H5: 批量上传文件大小检查
- M6: LIKE 查询通配符转义
- M1: 37 处 str(e) 异常信息统一脱敏(6 文件)
- M5: CORS 生产环境限制来源
- M7: SESSION_MANAGER None 保护(503)
- M11: subprocess 参数注入防护(白名单 + -- 分隔符)

第三批(架构改进):
- M8+M9: 提取 JSON 解析共享工具(extract_json_object/list)
- M10: Prompt 注入检测防御(prompt_guard.py)
- M12: 解析器文件大小限制(Excel 50MB/TXT 20MB/PDF 100MB)
- M13: 全局单例竞态条件双重检查锁定(engine/bm25/intent_analyzer)
2026-06-05 15:26:32 +08:00

123 lines
3.5 KiB
Python

"""
会话管理 API
路由:
- GET /sessions - 用户会话列表
- GET /history/<session_id> - 获取会话历史
- DELETE /session/<session_id> - 删除会话
- POST /clear/<session_id> - 清空会话历史
"""
from flask import Blueprint, request, jsonify, current_app
from auth.gateway import require_gateway_auth
session_bp = Blueprint('session', __name__)
@session_bp.route('/sessions', methods=['GET'])
@require_gateway_auth
def get_sessions():
"""
获取用户的会话列表
返回:
{
"sessions": [
{
"session_id": "...",
"created_at": "...",
"last_active": "...",
"preview": "最后一条消息预览..."
}
]
}
"""
session_manager = current_app.config['SESSION_MANAGER']
if session_manager is None:
return jsonify({"error": "会话服务不可用"}), 503
user_id = request.current_user["user_id"]
sessions = session_manager.get_user_sessions(user_id, limit=20)
# 添加最后一条消息预览
for s in sessions:
history = session_manager.get_history(s["session_id"], limit=1)
if history:
s["preview"] = history[0]["content"][:50] + "..."
else:
s["preview"] = "空会话"
return jsonify({"sessions": sessions})
@session_bp.route('/history/<session_id>', methods=['GET'])
@require_gateway_auth
def get_history(session_id):
"""
获取会话历史
返回:
{
"history": [
{"role": "user/assistant", "content": "...", "created_at": "..."}
]
}
"""
session_manager = current_app.config['SESSION_MANAGER']
if session_manager is None:
return jsonify({"error": "会话服务不可用"}), 503
user_id = request.current_user["user_id"]
# 验证会话归属
sessions = session_manager.get_user_sessions(user_id)
session_ids = [s["session_id"] for s in sessions]
if session_id not in session_ids:
return jsonify({"error": "无权访问此会话"}), 403
history = session_manager.get_history(session_id, limit=100)
return jsonify({"history": history})
@session_bp.route('/session/<session_id>', methods=['DELETE'])
@require_gateway_auth
def delete_session(session_id):
"""删除会话"""
session_manager = current_app.config['SESSION_MANAGER']
if session_manager is None:
return jsonify({"error": "会话服务不可用"}), 503
user_id = request.current_user["user_id"]
# 验证会话归属
sessions = session_manager.get_user_sessions(user_id)
session_ids = [s["session_id"] for s in sessions]
if session_id not in session_ids:
return jsonify({"error": "无权删除此会话"}), 403
session_manager.delete_session(session_id)
return jsonify({"success": True, "message": "会话已删除"})
@session_bp.route('/clear/<session_id>', methods=['POST'])
@require_gateway_auth
def clear_history(session_id):
"""清空会话历史(保留会话)"""
session_manager = current_app.config['SESSION_MANAGER']
if session_manager is None:
return jsonify({"error": "会话服务不可用"}), 503
user_id = request.current_user["user_id"]
# 验证会话归属
sessions = session_manager.get_user_sessions(user_id)
session_ids = [s["session_id"] for s in sessions]
if session_id not in session_ids:
return jsonify({"error": "无权操作此会话"}), 403
session_manager.clear_history(session_id)
return jsonify({"success": True, "message": "历史已清空"})