@jantstack/adonis-authz 2.4.0-alpha.1 → 2.4.0-alpha.3
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 +299 -19
- package/build/commands/authz_relations_reconcile.d.ts +25 -1
- package/build/commands/authz_relations_reconcile.d.ts.map +1 -1
- package/build/commands/authz_relations_reconcile.js +94 -6
- package/build/commands/authz_relations_reconcile.js.map +1 -1
- package/build/index.d.ts +13 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +15 -1
- package/build/index.js.map +1 -1
- package/build/providers/authz_provider.d.ts +6 -1
- package/build/providers/authz_provider.d.ts.map +1 -1
- package/build/providers/authz_provider.js +18 -2
- package/build/providers/authz_provider.js.map +1 -1
- package/build/src/define_config.d.ts +73 -1
- package/build/src/define_config.d.ts.map +1 -1
- package/build/src/define_config.js.map +1 -1
- package/build/src/drivers/database_driver.d.ts +53 -14
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +104 -32
- package/build/src/drivers/database_driver.js.map +1 -1
- package/build/src/drivers/database_relations_driver.d.ts +57 -9
- package/build/src/drivers/database_relations_driver.d.ts.map +1 -1
- package/build/src/drivers/database_relations_driver.js +344 -89
- package/build/src/drivers/database_relations_driver.js.map +1 -1
- package/build/src/drivers/openfga_driver.d.ts +17 -4
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +38 -3
- package/build/src/drivers/openfga_driver.js.map +1 -1
- package/build/src/drivers/openfga_facts.d.ts +15 -0
- package/build/src/drivers/openfga_facts.d.ts.map +1 -1
- package/build/src/drivers/openfga_facts.js +25 -2
- package/build/src/drivers/openfga_facts.js.map +1 -1
- package/build/src/drivers/openfga_relations_driver.d.ts +40 -6
- package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_relations_driver.js +244 -44
- package/build/src/drivers/openfga_relations_driver.js.map +1 -1
- package/build/src/errors.d.ts +83 -4
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +139 -3
- package/build/src/errors.js.map +1 -1
- package/build/src/freeze.d.ts +37 -16
- package/build/src/freeze.d.ts.map +1 -1
- package/build/src/freeze.js +53 -8
- package/build/src/freeze.js.map +1 -1
- package/build/src/manager.d.ts +16 -1
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +116 -25
- package/build/src/manager.js.map +1 -1
- package/build/src/models/authz_assignment.d.ts +2 -2
- package/build/src/models/authz_assignment.d.ts.map +1 -1
- package/build/src/models/authz_deny.d.ts +2 -2
- package/build/src/models/authz_deny.d.ts.map +1 -1
- package/build/src/models/authz_permission.d.ts +2 -2
- package/build/src/models/authz_permission.d.ts.map +1 -1
- package/build/src/models/authz_role.d.ts +2 -2
- package/build/src/models/authz_role.d.ts.map +1 -1
- package/build/src/models/authz_role_permission.d.ts +2 -2
- package/build/src/models/authz_role_permission.d.ts.map +1 -1
- package/build/src/relation_partition_trigger.d.ts.map +1 -1
- package/build/src/relation_partition_trigger.js +11 -3
- package/build/src/relation_partition_trigger.js.map +1 -1
- package/build/src/relations/define_relations_config.d.ts +51 -0
- package/build/src/relations/define_relations_config.d.ts.map +1 -1
- package/build/src/relations/define_relations_config.js +68 -1
- package/build/src/relations/define_relations_config.js.map +1 -1
- package/build/src/relations/manager.d.ts +71 -6
- package/build/src/relations/manager.d.ts.map +1 -1
- package/build/src/relations/manager.js +301 -29
- package/build/src/relations/manager.js.map +1 -1
- package/build/src/relations/reconcile.d.ts +53 -4
- package/build/src/relations/reconcile.d.ts.map +1 -1
- package/build/src/relations/reconcile.js +92 -30
- package/build/src/relations/reconcile.js.map +1 -1
- package/build/src/scope_outbox.d.ts.map +1 -1
- package/build/src/scope_outbox.js +17 -10
- package/build/src/scope_outbox.js.map +1 -1
- package/build/src/shared/backend_guard.d.ts +28 -0
- package/build/src/shared/backend_guard.d.ts.map +1 -1
- package/build/src/shared/backend_guard.js +52 -0
- package/build/src/shared/backend_guard.js.map +1 -1
- package/build/src/shared/transaction_guard.d.ts +50 -0
- package/build/src/shared/transaction_guard.d.ts.map +1 -0
- package/build/src/shared/transaction_guard.js +60 -0
- package/build/src/shared/transaction_guard.js.map +1 -0
- package/build/src/testing/contract.d.ts +55 -4
- package/build/src/testing/contract.d.ts.map +1 -1
- package/build/src/testing/contract.js +240 -8
- package/build/src/testing/contract.js.map +1 -1
- package/build/src/testing/main.d.ts +4 -4
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +2 -2
- package/build/src/testing/main.js.map +1 -1
- package/build/src/testing/relations_contract.d.ts +23 -1
- package/build/src/testing/relations_contract.d.ts.map +1 -1
- package/build/src/testing/relations_contract.js +603 -19
- package/build/src/testing/relations_contract.js.map +1 -1
- package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -1
- package/build/src/testing/relations_reconcile_contract.js +49 -1
- package/build/src/testing/relations_reconcile_contract.js.map +1 -1
- package/build/src/traits/has_uuid.d.ts +2 -2
- package/build/src/traits/has_uuid.d.ts.map +1 -1
- package/build/src/types.d.ts +284 -16
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js +4 -0
- package/build/src/types.js.map +1 -1
- package/build/stubs/config/authorization.stub +45 -1
- package/build/stubs/migration.stub +20 -10
- package/package.json +1 -1
|
@@ -21,18 +21,154 @@
|
|
|
21
21
|
* Pureza (regla 2): solo depende del puerto, los errores, la gramática
|
|
22
22
|
* compartida y `defineRelationsConfig`. Nada de `manager`/`drivers/*`.
|
|
23
23
|
*/
|
|
24
|
-
import { ActorRequiredError,
|
|
25
|
-
import { assertScope, assertSubject, assertRelationId } from '../identity.js';
|
|
24
|
+
import { ActorRequiredError, AuthorizationBackendTimeoutError, AuthorizationConfigError, UnsupportedOperationError, isPartialWrite, } from '../errors.js';
|
|
25
|
+
import { assertScope, assertSubject, assertRelationId, assertExpiresAt } from '../identity.js';
|
|
26
|
+
import { isClock, systemClock } from '../clock.js';
|
|
27
|
+
import { assertNotFrozenRow } from '../freeze.js';
|
|
26
28
|
import { isRelUserset } from '../types.js';
|
|
29
|
+
import { assertRelationDeclared, assertObjectTypeDeclared } from './define_relations_config.js';
|
|
27
30
|
export class RelationsManager {
|
|
28
31
|
#driver;
|
|
29
32
|
#config;
|
|
30
33
|
#options;
|
|
31
34
|
constructor(driver, config, options = {}) {
|
|
35
|
+
if (options.clock !== undefined) {
|
|
36
|
+
if (!isClock(options.clock)) {
|
|
37
|
+
throw new AuthorizationConfigError(`RelationsManager: clock debe ser una función () => Date (llegó ${typeof options.clock})`);
|
|
38
|
+
}
|
|
39
|
+
if (typeof driver.withClock !== 'function') {
|
|
40
|
+
throw new AuthorizationConfigError(`RelationsManager: el driver de relaciones no implementa withClock(now) y la config declara clock: ` +
|
|
41
|
+
`sin él la caducidad de las relaciones se decidiría con otro reloj que el declarado.`);
|
|
42
|
+
}
|
|
43
|
+
driver = driver.withClock(options.clock);
|
|
44
|
+
}
|
|
45
|
+
if (options.requireTransactionalWrites === true && driver.capabilities?.transactionalWrites !== true) {
|
|
46
|
+
throw new AuthorizationConfigError(`requireTransactionalWrites está en true y el driver de relaciones '${options.driverName ?? 'relations'}' ` +
|
|
47
|
+
`declara transactionalWrites: ${driver.capabilities ? String(driver.capabilities.transactionalWrites) : 'nada (sin capabilities)'}: ` +
|
|
48
|
+
`no puede inscribir relate/unrelate/purge* en la transacción del consumidor («los dos o ninguno»), así que ` +
|
|
49
|
+
`el RelationsManager no se construye. Usa un driver que la declare (database) o quita el flag ` +
|
|
50
|
+
`(relations.requireTransactionalWrites, o el del raíz).`);
|
|
51
|
+
}
|
|
32
52
|
this.#driver = driver;
|
|
33
53
|
this.#config = config;
|
|
34
54
|
this.#options = options;
|
|
35
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* **Puerta 1 de `{ transaction }`** (L-2, siempre activa): una escritura con
|
|
58
|
+
* `{ transaction }` a un driver que no declara `transactionalWrites: true`
|
|
59
|
+
* es 500 `E_AUTHZ_UNSUPPORTED` nombrando driver y operación, ANTES de la
|
|
60
|
+
* barrera, de F-05 y del driver (cero llamadas). Encolar ≠ escribir: aquí
|
|
61
|
+
* la transacción ESCRIBE la tupla dentro de ella, no hay outbox.
|
|
62
|
+
*/
|
|
63
|
+
#assertTransactional(options, operation) {
|
|
64
|
+
if (options?.transaction === undefined || options.transaction === null)
|
|
65
|
+
return;
|
|
66
|
+
if (this.#driver.capabilities?.transactionalWrites === true)
|
|
67
|
+
return;
|
|
68
|
+
throw UnsupportedOperationError.transactional(`relations.${operation}`, this.#options.driverName ?? 'relations', 'relations');
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* La marca del evento de una escritura inscrita en la transacción del
|
|
72
|
+
* llamante (2.4.0-alpha.3 · B, paridad literal con `#transactional` de
|
|
73
|
+
* roles, L-3): `onRelationWrite` se dispara cuando el DRIVER vuelve, y en
|
|
74
|
+
* ese momento la tupla existe solo dentro de esa transacción — es un hecho
|
|
75
|
+
* si y solo si el llamante confirma, cosa que el paquete nunca ve. Quien
|
|
76
|
+
* audita lo necesita para no registrar como firme lo que un rollback
|
|
77
|
+
* deshace (`trx.after('commit')`). `undefined`/`null` cuentan como SIN
|
|
78
|
+
* transacción (lo mismo que `#assertTransactional`); sin ella la marca está
|
|
79
|
+
* AUSENTE, nunca `false`.
|
|
80
|
+
*/
|
|
81
|
+
#transactional(options) {
|
|
82
|
+
return options?.transaction === undefined || options.transaction === null ? {} : { transactional: true };
|
|
83
|
+
}
|
|
84
|
+
/** `{ actor }` listo para fundir en el evento, o `{}`: el evento no inventa autores (como `#writeOptions` de roles). */
|
|
85
|
+
#actorOf(options) {
|
|
86
|
+
return options?.actor ? { actor: options.actor } : {};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* **Invariante 13 en relaciones** (2.4.0-alpha.3 · C; el MISMO `#write` de
|
|
90
|
+
* roles, `manager.ts:3257`): una escritura que vence el deadline (503
|
|
91
|
+
* `E_AUTHZ_BACKEND_TIMEOUT`) es INDETERMINADA — la sentencia/el `Write`
|
|
92
|
+
* puede aterrizar después de que el llamante reciba el error—. Antes de
|
|
93
|
+
* propagar se notifica el mismo evento con `indeterminate: true`, para que
|
|
94
|
+
* quien audita registre «puede haber ocurrido» en vez de nada. Cualquier
|
|
95
|
+
* otro fallo (422, `assertWrite`, freeze, conexión rechazada) significa que
|
|
96
|
+
* la escritura no ocurrió y se propaga SIN evento. Con `{ transaction }` el
|
|
97
|
+
* evento lleva además `transactional: true` (el rollback del llamante
|
|
98
|
+
* determina el resultado, pero es suyo y el paquete no lo ve). Envuelve las
|
|
99
|
+
* CUATRO escrituras.
|
|
100
|
+
*
|
|
101
|
+
* **Y una escritura PARCIAL también es indeterminada** (cierre del 🟡 6 del
|
|
102
|
+
* auditor de alpha.3): la purga de `openfga` es multi-request (ortografías
|
|
103
|
+
* × tipos, cada una `Read`+`deleteTuples`+`Read`), así que un 503 que NO es
|
|
104
|
+
* timeout —o el 500 `E_AUTHZ_PURGE_INCOMPLETE`— puede llegar DESPUÉS de haber
|
|
105
|
+
* borrado parte. Ahí «esa escritura no ocurrió» sería falso; el driver marca
|
|
106
|
+
* el error con `markPartialWrite` (`src/errors.ts`) y aquí se notifica
|
|
107
|
+
* `indeterminate: true` igual que con el deadline. La frase «no ocurrió y no
|
|
108
|
+
* hay evento» queda para los fallos ANTES de la primera sentencia/`Write`.
|
|
109
|
+
*/
|
|
110
|
+
async #write(event, fn) {
|
|
111
|
+
try {
|
|
112
|
+
return await fn();
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
if (error instanceof AuthorizationBackendTimeoutError || isPartialWrite(error)) {
|
|
116
|
+
await this.#notify({ ...event, indeterminate: true });
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* **El evento es una COPIA, no un alias** (⚪ 8 del auditor de alpha.3): el
|
|
123
|
+
* sink lo guarda y el llamante (o el propio sink, ahora que se `await`ea)
|
|
124
|
+
* puede mutar después `object.id`, `partition.uuid` o el `actor`. Copia por
|
|
125
|
+
* nivel de identidad (spread: el `actor` conserva los campos de más que
|
|
126
|
+
* traiga, como en roles — se documenta, no se poda); `expiresAt` es un
|
|
127
|
+
* `Date` inmutable por convención y se copia como instante.
|
|
128
|
+
*/
|
|
129
|
+
#copyEvent(event) {
|
|
130
|
+
const copy = { ...event, partition: { ...event.partition } };
|
|
131
|
+
if (event.subject !== undefined) {
|
|
132
|
+
copy.subject = isRelUserset(event.subject)
|
|
133
|
+
? { ...event.subject, object: { ...event.subject.object } }
|
|
134
|
+
: { ...event.subject };
|
|
135
|
+
}
|
|
136
|
+
if (event.object !== undefined)
|
|
137
|
+
copy.object = { ...event.object };
|
|
138
|
+
if (event.actor !== undefined)
|
|
139
|
+
copy.actor = { ...event.actor };
|
|
140
|
+
if (event.expiresAt instanceof Date)
|
|
141
|
+
copy.expiresAt = new Date(event.expiresAt.getTime());
|
|
142
|
+
return copy;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Notifica al consumidor (2.4.0-alpha.3 · D1/D2, hallazgo H1; el MISMO
|
|
146
|
+
* `#notify` de roles, `manager.ts:3276`). El hook es un side-effect
|
|
147
|
+
* (auditar, emitir un evento): cuando falla, la escritura YA está aplicada,
|
|
148
|
+
* así que propagar su error le daría al llamante un fallo por una operación
|
|
149
|
+
* que sí ocurrió — y le invitaría a reintentar algo ya hecho. Se ESPERA (un
|
|
150
|
+
* hook `async` que rechaza ya no es un unhandled rejection), se registra y
|
|
151
|
+
* se sigue. Hasta alpha.3 se llamaba sin `await` ni `try/catch`.
|
|
152
|
+
*/
|
|
153
|
+
async #notify(event) {
|
|
154
|
+
try {
|
|
155
|
+
await this.#options.onRelationWrite?.(event);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
await this.#logHookFailure(event, error);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async #logHookFailure(event, error) {
|
|
162
|
+
const context = `authz: el hook onRelationWrite falló tras '${event.operation}' (la escritura sí se aplicó)`;
|
|
163
|
+
try {
|
|
164
|
+
const { default: logger } = await import('@adonisjs/core/services/logger');
|
|
165
|
+
logger.error({ err: error, event }, context);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Fuera de una app booteada (tests, scripts sueltos) no hay logger.
|
|
169
|
+
console.error(context, error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
36
172
|
/** El driver crudo — salida documentada de las barreras (plataforma y tests). */
|
|
37
173
|
driver() {
|
|
38
174
|
return this.#driver;
|
|
@@ -41,21 +177,29 @@ export class RelationsManager {
|
|
|
41
177
|
* **F-05**: rechaza un tipo/relación no declarado ANTES de tocar el driver.
|
|
42
178
|
* La gramática de identidad no basta: `role_binding`/`assignee` son
|
|
43
179
|
* gramaticalmente válidos y en el store compartido componen el id de un
|
|
44
|
-
* binding real.
|
|
180
|
+
* binding real. Es la MISMA función que aplican los dos drivers (L-0,
|
|
181
|
+
* `assertRelationDeclared`): el manager corta primero; el driver es la red
|
|
182
|
+
* para quien entra por `manager.driver()` o por `reconcileRelations`.
|
|
183
|
+
*
|
|
184
|
+
* **En las OCHO operaciones** (2.4.0-alpha.3, 🔴 1 / 🟠 2 del auditor;
|
|
185
|
+
* cierre-2 · 🟡 3 `membersOf`): hasta alpha.3 solo `relate`/`unrelate`
|
|
186
|
+
* pasaban por aquí, y `purgeObject({ type: 'role_binding', id: R }, S)`
|
|
187
|
+
* componía en el driver `openfga` el id EXACTO del binding real y lo
|
|
188
|
+
* borraba con demostración de cero (`authorize` de `true` a `false`), con
|
|
189
|
+
* un evento de auditoría limpio; `listSubjects('assignee', role_binding)`
|
|
190
|
+
* enumeraba sus asignados. **Dos funciones, no un opcional** (cierre-2,
|
|
191
|
+
* 🟠 1: la `relation?` opcional apagó F-05 en `relate`/`unrelate` sin
|
|
192
|
+
* relación): `#assertDeclared` es ESTRICTA —la relación es obligatoria— y
|
|
193
|
+
* la usan `relate`/`unrelate`/`check`/`listObjects`/`listSubjects`/
|
|
194
|
+
* `membersOf` y el userset del sujeto; `#assertTypeDeclared` (solo el tipo)
|
|
195
|
+
* la usa `purgeObject`. `purgeSubject` no nombra objeto: su F-05 es la del
|
|
196
|
+
* userset (`#assertSubject`).
|
|
45
197
|
*/
|
|
46
198
|
#assertDeclared(object, relation) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
throw new RelationTypeUnknownError(`El tipo de objeto '${object.type}' no está declarado en defineRelationsConfig (F-05): ` +
|
|
52
|
-
`relate/unrelate solo aceptan tipos declarados. En el store compartido un tipo no declarado ` +
|
|
53
|
-
`podría componer el id de un 'role_binding' real y escalar a roles.authorize.`);
|
|
54
|
-
}
|
|
55
|
-
if (!this.#config.isDeclared(object.type, relation)) {
|
|
56
|
-
throw new RelationUnknownError(`La relación '${relation}' no está declarada para el tipo '${object.type}' en ` +
|
|
57
|
-
`defineRelationsConfig (F-05).`);
|
|
58
|
-
}
|
|
199
|
+
assertRelationDeclared(this.#config, object, relation);
|
|
200
|
+
}
|
|
201
|
+
#assertTypeDeclared(object) {
|
|
202
|
+
assertObjectTypeDeclared(this.#config, object);
|
|
59
203
|
}
|
|
60
204
|
/**
|
|
61
205
|
* **R-16**: el `object.id` con la gramática estricta de relaciones ANTES del
|
|
@@ -68,55 +212,176 @@ export class RelationsManager {
|
|
|
68
212
|
#assertObjectId(object) {
|
|
69
213
|
assertRelationId(`el id del objeto '${object?.type}'`, object?.id);
|
|
70
214
|
}
|
|
71
|
-
|
|
215
|
+
/**
|
|
216
|
+
* El `actor` de una escritura (2.4.0-alpha.3 · D4, hallazgo H3; paridad con
|
|
217
|
+
* `#writeOptions` de roles, `manager.ts:1512`): **validar-si-viene y después
|
|
218
|
+
* exigir-si-falta**. Hasta alpha.3 solo se comprobaba la PRESENCIA: un
|
|
219
|
+
* `actor: { uuid: 'A#B' }` viajaba al evento (envenena el rastro) y un
|
|
220
|
+
* `actor: {}` truthy satisfacía `requireActor`. Ahora un actor mal formado
|
|
221
|
+
* es 422 `E_AUTHZ_INVALID_IDENTITY` ANTES del driver, en las CUATRO
|
|
222
|
+
* escrituras (purgas incluidas, D-3).
|
|
223
|
+
*/
|
|
224
|
+
#assertActor(options, operation) {
|
|
225
|
+
if (options?.actor !== undefined)
|
|
226
|
+
assertSubject(options.actor);
|
|
72
227
|
if (this.#options.requireActor && !options?.actor) {
|
|
73
|
-
throw new ActorRequiredError(`
|
|
228
|
+
throw new ActorRequiredError(`relations.${operation}: escritura de relación sin 'actor' y la config exige uno (requireActor).`);
|
|
74
229
|
}
|
|
75
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* **R-13 con dientes** (2.4.0-alpha.3 · D3, hallazgo H2; cierre 🟠 3 / 🟡 4
|
|
233
|
+
* del auditor): `assertWrite` es síncrono y puro, y **no devuelve
|
|
234
|
+
* veredictos: lanza o no lanza**. TODO retorno distinto de `undefined` es
|
|
235
|
+
* 500 `E_AUTHZ_CONFIG` antes de tocar el driver — una promesa (H2: la
|
|
236
|
+
* promesa se descarta con el rechazo quitado para que no salga como
|
|
237
|
+
* unhandled rejection), una FUNCIÓN con `.then` (esquivaba la guarda
|
|
238
|
+
* `typeof 'object'`), un `false` (compila bajo `--strict` y hasta el cierre
|
|
239
|
+
* la escritura ENTRABA: fail-open) y también un `true` (el mismo error de
|
|
240
|
+
* modelo). Un `assertWrite` que LANZA propaga tal cual (es su forma de
|
|
241
|
+
* rechazar). La policy con actor/BD/await va en el servicio del consumidor.
|
|
242
|
+
*/
|
|
243
|
+
#assertWrite(ref, operation) {
|
|
244
|
+
const result = this.#options.assertWrite?.(ref);
|
|
245
|
+
if (result === undefined)
|
|
246
|
+
return;
|
|
247
|
+
if (result !== null && typeof result.then === 'function') {
|
|
248
|
+
Promise.resolve(result).then(undefined, () => { });
|
|
249
|
+
}
|
|
250
|
+
throw AuthorizationConfigError.assertWriteReturned(`relations.${operation}`, result);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* **La barrera del freeze, la MISMA que la de roles** (L-1 · J1, juez del
|
|
254
|
+
* panel `{trx}`): hasta L-1 no había una sola referencia al freeze en
|
|
255
|
+
* `relations/`, así que durante un cutover las escrituras de roles recibían
|
|
256
|
+
* 503 y las de relaciones ENTRABAN, y `authz:relations:reconcile`
|
|
257
|
+
* certificaba un estado que podía cambiar debajo. Es la fila `id = 2` de
|
|
258
|
+
* `authz_catalog_version` leída por la conexión del motor (`assertNotFrozenRow`,
|
|
259
|
+
* `src/freeze.ts` — raíz de `src/`, así que la regla 2 de pureza se cumple),
|
|
260
|
+
* delante de las CUATRO escrituras y antes de validar nada: 503
|
|
261
|
+
* `E_AUTHZ_FROZEN` reintentable. Las lecturas no pasan por aquí.
|
|
262
|
+
* `manager.driver()` sigue siendo la salida documentada.
|
|
263
|
+
*/
|
|
264
|
+
#assertNotFrozen(operation) {
|
|
265
|
+
return assertNotFrozenRow(`relations.${operation}`, {
|
|
266
|
+
driver: 'relations',
|
|
267
|
+
nowMs: (this.#options.clock ?? systemClock)().getTime(),
|
|
268
|
+
timeoutMs: this.#options.freezeTimeoutMs,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
76
271
|
async relate(subject, relation, object, partition, options) {
|
|
272
|
+
this.#assertTransactional(options, 'relate');
|
|
273
|
+
await this.#assertNotFrozen('relate');
|
|
77
274
|
this.#assertDeclared(object, relation);
|
|
78
275
|
this.#assertObjectId(object);
|
|
79
|
-
this.#assertActor(options);
|
|
276
|
+
this.#assertActor(options, 'relate');
|
|
80
277
|
assertScope(partition);
|
|
81
278
|
this.#assertSubject(subject, partition);
|
|
279
|
+
// R-15: `expiresAt` en sus tres estados legales (omitido / null / Date
|
|
280
|
+
// válida); cualquier otra cosa es 422 ANTES del driver (invariante 5).
|
|
281
|
+
assertExpiresAt(options?.expiresAt);
|
|
82
282
|
const ref = { operation: 'relate', subject, relation, object, partition };
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this.#
|
|
283
|
+
if (options && 'expiresAt' in options)
|
|
284
|
+
ref.expiresAt = options.expiresAt;
|
|
285
|
+
this.#assertWrite(ref, 'relate');
|
|
286
|
+
const event = this.#copyEvent({ ...ref, ...this.#actorOf(options), ...this.#transactional(options) });
|
|
287
|
+
await this.#write(event, () => this.#driver.relate(subject, relation, object, partition, options));
|
|
288
|
+
await this.#notify(event);
|
|
86
289
|
}
|
|
87
290
|
async unrelate(subject, relation, object, partition, options) {
|
|
291
|
+
this.#assertTransactional(options, 'unrelate');
|
|
292
|
+
await this.#assertNotFrozen('unrelate');
|
|
88
293
|
this.#assertDeclared(object, relation);
|
|
89
294
|
this.#assertObjectId(object);
|
|
90
|
-
this.#assertActor(options);
|
|
295
|
+
this.#assertActor(options, 'unrelate');
|
|
91
296
|
assertScope(partition);
|
|
92
297
|
this.#assertSubject(subject, partition);
|
|
93
298
|
const ref = { operation: 'unrelate', subject, relation, object, partition };
|
|
94
|
-
this.#
|
|
95
|
-
|
|
96
|
-
this.#
|
|
299
|
+
this.#assertWrite(ref, 'unrelate');
|
|
300
|
+
const event = this.#copyEvent({ ...ref, ...this.#actorOf(options), ...this.#transactional(options) });
|
|
301
|
+
await this.#write(event, () => this.#driver.unrelate(subject, relation, object, partition, options));
|
|
302
|
+
await this.#notify(event);
|
|
97
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* **Las lecturas también pasan por F-05** (2.4.0-alpha.3, 🟠 2 del auditor):
|
|
306
|
+
* el `objectId` lleva la partición, así que `listSubjects('assignee',
|
|
307
|
+
* { type: 'role_binding', id: R }, S)` era la lista de asignados de un rol
|
|
308
|
+
* en un scope, por el puerto de relaciones, sin catálogo, sin `within`, sin
|
|
309
|
+
* `requireActor` (las lecturas no lo tienen) y sin visibilidad de rol
|
|
310
|
+
* (invariante 18). `check`/`listSubjects` validan el par (tipo, relación);
|
|
311
|
+
* `listObjects` el tipo; el userset del sujeto, su par. PRIMERA línea,
|
|
312
|
+
* cero llamadas al driver; el driver re-valida (defensa en profundidad).
|
|
313
|
+
*/
|
|
98
314
|
async check(subject, relation, object, partition) {
|
|
315
|
+
this.#assertDeclared(object, relation);
|
|
99
316
|
assertScope(partition);
|
|
100
317
|
this.#assertObjectId(object);
|
|
318
|
+
this.#assertSubject(subject, partition);
|
|
101
319
|
return this.#driver.check(subject, relation, object, partition);
|
|
102
320
|
}
|
|
103
321
|
async listObjects(subject, relation, objectType, partition, page) {
|
|
322
|
+
this.#assertDeclared({ type: objectType }, relation);
|
|
104
323
|
assertScope(partition);
|
|
324
|
+
this.#assertSubject(subject, partition);
|
|
105
325
|
return this.#driver.listObjects(subject, relation, objectType, partition, page);
|
|
106
326
|
}
|
|
107
327
|
async listSubjects(relation, object, partition, page) {
|
|
328
|
+
this.#assertDeclared(object, relation);
|
|
108
329
|
assertScope(partition);
|
|
109
330
|
this.#assertObjectId(object);
|
|
110
331
|
return this.#driver.listSubjects(relation, object, partition, page);
|
|
111
332
|
}
|
|
112
|
-
|
|
333
|
+
/**
|
|
334
|
+
* **Las purgas notifican** (2.4.0-alpha.3 · E, hallazgo #4; D-1/D-3): UN
|
|
335
|
+
* evento por llamada —aunque el driver barra las dos ortografías del uuid
|
|
336
|
+
* de partición por dentro: el manager no canoniza particiones, y diverge a
|
|
337
|
+
* propósito de `scopes.detached`, que emite uno por ortografía porque ahí
|
|
338
|
+
* canoniza el MANAGER—, con el objetivo y la partición TAL COMO la pasó el
|
|
339
|
+
* llamante, sin `relation` y SIN conteo (el puerto devuelve `void`; un
|
|
340
|
+
* conteo lo rompería para terceros y un rollback lo desmentiría). Se
|
|
341
|
+
* notifica también cuando no borra nada: el hecho auditable es «alguien
|
|
342
|
+
* pidió borrar las llaves de X». Sujeta a `requireActor` (D-3, breaking) y
|
|
343
|
+
* al actor validado; NO pasa por `assertWrite` (su `RelationRef.operation`
|
|
344
|
+
* es `'relate' | 'unrelate'`, tipo publicado de R-13). Mismo `#write`
|
|
345
|
+
* (invariante 13) y mismo `#notify` que `relate`/`unrelate`.
|
|
346
|
+
*
|
|
347
|
+
* **Y pasan por F-05** (cierre del 🔴 1 del auditor de alpha.3): el mismo
|
|
348
|
+
* orden que `relate` —puerta 1, freeze, F-05 (solo el TIPO: una purga no
|
|
349
|
+
* nombra relación), id, actor, scope—. `purgeSubject` valida su sujeto como
|
|
350
|
+
* `relate` (`#assertSubject`, ⚪ 7: un userset no declarado o un holder mal
|
|
351
|
+
* formado es 422 ANTES del driver y no llega al evento).
|
|
352
|
+
*/
|
|
353
|
+
async purgeObject(object, partition, options) {
|
|
354
|
+
this.#assertTransactional(options, 'purgeObject');
|
|
355
|
+
await this.#assertNotFrozen('purgeObject');
|
|
356
|
+
this.#assertTypeDeclared(object);
|
|
113
357
|
assertScope(partition);
|
|
114
358
|
this.#assertObjectId(object);
|
|
115
|
-
|
|
359
|
+
this.#assertActor(options, 'purgeObject');
|
|
360
|
+
const event = this.#copyEvent({
|
|
361
|
+
operation: 'purgeObject',
|
|
362
|
+
object,
|
|
363
|
+
partition,
|
|
364
|
+
...this.#actorOf(options),
|
|
365
|
+
...this.#transactional(options),
|
|
366
|
+
});
|
|
367
|
+
await this.#write(event, () => this.#driver.purgeObject(object, partition, options));
|
|
368
|
+
await this.#notify(event);
|
|
116
369
|
}
|
|
117
|
-
async purgeSubject(subject, partition) {
|
|
370
|
+
async purgeSubject(subject, partition, options) {
|
|
371
|
+
this.#assertTransactional(options, 'purgeSubject');
|
|
372
|
+
await this.#assertNotFrozen('purgeSubject');
|
|
118
373
|
assertScope(partition);
|
|
119
|
-
|
|
374
|
+
this.#assertSubject(subject, partition);
|
|
375
|
+
this.#assertActor(options, 'purgeSubject');
|
|
376
|
+
const event = this.#copyEvent({
|
|
377
|
+
operation: 'purgeSubject',
|
|
378
|
+
subject,
|
|
379
|
+
partition,
|
|
380
|
+
...this.#actorOf(options),
|
|
381
|
+
...this.#transactional(options),
|
|
382
|
+
});
|
|
383
|
+
await this.#write(event, () => this.#driver.purgeSubject(subject, partition, options));
|
|
384
|
+
await this.#notify(event);
|
|
120
385
|
}
|
|
121
386
|
/**
|
|
122
387
|
* Membresía TRANSITIVA de un grupo (a través de usersets anidados) —
|
|
@@ -126,7 +391,14 @@ export class RelationsManager {
|
|
|
126
391
|
* trunca), jamás un `skip`.
|
|
127
392
|
*/
|
|
128
393
|
async membersOf(object, relation, partition, page) {
|
|
394
|
+
// Cierre-2 · 🟡 3: `membersOf` toma `(object, relation)` —la forma exacta
|
|
395
|
+
// que F-05 guarda— y era la octava operación fuera de «las siete»; un
|
|
396
|
+
// driver de terceros con `membersOfNative: true` sobre un store compartido
|
|
397
|
+
// reabría la fuga de `listSubjects`. F-05 (par, ESTRICTA) ANTES de la
|
|
398
|
+
// capacidad: 422 con cero llamadas, también donde `membersOf` sería 500.
|
|
399
|
+
this.#assertDeclared(object, relation);
|
|
129
400
|
assertScope(partition);
|
|
401
|
+
this.#assertObjectId(object);
|
|
130
402
|
if (!this.#driver.membersOf || !this.#driver.capabilities?.membersOfNative) {
|
|
131
403
|
throw new UnsupportedOperationError('membersOf', 'la membresía transitiva de un grupo', 'relations', `Solo el driver 'database' la resuelve (CTE recursiva); en 'openfga' la transitiva sería ` +
|
|
132
404
|
`'ListUsers', que trunca. Usa 'listSubjects' para los hechos directos.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/relations/manager.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/relations/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Clock } from '../clock.js';
|
|
1
2
|
import type { RelationsDriver, ScopeRef } from '../types.js';
|
|
2
3
|
import type { RelationsConfig } from './define_relations_config.js';
|
|
3
4
|
export interface RelationsReconcileOptions {
|
|
@@ -21,11 +22,22 @@ export interface RelationsReconcileOptions {
|
|
|
21
22
|
*/
|
|
22
23
|
allowMassDelete?: boolean;
|
|
23
24
|
/**
|
|
24
|
-
* La config del DESTINO
|
|
25
|
-
*
|
|
26
|
-
*
|
|
25
|
+
* La config del DESTINO. Dos usos: vigilar la deriva del modelo fusionado
|
|
26
|
+
* (un tipo del origen que el destino NO declara se reporta en `modelDrift`)
|
|
27
|
+
* y **embudar F-05 ANTES del driver** (L-0): la tupla cuyo tipo o relación
|
|
28
|
+
* el destino no declara se descarta aquí y se cuenta en
|
|
29
|
+
* `skipped.undeclared`, de modo que `--dry-run` y la pasada real dan los
|
|
30
|
+
* MISMOS números. Sin ella, la embuda el 422 del propio driver del destino
|
|
31
|
+
* (la misma función, `assertRelationDeclared`) y se cuenta igual — pero
|
|
32
|
+
* `--dry-run` no puede anticiparla (la reporta como `written`).
|
|
27
33
|
*/
|
|
28
34
|
toConfig?: RelationsConfig;
|
|
35
|
+
/**
|
|
36
|
+
* El reloj que decide qué tupla del ORIGEN está CADUCADA (R-15): una caducada
|
|
37
|
+
* no se migra —se cuenta en `skipped.expired`— y no respalda nada en el
|
|
38
|
+
* destino. Default `systemClock`; inyectable para el juez.
|
|
39
|
+
*/
|
|
40
|
+
now?: Clock;
|
|
29
41
|
}
|
|
30
42
|
export interface RelationsReconcileReport {
|
|
31
43
|
/** ¿Fue `--dry-run` (sin escrituras)? */
|
|
@@ -34,7 +46,13 @@ export interface RelationsReconcileReport {
|
|
|
34
46
|
written: number;
|
|
35
47
|
/** Tuplas que sobraban en el destino y se borraron (solo con `prune`; o que se borrarían). */
|
|
36
48
|
deleted: number;
|
|
37
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Tuplas que estaban en el destino con OTRA caducidad y se reescribieron con
|
|
51
|
+
* la del origen (R-15; delete+write en ambos drivers, nunca un `Ignore` a
|
|
52
|
+
* ciegas que se quedara la caducidad vieja — la lección S7 de la 3b).
|
|
53
|
+
*/
|
|
54
|
+
updated: number;
|
|
55
|
+
/** Tuplas que ya estaban exactamente igual (misma clave y misma caducidad). */
|
|
38
56
|
unchanged: number;
|
|
39
57
|
/**
|
|
40
58
|
* Tuplas del destino que el origen ya no respalda y que NO se borraron por
|
|
@@ -52,6 +70,37 @@ export interface RelationsReconcileReport {
|
|
|
52
70
|
* (salvo `allowMassDelete`); en `--dry-run` NO lanza y esto lo marca.
|
|
53
71
|
*/
|
|
54
72
|
massDelete: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Lo que el origen ENUMERÓ y no se migró, con su motivo:
|
|
75
|
+
* - `expired` (R-15) = tuplas caducadas al instante de la pasada. Es la
|
|
76
|
+
* pérdida DECLARADA de la migración (como `expired` en `authz:reconcile`
|
|
77
|
+
* de roles, 3b-8 · B2): se cuenta, no clava el exit 1. Un origen que las
|
|
78
|
+
* filtrara antes de enumerarlas las haría desaparecer sin rastro; por eso
|
|
79
|
+
* tienen que LLEGAR.
|
|
80
|
+
* - `undeclared` (L-0) = tuplas VIVAS cuyo `object.type` o `relation` el
|
|
81
|
+
* DESTINO no declara (F-05): no se escriben —hasta L-0 `modelDrift` las
|
|
82
|
+
* reportaba y `to.relate` las escribía igual, por el driver— y se cuentan
|
|
83
|
+
* aquí. Es una relación viva que no llegó, así que SÍ es deriva
|
|
84
|
+
* (exit ≠ 0 en el comando): declárala en el destino y repite la pasada.
|
|
85
|
+
*/
|
|
86
|
+
skipped: {
|
|
87
|
+
expired: number;
|
|
88
|
+
undeclared: number;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* **La ventana durable bajo la que corrió la pasada que ESCRIBE** (L-1 ·
|
|
92
|
+
* J1; paridad con `report.frozen` de `authz:reconcile` de roles). La pone
|
|
93
|
+
* `runRelationsReconcile` (el comando), no esta función —que no ve al
|
|
94
|
+
* manager de roles—; ausente en `--dry-run` (el verificador no congela) y
|
|
95
|
+
* cuando se llama a `reconcileRelations` a pelo. `lapsed: true` = el lease
|
|
96
|
+
* se perdió a mitad ⇒ la pasada NO se certifica (exit ≠ 0).
|
|
97
|
+
*/
|
|
98
|
+
frozen?: {
|
|
99
|
+
durable: true;
|
|
100
|
+
lapsed: boolean;
|
|
101
|
+
leaseMs: number | null;
|
|
102
|
+
fence: number;
|
|
103
|
+
};
|
|
55
104
|
}
|
|
56
105
|
/**
|
|
57
106
|
* Migra las tuplas de relación de `from` a `to` en `partition`. Idempotente
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../../src/relations/reconcile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../../src/relations/reconcile.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAGxC,OAAO,KAAK,EAA6B,eAAe,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAkBnE,MAAM,WAAW,yBAAyB;IACxC,oFAAoF;IACpF,IAAI,EAAE,eAAe,CAAA;IACrB,mGAAmG;IACnG,EAAE,EAAE,eAAe,CAAA;IACnB,uFAAuF;IACvF,SAAS,EAAE,QAAQ,CAAA;IACnB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,qFAAqF;IACrF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAA;IAC1B;;;;OAIG;IACH,GAAG,CAAC,EAAE,KAAK,CAAA;CACZ;AAED,MAAM,WAAW,wBAAwB;IACvC,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAA;IACf,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAA;IACf,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAA;IACnB;;;;;;;;;;;;OAYG;IACH,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CACnF;AA8BD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CA8G9G"}
|