mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 05:50:44 +08:00
将高风险 public 工具开关改为按用户生效。
在 Admin 工作区路径页新增并保存用户级 public_tools_allow_high,扩展用户路径策略存储字段并让 catalog 风险门控优先读取该用户策略(环境变量仍可覆盖)。 Made-with: Cursor
This commit is contained in:
parent
e06184cc2f
commit
5ef9abb069
4 changed files with 81 additions and 11 deletions
|
|
@ -1401,8 +1401,18 @@ def build_admin_router() -> APIRouter:
|
|||
raise HTTPException(status_code=403, detail="workspace_paths_self_only")
|
||||
row = store.get_user_workspace_path_allowlist(tenant_id=tid, user_id=uid)
|
||||
if not row:
|
||||
return {"ok": True, "from_db": False, "policy": {"extra_roots": "", "allow_any_path": False}}
|
||||
return {"ok": True, "from_db": True, "policy": row}
|
||||
return {
|
||||
"ok": True,
|
||||
"from_db": False,
|
||||
"policy": {"extra_roots": "", "allow_any_path": False},
|
||||
"public_tools_allow_high": False,
|
||||
}
|
||||
return {
|
||||
"ok": True,
|
||||
"from_db": True,
|
||||
"policy": row,
|
||||
"public_tools_allow_high": bool(row.get("allow_high_risk_public_tools")),
|
||||
}
|
||||
|
||||
@router.post("/admin/api/users/workspace-path-policy")
|
||||
def api_users_workspace_path_policy_save(
|
||||
|
|
@ -1429,11 +1439,13 @@ def build_admin_router() -> APIRouter:
|
|||
if err:
|
||||
return {"ok": False, "error": err}
|
||||
allow_any = bool(payload.get("allow_any_path", False))
|
||||
allow_high = bool(payload.get("public_tools_allow_high", False))
|
||||
store.upsert_user_workspace_path_allowlist(
|
||||
tenant_id=tid,
|
||||
user_id=uid,
|
||||
extra_roots=norm,
|
||||
allow_any_path=allow_any,
|
||||
allow_high_risk_public_tools=allow_high,
|
||||
)
|
||||
store.add_admin_audit_log(
|
||||
actor_tenant_id=ctx["tenant_id"],
|
||||
|
|
@ -1442,10 +1454,15 @@ def build_admin_router() -> APIRouter:
|
|||
target_type="user",
|
||||
target_id=uid,
|
||||
status="ok",
|
||||
detail={"tenant_id": tid, "allow_any_path": allow_any, "extra_roots_preview": norm[:500]},
|
||||
detail={
|
||||
"tenant_id": tid,
|
||||
"allow_any_path": allow_any,
|
||||
"public_tools_allow_high": bool(allow_high),
|
||||
"extra_roots_preview": norm[:500],
|
||||
},
|
||||
)
|
||||
row = store.get_user_workspace_path_allowlist(tenant_id=tid, user_id=uid)
|
||||
return {"ok": True, "policy": row or {}}
|
||||
return {"ok": True, "policy": row or {}, "public_tools_allow_high": bool((row or {}).get("allow_high_risk_public_tools"))}
|
||||
|
||||
@router.post("/admin/api/users/delete-unbound")
|
||||
def api_users_delete_unbound(
|
||||
|
|
|
|||
|
|
@ -208,6 +208,9 @@ const I18N = {
|
|||
"workspacePaths.allowAny": "允许任意路径(高风险)",
|
||||
"workspacePaths.allowAnyHint":
|
||||
"仅作用于内置工作区工具(read_file / glob 等)的路径校验;不会放开 MCP filesystem,也不会自动把整盘写进 MCP。需要 MCP 列目录的盘符/目录请填在「额外根路径」或环境变量 AIA_WORKSPACE_EXTRA_ROOTS。",
|
||||
"workspacePaths.allowHighTools": "允许高风险 Public 工具(全局)",
|
||||
"workspacePaths.allowHighToolsHint":
|
||||
"开启后将放开 run_command / write_file / edit_file 等高风险 public 工具的模型可见性(等效 AIA_PUBLIC_TOOLS_ALLOW_HIGH=1)。",
|
||||
"workspacePaths.load": "加载",
|
||||
"workspacePaths.save": "保存",
|
||||
"workspacePaths.status": "状态",
|
||||
|
|
@ -624,6 +627,9 @@ const I18N = {
|
|||
"workspacePaths.allowAny": "Allow any path (high risk)",
|
||||
"workspacePaths.allowAnyHint":
|
||||
"Applies only to built-in workspace tools (read_file / glob, etc.); it does not unlock MCP filesystem or auto-mount whole disks for MCP. List directories you need in “Extra roots” or AIA_WORKSPACE_EXTRA_ROOTS.",
|
||||
"workspacePaths.allowHighTools": "Allow high-risk public tools (global)",
|
||||
"workspacePaths.allowHighToolsHint":
|
||||
"When enabled, high-risk public tools (run_command / write_file / edit_file, etc.) become model-visible (equivalent to AIA_PUBLIC_TOOLS_ALLOW_HIGH=1).",
|
||||
"workspacePaths.load": "Load",
|
||||
"workspacePaths.save": "Save",
|
||||
"workspacePaths.status": "Status",
|
||||
|
|
@ -6856,8 +6862,13 @@ async function renderWorkspacePaths() {
|
|||
style: "min-height:88px;font-family:monospace;",
|
||||
});
|
||||
const allowAnyCb = el("input", { type: "checkbox" });
|
||||
const allowHighToolsCb = el("input", { type: "checkbox" });
|
||||
const status = el("div", { class: "muted", text: "" });
|
||||
const canWrite = hasPermission("admin:user:write") || canWsWrite;
|
||||
const canTogglePublicHigh = hasPermission("admin:user:write");
|
||||
if (!canTogglePublicHigh) {
|
||||
allowHighToolsCb.disabled = true;
|
||||
}
|
||||
|
||||
const getEffectiveTid = () => (selfService ? sessionTid : String(tenantSel.value || ""));
|
||||
const getEffectiveUid = () => (selfService ? sessionUid : String(userSel.value || ""));
|
||||
|
|
@ -6904,6 +6915,7 @@ async function renderWorkspacePaths() {
|
|||
const pol = r.policy || {};
|
||||
extraInput.value = String(pol.extra_roots || "");
|
||||
allowAnyCb.checked = !!pol.allow_any_path;
|
||||
allowHighToolsCb.checked = !!r.public_tools_allow_high;
|
||||
status.textContent = (r.from_db ? t("workspacePaths.fromDb") + " · " : "") + JSON.stringify(pol);
|
||||
} catch (e) {
|
||||
status.textContent = String(e && e.message ? e.message : e);
|
||||
|
|
@ -6937,12 +6949,16 @@ async function renderWorkspacePaths() {
|
|||
if (!tid || !uid) return;
|
||||
status.textContent = "…";
|
||||
try {
|
||||
const r = await apiPost("/admin/api/users/workspace-path-policy", {
|
||||
const payload = {
|
||||
tenant_id: tid,
|
||||
user_id: uid,
|
||||
extra_roots: extraInput.value,
|
||||
allow_any_path: !!allowAnyCb.checked,
|
||||
});
|
||||
};
|
||||
if (canTogglePublicHigh) {
|
||||
payload.public_tools_allow_high = !!allowHighToolsCb.checked;
|
||||
}
|
||||
const r = await apiPost("/admin/api/users/workspace-path-policy", payload);
|
||||
if (!r.ok) {
|
||||
status.textContent = String(r.error || "error");
|
||||
return;
|
||||
|
|
@ -6979,6 +6995,11 @@ async function renderWorkspacePaths() {
|
|||
el("span", { text: t("workspacePaths.allowAny") }),
|
||||
]),
|
||||
el("div", { class: "muted", style: "margin-top:6px;line-height:1.45;", text: t("workspacePaths.allowAnyHint") }),
|
||||
el("label", { class: "row", style: "align-items:center;gap:8px;margin-top:10px;" }, [
|
||||
allowHighToolsCb,
|
||||
el("span", { text: t("workspacePaths.allowHighTools") }),
|
||||
]),
|
||||
el("div", { class: "muted", style: "margin-top:6px;line-height:1.45;", text: t("workspacePaths.allowHighToolsHint") }),
|
||||
el("div", { class: "row", style: "margin-top:10px;gap:8px;" }, [loadBtn, saveBtn]),
|
||||
el("div", { class: "muted", style: "margin-top:8px;" }, [el("span", { text: t("workspacePaths.status") + ": " }), status]),
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue