@substrat-run/contract-tests 0.125.0 → 0.127.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/impersonation-suite.d.ts.map +1 -1
- package/dist/impersonation-suite.js +13 -0
- package/dist/impersonation-suite.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modules.d.ts.map +1 -1
- package/dist/modules.js +87 -4
- package/dist/modules.js.map +1 -1
- package/dist/permission-suite.d.ts.map +1 -1
- package/dist/permission-suite.js +69 -0
- package/dist/permission-suite.js.map +1 -1
- package/dist/scope-host-suite.d.ts.map +1 -1
- package/dist/scope-host-suite.js +350 -2
- package/dist/scope-host-suite.js.map +1 -1
- package/dist/scope-repoint-suite.d.ts +19 -0
- package/dist/scope-repoint-suite.d.ts.map +1 -0
- package/dist/scope-repoint-suite.js +231 -0
- package/dist/scope-repoint-suite.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ScopeHostFixture } from './scope-host-suite.js';
|
|
2
|
+
/**
|
|
3
|
+
* #1869: which tuples a restore, fork or snapshot re-points at the scope it lands in.
|
|
4
|
+
*
|
|
5
|
+
* A scope-level grant is stored as `scope:<scopeId>`, naming the scope a dump was captured
|
|
6
|
+
* from, so a copy landing elsewhere must move it. An entity-narrowed grant is stored as
|
|
7
|
+
* `<entityType>:<entityId>` and must not move. The rewrite used to select with
|
|
8
|
+
* `LIKE 'scope:%'`, which ignores ASCII case, so an entity grant typed `Scope` or `SCOPE`
|
|
9
|
+
* became a grant on the whole destination scope. The write verbs refuse such a type since
|
|
10
|
+
* #1856, so the rows are planted through the dump itself, the way a pre-#1856 scope holds
|
|
11
|
+
* them.
|
|
12
|
+
*
|
|
13
|
+
* Each case asserts the stored rows (byte for byte, every column) AND the checker's answer,
|
|
14
|
+
* with its twin: the genuine scope-level grant still resolves at the destination.
|
|
15
|
+
*
|
|
16
|
+
* The fixture must use the adapter's DEFAULT checker, as `permissionContractSuite` does.
|
|
17
|
+
*/
|
|
18
|
+
export declare function scopeRepointContractSuite(adapterName: string, makeFixture: () => Promise<ScopeHostFixture>): void;
|
|
19
|
+
//# sourceMappingURL=scope-repoint-suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-repoint-suite.d.ts","sourceRoot":"","sources":["../src/scope-repoint-suite.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAK9D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CA0OjH"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import { connectionId, permissionKey, platformActorId, principalId, scopeId, tenantId, } from '@substrat-run/contracts';
|
|
3
|
+
import { ulid } from '@substrat-run/kernel';
|
|
4
|
+
import { permMod } from './modules.js';
|
|
5
|
+
const PERM_READ = permissionKey.parse('perm:read');
|
|
6
|
+
/**
|
|
7
|
+
* #1869: which tuples a restore, fork or snapshot re-points at the scope it lands in.
|
|
8
|
+
*
|
|
9
|
+
* A scope-level grant is stored as `scope:<scopeId>`, naming the scope a dump was captured
|
|
10
|
+
* from, so a copy landing elsewhere must move it. An entity-narrowed grant is stored as
|
|
11
|
+
* `<entityType>:<entityId>` and must not move. The rewrite used to select with
|
|
12
|
+
* `LIKE 'scope:%'`, which ignores ASCII case, so an entity grant typed `Scope` or `SCOPE`
|
|
13
|
+
* became a grant on the whole destination scope. The write verbs refuse such a type since
|
|
14
|
+
* #1856, so the rows are planted through the dump itself, the way a pre-#1856 scope holds
|
|
15
|
+
* them.
|
|
16
|
+
*
|
|
17
|
+
* Each case asserts the stored rows (byte for byte, every column) AND the checker's answer,
|
|
18
|
+
* with its twin: the genuine scope-level grant still resolves at the destination.
|
|
19
|
+
*
|
|
20
|
+
* The fixture must use the adapter's DEFAULT checker, as `permissionContractSuite` does.
|
|
21
|
+
*/
|
|
22
|
+
export function scopeRepointContractSuite(adapterName, makeFixture) {
|
|
23
|
+
describe(`scope grant re-point on restore, fork and snapshot (#1869): ${adapterName}`, () => {
|
|
24
|
+
let fixture;
|
|
25
|
+
let host;
|
|
26
|
+
const staff = platformActorId.parse(ulid());
|
|
27
|
+
const t = tenantId.parse(ulid());
|
|
28
|
+
const source = scopeId.parse(ulid());
|
|
29
|
+
// gina holds a genuine role on the source scope; the others hold entity-narrowed reads
|
|
30
|
+
// whose entity type is a kernel namespace, spelled three ways.
|
|
31
|
+
const gina = principalId.parse(ulid());
|
|
32
|
+
const hana = principalId.parse(ulid()); // Scope:<source>
|
|
33
|
+
const ivan = principalId.parse(ulid()); // SCOPE:<source>
|
|
34
|
+
const jack = principalId.parse(ulid()); // scope:e-1
|
|
35
|
+
// Two more shapes spine SQL matched with LIKE (#1869 (c)): a role relation spelled
|
|
36
|
+
// `Role:`, and a connection subject spelled `Connection:`, beside the genuine one.
|
|
37
|
+
const kate = principalId.parse(ulid()); // Role:reader on the scope
|
|
38
|
+
const realConnection = connectionId.parse(ulid());
|
|
39
|
+
const casedConnection = connectionId.parse(ulid());
|
|
40
|
+
const casedRelation = connectionId.parse(ulid()); // `Granted:` rather than `granted:`
|
|
41
|
+
let planted;
|
|
42
|
+
const tuplesOf = (dump) => {
|
|
43
|
+
const table = dump.tables.find((tb) => tb.name === '_substrat_tuples');
|
|
44
|
+
expect(table).toBeDefined();
|
|
45
|
+
return table;
|
|
46
|
+
};
|
|
47
|
+
/** Every tuple `dump` holds for `who`, as whole rows keyed by column — the byte-for-byte view. */
|
|
48
|
+
const rowsIn = (dump, who) => {
|
|
49
|
+
const table = tuplesOf(dump);
|
|
50
|
+
return table.rows
|
|
51
|
+
.map((r) => Object.fromEntries(table.columns.map((c, i) => [c, r[i]])))
|
|
52
|
+
.filter((r) => r.subject === `principal:${who}`);
|
|
53
|
+
};
|
|
54
|
+
const rowsFor = async (scope, who) => rowsIn(await host.admin.exportScope(staff, t, scope), who);
|
|
55
|
+
const allowed = async (who, scope) => {
|
|
56
|
+
const stub = await host.getScope(who, t, scope);
|
|
57
|
+
const out = await stub.invoke('perm/probe', { permission: PERM_READ });
|
|
58
|
+
return out.allowed;
|
|
59
|
+
};
|
|
60
|
+
const blank = async () => {
|
|
61
|
+
const id = scopeId.parse(ulid());
|
|
62
|
+
await host.provisionScope(staff, { tenantId: t, scopeId: id, vertical: 'repoint-vertical' });
|
|
63
|
+
await host.admin.activateScope(staff, t, id);
|
|
64
|
+
return id;
|
|
65
|
+
};
|
|
66
|
+
/** The planted grants, read back from `scope`, must equal what the dump carried. */
|
|
67
|
+
const expectEntityGrantsKept = async (scope) => {
|
|
68
|
+
for (const who of [hana, ivan, jack]) {
|
|
69
|
+
const want = rowsIn(planted, who);
|
|
70
|
+
expect(want).toHaveLength(1);
|
|
71
|
+
expect(await rowsFor(scope, who)).toEqual(want);
|
|
72
|
+
// …and none of them reads the scope node: the grant stayed on its entity.
|
|
73
|
+
expect(await allowed(who, scope)).toBe(false);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
/** `planted` with its tuples rows (and optionally the table's DDL) rewritten. */
|
|
77
|
+
const variant = (rows, ddl) => ({
|
|
78
|
+
...planted,
|
|
79
|
+
tables: planted.tables.map((tb) => tb.name === '_substrat_tuples' ? { ...tb, rows: rows(tb.rows), ddl: ddl ? ddl(tb.ddl) : tb.ddl } : tb),
|
|
80
|
+
});
|
|
81
|
+
const tuplesAt = async (scope) => tuplesOf(await host.admin.exportScope(staff, t, scope)).rows;
|
|
82
|
+
const expectGenuineGrantMoved = async (scope) => {
|
|
83
|
+
const rows = await rowsFor(scope, gina);
|
|
84
|
+
expect(rows.map((r) => r.object)).toEqual([`scope:${scope}`]);
|
|
85
|
+
expect(await allowed(gina, scope)).toBe(true);
|
|
86
|
+
};
|
|
87
|
+
beforeAll(async () => {
|
|
88
|
+
fixture = await makeFixture();
|
|
89
|
+
host = fixture.host;
|
|
90
|
+
host.registerModule(permMod);
|
|
91
|
+
await host.admin.createTenant(staff, { id: t, slug: `repoint-${t.toLowerCase()}`, name: 'Repoint Co' });
|
|
92
|
+
await host.admin.grantEntitlement(staff, t, 'perm');
|
|
93
|
+
await host.admin.defineRole(staff, t, { key: 'reader', permissions: [PERM_READ], source: 'vertical' });
|
|
94
|
+
await host.provisionScope(staff, { tenantId: t, scopeId: source, vertical: 'repoint-vertical' });
|
|
95
|
+
await host.admin.activateScope(staff, t, source);
|
|
96
|
+
await host.admin.assignRole(staff, { principalId: gina, roleKey: 'reader', node: { tenantId: t, scopeId: source } });
|
|
97
|
+
// The source's own dump, with three pre-#1856 rows added to its tuples. Every column the
|
|
98
|
+
// table has is written, so the byte-for-byte comparison covers them all.
|
|
99
|
+
const dump = await host.admin.exportScope(staff, t, source);
|
|
100
|
+
const table = tuplesOf(dump);
|
|
101
|
+
const row = (subject, object, relation = `granted:${PERM_READ}`) => table.columns.map((c) => (c === 'subject' ? subject : c === 'relation' ? relation : c === 'object' ? object : null));
|
|
102
|
+
planted = {
|
|
103
|
+
...dump,
|
|
104
|
+
tables: dump.tables.map((tb) => tb === table
|
|
105
|
+
? {
|
|
106
|
+
...tb,
|
|
107
|
+
rows: [
|
|
108
|
+
...tb.rows,
|
|
109
|
+
row(`principal:${hana}`, `Scope:${source}`),
|
|
110
|
+
row(`principal:${ivan}`, `SCOPE:${source}`),
|
|
111
|
+
row(`principal:${jack}`, 'scope:e-1'),
|
|
112
|
+
row(`principal:${kate}`, `scope:${source}`, 'Role:reader'),
|
|
113
|
+
row(`connection:${realConnection}`, `scope:${source}`),
|
|
114
|
+
row(`Connection:${casedConnection}`, `scope:${source}`),
|
|
115
|
+
row(`connection:${casedRelation}`, `scope:${source}`, `Granted:${PERM_READ}`),
|
|
116
|
+
],
|
|
117
|
+
}
|
|
118
|
+
: tb),
|
|
119
|
+
};
|
|
120
|
+
// The genuine grant is in the dump, naming the source.
|
|
121
|
+
expect(rowsIn(planted, gina).map((r) => r.object)).toEqual([`scope:${source}`]);
|
|
122
|
+
}, 60_000);
|
|
123
|
+
afterAll(async () => {
|
|
124
|
+
await fixture?.cleanup();
|
|
125
|
+
});
|
|
126
|
+
it('a restore into another scope moves the source grant and nothing typed Scope, SCOPE or scope', async () => {
|
|
127
|
+
const dest = await blank();
|
|
128
|
+
await host.restoreScope(staff, t, dest, planted);
|
|
129
|
+
await expectGenuineGrantMoved(dest);
|
|
130
|
+
await expectEntityGrantsKept(dest);
|
|
131
|
+
});
|
|
132
|
+
it('a relation spelled Role: expands no role, and a subject spelled Connection: is no connection grant', async () => {
|
|
133
|
+
const dest = await blank();
|
|
134
|
+
await host.restoreScope(staff, t, dest, planted);
|
|
135
|
+
// Both rows sit on the scope node, so both moved with it…
|
|
136
|
+
expect((await rowsFor(dest, kate)).map((r) => [r.relation, r.object])).toEqual([['Role:reader', `scope:${dest}`]]);
|
|
137
|
+
// …and the walk still reads `Role:` as no role at all. Twin: gina's `role:reader` does.
|
|
138
|
+
expect(await allowed(kate, dest)).toBe(false);
|
|
139
|
+
expect(await allowed(gina, dest)).toBe(true);
|
|
140
|
+
// The read-back reports what the checker enforces: the genuine connection, not the cased one.
|
|
141
|
+
const reported = (await host.connectionGrantsInScope(t, dest)).map((g) => g.connectionId);
|
|
142
|
+
expect(reported).toContain(realConnection);
|
|
143
|
+
expect(reported).not.toContain(casedConnection);
|
|
144
|
+
expect(reported).not.toContain(casedRelation);
|
|
145
|
+
});
|
|
146
|
+
it('a dump declaring the object column COLLATE NOCASE does not make the match fold case again', async () => {
|
|
147
|
+
const nocase = variant((rows) => rows, (ddl) => {
|
|
148
|
+
const out = ddl.replace(/\bobject TEXT NOT NULL\b/, 'object TEXT NOT NULL COLLATE NOCASE');
|
|
149
|
+
expect(out).not.toBe(ddl);
|
|
150
|
+
return out;
|
|
151
|
+
});
|
|
152
|
+
const dest = await blank();
|
|
153
|
+
await host.restoreScope(staff, t, dest, nocase);
|
|
154
|
+
await expectGenuineGrantMoved(dest);
|
|
155
|
+
await expectEntityGrantsKept(dest);
|
|
156
|
+
});
|
|
157
|
+
it('a restored dump holding grants on a third scope is refused, and the target keeps what it held', async () => {
|
|
158
|
+
const third = scopeId.parse(ulid());
|
|
159
|
+
const lena = principalId.parse(ulid()); // holds a role on the third scope
|
|
160
|
+
const stray = tuplesOf(planted).columns.map((c) => c === 'subject' ? `principal:${lena}` : c === 'relation' ? 'role:reader' : c === 'object' ? `scope:${third}` : null);
|
|
161
|
+
const mixed = variant((rows) => [...rows, stray]);
|
|
162
|
+
const dest = await blank();
|
|
163
|
+
const before = await tuplesAt(dest);
|
|
164
|
+
await expect(host.restoreScope(staff, t, dest, mixed)).rejects.toThrow(new RegExp(`restore refused: the dump holds grants on 1 scope\\(s\\) other than its source .*scope:${third}`));
|
|
165
|
+
expect(await tuplesAt(dest)).toEqual(before);
|
|
166
|
+
// A fork of the same dump is a platform copy: the third-scope row authorized nothing in the
|
|
167
|
+
// source, so it is not refused and stays exactly as it was, while the source grant moves.
|
|
168
|
+
const fork = scopeId.parse(ulid());
|
|
169
|
+
await host.importScope(staff, { tenantId: t, scopeId: fork, vertical: 'repoint-vertical' }, mixed);
|
|
170
|
+
await expectGenuineGrantMoved(fork);
|
|
171
|
+
const strayRow = Object.fromEntries(tuplesOf(planted).columns.map((c, i) => [c, stray[i]]));
|
|
172
|
+
expect(await rowsFor(fork, lena)).toEqual([strayRow]);
|
|
173
|
+
// The twin is every other case here: a dump whose `scope:` rows are its source's, or an
|
|
174
|
+
// entity id that is not a scope id (`scope:e-1`), re-points without complaint.
|
|
175
|
+
});
|
|
176
|
+
it('a fork of a dump holding no grant on its source moves nothing: the platform vouches, so no fallback', async () => {
|
|
177
|
+
// A platform-exported dump (a fork, snapshot, preview, carry) whose source holds no
|
|
178
|
+
// scope-level grant. The fallback would read `scope:e-1` as a node grant and move it.
|
|
179
|
+
const object = tuplesOf(planted).columns.indexOf('object');
|
|
180
|
+
const bare = variant((rows) => rows.filter((r) => r[object] !== `scope:${source}`));
|
|
181
|
+
expect(rowsIn(bare, gina)).toEqual([]);
|
|
182
|
+
expect(rowsIn(bare, jack)).toHaveLength(1);
|
|
183
|
+
const fork = scopeId.parse(ulid());
|
|
184
|
+
await host.importScope(staff, { tenantId: t, scopeId: fork, vertical: 'repoint-vertical' }, bare);
|
|
185
|
+
await expectEntityGrantsKept(fork);
|
|
186
|
+
// Twin, the same dump restored by a caller: its provenance names no row, so it falls back.
|
|
187
|
+
const dest = await blank();
|
|
188
|
+
await host.restoreScope(staff, t, dest, bare);
|
|
189
|
+
expect((await rowsFor(dest, jack)).map((r) => r.object)).toEqual([`scope:${dest}`]);
|
|
190
|
+
});
|
|
191
|
+
it('a fork (importScope) does the same', async () => {
|
|
192
|
+
const fork = scopeId.parse(ulid());
|
|
193
|
+
await host.importScope(staff, { tenantId: t, scopeId: fork, vertical: 'repoint-vertical' }, planted);
|
|
194
|
+
await expectGenuineGrantMoved(fork);
|
|
195
|
+
await expectEntityGrantsKept(fork);
|
|
196
|
+
});
|
|
197
|
+
it('a scope restored from its own backup moves nothing, and a snapshot of it moves only the scope grant', async () => {
|
|
198
|
+
await host.restoreScope(staff, t, source, planted);
|
|
199
|
+
await expectGenuineGrantMoved(source);
|
|
200
|
+
await expectEntityGrantsKept(source);
|
|
201
|
+
const snap = await host.snapshotScope(staff, t, source);
|
|
202
|
+
await expectGenuineGrantMoved(snap);
|
|
203
|
+
await expectEntityGrantsKept(snap);
|
|
204
|
+
});
|
|
205
|
+
it('a separate source hint re-points exactly, while the dump itself names the destination (an upload)', async () => {
|
|
206
|
+
const dest = await blank();
|
|
207
|
+
await host.restoreScope(staff, t, dest, { ...planted, scopeId: dest }, { sourceScopeId: source });
|
|
208
|
+
await expectGenuineGrantMoved(dest);
|
|
209
|
+
await expectEntityGrantsKept(dest);
|
|
210
|
+
});
|
|
211
|
+
it("the fallback: provenance that names no row in the dump moves every exact 'scope:' prefix, never Scope or SCOPE", async () => {
|
|
212
|
+
// `substrat scope restore` stamps a local world with the TARGET's id, so the dump's
|
|
213
|
+
// stated source (`dest`) describes none of its rows (they name `source`). The exact rule
|
|
214
|
+
// would move nothing and strand gina's grant; the fallback moves what is spelled exactly
|
|
215
|
+
// `scope:`, which is the old rule without LIKE's case folding.
|
|
216
|
+
const dest = await blank();
|
|
217
|
+
await host.restoreScope(staff, t, dest, { ...planted, scopeId: dest });
|
|
218
|
+
await expectGenuineGrantMoved(dest);
|
|
219
|
+
for (const who of [hana, ivan]) {
|
|
220
|
+
expect((await rowsFor(dest, who)).map((r) => r.object)).toEqual([
|
|
221
|
+
`${who === hana ? 'Scope' : 'SCOPE'}:${source}`,
|
|
222
|
+
]);
|
|
223
|
+
expect(await allowed(who, dest)).toBe(false);
|
|
224
|
+
}
|
|
225
|
+
// The documented limit: without a source the dump holds, an entity typed exactly
|
|
226
|
+
// `scope` cannot be told from a node grant, and moves with it.
|
|
227
|
+
expect((await rowsFor(dest, jack)).map((r) => r.object)).toEqual([`scope:${dest}`]);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=scope-repoint-suite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-repoint-suite.js","sourceRoot":"","sources":["../src/scope-repoint-suite.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrat-run/contract-tests",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.127.0",
|
|
4
4
|
"description": "The suite every scope-host adapter must pass, forever (D-14)",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@substrat-run/contracts": "^0.
|
|
34
|
-
"@substrat-run/kernel": "^0.
|
|
33
|
+
"@substrat-run/contracts": "^0.127.0",
|
|
34
|
+
"@substrat-run/kernel": "^0.127.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@types/node": "^22.
|
|
37
|
+
"@types/node": "^22.20.4",
|
|
38
38
|
"typescript": "^7.0.0",
|
|
39
39
|
"vitest": "^3.2.7",
|
|
40
40
|
"zod": "^4.4.3"
|