Skip to content

Commit b361667

Browse files
committed
test(contracts): split config write lanes
1 parent 24afd52 commit b361667

4 files changed

Lines changed: 199 additions & 187 deletions

src/channels/plugins/contracts/plugins-core.authorize-config-write.contract.test.ts

Lines changed: 0 additions & 187 deletions
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { describeChannelConfigWritePolicyContract } from "../../../../test/helpers/channels/config-write-contract-suites.js";
2+
3+
describeChannelConfigWritePolicyContract();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { describeChannelConfigWriteTargetContract } from "../../../../test/helpers/channels/config-write-contract-suites.js";
2+
3+
describeChannelConfigWriteTargetContract();
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import { describe, expect, it } from "vitest";
2+
import {
3+
authorizeConfigWrite,
4+
canBypassConfigWritePolicy,
5+
formatConfigWriteDeniedMessage,
6+
resolveExplicitConfigWriteTarget,
7+
resolveConfigWriteTargetFromPath,
8+
} from "../../../src/channels/plugins/config-writes.js";
9+
import { INTERNAL_MESSAGE_CHANNEL } from "../../../src/utils/message-channel.js";
10+
11+
const demoOriginChannelId = "demo-origin";
12+
const demoTargetChannelId = "demo-target";
13+
14+
function makeDemoConfigWritesCfg(accountIdKey: string) {
15+
return {
16+
channels: {
17+
[demoOriginChannelId]: {
18+
configWrites: true,
19+
accounts: {
20+
[accountIdKey]: { configWrites: false },
21+
},
22+
},
23+
[demoTargetChannelId]: {
24+
configWrites: true,
25+
accounts: {
26+
[accountIdKey]: { configWrites: false },
27+
},
28+
},
29+
},
30+
};
31+
}
32+
33+
function expectConfigWriteBlocked(params: {
34+
disabledAccountId: string;
35+
reason: "target-disabled" | "origin-disabled";
36+
blockedScope: "target" | "origin";
37+
}) {
38+
expect(
39+
authorizeConfigWrite({
40+
cfg: makeDemoConfigWritesCfg(params.disabledAccountId),
41+
origin: { channelId: demoOriginChannelId, accountId: "default" },
42+
target: resolveExplicitConfigWriteTarget({
43+
channelId: params.blockedScope === "target" ? demoTargetChannelId : demoOriginChannelId,
44+
accountId: "work",
45+
}),
46+
}),
47+
).toEqual({
48+
allowed: false,
49+
reason: params.reason,
50+
blockedScope: {
51+
kind: params.blockedScope,
52+
scope: {
53+
channelId: params.blockedScope === "target" ? demoTargetChannelId : demoOriginChannelId,
54+
accountId: params.blockedScope === "target" ? "work" : "default",
55+
},
56+
},
57+
});
58+
}
59+
60+
function expectAuthorizedConfigWriteCase(
61+
input: Parameters<typeof authorizeConfigWrite>[0],
62+
expected: ReturnType<typeof authorizeConfigWrite>,
63+
) {
64+
expect(authorizeConfigWrite(input)).toEqual(expected);
65+
}
66+
67+
function expectResolvedConfigWriteTargetCase(pathSegments: readonly string[], expected: unknown) {
68+
expect(resolveConfigWriteTargetFromPath([...pathSegments])).toEqual(expected);
69+
}
70+
71+
function expectExplicitConfigWriteTargetCase(
72+
input: Parameters<typeof resolveExplicitConfigWriteTarget>[0],
73+
expected: ReturnType<typeof resolveExplicitConfigWriteTarget>,
74+
) {
75+
expect(resolveExplicitConfigWriteTarget(input)).toEqual(expected);
76+
}
77+
78+
function expectFormattedDeniedMessage(
79+
result: Exclude<ReturnType<typeof authorizeConfigWrite>, { allowed: true }>,
80+
) {
81+
expect(
82+
formatConfigWriteDeniedMessage({
83+
result,
84+
}),
85+
).toContain(`channels.${demoTargetChannelId}.accounts.work.configWrites=true`);
86+
}
87+
88+
export function describeChannelConfigWritePolicyContract() {
89+
describe("authorizeConfigWrite policy contract", () => {
90+
it.each([
91+
{
92+
name: "blocks when a target account disables writes",
93+
disabledAccountId: "work",
94+
reason: "target-disabled",
95+
blockedScope: "target",
96+
},
97+
{
98+
name: "blocks when the origin account disables writes",
99+
disabledAccountId: "default",
100+
reason: "origin-disabled",
101+
blockedScope: "origin",
102+
},
103+
] as const)("$name", (testCase) => {
104+
expectConfigWriteBlocked(testCase);
105+
});
106+
107+
it.each([
108+
{
109+
name: "allows bypass for internal operator.admin writes",
110+
input: {
111+
cfg: makeDemoConfigWritesCfg("work"),
112+
origin: { channelId: demoOriginChannelId, accountId: "default" },
113+
target: resolveExplicitConfigWriteTarget({
114+
channelId: demoTargetChannelId,
115+
accountId: "work",
116+
}),
117+
allowBypass: canBypassConfigWritePolicy({
118+
channel: INTERNAL_MESSAGE_CHANNEL,
119+
gatewayClientScopes: ["operator.admin"],
120+
}),
121+
},
122+
expected: { allowed: true },
123+
},
124+
{
125+
name: "treats non-channel config paths as global writes",
126+
input: {
127+
cfg: makeDemoConfigWritesCfg("work"),
128+
origin: { channelId: demoOriginChannelId, accountId: "default" },
129+
target: resolveConfigWriteTargetFromPath(["messages", "ackReaction"]),
130+
},
131+
expected: { allowed: true },
132+
},
133+
] as const)("$name", ({ input, expected }) => {
134+
expectAuthorizedConfigWriteCase(input, expected);
135+
});
136+
});
137+
}
138+
139+
export function describeChannelConfigWriteTargetContract() {
140+
describe("authorizeConfigWrite target contract", () => {
141+
it.each([
142+
{
143+
name: "rejects bare channel collection writes",
144+
pathSegments: ["channels", "demo-channel"],
145+
expected: { kind: "ambiguous", scopes: [{ channelId: "demo-channel" }] },
146+
},
147+
{
148+
name: "rejects account collection writes",
149+
pathSegments: ["channels", "demo-channel", "accounts"],
150+
expected: { kind: "ambiguous", scopes: [{ channelId: "demo-channel" }] },
151+
},
152+
] as const)("$name", ({ pathSegments, expected }) => {
153+
expectResolvedConfigWriteTargetCase(pathSegments, expected);
154+
});
155+
156+
it.each([
157+
{
158+
name: "resolves explicit channel target",
159+
input: { channelId: demoOriginChannelId },
160+
expected: {
161+
kind: "channel",
162+
scope: { channelId: demoOriginChannelId },
163+
},
164+
},
165+
{
166+
name: "resolves explicit account target",
167+
input: { channelId: demoTargetChannelId, accountId: "work" },
168+
expected: {
169+
kind: "account",
170+
scope: { channelId: demoTargetChannelId, accountId: "work" },
171+
},
172+
},
173+
] as const)("$name", ({ input, expected }) => {
174+
expectExplicitConfigWriteTargetCase(input, expected);
175+
});
176+
177+
it.each([
178+
{
179+
name: "formats denied messages consistently",
180+
result: {
181+
allowed: false,
182+
reason: "target-disabled",
183+
blockedScope: {
184+
kind: "target",
185+
scope: { channelId: demoTargetChannelId, accountId: "work" },
186+
},
187+
} as const,
188+
},
189+
] as const)("$name", ({ result }) => {
190+
expectFormattedDeniedMessage(result);
191+
});
192+
});
193+
}

0 commit comments

Comments
 (0)