376 lines · 12.8 KB · TypeScript
RawDownload
// Tenant isolation integration test. Runs in plain node (not workerd)// via vitest.node.config.ts — workerd's dev-mode compile stack crashes// on the full cloud module graph. import { describe, expect, it } from "@effect/vitest";import { Effect, Result, Schema } from "effect";import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"; import { ConnectionId, ScopeId, SecretId } from "@executor-js/sdk";import { makeOpenApiHttpApiTestAddSpecPayload } from "@executor-js/plugin-openapi/testing"; import { asOrg } from "./__test-harness__/api-harness"; const PingGroup = HttpApiGroup.make("default", { topLevel: true }).add(  HttpApiEndpoint.get("ping", "/ping", { success: Schema.Unknown }),); const TenantIsolationApi = HttpApi.make("tenantIsolationTest")  .add(PingGroup)  .annotateMerge(OpenApi.annotations({ title: "Tenant Test API", version: "1.0.0" })); const makeTenantOpenApiSourcePayload = (  namespace: string,  options: Omit<Parameters<typeof makeOpenApiHttpApiTestAddSpecPayload>[1], "namespace"> = {},) =>  makeOpenApiHttpApiTestAddSpecPayload(TenantIsolationApi, {    namespace,    ...options,  }); describe("tenant isolation (HTTP)", () => {  it.effect("write requests cannot target another org scope", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;       const result = yield* asOrg(orgB, (client) =>        client.secrets.set({          params: { scopeId: ScopeId.make(orgA) },          payload: {            id: SecretId.make("planted"),            name: "planted-by-org-b",            value: "should-be-rejected",          },        }),      ).pipe(Effect.result);       expect(Result.isFailure(result)).toBe(true);       const orgASecrets = yield* asOrg(orgA, (client) =>        client.secrets.list({ params: { scopeId: ScopeId.make(orgA) } }),      );      expect(orgASecrets.map((s) => s.id)).not.toContain("planted");    }),  );   it.effect("read requests with another org scope still use the caller stack", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const idA = `sec_a_${crypto.randomUUID().slice(0, 8)}`;       yield* asOrg(orgA, (client) =>        client.secrets.set({          params: { scopeId: ScopeId.make(orgA) },          payload: { id: SecretId.make(idA), name: "org-a only", value: "v" },        }),      );       const result = yield* asOrg(orgB, (client) =>        client.secrets.list({ params: { scopeId: ScopeId.make(orgA) } }),      );      expect(result.map((s) => s.id)).not.toContain(idA);    }),  );   it.effect("delete requests cannot remove another org secret", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const idA = `sec_a_${crypto.randomUUID().slice(0, 8)}`;       yield* asOrg(orgA, (client) =>        client.secrets.set({          params: { scopeId: ScopeId.make(orgA) },          payload: { id: SecretId.make(idA), name: "org-a only", value: "v" },        }),      );       yield* asOrg(orgB, (client) =>        client.secrets.remove({          params: { scopeId: ScopeId.make(orgA), secretId: SecretId.make(idA) },        }),      ).pipe(Effect.result);       const status = yield* asOrg(orgA, (client) =>        client.secrets.status({          params: { scopeId: ScopeId.make(orgA), secretId: SecretId.make(idA) },        }),      );      expect(status.status).toBe("resolved");    }),  );   it.effect("sources.list is scoped to the caller org", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const namespaceA = `a_${crypto.randomUUID().replace(/-/g, "_")}`;       yield* asOrg(orgA, (client) =>        client.openapi.addSpec({          params: { scopeId: ScopeId.make(orgA) },          payload: makeTenantOpenApiSourcePayload(namespaceA),        }),      );       const orgBSources = yield* asOrg(orgB, (client) =>        client.sources.list({ params: { scopeId: ScopeId.make(orgB) } }),      );      expect(orgBSources.map((s) => s.id)).not.toContain(namespaceA);    }),  );   it.effect("tools.list is scoped to the caller org", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const namespaceA = `a_${crypto.randomUUID().replace(/-/g, "_")}`;       yield* asOrg(orgA, (client) =>        client.openapi.addSpec({          params: { scopeId: ScopeId.make(orgA) },          payload: makeTenantOpenApiSourcePayload(namespaceA),        }),      );       const orgBTools = yield* asOrg(orgB, (client) =>        client.tools.list({ params: { scopeId: ScopeId.make(orgB) } }),      );      expect(orgBTools.map((t) => t.sourceId)).not.toContain(namespaceA);      for (const id of orgBTools.map((t) => t.id)) {        expect(id).not.toContain(namespaceA);      }    }),  );   it.effect("openapi.getSource cannot reach another org's source by namespace", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const namespaceA = `a_${crypto.randomUUID().replace(/-/g, "_")}`;       yield* asOrg(orgA, (client) =>        client.openapi.addSpec({          params: { scopeId: ScopeId.make(orgA) },          payload: makeTenantOpenApiSourcePayload(namespaceA),        }),      );       const source = yield* asOrg(orgB, (client) =>        client.openapi.getSource({          params: { scopeId: ScopeId.make(orgB), namespace: namespaceA },        }),      );       expect(source).toBeNull();    }),  );   it.effect("secrets.list is scoped to the caller org", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const secretIdA = `sec_a_${crypto.randomUUID().slice(0, 8)}`;       yield* asOrg(orgA, (client) =>        client.secrets.set({          params: { scopeId: ScopeId.make(orgA) },          payload: { id: SecretId.make(secretIdA), name: "org-a only", value: "super-secret-a" },        }),      );       const orgBSecrets = yield* asOrg(orgB, (client) =>        client.secrets.list({ params: { scopeId: ScopeId.make(orgB) } }),      );      expect(orgBSecrets.map((s) => s.id)).not.toContain(secretIdA);    }),  );   it.effect("secrets.status reports another org's secret as missing", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const secretIdA = `sec_a_${crypto.randomUUID().slice(0, 8)}`;       yield* asOrg(orgA, (client) =>        client.secrets.set({          params: { scopeId: ScopeId.make(orgA) },          payload: { id: SecretId.make(secretIdA), name: "org-a only", value: "super-secret-a" },        }),      );       const status = yield* asOrg(orgB, (client) =>        client.secrets.status({          params: { scopeId: ScopeId.make(orgB), secretId: SecretId.make(secretIdA) },        }),      );       expect(status.status).toBe("missing");    }),  );   it.effect("secret metadata is not visible across orgs", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const secretIdA = `sec_a_${crypto.randomUUID().slice(0, 8)}`;       yield* asOrg(orgA, (client) =>        client.secrets.set({          params: { scopeId: ScopeId.make(orgA) },          payload: { id: SecretId.make(secretIdA), name: "org-a only", value: "super-secret-a" },        }),      );       const status = yield* asOrg(orgB, (client) =>        client.secrets.status({          params: { scopeId: ScopeId.make(orgB), secretId: SecretId.make(secretIdA) },        }),      );      const list = yield* asOrg(orgB, (client) =>        client.secrets.list({ params: { scopeId: ScopeId.make(orgB) } }),      );       expect(status.status).toBe("missing");      expect(list.map((s) => s.id)).not.toContain(secretIdA);    }),  );   it.effect("secret usages are scoped to the caller stack", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const namespaceA = `a_${crypto.randomUUID().replace(/-/g, "_")}`;      const secretIdA = SecretId.make(`sec_a_${crypto.randomUUID().slice(0, 8)}`);       yield* asOrg(orgA, (client) =>        Effect.gen(function* () {          yield* client.secrets.set({            params: { scopeId: ScopeId.make(orgA) },            payload: { id: secretIdA, name: "org-a token", value: "v" },          });          yield* client.openapi.addSpec({            params: { scopeId: ScopeId.make(orgA) },            payload: {              ...makeTenantOpenApiSourcePayload(namespaceA),              headers: {                Authorization: {                  kind: "secret",                  prefix: "Bearer ",                },              },            },          });          yield* client.sources.setBinding({            params: { scopeId: ScopeId.make(orgA) },            payload: {              scope: ScopeId.make(orgA),              source: { id: namespaceA, scope: ScopeId.make(orgA) },              slotKey: "header:authorization",              value: { kind: "secret", secretId: secretIdA },            },          });        }),      );       const usages = yield* asOrg(orgB, (client) =>        client.secrets.usages({          params: { scopeId: ScopeId.make(orgB), secretId: secretIdA },        }),      );       expect(usages).toEqual([]);    }),  );   it.effect("connection usages are scoped to the caller stack", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const namespaceA = `a_${crypto.randomUUID().replace(/-/g, "_")}`;      const connectionIdA = ConnectionId.make(`conn_a_${crypto.randomUUID().slice(0, 8)}`);       yield* asOrg(orgA, (client) =>        Effect.gen(function* () {          yield* client.openapi.addSpec({            params: { scopeId: ScopeId.make(orgA) },            payload: makeTenantOpenApiSourcePayload(namespaceA),          });          yield* client.sources.setBinding({            params: { scopeId: ScopeId.make(orgA) },            payload: {              scope: ScopeId.make(orgA),              source: { id: namespaceA, scope: ScopeId.make(orgA) },              slotKey: "auth:conn",              value: { kind: "connection", connectionId: connectionIdA },            },          });        }),      ).pipe(Effect.result);       const usages = yield* asOrg(orgB, (client) =>        client.connections.usages({          params: { scopeId: ScopeId.make(orgB), connectionId: connectionIdA },        }),      );       expect(usages).toEqual([]);    }),  );   it.effect("updating a same-namespace OpenAPI source in one org does not mutate another org", () =>    Effect.gen(function* () {      const orgA = `org_${crypto.randomUUID()}`;      const orgB = `org_${crypto.randomUUID()}`;      const namespace = `shared_${crypto.randomUUID().replace(/-/g, "_")}`;       yield* asOrg(orgA, (client) =>        client.openapi.addSpec({          params: { scopeId: ScopeId.make(orgA) },          payload: makeTenantOpenApiSourcePayload(namespace, {            name: "Org A API",            baseUrl: "https://org-a.example.com",          }),        }),      );      yield* asOrg(orgB, (client) =>        client.openapi.addSpec({          params: { scopeId: ScopeId.make(orgB) },          payload: makeTenantOpenApiSourcePayload(namespace, {            name: "Org B API",            baseUrl: "https://org-b.example.com",          }),        }),      );       yield* asOrg(orgA, (client) =>        client.sources.configure({          params: { scopeId: ScopeId.make(orgA) },          payload: {            source: { id: namespace, scope: ScopeId.make(orgA) },            scope: ScopeId.make(orgA),            type: "openapi",            config: {              scope: orgA,              name: "Org A Updated API",              baseUrl: "https://org-a-updated.example.com",            },          },        }),      );       const orgASource = yield* asOrg(orgA, (client) =>        client.openapi.getSource({ params: { scopeId: ScopeId.make(orgA), namespace } }),      );      const orgBSource = yield* asOrg(orgB, (client) =>        client.openapi.getSource({ params: { scopeId: ScopeId.make(orgB), namespace } }),      );      expect(orgASource?.name).toBe("Org A Updated API");      expect(orgASource?.config.baseUrl).toBe("https://org-a-updated.example.com");      expect(orgBSource?.name).toBe("Org B API");      expect(orgBSource?.config.baseUrl).toBe("https://org-b.example.com");    }),  );});

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t