mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
test: cherry-pick agent JWT plugin-tool regression tests from #5549
Adds focused regression tests for the agent JWT plugin tool access fix in this PR: - agent JWT can list available plugin tools (GET /api/plugins/tools) - agent JWT can execute a tool within its company scope - agent JWT cannot call execute with runContext.companyId outside its authenticated company - agent JWT cannot call execute with a runContext.agentId that does not belong to runContext.companyId Cherry-picked from #5549 and adapted to this PR's symbol names (assertBoardOrAgent) and three-row validateToolRunContextScope queue. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
2e34a77980
commit
8582881777
1 file changed
+118
@@ -912,4 +912,122 @@ describe.sequential("plugin tool and bridge authz", () => {
|
||||
expect(res.body).toEqual({ runId: "run-1", jobId: "job-1" });
|
||||
expect(scheduler.triggerJob).toHaveBeenCalledWith("job-1", "manual");
|
||||
});
|
||||
|
||||
// ─── Agent JWT tool execution (cherry-picked from #5549) ─────────────────────
|
||||
|
||||
it("allows agent JWT to list available plugin tools", async () => {
|
||||
const listToolsForAgent = vi.fn(() => []);
|
||||
const { app } = await createApp(agentActor(), {}, {
|
||||
toolDeps: {
|
||||
toolDispatcher: {
|
||||
listToolsForAgent,
|
||||
getTool: vi.fn(),
|
||||
executeTool: vi.fn(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const res = await request(app).get("/api/plugins/tools");
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(listToolsForAgent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows agent JWT to execute a tool within its company scope", async () => {
|
||||
const executeTool = vi.fn().mockResolvedValue({ content: "ok" });
|
||||
const { app } = await createApp(
|
||||
agentActor(),
|
||||
{},
|
||||
{
|
||||
db: createSelectQueueDb([
|
||||
[{ companyId: companyA }],
|
||||
[{ companyId: companyA, agentId: agentA }],
|
||||
[{ companyId: companyA }],
|
||||
]),
|
||||
toolDeps: {
|
||||
toolDispatcher: {
|
||||
listToolsForAgent: vi.fn(),
|
||||
getTool: vi.fn(() => ({ name: "paperclip.example:search", pluginDbId: pluginId })),
|
||||
executeTool,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const res = await request(app)
|
||||
.post("/api/plugins/tools/execute")
|
||||
.send({
|
||||
tool: "paperclip.example:search",
|
||||
parameters: { q: "test" },
|
||||
runContext: { agentId: agentA, runId: runA, companyId: companyA, projectId: projectA },
|
||||
});
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(executeTool).toHaveBeenCalledWith(
|
||||
"paperclip.example:search",
|
||||
{ q: "test" },
|
||||
{ agentId: agentA, runId: runA, companyId: companyA, projectId: projectA },
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects agent JWT when runContext.companyId is outside the agent's company scope", async () => {
|
||||
const executeTool = vi.fn();
|
||||
const { app } = await createApp(
|
||||
agentActor(),
|
||||
{},
|
||||
{
|
||||
db: createSelectQueueDb([]),
|
||||
toolDeps: {
|
||||
toolDispatcher: {
|
||||
listToolsForAgent: vi.fn(),
|
||||
getTool: vi.fn(() => ({ name: "paperclip.example:search", pluginDbId: pluginId })),
|
||||
executeTool,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const res = await request(app)
|
||||
.post("/api/plugins/tools/execute")
|
||||
.send({
|
||||
tool: "paperclip.example:search",
|
||||
parameters: {},
|
||||
runContext: { agentId: agentA, runId: runA, companyId: companyB, projectId: projectA },
|
||||
});
|
||||
|
||||
expect(res.status).toBe(403);
|
||||
expect(executeTool).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects agent JWT when runContext.agentId does not belong to runContext.companyId", async () => {
|
||||
const otherAgent = "77777777-7777-4777-8777-777777777777";
|
||||
const executeTool = vi.fn();
|
||||
const { app } = await createApp(
|
||||
agentActor(),
|
||||
{},
|
||||
{
|
||||
db: createSelectQueueDb([
|
||||
[{ companyId: companyB }],
|
||||
]),
|
||||
toolDeps: {
|
||||
toolDispatcher: {
|
||||
listToolsForAgent: vi.fn(),
|
||||
getTool: vi.fn(() => ({ name: "paperclip.example:search", pluginDbId: pluginId })),
|
||||
executeTool,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const res = await request(app)
|
||||
.post("/api/plugins/tools/execute")
|
||||
.send({
|
||||
tool: "paperclip.example:search",
|
||||
parameters: {},
|
||||
runContext: { agentId: otherAgent, runId: runA, companyId: companyA, projectId: projectA },
|
||||
});
|
||||
|
||||
expect(res.status).toBe(403);
|
||||
expect(executeTool).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user