@spinajs/rbac 2.0.522 → 2.0.523

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.
Files changed (47) hide show
  1. package/lib/cjs/actions.d.ts.map +1 -1
  2. package/lib/cjs/actions.js.map +1 -1
  3. package/lib/cjs/index.d.ts +2 -0
  4. package/lib/cjs/index.d.ts.map +1 -1
  5. package/lib/cjs/index.js +2 -0
  6. package/lib/cjs/index.js.map +1 -1
  7. package/lib/cjs/interfaces.d.ts +0 -24
  8. package/lib/cjs/interfaces.d.ts.map +1 -1
  9. package/lib/cjs/interfaces.js +1 -5
  10. package/lib/cjs/interfaces.js.map +1 -1
  11. package/lib/cjs/middleware.d.ts +16 -6
  12. package/lib/cjs/middleware.d.ts.map +1 -1
  13. package/lib/cjs/middleware.js +151 -90
  14. package/lib/cjs/middleware.js.map +1 -1
  15. package/lib/cjs/orm-permission.d.ts +77 -0
  16. package/lib/cjs/orm-permission.d.ts.map +1 -0
  17. package/lib/cjs/orm-permission.js +128 -0
  18. package/lib/cjs/orm-permission.js.map +1 -0
  19. package/lib/cjs/permission-service.d.ts +80 -0
  20. package/lib/cjs/permission-service.d.ts.map +1 -0
  21. package/lib/cjs/permission-service.js +144 -0
  22. package/lib/cjs/permission-service.js.map +1 -0
  23. package/lib/mjs/actions.d.ts.map +1 -1
  24. package/lib/mjs/actions.js.map +1 -1
  25. package/lib/mjs/index.d.ts +2 -0
  26. package/lib/mjs/index.d.ts.map +1 -1
  27. package/lib/mjs/index.js +2 -0
  28. package/lib/mjs/index.js.map +1 -1
  29. package/lib/mjs/interfaces.d.ts +0 -24
  30. package/lib/mjs/interfaces.d.ts.map +1 -1
  31. package/lib/mjs/interfaces.js +0 -4
  32. package/lib/mjs/interfaces.js.map +1 -1
  33. package/lib/mjs/middleware.d.ts +16 -6
  34. package/lib/mjs/middleware.d.ts.map +1 -1
  35. package/lib/mjs/middleware.js +152 -91
  36. package/lib/mjs/middleware.js.map +1 -1
  37. package/lib/mjs/orm-permission.d.ts +77 -0
  38. package/lib/mjs/orm-permission.d.ts.map +1 -0
  39. package/lib/mjs/orm-permission.js +119 -0
  40. package/lib/mjs/orm-permission.js.map +1 -0
  41. package/lib/mjs/permission-service.d.ts +80 -0
  42. package/lib/mjs/permission-service.d.ts.map +1 -0
  43. package/lib/mjs/permission-service.js +137 -0
  44. package/lib/mjs/permission-service.js.map +1 -0
  45. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  46. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  47. package/package.json +11 -11
@@ -7,16 +7,15 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- import { Autoinject, DI, Injectable } from '@spinajs/di';
10
+ import { DI, Injectable } from '@spinajs/di';
11
11
  import { DeleteQueryBuilder, extractModelDescriptor, InsertQueryBuilder, OrmException, QueryMiddleware, SelectQueryBuilder, UpdateQueryBuilder } from '@spinajs/orm';
12
12
  import { AsyncLocalStorage } from 'async_hooks';
13
- import { RBAC_HOOK_FALLBACK } from './interfaces.js';
14
- import { AccessControl } from 'accesscontrol';
15
13
  import { Forbidden } from '@spinajs/exceptions';
16
14
  import { Log, Logger } from '@spinajs/log-common';
