mirror of https://github.com/openclaw/openclaw.git
fix(gateway): bind OpenResponses HTTP ingress as non-owner (#57778)
* fix(gateway): bind OpenResponses HTTP ingress as non-owner Co-authored-by: bmendonca3 <208517100+bmendonca3@users.noreply.github.com> * test(gateway): cover streaming OpenResponses non-owner ingress --------- Co-authored-by: bmendonca3 <208517100+bmendonca3@users.noreply.github.com>
This commit is contained in:
parent
1a75906a6f
commit
17d0be02f2
|
|
@ -700,6 +700,62 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it("treats HTTP callers as non-owner regardless of requested scopes", async () => {
|
||||
const port = enabledPort;
|
||||
|
||||
agentCommand.mockClear();
|
||||
agentCommand.mockResolvedValueOnce({ payloads: [{ text: "hello" }] } as never);
|
||||
|
||||
const writeScopeResponse = await postResponses(port, {
|
||||
model: "openclaw",
|
||||
input: "hi",
|
||||
});
|
||||
expect(writeScopeResponse.status).toBe(200);
|
||||
const writeScopeOpts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0] as
|
||||
| { senderIsOwner?: boolean }
|
||||
| undefined;
|
||||
expect(writeScopeOpts?.senderIsOwner).toBe(false);
|
||||
await ensureResponseConsumed(writeScopeResponse);
|
||||
|
||||
agentCommand.mockClear();
|
||||
agentCommand.mockResolvedValueOnce({ payloads: [{ text: "hello" }] } as never);
|
||||
|
||||
const adminScopeResponse = await postResponses(
|
||||
port,
|
||||
{ model: "openclaw", input: "hi" },
|
||||
{ "x-openclaw-scopes": "operator.admin, operator.write" },
|
||||
);
|
||||
expect(adminScopeResponse.status).toBe(200);
|
||||
const adminScopeOpts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0] as
|
||||
| { senderIsOwner?: boolean }
|
||||
| undefined;
|
||||
// Requested HTTP scopes do not prove owner identity for owner-only tools.
|
||||
expect(adminScopeOpts?.senderIsOwner).toBe(false);
|
||||
await ensureResponseConsumed(adminScopeResponse);
|
||||
|
||||
agentCommand.mockClear();
|
||||
agentCommand.mockImplementationOnce((async (opts: unknown) =>
|
||||
buildAssistantDeltaResult({
|
||||
opts,
|
||||
emit: emitAgentEvent,
|
||||
deltas: ["he", "llo"],
|
||||
text: "hello",
|
||||
})) as never);
|
||||
|
||||
const streamingResponse = await postResponses(
|
||||
port,
|
||||
{ stream: true, model: "openclaw", input: "hi" },
|
||||
{ "x-openclaw-scopes": "operator.admin, operator.write" },
|
||||
);
|
||||
expect(streamingResponse.status).toBe(200);
|
||||
const streamingOpts = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0] as
|
||||
| { senderIsOwner?: boolean }
|
||||
| undefined;
|
||||
expect(streamingOpts?.senderIsOwner).toBe(false);
|
||||
const streamingEvents = parseSseEvents(await streamingResponse.text());
|
||||
expect(streamingEvents.some((event) => event.event === "response.completed")).toBe(true);
|
||||
});
|
||||
|
||||
it("preserves assistant text alongside non-stream function_call output", async () => {
|
||||
const port = enabledPort;
|
||||
agentCommand.mockClear();
|
||||
|
|
|
|||
|
|
@ -424,6 +424,7 @@ async function runResponsesAgentCommand(params: {
|
|||
sessionKey: string;
|
||||
runId: string;
|
||||
messageChannel: string;
|
||||
senderIsOwner: boolean;
|
||||
deps: ReturnType<typeof createDefaultDeps>;
|
||||
}) {
|
||||
return agentCommandFromIngress(
|
||||
|
|
@ -439,8 +440,7 @@ async function runResponsesAgentCommand(params: {
|
|||
deliver: false,
|
||||
messageChannel: params.messageChannel,
|
||||
bestEffortDeliver: false,
|
||||
// HTTP API callers are authenticated operator clients for this gateway context.
|
||||
senderIsOwner: true,
|
||||
senderIsOwner: params.senderIsOwner,
|
||||
allowModelOverride: true,
|
||||
},
|
||||
defaultRuntime,
|
||||
|
|
@ -704,6 +704,7 @@ export async function handleOpenResponsesHttpRequest(
|
|||
sessionKey,
|
||||
runId: responseId,
|
||||
messageChannel,
|
||||
senderIsOwner: false,
|
||||
deps,
|
||||
});
|
||||
|
||||
|
|
@ -956,6 +957,7 @@ export async function handleOpenResponsesHttpRequest(
|
|||
sessionKey,
|
||||
runId: responseId,
|
||||
messageChannel,
|
||||
senderIsOwner: false,
|
||||
deps,
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue