@jantstack/adonis-authz 2.0.0-alpha.1 → 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/README.md +462 -35
- package/build/commands/authz_catalog_diff.js +1 -1
- package/build/commands/authz_catalog_diff.js.map +1 -1
- 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 +17 -0
- package/build/commands/authz_catalog_sync.d.ts.map +1 -1
- package/build/commands/authz_catalog_sync.js +27 -4
- package/build/commands/authz_catalog_sync.js.map +1 -1
- 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 +6 -1
- package/build/commands/main.d.ts.map +1 -1
- package/build/commands/main.js +6 -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 +90 -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 +39 -10
- package/build/index.d.ts.map +1 -1
- package/build/index.js +35 -6
- 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.d.ts → catalog/catalog.d.ts} +41 -2
- package/build/src/catalog/catalog.d.ts.map +1 -0
- package/build/src/{catalog.js → catalog/catalog.js} +120 -14
- package/build/src/catalog/catalog.js.map +1 -0
- package/build/src/{catalog_cache.d.ts → catalog/catalog_cache.d.ts} +46 -22
- package/build/src/catalog/catalog_cache.d.ts.map +1 -0
- package/build/src/{catalog_cache.js → catalog/catalog_cache.js} +53 -43
- package/build/src/catalog/catalog_cache.js.map +1 -0
- package/build/src/define_config.d.ts +101 -3
- 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 +86 -4
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +425 -11
- 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 +713 -119
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +2048 -476
- 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 +258 -5
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +238 -7
- package/build/src/errors.js.map +1 -1
- 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/http/app_access_middleware.d.ts.map +1 -0
- 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 +74 -1
- package/build/src/identity.d.ts.map +1 -1
- package/build/src/identity.js +100 -2
- package/build/src/identity.js.map +1 -1
- package/build/src/manager.d.ts +315 -4
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +1187 -181
- package/build/src/manager.js.map +1 -1
- package/build/src/models/authz_assignment.d.ts +6 -6
- package/build/src/models/authz_assignment.d.ts.map +1 -1
- package/build/src/models/authz_deny.d.ts +6 -6
- package/build/src/models/authz_deny.d.ts.map +1 -1
- package/build/src/models/authz_permission.d.ts +6 -6
- package/build/src/models/authz_permission.d.ts.map +1 -1
- package/build/src/models/authz_role.d.ts +6 -6
- package/build/src/models/authz_role.d.ts.map +1 -1
- package/build/src/models/authz_role_permission.d.ts +6 -6
- package/build/src/models/authz_role_permission.d.ts.map +1 -1
- package/build/src/openfga.d.ts +18 -2
- package/build/src/openfga.d.ts.map +1 -1
- package/build/src/openfga.js +15 -1
- package/build/src/openfga.js.map +1 -1
- 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/{drivers → shared}/backend_guard.d.ts +14 -0
- package/build/src/shared/backend_guard.d.ts.map +1 -0
- package/build/src/{drivers → shared}/backend_guard.js +26 -1
- package/build/src/shared/backend_guard.js.map +1 -0
- package/build/src/shared/sql_expiry.d.ts.map +1 -0
- package/build/src/shared/sql_expiry.js.map +1 -0
- package/build/src/sql_descendants.d.ts +47 -1
- package/build/src/sql_descendants.d.ts.map +1 -1
- package/build/src/sql_descendants.js +75 -1
- package/build/src/sql_descendants.js.map +1 -1
- package/build/src/testing/contract.d.ts +74 -0
- package/build/src/testing/contract.d.ts.map +1 -1
- package/build/src/testing/contract.js +672 -169
- package/build/src/testing/contract.js.map +1 -1
- package/build/src/testing/main.d.ts +6 -0
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +3 -0
- 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/traits/authz_scopes.js +1 -1
- package/build/src/traits/authz_scopes.js.map +1 -1
- package/build/src/traits/has_uuid.d.ts +7 -7
- package/build/src/traits/has_uuid.d.ts.map +1 -1
- package/build/src/types.d.ts +865 -82
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js +10 -0
- package/build/src/types.js.map +1 -1
- package/build/stubs/config/authorization.stub +104 -4
- package/build/stubs/migration.stub +126 -0
- package/build/stubs/scopes_outbox_migration.stub +57 -0
- package/package.json +4 -2
- package/build/commands/openfga_import.d.ts +0 -34
- package/build/commands/openfga_import.d.ts.map +0 -1
- package/build/commands/openfga_import.js +0 -97
- package/build/commands/openfga_import.js.map +0 -1
- package/build/src/catalog.d.ts.map +0 -1
- package/build/src/catalog.js.map +0 -1
- package/build/src/catalog_cache.d.ts.map +0 -1
- package/build/src/catalog_cache.js.map +0 -1
- package/build/src/drivers/backend_guard.d.ts.map +0 -1
- package/build/src/drivers/backend_guard.js.map +0 -1
- package/build/src/drivers/sql_expiry.d.ts.map +0 -1
- package/build/src/drivers/sql_expiry.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/{middleware → http}/app_access_middleware.d.ts +0 -0
- /package/build/src/{middleware → http}/app_access_middleware.js +0 -0
- /package/build/src/{drivers → shared}/sql_expiry.d.ts +0 -0
- /package/build/src/{drivers → shared}/sql_expiry.js +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { AuthorizationDriverFactory, AuthzCatalogWriteEvent, AuthzWriteEvent, HolderTypeMap, ScopeChainResolver, ScopeDescendantsResolver } from './types.js';
|
|
2
|
-
import type { CatalogSource } from './catalog.js';
|
|
1
|
+
import type { AuthorizationDriverFactory, AuthzCatalogWriteEvent, AuthzWriteEvent, HolderTypeMap, RelationsDriverFactory, ScopeChainResolver, ScopeDescendantsResolver, ScopeEdgesEnumerator, ScopeOutbox } from './types.js';
|
|
2
|
+
import type { CatalogSource } from './catalog/catalog.js';
|
|
3
|
+
import type { RelationsConfig } from './relations/define_relations_config.js';
|
|
3
4
|
/**
|
|
4
5
|
* Config del sistema de autorización. Todo lo específico del consumidor
|
|
5
6
|
* entra por aquí: qué drivers existen, cuál está activo, cómo se llaman sus
|
|
@@ -25,7 +26,7 @@ export interface AuthorizationConfig {
|
|
|
25
26
|
/**
|
|
26
27
|
* Holders del consumidor: morph name (`@MorphMap` del modelo) → tipo del
|
|
27
28
|
* modelo FGA. Lo necesitan el driver `openfga` y los comandos
|
|
28
|
-
* `openfga:provision
|
|
29
|
+
* `openfga:provision`; el driver `database` lo ignora.
|
|
29
30
|
*/
|
|
30
31
|
holderTypes?: HolderTypeMap;
|
|
31
32
|
/**
|
|
@@ -58,6 +59,25 @@ export interface AuthorizationConfig {
|
|
|
58
59
|
* con columna padre (PG y SQLite).
|
|
59
60
|
*/
|
|
60
61
|
descendantsOf?: ScopeDescendantsResolver;
|
|
62
|
+
/**
|
|
63
|
+
* **El árbol entero, paginado** (3b-3a): lo que `authz:reconcile` usa
|
|
64
|
+
* para reconstruir —y para PODAR— el árbol de un driver que lo guarda
|
|
65
|
+
* como hechos propios (`openfga` en modo `facts`). `resolveChain`
|
|
66
|
+
* responde por un scope; esto los enumera todos.
|
|
67
|
+
*
|
|
68
|
+
* scopes: {
|
|
69
|
+
* resolveChain,
|
|
70
|
+
* enumerateEdges: sqlScopeEdges({
|
|
71
|
+
* table: 'organization_nodes', uuidColumn: 'uuid',
|
|
72
|
+
* parentColumn: 'parent_uuid', typeColumn: 'kind',
|
|
73
|
+
* }),
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* Solo lo usa `authz:reconcile`: sin él la migración del ÁRBOL no se
|
|
77
|
+
* hace y el comando lo dice (500 `E_AUTHZ_CONFIG`) en vez de suponer que
|
|
78
|
+
* el árbol del backend ya está bien.
|
|
79
|
+
*/
|
|
80
|
+
enumerateEdges?: ScopeEdgesEnumerator;
|
|
61
81
|
/**
|
|
62
82
|
* Tope de scopes que `authorizedScopes` devuelve (default 1000); superado
|
|
63
83
|
* ⇒ 422 `E_AUTHZ_TOO_MANY_SCOPES`, nunca parcial. Se puede bajar por
|
|
@@ -72,6 +92,38 @@ export interface AuthorizationConfig {
|
|
|
72
92
|
* hacen, 2.5-B · ⚪6).
|
|
73
93
|
*/
|
|
74
94
|
maxDescendants?: number;
|
|
95
|
+
/**
|
|
96
|
+
* **La outbox del árbol** (3b-2d, panel 2 cruce 4 · S5). Con ella,
|
|
97
|
+
* `manager.scopes.attached/moved/detached` NO escriben en el backend:
|
|
98
|
+
* ENCOLAN el cambio —pásale tu transacción en
|
|
99
|
+
* `{ transaction }`— y lo aplica después `node ace authz:scopes:relay`.
|
|
100
|
+
*
|
|
101
|
+
* Sin ella, el paquete escribe en el backend dentro de TU transacción y
|
|
102
|
+
* un `rollback` posterior no lo deshace: el árbol del backend queda
|
|
103
|
+
* adelantado al tuyo y, en `hierarchy: 'facts'` (donde FGA es el PDP),
|
|
104
|
+
* eso es una escalada persistente e invisible desde tu base. Por eso el
|
|
105
|
+
* driver `facts` se niega a construirse sin outbox y sin
|
|
106
|
+
* `acceptScopeDriftRisk: true`.
|
|
107
|
+
*
|
|
108
|
+
* El paquete no impone tabla: `sqlScopeOutbox(...)` implementa el puerto
|
|
109
|
+
* sobre Lucid y `stubs/scopes_outbox_migration.stub` es la migración que
|
|
110
|
+
* puedes copiar, pero cualquier implementación del puerto vale.
|
|
111
|
+
*
|
|
112
|
+
* Lo que la outbox NO arregla: durante el lag del relay (segundos) el
|
|
113
|
+
* backend decide con el árbol VIEJO. Es un fail-open temporal —el tenant
|
|
114
|
+
* antiguo conserva acceso tras un `moved`, los denies heredados no
|
|
115
|
+
* aplican tras un `attached`—. No hay 2PC.
|
|
116
|
+
*/
|
|
117
|
+
outbox?: ScopeOutbox;
|
|
118
|
+
/**
|
|
119
|
+
* «Sé que sin outbox un `rollback` de mi transacción deja el árbol del
|
|
120
|
+
* backend adelantado al mío, y lo asumo» (3b-2e · E3). Es la salida
|
|
121
|
+
* explícita del gate del MANAGER, que es quien encola: declarar la outbox
|
|
122
|
+
* solo en el driver dejaba el gate del driver contento y la mitigación
|
|
123
|
+
* APAGADA. Tiene que ser el booleano `true`: un valor «truthy» no es una
|
|
124
|
+
* aceptación.
|
|
125
|
+
*/
|
|
126
|
+
acceptScopeDriftRisk?: boolean;
|
|
75
127
|
};
|
|
76
128
|
/**
|
|
77
129
|
* Catálogos de roles/permisos del consumidor (uno por módulo: plataforma,
|
|
@@ -131,6 +183,52 @@ export interface AuthorizationConfig {
|
|
|
131
183
|
* tiene que tener cada permiso EFECTIVO en el owner (sin deny).
|
|
132
184
|
*/
|
|
133
185
|
delegablePermissions?: string[];
|
|
186
|
+
/**
|
|
187
|
+
* **ReBAC genérico** (Fase 4, `relations/`). Los drivers del puerto
|
|
188
|
+
* `RelationsDriver`, por clave, análogos a `drivers` de roles, más la CONFIG
|
|
189
|
+
* de relaciones (`defineRelationsConfig`) que declara los tipos y sus
|
|
190
|
+
* relaciones. La factory del driver `openfga` de relaciones entra por el
|
|
191
|
+
* subpath `/openfga` DENTRO de ella, como la de roles, así que ningún comando
|
|
192
|
+
* importa el SDK.
|
|
193
|
+
*
|
|
194
|
+
* const relationsConfig = defineRelationsConfig({
|
|
195
|
+
* objectTypes: [{ type: 'document', relations: [{ name: 'viewer' }] }],
|
|
196
|
+
* holderTypes: ['user'],
|
|
197
|
+
* })
|
|
198
|
+
* relations: {
|
|
199
|
+
* config: relationsConfig,
|
|
200
|
+
* default: env.get('AUTHZ_DRIVER', 'database'),
|
|
201
|
+
* drivers: {
|
|
202
|
+
* database: () => new DatabaseRelationsDriver(relationsConfig),
|
|
203
|
+
* openfga: () => new OpenFgaRelationsDriver(relationsConfig, { ... }),
|
|
204
|
+
* },
|
|
205
|
+
* }
|
|
206
|
+
*
|
|
207
|
+
* Con `config` declarado, el paquete cablea el `RelationsManager` como
|
|
208
|
+
* singleton (servicio `@jantstack/adonis-authz/services/relations`, análogo
|
|
209
|
+
* al de roles) y `openfga:provision` incluye los tipos de relación en el
|
|
210
|
+
* modelo `facts` que publica (así un store recién aprovisionado ya acepta
|
|
211
|
+
* tuplas de relación sin un `authz:catalog:sync` previo). `drivers` los usa
|
|
212
|
+
* además `authz:relations:reconcile` para el ORIGEN y el DESTINO de una
|
|
213
|
+
* migración de tuplas.
|
|
214
|
+
*/
|
|
215
|
+
relations?: {
|
|
216
|
+
/**
|
|
217
|
+
* La config de relaciones (`defineRelationsConfig(...)`): los tipos de
|
|
218
|
+
* objeto y sus relaciones. Es lo que el `RelationsManager` de servicio usa
|
|
219
|
+
* para F-05 (rechazar un tipo/relación no declarado) y lo que
|
|
220
|
+
* `openfga:provision` mete en el modelo `facts`. Es la MISMA instancia que
|
|
221
|
+
* las factories de `drivers` capturan para construir sus drivers.
|
|
222
|
+
*/
|
|
223
|
+
config?: RelationsConfig;
|
|
224
|
+
/**
|
|
225
|
+
* Clave del driver de relaciones ACTIVO (en `drivers`) que el singleton de
|
|
226
|
+
* servicio resuelve. Default: el `default` de roles (los drivers de
|
|
227
|
+
* relaciones se nombran igual que los de roles).
|
|
228
|
+
*/
|
|
229
|
+
default?: string;
|
|
230
|
+
drivers?: Record<string, RelationsDriverFactory>;
|
|
231
|
+
};
|
|
134
232
|
/**
|
|
135
233
|
* Hooks del consumidor. `onWrite` se llama tras cada escritura del motor
|
|
136
234
|
* (grant/extended/revoke/deny/removeDeny/scope_purged) — el sitio natural
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,EACpB,WAAW,EACZ,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAE7E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAA;IAEnD;;;;OAIG;IACH,WAAW,CAAC,EAAE,aAAa,CAAA;IAE3B;;;OAGG;IACH,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,uCAAuC;QACvC,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,CAAA;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE;QACP,YAAY,EAAE,kBAAkB,CAAA;QAChC;;;;;WAKG;QACH,aAAa,CAAC,EAAE,wBAAwB,CAAA;QACxC;;;;;;;;;;;;;;;;;WAiBG;QACH,cAAc,CAAC,EAAE,oBAAoB,CAAA;QACrC;;;;WAIG;QACH,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB;;;;;;WAMG;QACH,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB;;;;;;;;;;;;;;;;;;;;;WAqBG;QACH,MAAM,CAAC,EAAE,WAAW,CAAA;QACpB;;;;;;;WAOG;QACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;KAC/B,CAAA;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAA;IAE1B;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;IAElB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;IAEpC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAE7B;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;IAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,SAAS,CAAC,EAAE;QACV;;;;;;WAMG;QACH,MAAM,CAAC,EAAE,eAAe,CAAA;QACxB;;;;WAIG;QACH,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAA;KACjD,CAAA;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;QACnD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAClE,CAAA;CACF;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,mBAAmB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAExE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AA4QA,MAAM,UAAU,YAAY,CAAgC,MAAS;IACnE,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import db from '@adonisjs/lucid/services/db';
|
|
2
|
-
import type { AuthorizationDriver, CatalogRoleRef, DenyRef, GrantOptions, GrantOutcome, NormalizedRoleQuery, RoleQuery, ScopeRef, ScopeType, SubjectRef } from '../types.js';
|
|
2
|
+
import type { AuthorizationDriver, CatalogRoleRef, DenyRef, GrantOptions, GrantOutcome, NormalizedRoleQuery, ReconcileOptions, ReconcileReport, ReconcileSource, RoleQuery, ScopeRef, ScopeType, SubjectRef } from '../types.js';
|
|
3
3
|
import type { ScopeChainResolver } from '../types.js';
|
|
4
|
-
import { CatalogCache } from '../catalog_cache.js';
|
|
5
|
-
import type { CatalogRevalidate, CatalogRole, CatalogView } from '../catalog_cache.js';
|
|
4
|
+
import { CatalogCache } from '../catalog/catalog_cache.js';
|
|
5
|
+
import type { CatalogRevalidate, CatalogRole, CatalogView } from '../catalog/catalog_cache.js';
|
|
6
6
|
import type { Clock } from '../clock.js';
|
|
7
7
|
export type QueryBuilder = ReturnType<typeof db.from>;
|
|
8
8
|
/**
|
|
@@ -12,6 +12,15 @@ export type QueryBuilder = ReturnType<typeof db.from>;
|
|
|
12
12
|
* de ESTE driver — la API pública sigue usando uuid null para app.
|
|
13
13
|
*/
|
|
14
14
|
export declare const APP_SCOPE_DB_UUID = "00000000-0000-0000-0000-000000000000";
|
|
15
|
+
/**
|
|
16
|
+
* La vuelta de `toDbScopeUuid`: el centinela de la raíz vuelve a ser `null`.
|
|
17
|
+
* **Exportada desde 3b-3b**: `authz:reconcile --to=openfga` lee estas mismas
|
|
18
|
+
* columnas y hacía `row.scope_uuid ?? null`, que con la columna NOT NULL
|
|
19
|
+
* nunca es null — un grant o un deny en la RAÍZ reventaban la migración con
|
|
20
|
+
* un 422 a mitad de pasada (`el scope 'app' no admite uuid`). Lo cazó el
|
|
21
|
+
* contrato de migración, cuya siembra fija sí concede en `app`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function fromDbScopeUuid(uuid: string): string | null;
|
|
15
24
|
/**
|
|
16
25
|
* El rol `(slug, scopeType)` que existe en el scope cuya cadena empieza por
|
|
17
26
|
* `chainKeys`, o 422: `E_AUTHZ_ROLE_NOT_VISIBLE` si hay roles con ese nombre
|
|
@@ -141,6 +150,24 @@ export declare const DEFAULT_TIMEOUT_MS = 5000;
|
|
|
141
150
|
* crudo de knex (L0.11).
|
|
142
151
|
*/
|
|
143
152
|
export declare class DatabaseAuthorizationDriver implements AuthorizationDriver {
|
|
153
|
+
/**
|
|
154
|
+
* Lo que este driver declara (3b-2e · E2). El árbol es del consumidor
|
|
155
|
+
* (`resolveChain`), así que no hay hechos de jerarquía ni deriva que
|
|
156
|
+
* mitigar; `authorize` son varias consultas SQL; la membresía la resuelve
|
|
157
|
+
* el propio SQL contra la cadena que le pasan; los `list*` no enumeran
|
|
158
|
+
* herencia (invariante 7); y `purgeRole` está implementado en una
|
|
159
|
+
* transacción.
|
|
160
|
+
*/
|
|
161
|
+
readonly capabilities: Readonly<{
|
|
162
|
+
hierarchyFacts: false;
|
|
163
|
+
singleCheckAuthorize: false;
|
|
164
|
+
roleInheritanceNative: false;
|
|
165
|
+
listObjectsInherited: false;
|
|
166
|
+
purgeRole: true;
|
|
167
|
+
countRoleAssignments: true;
|
|
168
|
+
canonicalScopeReads: true;
|
|
169
|
+
enumerateFacts: false;
|
|
170
|
+
}>;
|
|
144
171
|
/**
|
|
145
172
|
* Resolutor de jerarquía inyectado por el consumidor (el chasis pasa el
|
|
146
173
|
* suyo, que conoce organizations/units, en `config/authorization.ts`).
|
|
@@ -191,8 +218,10 @@ export declare class DatabaseAuthorizationDriver implements AuthorizationDriver
|
|
|
191
218
|
private chain;
|
|
192
219
|
/** La cadena o 422: una escritura no puede ir a un scope que nadie reconoce. */
|
|
193
220
|
private knownScope;
|
|
194
|
-
/** El scope canónico para `
|
|
221
|
+
/** El scope canónico para `purgeScope` (ver `canonicalScope`). */
|
|
195
222
|
private canonicalOrSelf;
|
|
223
|
+
/** Los destinos de un delete de hechos (`revoke`/`removeDeny`): canónico, o el fan-out de alias (3b-8 · A4). */
|
|
224
|
+
private canonicalTargets;
|
|
196
225
|
/**
|
|
197
226
|
* Ejecuta una consulta clasificando su fallo (503 con código propio). `fn`
|
|
198
227
|
* devuelve el BUILDER sin ejecutar: el guard le fija el deadline y luego lo
|
|
@@ -271,5 +300,58 @@ export declare class DatabaseAuthorizationDriver implements AuthorizationDriver
|
|
|
271
300
|
* `manager.driver()`) se purga lo que se pida.
|
|
272
301
|
*/
|
|
273
302
|
purgeRole(roleUuid: string): Promise<void>;
|
|
303
|
+
/**
|
|
304
|
+
* Cuántos hechos VIGENTES tiene cada rol, en todos los scopes (3b-2j). Es
|
|
305
|
+
* lo que `pruneOrphanRoles` necesita para decir si un huérfano todavía
|
|
306
|
+
* concede, y es una pregunta del PUERTO porque los hechos son del driver:
|
|
307
|
+
* aquí son filas de `authz_assignments`, en `openfga` son tuplas del store.
|
|
308
|
+
*
|
|
309
|
+
* Una consulta agrupada para todos los uuids (no una por rol) y la misma
|
|
310
|
+
* caducidad ESTRICTA que el resto del driver, con SU reloj (`whereActive`,
|
|
311
|
+
* J1): la asignación que vence ahora ya no cuenta, como no cuenta en
|
|
312
|
+
* `authorize`. Un rol sin hechos —o que no está en la tabla— es `0`.
|
|
313
|
+
*/
|
|
314
|
+
countRoleAssignments(roleUuids: string[]): Promise<number[]>;
|
|
315
|
+
/**
|
|
316
|
+
* **Rehace `authz_assignments`/`authz_denies` desde los hechos de OTRO
|
|
317
|
+
* driver** — la vuelta de la migración, y con ella la simetría que el dueño
|
|
318
|
+
* compró: «todo en un driver o todo en otro».
|
|
319
|
+
*
|
|
320
|
+
* Qué se migra y qué NO, y por qué:
|
|
321
|
+
* - **los HECHOS, sí**: es lo único que vive en el otro driver. Llegan por
|
|
322
|
+
* `source.facts` —el puerto `enumerateFacts`, paginado— y no por SQL:
|
|
323
|
+
* aquí el origen es un store, no una tabla de este paquete.
|
|
324
|
+
* - **el ÁRBOL, no**. En esta dirección el árbol NO se migra: el driver
|
|
325
|
+
* `database` lo lee de las tablas del CONSUMIDOR en cada pregunta
|
|
326
|
+
* (`resolveChain`), que son su fuente de verdad. Copiarlo a algún sitio
|
|
327
|
+
* sería inventarse una segunda copia y con ella una deriva que hoy no
|
|
328
|
+
* existe. Se usa, eso sí, para decidir qué hecho es migrable
|
|
329
|
+
* (`unknown-scope`) y bajo qué identidad CANÓNICA se escribe
|
|
330
|
+
* (invariante 17).
|
|
331
|
+
* - **el CATÁLOGO, tampoco**: es propiedad local SIEMPRE (regla de higiene
|
|
332
|
+
* del paquete), ya está en `authz_*` y ningún driver es su fuente. Aquí
|
|
333
|
+
* solo se usa para traducir: un `roleUuid` que el catálogo no declara y
|
|
334
|
+
* un permiso que no existe no son hechos migrables.
|
|
335
|
+
*
|
|
336
|
+
* Por eso `phases.root`, `phases.catalog` y `phases.tree` son CERO en esta
|
|
337
|
+
* dirección, y todo el movimiento está en `phases.facts`. Es una respuesta,
|
|
338
|
+
* no un hueco: los ceros dicen «aquí no hay nada derivado que rehacer».
|
|
339
|
+
*
|
|
340
|
+
* El resto del contrato es el mismo que en la ida (3b-3a): idempotente (la
|
|
341
|
+
* segunda pasada escribe cero), `dryRun` es el VERIFICADOR y es read-only
|
|
342
|
+
* por contrato —**un `--fix` está prohibido** (cruce 4 · S18) y no se
|
|
343
|
+
* implementa ni se deja preparado—, nunca silenciosa (`skipped{motivo}` +
|
|
344
|
+
* `details`), los hechos que sobran solo se borran con `prune`, y el
|
|
345
|
+
* seguro del origen ciego (`E_AUTHZ_MASS_RECONCILE_REFUSED`) se aplica
|
|
346
|
+
* igual: un origen que devuelve CERO hechos y un `--prune` detrás vacían
|
|
347
|
+
* la base, y eso es casi siempre apuntar al store equivocado.
|
|
348
|
+
*/
|
|
349
|
+
reconcile(source: ReconcileSource, options?: ReconcileOptions): Promise<ReconcileReport>;
|
|
350
|
+
/**
|
|
351
|
+
* Pasea una tabla `authz_*` por lotes con cursor sobre `uuid` (PK: orden
|
|
352
|
+
* total y estable). Lo mismo que hace `openfga.reconcile` con el origen,
|
|
353
|
+
* por el mismo motivo: una base grande no entra entera de golpe.
|
|
354
|
+
*/
|
|
355
|
+
private eachReconcileRow;
|
|
274
356
|
}
|
|
275
357
|
//# sourceMappingURL=database_driver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database_driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/database_driver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAE5C,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,SAAS,EACT,UAAU,EACX,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"database_driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/database_driver.ts"],"names":[],"mappings":"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"}
|