15
+ import { DEFAULT_PERMISSION_SCOPE, getOrCreatePolicyMap, ormPermissionModel, OrmPermissionPolicy, PERMISSION_SCOPE_ATTR_PREFIX, policyMapKey } from './orm-permission.js';
16
+ import { effectiveRoles, probeGrant } from './permission-service.js';
17
17
  /**
18
- * Which permission scopes a builder type is checked against, and which per-operation
19
- * model hook it looks for.
18
+ * Which permission scopes a builder type is checked against.
20
19
  *
21
20
  * Keyed on the CONSTRUCTOR, not on `constructor.name`. A name-keyed lookup breaks under
22
21
  * minification and silently yields "no mapping" — for a security check that means an
@@ -25,14 +24,13 @@ import { Log, Logger } from '@spinajs/log-common';
25
24
  * `InsertQueryBuilder` was missing here while `PERMISSION_SCOPE_TO_QUERY` claimed to
26
25
  * support `createOwn`/`createAny`, so the insert branch of the middleware could only ever
27
26
  * have thrown a TypeError. The inverse map below is now DERIVED from this one, so the two
28
- * cannot drift apart again — and the hook name lives here for the same reason, so a hook
29
- * can never be paired with the wrong builder type.
27
+ * cannot drift apart again.
30
28
  */
31
29
  const QUERY_TO_PERMISSION = new Map([
32
- [DeleteQueryBuilder, { own: 'deleteOwn', all: 'deleteAny', hook: 'rbacDelete' }],
33
- [UpdateQueryBuilder, { own: 'updateOwn', all: 'updateAny', hook: 'rbacUpdate' }],
34
- [SelectQueryBuilder, { own: 'readOwn', all: 'readAny', hook: 'rbacRead' }],
35
- [InsertQueryBuilder, { own: 'createOwn', all: 'createAny', hook: 'rbacCreate' }],
30
+ [DeleteQueryBuilder, { own: 'deleteOwn', all: 'deleteAny' }],
31
+ [UpdateQueryBuilder, { own: 'updateOwn', all: 'updateAny' }],
32
+ [SelectQueryBuilder, { own: 'readOwn', all: 'readAny' }],
33
+ [InsertQueryBuilder, { own: 'createOwn', all: 'createAny' }],
36
34
  ]);
37
35
  /** Derived inverse of {@link QUERY_TO_PERMISSION}. Never hand-maintained. */
38
36
  const PERMISSION_SCOPE_TO_QUERY = new Map();
@@ -53,32 +51,60 @@ function permissionsFor(builder) {
53
51
  return undefined;
54
52
  }
55
53
  /**
56
- * The custom rbac constraint `model` declares for this operation, or `undefined` when it
57
- * declares none and the caller should fall through to `OwnerField`.
58
- *
59
- * Resolution is specific-then-generic: `rbacDelete` beats `rbac` on a delete, and a model
60
- * declaring only `rbac` keeps its pre-split behaviour on every operation. Statics resolve
61
- * through the prototype chain, so a subclass inherits whichever hooks it does not override.
62
- *
63
- * `allowFallback` is false for INSERT only. `rbac` has always been called on builders that
64
- * have a WHERE clause, so every implementation in the wild is where-shaped —
65
- * `ContentEntries.rbac` and `EntriesGroup.rbac` both call `whereExist`, which
66
- * `InsertQueryBuilder` does not define. Falling back there would turn a silent gap into a
67
- * crash on every insert for every model already using the feature. Insert-time control is
68
- * opt-in via an explicit `rbacCreate`.
54
+ * Steps from `model` up its prototype (class inheritance) chain to `boundModel`, or
55
+ * `undefined` if `boundModel` is not `model` itself or an ancestor. ES class inheritance
56
+ * puts the parent constructor at `Object.getPrototypeOf(Child)`, so walking constructors —
57
+ * not instances is the correct way to test "is a subclass of".
58
+ */
59
+ function distanceTo(model, boundModel) {
60
+ let current = model;
61
+ for (let distance = 0; current; distance++) {
62
+ if (current === boundModel) {
63
+ return distance;
64
+ }
65
+ current = Object.getPrototypeOf(current);
66
+ }
67
+ return undefined;
68
+ }
69
+ /**
70
+ * Picks the policy bound to `model` itself or the closest bound ancestor. Two unrelated
71
+ * models can share one resource+scope key on purpose (CampaignFileAttachment /
72
+ * ArrowV1CampaignView) — the resource string alone cannot disambiguate them, so every
73
+ * candidate is checked against `model`'s actual prototype chain. When both an ancestor-bound
74
+ * and an exact-bound policy are registered, the most-derived (smallest distance) one wins.
69
75
  */
