@jantstack/adonis-authz 2.4.0-alpha.9 → 2.5.0-alpha.2
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/README.md +468 -30
- package/build/commands/authz_freeze.js +1 -1
- package/build/commands/authz_freeze.js.map +1 -1
- package/build/commands/authz_reconcile.d.ts +6 -2
- package/build/commands/authz_reconcile.d.ts.map +1 -1
- package/build/commands/authz_reconcile.js +129 -13
- package/build/commands/authz_reconcile.js.map +1 -1
- package/build/commands/authz_relations_reconcile.d.ts +16 -24
- package/build/commands/authz_relations_reconcile.d.ts.map +1 -1
- package/build/commands/authz_relations_reconcile.js +198 -49
- package/build/commands/authz_relations_reconcile.js.map +1 -1
- package/build/commands/authz_scopes_relay.d.ts.map +1 -1
- package/build/commands/authz_scopes_relay.js +81 -1
- package/build/commands/authz_scopes_relay.js.map +1 -1
- package/build/commands/authz_unfreeze.d.ts +12 -4
- package/build/commands/authz_unfreeze.d.ts.map +1 -1
- package/build/commands/authz_unfreeze.js +74 -9
- package/build/commands/authz_unfreeze.js.map +1 -1
- package/build/index.d.ts +6 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -3
- package/build/index.js.map +1 -1
- package/build/providers/authz_provider.d.ts +1 -1
- package/build/providers/authz_provider.d.ts.map +1 -1
- package/build/providers/authz_provider.js +5 -1
- package/build/providers/authz_provider.js.map +1 -1
- package/build/src/define_config.d.ts +41 -0
- package/build/src/define_config.d.ts.map +1 -1
- package/build/src/define_config.js +120 -0
- package/build/src/define_config.js.map +1 -1
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +1 -0
- package/build/src/drivers/database_driver.js.map +1 -1
- package/build/src/drivers/database_relations_driver.d.ts +18 -6
- package/build/src/drivers/database_relations_driver.d.ts.map +1 -1
- package/build/src/drivers/database_relations_driver.js +94 -46
- package/build/src/drivers/database_relations_driver.js.map +1 -1
- package/build/src/drivers/openfga_driver.d.ts +46 -5
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +115 -29
- package/build/src/drivers/openfga_driver.js.map +1 -1
- package/build/src/drivers/openfga_relations_driver.d.ts +82 -13
- package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_relations_driver.js +216 -55
- package/build/src/drivers/openfga_relations_driver.js.map +1 -1
- package/build/src/errors.d.ts +86 -0
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +86 -0
- package/build/src/errors.js.map +1 -1
- package/build/src/freeze.d.ts +63 -4
- package/build/src/freeze.d.ts.map +1 -1
- package/build/src/freeze.js +107 -18
- package/build/src/freeze.js.map +1 -1
- package/build/src/identity.d.ts +120 -9
- package/build/src/identity.d.ts.map +1 -1
- package/build/src/identity.js +164 -12
- package/build/src/identity.js.map +1 -1
- package/build/src/manager.d.ts +64 -2
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +267 -35
- package/build/src/manager.js.map +1 -1
- package/build/src/openfga.d.ts +2 -2
- package/build/src/openfga.d.ts.map +1 -1
- package/build/src/openfga.js +2 -2
- package/build/src/openfga.js.map +1 -1
- package/build/src/relations/check_many.d.ts +17 -0
- package/build/src/relations/check_many.d.ts.map +1 -0
- package/build/src/relations/check_many.js +57 -0
- package/build/src/relations/check_many.js.map +1 -0
- package/build/src/relations/define_relations_config.d.ts +74 -1
- package/build/src/relations/define_relations_config.d.ts.map +1 -1
- package/build/src/relations/define_relations_config.js +201 -7
- package/build/src/relations/define_relations_config.js.map +1 -1
- package/build/src/relations/manager.d.ts +20 -0
- package/build/src/relations/manager.d.ts.map +1 -1
- package/build/src/relations/manager.js +88 -15
- package/build/src/relations/manager.js.map +1 -1
- package/build/src/relations/reconcile.d.ts +134 -3
- package/build/src/relations/reconcile.d.ts.map +1 -1
- package/build/src/relations/reconcile.js +340 -36
- package/build/src/relations/reconcile.js.map +1 -1
- package/build/src/relations/tuple_key.d.ts +25 -0
- package/build/src/relations/tuple_key.d.ts.map +1 -0
- package/build/src/relations/tuple_key.js +60 -0
- package/build/src/relations/tuple_key.js.map +1 -0
- package/build/src/relations_config_store.d.ts.map +1 -1
- package/build/src/relations_config_store.js +29 -7
- package/build/src/relations_config_store.js.map +1 -1
- package/build/src/relations_reconcile.d.ts +79 -0
- package/build/src/relations_reconcile.d.ts.map +1 -0
- package/build/src/relations_reconcile.js +85 -0
- package/build/src/relations_reconcile.js.map +1 -0
- package/build/src/scope_outbox.d.ts +9 -5
- package/build/src/scope_outbox.d.ts.map +1 -1
- package/build/src/scope_outbox.js +7 -4
- package/build/src/scope_outbox.js.map +1 -1
- package/build/src/shared/backend_guard.d.ts +30 -11
- package/build/src/shared/backend_guard.d.ts.map +1 -1
- package/build/src/shared/backend_guard.js +45 -15
- package/build/src/shared/backend_guard.js.map +1 -1
- package/build/src/shared/sql_expiry.d.ts +2 -0
- package/build/src/shared/sql_expiry.d.ts.map +1 -1
- package/build/src/shared/sql_expiry.js +4 -0
- package/build/src/shared/sql_expiry.js.map +1 -1
- package/build/src/testing/main.d.ts +3 -1
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +2 -1
- package/build/src/testing/main.js.map +1 -1
- package/build/src/testing/migration_contract.d.ts +9 -0
- package/build/src/testing/migration_contract.d.ts.map +1 -1
- package/build/src/testing/migration_contract.js +5 -2
- package/build/src/testing/migration_contract.js.map +1 -1
- package/build/src/testing/relations_contract.d.ts +14 -0
- package/build/src/testing/relations_contract.d.ts.map +1 -1
- package/build/src/testing/relations_contract.js +367 -21
- package/build/src/testing/relations_contract.js.map +1 -1
- package/build/src/testing/scope_outbox_contract.d.ts +14 -1
- package/build/src/testing/scope_outbox_contract.d.ts.map +1 -1
- package/build/src/testing/scope_outbox_contract.js +126 -48
- package/build/src/testing/scope_outbox_contract.js.map +1 -1
- package/build/src/testing/test_clock.d.ts +15 -0
- package/build/src/testing/test_clock.d.ts.map +1 -0
- package/build/src/testing/test_clock.js +65 -0
- package/build/src/testing/test_clock.js.map +1 -0
- package/build/src/types.d.ts +115 -12
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js.map +1 -1
- package/package.json +6 -1
|
@@ -19,23 +19,31 @@
|
|
|
19
19
|
* puerto (`../types.js`), los errores y la config de relaciones. NO importa
|
|
20
20
|
* `manager` ni `drivers/*`: los drivers concretos los inyecta el llamante (la
|
|
21
21
|
* plataforma), como `manager.reconcile` recibe el destino por su clave.
|
|
22
|
+
*
|
|
23
|
+
* **Es un PRIMITIVO PRIVADO** (cierre del auditor de alpha.10 · R1): no sabe
|
|
24
|
+
* cuál es el driver activo ni toma la ventana durable, así que ya no sale de la
|
|
25
|
+
* raíz del paquete. La vía pública es `runRelationsReconcile`
|
|
26
|
+
* (`commands/authz_relations_reconcile.ts`), que resuelve origen y destino por
|
|
27
|
+
* clave, niega la dirección rancia y congela; la guardia de superficie de
|
|
28
|
+
* `command_flags.spec.ts` impide re-exportarlo por ningún subpath.
|
|
22
29
|
*/
|
|
23
|
-
import { AuthorizationConfigError, MassReconcileRefusedError, RelationTypeUnknownError, RelationUnknownError, UnsupportedOperationError, } from '../errors.js';
|
|
30
|
+
import { AuthorizationConfigError, InvalidIdentityError, MassReconcileRefusedError, RelationTypeUnknownError, RelationUnknownError, RelationUsersetUnsupportedError, UnsupportedOperationError, } from '../errors.js';
|
|
24
31
|
import { systemClock } from '../clock.js';
|
|
25
32
|
import { isActiveExpiry, sameInstant } from '../expiry.js';
|
|
33
|
+
import { assertPartition, scopeKey } from '../identity.js';
|
|
26
34
|
import { isRelUserset } from '../types.js';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
import { assertRelationDeclared, assertSupportedUserset } from './define_relations_config.js';
|
|
36
|
+
import { relationTupleKey } from './tuple_key.js';
|
|
37
|
+
/**
|
|
38
|
+
* La clave con la que se casan origen y destino es `relationTupleKey` (plan
|
|
39
|
+
* 2.5 · lote A, P3-4): la MISMA función pura y exportada que un consumidor
|
|
40
|
+
* usa para indexar sus metadatos, con `kind` desde el primer día (hoy todo
|
|
41
|
+
* lo que un driver enumera es `allow`; el lote D lo trae en `RelationTuple`
|
|
42
|
+
* y el `kind` explícito de aquí desaparece). Este módulo no define clave
|
|
43
|
+
* propia ni copia `scopeKey`
|
|
44
|
+
* (`tests/relation_tuple_key.spec.ts` lo vigila por fuente).
|
|
45
|
+
*/
|
|
46
|
+
const tupleKey = relationTupleKey;
|
|
39
47
|
/**
|
|
40
48
|
* Enumera TODAS las tuplas de las particiones pedidas, repartidas por clave de
|
|
41
49
|
* partición. UNA pasada con `enumerateRelationsMany` si el driver lo trae
|
|
@@ -51,10 +59,10 @@ async function enumerateAllMany(driver, partitions, role) {
|
|
|
51
59
|
}
|
|
52
60
|
const out = new Map();
|
|
53
61
|
for (const partition of partitions)
|
|
54
|
-
out.set(
|
|
62
|
+
out.set(scopeKey(partition), []);
|
|
55
63
|
const collect = (tuples) => {
|
|
56
64
|
for (const tuple of tuples) {
|
|
57
|
-
const bucket = out.get(
|
|
65
|
+
const bucket = out.get(scopeKey(tuple.partition));
|
|
58
66
|
// Una tupla de una partición que no se pidió no es de esta pasada: el
|
|
59
67
|
// puerto promete «solo las pedidas», y si un driver de terceros trae de
|
|
60
68
|
// más, no se migra lo ajeno.
|
|
@@ -101,12 +109,13 @@ export async function reconcileRelations(options) {
|
|
|
101
109
|
// seguro que salte en la partición 3 no deja las dos primeras a medias.
|
|
102
110
|
const plans = [];
|
|
103
111
|
for (const partition of partitions) {
|
|
104
|
-
const enumerated = enumeratedByKey.get(
|
|
105
|
-
const destTuples = destByKeyAll.get(
|
|
112
|
+
const enumerated = enumeratedByKey.get(scopeKey(partition)) ?? [];
|
|
113
|
+
const destTuples = destByKeyAll.get(scopeKey(partition)) ?? [];
|
|
106
114
|
plans.push(planPartition(partition, enumerated, destTuples, { now, prune, toConfig }));
|
|
107
115
|
}
|
|
108
116
|
const report = {
|
|
109
117
|
dryRun,
|
|
118
|
+
prune,
|
|
110
119
|
written: 0,
|
|
111
120
|
updated: 0,
|
|
112
121
|
deleted: 0,
|
|
@@ -114,7 +123,9 @@ export async function reconcileRelations(options) {
|
|
|
114
123
|
extra: 0,
|
|
115
124
|
modelDrift: [],
|
|
116
125
|
massDelete: false,
|
|
117
|
-
|
|
126
|
+
allowMassDelete,
|
|
127
|
+
skipped: { expired: 0, undeclared: 0, invalid: 0, usersetUnsupported: 0 },
|
|
128
|
+
details: [],
|
|
118
129
|
};
|
|
119
130
|
for (const plan of plans) {
|
|
120
131
|
// **El seguro de borrado masivo** (R-17, paridad con `authz:reconcile` de
|
|
@@ -126,10 +137,8 @@ export async function reconcileRelations(options) {
|
|
|
126
137
|
// recoge no migran, así que no cuentan como respaldo).
|
|
127
138
|
if (plan.massDelete && !dryRun && !allowMassDelete) {
|
|
128
139
|
throw new MassReconcileRefusedError(`authz:relations:reconcile --prune borraría ${plan.toDelete.length} tupla(s) de relación del destino` +
|
|
129
|
-
`${partitions.length > 1 ? ` (partición ${
|
|
130
|
-
`ORIGEN no ha aportado NI UNA utilizable (${plan.enumerated} leídas` +
|
|
131
|
-
`${toConfig ? ', todas de tipos que el destino no declara' : ''}` +
|
|
132
|
-
`${plan.skipped.expired ? `, ${plan.skipped.expired} caducada(s)` : ''}). Eso es la firma de un --from ` +
|
|
140
|
+
`${partitions.length > 1 ? ` (partición ${scopeKey(plan.partition)})` : ''} y el ` +
|
|
141
|
+
`ORIGEN no ha aportado NI UNA utilizable (${plan.enumerated} leídas${describeSkipped(plan.skipped)}). Eso es la firma de un --from ` +
|
|
133
142
|
`equivocado o de un store vacío, no de un destino que sobra: esta pasada dejaría la partición sin ` +
|
|
134
143
|
`una sola relación. Comprueba el --from y el store; si de verdad quieres vaciarlo, --allow-mass-delete.` +
|
|
135
144
|
`${partitions.length > 1 ? ' No se ha escrito nada en ninguna partición.' : ''}`);
|
|
@@ -137,6 +146,8 @@ export async function reconcileRelations(options) {
|
|
|
137
146
|
report.massDelete ||= plan.massDelete;
|
|
138
147
|
report.skipped.expired += plan.skipped.expired;
|
|
139
148
|
report.skipped.undeclared += plan.skipped.undeclared;
|
|
149
|
+
report.skipped.invalid += plan.skipped.invalid;
|
|
150
|
+
report.skipped.usersetUnsupported += plan.skipped.usersetUnsupported;
|
|
140
151
|
for (const type of plan.modelDrift)
|
|
141
152
|
if (!report.modelDrift.includes(type))
|
|
142
153
|
report.modelDrift.push(type);
|
|
@@ -164,26 +175,170 @@ export async function reconcileRelations(options) {
|
|
|
164
175
|
report.skipped.undeclared += 1;
|
|
165
176
|
updated -= 1;
|
|
166
177
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
178
|
+
}
|
|
179
|
+
// ⚪ R2 + cierre 1 y cierre 2 del lote B (🟡 N3, una regla, no dos): lo
|
|
180
|
+
// enumerado fuera de la gramática (`invalid-identity`) y el residuo pre-2.5
|
|
181
|
+
// de B3 (`userset-unsupported`) se LISTAN siempre, en los dos lados; con
|
|
182
|
+
// `prune` el del destino lleva `pruned: false` desde el plan — también en
|
|
183
|
+
// `--dry-run`—, porque NADIE lo borra: ni `toDelete` lo contiene ni el driver
|
|
184
|
+
// lo ve (hasta el cierre 2 `invalid-identity` se le pedía al driver y los dos
|
|
185
|
+
// del paquete lo rechazaban por el puerto, R-16). Cuenta en `extra` (abajo)
|
|
186
|
+
// y es deriva en los cuatro modos.
|
|
187
|
+
for (const invalid of plan.invalid) {
|
|
188
|
+
const detail = {
|
|
189
|
+
side: invalid.side,
|
|
190
|
+
reason: 'invalid-identity',
|
|
191
|
+
tuple: invalid.tuple,
|
|
192
|
+
message: invalid.message,
|
|
193
|
+
};
|
|
194
|
+
if (invalid.side === 'destino' && prune)
|
|
195
|
+
detail.pruned = false;
|
|
196
|
+
report.details.push(detail);
|
|
197
|
+
}
|
|
198
|
+
for (const residue of plan.usersetResidue) {
|
|
199
|
+
const detail = {
|
|
200
|
+
side: residue.side,
|
|
201
|
+
reason: 'userset-unsupported',
|
|
202
|
+
tuple: residue.tuple,
|
|
203
|
+
message: residue.message,
|
|
204
|
+
};
|
|
205
|
+
if (residue.side === 'destino' && prune)
|
|
206
|
+
detail.pruned = false;
|
|
207
|
+
report.details.push(detail);
|
|
208
|
+
}
|
|
209
|
+
// Cierre 3 del lote B · 🟠 N9, capa 1: la fila del DESTINO cuya relación o
|
|
210
|
+
// tipo `toConfig` no declara (una relación RETIRADA con filas vivas) se
|
|
211
|
+
// clasifica en el PLAN con la MISMA regla que los otros dos motivos: `extra`
|
|
212
|
+
// + `details`, `pruned: false` bajo `prune` (también en `--dry-run`), nunca
|
|
213
|
+
// en `toDelete` — `unrelate` la rechazaría por F-05 y hasta el cierre 3 ese
|
|
214
|
+
// 422 tumbaba la pasada a mitad, después de escribir.
|
|
215
|
+
for (const residue of plan.undeclaredResidue) {
|
|
216
|
+
const detail = { side: 'destino', reason: 'undeclared', tuple: residue.tuple, message: residue.message };
|
|
217
|
+
if (prune)
|
|
218
|
+
detail.pruned = false;
|
|
219
|
+
report.details.push(detail);
|
|
220
|
+
}
|
|
221
|
+
let deleted = prune ? plan.toDelete.length : 0;
|
|
222
|
+
let refused = 0;
|
|
223
|
+
if (!dryRun && prune) {
|
|
224
|
+
// Todo lo que hay en `toDelete` pasó la gramática Y, con `toConfig`, F-05
|
|
225
|
+
// del destino: un 422 del driver aquí es el driver diciendo otra cosa que
|
|
226
|
+
// el plan — o el plan sin `toConfig`, que no pudo anticipar F-05 (🟠 N9,
|
|
227
|
+
// capa 2). **La poda NUNCA lanza por un 422 de la familia de relaciones**:
|
|
228
|
+
// se clasifica por `code` con la MISMA regla (`extra` + `details`,
|
|
229
|
+
// `pruned: false`, deriva), se sigue con las demás filas y el comando sale
|
|
230
|
+
// ≠ 0 con la línea «sobra (<motivo>) destino:». Un 422 de OTRA familia o
|
|
231
|
+
// cualquier otro error sigue propagándose: eso sí es una contradicción que
|
|
232
|
+
// el reporte no sabe contar (R2-5: el plan clasifica, el driver no absorbe
|
|
233
|
+
// lo que no es suyo).
|
|
234
|
+
for (const tuple of plan.toDelete) {
|
|
235
|
+
const refusal = await unrelateOrClassify(to, tuple);
|
|
236
|
+
if (refusal === null)
|
|
237
|
+
continue;
|
|
238
|
+
report.details.push({ side: 'destino', reason: refusal.reason, tuple: describeTuple(tuple), message: refusal.message, pruned: false });
|
|
239
|
+
refused += 1;
|
|
240
|
+
deleted -= 1;
|
|
171
241
|
}
|
|
172
242
|
}
|
|
173
243
|
report.written += written;
|
|
174
244
|
report.updated += updated;
|
|
175
|
-
report.deleted +=
|
|
245
|
+
report.deleted += deleted;
|
|
176
246
|
report.unchanged += plan.unchanged;
|
|
177
|
-
|
|
247
|
+
// El residuo del destino (los tres motivos) sobra SIEMPRE, con o sin `prune`:
|
|
248
|
+
// no está en `toDelete`, así que se suma aparte — más lo que el driver
|
|
249
|
+
// rechazó con un 422 de la familia en la pasada real (capa 2 de N9).
|
|
250
|
+
report.extra += (prune ? 0 : plan.toDelete.length) + plan.destResidue + refused;
|
|
178
251
|
}
|
|
179
252
|
return report;
|
|
180
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* ⚪ N8 (cierre 2 del lote B): el desglose del seguro R-17, cada motivo POR SU
|
|
256
|
+
* NOMBRE y solo si cuenta (> 0). Hasta el cierre decía «todas de tipos que el
|
|
257
|
+
* destino no declara» siempre que había `toConfig`, también cuando el único
|
|
258
|
+
* aporte era residuo B3 — y sin `toConfig` no nombraba nada.
|
|
259
|
+
*/
|
|
260
|
+
function describeSkipped(skipped) {
|
|
261
|
+
const parts = [];
|
|
262
|
+
if (skipped.undeclared)
|
|
263
|
+
parts.push(`${skipped.undeclared} de tipo o relación que el destino no declara (skipped.undeclared)`);
|
|
264
|
+
if (skipped.usersetUnsupported)
|
|
265
|
+
parts.push(`${skipped.usersetUnsupported} con sujeto userset no admitido (B3, skipped.usersetUnsupported)`);
|
|
266
|
+
if (skipped.invalid)
|
|
267
|
+
parts.push(`${skipped.invalid} con identidad fuera de la gramática (skipped.invalid)`);
|
|
268
|
+
if (skipped.expired)
|
|
269
|
+
parts.push(`${skipped.expired} caducada(s)`);
|
|
270
|
+
return parts.length ? `: ${parts.join(', ')}` : '';
|
|
271
|
+
}
|
|
272
|
+
/** Una tupla enumerada, legible, para la línea del reporte (sin validar nada: puede estar fuera de la gramática). */
|
|
273
|
+
function describeTuple(tuple) {
|
|
274
|
+
const s = tuple?.subject;
|
|
275
|
+
const subject = isRelUserset(s) ? `${s.object?.type}:${s.object?.id}#${s.relation}` : `${s?.type}:${s?.uuid}`;
|
|
276
|
+
const p = tuple?.partition;
|
|
277
|
+
const partition = p?.type === 'app' ? 'app' : `${p?.type}|${p?.uuid}`;
|
|
278
|
+
return `${partition} ${tuple?.object?.type}:${tuple?.object?.id}#${tuple?.relation}@${subject}`;
|
|
279
|
+
}
|
|
280
|
+
/** `tupleKey` de una tupla ENUMERADA: la clave, o el motivo por el que su identidad no entra en la gramática (⚪ R2). */
|
|
281
|
+
function enumeratedKey(tuple) {
|
|
282
|
+
try {
|
|
283
|
+
return { key: tupleKey({ ...tuple, kind: 'allow' }) };
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
if (error instanceof InvalidIdentityError)
|
|
287
|
+
return { message: error.message };
|
|
288
|
+
throw error;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* **El sujeto de una tupla ENUMERADA, clasificado** (cierre 1 del lote B · 🟠 2;
|
|
293
|
+
* cierre 2 · 🟡 N2): `ok`, `userset-unsupported` (B3: userset ≠ `group#member`,
|
|
294
|
+
* con o sin config — `assertSupportedUserset` no necesita F-05), o `undeclared`
|
|
295
|
+
* (solo con `toConfig`: un `group#member` cuyo tipo/relación el destino no
|
|
296
|
+
* declara — F-05 del par; sin config esa cara la embuda el 422 del driver, como
|
|
297
|
+
* la del objeto). **La FORMA se juzga ANTES que F-05** (N2; decisión 3 del
|
|
298
|
+
* cierre 1 rechazada): un residuo B3 es inadmisible con cualquier config, así
|
|
299
|
+
* que un userset `folder#viewer` o `document#reader` que `toConfig` no declara
|
|
300
|
+
* es residuo con receta, nunca `undeclared` con el consejo falso «decláralo en
|
|
301
|
+
* el destino» (declarado, la pasada siguiente lo reclasificaba como residuo).
|
|
302
|
+
* Mutante «F-05 primero» ⇒ rojo. Nunca lanza por un dato del store
|
|
303
|
+
* (invariante 5).
|
|
304
|
+
*/
|
|
305
|
+
function classifySubject(tuple, toConfig) {
|
|
306
|
+
const subject = tuple?.subject;
|
|
307
|
+
if (!isRelUserset(subject))
|
|
308
|
+
return { kind: 'ok' };
|
|
309
|
+
try {
|
|
310
|
+
assertSupportedUserset(subject);
|
|
311
|
+
if (toConfig)
|
|
312
|
+
assertRelationDeclared(toConfig, subject.object, subject.relation);
|
|
313
|
+
return { kind: 'ok' };
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
if (error instanceof RelationUsersetUnsupportedError)
|
|
317
|
+
return { kind: 'userset-unsupported', message: error.message };
|
|
318
|
+
if (error instanceof RelationTypeUnknownError || error instanceof RelationUnknownError)
|
|
319
|
+
return { kind: 'undeclared' };
|
|
320
|
+
throw error;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
181
323
|
/** Exactamente uno de `partition` / `partitions` (y `partitions` no vacío): lo demás es 500 antes de leer nada. */
|
|
182
324
|
function partitionsOf(options) {
|
|
183
325
|
const { partition, partitions } = options;
|
|
184
326
|
if (partition !== undefined && partitions !== undefined) {
|
|
185
327
|
throw new AuthorizationConfigError('reconcileRelations: pasa `partition` O `partitions`, no los dos.');
|
|
186
328
|
}
|
|
329
|
+
// alpha.10 · 5, gemelo en la API: `{ type: 'app', uuid: 'x' }` reconciliaba la
|
|
330
|
+
// RAÍZ en silencio (la clave de `app` ignora el uuid), igual que la pareja
|
|
331
|
+
// `--partition-type=app --partition-uuid=x` del comando.
|
|
332
|
+
for (const p of partition !== undefined ? [partition] : Array.isArray(partitions) ? partitions : []) {
|
|
333
|
+
if (p?.type === 'app' && p.uuid !== null && p.uuid !== undefined) {
|
|
334
|
+
throw new AuthorizationConfigError(`reconcileRelations: la partición raíz no lleva uuid (llegó { type: 'app', uuid: ${JSON.stringify(p.uuid)} }). ` +
|
|
335
|
+
'O la raíz ({ type: app, uuid: null }) o el tipo del tenant.');
|
|
336
|
+
}
|
|
337
|
+
// D4 (plan 2.5 · lote A): la pasada recibe partición, así que la misma
|
|
338
|
+
// regla que toda operación del puerto — un uuid sin guiones es 422 antes
|
|
339
|
+
// de leer nada.
|
|
340
|
+
assertPartition(p);
|
|
341
|
+
}
|
|
187
342
|
if (partition !== undefined)
|
|
188
343
|
return [partition];
|
|
189
344
|
if (!Array.isArray(partitions) || partitions.length === 0) {
|
|
@@ -193,7 +348,7 @@ function partitionsOf(options) {
|
|
|
193
348
|
// Dos referencias con la misma clave son la misma partición: se migra una vez.
|
|
194
349
|
const seen = new Set();
|
|
195
350
|
return partitions.filter((p) => {
|
|
196
|
-
const key =
|
|
351
|
+
const key = scopeKey(p);
|
|
197
352
|
if (seen.has(key))
|
|
198
353
|
return false;
|
|
199
354
|
seen.add(key);
|
|
@@ -210,14 +365,40 @@ function planPartition(partition, enumerated, destTuples, context) {
|
|
|
210
365
|
// pasada real dan los mismos números— y tampoco respalda nada en el destino
|
|
211
366
|
// (una que ya estuviera allí es `extra`, y `--prune` la barre). El tipo se
|
|
212
367
|
// reporta además en `modelDrift` (deriva del modelo fusionado).
|
|
213
|
-
const skipped = { expired: 0, undeclared: 0 };
|
|
368
|
+
const skipped = { expired: 0, undeclared: 0, invalid: 0, usersetUnsupported: 0 };
|
|
214
369
|
const modelDrift = [];
|
|
215
370
|
const sourceTuples = [];
|
|
371
|
+
const invalid = [];
|
|
372
|
+
const usersetResidue = [];
|
|
216
373
|
for (const tuple of enumerated) {
|
|
217
374
|
if (!isActiveExpiry(tuple.expiresAt ?? null, now)) {
|
|
218
375
|
skipped.expired += 1;
|
|
219
376
|
continue;
|
|
220
377
|
}
|
|
378
|
+
// ⚪ R2: una identidad fuera de la gramática en el ORIGEN no es una pregunta
|
|
379
|
+
// del llamante (invariante 5): no se migra —la API del destino no podría
|
|
380
|
+
// escribirla—, se lista y se cuenta. Nunca un 422 por un dato del store.
|
|
381
|
+
const keyed = enumeratedKey(tuple);
|
|
382
|
+
if ('message' in keyed) {
|
|
383
|
+
skipped.invalid += 1;
|
|
384
|
+
invalid.push({ side: 'origen', tuple: describeTuple(tuple), message: keyed.message });
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
// Cierre 1 del lote B · 🟠 2: el residuo pre-2.5 de B3 en el ORIGEN se
|
|
388
|
+
// clasifica AQUÍ, con o sin `toConfig` — no se migra (ninguna puerta del
|
|
389
|
+
// destino lo admite), se lista con su receta y se cuenta aparte. Hasta el
|
|
390
|
+
// cierre llegaba al driver, que lo rechazaba con 422, y `relateOrSkip` lo
|
|
391
|
+
// tragaba como `undeclared` (consejo falso; `--dry-run` decía `written`).
|
|
392
|
+
const subject = classifySubject(tuple, toConfig);
|
|
393
|
+
if (subject.kind === 'userset-unsupported') {
|
|
394
|
+
skipped.usersetUnsupported += 1;
|
|
395
|
+
usersetResidue.push({ side: 'origen', tuple: describeTuple(tuple), message: subject.message });
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (subject.kind === 'undeclared') {
|
|
399
|
+
skipped.undeclared += 1;
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
221
402
|
if (toConfig && !declaredIn(toConfig, tuple.object.type)) {
|
|
222
403
|
skipped.undeclared += 1;
|
|
223
404
|
if (!modelDrift.includes(tuple.object.type))
|
|
@@ -232,10 +413,54 @@ function planPartition(partition, enumerated, destTuples, context) {
|
|
|
232
413
|
}
|
|
233
414
|
const sourceByKey = new Map();
|
|
234
415
|
for (const tuple of sourceTuples)
|
|
235
|
-
sourceByKey.set(tupleKey(tuple), tuple);
|
|
416
|
+
sourceByKey.set(tupleKey({ ...tuple, kind: 'allow' }), tuple);
|
|
417
|
+
// ⚪ R2 + cierre 2 · N3: una tupla del DESTINO fuera de la gramática es
|
|
418
|
+
// `extra` con motivo (`invalid-identity`): nadie del origen puede respaldarla
|
|
419
|
+
// (la clave no se puede ni componer) y NADIE la borra — ni `toDelete` (los dos
|
|
420
|
+
// drivers del paquete la rechazan por el puerto, R-16; hasta el cierre 2 se les
|
|
421
|
+
// pedía igual) ni un DELETE de plataforma—: se lista con `pruned: false` y es
|
|
422
|
+
// deriva en los cuatro modos, exactamente como el residuo de B3 de abajo.
|
|
236
423
|
const destByKey = new Map();
|
|
237
|
-
|
|
238
|
-
|
|
424
|
+
const destInvalid = new Set();
|
|
425
|
+
const destResidue = new Set();
|
|
426
|
+
const undeclaredResidue = [];
|
|
427
|
+
for (const tuple of destTuples) {
|
|
428
|
+
const keyed = enumeratedKey(tuple);
|
|
429
|
+
if ('message' in keyed) {
|
|
430
|
+
destInvalid.add(tuple);
|
|
431
|
+
invalid.push({ side: 'destino', tuple: describeTuple(tuple), message: keyed.message });
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
// Cierre 1 del lote B · 🟠 1: el residuo pre-2.5 de B3 en el DESTINO sobra
|
|
435
|
+
// (nadie del origen puede respaldarlo: el origen lo descarta arriba) pero
|
|
436
|
+
// NO entra en `toDelete`: la pasada no se lo pide al driver ni con `--prune`
|
|
437
|
+
// —`unrelate` lo rechazaría con 422 y hasta el cierre eso ABORTABA la pasada
|
|
438
|
+
// a mitad, con los `toWrite` ya escritos—. Se lista con `pruned: false` y
|
|
439
|
+
// la receta, cuenta en `extra` y es deriva. Solo la forma del userset: la
|
|
440
|
+
// F-05 del par del SUJETO no decide aquí (un userset que pasa la forma es
|
|
441
|
+
// `group#member`, declarado en toda config).
|
|
442
|
+
const subject = classifySubject(tuple, undefined);
|
|
443
|
+
if (subject.kind === 'userset-unsupported') {
|
|
444
|
+
destResidue.add(tuple);
|
|
445
|
+
usersetResidue.push({ side: 'destino', tuple: describeTuple(tuple), message: subject.message });
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
// Cierre 3 del lote B · 🟠 N9 (capa 1): la fila cuya RELACIÓN o TIPO el
|
|
449
|
+
// destino (`toConfig`) ya no declara — una relación retirada de la config con
|
|
450
|
+
// filas vivas (`#enumerateRows`/`#sweep` filtran por tipo, no por relación) o
|
|
451
|
+
// un driver con la config vieja — es la tercera fila que la API no admite:
|
|
452
|
+
// `unrelate` la rechaza por F-05, así que lleva la MISMA regla que las dos de
|
|
453
|
+
// arriba (nunca en `toDelete`, `pruned: false`, deriva, receta). La regla es
|
|
454
|
+
// por la FILA, no por el driver (N3): hasta el cierre 3 un driver viejo la
|
|
455
|
+
// borraba y el driver nuevo tumbaba la pasada a mitad con un stack crudo.
|
|
456
|
+
const undeclared = toConfig ? classifyDestinationRow(toConfig, tuple) : null;
|
|
457
|
+
if (undeclared !== null) {
|
|
458
|
+
destResidue.add(tuple);
|
|
459
|
+
undeclaredResidue.push({ tuple: describeTuple(tuple), message: undeclared });
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
destByKey.set(keyed.key, tuple);
|
|
463
|
+
}
|
|
239
464
|
const toWrite = [];
|
|
240
465
|
const toUpdate = [];
|
|
241
466
|
let unchanged = 0;
|
|
@@ -249,9 +474,81 @@ function planPartition(partition, enumerated, destTuples, context) {
|
|
|
249
474
|
else
|
|
250
475
|
unchanged += 1;
|
|
251
476
|
}
|
|
252
|
-
const toDelete = destTuples.filter((tuple) => !sourceByKey.has(tupleKey(tuple)));
|
|
477
|
+
const toDelete = destTuples.filter((tuple) => !destResidue.has(tuple) && !destInvalid.has(tuple) && !sourceByKey.has(tupleKey({ ...tuple, kind: 'allow' })));
|
|
253
478
|
const massDelete = prune && toDelete.length > 0 && sourceTuples.length === 0;
|
|
254
|
-
return {
|
|
479
|
+
return {
|
|
480
|
+
partition,
|
|
481
|
+
enumerated: enumerated.length,
|
|
482
|
+
toWrite,
|
|
483
|
+
toUpdate,
|
|
484
|
+
toDelete,
|
|
485
|
+
unchanged,
|
|
486
|
+
skipped,
|
|
487
|
+
modelDrift,
|
|
488
|
+
massDelete,
|
|
489
|
+
invalid,
|
|
490
|
+
usersetResidue,
|
|
491
|
+
undeclaredResidue,
|
|
492
|
+
destResidue: destResidue.size + destInvalid.size,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* **F-05 del destino sobre una fila ENUMERADA del destino** (cierre 3 del lote B ·
|
|
497
|
+
* 🟠 N9, capa 1): la MISMA `assertRelationDeclared` que corre en la primera línea
|
|
498
|
+
* de `unrelate` de los dos drivers, aplicada en el plan para que `--dry-run` y la
|
|
499
|
+
* pasada real den los mismos números y la fila nunca llegue a un `unrelate` que
|
|
500
|
+
* la rechazaría. Devuelve el porqué (el mensaje de F-05: tipo o relación) o
|
|
501
|
+
* `null` si el destino la declara. Nunca lanza por un dato del store
|
|
502
|
+
* (invariante 5): cualquier otra excepción se propaga tal cual.
|
|
503
|
+
*/
|
|
504
|
+
function classifyDestinationRow(toConfig, tuple) {
|
|
505
|
+
try {
|
|
506
|
+
assertRelationDeclared(toConfig, tuple.object, tuple.relation);
|
|
507
|
+
return null;
|
|
508
|
+
}
|
|
509
|
+
catch (error) {
|
|
510
|
+
if (error instanceof RelationTypeUnknownError || error instanceof RelationUnknownError)
|
|
511
|
+
return error.message;
|
|
512
|
+
throw error;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* **Los 422 de la FAMILIA de relaciones, clasificados por `code`** (cierre 3 del
|
|
517
|
+
* lote B · 🟠 N9, capa 2): lo que el bucle de poda absorbe cuando el driver del
|
|
518
|
+
* destino rechaza un `unrelate` que el plan dio por bueno — sin `toConfig` el plan
|
|
519
|
+
* no puede anticipar F-05, y un driver de terceros puede decir cualquiera de los
|
|
520
|
+
* cuatro—. Por `code` y `status`, no por clase: un driver de terceros lanza su
|
|
521
|
+
* propia clase con el mismo código. Fuera de esta tabla NADA se absorbe.
|
|
522
|
+
*/
|
|
523
|
+
const RELATION_422_REASONS = Object.freeze({
|
|
524
|
+
[RelationTypeUnknownError.code]: 'undeclared',
|
|
525
|
+
[RelationUnknownError.code]: 'undeclared',
|
|
526
|
+
[RelationUsersetUnsupportedError.code]: 'userset-unsupported',
|
|
527
|
+
[InvalidIdentityError.code]: 'invalid-identity',
|
|
528
|
+
});
|
|
529
|
+
/**
|
|
530
|
+
* Borra la tupla del destino; devuelve `null` si se borró (o ya no estaba) y el
|
|
531
|
+
* motivo + porqué si el DRIVER la rechazó con un 422 de la familia de relaciones
|
|
532
|
+
* (`RELATION_422_REASONS`): la pasada lo clasifica como residuo del destino con
|
|
533
|
+
* `pruned: false` y SIGUE con las demás filas (🟠 N9: nunca un throw a mitad de
|
|
534
|
+
* pasada por una fila que el reporte puede contar). Cualquier otro error —otro
|
|
535
|
+
* 422, un 503, un `Error`— se propaga tal cual: eso sí es el driver
|
|
536
|
+
* contradiciendo al plan por algo que la pasada no sabe contar.
|
|
537
|
+
*/
|
|
538
|
+
async function unrelateOrClassify(to, tuple) {
|
|
539
|
+
try {
|
|
540
|
+
await to.unrelate(tuple.subject, tuple.relation, tuple.object, tuple.partition);
|
|
541
|
+
return null;
|
|
542
|
+
}
|
|
543
|
+
catch (error) {
|
|
544
|
+
// Por `status` Y por `code` PROPIO de la tabla (`Object.hasOwn`, repaso del cierre 3 · ⚪ N13): un 422 con un
|
|
545
|
+
// `code` heredado del prototipo (`constructor`, `toString`, `__proto__`) no es de la familia y se propaga.
|
|
546
|
+
const code = String(error?.code);
|
|
547
|
+
const reason = error?.status === 422 && Object.hasOwn(RELATION_422_REASONS, code) ? RELATION_422_REASONS[code] : undefined;
|
|
548
|
+
if (reason === undefined)
|
|
549
|
+
throw error;
|
|
550
|
+
return { reason, message: String(error?.message ?? error) };
|
|
551
|
+
}
|
|
255
552
|
}
|
|
256
553
|
/** ¿El tipo de objeto cabe en el modelo fusionado del destino? (`group` es built-in: `hasType` lo incluye.) */
|
|
257
554
|
function declaredIn(config, objectType) {
|
|
@@ -260,7 +557,12 @@ function declaredIn(config, objectType) {
|
|
|
260
557
|
/**
|
|
261
558
|
* Escribe la tupla en el destino; `false` si el DRIVER la rechazó por F-05
|
|
262
559
|
* (tipo o relación no declarados: 422 `E_AUTHZ_RELATION_TYPE_UNKNOWN` /
|
|
263
|
-
* `E_AUTHZ_RELATION_UNKNOWN`). Cualquier otro error se propaga tal cual
|
|
560
|
+
* `E_AUTHZ_RELATION_UNKNOWN`). Cualquier otro error se propaga tal cual —
|
|
561
|
+
* **también `E_AUTHZ_RELATION_USERSET_UNSUPPORTED`** (cierre 1 del lote B,
|
|
562
|
+
* decisión 4 rechazada): esa clase ya no hereda de F-05 y aquí no se absorbe;
|
|
563
|
+
* el residuo de B3 se clasifica en el PLAN y nunca llega a este `relate`. Un
|
|
564
|
+
* driver que lo lanzara por una tupla que el plan dio por buena está diciendo
|
|
565
|
+
* otra cosa, y eso se propaga (R2-5: el plan clasifica, el driver no absorbe).
|
|
264
566
|
*/
|
|
265
567
|
async function relateOrSkip(to, tuple) {
|
|
266
568
|
try {
|
|
@@ -270,6 +572,8 @@ async function relateOrSkip(to, tuple) {
|
|
|
270
572
|
return true;
|
|
271
573
|
}
|
|
272
574
|
catch (error) {
|
|
575
|
+
if (error instanceof RelationUsersetUnsupportedError)
|
|
576
|
+
throw error;
|
|
273
577
|
if (error instanceof RelationTypeUnknownError || error instanceof RelationUnknownError)
|
|
274
578
|
return false;
|
|
275
579
|
throw error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../../src/relations/reconcile.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../../src/relations/reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RelObject, RelSubject, ScopeRef } from '../types.js';
|
|
2
|
+
export type RelationTupleKind = 'allow' | 'deny';
|
|
3
|
+
/**
|
|
4
|
+
* Lo que identifica una tupla: la forma de `RelationTuple` más el `kind`,
|
|
5
|
+
* **obligatorio y sin default** (⚪ A9 del auditor del lote A): `allow` por
|
|
6
|
+
* omisión era el modo de fallo peligroso —un deny enumerado por un driver que
|
|
7
|
+
* no pusiera `kind` casaría con el allow en `reconcileRelations`—. Quien
|
|
8
|
+
* casa tuplas dice de qué clase son.
|
|
9
|
+
*/
|
|
10
|
+
export interface RelationTupleIdentity {
|
|
11
|
+
partition: ScopeRef;
|
|
12
|
+
object: RelObject;
|
|
13
|
+
relation: string;
|
|
14
|
+
subject: RelSubject;
|
|
15
|
+
kind: RelationTupleKind;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* La clave de un SUJETO: holder `<type>:<uuid>`, userset `<type>:<id>#<relation>`.
|
|
19
|
+
* Valida sus componentes con la gramática de identidad (⚪ A9): sin ella
|
|
20
|
+
* `{ relation: 'b@user:c#d' }` y un userset legítimo daban la MISMA clave y
|
|
21
|
+
* el «parseo unívoco» del docblock era falso.
|
|
22
|
+
*/
|
|
23
|
+
export declare function relationSubjectKey(subject: RelSubject): string;
|
|
24
|
+
export declare function relationTupleKey(tuple: RelationTupleIdentity): string;
|
|
25
|
+
//# sourceMappingURL=tuple_key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tuple_key.d.ts","sourceRoot":"","sources":["../../../src/relations/tuple_key.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAElE,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,CAAA;AAEhD;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,QAAQ,CAAA;IACnB,MAAM,EAAE,SAAS,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,iBAAiB,CAAA;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAS9D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAcrE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **`relationTupleKey` — la clave PURA y estable de una tupla de relación**
|
|
3
|
+
* (plan 2.5 · lote A, P3 del 7.º informe de COGNITIV; `panel-tenencia-juez.md`
|
|
4
|
+
* §P3: «sin `meta` en el paquete; clave pura sí»).
|
|
5
|
+
*
|
|
6
|
+
* Determinista e inyectiva sobre los cinco componentes que identifican una
|
|
7
|
+
* tupla —`kind`, partición, objeto (tipo + id), relación y sujeto (holder o
|
|
8
|
+
* userset)— y SOLO sobre ellos: la caducidad no entra (renovarla no cambia la
|
|
9
|
+
* identidad; en `database` sí cambia el uuid de fila, que por eso tampoco
|
|
10
|
+
* sirve de clave), y el `uuid` de fila o el id del store tampoco. Es la clave
|
|
11
|
+
* que `reconcileRelations` usa para casar origen y destino, y la que un
|
|
12
|
+
* consumidor puede usar para indexar sus propios metadatos sobre una tupla
|
|
13
|
+
* sin que el paquete los guarde.
|
|
14
|
+
*
|
|
15
|
+
* **`kind` desde el primer día, con literal de oro**: el lote D trae el deny
|
|
16
|
+
* como tuplas `kind: 'deny'`. Para que un deny y un allow sobre la misma
|
|
17
|
+
* terna nunca colapsen en una clave —y para que la clave de un allow que ya
|
|
18
|
+
* está en un índice del consumidor NO cambie cuando llegue el deny—, el
|
|
19
|
+
* `kind` va en la clave desde ahora (OBLIGATORIO, sin default: ⚪ A9) y
|
|
20
|
+
* `tests/relation_tuple_key.spec.ts` fija el literal exacto de un allow.
|
|
21
|
+
*
|
|
22
|
+
* Forma: `<kind>|<scopeKey(partition)>|<object.type>:<object.id>#<relation>@<subject>`,
|
|
23
|
+
* con `<subject>` = `<type>:<uuid>` (holder) o `<type>:<id>#<relation>`
|
|
24
|
+
* (userset). Ningún componente admite `|`, `#`, `:` ni `@` —la gramática de
|
|
25
|
+
* identidad se APLICA aquí a cada componente (⚪ A9), no se presupone—, así
|
|
26
|
+
* que el parseo es unívoco.
|
|
27
|
+
*
|
|
28
|
+
* Pureza (regla 2): solo el puerto y la gramática de identidad.
|
|
29
|
+
*/
|
|
30
|
+
import { InvalidIdentityError } from '../errors.js';
|
|
31
|
+
import { assertRelationId, assertSubject, scopeKey } from '../identity.js';
|
|
32
|
+
import { isRelUserset } from '../types.js';
|
|
33
|
+
/**
|
|
34
|
+
* La clave de un SUJETO: holder `<type>:<uuid>`, userset `<type>:<id>#<relation>`.
|
|
35
|
+
* Valida sus componentes con la gramática de identidad (⚪ A9): sin ella
|
|
36
|
+
* `{ relation: 'b@user:c#d' }` y un userset legítimo daban la MISMA clave y
|
|
37
|
+
* el «parseo unívoco» del docblock era falso.
|
|
38
|
+
*/
|
|
39
|
+
export function relationSubjectKey(subject) {
|
|
40
|
+
if (isRelUserset(subject)) {
|
|
41
|
+
assertRelationId('el tipo del objeto del userset', subject.object?.type);
|
|
42
|
+
assertRelationId(`el id del objeto '${subject.object?.type}' del userset`, subject.object?.id);
|
|
43
|
+
assertRelationId('la relación del userset', subject.relation);
|
|
44
|
+
return `${subject.object.type}:${subject.object.id}#${subject.relation}`;
|
|
45
|
+
}
|
|
46
|
+
assertSubject(subject);
|
|
47
|
+
return `${subject.type}:${subject.uuid}`;
|
|
48
|
+
}
|
|
49
|
+
export function relationTupleKey(tuple) {
|
|
50
|
+
const kind = tuple?.kind;
|
|
51
|
+
if (kind !== 'allow' && kind !== 'deny') {
|
|
52
|
+
throw new InvalidIdentityError(`relationTupleKey: kind inválido ${kind === undefined ? 'ausente' : `'${String(kind)}'`} ` +
|
|
53
|
+
`(se exige 'allow' o 'deny', sin default: un deny sin kind casaría con el allow)`);
|
|
54
|
+
}
|
|
55
|
+
assertRelationId('el tipo del objeto', tuple.object?.type);
|
|
56
|
+
assertRelationId(`el id del objeto '${tuple.object?.type}'`, tuple.object?.id);
|
|
57
|
+
assertRelationId('la relación', tuple.relation);
|
|
58
|
+
return `${kind}|${scopeKey(tuple.partition)}|${tuple.object.type}:${tuple.object.id}#${tuple.relation}@${relationSubjectKey(tuple.subject)}`;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=tuple_key.js.map
|