feat: 添加安全模块 + Dockerfile添加curl支持健康检查

主要更新:
- 新增 security/ 安全模块 (风险评估、威胁检测、蜜罐等)
- Dockerfile 添加 curl 以支持 Docker 健康检查
- 前端页面更新 (管理后台、用户端)
- 数据库迁移和 schema 更新
- 新增 kdocs 上传服务
- 添加安全相关测试用例

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Yu Yon
2026-01-08 17:48:33 +08:00
parent e3b0c35da6
commit 53c78e8e3c
76 changed files with 8563 additions and 4709 deletions

View File

@@ -6,7 +6,7 @@ import json
import os
from typing import Optional
from flask import Blueprint, current_app, redirect, render_template, session, url_for
from flask import Blueprint, current_app, redirect, render_template, request, session, url_for
from flask_login import current_user, login_required
from routes.decorators import admin_required
@@ -36,10 +36,18 @@ def render_app_spa_or_legacy(
logger.warning(f"[app_spa] manifest缺少入口文件: {manifest_path}")
return render_template(legacy_template_name, **legacy_context)
app_spa_js_file = f"app/{js_file}"
app_spa_css_files = [f"app/{p}" for p in css_files]
app_spa_build_id = _get_asset_build_id(
os.path.join(current_app.root_path, "static"),
[app_spa_js_file, *app_spa_css_files],
)
return render_template(
"app.html",
app_spa_js_file=f"app/{js_file}",
app_spa_css_files=[f"app/{p}" for p in css_files],
app_spa_js_file=app_spa_js_file,
app_spa_css_files=app_spa_css_files,
app_spa_build_id=app_spa_build_id,
app_spa_initial_state=spa_initial_state,
)
except FileNotFoundError:
@@ -50,6 +58,27 @@ def render_app_spa_or_legacy(
return render_template(legacy_template_name, **legacy_context)
def _get_asset_build_id(static_root: str, rel_paths: list[str]) -> Optional[str]:
mtimes = []
for rel_path in rel_paths:
if not rel_path:
continue
try:
mtimes.append(os.path.getmtime(os.path.join(static_root, rel_path)))
except OSError:
continue
if not mtimes:
return None
return str(int(max(mtimes)))
def _is_legacy_admin_user_agent(user_agent: str) -> bool:
if not user_agent:
return False
ua = user_agent.lower()
return "msie" in ua or "trident/" in ua
@pages_bp.route("/")
def index():
"""主页 - 重定向到登录或应用"""
@@ -96,6 +125,8 @@ def admin_login_page():
@admin_required
def admin_page():
"""后台管理页面"""
if request.args.get("legacy") == "1" or _is_legacy_admin_user_agent(request.headers.get("User-Agent", "")):
return render_template("admin_legacy.html")
logger = get_logger()
manifest_path = os.path.join(current_app.root_path, "static", "admin", ".vite", "manifest.json")
try:
@@ -110,10 +141,18 @@ def admin_page():
logger.warning(f"[admin_spa] manifest缺少入口文件: {manifest_path}")
return render_template("admin_legacy.html")
admin_spa_js_file = f"admin/{js_file}"
admin_spa_css_files = [f"admin/{p}" for p in css_files]
admin_spa_build_id = _get_asset_build_id(
os.path.join(current_app.root_path, "static"),
[admin_spa_js_file, *admin_spa_css_files],
)
return render_template(
"admin.html",
admin_spa_js_file=f"admin/{js_file}",
admin_spa_css_files=[f"admin/{p}" for p in css_files],
admin_spa_js_file=admin_spa_js_file,
admin_spa_css_files=admin_spa_css_files,
admin_spa_build_id=admin_spa_build_id,
)
except FileNotFoundError:
logger.warning(f"[admin_spa] 未找到manifest: {manifest_path},回退旧版后台模板")