@authup/access 1.0.0-beta.30 → 1.0.0-beta.33
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 +201 -201
- package/dist/constants.d.ts +1 -14
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.mjs +127 -184
- package/dist/index.mjs.map +1 -1
- package/dist/permission/evaluator/index.d.ts.map +1 -0
- package/dist/permission/evaluator/module.d.ts +20 -0
- package/dist/permission/evaluator/module.d.ts.map +1 -0
- package/dist/permission/evaluator/types.d.ts +28 -0
- package/dist/permission/evaluator/types.d.ts.map +1 -0
- package/dist/permission/helpers/equal.d.ts +1 -2
- package/dist/permission/helpers/equal.d.ts.map +1 -1
- package/dist/permission/helpers/key.d.ts +1 -2
- package/dist/permission/helpers/key.d.ts.map +1 -1
- package/dist/permission/helpers/merge.d.ts +1 -2
- package/dist/permission/helpers/merge.d.ts.map +1 -1
- package/dist/permission/index.d.ts +2 -2
- package/dist/permission/index.d.ts.map +1 -1
- package/dist/permission/provider/index.d.ts.map +1 -0
- package/dist/permission/provider/memory.d.ts +9 -0
- package/dist/permission/provider/memory.d.ts.map +1 -0
- package/dist/permission/provider/types.d.ts +10 -0
- package/dist/permission/provider/types.d.ts.map +1 -0
- package/dist/permission/types.d.ts +1 -7
- package/dist/permission/types.d.ts.map +1 -1
- package/dist/policy/built-in/attributes/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/attributes/types.d.ts.map +1 -1
- package/dist/policy/built-in/composite/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/composite/types.d.ts +1 -1
- package/dist/policy/built-in/composite/types.d.ts.map +1 -1
- package/dist/policy/built-in/composite/validator.d.ts.map +1 -1
- package/dist/policy/built-in/constants.d.ts +8 -0
- package/dist/policy/built-in/constants.d.ts.map +1 -1
- package/dist/policy/built-in/date/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/identity/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/permission-binding/module.d.ts.map +1 -1
- package/dist/policy/built-in/realm-match/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/realm-match/types.d.ts +5 -5
- package/dist/policy/built-in/realm-match/types.d.ts.map +1 -1
- package/dist/policy/built-in/time/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/time/types.d.ts +3 -3
- package/dist/policy/built-in/time/types.d.ts.map +1 -1
- package/dist/policy/data.d.ts.map +1 -1
- package/dist/policy/engine/module.d.ts.map +1 -1
- package/dist/policy/error/module.d.ts.map +1 -1
- package/package.json +17 -7
- package/dist/permission/checker/index.d.ts.map +0 -1
- package/dist/permission/checker/module.d.ts +0 -36
- package/dist/permission/checker/module.d.ts.map +0 -1
- package/dist/permission/checker/types.d.ts +0 -26
- package/dist/permission/checker/types.d.ts.map +0 -1
- package/dist/permission/repository/index.d.ts.map +0 -1
- package/dist/permission/repository/memory.d.ts +0 -9
- package/dist/permission/repository/memory.d.ts.map +0 -1
- package/dist/permission/repository/types.d.ts +0 -10
- package/dist/permission/repository/types.d.ts.map +0 -1
- /package/dist/permission/{checker → evaluator}/index.d.ts +0 -0
- /package/dist/permission/{repository → provider}/index.d.ts +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { AuthupError, ErrorCode } from '@authup/errors';
|
|
2
|
+
import { buildPermissionBindingKey, mergePermissionBindings } from '@authup/core-kit';
|
|
3
|
+
export { buildPermissionBindingKey, isPermissionBindingEqual, mergePermissionBindings } from '@authup/core-kit';
|
|
2
4
|
import { defineIssueItem, defineIssueGroup, Container } from 'validup';
|
|
3
|
-
import { isObject, flattenObject, hasOwnProperty } from '@authup/kit';
|
|
5
|
+
import { isObject, flattenObject, DecisionStrategy, hasOwnProperty } from '@authup/kit';
|
|
6
|
+
export { DecisionStrategy } from '@authup/kit';
|
|
4
7
|
import { createValidator } from '@validup/adapter-zod';
|
|
5
8
|
import { z } from 'zod';
|
|
6
9
|
import { guard } from '@ucast/mongo2js';
|
|
@@ -51,51 +54,30 @@ class PermissionError extends AuthupError {
|
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* view the LICENSE file that was distributed with this source code.
|
|
59
|
-
*/ function buildPermissionItemKey(input) {
|
|
60
|
-
return `${input.realmId || '_'}/${input.clientId || '_'}/${input.name}`;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/*
|
|
64
|
-
* Copyright (c) 2024-2024.
|
|
65
|
-
* Author Peter Placzek (tada5hi)
|
|
66
|
-
* For the full copyright and license information,
|
|
67
|
-
* view the LICENSE file that was distributed with this source code.
|
|
68
|
-
*/ function isPermissionItemEqual(a, b) {
|
|
69
|
-
if (a.name !== b.name) {
|
|
70
|
-
return false;
|
|
57
|
+
class PermissionMemoryProvider {
|
|
58
|
+
items = {};
|
|
59
|
+
constructor(items = []){
|
|
60
|
+
this.setMany(items);
|
|
71
61
|
}
|
|
72
|
-
|
|
73
|
-
|
|
62
|
+
async findOne(options) {
|
|
63
|
+
const entry = this.items[buildPermissionBindingKey({
|
|
64
|
+
name: options.name,
|
|
65
|
+
client_id: options.clientId,
|
|
66
|
+
realm_id: options.realmId
|
|
67
|
+
})];
|
|
68
|
+
if (entry) {
|
|
69
|
+
return entry;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
74
72
|
}
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
setMany(input) {
|
|
74
|
+
this.items = mergePermissionBindings(input).reduce((prev, current)=>{
|
|
75
|
+
prev[buildPermissionBindingKey(current.permission)] = current;
|
|
76
|
+
return prev;
|
|
77
|
+
}, {});
|
|
77
78
|
}
|
|
78
|
-
return !!a.realmId === !!b.realmId && !!a.clientId === !!b.clientId;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
/*
|
|
82
|
-
* Copyright (c) 2024-2024.
|
|
83
|
-
* Author Peter Placzek (tada5hi)
|
|
84
|
-
* For the full copyright and license information,
|
|
85
|
-
* view the LICENSE file that was distributed with this source code.
|
|
86
|
-
*/ var DecisionStrategy = /*#__PURE__*/ function(DecisionStrategy) {
|
|
87
|
-
/**
|
|
88
|
-
* One or more positive
|
|
89
|
-
*/ DecisionStrategy["AFFIRMATIVE"] = "affirmative";
|
|
90
|
-
/**
|
|
91
|
-
* All positive
|
|
92
|
-
*/ DecisionStrategy["UNANIMOUS"] = "unanimous";
|
|
93
|
-
/**
|
|
94
|
-
* More positive than negative
|
|
95
|
-
*/ DecisionStrategy["CONSENSUS"] = "consensus";
|
|
96
|
-
return DecisionStrategy;
|
|
97
|
-
}({});
|
|
98
|
-
|
|
99
81
|
/*
|
|
100
82
|
* Copyright (c) 2024-2024.
|
|
101
83
|
* Author Peter Placzek (tada5hi)
|
|
@@ -151,20 +133,20 @@ class PolicyError extends AuthupError {
|
|
|
151
133
|
}
|
|
152
134
|
registerEvaluators(evaluators) {
|
|
153
135
|
const keys = Object.keys(evaluators);
|
|
154
|
-
for(
|
|
155
|
-
this.registerEvaluator(
|
|
136
|
+
for (const key of keys){
|
|
137
|
+
this.registerEvaluator(key, evaluators[key]);
|
|
156
138
|
}
|
|
157
139
|
}
|
|
158
140
|
/**
|
|
159
141
|
* @param policy
|
|
160
142
|
* @param ctx
|
|
161
143
|
*/ async evaluate(policy, ctx) {
|
|
162
|
-
if (ctx.exclude && ctx.exclude.length > 0 && ctx.exclude.
|
|
144
|
+
if (ctx.exclude && ctx.exclude.length > 0 && ctx.exclude.includes(policy.type)) {
|
|
163
145
|
return {
|
|
164
146
|
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
165
147
|
};
|
|
166
148
|
}
|
|
167
|
-
if (ctx.include && ctx.include.length > 0 && ctx.include.
|
|
149
|
+
if (ctx.include && ctx.include.length > 0 && !ctx.include.includes(policy.type)) {
|
|
168
150
|
return {
|
|
169
151
|
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
170
152
|
};
|
|
@@ -193,7 +175,7 @@ class PolicyError extends AuthupError {
|
|
|
193
175
|
...ctx.evaluators || {}
|
|
194
176
|
}
|
|
195
177
|
});
|
|
196
|
-
} catch
|
|
178
|
+
} catch {
|
|
197
179
|
issues.push(defineIssueItem({
|
|
198
180
|
path: [
|
|
199
181
|
policy.type
|
|
@@ -366,6 +348,14 @@ class AttributeNamesPolicyValidator extends Container {
|
|
|
366
348
|
*/ BuiltInPolicyType["PERMISSION_BINDING"] = "permissionBinding";
|
|
367
349
|
return BuiltInPolicyType;
|
|
368
350
|
}({});
|
|
351
|
+
const SystemPolicyName = {
|
|
352
|
+
DEFAULT: 'system.default',
|
|
353
|
+
IDENTITY: 'system.identity',
|
|
354
|
+
PERMISSION_BINDING: 'system.permission-binding',
|
|
355
|
+
REALM_MATCH: 'system.realm-match',
|
|
356
|
+
REALM_BOUND: 'system.realm-bound',
|
|
357
|
+
REALM_OR_GLOBAL: 'system.realm-or-global'
|
|
358
|
+
};
|
|
369
359
|
|
|
370
360
|
class AttributesPolicyValidator extends Container {
|
|
371
361
|
initialize() {
|
|
@@ -417,15 +407,14 @@ class AttributesPolicyEvaluator {
|
|
|
417
407
|
}
|
|
418
408
|
fixQuery(query) {
|
|
419
409
|
if (Array.isArray(query)) {
|
|
420
|
-
for(
|
|
421
|
-
this.fixQuery(
|
|
410
|
+
for (const element of query){
|
|
411
|
+
this.fixQuery(element);
|
|
422
412
|
}
|
|
423
413
|
return;
|
|
424
414
|
}
|
|
425
415
|
if (isObject(query)) {
|
|
426
416
|
const keys = Object.keys(query);
|
|
427
|
-
for(
|
|
428
|
-
const key = keys[i];
|
|
417
|
+
for (const key of keys){
|
|
429
418
|
const value = query[key];
|
|
430
419
|
if (isObject(value) || Array.isArray(value)) {
|
|
431
420
|
this.fixQuery(value);
|
|
@@ -468,15 +457,15 @@ class AttributeNamesPolicyEvaluator {
|
|
|
468
457
|
const attributes = flattenObject(data);
|
|
469
458
|
const keys = Object.keys(attributes);
|
|
470
459
|
const issues = [];
|
|
471
|
-
for(
|
|
472
|
-
const index = policy.names.indexOf(
|
|
460
|
+
for (const key of keys){
|
|
461
|
+
const index = policy.names.indexOf(key);
|
|
473
462
|
if (index === -1) {
|
|
474
463
|
issues.push(definePolicyIssueItem({
|
|
475
464
|
code: PolicyIssueCode.EVALUATION_DENIED,
|
|
476
|
-
message: `The attribute ${
|
|
465
|
+
message: `The attribute ${key} is not included`,
|
|
477
466
|
path: [
|
|
478
467
|
...ctx.path,
|
|
479
|
-
|
|
468
|
+
key
|
|
480
469
|
]
|
|
481
470
|
}));
|
|
482
471
|
}
|
|
@@ -491,7 +480,7 @@ class AttributeNamesPolicyEvaluator {
|
|
|
491
480
|
class CompositePolicyValidator extends Container {
|
|
492
481
|
initialize() {
|
|
493
482
|
super.initialize();
|
|
494
|
-
this.mount('
|
|
483
|
+
this.mount('decision_strategy', createValidator(z.enum(DecisionStrategy).or(z.null()).or(z.undefined()).optional()));
|
|
495
484
|
this.mount('children', createValidator(z.array(z.looseObject({
|
|
496
485
|
type: z.string().min(3)
|
|
497
486
|
}))));
|
|
@@ -508,7 +497,7 @@ class CompositePolicyEvaluator {
|
|
|
508
497
|
// todo: catch errors + transform to issue(s)
|
|
509
498
|
const policy = await this.validator.run(value);
|
|
510
499
|
let count = 0;
|
|
511
|
-
const
|
|
500
|
+
const decision_strategy = policy.decision_strategy ?? DecisionStrategy.UNANIMOUS;
|
|
512
501
|
const engine = new PolicyEngine(ctx.evaluators);
|
|
513
502
|
const issues = [];
|
|
514
503
|
for(let i = 0; i < policy.children.length; i++){
|
|
@@ -522,7 +511,7 @@ class CompositePolicyEvaluator {
|
|
|
522
511
|
path
|
|
523
512
|
});
|
|
524
513
|
if (outcome.success) {
|
|
525
|
-
if (
|
|
514
|
+
if (decision_strategy === DecisionStrategy.AFFIRMATIVE) {
|
|
526
515
|
return {
|
|
527
516
|
success: maybeInvertPolicyOutcome(true, policy.invert),
|
|
528
517
|
issues: []
|
|
@@ -537,7 +526,7 @@ class CompositePolicyEvaluator {
|
|
|
537
526
|
path
|
|
538
527
|
}));
|
|
539
528
|
}
|
|
540
|
-
if (
|
|
529
|
+
if (decision_strategy === DecisionStrategy.UNANIMOUS) {
|
|
541
530
|
return {
|
|
542
531
|
success: maybeInvertPolicyOutcome(false, policy.invert),
|
|
543
532
|
issues: [
|
|
@@ -696,7 +685,7 @@ class IdentityPolicyEvaluator {
|
|
|
696
685
|
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
697
686
|
};
|
|
698
687
|
}
|
|
699
|
-
const typeAllowed = policy.types.
|
|
688
|
+
const typeAllowed = policy.types.includes(data.type);
|
|
700
689
|
if (typeAllowed) {
|
|
701
690
|
return {
|
|
702
691
|
success: maybeInvertPolicyOutcome(typeAllowed, policy.invert)
|
|
@@ -736,11 +725,11 @@ class PermissionBindingPolicyEvaluator {
|
|
|
736
725
|
class RealmMatchPolicyValidator extends Container {
|
|
737
726
|
initialize() {
|
|
738
727
|
super.initialize();
|
|
739
|
-
this.mount('
|
|
740
|
-
this.mount('
|
|
741
|
-
this.mount('
|
|
742
|
-
this.mount('
|
|
743
|
-
this.mount('
|
|
728
|
+
this.mount('decision_strategy', createValidator(z.enum(DecisionStrategy).or(z.null()).or(z.undefined()).optional()));
|
|
729
|
+
this.mount('attribute_name', createValidator(z.string().min(3).or(z.array(z.string().min(3))).or(z.null()).or(z.undefined()).optional()));
|
|
730
|
+
this.mount('attribute_name_strict', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
731
|
+
this.mount('attribute_null_match_all', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
732
|
+
this.mount('identity_master_match_all', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
744
733
|
this.mount('invert', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
745
734
|
}
|
|
746
735
|
}
|
|
@@ -783,19 +772,19 @@ class RealmMatchPolicyEvaluator {
|
|
|
783
772
|
]
|
|
784
773
|
};
|
|
785
774
|
}
|
|
786
|
-
const identityMasterMatchAll = policy.
|
|
775
|
+
const identityMasterMatchAll = policy.identity_master_match_all ?? true;
|
|
787
776
|
if (identityMasterMatchAll && identity.realmName && identity.realmName === 'master') {
|
|
788
777
|
return {
|
|
789
778
|
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
790
779
|
};
|
|
791
780
|
}
|
|
792
781
|
let keys;
|
|
793
|
-
if (policy.
|
|
794
|
-
if (Array.isArray(policy.
|
|
795
|
-
keys = policy.
|
|
782
|
+
if (policy.attribute_name) {
|
|
783
|
+
if (Array.isArray(policy.attribute_name)) {
|
|
784
|
+
keys = policy.attribute_name;
|
|
796
785
|
} else {
|
|
797
786
|
keys = [
|
|
798
|
-
policy.
|
|
787
|
+
policy.attribute_name
|
|
799
788
|
];
|
|
800
789
|
}
|
|
801
790
|
} else {
|
|
@@ -805,22 +794,22 @@ class RealmMatchPolicyEvaluator {
|
|
|
805
794
|
'realmId',
|
|
806
795
|
'realmName'
|
|
807
796
|
];
|
|
808
|
-
policy.
|
|
797
|
+
policy.decision_strategy = DecisionStrategy.CONSENSUS;
|
|
809
798
|
}
|
|
810
|
-
const
|
|
811
|
-
if (!
|
|
799
|
+
const attribute_name_strict = policy.attribute_name_strict ?? true;
|
|
800
|
+
if (!attribute_name_strict) {
|
|
812
801
|
const resourceKeys = Object.keys(attributes);
|
|
813
802
|
const keysToAdd = [];
|
|
814
|
-
for(
|
|
803
|
+
for (const resourceKey of resourceKeys){
|
|
815
804
|
let contains = false;
|
|
816
|
-
for(
|
|
817
|
-
if (
|
|
805
|
+
for (const key of keys){
|
|
806
|
+
if (resourceKey !== key && resourceKey.includes(key)) {
|
|
818
807
|
contains = true;
|
|
819
808
|
break;
|
|
820
809
|
}
|
|
821
810
|
}
|
|
822
811
|
if (contains) {
|
|
823
|
-
keysToAdd.push(
|
|
812
|
+
keysToAdd.push(resourceKey);
|
|
824
813
|
}
|
|
825
814
|
}
|
|
826
815
|
if (keysToAdd.length > 0) {
|
|
@@ -828,26 +817,28 @@ class RealmMatchPolicyEvaluator {
|
|
|
828
817
|
}
|
|
829
818
|
}
|
|
830
819
|
let count = 0;
|
|
831
|
-
|
|
832
|
-
|
|
820
|
+
let evaluated = false;
|
|
821
|
+
for (const key of keys){
|
|
822
|
+
if (!hasOwnProperty(attributes, key)) {
|
|
833
823
|
continue;
|
|
834
824
|
}
|
|
825
|
+
evaluated = true;
|
|
835
826
|
let outcome = false;
|
|
836
|
-
const attributeValue = attributes[
|
|
837
|
-
if (attributeValue === null && policy.
|
|
827
|
+
const attributeValue = attributes[key];
|
|
828
|
+
if (attributeValue === null && policy.attribute_null_match_all) {
|
|
838
829
|
outcome = true;
|
|
839
830
|
} else if (attributeValue === identity.realmId || attributeValue === identity.realmName) {
|
|
840
831
|
outcome = true;
|
|
841
832
|
}
|
|
842
833
|
if (outcome) {
|
|
843
|
-
if (policy.
|
|
834
|
+
if (policy.decision_strategy === DecisionStrategy.AFFIRMATIVE) {
|
|
844
835
|
return {
|
|
845
836
|
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
846
837
|
};
|
|
847
838
|
}
|
|
848
839
|
count++;
|
|
849
840
|
} else {
|
|
850
|
-
if (policy.
|
|
841
|
+
if (policy.decision_strategy === DecisionStrategy.UNANIMOUS) {
|
|
851
842
|
return {
|
|
852
843
|
success: maybeInvertPolicyOutcome(false, policy.invert)
|
|
853
844
|
};
|
|
@@ -855,6 +846,11 @@ class RealmMatchPolicyEvaluator {
|
|
|
855
846
|
count--;
|
|
856
847
|
}
|
|
857
848
|
}
|
|
849
|
+
if (!evaluated) {
|
|
850
|
+
return {
|
|
851
|
+
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
852
|
+
};
|
|
853
|
+
}
|
|
858
854
|
return {
|
|
859
855
|
success: maybeInvertPolicyOutcome(count > 0, policy.invert)
|
|
860
856
|
};
|
|
@@ -887,9 +883,9 @@ function isIntervalForDayOfYear(interval) {
|
|
|
887
883
|
class TimePolicyValidator extends Container {
|
|
888
884
|
initialize() {
|
|
889
885
|
super.initialize();
|
|
890
|
-
this.mount('
|
|
891
|
-
this.mount('
|
|
892
|
-
this.mount('
|
|
886
|
+
this.mount('day_of_week', createValidator(z.number().min(0).max(6).or(z.null()).or(z.undefined()).optional()));
|
|
887
|
+
this.mount('day_of_month', createValidator(z.number().min(1).max(31).or(z.null()).or(z.undefined()).optional()));
|
|
888
|
+
this.mount('day_of_year', createValidator(z.number().min(1).max(365).or(z.null()).or(z.undefined()).optional()));
|
|
893
889
|
this.mount('start', createValidator(z.date().or(z.iso.datetime()).or(z.iso.time()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
|
|
894
890
|
this.mount('end', createValidator(z.date().or(z.iso.datetime()).or(z.iso.time()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
|
|
895
891
|
this.mount('interval', createValidator(z.enum(TimePolicyInterval).or(z.null()).or(z.undefined()).optional()));
|
|
@@ -956,26 +952,26 @@ class TimePolicyEvaluator {
|
|
|
956
952
|
}
|
|
957
953
|
}
|
|
958
954
|
if (policy.interval) {
|
|
959
|
-
if (isIntervalForDayOfWeek(policy.interval) && policy.
|
|
960
|
-
if (now.getDay() !== policy.
|
|
955
|
+
if (isIntervalForDayOfWeek(policy.interval) && policy.day_of_week) {
|
|
956
|
+
if (now.getDay() !== policy.day_of_week) {
|
|
961
957
|
return {
|
|
962
958
|
success: maybeInvertPolicyOutcome(false, policy.invert)
|
|
963
959
|
};
|
|
964
960
|
}
|
|
965
961
|
}
|
|
966
|
-
if (isIntervalForDayOfMonth(policy.interval) && policy.
|
|
967
|
-
if (now.getDate() !== policy.
|
|
962
|
+
if (isIntervalForDayOfMonth(policy.interval) && policy.day_of_month) {
|
|
963
|
+
if (now.getDate() !== policy.day_of_month) {
|
|
968
964
|
return {
|
|
969
965
|
success: maybeInvertPolicyOutcome(false, policy.invert)
|
|
970
966
|
};
|
|
971
967
|
}
|
|
972
968
|
}
|
|
973
|
-
if (isIntervalForDayOfYear(policy.interval) && policy.
|
|
969
|
+
if (isIntervalForDayOfYear(policy.interval) && policy.day_of_year) {
|
|
974
970
|
const start = new Date(now.getFullYear(), 0, 0);
|
|
975
971
|
const diff = now.getTime() - start.getTime() + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
|
|
976
972
|
const oneDay = 1000 * 60 * 60 * 24;
|
|
977
973
|
const dayOfYear = Math.floor(diff / oneDay);
|
|
978
|
-
if (dayOfYear !== policy.
|
|
974
|
+
if (dayOfYear !== policy.day_of_year) {
|
|
979
975
|
return {
|
|
980
976
|
success: maybeInvertPolicyOutcome(false, policy.invert)
|
|
981
977
|
};
|
|
@@ -1011,73 +1007,22 @@ const PolicyDefaultEvaluators = {
|
|
|
1011
1007
|
[BuiltInPolicyType.TIME]: new TimePolicyEvaluator()
|
|
1012
1008
|
};
|
|
1013
1009
|
|
|
1014
|
-
|
|
1015
|
-
const grouped = input.reduce((previous, current)=>{
|
|
1016
|
-
const key = buildPermissionItemKey(current);
|
|
1017
|
-
if (!previous[key]) {
|
|
1018
|
-
previous[key] = [];
|
|
1019
|
-
}
|
|
1020
|
-
previous[key].push(current);
|
|
1021
|
-
return previous;
|
|
1022
|
-
}, {});
|
|
1023
|
-
const output = [];
|
|
1024
|
-
const keys = Object.keys(grouped);
|
|
1025
|
-
for(let i = 0; i < keys.length; i++){
|
|
1026
|
-
const [permission, ...permissions] = grouped[keys[i]];
|
|
1027
|
-
if (permissions.length > 0) {
|
|
1028
|
-
const policy = {
|
|
1029
|
-
type: BuiltInPolicyType.COMPOSITE,
|
|
1030
|
-
decisionStrategy: DecisionStrategy.AFFIRMATIVE,
|
|
1031
|
-
children: permissions.map((el)=>el.policy).filter((el)=>typeof el !== 'undefined')
|
|
1032
|
-
};
|
|
1033
|
-
if (permission.policy) {
|
|
1034
|
-
policy.children.push(permission.policy);
|
|
1035
|
-
}
|
|
1036
|
-
if (policy.children.length > 0) {
|
|
1037
|
-
permission.policy = policy;
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
output.push(permission);
|
|
1041
|
-
}
|
|
1042
|
-
return output;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
class PermissionMemoryRepository {
|
|
1046
|
-
items = {};
|
|
1047
|
-
constructor(items = []){
|
|
1048
|
-
this.setMany(items);
|
|
1049
|
-
}
|
|
1050
|
-
async findOne(options) {
|
|
1051
|
-
const entry = this.items[buildPermissionItemKey(options)];
|
|
1052
|
-
if (entry) {
|
|
1053
|
-
return entry;
|
|
1054
|
-
}
|
|
1055
|
-
return null;
|
|
1056
|
-
}
|
|
1057
|
-
setMany(input) {
|
|
1058
|
-
this.items = mergePermissionItems(input).reduce((prev, current)=>{
|
|
1059
|
-
prev[buildPermissionItemKey(current)] = current;
|
|
1060
|
-
return prev;
|
|
1061
|
-
}, {});
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
class PermissionChecker {
|
|
1010
|
+
class PermissionEvaluator {
|
|
1066
1011
|
provider;
|
|
1067
1012
|
policyEngine;
|
|
1068
1013
|
clientId;
|
|
1069
1014
|
realmId;
|
|
1070
1015
|
// ----------------------------------------------
|
|
1071
1016
|
constructor(options = {}){
|
|
1072
|
-
if (options.
|
|
1073
|
-
this.provider = options.
|
|
1017
|
+
if (options.provider) {
|
|
1018
|
+
this.provider = options.provider;
|
|
1074
1019
|
} else {
|
|
1075
|
-
this.provider = new
|
|
1020
|
+
this.provider = new PermissionMemoryProvider();
|
|
1076
1021
|
}
|
|
1077
|
-
if (options.clientId) {
|
|
1022
|
+
if (typeof options.clientId !== 'undefined') {
|
|
1078
1023
|
this.clientId = options.clientId;
|
|
1079
1024
|
}
|
|
1080
|
-
if (options.realmId) {
|
|
1025
|
+
if (typeof options.realmId !== 'undefined') {
|
|
1081
1026
|
this.realmId = options.realmId;
|
|
1082
1027
|
}
|
|
1083
1028
|
if (options.policyEngine) {
|
|
@@ -1087,32 +1032,26 @@ class PermissionChecker {
|
|
|
1087
1032
|
}
|
|
1088
1033
|
}
|
|
1089
1034
|
// ----------------------------------------------
|
|
1090
|
-
|
|
1091
|
-
* Get a permission.
|
|
1092
|
-
*
|
|
1093
|
-
* @param input
|
|
1094
|
-
*/ async findOne(input) {
|
|
1035
|
+
async findOne(input, overrides) {
|
|
1095
1036
|
const options = {
|
|
1096
1037
|
name: input
|
|
1097
1038
|
};
|
|
1098
|
-
if (
|
|
1039
|
+
if (typeof overrides?.clientId !== 'undefined') {
|
|
1040
|
+
options.clientId = overrides.clientId;
|
|
1041
|
+
} else if (typeof this.clientId !== 'undefined') {
|
|
1099
1042
|
options.clientId = this.clientId;
|
|
1100
1043
|
}
|
|
1101
|
-
if (
|
|
1044
|
+
if (typeof overrides?.realmId !== 'undefined') {
|
|
1045
|
+
options.realmId = overrides.realmId;
|
|
1046
|
+
} else if (typeof this.realmId !== 'undefined') {
|
|
1102
1047
|
options.realmId = this.realmId;
|
|
1103
1048
|
}
|
|
1104
1049
|
return this.provider.findOne(options);
|
|
1105
1050
|
}
|
|
1106
1051
|
// ----------------------------------------------
|
|
1107
|
-
|
|
1108
|
-
* Verify if one or more possible owned permissions satisfy their conditions.
|
|
1109
|
-
*
|
|
1110
|
-
* @throws PermissionError
|
|
1111
|
-
*
|
|
1112
|
-
* @param ctx
|
|
1113
|
-
*/ async check(ctx) {
|
|
1052
|
+
async evaluate(ctx) {
|
|
1114
1053
|
if (!Array.isArray(ctx.name)) {
|
|
1115
|
-
await this.
|
|
1054
|
+
await this.evaluate({
|
|
1116
1055
|
...ctx,
|
|
1117
1056
|
name: [
|
|
1118
1057
|
ctx.name
|
|
@@ -1126,8 +1065,11 @@ class PermissionChecker {
|
|
|
1126
1065
|
let count = 0;
|
|
1127
1066
|
const dataBase = ctx.input || new PolicyData();
|
|
1128
1067
|
for(let i = 0; i < ctx.name.length; i++){
|
|
1129
|
-
const
|
|
1130
|
-
|
|
1068
|
+
const binding = await this.findOne(ctx.name[i], {
|
|
1069
|
+
realmId: ctx.realmId,
|
|
1070
|
+
clientId: ctx.clientId
|
|
1071
|
+
});
|
|
1072
|
+
if (!binding) {
|
|
1131
1073
|
issues.push(defineIssueItem({
|
|
1132
1074
|
code: ErrorCode.PERMISSION_NOT_FOUND,
|
|
1133
1075
|
message: `The ${ctx.name[i]} permission could not be resolved`,
|
|
@@ -1142,7 +1084,8 @@ class PermissionChecker {
|
|
|
1142
1084
|
}
|
|
1143
1085
|
continue;
|
|
1144
1086
|
}
|
|
1145
|
-
|
|
1087
|
+
const policies = binding.policies ?? [];
|
|
1088
|
+
if (policies.length === 0) {
|
|
1146
1089
|
if (decisionStrategy === DecisionStrategy.AFFIRMATIVE) {
|
|
1147
1090
|
return;
|
|
1148
1091
|
}
|
|
@@ -1150,8 +1093,14 @@ class PermissionChecker {
|
|
|
1150
1093
|
continue;
|
|
1151
1094
|
}
|
|
1152
1095
|
const data = dataBase.clone();
|
|
1153
|
-
data.set(BuiltInPolicyType.PERMISSION_BINDING,
|
|
1154
|
-
const
|
|
1096
|
+
data.set(BuiltInPolicyType.PERMISSION_BINDING, binding);
|
|
1097
|
+
const policyDecisionStrategy = binding.permission.decision_strategy ?? DecisionStrategy.UNANIMOUS;
|
|
1098
|
+
const compositePolicy = {
|
|
1099
|
+
type: BuiltInPolicyType.COMPOSITE,
|
|
1100
|
+
decision_strategy: policyDecisionStrategy,
|
|
1101
|
+
children: policies
|
|
1102
|
+
};
|
|
1103
|
+
const evaluationResult = await this.policyEngine.evaluate(compositePolicy, definePolicyEvaluationContext({
|
|
1155
1104
|
include: options.policiesIncluded,
|
|
1156
1105
|
exclude: options.policiesExcluded,
|
|
1157
1106
|
data
|
|
@@ -1165,13 +1114,13 @@ class PermissionChecker {
|
|
|
1165
1114
|
issues.push(definePolicyIssueGroup({
|
|
1166
1115
|
code: ErrorCode.PERMISSION_EVALUATION_FAILED,
|
|
1167
1116
|
issues: evaluationResult.issues || [],
|
|
1168
|
-
message: `The ${
|
|
1117
|
+
message: `The ${binding.permission.name} permissions policy evaluation failed`,
|
|
1169
1118
|
path: [
|
|
1170
|
-
|
|
1119
|
+
binding.permission.name
|
|
1171
1120
|
]
|
|
1172
1121
|
}));
|
|
1173
1122
|
if (decisionStrategy === DecisionStrategy.UNANIMOUS) {
|
|
1174
|
-
const error = PermissionError.evaluationFailed(
|
|
1123
|
+
const error = PermissionError.evaluationFailed(binding.permission.name);
|
|
1175
1124
|
error.addIssues(issues);
|
|
1176
1125
|
throw error;
|
|
1177
1126
|
}
|
|
@@ -1189,14 +1138,8 @@ class PermissionChecker {
|
|
|
1189
1138
|
throw error;
|
|
1190
1139
|
}
|
|
1191
1140
|
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
*
|
|
1195
|
-
* @throws PermissionError
|
|
1196
|
-
*
|
|
1197
|
-
* @param ctx
|
|
1198
|
-
*/ async checkOneOf(ctx) {
|
|
1199
|
-
return this.check({
|
|
1141
|
+
async evaluateOneOf(ctx) {
|
|
1142
|
+
return this.evaluate({
|
|
1200
1143
|
...ctx,
|
|
1201
1144
|
options: {
|
|
1202
1145
|
...ctx.options || {},
|
|
@@ -1205,8 +1148,8 @@ class PermissionChecker {
|
|
|
1205
1148
|
});
|
|
1206
1149
|
}
|
|
1207
1150
|
// ----------------------------------------------
|
|
1208
|
-
async
|
|
1209
|
-
return this.
|
|
1151
|
+
async preEvaluate(ctx) {
|
|
1152
|
+
return this.evaluate({
|
|
1210
1153
|
...ctx,
|
|
1211
1154
|
options: {
|
|
1212
1155
|
...ctx.options || {},
|
|
@@ -1218,8 +1161,8 @@ class PermissionChecker {
|
|
|
1218
1161
|
}
|
|
1219
1162
|
});
|
|
1220
1163
|
}
|
|
1221
|
-
async
|
|
1222
|
-
return this.
|
|
1164
|
+
async preEvaluateOneOf(ctx) {
|
|
1165
|
+
return this.preEvaluate({
|
|
1223
1166
|
...ctx,
|
|
1224
1167
|
options: {
|
|
1225
1168
|
...ctx.options || {},
|
|
@@ -1229,5 +1172,5 @@ class PermissionChecker {
|
|
|
1229
1172
|
}
|
|
1230
1173
|
}
|
|
1231
1174
|
|
|
1232
|
-
export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator,
|
|
1175
|
+
export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, IdentityPolicyEvaluator, IdentityPolicyValidator, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionError, PermissionEvaluator, PermissionMemoryProvider, PolicyData, PolicyDefaultEvaluators, PolicyEngine, PolicyError, PolicyIssueCode, PolicyIssueSeverity, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, SystemPolicyName, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, defineAttributesPolicy, definePolicyEvaluationContext, definePolicyIssueGroup, definePolicyIssueItem, definePolicyWithType, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, maybeInvertPolicyOutcome };
|
|
1233
1176
|
//# sourceMappingURL=index.mjs.map
|