mirror of https://github.com/openclaw/openclaw.git
fix: preserve explicit node routing under elevated auto exec
This commit is contained in:
parent
7bae391f33
commit
c0a0e295cb
|
|
@ -221,6 +221,22 @@ describe("resolveExecTarget", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("keeps explicit node override under elevated requests when configured target is auto", () => {
|
||||
expect(
|
||||
resolveExecTarget({
|
||||
configuredTarget: "auto",
|
||||
requestedTarget: "node",
|
||||
elevatedRequested: true,
|
||||
sandboxAvailable: false,
|
||||
}),
|
||||
).toMatchObject({
|
||||
configuredTarget: "auto",
|
||||
requestedTarget: "node",
|
||||
selectedTarget: "node",
|
||||
effectiveHost: "node",
|
||||
});
|
||||
});
|
||||
|
||||
it("honours node target for elevated requests when configured target is node", () => {
|
||||
expect(
|
||||
resolveExecTarget({
|
||||
|
|
@ -252,20 +268,17 @@ describe("resolveExecTarget", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("silently discards mismatched requestedTarget under elevated+node", () => {
|
||||
expect(
|
||||
it("rejects mismatched requestedTarget under elevated+node", () => {
|
||||
expect(() =>
|
||||
resolveExecTarget({
|
||||
configuredTarget: "node",
|
||||
requestedTarget: "gateway",
|
||||
elevatedRequested: true,
|
||||
sandboxAvailable: false,
|
||||
}),
|
||||
).toMatchObject({
|
||||
configuredTarget: "node",
|
||||
requestedTarget: "gateway",
|
||||
selectedTarget: "node",
|
||||
effectiveHost: "node",
|
||||
});
|
||||
).toThrow(
|
||||
"exec host not allowed (requested gateway; configured host is node; set tools.exec.host=gateway or auto to allow this override).",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -242,15 +242,6 @@ export function resolveExecTarget(params: {
|
|||
}) {
|
||||
const configuredTarget = params.configuredTarget ?? "auto";
|
||||
const requestedTarget = params.requestedTarget ?? null;
|
||||
if (params.elevatedRequested) {
|
||||
const elevatedTarget = configuredTarget === "node" ? ("node" as const) : ("gateway" as const);
|
||||
return {
|
||||
configuredTarget,
|
||||
requestedTarget,
|
||||
selectedTarget: elevatedTarget,
|
||||
effectiveHost: elevatedTarget,
|
||||
};
|
||||
}
|
||||
if (
|
||||
requestedTarget &&
|
||||
!isRequestedExecTargetAllowed({
|
||||
|
|
@ -273,12 +264,17 @@ export function resolveExecTarget(params: {
|
|||
);
|
||||
}
|
||||
const selectedTarget = requestedTarget ?? configuredTarget;
|
||||
const resolvedTarget = params.elevatedRequested
|
||||
? selectedTarget === "node"
|
||||
? "node"
|
||||
: "gateway"
|
||||
: selectedTarget;
|
||||
const effectiveHost =
|
||||
selectedTarget === "auto" ? (params.sandboxAvailable ? "sandbox" : "gateway") : selectedTarget;
|
||||
resolvedTarget === "auto" ? (params.sandboxAvailable ? "sandbox" : "gateway") : resolvedTarget;
|
||||
return {
|
||||
configuredTarget,
|
||||
requestedTarget,
|
||||
selectedTarget,
|
||||
selectedTarget: resolvedTarget,
|
||||
effectiveHost,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -458,6 +458,41 @@ describe("exec approvals", () => {
|
|||
expect(prepareCwd).toBeUndefined();
|
||||
});
|
||||
|
||||
it("routes explicit host=node to node invoke when elevated default is on under auto host", async () => {
|
||||
const calls: string[] = [];
|
||||
|
||||
vi.mocked(callGatewayTool).mockImplementation(async (method, _opts, params) => {
|
||||
calls.push(method);
|
||||
if (method === "node.invoke") {
|
||||
const invoke = params as { command?: string };
|
||||
if (invoke.command === "system.run.prepare") {
|
||||
return buildPreparedSystemRunPayload(params);
|
||||
}
|
||||
if (invoke.command === "system.run") {
|
||||
return { payload: { success: true, stdout: "node-ok" } };
|
||||
}
|
||||
}
|
||||
return { ok: true };
|
||||
});
|
||||
|
||||
const tool = createExecTool({
|
||||
host: "auto",
|
||||
ask: "off",
|
||||
security: "full",
|
||||
approvalRunningNoticeMs: 0,
|
||||
elevated: { enabled: true, allowed: true, defaultLevel: "on" },
|
||||
});
|
||||
|
||||
const result = await tool.execute("call-auto-node-elevated-default", {
|
||||
command: "echo gateway-ok",
|
||||
host: "node",
|
||||
});
|
||||
|
||||
expect(result.details.status).toBe("completed");
|
||||
expect(getResultText(result)).toContain("node-ok");
|
||||
expect(calls).toContain("node.invoke");
|
||||
});
|
||||
|
||||
it("honors ask=off for elevated gateway exec without prompting", async () => {
|
||||
const calls: string[] = [];
|
||||
vi.mocked(callGatewayTool).mockImplementation(async (method) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue