mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 19:35:13 +01:00
perf(git): filter managed identity connection reads (#17563)
Apply the existing exact GitHub source marker predicate in the company-scoped connection query. Keep the JavaScript guard and every current install, grant, consent, identity, and credential check unchanged. Validation: 74 focused tests, full build and typecheck, exact-head Greptile 5/5 (medium), full green CI, and no unresolved threads. Both marker locations, malformed JSON types, changed/disabled connections, and retained unrelated configuration are covered. The unfiltered counterfactual fails both row-count regressions. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
bf142db65a
commit
75dbd3050b
2 files changed
+42
-1
No files matched your search
@@ -6,6 +6,7 @@ import { createRuntimeToolsToken } from "../runtime-tools-token.js";
|
||||
import { errorHandler } from "../middleware/index.js";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { createDatabaseResponseCapture, installDatabaseResponseCapture } from "@paperclipai/db/response-capture";
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
agents,
|
||||
@@ -192,6 +193,42 @@ const support = await getEmbeddedPostgresTestSupport();
|
||||
});
|
||||
return { id, connectionId, secretId, definitionId };
|
||||
}
|
||||
it.each(["config", "transportConfig"] as const)("reads only current GitHub identity connections via %s", async location => {
|
||||
const input = await seed(), selected = await grant(input, "A");
|
||||
const [connection] = await db.select().from(toolConnections).where(eq(toolConnections.id, selected.connectionId));
|
||||
await db.update(toolConnections).set({ config: {}, transportConfig: {}, [location]: { sourceTemplateKey: "github" } })
|
||||
.where(eq(toolConnections.id, selected.connectionId));
|
||||
const payload = "unrelated-connection-config🙂".repeat(10_000);
|
||||
const irrelevant = [null, true, 42, ["github"], { name: "github" }, "GitHub", " github ", "other"].map(sourceTemplateKey => {
|
||||
const id = randomUUID();
|
||||
return { id, companyId: input.companyId, applicationId: connection.applicationId, name: id, uid: id,
|
||||
transport: "mcp_remote" as const, config: { sourceTemplateKey, payload }, transportConfig: { sourceTemplateKey } };
|
||||
});
|
||||
await db.insert(toolConnections).values(irrelevant);
|
||||
const observed = createDb(database.connectionString), events: Array<Record<string, unknown>> = [], now = Date.now();
|
||||
const capture = createDatabaseResponseCapture({ start: now - 100, end: now + 59_000 }, event => events.push(event));
|
||||
installDatabaseResponseCapture(observed, { toolConnections }, capture);
|
||||
try {
|
||||
expect(await resolveManagedGitHubIdentitySelection(observed, input.companyId, { agentId: input.agentId, responsibleUserId: "A" }))
|
||||
.toMatchObject({ configured: true, grant: { id: selected.id } });
|
||||
capture.flush();
|
||||
const reads = events.filter(event => event.table === "tool_connections" && event.operation === "select");
|
||||
expect(reads).toHaveLength(1);
|
||||
expect(reads[0].rows).toBe(1);
|
||||
expect(reads[0].responseValueBytes).toBeLessThan(8192);
|
||||
await db.update(toolConnections).set({ enabled: false }).where(eq(toolConnections.id, selected.connectionId));
|
||||
expect((await resolveManagedGitHubIdentitySelection(observed, input.companyId, { agentId: input.agentId, responsibleUserId: "A" })).grant)
|
||||
.toBeUndefined();
|
||||
await db.update(toolConnections).set({ [location]: { sourceTemplateKey: "other" } }).where(eq(toolConnections.id, selected.connectionId));
|
||||
expect(await resolveManagedGitHubIdentitySelection(observed, input.companyId, { agentId: input.agentId, responsibleUserId: "A" }))
|
||||
.toEqual({ configured: false });
|
||||
expect(await resolveManagedGitHubIdentitySelection(observed, randomUUID(), { agentId: input.agentId, responsibleUserId: "A" }))
|
||||
.toEqual({ configured: false });
|
||||
const saved = await db.select().from(toolConnections).where(eq(toolConnections.companyId, input.companyId));
|
||||
for (const row of irrelevant) expect(saved.find(candidate => candidate.id === row.id)?.config).toEqual(row.config);
|
||||
} finally { capture.flush(); await observed.$client.end(); }
|
||||
});
|
||||
|
||||
async function switchTo(
|
||||
input: Awaited<ReturnType<typeof seed>>,
|
||||
user: string,
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
userSecretDefinitions,
|
||||
type Db,
|
||||
} from "@paperclipai/db";
|
||||
import { and, eq, inArray, or } from "drizzle-orm";
|
||||
import { and, eq, inArray, or, sql } from "drizzle-orm";
|
||||
import { isGitHubDotCom } from "./github-fetch.js";
|
||||
import { secretService } from "./secrets.js";
|
||||
import { toolAccessService } from "./tool-access.js";
|
||||
@@ -324,6 +324,10 @@ export async function resolveManagedGitHubIdentitySelection(
|
||||
}> {
|
||||
const connections = await db.select().from(toolConnections).where(and(
|
||||
eq(toolConnections.companyId, companyId),
|
||||
or(
|
||||
sql`${toolConnections.config}->'sourceTemplateKey' = '"github"'::jsonb`,
|
||||
sql`${toolConnections.transportConfig}->'sourceTemplateKey' = '"github"'::jsonb`,
|
||||
),
|
||||
));
|
||||
const githubConnections = connections.filter((connection) => {
|
||||
const config = connection.config && typeof connection.config === "object" ? connection.config as Record<string, unknown> : {};
|
||||
|
||||
Reference in new issue
Block a user