diff --git a/edc-web/app/auth.py b/edc-web/app/auth.py index 8d74806..969c2a7 100644 --- a/edc-web/app/auth.py +++ b/edc-web/app/auth.py @@ -42,6 +42,23 @@ def load_user(user_id): def init_auth(app): login_manager.init_app(app) + # analyst 角色:全局路由白名单拦截 + ANALYST_ALLOWED = { + "auth.login", "auth.logout", "auth.change_password", + "test_data.test_data_page", + "test_data.api_test_data", + "test_data.api_chart_data", + "test_data.api_export", + "test_data.api_delete", # 自身有 inline 角色检查 + } + + @app.before_request + def _restrict_analyst(): + if current_user.is_authenticated and current_user.role == "analyst": + ep = request.endpoint or "" + if ep not in ANALYST_ALLOWED and not ep.startswith("static"): + return "权限不足:当前角色为 analyst,仅可访问测试数据", 403 + # ─── 装饰器 ──────────────────────────────────────────────────────── diff --git a/edc-web/app/routes/test_data.py b/edc-web/app/routes/test_data.py index 70cb2cb..3cb8862 100644 --- a/edc-web/app/routes/test_data.py +++ b/edc-web/app/routes/test_data.py @@ -10,12 +10,14 @@ bp = Blueprint("test_data", __name__) @bp.route("/test-data") +@login_required def test_data_page(): """测试信息页""" return render_template("test_data.html") @bp.route("/api/test-data") +@login_required def api_test_data(): """分页查询测试数据""" page = request.args.get("page", 1, type=int) @@ -38,6 +40,7 @@ def api_test_data(): @bp.route("/api/test-data/chart") +@login_required def api_chart_data(): """返回图表所需全部数据(不分页)""" serial = request.args.get("serial", "", type=str) @@ -51,6 +54,7 @@ def api_chart_data(): return jsonify({"records": records, "total": len(records)}) @bp.route("/api/test-data/export") +@login_required def api_export(): """导出测试数据为 CSV""" serial = request.args.get("serial", "", type=str) diff --git a/edc-web/app/templates/base.html b/edc-web/app/templates/base.html index 25fc311..ea51848 100644 --- a/edc-web/app/templates/base.html +++ b/edc-web/app/templates/base.html @@ -8,7 +8,9 @@