feat: implement configurable Xingbang risk agent on mini-openclaw core

This commit is contained in:
NathanAlex7
2026-09-08 01:08:34 +08:00
parent f2439ee5a3
commit 58fb2854dc
26 changed files with 1990 additions and 208 deletions
+52
View File
@@ -0,0 +1,52 @@
"""Server-configured identities; preview mode is limited to a local backend."""
import hmac
import json
import os
from urllib.parse import urlsplit
from fastapi import HTTPException, Request
def authorize(request: Request):
configured = os.getenv("XINGBANG_AUTH_USERS", "")
if not configured:
forwarded_host = request.headers.get("x-xingbang-client-host", request.headers.get("host", ""))
hostname = urlsplit("//"+forwarded_host).hostname
if os.getenv("XINGBANG_REQUIRE_AUTH") == "1" or not request.client or request.client.host not in ("127.0.0.1", "::1", "testclient"):
raise HTTPException(401, "请配置服务器身份认证后访问")
if hostname not in ("localhost", "127.0.0.1", "::1", "testserver"):
raise HTTPException(401, "本机预览仅接受回环地址;远程访问必须配置身份认证")
user = {"id": "local-preview", "role": "admin", "projects": ["*"], "preview": True}
else:
try:
accounts = json.loads(configured)
except ValueError:
raise HTTPException(503, "身份配置无效")
supplied = request.headers.get("authorization", "").removeprefix("Bearer ")
user = next((dict(u) for u in accounts if isinstance(u.get("token"), str) and hmac.compare_digest(u["token"], supplied)), None)
if not user or user.get("role") not in ("admin", "reviewer", "manager"):
raise HTTPException(401, "访问令牌无效")
user.pop("token", None)
user["preview"] = False
request.state.identity = user
path = request.url.path.split("/risk-agent/", 1)[-1]
if user["role"] == "manager":
permitted = path in ("catalog", "access/context", "runs/history") or (path.startswith("plans/") and path.endswith("/run"))
if not permitted:
raise HTTPException(403, "客户经理无权管理配置")
if user["role"] == "reviewer" and request.method != "GET" and not path.endswith("/review"):
raise HTTPException(403, "审核员仅可审核发布,不能修改配置或执行查询")
def check_project(request: Request, project_id: str):
user = request.state.identity
if user["role"] == "manager" and "*" not in user.get("projects", []) and project_id not in user.get("projects", []):
raise HTTPException(403, "无权访问该项目")
def visible_result(result, user):
if user["role"] != "manager":
return result
# Project evidence remains visible, configuration and SQL stay in the admin area.
filtered={k: v for k, v in result.items() if k not in ("configuration", "connections")}
filtered["plan"]={k:result["plan"].get(k) for k in ("id","name","version","description")}
return filtered