@authup/access 1.0.0-beta.33 → 1.0.0-beta.35
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/dist/index.d.mts +547 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +980 -1149
- package/dist/index.mjs.map +1 -1
- package/dist/permission/evaluator/module.d.ts +3 -3
- package/dist/permission/evaluator/module.d.ts.map +1 -1
- package/dist/permission/evaluator/types.d.ts +1 -1
- package/dist/permission/evaluator/types.d.ts.map +1 -1
- package/dist/permission/helpers/equal.d.ts +2 -1
- package/dist/permission/helpers/equal.d.ts.map +1 -1
- package/dist/permission/helpers/index.d.ts +1 -1
- package/dist/permission/helpers/index.d.ts.map +1 -1
- package/dist/permission/helpers/key.d.ts +2 -1
- package/dist/permission/helpers/key.d.ts.map +1 -1
- package/dist/permission/helpers/merge.d.ts +2 -1
- package/dist/permission/helpers/merge.d.ts.map +1 -1
- package/dist/permission/provider/memory.d.ts +5 -5
- package/dist/permission/provider/memory.d.ts.map +1 -1
- package/dist/permission/provider/types.d.ts +2 -2
- package/dist/permission/provider/types.d.ts.map +1 -1
- package/dist/permission/types.d.ts +12 -1
- package/dist/permission/types.d.ts.map +1 -1
- package/dist/policy/built-in/attribute-names/types.d.ts +2 -2
- package/dist/policy/built-in/attribute-names/validator.d.ts.map +1 -1
- package/dist/policy/built-in/attributes/types.d.ts +2 -2
- package/dist/policy/built-in/attributes/validator.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 +3 -3
- 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/date/types.d.ts +2 -2
- package/dist/policy/built-in/date/validator.d.ts.map +1 -1
- package/dist/policy/built-in/identity/data/validator.d.ts.map +1 -1
- package/dist/policy/built-in/identity/types.d.ts +2 -2
- package/dist/policy/built-in/identity/validator.d.ts +1 -1
- package/dist/policy/built-in/identity/validator.d.ts.map +1 -1
- package/dist/policy/built-in/permission-binding/types.d.ts +2 -2
- package/dist/policy/built-in/permission-binding/validator.d.ts +1 -1
- package/dist/policy/built-in/permission-binding/validator.d.ts.map +1 -1
- package/dist/policy/built-in/realm-match/types.d.ts +2 -2
- package/dist/policy/built-in/realm-match/validator.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 +2 -2
- package/dist/policy/built-in/time/validator.d.ts.map +1 -1
- package/dist/policy/engine/module.d.ts +3 -3
- package/dist/policy/engine/module.d.ts.map +1 -1
- package/dist/policy/engine/types.d.ts +3 -3
- package/dist/policy/engine/types.d.ts.map +1 -1
- package/dist/policy/types.d.ts +6 -8
- package/dist/policy/types.d.ts.map +1 -1
- package/package.json +9 -12
package/dist/index.mjs
CHANGED
|
@@ -1,1176 +1,1007 @@
|
|
|
1
|
-
import { AuthupError, ErrorCode } from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
1
|
+
import { AuthupError, ErrorCode } from "@authup/errors";
|
|
2
|
+
import { DecisionStrategy, DecisionStrategy as DecisionStrategy$1, flattenObject, hasOwnProperty, isObject } from "@authup/kit";
|
|
3
|
+
import { Container, defineIssueGroup, defineIssueItem } from "validup";
|
|
4
|
+
import { createValidator } from "@validup/adapter-zod";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { guard } from "@ucast/mongo2js";
|
|
7
|
+
//#region src/permission/error/module.ts
|
|
8
|
+
var PermissionError = class PermissionError extends AuthupError {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
super({
|
|
11
|
+
...options,
|
|
12
|
+
message: options.message || "A permission error occurred.",
|
|
13
|
+
statusCode: options.statusCode || 403
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
addIssue(data) {
|
|
17
|
+
this.issues.push(data);
|
|
18
|
+
}
|
|
19
|
+
addIssues(data) {
|
|
20
|
+
this.issues.push(...data);
|
|
21
|
+
}
|
|
22
|
+
static notFound(name) {
|
|
23
|
+
return new PermissionError({
|
|
24
|
+
message: `The permission ${name} was not found.`,
|
|
25
|
+
code: ErrorCode.PERMISSION_NOT_FOUND
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
static denied(name) {
|
|
29
|
+
return new PermissionError({
|
|
30
|
+
message: `The permission ${name} has not been granted.`,
|
|
31
|
+
code: ErrorCode.PERMISSION_DENIED
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
static deniedAll(names) {
|
|
35
|
+
return new PermissionError({
|
|
36
|
+
message: `None of the permissions ${names.join(", ")} has been granted.`,
|
|
37
|
+
code: ErrorCode.PERMISSION_DENIED
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
static evaluationFailed(name) {
|
|
41
|
+
if (Array.isArray(name)) return new PermissionError({
|
|
42
|
+
message: `The evaluation of permissions ${name.join(", ")} failed`,
|
|
43
|
+
code: ErrorCode.PERMISSION_EVALUATION_FAILED
|
|
44
|
+
});
|
|
45
|
+
return new PermissionError({
|
|
46
|
+
message: `The evaluation of permission ${name} failed`,
|
|
47
|
+
code: ErrorCode.PERMISSION_EVALUATION_FAILED
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/permission/helpers/equal.ts
|
|
53
|
+
function isPermissionPolicyBindingEqual(a, b) {
|
|
54
|
+
if (a.permission.name !== b.permission.name) return false;
|
|
55
|
+
if ((a.permission.realm_id ?? null) !== (b.permission.realm_id ?? null)) return false;
|
|
56
|
+
if ((a.permission.client_id ?? null) !== (b.permission.client_id ?? null)) return false;
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/permission/helpers/key.ts
|
|
61
|
+
function formatKeySegment(value) {
|
|
62
|
+
return value || "*";
|
|
63
|
+
}
|
|
64
|
+
function buildPermissionKey(input) {
|
|
65
|
+
return `${formatKeySegment(input.realm_id)}/${formatKeySegment(input.client_id)}/${input.name}`;
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region src/permission/helpers/merge.ts
|
|
69
|
+
function mergePermissionPolicyBindings(input) {
|
|
70
|
+
const grouped = input.reduce((previous, current) => {
|
|
71
|
+
const key = buildPermissionKey(current.permission);
|
|
72
|
+
if (!previous[key]) previous[key] = [];
|
|
73
|
+
previous[key].push(current);
|
|
74
|
+
return previous;
|
|
75
|
+
}, {});
|
|
76
|
+
const output = [];
|
|
77
|
+
const keys = Object.keys(grouped);
|
|
78
|
+
for (const key of keys) {
|
|
79
|
+
const group = grouped[key];
|
|
80
|
+
const first = group[0];
|
|
81
|
+
if (group.length === 1) {
|
|
82
|
+
output.push(first);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const children = [];
|
|
86
|
+
for (const element of group) {
|
|
87
|
+
if (!element.policies || element.policies.length === 0) continue;
|
|
88
|
+
const policy = {
|
|
89
|
+
type: "composite",
|
|
90
|
+
decision_strategy: element.permission.decision_strategy || DecisionStrategy$1.UNANIMOUS,
|
|
91
|
+
children: element.policies
|
|
92
|
+
};
|
|
93
|
+
children.push(policy);
|
|
94
|
+
}
|
|
95
|
+
let mergedPolicies;
|
|
96
|
+
if (children.length > 0 && children.length === group.length) mergedPolicies = [{
|
|
97
|
+
type: "composite",
|
|
98
|
+
decision_strategy: DecisionStrategy$1.AFFIRMATIVE,
|
|
99
|
+
children
|
|
100
|
+
}];
|
|
101
|
+
output.push({
|
|
102
|
+
permission: {
|
|
103
|
+
...first.permission,
|
|
104
|
+
decision_strategy: DecisionStrategy$1.AFFIRMATIVE
|
|
105
|
+
},
|
|
106
|
+
policies: mergedPolicies
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return output;
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region src/permission/provider/memory.ts
|
|
113
|
+
var PermissionMemoryProvider = class {
|
|
114
|
+
items = {};
|
|
115
|
+
constructor(items = []) {
|
|
116
|
+
this.setMany(items);
|
|
117
|
+
}
|
|
118
|
+
async findOne(options) {
|
|
119
|
+
const key = buildPermissionKey({
|
|
120
|
+
name: options.name,
|
|
121
|
+
client_id: options.clientId,
|
|
122
|
+
realm_id: options.realmId
|
|
123
|
+
});
|
|
124
|
+
const entry = this.items[key];
|
|
125
|
+
if (entry) return entry;
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
setMany(input) {
|
|
129
|
+
this.items = mergePermissionPolicyBindings(input).reduce((prev, current) => {
|
|
130
|
+
const key = buildPermissionKey(current.permission);
|
|
131
|
+
prev[key] = current;
|
|
132
|
+
return prev;
|
|
133
|
+
}, {});
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/policy/helpers/invert.ts
|
|
138
|
+
function maybeInvertPolicyOutcome(outcome, invert) {
|
|
139
|
+
if (typeof invert === "undefined") return outcome;
|
|
140
|
+
if (typeof invert === "function") return invert(outcome);
|
|
141
|
+
if (!invert) return outcome;
|
|
142
|
+
return !outcome;
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/policy/error/module.ts
|
|
146
|
+
var PolicyError = class PolicyError extends AuthupError {
|
|
147
|
+
constructor(message, code) {
|
|
148
|
+
super({
|
|
149
|
+
message,
|
|
150
|
+
code
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
addIssue(data) {
|
|
154
|
+
this.issues.push(data);
|
|
155
|
+
}
|
|
156
|
+
addIssues(data) {
|
|
157
|
+
this.issues.push(...data);
|
|
158
|
+
}
|
|
159
|
+
static evaluatorNotFound(type) {
|
|
160
|
+
return new PolicyError(`No evaluator is registered to handle the policy: ${type}`, ErrorCode.POLICY_EVALUATOR_NOT_FOUND);
|
|
161
|
+
}
|
|
162
|
+
static evaluatorNotProcessable() {
|
|
163
|
+
return new PolicyError("The evaluator can not process the policy.", ErrorCode.POLICY_EVALUATOR_NOT_PROCESSABLE);
|
|
164
|
+
}
|
|
165
|
+
static evaluatorContextInvalid() {
|
|
166
|
+
return new PolicyError("The evaluator context is not valid.", ErrorCode.POLICY_EVALUATOR_CONTEXT_INVALID);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/policy/engine/module.ts
|
|
123
171
|
/**
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
throw new Error(`Policy data item ${key} does not exist.`);
|
|
234
|
-
}
|
|
235
|
-
has(key) {
|
|
236
|
-
return key in this.data;
|
|
237
|
-
}
|
|
238
|
-
setValidated(key) {
|
|
239
|
-
this.validated.add(key);
|
|
240
|
-
}
|
|
241
|
-
isValidated(key) {
|
|
242
|
-
return this.validated.has(key);
|
|
243
|
-
}
|
|
244
|
-
clone() {
|
|
245
|
-
return new PolicyData({
|
|
246
|
-
...this.data
|
|
247
|
-
}, new Set(this.validated));
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
172
|
+
* The policy engine is a component that interprets defined policies and makes decisions
|
|
173
|
+
* on whether to allow or deny a particular access.
|
|
174
|
+
*/
|
|
175
|
+
var PolicyEngine = class {
|
|
176
|
+
evaluators;
|
|
177
|
+
constructor(evaluators = {}) {
|
|
178
|
+
this.evaluators = evaluators;
|
|
179
|
+
}
|
|
180
|
+
registerEvaluator(type, evaluator) {
|
|
181
|
+
this.evaluators[type] = evaluator;
|
|
182
|
+
}
|
|
183
|
+
registerEvaluators(evaluators) {
|
|
184
|
+
const keys = Object.keys(evaluators);
|
|
185
|
+
for (const key of keys) this.registerEvaluator(key, evaluators[key]);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* @param policy
|
|
189
|
+
* @param ctx
|
|
190
|
+
*/
|
|
191
|
+
async evaluate(policy, ctx) {
|
|
192
|
+
if (!policy.type) return {
|
|
193
|
+
success: maybeInvertPolicyOutcome(false, policy.invert),
|
|
194
|
+
issues: [defineIssueItem({
|
|
195
|
+
path: [],
|
|
196
|
+
message: "The policy can not be handled by any evaluator.",
|
|
197
|
+
code: ErrorCode.POLICY_EVALUATOR_NOT_FOUND
|
|
198
|
+
})]
|
|
199
|
+
};
|
|
200
|
+
if (ctx.exclude && ctx.exclude.length > 0 && ctx.exclude.includes(policy.type)) return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
201
|
+
if (ctx.include && ctx.include.length > 0 && !ctx.include.includes(policy.type)) return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
202
|
+
const issues = [];
|
|
203
|
+
const evaluator = this.evaluators[policy.type];
|
|
204
|
+
if (!evaluator) {
|
|
205
|
+
issues.push(defineIssueItem({
|
|
206
|
+
path: [policy.type],
|
|
207
|
+
message: `The policy ${policy.type} can not be handled by any evaluator.`,
|
|
208
|
+
code: ErrorCode.POLICY_EVALUATOR_NOT_FOUND
|
|
209
|
+
}));
|
|
210
|
+
return {
|
|
211
|
+
success: maybeInvertPolicyOutcome(false, policy.invert),
|
|
212
|
+
issues
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
return await evaluator.evaluate(policy, {
|
|
217
|
+
...ctx,
|
|
218
|
+
evaluators: {
|
|
219
|
+
...this.evaluators,
|
|
220
|
+
...ctx.evaluators || {}
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
} catch {
|
|
224
|
+
issues.push(defineIssueItem({
|
|
225
|
+
path: [policy.type],
|
|
226
|
+
message: `The ${policy.type} evaluator can not process the policy specification.`,
|
|
227
|
+
code: ErrorCode.POLICY_EVALUATOR_NOT_PROCESSABLE
|
|
228
|
+
}));
|
|
229
|
+
return {
|
|
230
|
+
success: maybeInvertPolicyOutcome(false, policy.invert),
|
|
231
|
+
issues
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async evaluateOrFail(policy, ctx) {
|
|
236
|
+
const issues = [];
|
|
237
|
+
try {
|
|
238
|
+
const outcome = await this.evaluate(policy, ctx);
|
|
239
|
+
if (outcome.success) return;
|
|
240
|
+
if (outcome.issues) issues.push(...outcome.issues);
|
|
241
|
+
} catch (e) {
|
|
242
|
+
if (e instanceof PolicyError) throw e;
|
|
243
|
+
}
|
|
244
|
+
const error = new PolicyError(`The policy ${policy.type} evaluation failed.`);
|
|
245
|
+
error.addIssues(issues);
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
//#endregion
|
|
250
|
+
//#region src/policy/data.ts
|
|
251
|
+
var PolicyData = class PolicyData {
|
|
252
|
+
data;
|
|
253
|
+
validated;
|
|
254
|
+
constructor(data = {}, validated = /* @__PURE__ */ new Set()) {
|
|
255
|
+
this.data = data;
|
|
256
|
+
this.validated = validated;
|
|
257
|
+
}
|
|
258
|
+
set(key, value) {
|
|
259
|
+
this.data[key] = value;
|
|
260
|
+
this.validated.delete(key);
|
|
261
|
+
}
|
|
262
|
+
get(key) {
|
|
263
|
+
if (key in this.data) return this.data[key];
|
|
264
|
+
throw new Error(`Policy data item ${key} does not exist.`);
|
|
265
|
+
}
|
|
266
|
+
has(key) {
|
|
267
|
+
return key in this.data;
|
|
268
|
+
}
|
|
269
|
+
setValidated(key) {
|
|
270
|
+
this.validated.add(key);
|
|
271
|
+
}
|
|
272
|
+
isValidated(key) {
|
|
273
|
+
return this.validated.has(key);
|
|
274
|
+
}
|
|
275
|
+
clone() {
|
|
276
|
+
return new PolicyData({ ...this.data }, new Set(this.validated));
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/policy/evaluation/context/define.ts
|
|
251
281
|
function definePolicyEvaluationContext(input = {}) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
*/ var PolicyIssueSeverity = /*#__PURE__*/ function(PolicyIssueSeverity) {
|
|
267
|
-
PolicyIssueSeverity["WARNING"] = "warning";
|
|
268
|
-
PolicyIssueSeverity["ERROR"] = "error";
|
|
269
|
-
return PolicyIssueSeverity;
|
|
282
|
+
return {
|
|
283
|
+
evaluators: input.evaluators || {},
|
|
284
|
+
path: input.path || [],
|
|
285
|
+
data: input.data || new PolicyData(),
|
|
286
|
+
include: input.include || [],
|
|
287
|
+
exclude: input.exclude || []
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
//#region src/policy/issue/constants.ts
|
|
292
|
+
let PolicyIssueSeverity = /* @__PURE__ */ function(PolicyIssueSeverity) {
|
|
293
|
+
PolicyIssueSeverity["WARNING"] = "warning";
|
|
294
|
+
PolicyIssueSeverity["ERROR"] = "error";
|
|
295
|
+
return PolicyIssueSeverity;
|
|
270
296
|
}({});
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// Execution control
|
|
288
|
-
PolicyIssueCode["SKIPPED_EXCLUDED"] = "SKIPPED_EXCLUDED";
|
|
289
|
-
PolicyIssueCode["SKIPPED_NOT_INCLUDED"] = "SKIPPED_NOT_INCLUDED";
|
|
290
|
-
// Internal / unexpected
|
|
291
|
-
PolicyIssueCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
|
|
292
|
-
return PolicyIssueCode;
|
|
297
|
+
let PolicyIssueCode = /* @__PURE__ */ function(PolicyIssueCode) {
|
|
298
|
+
PolicyIssueCode["DATA_MISSING"] = "DATA_MISSING";
|
|
299
|
+
PolicyIssueCode["DATA_INVALID"] = "DATA_INVALID";
|
|
300
|
+
PolicyIssueCode["INVALID"] = "INVALID";
|
|
301
|
+
PolicyIssueCode["TYPE_UNKNOWN"] = "TYPE_UNKNOWN";
|
|
302
|
+
PolicyIssueCode["FIELD_MISSING"] = "FIELD_MISSING";
|
|
303
|
+
PolicyIssueCode["FIELD_INVALID"] = "FIELD_INVALID";
|
|
304
|
+
PolicyIssueCode["CHILD_INVALID"] = "CHILD_INVALID";
|
|
305
|
+
PolicyIssueCode["CHILD_EVALUATION_FAILED"] = "CHILD_EVALUATION_FAILED";
|
|
306
|
+
PolicyIssueCode["EVALUATION_DENIED"] = "EVALUATION_DENIED";
|
|
307
|
+
PolicyIssueCode["EVALUATOR_NOT_FOUND"] = "EVALUATOR_NOT_FOUND";
|
|
308
|
+
PolicyIssueCode["EVALUATOR_ERROR"] = "EVALUATOR_ERROR";
|
|
309
|
+
PolicyIssueCode["SKIPPED_EXCLUDED"] = "SKIPPED_EXCLUDED";
|
|
310
|
+
PolicyIssueCode["SKIPPED_NOT_INCLUDED"] = "SKIPPED_NOT_INCLUDED";
|
|
311
|
+
PolicyIssueCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
|
|
312
|
+
return PolicyIssueCode;
|
|
293
313
|
}({});
|
|
294
|
-
|
|
314
|
+
//#endregion
|
|
315
|
+
//#region src/policy/issue/define.ts
|
|
295
316
|
function definePolicyIssueItem(input) {
|
|
296
|
-
|
|
317
|
+
return defineIssueItem(input);
|
|
297
318
|
}
|
|
298
319
|
function definePolicyIssueGroup(input) {
|
|
299
|
-
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
320
|
+
return defineIssueGroup(input);
|
|
321
|
+
}
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/policy/built-in/attribute-names/validator.ts
|
|
324
|
+
var AttributeNamesPolicyValidator = class extends Container {
|
|
325
|
+
initialize() {
|
|
326
|
+
super.initialize();
|
|
327
|
+
this.mount("names", createValidator(z.array(z.string().min(3).max(128))));
|
|
328
|
+
this.mount("invert", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/policy/built-in/attributes/define.ts
|
|
333
|
+
function defineAttributesPolicy(data) {
|
|
334
|
+
return data;
|
|
335
|
+
}
|
|
336
|
+
//#endregion
|
|
337
|
+
//#region src/policy/built-in/constants.ts
|
|
338
|
+
let BuiltInPolicyType = /* @__PURE__ */ function(BuiltInPolicyType) {
|
|
339
|
+
/**
|
|
340
|
+
* Bundles different policies.
|
|
341
|
+
*/
|
|
342
|
+
BuiltInPolicyType["COMPOSITE"] = "composite";
|
|
343
|
+
/**
|
|
344
|
+
* Date Based Access Control (DBAC)
|
|
345
|
+
*/
|
|
346
|
+
BuiltInPolicyType["DATE"] = "date";
|
|
347
|
+
/**
|
|
348
|
+
* Time Based Access Control (TBAC)
|
|
349
|
+
*/
|
|
350
|
+
BuiltInPolicyType["TIME"] = "time";
|
|
351
|
+
/**
|
|
352
|
+
* Attribute Name Based Access Control (ANBAC)
|
|
353
|
+
*/
|
|
354
|
+
BuiltInPolicyType["ATTRIBUTE_NAMES"] = "attributeNames";
|
|
355
|
+
/**
|
|
356
|
+
* Attribute Based Access Control (ABAC)
|
|
357
|
+
*/
|
|
358
|
+
BuiltInPolicyType["ATTRIBUTES"] = "attributes";
|
|
359
|
+
/**
|
|
360
|
+
* Realm of Identity is for attribute realm.
|
|
361
|
+
*/
|
|
362
|
+
BuiltInPolicyType["REALM_MATCH"] = "realmMatch";
|
|
363
|
+
/**
|
|
364
|
+
* Restriction based on identity (type, id, ...)
|
|
365
|
+
*/
|
|
366
|
+
BuiltInPolicyType["IDENTITY"] = "identity";
|
|
367
|
+
/**
|
|
368
|
+
* Restriction based on a binding between identity <-> permission
|
|
369
|
+
*/
|
|
370
|
+
BuiltInPolicyType["PERMISSION_BINDING"] = "permissionBinding";
|
|
371
|
+
return BuiltInPolicyType;
|
|
350
372
|
}({});
|
|
351
373
|
const SystemPolicyName = {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
374
|
+
DEFAULT: "system.default",
|
|
375
|
+
IDENTITY: "system.identity",
|
|
376
|
+
PERMISSION_BINDING: "system.permission-binding",
|
|
377
|
+
REALM_MATCH: "system.realm-match",
|
|
378
|
+
REALM_BOUND: "system.realm-bound",
|
|
379
|
+
REALM_OR_GLOBAL: "system.realm-or-global"
|
|
358
380
|
};
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
issues: []
|
|
518
|
-
};
|
|
519
|
-
}
|
|
520
|
-
count++;
|
|
521
|
-
} else {
|
|
522
|
-
if (outcome.issues) {
|
|
523
|
-
issues.push(defineIssueGroup({
|
|
524
|
-
message: `The evaluation of child policy ${childPolicy.type} failed`,
|
|
525
|
-
issues: outcome.issues || [],
|
|
526
|
-
path
|
|
527
|
-
}));
|
|
528
|
-
}
|
|
529
|
-
if (decision_strategy === DecisionStrategy.UNANIMOUS) {
|
|
530
|
-
return {
|
|
531
|
-
success: maybeInvertPolicyOutcome(false, policy.invert),
|
|
532
|
-
issues: [
|
|
533
|
-
defineIssueGroup({
|
|
534
|
-
message: `The evaluation of composite policy failed (${DecisionStrategy.UNANIMOUS})`,
|
|
535
|
-
issues,
|
|
536
|
-
path: ctx.path
|
|
537
|
-
})
|
|
538
|
-
]
|
|
539
|
-
};
|
|
540
|
-
}
|
|
541
|
-
count--;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
if (count > 0) {
|
|
545
|
-
return {
|
|
546
|
-
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
return {
|
|
550
|
-
success: maybeInvertPolicyOutcome(false, policy.invert),
|
|
551
|
-
issues: [
|
|
552
|
-
defineIssueGroup({
|
|
553
|
-
message: `The evaluation of composite policy failed (${DecisionStrategy.CONSENSUS})`,
|
|
554
|
-
issues: issues || [],
|
|
555
|
-
path: ctx.path
|
|
556
|
-
})
|
|
557
|
-
]
|
|
558
|
-
};
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
381
|
+
//#endregion
|
|
382
|
+
//#region src/policy/built-in/attributes/validator.ts
|
|
383
|
+
var AttributesPolicyValidator = class extends Container {
|
|
384
|
+
initialize() {
|
|
385
|
+
super.initialize();
|
|
386
|
+
this.mount("query", createValidator(z.looseObject({})));
|
|
387
|
+
this.mount("invert", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/policy/built-in/attributes/evaluator.ts
|
|
392
|
+
var AttributesPolicyEvaluator = class {
|
|
393
|
+
validator;
|
|
394
|
+
constructor() {
|
|
395
|
+
this.validator = new AttributesPolicyValidator();
|
|
396
|
+
}
|
|
397
|
+
async accessData(ctx) {
|
|
398
|
+
if (!ctx.data.has(BuiltInPolicyType.ATTRIBUTES)) return null;
|
|
399
|
+
if (ctx.data.isValidated(BuiltInPolicyType.ATTRIBUTES)) return ctx.data.get(BuiltInPolicyType.ATTRIBUTES);
|
|
400
|
+
const data = ctx.data.get(BuiltInPolicyType.ATTRIBUTES);
|
|
401
|
+
ctx.data.set(BuiltInPolicyType.ATTRIBUTES, data);
|
|
402
|
+
ctx.data.setValidated(BuiltInPolicyType.ATTRIBUTES);
|
|
403
|
+
return data;
|
|
404
|
+
}
|
|
405
|
+
async evaluate(value, ctx) {
|
|
406
|
+
const policy = await this.validator.run(value);
|
|
407
|
+
const data = await this.accessData(ctx);
|
|
408
|
+
if (!data) return {
|
|
409
|
+
success: false,
|
|
410
|
+
issues: [definePolicyIssueItem({
|
|
411
|
+
code: PolicyIssueCode.DATA_MISSING,
|
|
412
|
+
message: "The data property attributes is missing",
|
|
413
|
+
path: ctx.path
|
|
414
|
+
})]
|
|
415
|
+
};
|
|
416
|
+
this.fixQuery(policy.query);
|
|
417
|
+
return { success: maybeInvertPolicyOutcome(guard(policy.query)(data), policy.invert) };
|
|
418
|
+
}
|
|
419
|
+
fixQuery(query) {
|
|
420
|
+
if (Array.isArray(query)) {
|
|
421
|
+
for (const element of query) this.fixQuery(element);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
if (isObject(query)) {
|
|
425
|
+
const keys = Object.keys(query);
|
|
426
|
+
for (const key of keys) {
|
|
427
|
+
const value = query[key];
|
|
428
|
+
if (isObject(value) || Array.isArray(value)) {
|
|
429
|
+
this.fixQuery(value);
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
if (key === "$regex" && typeof value === "string") {
|
|
433
|
+
const fragments = value.match(/\/(.*?)\/([a-z]*)?$/i);
|
|
434
|
+
if (fragments && fragments[1] !== void 0) query[key] = new RegExp(fragments[1], fragments[2] || "");
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
//#endregion
|
|
441
|
+
//#region src/policy/built-in/attribute-names/evaluator.ts
|
|
442
|
+
var AttributeNamesPolicyEvaluator = class {
|
|
443
|
+
validator;
|
|
444
|
+
attributesEvaluator;
|
|
445
|
+
constructor() {
|
|
446
|
+
this.validator = new AttributeNamesPolicyValidator();
|
|
447
|
+
this.attributesEvaluator = new AttributesPolicyEvaluator();
|
|
448
|
+
}
|
|
449
|
+
async evaluate(value, ctx) {
|
|
450
|
+
const policy = await this.validator.run(value);
|
|
451
|
+
const data = await this.attributesEvaluator.accessData(ctx);
|
|
452
|
+
if (!data) return {
|
|
453
|
+
success: false,
|
|
454
|
+
issues: [definePolicyIssueItem({
|
|
455
|
+
code: PolicyIssueCode.DATA_MISSING,
|
|
456
|
+
message: "The data property attributes is missing",
|
|
457
|
+
path: ctx.path
|
|
458
|
+
})]
|
|
459
|
+
};
|
|
460
|
+
const attributes = flattenObject(data);
|
|
461
|
+
const keys = Object.keys(attributes);
|
|
462
|
+
const issues = [];
|
|
463
|
+
for (const key of keys) if (policy.names.indexOf(key) === -1) issues.push(definePolicyIssueItem({
|
|
464
|
+
code: PolicyIssueCode.EVALUATION_DENIED,
|
|
465
|
+
message: `The attribute ${key} is not included`,
|
|
466
|
+
path: [...ctx.path, key]
|
|
467
|
+
}));
|
|
468
|
+
return {
|
|
469
|
+
success: maybeInvertPolicyOutcome(issues.length === 0, policy.invert),
|
|
470
|
+
issues
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
//#endregion
|
|
475
|
+
//#region src/policy/built-in/composite/validator.ts
|
|
476
|
+
var CompositePolicyValidator = class extends Container {
|
|
477
|
+
initialize() {
|
|
478
|
+
super.initialize();
|
|
479
|
+
this.mount("decision_strategy", createValidator(z.enum(DecisionStrategy).or(z.null()).or(z.undefined()).optional()));
|
|
480
|
+
this.mount("children", createValidator(z.array(z.looseObject({ type: z.string().min(3) }))));
|
|
481
|
+
this.mount("invert", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
//#endregion
|
|
485
|
+
//#region src/policy/built-in/composite/evaluator.ts
|
|
486
|
+
var CompositePolicyEvaluator = class {
|
|
487
|
+
validator;
|
|
488
|
+
constructor() {
|
|
489
|
+
this.validator = new CompositePolicyValidator();
|
|
490
|
+
}
|
|
491
|
+
async evaluate(value, ctx) {
|
|
492
|
+
const policy = await this.validator.run(value);
|
|
493
|
+
let count = 0;
|
|
494
|
+
const decision_strategy = policy.decision_strategy ?? DecisionStrategy.UNANIMOUS;
|
|
495
|
+
const engine = new PolicyEngine(ctx.evaluators);
|
|
496
|
+
const issues = [];
|
|
497
|
+
for (const childPolicy of policy.children) {
|
|
498
|
+
const path = [...ctx.path || [], ...childPolicy.type ? [childPolicy.type] : []];
|
|
499
|
+
const outcome = await engine.evaluate(childPolicy, {
|
|
500
|
+
...ctx,
|
|
501
|
+
path
|
|
502
|
+
});
|
|
503
|
+
if (outcome.success) {
|
|
504
|
+
if (decision_strategy === DecisionStrategy.AFFIRMATIVE) return {
|
|
505
|
+
success: maybeInvertPolicyOutcome(true, policy.invert),
|
|
506
|
+
issues: []
|
|
507
|
+
};
|
|
508
|
+
count++;
|
|
509
|
+
} else {
|
|
510
|
+
if (outcome.issues) issues.push(defineIssueGroup({
|
|
511
|
+
message: `The evaluation of child policy ${childPolicy.type} failed`,
|
|
512
|
+
issues: outcome.issues || [],
|
|
513
|
+
path
|
|
514
|
+
}));
|
|
515
|
+
if (decision_strategy === DecisionStrategy.UNANIMOUS) return {
|
|
516
|
+
success: maybeInvertPolicyOutcome(false, policy.invert),
|
|
517
|
+
issues: [defineIssueGroup({
|
|
518
|
+
message: `The evaluation of composite policy failed (${DecisionStrategy.UNANIMOUS})`,
|
|
519
|
+
issues,
|
|
520
|
+
path: ctx.path
|
|
521
|
+
})]
|
|
522
|
+
};
|
|
523
|
+
count--;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
if (count > 0) return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
527
|
+
return {
|
|
528
|
+
success: maybeInvertPolicyOutcome(false, policy.invert),
|
|
529
|
+
issues: [defineIssueGroup({
|
|
530
|
+
message: `The evaluation of composite policy failed (${DecisionStrategy.CONSENSUS})`,
|
|
531
|
+
issues: issues || [],
|
|
532
|
+
path: ctx.path
|
|
533
|
+
})]
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
//#endregion
|
|
538
|
+
//#region src/policy/built-in/composite/helper.ts
|
|
562
539
|
function isCompositePolicy(input) {
|
|
563
|
-
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
|
|
540
|
+
return input.type === BuiltInPolicyType.COMPOSITE;
|
|
541
|
+
}
|
|
542
|
+
//#endregion
|
|
543
|
+
//#region src/policy/built-in/date/validator.ts
|
|
544
|
+
var DatePolicyValidator = class extends Container {
|
|
545
|
+
initialize() {
|
|
546
|
+
super.initialize();
|
|
547
|
+
this.mount("start", createValidator(z.date().or(z.iso.date()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
|
|
548
|
+
this.mount("end", createValidator(z.date().or(z.iso.date()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
|
|
549
|
+
this.mount("invert", createValidator(z.boolean().or(z.undefined()).or(z.null()).optional()));
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
//#endregion
|
|
553
|
+
//#region src/policy/built-in/date/evaluator.ts
|
|
575
554
|
function normalizeDate$1(input) {
|
|
576
|
-
|
|
555
|
+
return new Date(input.getFullYear(), input.getMonth(), input.getDate());
|
|
577
556
|
}
|
|
578
557
|
function toDate$1(input) {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
} else {
|
|
786
|
-
keys = [
|
|
787
|
-
policy.attribute_name
|
|
788
|
-
];
|
|
789
|
-
}
|
|
790
|
-
} else {
|
|
791
|
-
keys = [
|
|
792
|
-
'realm_id',
|
|
793
|
-
'realm_name',
|
|
794
|
-
'realmId',
|
|
795
|
-
'realmName'
|
|
796
|
-
];
|
|
797
|
-
policy.decision_strategy = DecisionStrategy.CONSENSUS;
|
|
798
|
-
}
|
|
799
|
-
const attribute_name_strict = policy.attribute_name_strict ?? true;
|
|
800
|
-
if (!attribute_name_strict) {
|
|
801
|
-
const resourceKeys = Object.keys(attributes);
|
|
802
|
-
const keysToAdd = [];
|
|
803
|
-
for (const resourceKey of resourceKeys){
|
|
804
|
-
let contains = false;
|
|
805
|
-
for (const key of keys){
|
|
806
|
-
if (resourceKey !== key && resourceKey.includes(key)) {
|
|
807
|
-
contains = true;
|
|
808
|
-
break;
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
if (contains) {
|
|
812
|
-
keysToAdd.push(resourceKey);
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
if (keysToAdd.length > 0) {
|
|
816
|
-
keys.push(...keysToAdd);
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
let count = 0;
|
|
820
|
-
let evaluated = false;
|
|
821
|
-
for (const key of keys){
|
|
822
|
-
if (!hasOwnProperty(attributes, key)) {
|
|
823
|
-
continue;
|
|
824
|
-
}
|
|
825
|
-
evaluated = true;
|
|
826
|
-
let outcome = false;
|
|
827
|
-
const attributeValue = attributes[key];
|
|
828
|
-
if (attributeValue === null && policy.attribute_null_match_all) {
|
|
829
|
-
outcome = true;
|
|
830
|
-
} else if (attributeValue === identity.realmId || attributeValue === identity.realmName) {
|
|
831
|
-
outcome = true;
|
|
832
|
-
}
|
|
833
|
-
if (outcome) {
|
|
834
|
-
if (policy.decision_strategy === DecisionStrategy.AFFIRMATIVE) {
|
|
835
|
-
return {
|
|
836
|
-
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
837
|
-
};
|
|
838
|
-
}
|
|
839
|
-
count++;
|
|
840
|
-
} else {
|
|
841
|
-
if (policy.decision_strategy === DecisionStrategy.UNANIMOUS) {
|
|
842
|
-
return {
|
|
843
|
-
success: maybeInvertPolicyOutcome(false, policy.invert)
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
count--;
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
if (!evaluated) {
|
|
850
|
-
return {
|
|
851
|
-
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
852
|
-
};
|
|
853
|
-
}
|
|
854
|
-
return {
|
|
855
|
-
success: maybeInvertPolicyOutcome(count > 0, policy.invert)
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
/*
|
|
861
|
-
* Copyright (c) 2024-2024.
|
|
862
|
-
* Author Peter Placzek (tada5hi)
|
|
863
|
-
* For the full copyright and license information,
|
|
864
|
-
* view the LICENSE file that was distributed with this source code.
|
|
865
|
-
*/ var TimePolicyInterval = /*#__PURE__*/ function(TimePolicyInterval) {
|
|
866
|
-
TimePolicyInterval["DAILY"] = "daily";
|
|
867
|
-
TimePolicyInterval["WEEKLY"] = "weekly";
|
|
868
|
-
TimePolicyInterval["MONTHLY"] = "monthly";
|
|
869
|
-
TimePolicyInterval["YEARLY"] = "yearly";
|
|
870
|
-
return TimePolicyInterval;
|
|
558
|
+
if (typeof input === "string") return new Date(input);
|
|
559
|
+
if (typeof input === "number") return new Date(input);
|
|
560
|
+
return input;
|
|
561
|
+
}
|
|
562
|
+
var DatePolicyEvaluator = class {
|
|
563
|
+
validator;
|
|
564
|
+
constructor() {
|
|
565
|
+
this.validator = new DatePolicyValidator();
|
|
566
|
+
}
|
|
567
|
+
async evaluate(value, ctx) {
|
|
568
|
+
const policy = await this.validator.run(value);
|
|
569
|
+
let now;
|
|
570
|
+
if (ctx.data.has(BuiltInPolicyType.DATE)) if (ctx.data.isValidated(BuiltInPolicyType.DATE)) now = ctx.data.get(BuiltInPolicyType.DATE);
|
|
571
|
+
else {
|
|
572
|
+
now = normalizeDate$1(toDate$1(ctx.data.get(BuiltInPolicyType.DATE)));
|
|
573
|
+
ctx.data.set(BuiltInPolicyType.DATE, now);
|
|
574
|
+
ctx.data.setValidated(BuiltInPolicyType.DATE);
|
|
575
|
+
}
|
|
576
|
+
else now = normalizeDate$1(/* @__PURE__ */ new Date());
|
|
577
|
+
if (policy.start) {
|
|
578
|
+
const start = normalizeDate$1(toDate$1(policy.start));
|
|
579
|
+
if (now < start) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
580
|
+
}
|
|
581
|
+
if (policy.end) {
|
|
582
|
+
const end = normalizeDate$1(toDate$1(policy.end));
|
|
583
|
+
if (now > end) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
584
|
+
}
|
|
585
|
+
return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
//#endregion
|
|
589
|
+
//#region src/policy/built-in/identity/data/validator.ts
|
|
590
|
+
var PolicyIdentityDataValidator = class extends Container {
|
|
591
|
+
initialize() {
|
|
592
|
+
super.initialize();
|
|
593
|
+
this.mount("type", createValidator(z.string().min(3).max(128)));
|
|
594
|
+
this.mount("id", createValidator(z.uuid()));
|
|
595
|
+
this.mount("clientId", createValidator(z.uuid().or(z.null()).or(z.undefined()).optional()));
|
|
596
|
+
this.mount("realmId", createValidator(z.uuid().or(z.null()).or(z.undefined()).optional()));
|
|
597
|
+
this.mount("realmName", createValidator(z.string().min(3).max(128).or(z.null()).or(z.undefined()).optional()));
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
//#endregion
|
|
601
|
+
//#region src/policy/built-in/identity/validator.ts
|
|
602
|
+
var IdentityPolicyValidator = class extends Container {
|
|
603
|
+
initialize() {
|
|
604
|
+
this.mount("types", createValidator(z.array(z.string()).or(z.null()).or(z.undefined()).optional()));
|
|
605
|
+
this.mount("invert", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
//#endregion
|
|
609
|
+
//#region src/policy/built-in/identity/evaluator.ts
|
|
610
|
+
var IdentityPolicyEvaluator = class {
|
|
611
|
+
validator;
|
|
612
|
+
dataValidator;
|
|
613
|
+
constructor() {
|
|
614
|
+
this.validator = new IdentityPolicyValidator();
|
|
615
|
+
this.dataValidator = new PolicyIdentityDataValidator();
|
|
616
|
+
}
|
|
617
|
+
async accessData(ctx) {
|
|
618
|
+
if (!ctx.data.has("identity")) return null;
|
|
619
|
+
if (ctx.data.isValidated("identity")) return ctx.data.get("identity");
|
|
620
|
+
const data = await this.dataValidator.run(ctx.data.get("identity"));
|
|
621
|
+
ctx.data.set("identity", data);
|
|
622
|
+
ctx.data.setValidated("identity");
|
|
623
|
+
return data;
|
|
624
|
+
}
|
|
625
|
+
async evaluate(value, ctx) {
|
|
626
|
+
const policy = await this.validator.run(value);
|
|
627
|
+
const data = await this.accessData(ctx);
|
|
628
|
+
if (!data) return {
|
|
629
|
+
success: false,
|
|
630
|
+
issues: [definePolicyIssueItem({
|
|
631
|
+
code: PolicyIssueCode.DATA_MISSING,
|
|
632
|
+
message: "The data property identity is missing",
|
|
633
|
+
path: ctx.path
|
|
634
|
+
})]
|
|
635
|
+
};
|
|
636
|
+
if (!policy.types || policy.types.length === 0) return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
637
|
+
const typeAllowed = policy.types.includes(data.type);
|
|
638
|
+
if (typeAllowed) return { success: maybeInvertPolicyOutcome(typeAllowed, policy.invert) };
|
|
639
|
+
return {
|
|
640
|
+
success: maybeInvertPolicyOutcome(typeAllowed, policy.invert),
|
|
641
|
+
issues: [definePolicyIssueItem({
|
|
642
|
+
code: PolicyIssueCode.EVALUATION_DENIED,
|
|
643
|
+
message: `The type ${data.type} is not covered by the policy configuration`,
|
|
644
|
+
path: ctx.path
|
|
645
|
+
})]
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
//#endregion
|
|
650
|
+
//#region src/policy/built-in/permission-binding/validator.ts
|
|
651
|
+
var PermissionBindingPolicyValidator = class extends Container {
|
|
652
|
+
initialize() {}
|
|
653
|
+
};
|
|
654
|
+
//#endregion
|
|
655
|
+
//#region src/policy/built-in/permission-binding/module.ts
|
|
656
|
+
var PermissionBindingPolicyEvaluator = class {
|
|
657
|
+
validator;
|
|
658
|
+
constructor() {
|
|
659
|
+
this.validator = new PermissionBindingPolicyValidator();
|
|
660
|
+
}
|
|
661
|
+
async evaluate(value) {
|
|
662
|
+
return { success: maybeInvertPolicyOutcome(true, (await this.validator.run(value)).invert) };
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
//#endregion
|
|
666
|
+
//#region src/policy/built-in/realm-match/validator.ts
|
|
667
|
+
var RealmMatchPolicyValidator = class extends Container {
|
|
668
|
+
initialize() {
|
|
669
|
+
super.initialize();
|
|
670
|
+
this.mount("decision_strategy", createValidator(z.enum(DecisionStrategy).or(z.null()).or(z.undefined()).optional()));
|
|
671
|
+
this.mount("attribute_name", createValidator(z.string().min(3).or(z.array(z.string().min(3))).or(z.null()).or(z.undefined()).optional()));
|
|
672
|
+
this.mount("attribute_name_strict", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
673
|
+
this.mount("attribute_null_match_all", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
674
|
+
this.mount("identity_master_match_all", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
675
|
+
this.mount("invert", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
//#endregion
|
|
679
|
+
//#region src/policy/built-in/realm-match/evaluator.ts
|
|
680
|
+
var RealmMatchPolicyEvaluator = class {
|
|
681
|
+
validator;
|
|
682
|
+
identityEvaluator;
|
|
683
|
+
attributesEvaluator;
|
|
684
|
+
constructor() {
|
|
685
|
+
this.validator = new RealmMatchPolicyValidator();
|
|
686
|
+
this.identityEvaluator = new IdentityPolicyEvaluator();
|
|
687
|
+
this.attributesEvaluator = new AttributesPolicyEvaluator();
|
|
688
|
+
}
|
|
689
|
+
async evaluate(value, ctx) {
|
|
690
|
+
const policy = await this.validator.run(value);
|
|
691
|
+
const identity = await this.identityEvaluator.accessData(ctx);
|
|
692
|
+
if (!identity) return {
|
|
693
|
+
success: false,
|
|
694
|
+
issues: [definePolicyIssueItem({
|
|
695
|
+
code: PolicyIssueCode.DATA_MISSING,
|
|
696
|
+
message: "The data property identity is missing",
|
|
697
|
+
path: ctx.path
|
|
698
|
+
})]
|
|
699
|
+
};
|
|
700
|
+
const attributes = await this.attributesEvaluator.accessData(ctx);
|
|
701
|
+
if (!attributes) return {
|
|
702
|
+
success: false,
|
|
703
|
+
issues: [definePolicyIssueItem({
|
|
704
|
+
code: PolicyIssueCode.DATA_MISSING,
|
|
705
|
+
message: "The data property attributes is missing",
|
|
706
|
+
path: ctx.path
|
|
707
|
+
})]
|
|
708
|
+
};
|
|
709
|
+
if ((policy.identity_master_match_all ?? true) && identity.realmName && identity.realmName === "master") return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
710
|
+
let keys;
|
|
711
|
+
if (policy.attribute_name) if (Array.isArray(policy.attribute_name)) keys = policy.attribute_name;
|
|
712
|
+
else keys = [policy.attribute_name];
|
|
713
|
+
else {
|
|
714
|
+
keys = [
|
|
715
|
+
"realm_id",
|
|
716
|
+
"realm_name",
|
|
717
|
+
"realmId",
|
|
718
|
+
"realmName"
|
|
719
|
+
];
|
|
720
|
+
policy.decision_strategy = DecisionStrategy.CONSENSUS;
|
|
721
|
+
}
|
|
722
|
+
if (!(policy.attribute_name_strict ?? true)) {
|
|
723
|
+
const resourceKeys = Object.keys(attributes);
|
|
724
|
+
const keysToAdd = [];
|
|
725
|
+
for (const resourceKey of resourceKeys) {
|
|
726
|
+
let contains = false;
|
|
727
|
+
for (const key of keys) if (resourceKey !== key && resourceKey.includes(key)) {
|
|
728
|
+
contains = true;
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
if (contains) keysToAdd.push(resourceKey);
|
|
732
|
+
}
|
|
733
|
+
if (keysToAdd.length > 0) keys.push(...keysToAdd);
|
|
734
|
+
}
|
|
735
|
+
let count = 0;
|
|
736
|
+
let evaluated = false;
|
|
737
|
+
for (const key of keys) {
|
|
738
|
+
if (!hasOwnProperty(attributes, key)) continue;
|
|
739
|
+
evaluated = true;
|
|
740
|
+
let outcome = false;
|
|
741
|
+
const attributeValue = attributes[key];
|
|
742
|
+
if (attributeValue === null && policy.attribute_null_match_all) outcome = true;
|
|
743
|
+
else if (attributeValue === identity.realmId || attributeValue === identity.realmName) outcome = true;
|
|
744
|
+
if (outcome) {
|
|
745
|
+
if (policy.decision_strategy === DecisionStrategy.AFFIRMATIVE) return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
746
|
+
count++;
|
|
747
|
+
} else {
|
|
748
|
+
if (policy.decision_strategy === DecisionStrategy.UNANIMOUS) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
749
|
+
count--;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
if (!evaluated) return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
753
|
+
return { success: maybeInvertPolicyOutcome(count > 0, policy.invert) };
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
//#endregion
|
|
757
|
+
//#region src/policy/built-in/time/constants.ts
|
|
758
|
+
let TimePolicyInterval = /* @__PURE__ */ function(TimePolicyInterval) {
|
|
759
|
+
TimePolicyInterval["DAILY"] = "daily";
|
|
760
|
+
TimePolicyInterval["WEEKLY"] = "weekly";
|
|
761
|
+
TimePolicyInterval["MONTHLY"] = "monthly";
|
|
762
|
+
TimePolicyInterval["YEARLY"] = "yearly";
|
|
763
|
+
return TimePolicyInterval;
|
|
871
764
|
}({});
|
|
872
|
-
|
|
765
|
+
//#endregion
|
|
766
|
+
//#region src/policy/built-in/time/helpers.ts
|
|
873
767
|
function isIntervalForDayOfWeek(interval) {
|
|
874
|
-
|
|
768
|
+
return interval === TimePolicyInterval.WEEKLY || interval === TimePolicyInterval.MONTHLY || interval === TimePolicyInterval.YEARLY;
|
|
875
769
|
}
|
|
876
770
|
function isIntervalForDayOfMonth(interval) {
|
|
877
|
-
|
|
771
|
+
return interval === TimePolicyInterval.MONTHLY || interval === TimePolicyInterval.YEARLY;
|
|
878
772
|
}
|
|
879
773
|
function isIntervalForDayOfYear(interval) {
|
|
880
|
-
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
}
|
|
895
|
-
|
|
774
|
+
return interval === TimePolicyInterval.YEARLY;
|
|
775
|
+
}
|
|
776
|
+
//#endregion
|
|
777
|
+
//#region src/policy/built-in/time/validator.ts
|
|
778
|
+
var TimePolicyValidator = class extends Container {
|
|
779
|
+
initialize() {
|
|
780
|
+
super.initialize();
|
|
781
|
+
this.mount("day_of_week", createValidator(z.number().min(0).max(6).or(z.null()).or(z.undefined()).optional()));
|
|
782
|
+
this.mount("day_of_month", createValidator(z.number().min(1).max(31).or(z.null()).or(z.undefined()).optional()));
|
|
783
|
+
this.mount("day_of_year", createValidator(z.number().min(1).max(365).or(z.null()).or(z.undefined()).optional()));
|
|
784
|
+
this.mount("start", createValidator(z.date().or(z.iso.datetime()).or(z.iso.time()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
|
|
785
|
+
this.mount("end", createValidator(z.date().or(z.iso.datetime()).or(z.iso.time()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
|
|
786
|
+
this.mount("interval", createValidator(z.enum(TimePolicyInterval).or(z.null()).or(z.undefined()).optional()));
|
|
787
|
+
this.mount("invert", createValidator(z.boolean().or(z.undefined()).or(z.null()).optional()));
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
//#endregion
|
|
791
|
+
//#region src/policy/built-in/time/evaluator.ts
|
|
896
792
|
const timeRegex = /^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/;
|
|
897
793
|
function normalizeDate(input, dateRef) {
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
794
|
+
const date = dateRef ? new Date(dateRef) : /* @__PURE__ */ new Date();
|
|
795
|
+
date.setHours(input.getHours(), input.getMinutes());
|
|
796
|
+
return date;
|
|
901
797
|
}
|
|
902
798
|
function toDate(input, dateRef) {
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
if (isIntervalForDayOfYear(policy.interval) && policy.day_of_year) {
|
|
970
|
-
const start = new Date(now.getFullYear(), 0, 0);
|
|
971
|
-
const diff = now.getTime() - start.getTime() + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
|
|
972
|
-
const oneDay = 1000 * 60 * 60 * 24;
|
|
973
|
-
const dayOfYear = Math.floor(diff / oneDay);
|
|
974
|
-
if (dayOfYear !== policy.day_of_year) {
|
|
975
|
-
return {
|
|
976
|
-
success: maybeInvertPolicyOutcome(false, policy.invert)
|
|
977
|
-
};
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
return {
|
|
982
|
-
success: maybeInvertPolicyOutcome(true, policy.invert)
|
|
983
|
-
};
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
/*
|
|
988
|
-
* Copyright (c) 2025.
|
|
989
|
-
* Author Peter Placzek (tada5hi)
|
|
990
|
-
* For the full copyright and license information,
|
|
991
|
-
* view the LICENSE file that was distributed with this source code.
|
|
992
|
-
*/ function definePolicyWithType(type, data) {
|
|
993
|
-
return {
|
|
994
|
-
...data,
|
|
995
|
-
type
|
|
996
|
-
};
|
|
997
|
-
}
|
|
998
|
-
|
|
799
|
+
if (typeof input === "string") {
|
|
800
|
+
if (timeRegex.test(input)) {
|
|
801
|
+
const parts = input.split(":");
|
|
802
|
+
const startHours = Number(parts[0]);
|
|
803
|
+
const startMinutes = Number(parts[1]);
|
|
804
|
+
const startSeconds = parts[2] !== void 0 ? Number(parts[2]) : 0;
|
|
805
|
+
if (Number.isFinite(startHours) && Number.isFinite(startMinutes) && Number.isFinite(startSeconds)) {
|
|
806
|
+
const date = dateRef ? new Date(dateRef) : /* @__PURE__ */ new Date();
|
|
807
|
+
date.setHours(startHours, startMinutes, startSeconds, 0);
|
|
808
|
+
return date;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
return new Date(input);
|
|
812
|
+
}
|
|
813
|
+
if (typeof input === "number") return new Date(input);
|
|
814
|
+
return input;
|
|
815
|
+
}
|
|
816
|
+
var TimePolicyEvaluator = class {
|
|
817
|
+
validator;
|
|
818
|
+
constructor() {
|
|
819
|
+
this.validator = new TimePolicyValidator();
|
|
820
|
+
}
|
|
821
|
+
async evaluate(value, ctx) {
|
|
822
|
+
const policy = await this.validator.run(value);
|
|
823
|
+
let now;
|
|
824
|
+
if (ctx.data.has(BuiltInPolicyType.TIME)) if (ctx.data.isValidated(BuiltInPolicyType.TIME)) now = ctx.data.get(BuiltInPolicyType.TIME);
|
|
825
|
+
else {
|
|
826
|
+
now = toDate(ctx.data.get(BuiltInPolicyType.TIME));
|
|
827
|
+
ctx.data.set(BuiltInPolicyType.TIME, now);
|
|
828
|
+
ctx.data.setValidated(BuiltInPolicyType.TIME);
|
|
829
|
+
}
|
|
830
|
+
else now = /* @__PURE__ */ new Date();
|
|
831
|
+
if (policy.start) {
|
|
832
|
+
const start = normalizeDate(toDate(policy.start, now), now);
|
|
833
|
+
if (now < start) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
834
|
+
}
|
|
835
|
+
if (policy.end) {
|
|
836
|
+
const end = normalizeDate(toDate(policy.end, now), now);
|
|
837
|
+
if (now > end) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
838
|
+
}
|
|
839
|
+
if (policy.interval) {
|
|
840
|
+
if (isIntervalForDayOfWeek(policy.interval) && policy.day_of_week) {
|
|
841
|
+
if (now.getDay() !== policy.day_of_week) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
842
|
+
}
|
|
843
|
+
if (isIntervalForDayOfMonth(policy.interval) && policy.day_of_month) {
|
|
844
|
+
if (now.getDate() !== policy.day_of_month) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
845
|
+
}
|
|
846
|
+
if (isIntervalForDayOfYear(policy.interval) && policy.day_of_year) {
|
|
847
|
+
const start = new Date(now.getFullYear(), 0, 0);
|
|
848
|
+
const diff = now.getTime() - start.getTime() + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1e3;
|
|
849
|
+
if (Math.floor(diff / (1e3 * 60 * 60 * 24)) !== policy.day_of_year) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return { success: maybeInvertPolicyOutcome(true, policy.invert) };
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
//#endregion
|
|
856
|
+
//#region src/policy/built-in/define.ts
|
|
857
|
+
function definePolicyWithType(type, data) {
|
|
858
|
+
return {
|
|
859
|
+
...data,
|
|
860
|
+
type
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
//#endregion
|
|
864
|
+
//#region src/policy/constants.ts
|
|
999
865
|
const PolicyDefaultEvaluators = {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
866
|
+
[BuiltInPolicyType.COMPOSITE]: new CompositePolicyEvaluator(),
|
|
867
|
+
[BuiltInPolicyType.ATTRIBUTES]: new AttributesPolicyEvaluator(),
|
|
868
|
+
[BuiltInPolicyType.ATTRIBUTE_NAMES]: new AttributeNamesPolicyEvaluator(),
|
|
869
|
+
[BuiltInPolicyType.DATE]: new DatePolicyEvaluator(),
|
|
870
|
+
[BuiltInPolicyType.IDENTITY]: new IdentityPolicyEvaluator(),
|
|
871
|
+
[BuiltInPolicyType.PERMISSION_BINDING]: new PermissionBindingPolicyEvaluator(),
|
|
872
|
+
[BuiltInPolicyType.REALM_MATCH]: new RealmMatchPolicyEvaluator(),
|
|
873
|
+
[BuiltInPolicyType.TIME]: new TimePolicyEvaluator()
|
|
1008
874
|
};
|
|
875
|
+
//#endregion
|
|
876
|
+
//#region src/permission/evaluator/module.ts
|
|
877
|
+
var PermissionEvaluator = class {
|
|
878
|
+
provider;
|
|
879
|
+
policyEngine;
|
|
880
|
+
clientId;
|
|
881
|
+
realmId;
|
|
882
|
+
constructor(options) {
|
|
883
|
+
this.provider = options.provider;
|
|
884
|
+
this.clientId = options.clientId || null;
|
|
885
|
+
this.realmId = options.realmId || null;
|
|
886
|
+
if (options.policyEngine) this.policyEngine = options.policyEngine;
|
|
887
|
+
else this.policyEngine = new PolicyEngine(PolicyDefaultEvaluators);
|
|
888
|
+
}
|
|
889
|
+
async findOne(input, overrides = {}) {
|
|
890
|
+
return this.provider.findOne({
|
|
891
|
+
name: input,
|
|
892
|
+
clientId: overrides.clientId ?? this.clientId,
|
|
893
|
+
realmId: overrides.realmId ?? this.realmId
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
async evaluate(ctx) {
|
|
897
|
+
if (!Array.isArray(ctx.name)) {
|
|
898
|
+
await this.evaluate({
|
|
899
|
+
...ctx,
|
|
900
|
+
name: [ctx.name]
|
|
901
|
+
});
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
const { options = {} } = ctx;
|
|
905
|
+
const decisionStrategy = options.decisionStrategy ?? DecisionStrategy.UNANIMOUS;
|
|
906
|
+
const issues = [];
|
|
907
|
+
let count = 0;
|
|
908
|
+
const dataBase = ctx.input || new PolicyData();
|
|
909
|
+
for (const name of ctx.name) {
|
|
910
|
+
const binding = await this.findOne(name, {
|
|
911
|
+
realmId: ctx.realmId,
|
|
912
|
+
clientId: ctx.clientId
|
|
913
|
+
});
|
|
914
|
+
if (!binding) {
|
|
915
|
+
issues.push(defineIssueItem({
|
|
916
|
+
code: ErrorCode.PERMISSION_NOT_FOUND,
|
|
917
|
+
message: `The ${name} permission could not be resolved`,
|
|
918
|
+
path: [name]
|
|
919
|
+
}));
|
|
920
|
+
if (decisionStrategy === DecisionStrategy.UNANIMOUS) {
|
|
921
|
+
const error = PermissionError.evaluationFailed(ctx.name);
|
|
922
|
+
error.addIssues(issues);
|
|
923
|
+
throw error;
|
|
924
|
+
}
|
|
925
|
+
continue;
|
|
926
|
+
}
|
|
927
|
+
const policies = binding.policies ?? [];
|
|
928
|
+
if (policies.length === 0) {
|
|
929
|
+
if (decisionStrategy === DecisionStrategy.AFFIRMATIVE) return;
|
|
930
|
+
count++;
|
|
931
|
+
continue;
|
|
932
|
+
}
|
|
933
|
+
const data = dataBase.clone();
|
|
934
|
+
data.set(BuiltInPolicyType.PERMISSION_BINDING, binding);
|
|
935
|
+
const policyDecisionStrategy = binding.permission.decision_strategy ?? DecisionStrategy.UNANIMOUS;
|
|
936
|
+
const compositePolicy = {
|
|
937
|
+
type: BuiltInPolicyType.COMPOSITE,
|
|
938
|
+
decision_strategy: policyDecisionStrategy,
|
|
939
|
+
children: policies
|
|
940
|
+
};
|
|
941
|
+
const evaluationResult = await this.policyEngine.evaluate(compositePolicy, definePolicyEvaluationContext({
|
|
942
|
+
include: options.policiesIncluded,
|
|
943
|
+
exclude: options.policiesExcluded,
|
|
944
|
+
data
|
|
945
|
+
}));
|
|
946
|
+
if (evaluationResult.success) {
|
|
947
|
+
if (decisionStrategy === DecisionStrategy.AFFIRMATIVE) return;
|
|
948
|
+
count++;
|
|
949
|
+
} else {
|
|
950
|
+
issues.push(definePolicyIssueGroup({
|
|
951
|
+
code: ErrorCode.PERMISSION_EVALUATION_FAILED,
|
|
952
|
+
issues: evaluationResult.issues || [],
|
|
953
|
+
message: `The ${binding.permission.name} permissions policy evaluation failed`,
|
|
954
|
+
path: [binding.permission.name]
|
|
955
|
+
}));
|
|
956
|
+
if (decisionStrategy === DecisionStrategy.UNANIMOUS) {
|
|
957
|
+
const error = PermissionError.evaluationFailed(binding.permission.name);
|
|
958
|
+
error.addIssues(issues);
|
|
959
|
+
throw error;
|
|
960
|
+
}
|
|
961
|
+
count--;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
if (count > 0) return;
|
|
965
|
+
if (issues.length === 0) throw PermissionError.deniedAll(ctx.name);
|
|
966
|
+
else {
|
|
967
|
+
const error = PermissionError.evaluationFailed(ctx.name);
|
|
968
|
+
error.addIssues(issues);
|
|
969
|
+
throw error;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
async evaluateOneOf(ctx) {
|
|
973
|
+
return this.evaluate({
|
|
974
|
+
...ctx,
|
|
975
|
+
options: {
|
|
976
|
+
...ctx.options || {},
|
|
977
|
+
decisionStrategy: DecisionStrategy.AFFIRMATIVE
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
async preEvaluate(ctx) {
|
|
982
|
+
return this.evaluate({
|
|
983
|
+
...ctx,
|
|
984
|
+
options: {
|
|
985
|
+
...ctx.options || {},
|
|
986
|
+
policiesExcluded: [
|
|
987
|
+
BuiltInPolicyType.ATTRIBUTES,
|
|
988
|
+
BuiltInPolicyType.ATTRIBUTE_NAMES,
|
|
989
|
+
BuiltInPolicyType.REALM_MATCH
|
|
990
|
+
]
|
|
991
|
+
}
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
async preEvaluateOneOf(ctx) {
|
|
995
|
+
return this.preEvaluate({
|
|
996
|
+
...ctx,
|
|
997
|
+
options: {
|
|
998
|
+
...ctx.options || {},
|
|
999
|
+
decisionStrategy: DecisionStrategy.AFFIRMATIVE
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
//#endregion
|
|
1005
|
+
export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, DecisionStrategy, IdentityPolicyEvaluator, IdentityPolicyValidator, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionError, PermissionEvaluator, PermissionMemoryProvider, PolicyData, PolicyDefaultEvaluators, PolicyEngine, PolicyError, PolicyIssueCode, PolicyIssueSeverity, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, SystemPolicyName, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, buildPermissionKey, defineAttributesPolicy, definePolicyEvaluationContext, definePolicyIssueGroup, definePolicyIssueItem, definePolicyWithType, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, isPermissionPolicyBindingEqual, maybeInvertPolicyOutcome, mergePermissionPolicyBindings };
|
|
1009
1006
|
|
|
1010
|
-
|
|
1011
|
-
provider;
|
|
1012
|
-
policyEngine;
|
|
1013
|
-
clientId;
|
|
1014
|
-
realmId;
|
|
1015
|
-
// ----------------------------------------------
|
|
1016
|
-
constructor(options = {}){
|
|
1017
|
-
if (options.provider) {
|
|
1018
|
-
this.provider = options.provider;
|
|
1019
|
-
} else {
|
|
1020
|
-
this.provider = new PermissionMemoryProvider();
|
|
1021
|
-
}
|
|
1022
|
-
if (typeof options.clientId !== 'undefined') {
|
|
1023
|
-
this.clientId = options.clientId;
|
|
1024
|
-
}
|
|
1025
|
-
if (typeof options.realmId !== 'undefined') {
|
|
1026
|
-
this.realmId = options.realmId;
|
|
1027
|
-
}
|
|
1028
|
-
if (options.policyEngine) {
|
|
1029
|
-
this.policyEngine = options.policyEngine;
|
|
1030
|
-
} else {
|
|
1031
|
-
this.policyEngine = new PolicyEngine(PolicyDefaultEvaluators);
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
// ----------------------------------------------
|
|
1035
|
-
async findOne(input, overrides) {
|
|
1036
|
-
const options = {
|
|
1037
|
-
name: input
|
|
1038
|
-
};
|
|
1039
|
-
if (typeof overrides?.clientId !== 'undefined') {
|
|
1040
|
-
options.clientId = overrides.clientId;
|
|
1041
|
-
} else if (typeof this.clientId !== 'undefined') {
|
|
1042
|
-
options.clientId = this.clientId;
|
|
1043
|
-
}
|
|
1044
|
-
if (typeof overrides?.realmId !== 'undefined') {
|
|
1045
|
-
options.realmId = overrides.realmId;
|
|
1046
|
-
} else if (typeof this.realmId !== 'undefined') {
|
|
1047
|
-
options.realmId = this.realmId;
|
|
1048
|
-
}
|
|
1049
|
-
return this.provider.findOne(options);
|
|
1050
|
-
}
|
|
1051
|
-
// ----------------------------------------------
|
|
1052
|
-
async evaluate(ctx) {
|
|
1053
|
-
if (!Array.isArray(ctx.name)) {
|
|
1054
|
-
await this.evaluate({
|
|
1055
|
-
...ctx,
|
|
1056
|
-
name: [
|
|
1057
|
-
ctx.name
|
|
1058
|
-
]
|
|
1059
|
-
});
|
|
1060
|
-
return;
|
|
1061
|
-
}
|
|
1062
|
-
const { options = {} } = ctx;
|
|
1063
|
-
const decisionStrategy = options.decisionStrategy ?? DecisionStrategy.UNANIMOUS;
|
|
1064
|
-
const issues = [];
|
|
1065
|
-
let count = 0;
|
|
1066
|
-
const dataBase = ctx.input || new PolicyData();
|
|
1067
|
-
for(let i = 0; i < ctx.name.length; i++){
|
|
1068
|
-
const binding = await this.findOne(ctx.name[i], {
|
|
1069
|
-
realmId: ctx.realmId,
|
|
1070
|
-
clientId: ctx.clientId
|
|
1071
|
-
});
|
|
1072
|
-
if (!binding) {
|
|
1073
|
-
issues.push(defineIssueItem({
|
|
1074
|
-
code: ErrorCode.PERMISSION_NOT_FOUND,
|
|
1075
|
-
message: `The ${ctx.name[i]} permission could not be resolved`,
|
|
1076
|
-
path: [
|
|
1077
|
-
ctx.name[i]
|
|
1078
|
-
]
|
|
1079
|
-
}));
|
|
1080
|
-
if (decisionStrategy === DecisionStrategy.UNANIMOUS) {
|
|
1081
|
-
const error = PermissionError.evaluationFailed(ctx.name);
|
|
1082
|
-
error.addIssues(issues);
|
|
1083
|
-
throw error;
|
|
1084
|
-
}
|
|
1085
|
-
continue;
|
|
1086
|
-
}
|
|
1087
|
-
const policies = binding.policies ?? [];
|
|
1088
|
-
if (policies.length === 0) {
|
|
1089
|
-
if (decisionStrategy === DecisionStrategy.AFFIRMATIVE) {
|
|
1090
|
-
return;
|
|
1091
|
-
}
|
|
1092
|
-
count++;
|
|
1093
|
-
continue;
|
|
1094
|
-
}
|
|
1095
|
-
const data = dataBase.clone();
|
|
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({
|
|
1104
|
-
include: options.policiesIncluded,
|
|
1105
|
-
exclude: options.policiesExcluded,
|
|
1106
|
-
data
|
|
1107
|
-
}));
|
|
1108
|
-
if (evaluationResult.success) {
|
|
1109
|
-
if (decisionStrategy === DecisionStrategy.AFFIRMATIVE) {
|
|
1110
|
-
return;
|
|
1111
|
-
}
|
|
1112
|
-
count++;
|
|
1113
|
-
} else {
|
|
1114
|
-
issues.push(definePolicyIssueGroup({
|
|
1115
|
-
code: ErrorCode.PERMISSION_EVALUATION_FAILED,
|
|
1116
|
-
issues: evaluationResult.issues || [],
|
|
1117
|
-
message: `The ${binding.permission.name} permissions policy evaluation failed`,
|
|
1118
|
-
path: [
|
|
1119
|
-
binding.permission.name
|
|
1120
|
-
]
|
|
1121
|
-
}));
|
|
1122
|
-
if (decisionStrategy === DecisionStrategy.UNANIMOUS) {
|
|
1123
|
-
const error = PermissionError.evaluationFailed(binding.permission.name);
|
|
1124
|
-
error.addIssues(issues);
|
|
1125
|
-
throw error;
|
|
1126
|
-
}
|
|
1127
|
-
count--;
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
if (count > 0) {
|
|
1131
|
-
return;
|
|
1132
|
-
}
|
|
1133
|
-
if (issues.length === 0) {
|
|
1134
|
-
throw PermissionError.deniedAll(ctx.name);
|
|
1135
|
-
} else {
|
|
1136
|
-
const error = PermissionError.evaluationFailed(ctx.name);
|
|
1137
|
-
error.addIssues(issues);
|
|
1138
|
-
throw error;
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
async evaluateOneOf(ctx) {
|
|
1142
|
-
return this.evaluate({
|
|
1143
|
-
...ctx,
|
|
1144
|
-
options: {
|
|
1145
|
-
...ctx.options || {},
|
|
1146
|
-
decisionStrategy: DecisionStrategy.AFFIRMATIVE
|
|
1147
|
-
}
|
|
1148
|
-
});
|
|
1149
|
-
}
|
|
1150
|
-
// ----------------------------------------------
|
|
1151
|
-
async preEvaluate(ctx) {
|
|
1152
|
-
return this.evaluate({
|
|
1153
|
-
...ctx,
|
|
1154
|
-
options: {
|
|
1155
|
-
...ctx.options || {},
|
|
1156
|
-
policiesExcluded: [
|
|
1157
|
-
BuiltInPolicyType.ATTRIBUTES,
|
|
1158
|
-
BuiltInPolicyType.ATTRIBUTE_NAMES,
|
|
1159
|
-
BuiltInPolicyType.REALM_MATCH
|
|
1160
|
-
]
|
|
1161
|
-
}
|
|
1162
|
-
});
|
|
1163
|
-
}
|
|
1164
|
-
async preEvaluateOneOf(ctx) {
|
|
1165
|
-
return this.preEvaluate({
|
|
1166
|
-
...ctx,
|
|
1167
|
-
options: {
|
|
1168
|
-
...ctx.options || {},
|
|
1169
|
-
decisionStrategy: DecisionStrategy.AFFIRMATIVE
|
|
1170
|
-
}
|
|
1171
|
-
});
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
|
|
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 };
|
|
1176
|
-
//# sourceMappingURL=index.mjs.map
|
|
1007
|
+
//# sourceMappingURL=index.mjs.map
|