@jantstack/adonis-authz 1.1.0 → 2.4.0-alpha.1
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/LICENSE +1 -1
- package/README.md +837 -51
- package/build/commands/authz_catalog_diff.d.ts +28 -0
- package/build/commands/authz_catalog_diff.d.ts.map +1 -0
- package/build/commands/authz_catalog_diff.js +67 -0
- package/build/commands/authz_catalog_diff.js.map +1 -0
- package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
- package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
- package/build/commands/authz_catalog_prune_orphans.js +136 -0
- package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
- package/build/commands/authz_catalog_sync.d.ts +37 -0
- package/build/commands/authz_catalog_sync.d.ts.map +1 -0
- package/build/commands/authz_catalog_sync.js +81 -0
- package/build/commands/authz_catalog_sync.js.map +1 -0
- package/build/commands/authz_freeze.d.ts +44 -0
- package/build/commands/authz_freeze.d.ts.map +1 -0
- package/build/commands/authz_freeze.js +95 -0
- package/build/commands/authz_freeze.js.map +1 -0
- package/build/commands/authz_reconcile.d.ts +102 -0
- package/build/commands/authz_reconcile.d.ts.map +1 -0
- package/build/commands/authz_reconcile.js +294 -0
- package/build/commands/authz_reconcile.js.map +1 -0
- package/build/commands/authz_relations_reconcile.d.ts +73 -0
- package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
- package/build/commands/authz_relations_reconcile.js +225 -0
- package/build/commands/authz_relations_reconcile.js.map +1 -0
- package/build/commands/authz_scopes_relay.d.ts +47 -0
- package/build/commands/authz_scopes_relay.d.ts.map +1 -0
- package/build/commands/authz_scopes_relay.js +141 -0
- package/build/commands/authz_scopes_relay.js.map +1 -0
- package/build/commands/authz_unfreeze.d.ts +37 -0
- package/build/commands/authz_unfreeze.d.ts.map +1 -0
- package/build/commands/authz_unfreeze.js +92 -0
- package/build/commands/authz_unfreeze.js.map +1 -0
- package/build/commands/main.d.ts +8 -1
- package/build/commands/main.d.ts.map +1 -1
- package/build/commands/main.js +8 -1
- package/build/commands/main.js.map +1 -1
- package/build/commands/openfga_provision.d.ts +46 -4
- package/build/commands/openfga_provision.d.ts.map +1 -1
- package/build/commands/openfga_provision.js +91 -7
- package/build/commands/openfga_provision.js.map +1 -1
- package/build/configure.d.ts +11 -0
- package/build/configure.d.ts.map +1 -1
- package/build/configure.js +37 -1
- package/build/configure.js.map +1 -1
- package/build/index.d.ts +75 -7
- package/build/index.d.ts.map +1 -1
- package/build/index.js +67 -5
- package/build/index.js.map +1 -1
- package/build/providers/authz_provider.d.ts +26 -2
- package/build/providers/authz_provider.d.ts.map +1 -1
- package/build/providers/authz_provider.js +48 -2
- package/build/providers/authz_provider.js.map +1 -1
- package/build/services/relations.d.ts +14 -0
- package/build/services/relations.d.ts.map +1 -0
- package/build/services/relations.js +17 -0
- package/build/services/relations.js.map +1 -0
- package/build/src/catalog/catalog.d.ts +289 -0
- package/build/src/catalog/catalog.d.ts.map +1 -0
- package/build/src/catalog/catalog.js +859 -0
- package/build/src/catalog/catalog.js.map +1 -0
- package/build/src/catalog/catalog_cache.d.ts +324 -0
- package/build/src/catalog/catalog_cache.d.ts.map +1 -0
- package/build/src/catalog/catalog_cache.js +666 -0
- package/build/src/catalog/catalog_cache.js.map +1 -0
- package/build/src/clock.d.ts +24 -0
- package/build/src/clock.d.ts.map +1 -0
- package/build/src/clock.js +7 -0
- package/build/src/clock.js.map +1 -0
- package/build/src/define_config.d.ts +201 -7
- 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 +324 -15
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +1107 -128
- package/build/src/drivers/database_driver.js.map +1 -1
- package/build/src/drivers/database_relations_driver.d.ts +75 -0
- package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
- package/build/src/drivers/database_relations_driver.js +450 -0
- package/build/src/drivers/database_relations_driver.js.map +1 -0
- package/build/src/drivers/openfga_driver.d.ts +963 -55
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +2693 -372
- package/build/src/drivers/openfga_driver.js.map +1 -1
- package/build/src/drivers/openfga_facts.d.ts +369 -0
- package/build/src/drivers/openfga_facts.d.ts.map +1 -0
- package/build/src/drivers/openfga_facts.js +813 -0
- package/build/src/drivers/openfga_facts.js.map +1 -0
- package/build/src/drivers/openfga_relations_driver.d.ts +120 -0
- package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
- package/build/src/drivers/openfga_relations_driver.js +466 -0
- package/build/src/drivers/openfga_relations_driver.js.map +1 -0
- package/build/src/errors.d.ts +586 -0
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +583 -0
- package/build/src/errors.js.map +1 -1
- package/build/src/expiry.d.ts +27 -0
- package/build/src/expiry.d.ts.map +1 -0
- package/build/src/expiry.js +50 -0
- package/build/src/expiry.js.map +1 -0
- package/build/src/freeze.d.ts +120 -0
- package/build/src/freeze.d.ts.map +1 -0
- package/build/src/freeze.js +172 -0
- package/build/src/freeze.js.map +1 -0
- package/build/src/hierarchical_resolver.d.ts +56 -0
- package/build/src/hierarchical_resolver.d.ts.map +1 -0
- package/build/src/hierarchical_resolver.js +87 -0
- package/build/src/hierarchical_resolver.js.map +1 -0
- package/build/src/{middleware → http}/app_access_middleware.d.ts +8 -6
- package/build/src/http/app_access_middleware.d.ts.map +1 -0
- package/build/src/{middleware → http}/app_access_middleware.js +10 -26
- package/build/src/http/app_access_middleware.js.map +1 -0
- package/build/src/http/resource_access_middleware.d.ts +105 -0
- package/build/src/http/resource_access_middleware.d.ts.map +1 -0
- package/build/src/http/resource_access_middleware.js +81 -0
- package/build/src/http/resource_access_middleware.js.map +1 -0
- package/build/src/identity.d.ts +228 -0
- package/build/src/identity.d.ts.map +1 -0
- package/build/src/identity.js +457 -0
- package/build/src/identity.js.map +1 -0
- package/build/src/manager.d.ts +536 -7
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +2676 -23
- package/build/src/manager.js.map +1 -1
- package/build/src/memoize_ancestors.d.ts +23 -0
- package/build/src/memoize_ancestors.d.ts.map +1 -0
- package/build/src/memoize_ancestors.js +42 -0
- package/build/src/memoize_ancestors.js.map +1 -0
- package/build/src/models/authz_assignment.d.ts +11 -11
- package/build/src/models/authz_assignment.d.ts.map +1 -1
- package/build/src/models/authz_deny.d.ts +11 -11
- package/build/src/models/authz_deny.d.ts.map +1 -1
- package/build/src/models/authz_permission.d.ts +17 -11
- package/build/src/models/authz_permission.d.ts.map +1 -1
- package/build/src/models/authz_permission.js +4 -0
- package/build/src/models/authz_permission.js.map +1 -1
- package/build/src/models/authz_role.d.ts +19 -12
- package/build/src/models/authz_role.d.ts.map +1 -1
- package/build/src/models/authz_role.js +6 -1
- package/build/src/models/authz_role.js.map +1 -1
- package/build/src/models/authz_role_permission.d.ts +11 -11
- package/build/src/models/authz_role_permission.d.ts.map +1 -1
- package/build/src/openfga.d.ts +29 -0
- package/build/src/openfga.d.ts.map +1 -0
- package/build/src/openfga.js +26 -0
- package/build/src/openfga.js.map +1 -0
- package/build/src/reconcile.d.ts +37 -0
- package/build/src/reconcile.d.ts.map +1 -0
- package/build/src/reconcile.js +69 -0
- package/build/src/reconcile.js.map +1 -0
- package/build/src/relation_partition_trigger.d.ts +8 -0
- package/build/src/relation_partition_trigger.d.ts.map +1 -0
- package/build/src/relation_partition_trigger.js +85 -0
- package/build/src/relation_partition_trigger.js.map +1 -0
- package/build/src/relations/define_relations_config.d.ts +58 -0
- package/build/src/relations/define_relations_config.d.ts.map +1 -0
- package/build/src/relations/define_relations_config.js +144 -0
- package/build/src/relations/define_relations_config.js.map +1 -0
- package/build/src/relations/manager.d.ts +38 -0
- package/build/src/relations/manager.d.ts.map +1 -0
- package/build/src/relations/manager.js +156 -0
- package/build/src/relations/manager.js.map +1 -0
- package/build/src/relations/reconcile.d.ts +62 -0
- package/build/src/relations/reconcile.d.ts.map +1 -0
- package/build/src/relations/reconcile.js +138 -0
- package/build/src/relations/reconcile.js.map +1 -0
- package/build/src/relations_config_store.d.ts +22 -0
- package/build/src/relations_config_store.d.ts.map +1 -0
- package/build/src/relations_config_store.js +74 -0
- package/build/src/relations_config_store.js.map +1 -0
- package/build/src/scope_outbox.d.ts +69 -0
- package/build/src/scope_outbox.d.ts.map +1 -0
- package/build/src/scope_outbox.js +291 -0
- package/build/src/scope_outbox.js.map +1 -0
- package/build/src/shared/backend_guard.d.ts +106 -0
- package/build/src/shared/backend_guard.d.ts.map +1 -0
- package/build/src/shared/backend_guard.js +246 -0
- package/build/src/shared/backend_guard.js.map +1 -0
- package/build/src/shared/sql_expiry.d.ts +53 -0
- package/build/src/shared/sql_expiry.d.ts.map +1 -0
- package/build/src/shared/sql_expiry.js +66 -0
- package/build/src/shared/sql_expiry.js.map +1 -0
- package/build/src/sql_descendants.d.ts +97 -0
- package/build/src/sql_descendants.d.ts.map +1 -0
- package/build/src/sql_descendants.js +203 -0
- package/build/src/sql_descendants.js.map +1 -0
- package/build/src/testing/contract.d.ts +212 -7
- package/build/src/testing/contract.d.ts.map +1 -1
- package/build/src/testing/contract.js +3449 -24
- package/build/src/testing/contract.js.map +1 -1
- package/build/src/testing/main.d.ts +10 -2
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +5 -1
- package/build/src/testing/main.js.map +1 -1
- package/build/src/testing/migration_contract.d.ts +284 -0
- package/build/src/testing/migration_contract.d.ts.map +1 -0
- package/build/src/testing/migration_contract.js +586 -0
- package/build/src/testing/migration_contract.js.map +1 -0
- package/build/src/testing/relations_contract.d.ts +51 -0
- package/build/src/testing/relations_contract.d.ts.map +1 -0
- package/build/src/testing/relations_contract.js +654 -0
- package/build/src/testing/relations_contract.js.map +1 -0
- package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
- package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
- package/build/src/testing/relations_reconcile_contract.js +172 -0
- package/build/src/testing/relations_reconcile_contract.js.map +1 -0
- package/build/src/testing/scope_tree.d.ts +65 -0
- package/build/src/testing/scope_tree.d.ts.map +1 -0
- package/build/src/testing/scope_tree.js +145 -0
- package/build/src/testing/scope_tree.js.map +1 -0
- package/build/src/traits/authz_scopes.d.ts +30 -6
- package/build/src/traits/authz_scopes.d.ts.map +1 -1
- package/build/src/traits/authz_scopes.js +30 -18
- package/build/src/traits/authz_scopes.js.map +1 -1
- package/build/src/traits/has_uuid.d.ts +12 -12
- package/build/src/traits/has_uuid.d.ts.map +1 -1
- package/build/src/types.d.ts +1313 -28
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js +20 -4
- package/build/src/types.js.map +1 -1
- package/build/stubs/config/app_acl.stub +4 -2
- package/build/stubs/config/authorization.stub +168 -14
- package/build/stubs/migration.stub +183 -13
- package/build/stubs/scopes_outbox_migration.stub +57 -0
- package/package.json +14 -7
- package/build/commands/openfga_import.d.ts +0 -28
- package/build/commands/openfga_import.d.ts.map +0 -1
- package/build/commands/openfga_import.js +0 -74
- package/build/commands/openfga_import.js.map +0 -1
- package/build/src/catalog.d.ts +0 -3
- package/build/src/catalog.d.ts.map +0 -1
- package/build/src/catalog.js +0 -103
- package/build/src/catalog.js.map +0 -1
- package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
- package/build/src/middleware/app_access_middleware.js.map +0 -1
package/build/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/build/src/types.js
CHANGED
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
* suite corre contra cada driver — es el juez del contrato):
|
|
13
13
|
*
|
|
14
14
|
* 1. **Scopes jerárquicos, herencia SOLO hacia abajo.** La cadena de un scope
|
|
15
|
-
* es `[scope, ...ancestros]` (`app` es la raíz: su cadena es él
|
|
15
|
+
* es `[scope canónico, ...ancestros]` (`app` es la raíz: su cadena es él
|
|
16
|
+
* mismo); la identidad de un scope es la que devuelve el resolutor, nunca
|
|
17
|
+
* la forma con la que lo escribió el llamante (2.5-B · K1).
|
|
16
18
|
* Un grant en un scope autoriza en ese scope y en TODOS sus descendientes;
|
|
17
19
|
* nunca en hermanos ni ancestros. En T1 solo opera `app` (los ancestros de
|
|
18
|
-
* `organization`/`unit` se completan en T2/T3 vía `
|
|
20
|
+
* `organization`/`unit` se completan en T2/T3 vía `resolveChain`).
|
|
19
21
|
* 2. **Deny explícito gana.** Un deny de un permiso en cualquier scope de la
|
|
20
22
|
* cadena bloquea `authorize`, aunque un rol lo conceda (el deny también
|
|
21
23
|
* hereda hacia abajo). Quitar el deny restaura el permiso.
|
|
@@ -28,11 +30,25 @@
|
|
|
28
30
|
* holder sin asignación vigente → `false`, nunca throw en `authorize`.
|
|
29
31
|
* En cambio `grant`/`deny` con rol/permiso fuera del catálogo → throw
|
|
30
32
|
* (error de programación, no de autorización).
|
|
31
|
-
* 6. **Idempotencia de escritura.** Re-`grant` no duplica (
|
|
32
|
-
* `
|
|
33
|
+
* 6. **Idempotencia de escritura.** Re-`grant` no duplica (`expiresAt` en
|
|
34
|
+
* tres estados: omitido preserva, `null` quita, `Date` fija);
|
|
35
|
+
* re-`revoke`/re-`deny`/re-`removeDeny` son no-ops seguros.
|
|
36
|
+
* 7. **El árbol es un hecho del contrato.** Un scope que el resolutor no
|
|
37
|
+
* conoce (`null`) deniega, no lista y no admite escrituras; `purgeScope`
|
|
38
|
+
* borra los hechos del scope exacto (los del catálogo) y demuestra cero.
|
|
33
39
|
*/
|
|
34
40
|
/** Nombre reservado del scope raíz. */
|
|
35
41
|
export const APP_SCOPE_TYPE = 'app';
|
|
36
42
|
/** El scope raíz de aplicación (nivel plataforma). */
|
|
37
43
|
export const APP_SCOPE = Object.freeze({ type: 'app', uuid: null });
|
|
44
|
+
/**
|
|
45
|
+
* Cuántas tuplas/filas del destino caben en una pasada de `authz:reconcile`
|
|
46
|
+
* (3b-3b · B5). No es una garantía de memoria: es la cota DECLARADA por
|
|
47
|
+
* encima de la cual la pasada se niega en vez de intentarlo.
|
|
48
|
+
*/
|
|
49
|
+
export const DEFAULT_RECONCILE_MAX_TUPLES = 1_000_000;
|
|
50
|
+
/** Discriminador: ¿este sujeto es un userset (`group:g#member`) y no un holder? */
|
|
51
|
+
export function isRelUserset(subject) {
|
|
52
|
+
return typeof subject.object === 'object' && subject.object !== null;
|
|
53
|
+
}
|
|
38
54
|
//# sourceMappingURL=types.js.map
|
package/build/src/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAoBH,uCAAuC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAA;AAQnC,sDAAsD;AACtD,MAAM,CAAC,MAAM,SAAS,GAAa,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;AAymB7E;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,SAAS,CAAA;AAkrBrD,mFAAmF;AACnF,MAAM,UAAU,YAAY,CAAC,OAAmB;IAC9C,OAAO,OAAQ,OAAsB,CAAC,MAAM,KAAK,QAAQ,IAAK,OAAsB,CAAC,MAAM,KAAK,IAAI,CAAA;AACtG,CAAC"}
|
|
@@ -17,9 +17,11 @@ import type { CatalogSpec } from '@jantstack/adonis-authz'
|
|
|
17
17
|
* Para el ACL POR TENANT ver `config/organization_acl.ts` (migra al motor
|
|
18
18
|
* en la tanda 2).
|
|
19
19
|
*
|
|
20
|
-
* Workflow para añadir un permiso:
|
|
20
|
+
* Workflow para añadir o quitar un permiso:
|
|
21
21
|
* 1. Editar este archivo.
|
|
22
|
-
* 2. `node ace
|
|
22
|
+
* 2. `node ace authz:catalog:sync` (quitar un permiso de un rol lo retira
|
|
23
|
+
* de verdad: el sync poda los vínculos que ya no listas).
|
|
24
|
+
* 3. En CI, `node ace authz:catalog:diff` falla si la base no coincide.
|
|
23
25
|
*/
|
|
24
26
|
const appAclConfig = {
|
|
25
27
|
/**
|
|
@@ -2,31 +2,89 @@
|
|
|
2
2
|
exports({ to: app.configPath('authorization.ts') })
|
|
3
3
|
}}}
|
|
4
4
|
import env from '#start/env'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
defineConfig,
|
|
7
|
+
DatabaseAuthorizationDriver,
|
|
8
|
+
DatabaseRelationsDriver,
|
|
9
|
+
defineRelationsConfig,
|
|
10
|
+
APP_SCOPE,
|
|
11
|
+
} from '@jantstack/adonis-authz'
|
|
6
12
|
import type { AuthzWriteEvent, ScopeRef } from '@jantstack/adonis-authz'
|
|
13
|
+
import { appAclCatalog } from '#config/app_acl'
|
|
7
14
|
|
|
8
15
|
/**
|
|
9
16
|
* Holders de tu aplicación: morph name (`@MorphMap` del modelo) → tipo del
|
|
10
17
|
* modelo FGA. Solo lo usa el driver `openfga` y sus comandos.
|
|
11
18
|
*
|
|
12
19
|
* ⚠️ Cambiar este mapa cambia el authorization model: hay que re-provisionar
|
|
13
|
-
* el store (`node ace openfga:provision`) y
|
|
20
|
+
* el store (`node ace openfga:provision`) y volver a proyectar el catálogo.
|
|
14
21
|
*/
|
|
15
22
|
export const holderTypes = {
|
|
16
23
|
users: 'user',
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
27
|
+
* ReBAC genérico (relaciones a nivel de objeto: `document#viewer`,
|
|
28
|
+
* `group#member`…), OPT-IN. Declara aquí tus tipos de objeto y sus relaciones.
|
|
29
|
+
* Con la sección `relations` de abajo, el paquete cablea el `RelationsManager`
|
|
30
|
+
* como servicio (`import relations from '@jantstack/adonis-authz/services/relations'`)
|
|
31
|
+
* y —con AUTHZ_DRIVER=openfga— `node ace openfga:provision` mete estos tipos en
|
|
32
|
+
* el modelo `facts`, así que un store recién aprovisionado ya acepta tuplas de
|
|
33
|
+
* relación sin un `authz:catalog:sync` previo.
|
|
23
34
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
35
|
+
* `document` es solo un EJEMPLO: cámbialo por tus tipos (o borra este bloque y
|
|
36
|
+
* la sección `relations` si no usas ReBAC). `defineRelationsConfig` exige al
|
|
37
|
+
* menos un tipo, así que un array vacío lanza.
|
|
26
38
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
39
|
+
export const relationsConfig = defineRelationsConfig({
|
|
40
|
+
objectTypes: [
|
|
41
|
+
{
|
|
42
|
+
type: 'document',
|
|
43
|
+
relations: [
|
|
44
|
+
{ name: 'owner' },
|
|
45
|
+
{ name: 'editor', includes: ['owner'] },
|
|
46
|
+
{ name: 'viewer', includes: ['editor'] },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
holderTypes: Object.values(holderTypes),
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Jerarquía de scopes de tu dominio: la ÚNICA costura entre tu dominio y el
|
|
55
|
+
* motor. El motor solo conoce la raíz (`app`); si tienes niveles propios
|
|
56
|
+
* (organizaciones, proyectos, sedes…), devuelve aquí la CADENA CANÓNICA del
|
|
57
|
+
* scope: él mismo TAL COMO ESTÁ EN TU TABLA (la fila leída, no lo que llegó
|
|
58
|
+
* en la pregunta) y después sus ancestros del más cercano a la raíz, con
|
|
59
|
+
* `APP_SCOPE` al final; y `null` si el scope NO existe (el motor deniega y
|
|
60
|
+
* rechaza escribir sobre él). Nunca devuelvas `[scope, APP_SCOPE]` para lo
|
|
61
|
+
* que no conoces: convertiría cualquier scope inventado en descendiente de la
|
|
62
|
+
* raíz. Devolver la fila (y no el argumento) es lo que impide que un alias del
|
|
63
|
+
* uuid —mayúsculas, guiones quitados, que el tipo `uuid` de PostgreSQL o una
|
|
64
|
+
* collation `*_ci` funden con la fila real— evada un deny escrito con la
|
|
65
|
+
* forma canónica. `hierarchicalScopeResolver({ nodeOf })` lo hace por ti a
|
|
66
|
+
* partir de un `nodeOf` que lea la fila.
|
|
67
|
+
*
|
|
68
|
+
* organization → [la organization (fila), APP_SCOPE] (si existe; si no, null)
|
|
69
|
+
* unit → [la unit (fila), su organization (fila), APP_SCOPE] (idem)
|
|
70
|
+
*
|
|
71
|
+
* Esta MISMA función va a tres sitios, y tiene que ser la misma:
|
|
72
|
+
* - `scopes.resolveChain` (abajo): el manager valida con ella
|
|
73
|
+
* `scopes.attached/moved` (padre existente, sin ciclos) antes de tocar
|
|
74
|
+
* el driver;
|
|
75
|
+
* - `resolveChain` de cada driver: con ella responde `authorize`,
|
|
76
|
+
* `hasRole` y los `list*`, y valida `grant`/`deny`.
|
|
77
|
+
* Un driver sin ella solo conoce `app` (422 al preguntar por otro nivel).
|
|
78
|
+
*
|
|
79
|
+
* Cuando tu árbol cambie, avisa al motor en todos los drivers:
|
|
80
|
+
* authorization.scopes.attached(child, parent) / moved(child, newParent) /
|
|
81
|
+
* detached(child) ← purga los hechos del scope antes de que borres la fila.
|
|
82
|
+
*/
|
|
83
|
+
async function resolveScopeChain(scope: ScopeRef): Promise<ScopeRef[] | null> {
|
|
84
|
+
if (scope.type === 'app') return [APP_SCOPE]
|
|
85
|
+
// TODO: consulta tu tabla; devuelve null si `scope.uuid` no existe, y si
|
|
86
|
+
// existe, [{ type, uuid: fila.uuid }, ...ancestros, APP_SCOPE].
|
|
87
|
+
return null
|
|
30
88
|
}
|
|
31
89
|
|
|
32
90
|
/**
|
|
@@ -46,15 +104,60 @@ export default defineConfig({
|
|
|
46
104
|
modelId: env.get('OPENFGA_MODEL_ID'),
|
|
47
105
|
},
|
|
48
106
|
|
|
107
|
+
// La costura del árbol (ver arriba): la misma función que reciben los drivers.
|
|
108
|
+
// 2.1: añade `descendantsOf: sqlDescendantsOf({ table, uuidColumn, parentColumn, typeColumn })`
|
|
109
|
+
// (2.2: con `descendantsOf`, `scopes.detached` purga también los roles
|
|
110
|
+
// locales del SUBÁRBOL —sin él, solo los del scope exacto— y el nivel de
|
|
111
|
+
// un rol local se comprueba contra el árbol de hoy; delegar hacia abajo
|
|
112
|
+
// —`lead@unit` con owner una org— funciona con o sin él)
|
|
113
|
+
// (o tu propia función) para `authorizedScopes`; y `requireWithin: true` / `requireActor: true`
|
|
114
|
+
// en cuanto todos los call-sites pasen `within` / `actor` (hasta entonces el manager avisa).
|
|
115
|
+
// 2.3: `enumerateEdges: sqlScopeEdges({ table, uuidColumn, parentColumn, typeColumn })` es
|
|
116
|
+
// el árbol ENTERO paginado, y lo necesita `node ace authz:reconcile` (migrar entre drivers
|
|
117
|
+
// y verificar con --dry-run). Sin él el comando se niega en vez de suponer un árbol plano.
|
|
118
|
+
// La migración va en las DOS direcciones: `--to=openfga` reconstruye el store desde `authz_*`
|
|
119
|
+
// + este árbol, y `--to=database` reconstruye `authz_*` desde los hechos del store (ahí el
|
|
120
|
+
// árbol NO se migra: el driver `database` lo lee de TUS tablas en cada pregunta).
|
|
121
|
+
scopes: {
|
|
122
|
+
resolveChain: resolveScopeChain,
|
|
123
|
+
// Con AUTHZ_DRIVER=openfga el árbol vive en DOS sitios (tus tablas y el
|
|
124
|
+
// store) y quien ENCOLA los cambios es el MANAGER, que lee ESTA sección
|
|
125
|
+
// —no las opciones del driver—: sin una de las dos mitigaciones aquí,
|
|
126
|
+
// cada request es 500 E_AUTHZ_SCOPE_DRIFT_UNGUARDED. Igual que en la
|
|
127
|
+
// factory de abajo: cámbialo por `outbox: scopeOutbox` (la MISMA
|
|
128
|
+
// instancia en los dos sitios) en cuanto el árbol lo muevan peticiones
|
|
129
|
+
// de tenant; hasta entonces, esta es la firma explícita del riesgo.
|
|
130
|
+
// Con AUTHZ_DRIVER=database no aplica (el árbol tiene una sola copia).
|
|
131
|
+
acceptScopeDriftRisk: true,
|
|
132
|
+
},
|
|
133
|
+
|
|
49
134
|
drivers: {
|
|
50
|
-
database: () => new DatabaseAuthorizationDriver({
|
|
135
|
+
database: () => new DatabaseAuthorizationDriver({ resolveChain: resolveScopeChain }),
|
|
51
136
|
|
|
52
137
|
/**
|
|
53
138
|
* Backend externo opcional. Levanta el servidor y provisiona con
|
|
54
|
-
* `node ace openfga:provision
|
|
139
|
+
* `node ace openfga:provision` (escribe el modelo con TUS permisos: el
|
|
140
|
+
* modelo cambia cada vez que añades o quitas uno, y `authz:catalog:sync`
|
|
141
|
+
* proyecta el catálogo en el store).
|
|
142
|
+
* El driver vive en el subpath `/openfga` (lo único que importa el peer
|
|
143
|
+
* opcional `@openfga/sdk`) y se carga DENTRO de la factory: sin
|
|
144
|
+
* AUTHZ_DRIVER=openfga el SDK ni se instala ni se importa.
|
|
145
|
+
*
|
|
146
|
+
* **El árbol de scopes vive en el store** (el driver es el PDP y
|
|
147
|
+
* `authorize` es un solo `Check`), así que hay DOS copias del árbol —la
|
|
148
|
+
* tuya y la suya— y un `rollback` de tu transacción dejaría la del store
|
|
149
|
+
* adelantada. Por eso el driver NO se construye sin una de las dos
|
|
150
|
+
* mitigaciones (500 `E_AUTHZ_SCOPE_DRIFT_UNGUARDED`):
|
|
151
|
+
*
|
|
152
|
+
* - `scopes.outbox`: la MISMA instancia que pones en `scopes` arriba —
|
|
153
|
+
* el manager encola los cambios del árbol dentro de tu transacción y
|
|
154
|
+
* `node ace authz:scopes:relay` los aplica. Es la recomendada;
|
|
155
|
+
* publica la tabla con la migración `scopes_outbox_migration.stub`.
|
|
156
|
+
* - `acceptScopeDriftRisk: true`: la firma explícita de quien mueve el
|
|
157
|
+
* árbol solo desde la plataforma y lo asume.
|
|
55
158
|
*/
|
|
56
159
|
openfga: async () => {
|
|
57
|
-
const { OpenFgaAuthorizationDriver } = await import('@jantstack/adonis-authz')
|
|
160
|
+
const { OpenFgaAuthorizationDriver } = await import('@jantstack/adonis-authz/openfga')
|
|
58
161
|
const apiUrl = env.get('OPENFGA_URL')
|
|
59
162
|
const storeId = env.get('OPENFGA_STORE_ID')
|
|
60
163
|
if (!apiUrl || !storeId) {
|
|
@@ -64,11 +167,62 @@ export default defineConfig({
|
|
|
64
167
|
apiUrl,
|
|
65
168
|
storeId,
|
|
66
169
|
modelId: env.get('OPENFGA_MODEL_ID'),
|
|
67
|
-
|
|
170
|
+
resolveChain: resolveScopeChain,
|
|
68
171
|
holderTypes,
|
|
172
|
+
// Cámbialo por `outbox: scopeOutbox` (la misma que pases en `scopes`)
|
|
173
|
+
// en cuanto el árbol lo muevan peticiones de tenant.
|
|
174
|
+
acceptScopeDriftRisk: true,
|
|
69
175
|
})
|
|
70
176
|
},
|
|
71
177
|
},
|
|
72
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Catálogos de roles/permisos (uno por módulo). `node ace authz:catalog:sync`
|
|
181
|
+
* los sincroniza en orden (podando los vínculos que el config ya no lista);
|
|
182
|
+
* `node ace authz:catalog:diff` falla en CI si la base no coincide.
|
|
183
|
+
*/
|
|
184
|
+
catalogs: [async () => appAclCatalog()],
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Roles locales a un scope (2.2): `defineScopedRole(actor, ownerScope, spec)`
|
|
188
|
+
* solo puede meter en un rol local permisos de esta lista blanca (y que el
|
|
189
|
+
* actor tenga efectivos en el owner). Vacía = nadie delega nada. Los
|
|
190
|
+
* permisos de plataforma (`admin:*`, ajustes de organización) no deberían
|
|
191
|
+
* estar aquí.
|
|
192
|
+
*/
|
|
193
|
+
delegablePermissions: [],
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* ReBAC genérico (OPT-IN). `config` es la MISMA instancia que capturan las
|
|
197
|
+
* factories de `drivers` (F-05 del manager y del driver es la misma frontera);
|
|
198
|
+
* `default` es el driver de relaciones activo que resuelve el servicio
|
|
199
|
+
* `@jantstack/adonis-authz/services/relations` (default: el `default` de
|
|
200
|
+
* roles). Los `drivers` los usa además `node ace authz:relations:reconcile`.
|
|
201
|
+
* El driver `openfga` de relaciones entra por el subpath `/openfga` DENTRO de
|
|
202
|
+
* la factory (peer opcional). Si no usas ReBAC, borra esta sección y el
|
|
203
|
+
* `relationsConfig` de arriba.
|
|
204
|
+
*/
|
|
205
|
+
relations: {
|
|
206
|
+
config: relationsConfig,
|
|
207
|
+
default: env.get('AUTHZ_DRIVER', 'database'),
|
|
208
|
+
drivers: {
|
|
209
|
+
database: () => new DatabaseRelationsDriver(relationsConfig),
|
|
210
|
+
openfga: async () => {
|
|
211
|
+
const { OpenFgaRelationsDriver } = await import('@jantstack/adonis-authz/openfga')
|
|
212
|
+
const apiUrl = env.get('OPENFGA_URL')
|
|
213
|
+
const storeId = env.get('OPENFGA_STORE_ID')
|
|
214
|
+
if (!apiUrl || !storeId) {
|
|
215
|
+
throw new Error('AUTHZ_DRIVER=openfga requiere OPENFGA_URL y OPENFGA_STORE_ID')
|
|
216
|
+
}
|
|
217
|
+
return new OpenFgaRelationsDriver(relationsConfig, {
|
|
218
|
+
apiUrl,
|
|
219
|
+
storeId,
|
|
220
|
+
modelId: env.get('OPENFGA_MODEL_ID'),
|
|
221
|
+
holderTypes,
|
|
222
|
+
})
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
|
|
73
227
|
hooks: { onWrite: onAuthzWrite },
|
|
74
228
|
})
|
|
@@ -14,31 +14,57 @@ import { BaseSchema } from '@adonisjs/lucid/schema'
|
|
|
14
14
|
* El catálogo (roles/permissions/role_permissions) es metadata compartida
|
|
15
15
|
* entre drivers; los HECHOS (assignments/denies) son lo único que otro
|
|
16
16
|
* driver (p.ej. openfga) materializaría fuera.
|
|
17
|
+
*
|
|
18
|
+
* Decisiones observadas en PostgreSQL y MySQL (2.5 · J3, la suite corre en
|
|
19
|
+
* los tres motores):
|
|
20
|
+
* - `holder_uuid`/`scope_uuid` son `varchar(64)`, NO `uuid`: la identidad
|
|
21
|
+
* es una cadena validada por la gramática del paquete (`[A-Za-z0-9._-]`,
|
|
22
|
+
* ≤ 36) y el uuid es del consumidor; el tipo `uuid` de PostgreSQL
|
|
23
|
+
* rechazaba cualquier id que no fuera un UUID.
|
|
24
|
+
* - Las columnas de identidad y los slugs llevan `collate 'utf8mb4_bin'`
|
|
25
|
+
* (solo MySQL lo compila; en PG y SQLite la comparación ya es binaria):
|
|
26
|
+
* con la collation por defecto (`*_ci`) `abc` y `ABC` eran la misma fila
|
|
27
|
+
* y un grant a uno autorizaba al otro.
|
|
28
|
+
* - `expires_at` es `DATETIME(3)` (`datetime` con precisión 3): el
|
|
29
|
+
* `timestamp` de MySQL redondea al segundo (una caducidad de +600 ms
|
|
30
|
+
* concedía hasta +1 s) y no admite fechas más allá de 2038.
|
|
17
31
|
*/
|
|
18
32
|
export default class extends BaseSchema {
|
|
19
33
|
public async up() {
|
|
20
34
|
this.schema.createTable('authz_roles', (table) => {
|
|
21
35
|
table.uuid('uuid').primary().notNullable()
|
|
22
|
-
table.string('slug', 100).notNullable()
|
|
36
|
+
table.string('slug', 100).notNullable().collate('utf8mb4_bin')
|
|
23
37
|
table.string('name', 100).notNullable()
|
|
24
38
|
table.string('description', 500).nullable()
|
|
25
39
|
// Nivel al que el rol es asignable: 'app' | 'organization' | 'unit'.
|
|
26
|
-
|
|
40
|
+
// Identidad: byte a byte, como el resto (2.5-B, auditor ⚪4).
|
|
41
|
+
table.string('scope_type', 20).notNullable().collate('utf8mb4_bin')
|
|
27
42
|
// Rango de privilegio (mayor = más poder). Lo consume la policy de
|
|
28
43
|
// asignación (role_assignment_policy): nadie otorga/quita por encima
|
|
29
44
|
// de su propio rango.
|
|
30
45
|
table.integer('rank').notNullable().defaultTo(0)
|
|
46
|
+
// Quién define el rol (3B · B1): `global` (el catálogo del config,
|
|
47
|
+
// `syncAuthzCatalog`) o la clave del scope que lo define
|
|
48
|
+
// (`<tipo>|<uuid>`, `defineScopedRole`). Un rol local solo existe
|
|
49
|
+
// dentro de su owner; dos tenants pueden definir `lead@unit` cada uno.
|
|
50
|
+
// Es identidad: byte a byte. `app` nunca es owner (sería global).
|
|
51
|
+
table.string('owner_scope_key', 80).notNullable().defaultTo('global').collate('utf8mb4_bin')
|
|
31
52
|
table.timestamp('created_at').notNullable()
|
|
32
53
|
table.timestamp('updated_at').notNullable()
|
|
33
54
|
|
|
34
|
-
table.unique(['slug', 'scope_type'], '
|
|
55
|
+
table.unique(['slug', 'scope_type', 'owner_scope_key'], 'authz_roles_slug_scope_owner_uq')
|
|
56
|
+
table.index(['owner_scope_key'], 'authz_roles_owner_idx')
|
|
35
57
|
})
|
|
36
58
|
|
|
37
59
|
this.schema.createTable('authz_permissions', (table) => {
|
|
38
60
|
table.uuid('uuid').primary().notNullable()
|
|
39
61
|
// Formato `recurso:accion` (la misma gramática que las abilities M3).
|
|
40
|
-
table.string('slug', 100).notNullable().unique()
|
|
62
|
+
table.string('slug', 100).notNullable().unique().collate('utf8mb4_bin')
|
|
41
63
|
table.string('description', 500).nullable()
|
|
64
|
+
// Niveles (scope types) cuyos roles PUEDEN llevar este permiso (3B ·
|
|
65
|
+
// B5): JSON `["app","organization"]`, o NULL = cualquiera. Control de
|
|
66
|
+
// COMPOSICIÓN (sync, defineScopedRole, grant); jamás de evaluación.
|
|
67
|
+
table.string('assignable_at', 500).nullable()
|
|
42
68
|
table.timestamp('created_at').notNullable()
|
|
43
69
|
table.timestamp('updated_at').notNullable()
|
|
44
70
|
})
|
|
@@ -65,22 +91,23 @@ export default class extends BaseSchema {
|
|
|
65
91
|
this.schema.createTable('authz_assignments', (table) => {
|
|
66
92
|
table.uuid('uuid').primary().notNullable()
|
|
67
93
|
// Holder polimórfico: morph name (users/admins/integrations/...).
|
|
68
|
-
table.string('holder_type', 50).notNullable()
|
|
69
|
-
table.
|
|
94
|
+
table.string('holder_type', 50).notNullable().collate('utf8mb4_bin')
|
|
95
|
+
table.string('holder_uuid', 64).notNullable().collate('utf8mb4_bin')
|
|
70
96
|
table
|
|
71
97
|
.uuid('role_uuid')
|
|
72
98
|
.notNullable()
|
|
73
99
|
.references('uuid')
|
|
74
100
|
.inTable('authz_roles')
|
|
75
101
|
.onDelete('RESTRICT')
|
|
76
|
-
table.string('scope_type', 20).notNullable()
|
|
102
|
+
table.string('scope_type', 20).notNullable().collate('utf8mb4_bin')
|
|
77
103
|
// Sin FK: el scope es polimórfico. El nivel 'app' usa el uuid CENTINELA
|
|
78
104
|
// 00000000-... (no NULL): los motores SQL tratan cada NULL como
|
|
79
105
|
// distinto y el unique no aplicaría — con centinela la idempotencia
|
|
80
106
|
// del grant la respalda la constraint en TODOS los niveles (sin
|
|
81
107
|
// features específicas de un motor, regla M6).
|
|
82
|
-
table.
|
|
83
|
-
|
|
108
|
+
table.string('scope_uuid', 64).notNullable().collate('utf8mb4_bin')
|
|
109
|
+
// Milisegundos y sin tope de 2038 (ver cabecera): DATETIME(3).
|
|
110
|
+
table.datetime('expires_at', { precision: 3 }).nullable()
|
|
84
111
|
table.timestamp('created_at').notNullable()
|
|
85
112
|
|
|
86
113
|
table.unique(
|
|
@@ -93,17 +120,17 @@ export default class extends BaseSchema {
|
|
|
93
120
|
|
|
94
121
|
this.schema.createTable('authz_denies', (table) => {
|
|
95
122
|
table.uuid('uuid').primary().notNullable()
|
|
96
|
-
table.string('holder_type', 50).notNullable()
|
|
97
|
-
table.
|
|
123
|
+
table.string('holder_type', 50).notNullable().collate('utf8mb4_bin')
|
|
124
|
+
table.string('holder_uuid', 64).notNullable().collate('utf8mb4_bin')
|
|
98
125
|
table
|
|
99
126
|
.uuid('permission_uuid')
|
|
100
127
|
.notNullable()
|
|
101
128
|
.references('uuid')
|
|
102
129
|
.inTable('authz_permissions')
|
|
103
130
|
.onDelete('CASCADE')
|
|
104
|
-
table.string('scope_type', 20).notNullable()
|
|
131
|
+
table.string('scope_type', 20).notNullable().collate('utf8mb4_bin')
|
|
105
132
|
// Centinela 00000000-... para 'app' (ver nota en authz_assignments).
|
|
106
|
-
table.
|
|
133
|
+
table.string('scope_uuid', 64).notNullable().collate('utf8mb4_bin')
|
|
107
134
|
table.timestamp('created_at').notNullable()
|
|
108
135
|
|
|
109
136
|
table.unique(
|
|
@@ -112,9 +139,109 @@ export default class extends BaseSchema {
|
|
|
112
139
|
)
|
|
113
140
|
table.index(['holder_type', 'holder_uuid'], 'authz_deny_holder_idx')
|
|
114
141
|
})
|
|
142
|
+
|
|
143
|
+
// Versión COMPARTIDA del catálogo (2.1): una fila (`id = 1`) cuyo entero
|
|
144
|
+
// sube `syncAuthzCatalog` dentro de su transacción. Los memos del
|
|
145
|
+
// catálogo de todos los procesos la contrastan antes de servir: un sync
|
|
146
|
+
// en un worker se ve en los demás sin reiniciar ni pub/sub. Quien
|
|
147
|
+
// escriba `authz_*` a mano lo hace con `withAuthzCatalogWrite(async (trx)
|
|
148
|
+
// => …)`: misma transacción, versión subida como última sentencia. Sin
|
|
149
|
+
// esta fila (id = 1) toda pregunta es 503: por eso se siembra aquí.
|
|
150
|
+
//
|
|
151
|
+
// La fila `id = 2` es el **freeze DURABLE** (2.3): motivo, dueño
|
|
152
|
+
// (`<kind>:<pid>:<hex>`), lease (`freeze_until_ms`, null = sin caducidad)
|
|
153
|
+
// y `freeze_fence` (número de generación: `unfreeze` solo levanta el
|
|
154
|
+
// freeze cuyo fence+holder coinciden). Toda ESCRITURA del manager la lee
|
|
155
|
+
// antes de validar nada; sin esta fila toda escritura es 503 «migración
|
|
156
|
+
// 2.0 no aplicada» — tratarla como «no congelado» sería fail-open.
|
|
157
|
+
this.schema.createTable('authz_catalog_version', (table) => {
|
|
158
|
+
table.integer('id').primary().notNullable()
|
|
159
|
+
table.bigInteger('version').notNullable().defaultTo(0)
|
|
160
|
+
table.timestamp('updated_at').notNullable()
|
|
161
|
+
table.string('freeze_reason', 255).nullable()
|
|
162
|
+
table.string('freeze_holder', 120).nullable()
|
|
163
|
+
table.bigInteger('freeze_until_ms').nullable()
|
|
164
|
+
table.bigInteger('freeze_fence').notNullable().defaultTo(0)
|
|
165
|
+
})
|
|
166
|
+
this.defer(async (db) => {
|
|
167
|
+
await db.table('authz_catalog_version').insert({ id: 1, version: 0, updated_at: new Date() })
|
|
168
|
+
await db.table('authz_catalog_version').insert({ id: 2, version: 0, updated_at: new Date() })
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
// La config de relaciones PERSISTIDA (Fase 4-5, 🟡3): vive donde el gate de
|
|
172
|
+
// versión la ve (invariante 14), como el catálogo, para que CUALQUIER
|
|
173
|
+
// proceso que republique el modelo fusionado lea los tipos de relación de
|
|
174
|
+
// la BASE y NO los deje caer —el «modelo de uno, tuplas de otro» del
|
|
175
|
+
// auditor—. `spec` es el JSON de `defineRelationsConfig`; `model_id` es el
|
|
176
|
+
// último modelId del modelo fusionado publicado (el pin de la carrera
|
|
177
|
+
// `defineRelationsConfig`↔`syncAuthzCatalog`). Fila ausente = sin
|
|
178
|
+
// relaciones declaradas (opt-in), nunca un error.
|
|
179
|
+
this.schema.createTable('authz_relations_config', (table) => {
|
|
180
|
+
table.integer('id').primary().notNullable()
|
|
181
|
+
table.text('spec').notNullable()
|
|
182
|
+
table.string('model_id', 64).nullable()
|
|
183
|
+
table.timestamp('updated_at').notNullable()
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
// Tuplas de ReBAC (Fase 4): una fila por relación, INSERT/DELETE-ONLY (sin
|
|
187
|
+
// `expires_at`: la caducidad de relaciones quedó fuera de la 2.4). Sin FK:
|
|
188
|
+
// las relaciones NO cuelgan del catálogo (viven en su propio espacio de
|
|
189
|
+
// ids, disjunto de `authz_*` por construcción). Identidad byte a byte
|
|
190
|
+
// (`utf8mb4_bin`) como el resto (2.5 · J3). La partición (tenant) es la
|
|
191
|
+
// clave del scope; `subject_relation` con valor = userset (`group:g#member`),
|
|
192
|
+
// `subject_partition` = la partición del userset.
|
|
193
|
+
this.schema.createTable('authz_relations', (table) => {
|
|
194
|
+
table.uuid('uuid').primary().notNullable()
|
|
195
|
+
table.string('partition_key', 64).notNullable().collate('utf8mb4_bin')
|
|
196
|
+
table.string('object_type', 50).notNullable().collate('utf8mb4_bin')
|
|
197
|
+
table.string('object_uuid', 64).notNullable().collate('utf8mb4_bin')
|
|
198
|
+
table.string('relation', 50).notNullable().collate('utf8mb4_bin')
|
|
199
|
+
table.string('subject_type', 50).notNullable().collate('utf8mb4_bin')
|
|
200
|
+
table.string('subject_uuid', 64).notNullable().collate('utf8mb4_bin')
|
|
201
|
+
table.string('subject_relation', 50).nullable().collate('utf8mb4_bin')
|
|
202
|
+
table.string('subject_partition', 64).nullable().collate('utf8mb4_bin')
|
|
203
|
+
table.timestamp('created_at').notNullable()
|
|
204
|
+
|
|
205
|
+
table.unique(
|
|
206
|
+
['partition_key', 'object_type', 'object_uuid', 'relation', 'subject_type', 'subject_uuid', 'subject_relation'],
|
|
207
|
+
'authz_rel_tuple_uq'
|
|
208
|
+
)
|
|
209
|
+
table.index(['partition_key', 'object_type', 'object_uuid', 'relation'], 'authz_rel_object_idx')
|
|
210
|
+
table.index(['partition_key', 'subject_type', 'subject_uuid'], 'authz_rel_subject_idx')
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
// El TRIGGER de partición, por dialecto. Defiende al escritor «a mano»: una
|
|
214
|
+
// fila con userset (`subject_relation` con valor) de OTRA partición que la
|
|
215
|
+
// de la tupla se rechaza en el motor. La DDL es radicalmente distinta en
|
|
216
|
+
// cada uno (SQLite `RAISE(ABORT)`, PostgreSQL función plpgsql + trigger,
|
|
217
|
+
// MySQL `SIGNAL SQLSTATE`), y el cuerpo `BEGIN…END` lleva `;` dentro: cada
|
|
218
|
+
// sentencia se ejecuta ENTERA con `rawQuery`, nunca por un runner que
|
|
219
|
+
// trocea por `;`.
|
|
220
|
+
this.defer(async (db) => {
|
|
221
|
+
const dialect = db.dialect.name
|
|
222
|
+
for (const statement of relationPartitionTriggerStatements(dialect)) {
|
|
223
|
+
await db.rawQuery(statement)
|
|
224
|
+
}
|
|
225
|
+
})
|
|
115
226
|
}
|
|
116
227
|
|
|
117
228
|
public async down() {
|
|
229
|
+
this.defer(async (db) => {
|
|
230
|
+
const drops =
|
|
231
|
+
db.dialect.name === 'postgres'
|
|
232
|
+
? [
|
|
233
|
+
'DROP TRIGGER IF EXISTS authz_relations_partition_biu ON authz_relations',
|
|
234
|
+
'DROP FUNCTION IF EXISTS authz_relations_partition_guard()',
|
|
235
|
+
]
|
|
236
|
+
: [
|
|
237
|
+
'DROP TRIGGER IF EXISTS authz_relations_partition_bi',
|
|
238
|
+
'DROP TRIGGER IF EXISTS authz_relations_partition_bu',
|
|
239
|
+
]
|
|
240
|
+
for (const statement of drops) await db.rawQuery(statement)
|
|
241
|
+
})
|
|
242
|
+
this.schema.dropTable('authz_relations')
|
|
243
|
+
this.schema.dropTable('authz_relations_config')
|
|
244
|
+
this.schema.dropTable('authz_catalog_version')
|
|
118
245
|
this.schema.dropTable('authz_denies')
|
|
119
246
|
this.schema.dropTable('authz_assignments')
|
|
120
247
|
this.schema.dropTable('authz_role_permissions')
|
|
@@ -122,3 +249,46 @@ export default class extends BaseSchema {
|
|
|
122
249
|
this.schema.dropTable('authz_roles')
|
|
123
250
|
}
|
|
124
251
|
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* La DDL del trigger de partición de `authz_relations` por dialecto. Es la
|
|
255
|
+
* MISMA que `relationPartitionTrigger` del paquete
|
|
256
|
+
* (`@jantstack/adonis-authz` → `src/drivers/database_relations_driver.ts`);
|
|
257
|
+
* se inlinea aquí porque una migración es una foto congelada y no importa
|
|
258
|
+
* código del paquete. Dialecto no medido ⇒ lanza (nunca una tabla sin defensa).
|
|
259
|
+
*/
|
|
260
|
+
function relationPartitionTriggerStatements(dialect) {
|
|
261
|
+
const msg = 'authz_relations: un userset no puede pertenecer a otra partición que su tupla'
|
|
262
|
+
if (dialect === 'sqlite3' || dialect === 'better-sqlite3') {
|
|
263
|
+
const body = (event) =>
|
|
264
|
+
`CREATE TRIGGER authz_relations_partition_b${event === 'INSERT' ? 'i' : 'u'} ` +
|
|
265
|
+
`BEFORE ${event} ON authz_relations FOR EACH ROW ` +
|
|
266
|
+
`WHEN NEW.subject_relation IS NOT NULL AND NEW.subject_partition IS NOT NEW.partition_key ` +
|
|
267
|
+
`BEGIN SELECT RAISE(ABORT, '${msg}'); END`
|
|
268
|
+
return [body('INSERT'), body('UPDATE')]
|
|
269
|
+
}
|
|
270
|
+
if (dialect === 'postgres') {
|
|
271
|
+
return [
|
|
272
|
+
`CREATE OR REPLACE FUNCTION authz_relations_partition_guard() RETURNS trigger LANGUAGE plpgsql AS $authz$ ` +
|
|
273
|
+
`BEGIN ` +
|
|
274
|
+
`IF NEW.subject_relation IS NOT NULL AND NEW.subject_partition IS DISTINCT FROM NEW.partition_key THEN ` +
|
|
275
|
+
`RAISE EXCEPTION '${msg} (subject_partition=%, partition_key=%)', NEW.subject_partition, NEW.partition_key; ` +
|
|
276
|
+
`END IF; RETURN NEW; END; $authz$`,
|
|
277
|
+
`CREATE TRIGGER authz_relations_partition_biu BEFORE INSERT OR UPDATE ON authz_relations ` +
|
|
278
|
+
`FOR EACH ROW EXECUTE FUNCTION authz_relations_partition_guard()`,
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
if (dialect === 'mysql' || dialect === 'mysql2') {
|
|
282
|
+
const body = (event) =>
|
|
283
|
+
`CREATE TRIGGER authz_relations_partition_b${event === 'INSERT' ? 'i' : 'u'} ` +
|
|
284
|
+
`BEFORE ${event} ON authz_relations FOR EACH ROW ` +
|
|
285
|
+
`BEGIN ` +
|
|
286
|
+
`IF NEW.subject_relation IS NOT NULL AND NOT (NEW.subject_partition <=> NEW.partition_key) THEN ` +
|
|
287
|
+
`SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '${msg}'; ` +
|
|
288
|
+
`END IF; END`
|
|
289
|
+
return [body('INSERT'), body('UPDATE')]
|
|
290
|
+
}
|
|
291
|
+
throw new Error(
|
|
292
|
+
`authz_relations: dialecto '${dialect}' sin trigger de partición medido (hoy: PostgreSQL, MySQL 8 y SQLite).`
|
|
293
|
+
)
|
|
294
|
+
}
|