History

add coverage for org-scoped account targeting rules

Rhys Sullivan committed 8 months ago

Commit e643d8d1 parent d90d1161 file · +73 −0Browse files

Unified · Split

executor/packages/database/convex/access-controls.test.ts+73−0
@@ -458,6 +458,23 @@ describe("workspace access controls", () => { · 457 unmodified lines
458458 expect(policy.resourcePattern).toBe("*.delete");
459459 });
460460
461+ test("account-scoped policy target must be active org member", async () => {
462+ const t = setup();
463+ const owner = await seedUser(t, { subject: "policy-target-owner" });
464+ const outsider = await seedUser(t, { subject: "policy-target-outsider" });
465+ const authedOwner = t.withIdentity({ subject: "policy-target-owner" });
466+
467+ await expect(
468+ authedOwner.mutation(api.workspace.upsertAccessPolicy, {
469+ workspaceId: owner.workspaceId,
470+ scopeType: "account",
471+ targetAccountId: outsider.accountId,
472+ resourcePattern: "*",
473+ effect: "allow",
474+ }),
475+ ).rejects.toThrow("targetAccountId must be an active member of this organization");
476+ });
477+
461478 test("workspace owner can upsert access policies", async () => {
462479 const t = setup();
463480 const owner = await seedUser(t, { subject: "ws-owner-policy" });
@@ -528,6 +545,23 @@ describe("workspace access controls", () => { · 64 unmodified lines
528545 ).rejects.toThrow("Only organization admins can perform this action");
529546 });
530547
548+ test("account-scoped credential target must be active org member", async () => {
549+ const t = setup();
550+ const owner = await seedUser(t, { subject: "cred-target-owner" });
551+ const outsider = await seedUser(t, { subject: "cred-target-outsider" });
552+ const authedOwner = t.withIdentity({ subject: "cred-target-owner" });
553+
554+ await expect(
555+ authedOwner.mutation(api.workspace.upsertCredential, {
556+ workspaceId: owner.workspaceId,
557+ sourceKey: "openapi:github",
558+ scopeType: "account",
559+ accountId: outsider.accountId,
560+ secretJson: { token: "ghp_test" },
561+ }),
562+ ).rejects.toThrow("accountId must be an active member of this organization");
563+ });
564+
531565 test("regular member cannot delete tool sources (admin-only)", async () => {
532566 const t = setup();
533567 const owner = await seedUser(t, { subject: "del-tool-owner" });
@@ -1256,6 +1290,45 @@ describe("credential security", () => { · 722 unmodified lines
12561290 }),
12571291 ).rejects.toThrow("Only organization admins can perform this action");
12581292 });
1293+
1294+ test("non-admin tool source listing redacts auth secret values", async () => {
1295+ const t = setup();
1296+ const owner = await seedUser(t, { subject: "source-redact-owner" });
1297+ const member = await seedUser(t, { subject: "source-redact-member" });
1298+
1299+ await addOrgMember(t, {
1300+ organizationId: owner.organizationId,
1301+ accountId: member.accountId,
1302+ role: "member",
1303+ });
1304+
1305+ const authedOwner = t.withIdentity({ subject: "source-redact-owner" });
1306+ await authedOwner.mutation(api.workspace.upsertToolSource, {
1307+ workspaceId: owner.workspaceId,
1308+ name: "secure-source",
1309+ type: "openapi",
1310+ config: {
1311+ spec: "https://example.com/openapi.json",
1312+ baseUrl: "https://example.com",
1313+ auth: {
1314+ type: "bearer",
1315+ mode: "workspace",
1316+ token: "super-secret-token",
1317+ },
1318+ },
1319+ });
1320+
1321+ const authedMember = t.withIdentity({ subject: "source-redact-member" });
1322+ const sources = await authedMember.query(api.workspace.listToolSources, {
1323+ workspaceId: owner.workspaceId,
1324+ });
1325+
1326+ expect(sources.length).toBe(1);
1327+ const auth = (sources[0]!.config.auth ?? {}) as Record<string, unknown>;
1328+ expect(auth.type).toBe("bearer");
1329+ expect(auth.mode).toBe("workspace");
1330+ expect(auth.token).toBeUndefined();
1331+ });
12591332 });
12601333
12611334 describe("role hierarchy validation", () => {

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