70
- function rbacHook(model, hook, allowFallback) {
71
- const statics = model;
72
- if (!statics) {
76
+ function selectPolicyClass(candidates, model) {
77
+ if (!candidates) {
73
78
  return undefined;
74
79
  }
75
- if (typeof statics[hook] === 'function') {
76
- return statics[hook];
80
+ let best;
81
+ let bestDistance = Infinity;
82
+ for (const candidate of candidates) {
83
+ const boundModel = ormPermissionModel(candidate);
84
+ if (!boundModel) {
85
+ continue;
86
+ }
87
+ const distance = distanceTo(model, boundModel);
88
+ if (distance !== undefined && distance < bestDistance) {
89
+ best = candidate;
90
+ bestDistance = distance;
91
+ }
77
92
  }
78
- if (allowFallback && typeof statics[RBAC_HOOK_FALLBACK] === 'function') {
79
- return statics[RBAC_HOOK_FALLBACK];
93
+ return best;
94
+ }
95
+ /** Fallback for models with `@ResourceOwner()` and no registered policy class. */
96
+ class OwnerFieldPolicy extends OrmPermissionPolicy {
97
+ constructor(ownerField) {
98
+ super();
99
+ this.ownerField = ownerField;
100
+ }
101
+ scope(query, user) {
102
+ query.andWhere(this.ownerField, user.PrimaryKeyValue);
103
+ }
104
+ async authorizeCreate(query, user) {
105
+ // Overwrite, never merge: a caller-supplied owner id is exactly the IDOR this closes.
106
+ query.forceColumn(this.ownerField, user.PrimaryKeyValue);
80
107
  }
81
- return undefined;
82
108
  }
83
109
  let RbacModelPermissionMiddleware = class RbacModelPermissionMiddleware extends QueryMiddleware {
84
110
  /**
@@ -103,26 +129,31 @@ let RbacModelPermissionMiddleware = class RbacModelPermissionMiddleware extends
103
129
  if (!canOwn) {
104
130
  throw new Forbidden(`User does not have permission to access ${resource}:${context.action} permission`);
105
131
  }
106
- /**
107
- * Model can take over insert-time ownership itself. No fallback to the generic `rbac`
108
- * here see {@link rbacHook}.
109
- *
110
- * Awaited: unlike the where-clause hooks, an insert rule usually cannot be decided from
111
- * the payload alone — "is this the caller's group?" is a lookup. Dropping the returned
112
- * promise would let the row land before the answer came back.
113
- */
114
- const rbacFunc = rbacHook(builder.Model, context.hook, false);
115
- if (rbacFunc) {
116
- this.Log.trace(`Applying custom ${context.hook} func for ${resource}`);
117
- await rbacFunc.call(builder, context.user);
118
- return;
119
- }
120
- if (!descriptor.OwnerField) {
121
- this.Log.error(`Model ${descriptor.Name} does not have OwnerField set, cannot apply :own permission`);
122
- throw new OrmException(`Model ${descriptor.Name} does not have OwnerField set, cannot apply :own permission`);
132
+ const policies = this.policiesFor(context.roles, resource, context.ownScope, descriptor, builder.Model);
133
+ // A candidate that does not opt into insert control denies by default (see
134
+ // OrmPermissionPolicy.authorizeCreate). Pre-refactor, a model with no rbacCreate static
135
+ // but an OwnerField had its owner column stamped and the insert allowed — an unrelated
136
+ // policy registered only for scope() must not shadow that. Deny-by-default is kept when
137
+ // there is no OwnerField to fall back to.
138
+ const createPolicies = policies.map((policy) => {
139
+ const opensOwnCreate = policy.authorizeCreate !== OrmPermissionPolicy.prototype.authorizeCreate;
140
+ return !opensOwnCreate && descriptor.OwnerField ? new OwnerFieldPolicy(descriptor.OwnerField) : policy;
141
+ });
142
+ // Multiple distinct scopes OR-compose on inserts too: the insert is allowed if ANY
143
+ // granted role's policy authorizes it. Policies are tried in registration-set order;
144
+ // when every one denies, the last error propagates.
145
+ let lastError;
146
+ for (const policy of createPolicies) {
147
+ try {
148
+ this.Log.trace(`Applying authorizeCreate of ${policy.constructor.name} for ${resource}`);
149
+ await policy.authorizeCreate(builder, context.user);
150
+ return;
151
+ }
152
+ catch (err) {
153
+ lastError = err;
154
+ }
123
155
  }
124
- // Overwrite, never merge: a caller-supplied owner id is exactly the IDOR this closes.
125
- builder.forceColumn(descriptor.OwnerField, context.user.PrimaryKeyValue);
156
+ throw lastError;
126
157
  }
127
158
  afterQueryCreation(builder) {
128
159
  // Insert is handled at execution time; anything else without a WHERE clause to constrain
@@ -143,11 +174,6 @@ let RbacModelPermissionMiddleware = class RbacModelPermissionMiddleware extends
143
174
  throw new Forbidden(`User does not have permission to access ${resource}:${context.action} permission`);
144
175
  }
145
176
  this.Log.trace(`Resource ${resource}:own permission granted`);
146
- /**
147
- * Model can have a custom rbac permission check, either for this operation
148
- * specifically (`rbacRead` / `rbacUpdate` / `rbacDelete`) or generically (`rbac`).
149
- */
150
- const rbacFunc = rbacHook(builder.Model, context.hook, true);
151
177
  /**
152
178
  * `relationScope: 'join'` ( @OrmResource options ): when this model is populated as a
153
179
  * BelongsTo relation, its :own constraint folded into the parent WHERE would silently
@@ -158,31 +184,79 @@ let RbacModelPermissionMiddleware = class RbacModelPermissionMiddleware extends
158
184
  */
159
185
  const joinScoped = descriptor.RbacRelationScope === 'join' && builder instanceof SelectQueryBuilder;
160
186
  const user = context.user;
161
- if (rbacFunc) {
162
- this.Log.trace(`Applying custom ${context.hook} func for ${resource}`);
163
- if (joinScoped) {
164
- builder.whereOnJoin(function () {
165
- rbacFunc.call(builder, user);
166
- });
167
- }
168
- else {
169
- rbacFunc.call(builder, user);
187
+ const policies = this.policiesFor(context.roles, resource, context.ownScope, descriptor, builder.Model);
188
+ const method = builder instanceof UpdateQueryBuilder ? 'scopeUpdate' : builder instanceof DeleteQueryBuilder ? 'scopeDelete' : 'scopeRead';
189
+ const apply = (target) => {
190
+ if (policies.length === 1) {
191
+ policies[0][method](target, user);
192
+ return;
170
193
  }
171
- return;
172
- }
173
- if (!descriptor.OwnerField) {
174
- this.Log.error(`Model ${descriptor.Name} does not have OwnerField set or static rbac function, cannot apply :own permission`);
175
- throw new OrmException(`Model ${descriptor.Name} does not have OwnerField set, cannot apply :own permission`);
176
- }
177
- this.Log.trace(`Applying owner field restriction for ${resource}`);
194
+ // Distinct scopes across the caller's roles OR-compose: reachable if ANY admits.
195
+ target.andWhere(function () {
196
+ for (const policy of policies) {
197
+ this.orWhere(function () {
198
+ policy[method](this, user);
199
+ });
200
+ }
201
+ });
202
+ };
203
+ this.Log.trace(`Applying ${policies.length} permission ${policies.length === 1 ? 'policy' : 'policies'} (${method}) for ${resource}`);
178
204
  if (joinScoped) {
179
205
  builder.whereOnJoin(function () {
180
- builder.andWhere(descriptor.OwnerField, user.PrimaryKeyValue);
206
+ apply(builder);
181
207
  });
182
208
  }
183
209
  else {
184
- builder.andWhere(descriptor.OwnerField, user.PrimaryKeyValue);
210
+ apply(builder);
211
+ }
212
+ }
213
+ /**
214
+ * Policies to apply for this query: one per distinct scope name across the caller's
215
+ * granted roles. A role without the grant must not contribute a policy — that would
216
+ * WIDEN the OR-composition in `afterQueryCreation`. Multiple distinct scopes OR-compose
217
+ * downstream: permissions are additive, a row is reachable if any granted role's policy
218
+ * admits it.
219
+ */
220
+ policiesFor(roles, resource, ownScope, descriptor, model) {
221
+ const scopeNames = new Set();
222
+ for (const role of roles) {
223
+ // role unknown to accesscontrol answers null — contributes no grant, no scope
224
+ const permission = probeGrant([role], ownScope, resource);
225
+ if (!permission?.granted) {
226
+ continue;
227
+ }
228
+ const attrs = permission.attributes ?? [];
229
+ const tokens = attrs.filter((a) => typeof a === 'string' && a.startsWith(PERMISSION_SCOPE_ATTR_PREFIX)).map((a) => a.slice(PERMISSION_SCOPE_ATTR_PREFIX.length));
230
+ if (tokens.length === 0) {
231
+ scopeNames.add(DEFAULT_PERMISSION_SCOPE);
232
+ }
233
+ else {
234
+ tokens.forEach((t) => scopeNames.add(t));
235
+ }
236
+ }
237
+ // canOwn was computed over the role union; per-role queries can still all miss when
238
+ // grants come from odd extension shapes. Degrade to the default scope — resolution
239
+ // below still fails loud if nothing is registered.
240
+ if (scopeNames.size === 0) {
241
+ scopeNames.add(DEFAULT_PERMISSION_SCOPE);
185
242
  }
243
+ const registered = getOrCreatePolicyMap();
244
+ const policies = [];
245
+ for (const name of scopeNames) {
246
+ const candidates = registered.get(policyMapKey(resource, name));
247
+ const policyClass = selectPolicyClass(candidates, model);
248
+ if (policyClass) {
249
+ policies.push(DI.resolve(policyClass));
250
+ continue;
251
+ }
252
+ if (name === DEFAULT_PERMISSION_SCOPE && descriptor.OwnerField) {
253
+ policies.push(new OwnerFieldPolicy(descriptor.OwnerField));
254
+ continue;
255
+ }
256
+ this.Log.error(`No OrmPermissionPolicy registered for ${descriptor.Name}/${name} and no OwnerField fallback`);
257
+ throw new OrmException(`no OrmPermissionPolicy registered for model ${descriptor.Name} scope '${name}' and no OwnerField fallback — refusing to run an unscoped :own query`);
258
+ }
259
+ return policies;
186
260
  }
187
261
  /**
188
262
  * Everything both hooks need, or `undefined` when this query is not subject to a check.
@@ -230,32 +304,19 @@ let RbacModelPermissionMiddleware = class RbacModelPermissionMiddleware extends
230
304
  }
231
305
  const ownScope = storage.PermissionScope ?? scopes.own;
232
306
  const anyScope = storage.PermissionScope ?? scopes.all;
233
- const roles = storage.ActiveRole ? [storage.ActiveRole] : storage.User.Role;
234
- let canAny = false;
235
- let canOwn = false;
236
- try {
237
- canAny = this.Ac.can(roles)[anyScope](resource).granted;
238
- canOwn = this.Ac.can(roles)[ownScope](resource).granted;
239
- }
240
- catch (err) {
241
- // accesscontrol throws eg. "Role not found" when role has no grants registered
242
- // treat as no permission so caller gets Forbidden instead of library error
243
- this.Log.trace(`Permission check for roles ${roles} on resource ${resource} failed: ${err.message}, treating as no permission`);
244
- }
307
+ const roles = effectiveRoles(storage.User, storage);
308
+ const canAny = probeGrant(roles, anyScope, resource)?.granted ?? false;
309
+ const canOwn = probeGrant(roles, ownScope, resource)?.granted ?? false;
245
310
  // 'readOwn' -> 'read'. Keeps the Forbidden message accurate per builder type instead of
246
311
  // the old hard-coded ':read', which was wrong for updates and deletes.
247
312
  const action = anyScope.replace(/(Any|Own)$/, '');
248
- return { descriptor, resource, canOwn, canAny, action, hook: scopes.hook, user: storage.User };
313
+ return { descriptor, resource, canOwn, canAny, action, user: storage.User, roles, ownScope };
249
314
  }
250
315
  };
251
316
  __decorate([
252
317
  Logger('RBAC'),
253
318
  __metadata("design:type", Log)
254
319
  ], RbacModelPermissionMiddleware.prototype, "Log", void 0);
255
- __decorate([
256
- Autoinject(),
257
- __metadata("design:type", AccessControl)
258
- ], RbacModelPermissionMiddleware.prototype, "Ac", void 0);
259
320
  RbacModelPermissionMiddleware = __decorate([
260
321
  Injectable(QueryMiddleware)
261
322
  ], RbacModelPermissionMiddleware);
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { Class } from '@spinajs/di';
2
+ import { InsertQueryBuilder, IWhereBuilder, ModelBase } from '@spinajs/orm';
3
+ import type { User } from './models/User.js';
4
+ export declare const DEFAULT_PERMISSION_SCOPE = "default";
5
+ /**
6
+ * Attribute prefix marking a named permission scope on a role grant (eg. `'scope:pool'`),
7
+ * read by `RbacModelPermissionMiddleware.policiesFor()` to pick a non-default
8
+ * `OrmPermissionPolicy`.
9
+ *
10
+ * WARNING: `accesscontrol`'s attribute union across a role and every role it `$extend`s
11
+ * collapses `['*']` merged with `['scope:x']` down to `['*']` (glob union absorption). A role
12
+ * granting `read:own: ['scope:pool']` while a role it `$extend`s (or that extends it) grants
13
+ * the same resource `['*']` silently loses the `scope:pool` token, and resolution falls
14
+ * through to the DEFAULT policy instead of the named one. This is a known limitation, not
15
+ * handled by this module — never mix `['*']` and `scope:` attributes for the SAME resource
16
+ * across an `$extend` chain.
17
+ */
18
+ export declare const PERMISSION_SCOPE_ATTR_PREFIX = "scope:";
19
+ export declare const ORM_PERMISSION_POLICY_MAP = "__orm_permission_policy__";
20
+ /**
21
+ * Bound model recorded on a policy class by `@OrmPermission`. Needed because the map is
22
+ * keyed on the shared resource STRING (minification-safe), which two unrelated models can
23
+ * legally share for grant purposes — the model recorded here is what lets `policiesFor()`
24
+ * in middleware.ts pick the right policy for `builder.Model` instead of an arbitrary one.
25
+ */
26
+ export declare const ORM_PERMISSION_MODEL: unique symbol;
27
+ /**
28
+ * Keyed on the DECLARED `@OrmResource` string, never on `constructor.name` — grants are
29
+ * keyed on the same string, so a model's resource name is the single permission identity
30
+ * everywhere, and models sharing a resource (a view over the base table) share policies.
31
+ */
32
+ export declare function policyMapKey(resource: string, scope: string): string;
33
+ export declare abstract class OrmPermissionPolicy<M extends ModelBase<unknown> = ModelBase<unknown>> {
34
+ /**
35
+ * Default throws so an accidentally inert policy fails loud instead of running an
36
+ * unscoped query.
37
+ */
38
+ scope(_query: IWhereBuilder<M>, _user: User): void;
39
+ scopeRead(query: IWhereBuilder<M>, user: User): void;
40
+ scopeUpdate(query: IWhereBuilder<M>, user: User): void;
41
+ scopeDelete(query: IWhereBuilder<M>, user: User): void;
42
+ /**
43
+ * Default denies: a policy that does not opt into insert control must not silently
44
+ * allow inserts under a `:own` grant. An authorization denial, not a config error, so
45
+ * `Forbidden` (403) — contrast `scope()`'s default, which stays `OrmException` because an
46
+ * unimplemented scope is a config bug. Callers with an `OwnerField` never reach this: see
47
+ * `RbacModelPermissionMiddleware.beforeQueryExecution`'s OwnerField fallback.
48
+ */
49
+ authorizeCreate(_query: InsertQueryBuilder, _user: User): Promise<void>;
50
+ }
51
+ export type OrmPermissionPolicyClass = Class<OrmPermissionPolicy>;
52
+ /** The model `@OrmPermission` bound `policy` to, or `undefined` for a policy built by hand
53
+ * (eg. the `OwnerFieldPolicy` fallback) that never went through the decorator.
54
+ *
55
+ * Read as an OWN property: `target[ORM_PERMISSION_MODEL] = model` stamps the constructor
56
+ * object itself, and ES class inheritance chains constructors ( `Sub.__proto__ === Base` ), so
57
+ * a plain property read here would let an undecorated `class Sub extends Base {}` silently
58
+ * inherit `Base`'s bound model instead of having none.
59
+ */
60
+ export declare function ormPermissionModel(policy: OrmPermissionPolicyClass): Class<ModelBase<unknown>> | undefined;
61
+ /**
62
+ * The single accessor for the policy map — used by both the registration side
63
+ * (`OrmPermission`) and the resolution side (`RbacModelPermissionMiddleware.policiesFor`) so
64
+ * the two can never read/write through differing DI cache accessors and drift apart.
65
+ */
66
+ export declare function getOrCreatePolicyMap(): Map<string, OrmPermissionPolicyClass[]>;
67
+ /**
68
+ * Registers `target` as a policy for `model`'s resource + `scope` in the DI hashmap.
69
+ * Refuses a model without `@OrmResource` (cannot be permission-guarded). The map value is a
70
+ * LIST: two unrelated models are allowed to share one resource+scope key (the
71
+ * CampaignFileAttachment / ArrowV1CampaignView shape) — only the same (model, scope) pair
72
+ * registered twice is a duplicate/config bug.
73
+ */
74
+ export declare function OrmPermission<M extends ModelBase<unknown>>(model: Class<M>, scope?: string): (target: Class<OrmPermissionPolicy<M>>) => void;
75
+ /** Test helper — wipes all registrations from the DI cache. */
76
+ export declare function clearOrmPermissionRegistry(): void;
77
+ //# sourceMappingURL=orm-permission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orm-permission.d.ts","sourceRoot":"","sources":["../../src/orm-permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAM,MAAM,aAAa,CAAC;AACxC,OAAO,EAA0B,kBAAkB,EAAE,aAAa,EAAE,SAAS,EAAgB,MAAM,cAAc,CAAC;AAGlH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,4BAA4B,WAAW,CAAC;AACrD,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAErE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,eAAqC,CAAC;AAEvE;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,8BAAsB,mBAAmB,CAAC,CAAC,SAAS,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC;IACzF;;;OAGG;IACI,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,CAExD;IAEM,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAE1D;IAEM,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAE5D;IAEM,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAE5D;IAED;;;;;;OAMG;IACU,eAAe,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF;CACF;AAED,MAAM,MAAM,wBAAwB,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAElE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,wBAAwB,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAG1G;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,GAAG,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAO9E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,MAAiC,YACnG,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAAG,IAAI,CAqBrD;AAED,+DAA+D;AAC/D,wBAAgB,0BAA0B,IAAI,IAAI,CAIjD"}
@@ -0,0 +1,119 @@
1
+ import { DI } from '@spinajs/di';
2
+ import { extractModelDescriptor, OrmException } from '@spinajs/orm';
3
+ import { Forbidden } from '@spinajs/exceptions';
4
+ export const DEFAULT_PERMISSION_SCOPE = 'default';
5
+ /**
6
+ * Attribute prefix marking a named permission scope on a role grant (eg. `'scope:pool'`),
7
+ * read by `RbacModelPermissionMiddleware.policiesFor()` to pick a non-default
8
+ * `OrmPermissionPolicy`.
9
+ *
10
+ * WARNING: `accesscontrol`'s attribute union across a role and every role it `$extend`s
11
+ * collapses `['*']` merged with `['scope:x']` down to `['*']` (glob union absorption). A role
12
+ * granting `read:own: ['scope:pool']` while a role it `$extend`s (or that extends it) grants
13
+ * the same resource `['*']` silently loses the `scope:pool` token, and resolution falls
14
+ * through to the DEFAULT policy instead of the named one. This is a known limitation, not
15
+ * handled by this module — never mix `['*']` and `scope:` attributes for the SAME resource
16
+ * across an `$extend` chain.
17
+ */
18
+ export const PERMISSION_SCOPE_ATTR_PREFIX = 'scope:';
19
+ export const ORM_PERMISSION_POLICY_MAP = '__orm_permission_policy__';
20
+ /**
21
+ * Bound model recorded on a policy class by `@OrmPermission`. Needed because the map is
22
+ * keyed on the shared resource STRING (minification-safe), which two unrelated models can
23
+ * legally share for grant purposes — the model recorded here is what lets `policiesFor()`
24
+ * in middleware.ts pick the right policy for `builder.Model` instead of an arbitrary one.
25
+ */
26
+ export const ORM_PERMISSION_MODEL = Symbol.for('orm-permission-model');
27
+ /**
28
+ * Keyed on the DECLARED `@OrmResource` string, never on `constructor.name` — grants are
29
+ * keyed on the same string, so a model's resource name is the single permission identity
30
+ * everywhere, and models sharing a resource (a view over the base table) share policies.
31
+ */
32
+ export function policyMapKey(resource, scope) {
33
+ return `${resource}:${scope}`;
34
+ }
35
+ export class OrmPermissionPolicy {
36
+ /**
37
+ * Default throws so an accidentally inert policy fails loud instead of running an
38
+ * unscoped query.
39
+ */
40
+ scope(_query, _user) {
41
+ throw new OrmException(`${this.constructor.name} defines neither a generic scope() nor a specific hook for this operation`);
42
+ }
43
+ scopeRead(query, user) {
44
+ this.scope(query, user);
45
+ }
46
+ scopeUpdate(query, user) {
47
+ this.scope(query, user);
48
+ }
49
+ scopeDelete(query, user) {
50
+ this.scope(query, user);
51
+ }
52
+ /**
53
+ * Default denies: a policy that does not opt into insert control must not silently
54
+ * allow inserts under a `:own` grant. An authorization denial, not a config error, so
55
+ * `Forbidden` (403) — contrast `scope()`'s default, which stays `OrmException` because an
56
+ * unimplemented scope is a config bug. Callers with an `OwnerField` never reach this: see
57
+ * `RbacModelPermissionMiddleware.beforeQueryExecution`'s OwnerField fallback.
58
+ */
59
+ async authorizeCreate(_query, _user) {
60
+ throw new Forbidden(`${this.constructor.name} does not implement authorizeCreate — INSERT under :own is not permitted by this policy`);
61
+ }
62
+ }
63
+ /** The model `@OrmPermission` bound `policy` to, or `undefined` for a policy built by hand
64
+ * (eg. the `OwnerFieldPolicy` fallback) that never went through the decorator.
65
+ *
66
+ * Read as an OWN property: `target[ORM_PERMISSION_MODEL] = model` stamps the constructor
67
+ * object itself, and ES class inheritance chains constructors ( `Sub.__proto__ === Base` ), so
68
+ * a plain property read here would let an undecorated `class Sub extends Base {}` silently
69
+ * inherit `Base`'s bound model instead of having none.
70
+ */
71
+ export function ormPermissionModel(policy) {
72
+ const target = policy;
73
+ return Object.prototype.hasOwnProperty.call(policy, ORM_PERMISSION_MODEL) ? target[ORM_PERMISSION_MODEL] : undefined;
74
+ }
75
+ /**
76
+ * The single accessor for the policy map — used by both the registration side
77
+ * (`OrmPermission`) and the resolution side (`RbacModelPermissionMiddleware.policiesFor`) so
78
+ * the two can never read/write through differing DI cache accessors and drift apart.
79
+ */
80
+ export function getOrCreatePolicyMap() {
81
+ if (DI.RootContainer.Cache.has(ORM_PERMISSION_POLICY_MAP)) {
82
+ return DI.RootContainer.Cache.get(ORM_PERMISSION_POLICY_MAP)[0];
83
+ }
84
+ const map = new Map();
85
+ DI.RootContainer.Cache.add(ORM_PERMISSION_POLICY_MAP, map);
86
+ return map;
87
+ }
88
+ /**
89
+ * Registers `target` as a policy for `model`'s resource + `scope` in the DI hashmap.
90
+ * Refuses a model without `@OrmResource` (cannot be permission-guarded). The map value is a
91
+ * LIST: two unrelated models are allowed to share one resource+scope key (the
92
+ * CampaignFileAttachment / ArrowV1CampaignView shape) — only the same (model, scope) pair
93
+ * registered twice is a duplicate/config bug.
94
+ */
95
+ export function OrmPermission(model, scope = DEFAULT_PERMISSION_SCOPE) {
96
+ return (target) => {
97
+ const descriptor = extractModelDescriptor(model);
98
+ const resource = descriptor?.RbacResource;
99
+ if (!resource) {
100
+ throw new OrmException(`cannot register ${target.name} for ${model.name}: model has no @OrmResource declaration`);
101
+ }
102
+ target[ORM_PERMISSION_MODEL] = model;
103
+ const key = policyMapKey(resource, scope);
104
+ const map = getOrCreatePolicyMap();
105
+ const list = map.get(key) ?? [];
106
+ if (list.some((p) => ormPermissionModel(p) === model)) {
107
+ throw new OrmException(`duplicate OrmPermission registration for ${model.name}/${scope} (${target.name} already registered for this model+scope)`);
108
+ }
109
+ list.push(target);
110
+ map.set(key, list);
111
+ };
112
+ }
113
+ /** Test helper — wipes all registrations from the DI cache. */
114
+ export function clearOrmPermissionRegistry() {
115
+ if (DI.RootContainer.Cache.has(ORM_PERMISSION_POLICY_MAP)) {
116
+ DI.RootContainer.Cache.remove(ORM_PERMISSION_POLICY_MAP);
117
+ }
118
+ }
119
+ //# sourceMappingURL=orm-permission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orm-permission.js","sourceRoot":"","sources":["../../src/orm-permission.ts"],"names":[],"mappings":"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"}