forked from bai/curriculum-project-hub
171 lines
6.5 KiB
TypeScript
171 lines
6.5 KiB
TypeScript
import { afterAll, beforeEach, describe, expect, it } from "vitest";
|
|
import { ProviderConnectionService } from "../../src/connections/providerConnections.js";
|
|
import { DatabaseRuntimeSettings } from "../../src/settings/runtime.js";
|
|
import type { ProviderUpstreamCredential } from "../../src/connections/providerProxy.js";
|
|
import { DEFAULT_ORG_ID, prisma, resetDb, seedTestOrganization, testSecretEnvelope } from "./helpers.js";
|
|
|
|
const secrets = testSecretEnvelope;
|
|
|
|
describe("project-scoped provider runtime settings", () => {
|
|
beforeEach(async () => {
|
|
await resetDb();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await prisma.$disconnect();
|
|
});
|
|
|
|
it("resolves two projects only through their own Organization connection", async () => {
|
|
await seedTestOrganization("org_other", "other");
|
|
await Promise.all([
|
|
prisma.user.create({ data: { id: "user-a", feishuOpenId: "ou_a", displayName: "A" } }),
|
|
prisma.user.create({ data: { id: "user-b", feishuOpenId: "ou_b", displayName: "B" } }),
|
|
prisma.project.create({
|
|
data: {
|
|
id: "project-a",
|
|
organizationId: DEFAULT_ORG_ID,
|
|
name: "A",
|
|
workspaceDir: "/tmp/project-a",
|
|
},
|
|
}),
|
|
prisma.project.create({
|
|
data: {
|
|
id: "project-b",
|
|
organizationId: "org_other",
|
|
name: "B",
|
|
workspaceDir: "/tmp/project-b",
|
|
},
|
|
}),
|
|
]);
|
|
await Promise.all([
|
|
prisma.organizationMembership.create({
|
|
data: { organizationId: DEFAULT_ORG_ID, userId: "user-a", role: "ADMIN" },
|
|
}),
|
|
prisma.organizationMembership.create({
|
|
data: { organizationId: "org_other", userId: "user-b", role: "OWNER" },
|
|
}),
|
|
]);
|
|
const service = new ProviderConnectionService(prisma, secrets, async () => {});
|
|
await service.rotateByok({
|
|
organizationId: DEFAULT_ORG_ID,
|
|
providerId: "openrouter",
|
|
actorUserId: "user-a",
|
|
baseUrl: "https://provider-a.example/api",
|
|
authToken: "provider-a-token",
|
|
anthropicApiKey: "provider-a-api-key",
|
|
});
|
|
await service.rotateByok({
|
|
organizationId: "org_other",
|
|
providerId: "openrouter",
|
|
actorUserId: "user-b",
|
|
baseUrl: "https://provider-b.example/api",
|
|
authToken: "provider-b-token",
|
|
});
|
|
const leasedCredentials: ProviderUpstreamCredential[] = [];
|
|
const settings = new DatabaseRuntimeSettings(prisma, secrets, {
|
|
ANTHROPIC_AUTH_TOKEN: "forbidden-global-token",
|
|
ANTHROPIC_BASE_URL: "https://forbidden-global.example",
|
|
}, async (credential) => {
|
|
leasedCredentials.push(credential);
|
|
return {
|
|
sdkEnv: {
|
|
ANTHROPIC_BASE_URL: "http://127.0.0.1:12345",
|
|
ANTHROPIC_AUTH_TOKEN: `run-capability-${leasedCredentials.length}`,
|
|
ANTHROPIC_API_KEY: "",
|
|
},
|
|
sensitiveValues: [`run-capability-${leasedCredentials.length}`],
|
|
async close() {},
|
|
};
|
|
});
|
|
|
|
const providerA = await settings.provider("openrouter", { projectId: "project-a" });
|
|
const providerB = await settings.provider("openrouter", { projectId: "project-b" });
|
|
expect(JSON.stringify([providerA, providerB])).not.toContain("provider-a-token");
|
|
expect(JSON.stringify([providerA, providerB])).not.toContain("provider-b-token");
|
|
|
|
const leaseA = await providerA.openAgentLease({ runId: "run-a" });
|
|
const leaseB = await providerB.openAgentLease({ runId: "run-b" });
|
|
expect(leaseA.sdkEnv).toMatchObject({
|
|
ANTHROPIC_BASE_URL: "http://127.0.0.1:12345",
|
|
ANTHROPIC_AUTH_TOKEN: "run-capability-1",
|
|
ANTHROPIC_API_KEY: "",
|
|
});
|
|
expect(leaseB.sdkEnv.ANTHROPIC_AUTH_TOKEN).toBe("run-capability-2");
|
|
expect(leasedCredentials).toEqual([
|
|
{
|
|
baseUrl: "https://provider-a.example/api",
|
|
authToken: "provider-a-token",
|
|
anthropicApiKey: "provider-a-api-key",
|
|
},
|
|
{
|
|
baseUrl: "https://provider-b.example/api",
|
|
authToken: "provider-b-token",
|
|
anthropicApiKey: "",
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("fails closed without project scope or for missing, inactive, and corrupt connections", async () => {
|
|
await prisma.user.create({ data: { id: "user-a", feishuOpenId: "ou_a", displayName: "A" } });
|
|
await prisma.organizationMembership.create({
|
|
data: { organizationId: DEFAULT_ORG_ID, userId: "user-a", role: "ADMIN" },
|
|
});
|
|
await prisma.project.create({
|
|
data: {
|
|
id: "project-a",
|
|
organizationId: DEFAULT_ORG_ID,
|
|
name: "A",
|
|
workspaceDir: "/tmp/project-a",
|
|
},
|
|
});
|
|
const settings = new DatabaseRuntimeSettings(prisma, secrets, {
|
|
ANTHROPIC_AUTH_TOKEN: "must-not-be-a-fallback",
|
|
});
|
|
|
|
await expect(settings.provider("openrouter")).rejects.toThrow("projectId is required");
|
|
await expect(settings.provider("openrouter", { projectId: "project-a" })).rejects.toThrow(
|
|
"active provider connection not found",
|
|
);
|
|
|
|
const service = new ProviderConnectionService(prisma, secrets, async () => {});
|
|
await service.rotateByok({
|
|
organizationId: DEFAULT_ORG_ID,
|
|
providerId: "openrouter",
|
|
actorUserId: "user-a",
|
|
baseUrl: "https://provider-a.example/api",
|
|
authToken: "provider-a-token",
|
|
});
|
|
await prisma.organization.update({
|
|
where: { id: DEFAULT_ORG_ID },
|
|
data: { status: "SUSPENDED" },
|
|
});
|
|
await expect(settings.provider("openrouter", { projectId: "project-a" })).rejects.toThrow(
|
|
`organization ${DEFAULT_ORG_ID} is SUSPENDED`,
|
|
);
|
|
|
|
await prisma.organization.update({ where: { id: DEFAULT_ORG_ID }, data: { status: "ACTIVE" } });
|
|
const connection = await prisma.organizationProviderConnection.findUniqueOrThrow({
|
|
where: {
|
|
organizationId_providerId: { organizationId: DEFAULT_ORG_ID, providerId: "openrouter" },
|
|
},
|
|
});
|
|
const version = await prisma.providerCredentialVersion.findUniqueOrThrow({
|
|
where: { id: connection.activeSecretVersionId ?? "missing" },
|
|
});
|
|
const envelope = structuredClone(version.envelope) as {
|
|
payload: { ciphertext: string };
|
|
};
|
|
const bytes = Buffer.from(envelope.payload.ciphertext, "base64");
|
|
bytes[0] = (bytes[0] ?? 0) ^ 1;
|
|
envelope.payload.ciphertext = bytes.toString("base64");
|
|
await prisma.providerCredentialVersion.update({
|
|
where: { id: version.id },
|
|
data: { envelope },
|
|
});
|
|
const corruptProvider = await settings.provider("openrouter", { projectId: "project-a" });
|
|
await expect(corruptProvider.openAgentLease({ runId: "run-corrupt" })).rejects.toThrow(
|
|
"secret envelope authentication failed",
|
|
);
|
|
});
|
|
});
|