Skip to content

Commit 3dd33f7

Browse files
committed
test(plugin-security): name the pins' permission sets by what the master door answers
Claude-Session: https://claude.ai/code/session_011TdZ8GjixNZFLz1xJD9zzK Co-authored-by: Claude <noreply@anthropic.com>
1 parent 438ef2d commit 3dd33f7

1 file changed

Lines changed: 18 additions & 15 deletions

File tree

‎packages/plugins/plugin-security/src/controlled-by-parent-master-object-read.test.ts‎

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,20 @@ const DELEGATOR_ADMITTED = 'u_cbp_mor_delegator_admitted';
6565

6666
const CRUD = { allowRead: true, allowCreate: true, allowEdit: true, allowDelete: true } as const;
6767

68-
/** Grant shapes, each named for what it holds on the MASTER object. */
68+
/**
69+
* The permission sets. Every one admits the detail objects it is used on; they
70+
* differ in whether the master object's read door admits the holder.
71+
*/
6972
const SET = {
70-
/** Detail and line grants, nothing on the master. */
71-
noMasterGrant: 'qa_cbp_mor_no_master_grant',
72-
/** Detail and line grants, and an edit grant on the master that is not a read grant. */
73-
masterEditNotRead: 'qa_cbp_mor_master_edit_not_read',
74-
/** Detail and line grants, a master read grant, and a row policy scoping the master to its owner. */
73+
/** The master object's read door does not admit the holder (first set). */
74+
unadmittedA: 'qa_cbp_mor_unadmitted_a',
75+
/** The master object's read door does not admit the holder (second set). */
76+
unadmittedB: 'qa_cbp_mor_unadmitted_b',
77+
/** Admitted to the master object, with its rows scoped to the holder's own. */
7578
masterReadRowScoped: 'qa_cbp_mor_master_read_row_scoped',
76-
/** Detail and line grants, and a master read grant with no row policy. */
79+
/** Admitted to the master object, rows unscoped. */
7780
masterRead: 'qa_cbp_mor_master_read',
78-
/** Line and master grants, nothing on the detail between them. */
81+
/** Admitted to the line and to the root master, not to the detail between them. */
7982
noMiddleGrant: 'qa_cbp_mor_no_middle_grant',
8083
} as const;
8184

@@ -164,9 +167,9 @@ async function boot() {
164167
}
165168
const sets = [
166169
...defaultPermissionSets,
167-
PermissionSetSchema.parse({ name: SET.noMasterGrant, objects: { [DETAIL]: CRUD, [LINE]: CRUD } }),
170+
PermissionSetSchema.parse({ name: SET.unadmittedA, objects: { [DETAIL]: CRUD, [LINE]: CRUD } }),
168171
PermissionSetSchema.parse({
169-
name: SET.masterEditNotRead,
172+
name: SET.unadmittedB,
170173
objects: { [MASTER]: { allowEdit: true }, [DETAIL]: CRUD, [LINE]: CRUD },
171174
}),
172175
PermissionSetSchema.parse({
@@ -186,13 +189,13 @@ async function boot() {
186189
}),
187190
];
188191
// The delegators hold their sets through stored grants, as a user does.
189-
for (const name of [SET.noMasterGrant, SET.masterRead]) {
192+
for (const name of [SET.unadmittedA, SET.masterRead]) {
190193
await e.getDriver('sys_permission_set').create('sys_permission_set', {
191194
id: `ps_${name}`, name, label: name, organization_id: null, managed_by: 'admin', active: true,
192195
object_permissions: JSON.stringify({}), system_permissions: JSON.stringify([]),
193196
});
194197
}
195-
for (const [user, set] of [[DELEGATOR_UNADMITTED, SET.noMasterGrant], [DELEGATOR_ADMITTED, SET.masterRead]] as const) {
198+
for (const [user, set] of [[DELEGATOR_UNADMITTED, SET.unadmittedA], [DELEGATOR_ADMITTED, SET.masterRead]] as const) {
196199
await e.insert('sys_user_permission_set', { id: `ups_${user}`, user_id: user, permission_set: set, organization_id: ORG }, SYS);
197200
}
198201

@@ -288,10 +291,10 @@ type Rig = Awaited<ReturnType<typeof boot>>;
288291

289292
const member = (userId: string, set: string) => ({ userId, positions: [], permissions: [set], posture: 'MEMBER' });
290293

291-
/** The two principals the master's own read door refuses at the object gate. */
294+
/** Two principals the master's own read door refuses at the object gate. */
292295
const UNADMITTED = [
293-
{ label: 'no grant on the master object', context: member(ME, SET.noMasterGrant) },
294-
{ label: 'an edit grant on the master object that is not a read grant', context: member(ME, SET.masterEditNotRead) },
296+
{ label: 'unadmitted principal A', context: member(ME, SET.unadmittedA) },
297+
{ label: 'unadmitted principal B', context: member(ME, SET.unadmittedB) },
295298
] as const;
296299

297300
describe('a controlled_by_parent detail is not read without object-level read on its master', () => {

0 commit comments

Comments
 (0)