test: add /approve gateway scope coverage (#1) (thanks @mitsuhiko)
parent
efe2a464af
commit
d41acf99a6
|
|
@ -16,6 +16,7 @@ Docs: https://docs.openclaw.ai
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
- Security: require operator.approvals for gateway /approve commands. (#1) Thanks @mitsuhiko, @yueyueL.
|
||||||
- Security: Matrix allowlists now require full MXIDs; ambiguous name resolution no longer grants access. Thanks @MegaManSec.
|
- Security: Matrix allowlists now require full MXIDs; ambiguous name resolution no longer grants access. Thanks @MegaManSec.
|
||||||
- Security: enforce access-group gating for Slack slash commands when channel type lookup fails.
|
- Security: enforce access-group gating for Slack slash commands when channel type lookup fails.
|
||||||
- Security: require validated shared-secret auth before skipping device identity on gateway connect.
|
- Security: require validated shared-secret auth before skipping device identity on gateway connect.
|
||||||
|
|
|
||||||
|
|
@ -98,4 +98,52 @@ describe("/approve command", () => {
|
||||||
expect(result.reply?.text).toContain("requires operator.approvals");
|
expect(result.reply?.text).toContain("requires operator.approvals");
|
||||||
expect(mockCallGateway).not.toHaveBeenCalled();
|
expect(mockCallGateway).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("allows gateway clients with approvals scope", async () => {
|
||||||
|
const cfg = {
|
||||||
|
commands: { text: true },
|
||||||
|
} as OpenClawConfig;
|
||||||
|
const params = buildParams("/approve abc allow-once", cfg, {
|
||||||
|
Provider: "webchat",
|
||||||
|
Surface: "webchat",
|
||||||
|
GatewayClientScopes: ["operator.approvals"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockCallGateway = vi.mocked(callGateway);
|
||||||
|
mockCallGateway.mockResolvedValueOnce({ ok: true });
|
||||||
|
|
||||||
|
const result = await handleCommands(params);
|
||||||
|
expect(result.shouldContinue).toBe(false);
|
||||||
|
expect(result.reply?.text).toContain("Exec approval allow-once submitted");
|
||||||
|
expect(mockCallGateway).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
method: "exec.approval.resolve",
|
||||||
|
params: { id: "abc", decision: "allow-once" },
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows gateway clients with admin scope", async () => {
|
||||||
|
const cfg = {
|
||||||
|
commands: { text: true },
|
||||||
|
} as OpenClawConfig;
|
||||||
|
const params = buildParams("/approve abc allow-once", cfg, {
|
||||||
|
Provider: "webchat",
|
||||||
|
Surface: "webchat",
|
||||||
|
GatewayClientScopes: ["operator.admin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockCallGateway = vi.mocked(callGateway);
|
||||||
|
mockCallGateway.mockResolvedValueOnce({ ok: true });
|
||||||
|
|
||||||
|
const result = await handleCommands(params);
|
||||||
|
expect(result.shouldContinue).toBe(false);
|
||||||
|
expect(result.reply?.text).toContain("Exec approval allow-once submitted");
|
||||||
|
expect(mockCallGateway).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
method: "exec.approval.resolve",
|
||||||
|
params: { id: "abc", decision: "allow-once" },
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue