@via-profit/ability 2.0.0-rc.8 → 2.1.0
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 +328 -156
- package/build/playground.js +58 -416
- package/build/playground.js.map +1 -1
- package/dist/AbilityCode.d.ts +6 -6
- package/dist/AbilityCompare.d.ts +2 -2
- package/dist/AbilityCondition.d.ts +13 -10
- package/dist/AbilityError.d.ts +0 -3
- package/dist/AbilityMatch.d.ts +2 -2
- package/dist/AbilityPolicy.d.ts +12 -11
- package/dist/AbilityPolicyEffect.d.ts +2 -2
- package/dist/AbilityRule.d.ts +18 -3
- package/dist/AbilityRuleSet.d.ts +11 -6
- package/dist/index.js +72 -62
- package/package.json +1 -2
- package/dist/AbilityPolicyResult.d.ts +0 -6
- package/dist/playground.d.ts +0 -26
package/build/playground.js
CHANGED
|
@@ -12,9 +12,12 @@
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
13
13
|
exports.AbilityCode = void 0;
|
|
14
14
|
class AbilityCode {
|
|
15
|
-
|
|
15
|
+
_code;
|
|
16
16
|
constructor(code) {
|
|
17
|
-
this.
|
|
17
|
+
this._code = code;
|
|
18
|
+
}
|
|
19
|
+
get code() {
|
|
20
|
+
return this._code;
|
|
18
21
|
}
|
|
19
22
|
isEqual(compareWith) {
|
|
20
23
|
return compareWith !== null && this.code === compareWith.code;
|
|
@@ -22,46 +25,11 @@ class AbilityCode {
|
|
|
22
25
|
isNotEqual(compareWith) {
|
|
23
26
|
return !this.isEqual(compareWith);
|
|
24
27
|
}
|
|
25
|
-
static fromLiteral(literal) {
|
|
26
|
-
let Code = null;
|
|
27
|
-
Object.keys(this).forEach(member => {
|
|
28
|
-
if (member === literal) {
|
|
29
|
-
Code = this[member];
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
if (!Code) {
|
|
33
|
-
throw new Error(`Mismatch error. The literal ${literal} can not be find as a member of this class`);
|
|
34
|
-
}
|
|
35
|
-
return new this(Code.code);
|
|
36
|
-
}
|
|
37
28
|
}
|
|
38
29
|
exports.AbilityCode = AbilityCode;
|
|
39
30
|
exports["default"] = AbilityCode;
|
|
40
31
|
|
|
41
32
|
|
|
42
|
-
/***/ }),
|
|
43
|
-
|
|
44
|
-
/***/ "./src/AbilityCompare.ts":
|
|
45
|
-
/*!*******************************!*\
|
|
46
|
-
!*** ./src/AbilityCompare.ts ***!
|
|
47
|
-
\*******************************/
|
|
48
|
-
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
52
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
53
|
-
};
|
|
54
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
55
|
-
exports.AbilityCompare = void 0;
|
|
56
|
-
const AbilityCode_1 = __importDefault(__webpack_require__(/*! ./AbilityCode */ "./src/AbilityCode.ts"));
|
|
57
|
-
class AbilityCompare extends AbilityCode_1.default {
|
|
58
|
-
static and = new AbilityCompare('and');
|
|
59
|
-
static or = new AbilityCompare('or');
|
|
60
|
-
}
|
|
61
|
-
exports.AbilityCompare = AbilityCompare;
|
|
62
|
-
exports["default"] = AbilityCompare;
|
|
63
|
-
|
|
64
|
-
|
|
65
33
|
/***/ }),
|
|
66
34
|
|
|
67
35
|
/***/ "./src/AbilityCondition.ts":
|
|
@@ -77,15 +45,33 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
77
45
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
78
46
|
exports.AbilityCondition = void 0;
|
|
79
47
|
const AbilityCode_1 = __importDefault(__webpack_require__(/*! ./AbilityCode */ "./src/AbilityCode.ts"));
|
|
48
|
+
const AbilityError_1 = __webpack_require__(/*! ~/AbilityError */ "./src/AbilityError.ts");
|
|
80
49
|
class AbilityCondition extends AbilityCode_1.default {
|
|
81
|
-
static
|
|
82
|
-
static
|
|
83
|
-
static
|
|
84
|
-
static
|
|
85
|
-
static
|
|
86
|
-
static
|
|
87
|
-
static
|
|
88
|
-
static
|
|
50
|
+
static equal = new AbilityCondition('=');
|
|
51
|
+
static not_equal = new AbilityCondition('<>');
|
|
52
|
+
static more_than = new AbilityCondition('>');
|
|
53
|
+
static less_than = new AbilityCondition('<');
|
|
54
|
+
static less_or_equal = new AbilityCondition('<=');
|
|
55
|
+
static more_or_equal = new AbilityCondition('>=');
|
|
56
|
+
static in = new AbilityCondition('in');
|
|
57
|
+
static not_in = new AbilityCondition('not in');
|
|
58
|
+
static fromLiteral(literal) {
|
|
59
|
+
const code = AbilityCondition[literal]?.code || null;
|
|
60
|
+
if (code === null) {
|
|
61
|
+
throw new AbilityError_1.AbilityParserError(`Literal ${literal} does not found in AbilityCondition class`);
|
|
62
|
+
}
|
|
63
|
+
return new AbilityCondition(code);
|
|
64
|
+
}
|
|
65
|
+
get literal() {
|
|
66
|
+
const literal = Object.keys(AbilityCondition).find(member => {
|
|
67
|
+
const val = AbilityCondition[member];
|
|
68
|
+
return val.code === this.code;
|
|
69
|
+
});
|
|
70
|
+
if (typeof literal === 'undefined') {
|
|
71
|
+
throw new Error(`Literal value does not found in class AbilityCondition`);
|
|
72
|
+
}
|
|
73
|
+
return literal;
|
|
74
|
+
}
|
|
89
75
|
}
|
|
90
76
|
exports.AbilityCondition = AbilityCondition;
|
|
91
77
|
exports["default"] = AbilityCondition;
|
|
@@ -146,246 +132,6 @@ exports.AbilityMatch = AbilityMatch;
|
|
|
146
132
|
exports["default"] = AbilityMatch;
|
|
147
133
|
|
|
148
134
|
|
|
149
|
-
/***/ }),
|
|
150
|
-
|
|
151
|
-
/***/ "./src/AbilityPolicy.ts":
|
|
152
|
-
/*!******************************!*\
|
|
153
|
-
!*** ./src/AbilityPolicy.ts ***!
|
|
154
|
-
\******************************/
|
|
155
|
-
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
159
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
160
|
-
};
|
|
161
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
162
|
-
exports.AbilityPolicy = void 0;
|
|
163
|
-
const AbilityRuleSet_1 = __importDefault(__webpack_require__(/*! ./AbilityRuleSet */ "./src/AbilityRuleSet.ts"));
|
|
164
|
-
const AbilityMatch_1 = __importDefault(__webpack_require__(/*! ./AbilityMatch */ "./src/AbilityMatch.ts"));
|
|
165
|
-
const AbilityCompare_1 = __importDefault(__webpack_require__(/*! ./AbilityCompare */ "./src/AbilityCompare.ts"));
|
|
166
|
-
const AbilityPolicyEffect_1 = __importDefault(__webpack_require__(/*! ./AbilityPolicyEffect */ "./src/AbilityPolicyEffect.ts"));
|
|
167
|
-
class AbilityPolicy {
|
|
168
|
-
matchState = AbilityMatch_1.default.pending;
|
|
169
|
-
/**
|
|
170
|
-
* List of rules
|
|
171
|
-
*/
|
|
172
|
-
ruleSet = [];
|
|
173
|
-
/**
|
|
174
|
-
* Policy effect
|
|
175
|
-
*/
|
|
176
|
-
effect;
|
|
177
|
-
/**
|
|
178
|
-
* Rules compare method.\
|
|
179
|
-
* For the «and» method the rule will be permitted if all\
|
|
180
|
-
* rules will be returns «permit» status and for the «or» - if\
|
|
181
|
-
* one of the rules returns as «permit»
|
|
182
|
-
*/
|
|
183
|
-
compareMethod = AbilityCompare_1.default.and;
|
|
184
|
-
/**
|
|
185
|
-
* Policy name
|
|
186
|
-
*/
|
|
187
|
-
name;
|
|
188
|
-
/**
|
|
189
|
-
* Policy ID
|
|
190
|
-
*/
|
|
191
|
-
id;
|
|
192
|
-
/**
|
|
193
|
-
* Soon
|
|
194
|
-
*/
|
|
195
|
-
action;
|
|
196
|
-
constructor(params) {
|
|
197
|
-
const { name, id, action, effect } = params;
|
|
198
|
-
this.name = name;
|
|
199
|
-
this.id = id;
|
|
200
|
-
this.action = action;
|
|
201
|
-
this.effect = effect;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Add rule set to the policy
|
|
205
|
-
* @param ruleSet - The rule set to add
|
|
206
|
-
*/
|
|
207
|
-
addRuleSet(ruleSet) {
|
|
208
|
-
this.ruleSet.push(ruleSet);
|
|
209
|
-
return this;
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Check if the policy is matched
|
|
213
|
-
* @param resources - The resource to check
|
|
214
|
-
*/
|
|
215
|
-
check(resources) {
|
|
216
|
-
this.matchState = AbilityMatch_1.default.mismatch;
|
|
217
|
-
if (!this.ruleSet.length) {
|
|
218
|
-
return this.matchState;
|
|
219
|
-
}
|
|
220
|
-
const rulesetCheckStates = this.ruleSet.reduce((collect, ruleSet) => {
|
|
221
|
-
return collect.concat(ruleSet.check(resources));
|
|
222
|
-
}, []);
|
|
223
|
-
if (AbilityCompare_1.default.and.isEqual(this.compareMethod)) {
|
|
224
|
-
if (rulesetCheckStates.every(ruleState => AbilityMatch_1.default.match.isEqual(ruleState))) {
|
|
225
|
-
this.matchState = AbilityMatch_1.default.match;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
if (AbilityCompare_1.default.or.isEqual(this.compareMethod)) {
|
|
229
|
-
if (rulesetCheckStates.some(ruleState => AbilityMatch_1.default.match.isEqual(ruleState))) {
|
|
230
|
-
this.matchState = AbilityMatch_1.default.match;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return this.matchState;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Parse the config JSON format to Policy class instance
|
|
237
|
-
*/
|
|
238
|
-
static parse(config) {
|
|
239
|
-
const { id, name, ruleSet, compareMethod, action, effect } = config;
|
|
240
|
-
// Create the empty policy
|
|
241
|
-
const policy = new AbilityPolicy({
|
|
242
|
-
name,
|
|
243
|
-
id,
|
|
244
|
-
action,
|
|
245
|
-
effect: new AbilityPolicyEffect_1.default(effect),
|
|
246
|
-
});
|
|
247
|
-
policy.compareMethod = AbilityCompare_1.default.fromLiteral(compareMethod);
|
|
248
|
-
ruleSet.forEach(ruleSetConfig => {
|
|
249
|
-
policy.addRuleSet(AbilityRuleSet_1.default.parse(ruleSetConfig));
|
|
250
|
-
});
|
|
251
|
-
return policy;
|
|
252
|
-
}
|
|
253
|
-
export() {
|
|
254
|
-
return {
|
|
255
|
-
id: this.id.toString(),
|
|
256
|
-
name: this.name.toString(),
|
|
257
|
-
compareMethod: this.compareMethod.code.toString(),
|
|
258
|
-
ruleSet: this.ruleSet.map(rule => rule.export()),
|
|
259
|
-
action: this.action,
|
|
260
|
-
effect: this.effect.code,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
exports.AbilityPolicy = AbilityPolicy;
|
|
265
|
-
exports["default"] = AbilityPolicy;
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
/***/ }),
|
|
269
|
-
|
|
270
|
-
/***/ "./src/AbilityPolicyEffect.ts":
|
|
271
|
-
/*!************************************!*\
|
|
272
|
-
!*** ./src/AbilityPolicyEffect.ts ***!
|
|
273
|
-
\************************************/
|
|
274
|
-
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
278
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
279
|
-
};
|
|
280
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
281
|
-
exports.AbilityPolicyEffect = void 0;
|
|
282
|
-
const AbilityCode_1 = __importDefault(__webpack_require__(/*! ./AbilityCode */ "./src/AbilityCode.ts"));
|
|
283
|
-
class AbilityPolicyEffect extends AbilityCode_1.default {
|
|
284
|
-
static deny = new AbilityPolicyEffect('deny');
|
|
285
|
-
static permit = new AbilityPolicyEffect('permit');
|
|
286
|
-
}
|
|
287
|
-
exports.AbilityPolicyEffect = AbilityPolicyEffect;
|
|
288
|
-
exports["default"] = AbilityPolicyEffect;
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
/***/ }),
|
|
292
|
-
|
|
293
|
-
/***/ "./src/AbilityResolver.ts":
|
|
294
|
-
/*!********************************!*\
|
|
295
|
-
!*** ./src/AbilityResolver.ts ***!
|
|
296
|
-
\********************************/
|
|
297
|
-
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
301
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
302
|
-
};
|
|
303
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
304
|
-
exports.AbilityResolver = void 0;
|
|
305
|
-
const AbilityPolicyEffect_1 = __importDefault(__webpack_require__(/*! ./AbilityPolicyEffect */ "./src/AbilityPolicyEffect.ts"));
|
|
306
|
-
const AbilityMatch_1 = __importDefault(__webpack_require__(/*! ./AbilityMatch */ "./src/AbilityMatch.ts"));
|
|
307
|
-
const AbilityError_1 = __webpack_require__(/*! ./AbilityError */ "./src/AbilityError.ts");
|
|
308
|
-
class AbilityResolver {
|
|
309
|
-
policies;
|
|
310
|
-
constructor(policyOrListOfPolicies) {
|
|
311
|
-
this.policies = Array.isArray(policyOrListOfPolicies)
|
|
312
|
-
? policyOrListOfPolicies
|
|
313
|
-
: [policyOrListOfPolicies];
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Resolve policy for the resource and action
|
|
317
|
-
*
|
|
318
|
-
@param action - Action
|
|
319
|
-
* @param resource - Resource
|
|
320
|
-
*/
|
|
321
|
-
resolve(action, resource) {
|
|
322
|
-
const filteredPolicies = this.policies.filter(policy => {
|
|
323
|
-
return AbilityResolver.isInActionContain(policy.action, String(action));
|
|
324
|
-
});
|
|
325
|
-
filteredPolicies.map(policy => policy.check(resource));
|
|
326
|
-
this.policies = filteredPolicies;
|
|
327
|
-
return this;
|
|
328
|
-
}
|
|
329
|
-
enforce(action, resource) {
|
|
330
|
-
const resolver = this.resolve(action, resource);
|
|
331
|
-
if (resolver) {
|
|
332
|
-
if (resolver.isDeny()) {
|
|
333
|
-
throw new AbilityError_1.PermissionError(resolver.getMatchedPolicy()?.name?.toString() || 'Unknown permission error');
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Get the last effect of the policy
|
|
339
|
-
*
|
|
340
|
-
* @returns {AbilityPolicyEffect | null}
|
|
341
|
-
*/
|
|
342
|
-
getEffect() {
|
|
343
|
-
const effects = this.policies.reduce((collect, policy, _index) => {
|
|
344
|
-
if (policy.matchState.isEqual(AbilityMatch_1.default.match)) {
|
|
345
|
-
return collect.concat(policy.effect);
|
|
346
|
-
}
|
|
347
|
-
return collect;
|
|
348
|
-
}, []);
|
|
349
|
-
if (effects.length) {
|
|
350
|
-
return effects[effects.length - 1];
|
|
351
|
-
}
|
|
352
|
-
return null;
|
|
353
|
-
}
|
|
354
|
-
isPermit() {
|
|
355
|
-
const effect = this.getEffect();
|
|
356
|
-
return effect !== null && effect.isEqual(AbilityPolicyEffect_1.default.permit);
|
|
357
|
-
}
|
|
358
|
-
isDeny() {
|
|
359
|
-
const effect = this.getEffect();
|
|
360
|
-
return effect !== null && effect.isEqual(AbilityPolicyEffect_1.default.deny);
|
|
361
|
-
}
|
|
362
|
-
getMatchedPolicy() {
|
|
363
|
-
const matchedPolicies = this.policies.filter(policy => policy.matchState.isEqual(AbilityMatch_1.default.match));
|
|
364
|
-
const lastPolicy = matchedPolicies.length ? matchedPolicies[matchedPolicies.length - 1] : null;
|
|
365
|
-
return lastPolicy || null;
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* Check if the action is contained in another action
|
|
369
|
-
* @param actionA - The first action to check
|
|
370
|
-
* @param actionB - The second action to check
|
|
371
|
-
*/
|
|
372
|
-
static isInActionContain(actionA, actionB) {
|
|
373
|
-
const actionAArray = String(actionA).split('.');
|
|
374
|
-
const actionBArray = String(actionB).split('.');
|
|
375
|
-
const a = actionAArray.length >= actionBArray.length ? actionAArray : actionBArray;
|
|
376
|
-
const b = actionBArray.length <= actionAArray.length ? actionBArray : actionAArray;
|
|
377
|
-
const c = a
|
|
378
|
-
.reduce((acc, chunk, index) => {
|
|
379
|
-
const iterationRes = chunk === b[index] || b[index] === '*' || chunk === '*';
|
|
380
|
-
return acc.concat(iterationRes);
|
|
381
|
-
}, []);
|
|
382
|
-
return c.every(Boolean);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
exports.AbilityResolver = AbilityResolver;
|
|
386
|
-
exports["default"] = AbilityResolver;
|
|
387
|
-
|
|
388
|
-
|
|
389
135
|
/***/ }),
|
|
390
136
|
|
|
391
137
|
/***/ "./src/AbilityRule.ts":
|
|
@@ -421,7 +167,7 @@ class AbilityRule {
|
|
|
421
167
|
this.name = name;
|
|
422
168
|
this.subject = subject;
|
|
423
169
|
this.resource = resource;
|
|
424
|
-
this.condition =
|
|
170
|
+
this.condition = condition;
|
|
425
171
|
}
|
|
426
172
|
/**
|
|
427
173
|
* Check if the rule is matched
|
|
@@ -430,25 +176,25 @@ class AbilityRule {
|
|
|
430
176
|
check(resource) {
|
|
431
177
|
let is = false;
|
|
432
178
|
const [valueS, valueO] = this.extractValues(resource);
|
|
433
|
-
if (AbilityCondition_1.default.
|
|
179
|
+
if (AbilityCondition_1.default.less_than.isEqual(this.condition)) {
|
|
434
180
|
is = Number(valueS) < Number(valueO);
|
|
435
181
|
}
|
|
436
|
-
if (AbilityCondition_1.default.
|
|
182
|
+
if (AbilityCondition_1.default.less_or_equal.isEqual(this.condition)) {
|
|
437
183
|
is = Number(valueS) <= Number(valueO);
|
|
438
184
|
}
|
|
439
|
-
if (AbilityCondition_1.default.
|
|
185
|
+
if (AbilityCondition_1.default.more_than.isEqual(this.condition)) {
|
|
440
186
|
is = Number(valueS) > Number(valueO);
|
|
441
187
|
}
|
|
442
|
-
if (AbilityCondition_1.default.
|
|
188
|
+
if (AbilityCondition_1.default.more_or_equal.isEqual(this.condition)) {
|
|
443
189
|
is = Number(valueS) >= Number(valueO);
|
|
444
190
|
}
|
|
445
|
-
if (AbilityCondition_1.default.
|
|
191
|
+
if (AbilityCondition_1.default.equal.isEqual(this.condition)) {
|
|
446
192
|
is = valueS === valueO;
|
|
447
193
|
}
|
|
448
|
-
if (AbilityCondition_1.default.
|
|
194
|
+
if (AbilityCondition_1.default.not_equal.isEqual(this.condition)) {
|
|
449
195
|
is = valueS !== valueO;
|
|
450
196
|
}
|
|
451
|
-
if (AbilityCondition_1.default.
|
|
197
|
+
if (AbilityCondition_1.default.in.isEqual(this.condition)) {
|
|
452
198
|
// [<some>] and [<some>]
|
|
453
199
|
if (Array.isArray(valueS) && Array.isArray(valueO)) {
|
|
454
200
|
is = valueS.some(v => valueO.find(v1 => v1 === v));
|
|
@@ -462,7 +208,7 @@ class AbilityRule {
|
|
|
462
208
|
is = valueS.includes(valueO);
|
|
463
209
|
}
|
|
464
210
|
}
|
|
465
|
-
if (AbilityCondition_1.default.
|
|
211
|
+
if (AbilityCondition_1.default.not_in.isEqual(this.condition)) {
|
|
466
212
|
// [<some>] and [<some>]
|
|
467
213
|
if (Array.isArray(valueS) && Array.isArray(valueO)) {
|
|
468
214
|
is = !valueS.some(v => valueO.find(v1 => v1 === v));
|
|
@@ -541,7 +287,7 @@ class AbilityRule {
|
|
|
541
287
|
name,
|
|
542
288
|
subject,
|
|
543
289
|
resource,
|
|
544
|
-
condition,
|
|
290
|
+
condition: new AbilityCondition_1.default(condition),
|
|
545
291
|
});
|
|
546
292
|
}
|
|
547
293
|
/**
|
|
@@ -561,110 +307,6 @@ exports.AbilityRule = AbilityRule;
|
|
|
561
307
|
exports["default"] = AbilityRule;
|
|
562
308
|
|
|
563
309
|
|
|
564
|
-
/***/ }),
|
|
565
|
-
|
|
566
|
-
/***/ "./src/AbilityRuleSet.ts":
|
|
567
|
-
/*!*******************************!*\
|
|
568
|
-
!*** ./src/AbilityRuleSet.ts ***!
|
|
569
|
-
\*******************************/
|
|
570
|
-
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
574
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
575
|
-
};
|
|
576
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
577
|
-
exports.AbilityRuleSet = void 0;
|
|
578
|
-
const AbilityRule_1 = __importDefault(__webpack_require__(/*! ./AbilityRule */ "./src/AbilityRule.ts"));
|
|
579
|
-
const AbilityCompare_1 = __importDefault(__webpack_require__(/*! ./AbilityCompare */ "./src/AbilityCompare.ts"));
|
|
580
|
-
const AbilityMatch_1 = __importDefault(__webpack_require__(/*! ./AbilityMatch */ "./src/AbilityMatch.ts"));
|
|
581
|
-
class AbilityRuleSet {
|
|
582
|
-
state = AbilityMatch_1.default.pending;
|
|
583
|
-
/**
|
|
584
|
-
* List of rules
|
|
585
|
-
*/
|
|
586
|
-
rules = [];
|
|
587
|
-
/**
|
|
588
|
-
* Rules compare method.\
|
|
589
|
-
* For the «and» method the rule will be permitted if all\
|
|
590
|
-
* rules will be returns «permit» status and for the «or» - if\
|
|
591
|
-
* one of the rules returns as «permit»
|
|
592
|
-
*/
|
|
593
|
-
compareMethod = AbilityCompare_1.default.and;
|
|
594
|
-
/**
|
|
595
|
-
* Group name
|
|
596
|
-
*/
|
|
597
|
-
name;
|
|
598
|
-
/**
|
|
599
|
-
* Group ID
|
|
600
|
-
*/
|
|
601
|
-
id;
|
|
602
|
-
constructor(params) {
|
|
603
|
-
const { name, id, compareMethod } = params;
|
|
604
|
-
this.name = name;
|
|
605
|
-
this.id = id;
|
|
606
|
-
this.compareMethod = AbilityCompare_1.default.fromLiteral(compareMethod);
|
|
607
|
-
// this.compareMethod = new AbilityCompare(compareMethod);
|
|
608
|
-
}
|
|
609
|
-
addRule(rule, compareMethod) {
|
|
610
|
-
this.rules.push(rule);
|
|
611
|
-
this.compareMethod = compareMethod;
|
|
612
|
-
return this;
|
|
613
|
-
}
|
|
614
|
-
addRules(rules, compareMethod) {
|
|
615
|
-
rules.forEach(rule => this.addRule(rule, compareMethod));
|
|
616
|
-
return this;
|
|
617
|
-
}
|
|
618
|
-
check(resources) {
|
|
619
|
-
this.state = AbilityMatch_1.default.mismatch;
|
|
620
|
-
if (!this.rules.length) {
|
|
621
|
-
return this.state;
|
|
622
|
-
}
|
|
623
|
-
const ruleCheckStates = this.rules.reduce((collect, rule) => {
|
|
624
|
-
return collect.concat(rule.check(resources));
|
|
625
|
-
}, []);
|
|
626
|
-
if (AbilityCompare_1.default.and.isEqual(this.compareMethod)) {
|
|
627
|
-
if (ruleCheckStates.every(ruleState => AbilityMatch_1.default.match.isEqual(ruleState))) {
|
|
628
|
-
this.state = AbilityMatch_1.default.match;
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
if (AbilityCompare_1.default.or.isEqual(this.compareMethod)) {
|
|
632
|
-
if (ruleCheckStates.some(ruleState => AbilityMatch_1.default.match.isEqual(ruleState))) {
|
|
633
|
-
this.state = AbilityMatch_1.default.match;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
return this.state;
|
|
637
|
-
}
|
|
638
|
-
/**
|
|
639
|
-
* Parse the config JSON format to Group class instance
|
|
640
|
-
*/
|
|
641
|
-
static parse(config) {
|
|
642
|
-
const { id, name, rules, compareMethod } = config;
|
|
643
|
-
const ruleSet = new AbilityRuleSet({
|
|
644
|
-
compareMethod,
|
|
645
|
-
name,
|
|
646
|
-
id,
|
|
647
|
-
});
|
|
648
|
-
// Adding rules if exists
|
|
649
|
-
if (rules && rules.length > 0) {
|
|
650
|
-
const abilityRules = rules.map(ruleConfig => AbilityRule_1.default.parse(ruleConfig));
|
|
651
|
-
ruleSet.addRules(abilityRules, ruleSet.compareMethod);
|
|
652
|
-
}
|
|
653
|
-
return ruleSet;
|
|
654
|
-
}
|
|
655
|
-
export() {
|
|
656
|
-
return {
|
|
657
|
-
id: this.id.toString(),
|
|
658
|
-
name: this.name.toString(),
|
|
659
|
-
compareMethod: this.compareMethod.code.toString(),
|
|
660
|
-
rules: this.rules.map(rule => rule.export()),
|
|
661
|
-
};
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
exports.AbilityRuleSet = AbilityRuleSet;
|
|
665
|
-
exports["default"] = AbilityRuleSet;
|
|
666
|
-
|
|
667
|
-
|
|
668
310
|
/***/ }),
|
|
669
311
|
|
|
670
312
|
/***/ "./src/playground.ts":
|
|
@@ -679,8 +321,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
679
321
|
};
|
|
680
322
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
681
323
|
const node_http_1 = __importDefault(__webpack_require__(/*! node:http */ "node:http"));
|
|
682
|
-
const
|
|
683
|
-
const
|
|
324
|
+
const AbilityCondition_1 = __importDefault(__webpack_require__(/*! ~/AbilityCondition */ "./src/AbilityCondition.ts"));
|
|
325
|
+
const AbilityRule_1 = __importDefault(__webpack_require__(/*! ./AbilityRule */ "./src/AbilityRule.ts"));
|
|
326
|
+
const AbilityMatch_1 = __importDefault(__webpack_require__(/*! ./AbilityMatch */ "./src/AbilityMatch.ts"));
|
|
684
327
|
const server = node_http_1.default.createServer();
|
|
685
328
|
server.on('request', (_req, res) => {
|
|
686
329
|
const config = [
|
|
@@ -705,7 +348,7 @@ server.on('request', (_req, res) => {
|
|
|
705
348
|
},
|
|
706
349
|
],
|
|
707
350
|
},
|
|
708
|
-
]
|
|
351
|
+
],
|
|
709
352
|
},
|
|
710
353
|
{
|
|
711
354
|
id: 'bb758c1b-1015-4894-ba25-d23156e063cf',
|
|
@@ -738,28 +381,27 @@ server.on('request', (_req, res) => {
|
|
|
738
381
|
],
|
|
739
382
|
},
|
|
740
383
|
];
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
// status: 'завершен'
|
|
752
|
-
},
|
|
384
|
+
const rule = new AbilityRule_1.default({
|
|
385
|
+
id: '<rule-id>',
|
|
386
|
+
name: 'Пользователь является владельцем заказа',
|
|
387
|
+
condition: AbilityCondition_1.default.equal,
|
|
388
|
+
subject: 'user.id',
|
|
389
|
+
resource: 'order.owner',
|
|
390
|
+
});
|
|
391
|
+
const matchState = rule.check({
|
|
392
|
+
user: { id: '1' },
|
|
393
|
+
order: { owner: '1' },
|
|
753
394
|
});
|
|
395
|
+
const is = matchState.isEqual(AbilityMatch_1.default.match); // true
|
|
754
396
|
res.statusCode = 200;
|
|
755
397
|
res.setHeader('content-type', 'application/json');
|
|
756
398
|
res.write(JSON.stringify({
|
|
757
|
-
status:
|
|
399
|
+
status: 'ok',
|
|
758
400
|
}));
|
|
759
401
|
res.end();
|
|
760
402
|
});
|
|
761
403
|
server.listen(8081, 'localhost', () => {
|
|
762
|
-
console.debug('server started at http://localhost:
|
|
404
|
+
console.debug('server started at http://localhost:8081');
|
|
763
405
|
});
|
|
764
406
|
|
|
765
407
|
|