@jantstack/adonis-authz 1.0.2 → 2.0.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 +417 -46
- 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_sync.d.ts +20 -0
- package/build/commands/authz_catalog_sync.d.ts.map +1 -0
- package/build/commands/authz_catalog_sync.js +58 -0
- package/build/commands/authz_catalog_sync.js.map +1 -0
- package/build/commands/main.d.ts +2 -0
- package/build/commands/main.d.ts.map +1 -1
- package/build/commands/main.js +2 -0
- package/build/commands/main.js.map +1 -1
- package/build/commands/openfga_import.d.ts +8 -2
- package/build/commands/openfga_import.d.ts.map +1 -1
- package/build/commands/openfga_import.js +29 -6
- package/build/commands/openfga_import.js.map +1 -1
- package/build/commands/openfga_provision.d.ts.map +1 -1
- package/build/commands/openfga_provision.js +2 -1
- package/build/commands/openfga_provision.js.map +1 -1
- package/build/index.d.ts +51 -5
- package/build/index.d.ts.map +1 -1
- package/build/index.js +43 -3
- package/build/index.js.map +1 -1
- package/build/src/catalog.d.ts +249 -2
- package/build/src/catalog.d.ts.map +1 -1
- package/build/src/catalog.js +709 -59
- package/build/src/catalog.js.map +1 -1
- package/build/src/catalog_cache.d.ts +300 -0
- package/build/src/catalog_cache.d.ts.map +1 -0
- package/build/src/catalog_cache.js +656 -0
- package/build/src/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 +102 -6
- package/build/src/define_config.d.ts.map +1 -1
- package/build/src/define_config.js.map +1 -1
- package/build/src/drivers/backend_guard.d.ts +92 -0
- package/build/src/drivers/backend_guard.d.ts.map +1 -0
- package/build/src/drivers/backend_guard.js +221 -0
- package/build/src/drivers/backend_guard.js.map +1 -0
- package/build/src/drivers/database_driver.d.ts +242 -15
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +692 -127
- package/build/src/drivers/database_driver.js.map +1 -1
- package/build/src/drivers/openfga_driver.d.ts +341 -27
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +1052 -264
- package/build/src/drivers/openfga_driver.js.map +1 -1
- package/build/src/drivers/sql_expiry.d.ts +53 -0
- package/build/src/drivers/sql_expiry.d.ts.map +1 -0
- package/build/src/drivers/sql_expiry.js +66 -0
- package/build/src/drivers/sql_expiry.js.map +1 -0
- package/build/src/errors.d.ts +366 -0
- package/build/src/errors.d.ts.map +1 -0
- package/build/src/errors.js +387 -0
- package/build/src/errors.js.map +1 -0
- 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/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/identity.d.ts +155 -0
- package/build/src/identity.d.ts.map +1 -0
- package/build/src/identity.js +359 -0
- package/build/src/identity.js.map +1 -0
- package/build/src/manager.d.ts +225 -7
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +1670 -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/middleware/app_access_middleware.d.ts +8 -6
- package/build/src/middleware/app_access_middleware.d.ts.map +1 -1
- package/build/src/middleware/app_access_middleware.js +10 -26
- package/build/src/middleware/app_access_middleware.js.map +1 -1
- package/build/src/models/authz_assignment.d.ts +5 -5
- package/build/src/models/authz_assignment.d.ts.map +1 -1
- package/build/src/models/authz_deny.d.ts +5 -5
- package/build/src/models/authz_deny.d.ts.map +1 -1
- package/build/src/models/authz_permission.d.ts +11 -5
- 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 +13 -6
- 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 +5 -5
- package/build/src/models/authz_role_permission.d.ts.map +1 -1
- package/build/src/openfga.d.ts +13 -0
- package/build/src/openfga.d.ts.map +1 -0
- package/build/src/openfga.js +12 -0
- package/build/src/openfga.js.map +1 -0
- package/build/src/sql_descendants.d.ts +51 -0
- package/build/src/sql_descendants.d.ts.map +1 -0
- package/build/src/sql_descendants.js +129 -0
- package/build/src/sql_descendants.js.map +1 -0
- package/build/src/testing/contract.d.ts +138 -7
- package/build/src/testing/contract.d.ts.map +1 -1
- package/build/src/testing/contract.js +2946 -24
- package/build/src/testing/contract.js.map +1 -1
- package/build/src/testing/main.d.ts +4 -2
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +2 -1
- package/build/src/testing/main.js.map +1 -1
- package/build/src/testing/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 +5 -5
- package/build/src/traits/has_uuid.d.ts.map +1 -1
- package/build/src/types.d.ts +530 -28
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js +10 -4
- package/build/src/types.js.map +1 -1
- package/build/stubs/config/app_acl.stub +4 -2
- package/build/stubs/config/authorization.stub +66 -12
- package/build/stubs/migration.stub +57 -13
- package/package.json +11 -6
package/build/src/manager.d.ts
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
import type { AuthorizationConfig } from './define_config.js';
|
|
2
|
-
import type { AuthorizationDriver, GrantOptions, ScopeRef, ScopeType, SubjectRef } from './types.js';
|
|
2
|
+
import type { AuthorizationDriver, AuthorizedScopes, CatalogRole, DenyOptions, DenyRef, ExcludedSubtree, GrantOptions, GrantOutcome, RoleQuery, ScopeDetachOutcome, ScopedRoleChanges, ScopedRoleSpec, ScopedWriteOptions, ScopeRef, ScopeType, SubjectRef } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Lo que devuelve `AuthorizationManager.forRequest()`: la misma API que el
|
|
5
|
+
* manager (lecturas, escrituras, `scopes.*`), con los ancestros memoizados
|
|
6
|
+
* SOLO en las lecturas. Es un tipo, no otra clase: la vista es un manager
|
|
7
|
+
* hijo que comparte config, driver y hooks con su padre.
|
|
8
|
+
*/
|
|
9
|
+
export type AuthorizationView = Pick<AuthorizationManager, 'authorize' | 'hasRole' | 'listSubjects' | 'listScopes' | 'listRoles' | 'listRoleScopes' | 'grant' | 'revoke' | 'deny' | 'removeDeny' | 'scopes' | 'driver' | 'forRequest' | 'isWithin' | 'listDenies' | 'effectivePermissions' | 'authorizeMany' | 'authorizedScopes' | 'expandExcludedSubtrees' | 'defineScopedRole' | 'updateScopedRole' | 'deleteScopedRole'>;
|
|
10
|
+
/**
|
|
11
|
+
* Expande los `excludedSubtrees` de un `all` (2D · F10) a la lista plana de
|
|
12
|
+
* scopes que hay que restar: cada scope denegado y TODOS sus descendientes,
|
|
13
|
+
* con el `descendantsOf` del config. Es la forma correcta del `NOT IN`;
|
|
14
|
+
* restar solo los scopes con deny dejaría dentro sus subárboles.
|
|
15
|
+
*/
|
|
16
|
+
export declare function expandExcludedSubtrees(view: AuthorizationView, excluded: ExcludedSubtree[]): Promise<ScopeRef[]>;
|
|
17
|
+
/** Cotas por defecto de `authorizedScopes` (config `scopes.maxScopes` / `scopes.maxDescendants`). */
|
|
18
|
+
export declare const DEFAULT_MAX_SCOPES = 1000;
|
|
19
|
+
export declare const DEFAULT_MAX_DESCENDANTS = 10000;
|
|
20
|
+
/**
|
|
21
|
+
* Tope sano de `maxScopes`/`maxDescendants` (2.5-B, auditor ⚪6): por encima
|
|
22
|
+
* de ~4,29e9 el hint `SET_VAR(cte_max_recursion_depth)` de MySQL sale de
|
|
23
|
+
* rango y un ciclo en la tabla deja de ser el 422 «posible ciclo» del
|
|
24
|
+
* contrato (503); y ya con 1e6 un ciclo cuesta segundos de CPU por llamada.
|
|
25
|
+
* Una cota mayor es config rota (500), nunca una pregunta.
|
|
26
|
+
*/
|
|
27
|
+
export declare const MAX_SCOPE_BOUND = 10000000;
|
|
28
|
+
/** Vida por defecto de una vista de `forRequest()` para LEER (F9): un request, no un módulo. */
|
|
29
|
+
export declare const DEFAULT_VIEW_MAX_AGE_MS = 30000;
|
|
30
|
+
export interface ForRequestOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Milisegundos durante los que la vista puede LEER (default 30 000).
|
|
33
|
+
* Después, cualquier lectura es 500 `E_AUTHZ_VIEW_EXPIRED`: el memo de
|
|
34
|
+
* ancestros solo es correcto mientras dura el request y una vista guardada
|
|
35
|
+
* por error serviría la cadena vieja para siempre. `0` = sin límite, a
|
|
36
|
+
* sabiendas. Las escrituras e `isWithin` no caducan (resuelven en fresco).
|
|
37
|
+
* Se mide con un reloj MONÓTONO (`performance.now()`, 2E · H3): un salto
|
|
38
|
+
* del reloj de pared hacia atrás no resucita una vista caducada.
|
|
39
|
+
*/
|
|
40
|
+
maxAgeMs?: number;
|
|
41
|
+
/**
|
|
42
|
+
* SOLO TESTS: fuente del reloj monótono, en ms (default `performance.now`).
|
|
43
|
+
* Sirve para fijar la frontera exacta de `maxAgeMs` sin dormir; en
|
|
44
|
+
* producción no se toca.
|
|
45
|
+
*/
|
|
46
|
+
now?: () => number;
|
|
47
|
+
}
|
|
3
48
|
/**
|
|
4
49
|
* Manager de autorización — la fachada que usan middleware, services y
|
|
5
50
|
* seeders. Resuelve el driver activo del config y notifica cada escritura
|
|
@@ -12,18 +57,191 @@ import type { AuthorizationDriver, GrantOptions, ScopeRef, ScopeType, SubjectRef
|
|
|
12
57
|
export declare class AuthorizationManager {
|
|
13
58
|
#private;
|
|
14
59
|
constructor(config: AuthorizationConfig);
|
|
60
|
+
/**
|
|
61
|
+
* Vista por request (2A/A3): las LECTURAS (`authorize`, `hasRole`, `list*`)
|
|
62
|
+
* resuelven ancestros con `memoizeAncestors(config.scopes.resolveChain)`
|
|
63
|
+
* —una llamada al árbol por scope durante la vida de la vista—; las
|
|
64
|
+
* ESCRITURAS (`grant`, `revoke`, `deny`, `removeDeny`, `scopes.*`) siguen
|
|
65
|
+
* resolviendo en fresco, porque una lectura obsoleta caduca sola y un
|
|
66
|
+
* grant sobre una cadena que ya cambió queda escrito para siempre (auditor
|
|
67
|
+
* C3/E3). El memo es de ANCESTROS, nunca de decisiones: un deny escrito
|
|
68
|
+
* entre dos `authorize` de la misma vista cambia la segunda respuesta.
|
|
69
|
+
*
|
|
70
|
+
* Patrón en Adonis: un middleware hace `ctx.authz = authorization.forRequest()`
|
|
71
|
+
* y controladores y policies leen de `ctx.authz`. Sin `AsyncLocalStorage`:
|
|
72
|
+
* la vista es un objeto explícito con la vida que le des. Sin
|
|
73
|
+
* `config.scopes.resolveChain`, o con un driver de terceros sin
|
|
74
|
+
* `withChainResolver`, la vista lee con el driver tal cual (sin memo)
|
|
75
|
+
* y sigue siendo correcta.
|
|
76
|
+
*/
|
|
77
|
+
forRequest(options?: ForRequestOptions): AuthorizationView;
|
|
78
|
+
/**
|
|
79
|
+
* El driver activo, TAL CUAL. Es la salida explícita de las barreras del
|
|
80
|
+
* manager (2D · G4, auditor 8): lo que escribas por aquí no pasa por
|
|
81
|
+
* `actor`/`requireActor`, `within`/`requireWithin` ni `onWrite`, y lo que
|
|
82
|
+
* leas no pasa por el memo de ancestros. Está pensado para el código de
|
|
83
|
+
* PLATAFORMA (seeders, comandos, la escritura en la raíz con
|
|
84
|
+
* `requireWithin: 'non-root'`) y para tests; un call-site de tenant nunca
|
|
85
|
+
* debería llamarlo. No se ofrece nada más por aquí a propósito.
|
|
86
|
+
*
|
|
87
|
+
* Lo único que el manager le aplica al resolverlo es el reloj del config
|
|
88
|
+
* (`clock`, 2.5 · J1) vía `withClock`: no es una barrera, es la hora con
|
|
89
|
+
* la que el driver decide, y vale igual para la plataforma, los tests y
|
|
90
|
+
* cada vista de `forRequest()` (todas leen el driver del padre). Un driver
|
|
91
|
+
* sin `withClock` con `clock` declarado es 500 `E_AUTHZ_CONFIG`.
|
|
92
|
+
*/
|
|
15
93
|
driver(): Promise<AuthorizationDriver>;
|
|
16
94
|
/** Solo tests: fuerza re-resolución del driver. */
|
|
17
95
|
clearCachedDriver(): void;
|
|
96
|
+
/**
|
|
97
|
+
* El árbol de scopes es un hecho del contrato: el consumidor notifica sus
|
|
98
|
+
* cambios aquí, en TODOS los drivers, y el PAQUETE valida antes de tocar
|
|
99
|
+
* el driver — la raíz no cuelga de nada, el padre tiene que existir y no
|
|
100
|
+
* puede haber ciclos. FGA acepta un ciclo de `parent` y lo evalúa (un grant
|
|
101
|
+
* en cualquier nodo concede en la raíz, S2), así que la barrera es esta.
|
|
102
|
+
* Espía: si la validación falla, cero llamadas al driver.
|
|
103
|
+
*/
|
|
104
|
+
readonly scopes: {
|
|
105
|
+
attached: (child: ScopeRef, parent: ScopeRef, options?: ScopedWriteOptions) => Promise<void>;
|
|
106
|
+
moved: (child: ScopeRef, newParent: ScopeRef, options?: ScopedWriteOptions) => Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Hechos primero (el driver demuestra cero o lanza), arista después
|
|
109
|
+
* (S6): si la purga muere a medias, el subárbol sigue colgado y los
|
|
110
|
+
* denies heredados siguen valiendo. Sin `within` no comprueba que el
|
|
111
|
+
* scope exista (el consumidor puede haber borrado ya su fila); con
|
|
112
|
+
* `within` (2D · F2) el hijo tiene que seguir en el árbol para
|
|
113
|
+
* contrastar su cadena: purga ANTES de borrar la fila.
|
|
114
|
+
*/
|
|
115
|
+
detached: (child: ScopeRef, options?: ScopedWriteOptions) => Promise<ScopeDetachOutcome>;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* ¿`outer` contiene a `inner`? = `outer ∈ chain(inner)`, inclusive: un scope
|
|
119
|
+
* se contiene a sí mismo y `APP_SCOPE` contiene todo. Un `inner` que el
|
|
120
|
+
* árbol no conoce no está dentro de nada (`false`). Siempre con el resolutor
|
|
121
|
+
* fresco (nunca el memo por request): la contención decide escrituras.
|
|
122
|
+
*/
|
|
123
|
+
isWithin(inner: ScopeRef, outer: ScopeRef): Promise<boolean>;
|
|
18
124
|
authorize(subject: SubjectRef, permission: string, scope: ScopeRef): Promise<boolean>;
|
|
19
|
-
hasRole(subject: SubjectRef, role:
|
|
20
|
-
|
|
125
|
+
hasRole(subject: SubjectRef, role: RoleQuery, scope: ScopeRef): Promise<boolean>;
|
|
126
|
+
/**
|
|
127
|
+
* `authorize` sobre varios scopes, un booleano por posición (2.1, B6).
|
|
128
|
+
* Delegado al driver si trae `authorizeMany` (openfga: un batchCheck);
|
|
129
|
+
* si no, `Promise.all` de `authorize` sobre una vista con los ancestros
|
|
130
|
+
* memoizados (una llamada al árbol por scope distinto, aunque se repita).
|
|
131
|
+
* Idéntico a N `authorize`: duplicados por posición, desconocido ⇒ false,
|
|
132
|
+
* y si una posición no se puede responder, lanza entero. Vacío ⇒ `[]`
|
|
133
|
+
* sin tocar backend ni árbol.
|
|
134
|
+
*/
|
|
135
|
+
authorizeMany(subject: SubjectRef, permission: string, scopes: ScopeRef[]): Promise<boolean[]>;
|
|
136
|
+
/** Holders con asignación vigente del rol en ese scope exacto. `{ uuid }` es la forma exacta (3D · M1). */
|
|
137
|
+
listSubjects(role: RoleQuery, scope: ScopeRef): Promise<SubjectRef[]>;
|
|
21
138
|
listScopes(subject: SubjectRef, permission: string): Promise<ScopeRef[]>;
|
|
22
139
|
listRoles(subject: SubjectRef, scope: ScopeRef): Promise<string[]>;
|
|
23
140
|
listRoleScopes(subject: SubjectRef, scopeType: ScopeType): Promise<ScopeRef[]>;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
141
|
+
/** Denies directos del holder (scope exacto, o todos). 500 `E_AUTHZ_UNSUPPORTED` si el driver no lo implementa. */
|
|
142
|
+
listDenies(subject: SubjectRef, scope?: ScopeRef): Promise<DenyRef[]>;
|
|
143
|
+
/**
|
|
144
|
+
* Permisos efectivos del holder en un scope (2.1, B5): la unión de lo que
|
|
145
|
+
* conceden sus roles vigentes en toda la cadena (`listRoles` por nivel +
|
|
146
|
+
* catálogo) MENOS lo denegado en cualquier nivel de la cadena
|
|
147
|
+
* (`listDenies` por nivel). Es exactamente el conjunto `{ p | authorize(p) }`,
|
|
148
|
+
* calculado sin preguntar permiso a permiso. Scope desconocido ⇒ `[]`.
|
|
149
|
+
* Prerrequisito de `catalog/` (Fase 3).
|
|
150
|
+
*/
|
|
151
|
+
effectivePermissions(subject: SubjectRef, scope: ScopeRef): Promise<string[]>;
|
|
152
|
+
/**
|
|
153
|
+
* Define un rol LOCAL a `ownerScope`. Policy, en este orden y antes de
|
|
154
|
+
* escribir nada: `actor` obligatorio y bien formado; `ownerScope` válido,
|
|
155
|
+
* no la raíz (los roles de la raíz son globales: config + sync) y conocido
|
|
156
|
+
* por el árbol (fresco); `spec` bien formado (slug, nivel ≠ `app`, rank
|
|
157
|
+
* entero, permisos); cada permiso en `config.delegablePermissions`, en el
|
|
158
|
+
* catálogo, componible en ese nivel (`assignableAt`, B5) y EFECTIVO para
|
|
159
|
+
* el actor en el owner (lo concede un rol suyo de la cadena y no lo tiene
|
|
160
|
+
* denegado en ella — C2); `0 < rank < min(rank del actor, rank máximo
|
|
161
|
+
* global)`; y ningún rol `(slug, scopeType)` visible en el owner (global,
|
|
162
|
+
* o local a un ancestro) ni local a un descendiente (colisión, 422
|
|
163
|
+
* `E_AUTHZ_CATALOG_CONFLICT`, re-comprobada dentro de la transacción
|
|
164
|
+
* serializada — 3D · M2). `options.within` contiene la escritura contra el
|
|
165
|
+
* OWNER y `requireWithin` la exige, como en las otras ocho (3D · M3).
|
|
166
|
+
* Devuelve el rol y notifica `role_defined`.
|
|
167
|
+
*/
|
|
168
|
+
defineScopedRole(actor: SubjectRef, ownerScope: ScopeRef, spec: ScopedRoleSpec, options?: ScopedWriteOptions): Promise<CatalogRole>;
|
|
169
|
+
/**
|
|
170
|
+
* Cambia `name`/`description`/`rank`/`permissions` de un rol LOCAL (nunca
|
|
171
|
+
* su slug, nivel ni owner). Un global es 422 `E_AUTHZ_ROLE_IMMUTABLE`. El
|
|
172
|
+
* actor tiene que tener, en el owner del rol, rank MAYOR que el del rol
|
|
173
|
+
* (no se toca un rol de rango ≥ al propio) y la misma policy que al
|
|
174
|
+
* definir para lo que cambia: los permisos nuevos delegables/efectivos y
|
|
175
|
+
* componibles, el rank nuevo por debajo del suyo. Sin cambios reales no
|
|
176
|
+
* escribe ni notifica (idempotente). Notifica `role_updated`.
|
|
177
|
+
*/
|
|
178
|
+
updateScopedRole(actor: SubjectRef, roleUuid: string, changes: ScopedRoleChanges, options?: ScopedWriteOptions): Promise<CatalogRole>;
|
|
179
|
+
/**
|
|
180
|
+
* Purga un rol LOCAL: sus asignaciones en todos los scopes, sus vínculos y
|
|
181
|
+
* el rol (`driver.purgeRole`, B4; 500 `E_AUTHZ_UNSUPPORTED` en un driver
|
|
182
|
+
* que no lo trae, sin tocar nada). Un global es 422
|
|
183
|
+
* `E_AUTHZ_ROLE_IMMUTABLE`; el actor necesita rank MAYOR que el del rol en
|
|
184
|
+
* su owner. Notifica `role_purged`. No necesita `listDenies`.
|
|
185
|
+
*/
|
|
186
|
+
deleteScopedRole(actor: SubjectRef, roleUuid: string, options?: ScopedWriteOptions): Promise<void>;
|
|
187
|
+
/**
|
|
188
|
+
* Asigna un rol al holder en un scope. `role` es un `RoleQuery` (3D · M1):
|
|
189
|
+
* un slug, `{ slug, scopeType }` o `{ uuid }` — esta última es la forma
|
|
190
|
+
* exacta, la única que responde cuando dos roles locales homónimos son
|
|
191
|
+
* visibles en la misma cadena (las otras dos son 422
|
|
192
|
+
* `E_AUTHZ_AMBIGUOUS_ROLE`, nunca «el más cercano gana»).
|
|
193
|
+
*/
|
|
194
|
+
grant(subject: SubjectRef, role: RoleQuery, scope: ScopeRef, options?: GrantOptions): Promise<GrantOutcome>;
|
|
195
|
+
/**
|
|
196
|
+
* Quita la asignación del rol en ese scope exacto. Por slug se quitan las
|
|
197
|
+
* de TODOS los homónimos `(slug, nivel)` (3B; quitar nunca concede, y el
|
|
198
|
+
* scope puede no existir ya para el árbol); por `{ uuid }`, solo la de ese
|
|
199
|
+
* rol.
|
|
200
|
+
*/
|
|
201
|
+
revoke(subject: SubjectRef, role: RoleQuery, scope: ScopeRef, options?: ScopedWriteOptions): Promise<void>;
|
|
202
|
+
deny(subject: SubjectRef, permission: string, scope: ScopeRef, options?: DenyOptions): Promise<void>;
|
|
203
|
+
removeDeny(subject: SubjectRef, permission: string, scope: ScopeRef, options?: ScopedWriteOptions): Promise<void>;
|
|
204
|
+
/**
|
|
205
|
+
* Scopes de un tipo donde el holder tiene el permiso (2.1, B3). La ÚNICA
|
|
206
|
+
* API del paquete que enumera descendientes — excepción explícita al
|
|
207
|
+
* invariante 7 (`list*` siguen siendo directos) — y lo hace con el
|
|
208
|
+
* `descendantsOf` del consumidor, nunca con N+1 `resolveChain` a ciegas.
|
|
209
|
+
*
|
|
210
|
+
* Regla:
|
|
211
|
+
* 1. `listScopes(subject, permission)`: los scopes DIRECTOS que conceden,
|
|
212
|
+
* ya sin los bloqueados por un deny en su cadena y sin los que el árbol
|
|
213
|
+
* no conoce. Vacío ⇒ `none`.
|
|
214
|
+
* 2. Si la raíz está entre ellos ⇒ `all`, con `excludedSubtrees` = todos
|
|
215
|
+
* los scopes con deny vivo del permiso (`listDenies`), como subárboles
|
|
216
|
+
* (F10). Nunca `all` sin esa lista (juez cruce 5): un deny vivo tiene
|
|
217
|
+
* que verse.
|
|
218
|
+
* 3. Si no: candidatos = directos ∪ sus descendientes (`descendantsOf`).
|
|
219
|
+
* Cada candidato se contrasta con `resolveChain` (memoizado por
|
|
220
|
+
* request, F3): su cadena tiene que contener el scope concedente —si
|
|
221
|
+
* no, los dos resolutores del consumidor describen árboles distintos y
|
|
222
|
+
* se lanza 503 `E_AUTHZ_RESOLVER_FAILED`, nunca una lista con cruces—
|
|
223
|
+
* y no puede contener un scope denegado (es EXACTAMENTE la regla de
|
|
224
|
+
* `authorize`: deny en la cadena ⇒ false). Se filtran por `scopeType`.
|
|
225
|
+
* 4. Más de `maxScopes` ⇒ 422 `E_AUTHZ_TOO_MANY_SCOPES`, nunca parcial, y
|
|
226
|
+
* se corta en cuanto se sabe (F8): los directos del tipo antes de bajar
|
|
227
|
+
* y el conteo del tipo dentro del bucle. `options.maxScopes` solo puede
|
|
228
|
+
* BAJAR la cota del config.
|
|
229
|
+
* Sin `scopes.descendantsOf` ⇒ 500 `E_AUTHZ_NO_DESCENDANTS_RESOLVER`
|
|
230
|
+
* (antes de mirar nada: un `none` sin árbol sería mentira).
|
|
231
|
+
*/
|
|
232
|
+
authorizedScopes(subject: SubjectRef, permission: string, scopeType: ScopeType, options?: {
|
|
233
|
+
maxScopes?: number;
|
|
234
|
+
}): Promise<AuthorizedScopes>;
|
|
235
|
+
/**
|
|
236
|
+
* Los `excludedSubtrees` de un `all` (F10) expandidos: cada scope denegado
|
|
237
|
+
* y todos sus descendientes, con el `descendantsOf` del config. Un scope
|
|
238
|
+
* que `descendantsOf` no conoce (`null`) es 503: restarlo a medias
|
|
239
|
+
* dejaría su subárbol dentro (fail-open). Cotas: `maxDescendants` por
|
|
240
|
+
* subárbol y `maxScopes` (config o por llamada, nunca por encima del
|
|
241
|
+
* config) sobre el total ⇒ 422, nunca parcial.
|
|
242
|
+
*/
|
|
243
|
+
expandExcludedSubtrees(excluded: ExcludedSubtree[], options?: {
|
|
244
|
+
maxScopes?: number;
|
|
245
|
+
}): Promise<ScopeRef[]>;
|
|
28
246
|
}
|
|
29
247
|
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"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"}
|