mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:50:43 +00:00
fix(voice-call): scope call control gateway methods
This commit is contained in:
committed by
Peter Steinberger
parent
309ff6bada
commit
0c1df35315
@@ -29,6 +29,7 @@ const callGatewayFromCliMock = vi.fn();
|
||||
|
||||
type Registered = {
|
||||
methods: Map<string, unknown>;
|
||||
methodScopes: Map<string, string | undefined>;
|
||||
tools: unknown[];
|
||||
service?: Parameters<OpenClawPluginApi["registerService"]>[0];
|
||||
};
|
||||
@@ -108,6 +109,7 @@ function createServiceContext(): Parameters<NonNullable<Registered["service"]>["
|
||||
|
||||
function setup(config: Record<string, unknown>): Registered {
|
||||
const methods = new Map<string, unknown>();
|
||||
const methodScopes = new Map<string, string | undefined>();
|
||||
const tools: unknown[] = [];
|
||||
let service: Registered["service"];
|
||||
const api = createTestPluginApi({
|
||||
@@ -120,7 +122,10 @@ function setup(config: Record<string, unknown>): Registered {
|
||||
pluginConfig: config,
|
||||
runtime: { tts: { textToSpeechTelephony: vi.fn() } } as unknown as OpenClawPluginApi["runtime"],
|
||||
logger: noopLogger,
|
||||
registerGatewayMethod: (method: string, handler: unknown) => methods.set(method, handler),
|
||||
registerGatewayMethod: (method: string, handler: unknown, opts?: { scope?: string }) => {
|
||||
methods.set(method, handler);
|
||||
methodScopes.set(method, opts?.scope);
|
||||
},
|
||||
registerTool: (tool: unknown) => tools.push(tool),
|
||||
registerCli: () => {},
|
||||
registerService: (registeredService) => {
|
||||
@@ -129,7 +134,7 @@ function setup(config: Record<string, unknown>): Registered {
|
||||
resolvePath: (p: string) => p,
|
||||
});
|
||||
plugin.register(api);
|
||||
return { methods, tools, service };
|
||||
return { methods, methodScopes, tools, service };
|
||||
}
|
||||
|
||||
function envRef(id: string) {
|
||||
@@ -363,6 +368,24 @@ describe("voice-call plugin", () => {
|
||||
expect(payload.callId).toBe("call-1");
|
||||
});
|
||||
|
||||
it("registers voice call gateway methods with least-privilege scopes", () => {
|
||||
const { methodScopes } = setup({ provider: "mock" });
|
||||
|
||||
for (const method of [
|
||||
"voicecall.initiate",
|
||||
"voicecall.start",
|
||||
"voicecall.continue",
|
||||
"voicecall.continue.start",
|
||||
"voicecall.speak",
|
||||
"voicecall.dtmf",
|
||||
"voicecall.end",
|
||||
]) {
|
||||
expect(methodScopes.get(method)).toBe("operator.write");
|
||||
}
|
||||
expect(methodScopes.get("voicecall.continue.result")).toBe("operator.read");
|
||||
expect(methodScopes.get("voicecall.status")).toBe("operator.read");
|
||||
});
|
||||
|
||||
it("preserves mode on legacy voicecall.start", async () => {
|
||||
const { methods } = setup({ provider: "mock" });
|
||||
const handler = methods.get("voicecall.start") as
|
||||
|
||||
@@ -22,6 +22,9 @@ import {
|
||||
import type { CoreConfig } from "./src/core-bridge.js";
|
||||
import { createVoiceCallContinueOperationStore } from "./src/gateway-continue-operation.js";
|
||||
|
||||
const VOICE_CALL_WRITE_METHOD_SCOPE = { scope: "operator.write" as const };
|
||||
const VOICE_CALL_READ_METHOD_SCOPE = { scope: "operator.read" as const };
|
||||
|
||||
const voiceCallConfigSchema = {
|
||||
parse(value: unknown): VoiceCallConfig {
|
||||
const normalized = normalizeVoiceCallLegacyConfigInput(value);
|
||||
@@ -415,6 +418,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_WRITE_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerGatewayMethod(
|
||||
@@ -432,6 +436,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_WRITE_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerGatewayMethod(
|
||||
@@ -452,6 +457,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_WRITE_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerGatewayMethod(
|
||||
@@ -473,6 +479,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_READ_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerGatewayMethod(
|
||||
@@ -508,6 +515,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_WRITE_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerGatewayMethod(
|
||||
@@ -531,6 +539,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_WRITE_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerGatewayMethod(
|
||||
@@ -553,6 +562,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_WRITE_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerGatewayMethod(
|
||||
@@ -576,6 +586,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_READ_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerGatewayMethod(
|
||||
@@ -604,6 +615,7 @@ export default definePluginEntry({
|
||||
sendError(respond, err);
|
||||
}
|
||||
},
|
||||
VOICE_CALL_WRITE_METHOD_SCOPE,
|
||||
);
|
||||
|
||||
api.registerTool({
|
||||
|
||||
Reference in New Issue
Block a user