@casual-simulation/aux-records 3.2.13 → 3.2.14-alpha.7890390188
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/AIController.d.ts +7 -4
- package/AIController.js +11 -0
- package/AIController.js.map +1 -1
- package/AuthController.d.ts +2 -1
- package/AuthController.js +6 -3
- package/AuthController.js.map +1 -1
- package/AuthStore.d.ts +1 -21
- package/CachingPolicyStore.d.ts +16 -5
- package/CachingPolicyStore.js +66 -39
- package/CachingPolicyStore.js.map +1 -1
- package/DataRecordsController.d.ts +67 -5
- package/DataRecordsController.js +141 -78
- package/DataRecordsController.js.map +1 -1
- package/DataRecordsStore.d.ts +35 -1
- package/DataRecordsStore.js.map +1 -1
- package/EventRecordsController.d.ts +5 -5
- package/EventRecordsController.js +54 -35
- package/EventRecordsController.js.map +1 -1
- package/FileRecordsController.d.ts +6 -6
- package/FileRecordsController.js +142 -76
- package/FileRecordsController.js.map +1 -1
- package/MemoryStore.d.ts +28 -17
- package/MemoryStore.js +457 -110
- package/MemoryStore.js.map +1 -1
- package/PolicyController.d.ts +512 -677
- package/PolicyController.js +1196 -2934
- package/PolicyController.js.map +1 -1
- package/PolicyStore.d.ts +319 -90
- package/PolicyStore.js +125 -0
- package/PolicyStore.js.map +1 -1
- package/RecordsServer.d.ts +3 -4
- package/RecordsServer.js +88 -111
- package/RecordsServer.js.map +1 -1
- package/RecordsStore.d.ts +3 -0
- package/TestUtils.d.ts +1 -1
- package/TestUtils.js.map +1 -1
- package/Utils.d.ts +21 -3
- package/Utils.js +42 -3
- package/Utils.js.map +1 -1
- package/package.json +3 -3
- package/websockets/InstRecordsStore.d.ts +21 -0
- package/websockets/InstRecordsStore.js +43 -1
- package/websockets/InstRecordsStore.js.map +1 -1
- package/websockets/WebsocketController.d.ts +7 -7
- package/websockets/WebsocketController.js +153 -82
- package/websockets/WebsocketController.js.map +1 -1
package/PolicyController.js
CHANGED
|
@@ -7,21 +7,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
|
-
var t = {};
|
|
12
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
13
|
-
t[p] = s[p];
|
|
14
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
15
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
16
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
17
|
-
t[p[i]] = s[p[i]];
|
|
18
|
-
}
|
|
19
|
-
return t;
|
|
20
|
-
};
|
|
21
10
|
import { isRecordKey, } from './RecordsController';
|
|
22
|
-
import { ADMIN_ROLE_NAME, ACCOUNT_MARKER, } from '@casual-simulation/aux-common';
|
|
23
|
-
import { getExpireTime, } from './PolicyStore';
|
|
24
|
-
import {
|
|
11
|
+
import { ADMIN_ROLE_NAME, PUBLIC_READ_MARKER, ACCOUNT_MARKER, } from '@casual-simulation/aux-common';
|
|
12
|
+
import { getExpireTime, getPublicMarkersPermission, } from './PolicyStore';
|
|
13
|
+
import { sortBy, without } from 'lodash';
|
|
14
|
+
import { getRootMarker, getRootMarkersOrDefault } from './Utils';
|
|
15
|
+
import { normalizeInstId, parseInstId } from './websockets';
|
|
25
16
|
/**
|
|
26
17
|
* The maximum number of instances that can be authorized at once.
|
|
27
18
|
*/
|
|
@@ -30,25 +21,105 @@ export const MAX_ALLOWED_INSTANCES = 2;
|
|
|
30
21
|
* The maximum number of markers that can be placed on a resource at once.
|
|
31
22
|
*/
|
|
32
23
|
export const MAX_ALLOWED_MARKERS = 2;
|
|
24
|
+
const ALLOWED_RECORD_KEY_RESOURCES = [
|
|
25
|
+
['data', ['read', 'create', 'delete', 'update', 'list']],
|
|
26
|
+
['file', ['read', 'create', 'delete']],
|
|
27
|
+
['event', ['create', 'count', 'increment', 'update']],
|
|
28
|
+
[
|
|
29
|
+
'inst',
|
|
30
|
+
['read', 'create', 'delete', 'update', 'updateData', 'sendAction'],
|
|
31
|
+
],
|
|
32
|
+
];
|
|
33
|
+
const ALLOWED_STUDIO_MEMBER_RESOURCES = [
|
|
34
|
+
['data', ['read', 'create', 'delete', 'update', 'list']],
|
|
35
|
+
['file', ['read', 'create', 'delete', 'list']],
|
|
36
|
+
['event', ['create', 'count', 'increment', 'list']],
|
|
37
|
+
[
|
|
38
|
+
'inst',
|
|
39
|
+
[
|
|
40
|
+
'read',
|
|
41
|
+
'create',
|
|
42
|
+
'delete',
|
|
43
|
+
'update',
|
|
44
|
+
'updateData',
|
|
45
|
+
'sendAction',
|
|
46
|
+
'list',
|
|
47
|
+
],
|
|
48
|
+
],
|
|
49
|
+
];
|
|
50
|
+
function constructAllowedResourcesLookup(allowedResources) {
|
|
51
|
+
const lookup = new Set();
|
|
52
|
+
for (let [resourceKind, actions] of allowedResources) {
|
|
53
|
+
for (let action of actions) {
|
|
54
|
+
lookup.add(`${resourceKind}.${action}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return lookup;
|
|
58
|
+
}
|
|
59
|
+
const ALLOWED_RECORD_KEY_RESOURCES_LOOKUP = constructAllowedResourcesLookup(ALLOWED_RECORD_KEY_RESOURCES);
|
|
60
|
+
const ALLOWED_STUDIO_MEMBER_RESOURCES_LOOKUP = constructAllowedResourcesLookup(ALLOWED_STUDIO_MEMBER_RESOURCES);
|
|
33
61
|
/**
|
|
34
|
-
*
|
|
62
|
+
* Determines if the given resource kind and action are allowed to be accessed by a record key.
|
|
63
|
+
* @param resourceKind The kind of the resource kind.
|
|
64
|
+
* @param action The action.
|
|
35
65
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
errorMessage: 'You are not authorized to perform this action.',
|
|
40
|
-
};
|
|
66
|
+
function isAllowedRecordKeyResource(resourceKind, action) {
|
|
67
|
+
return ALLOWED_RECORD_KEY_RESOURCES_LOOKUP.has(`${resourceKind}.${action}`);
|
|
68
|
+
}
|
|
41
69
|
/**
|
|
42
|
-
*
|
|
70
|
+
* Determines if the given resource kind and action are allowed to be accessed by a studio member.
|
|
71
|
+
* @param resourceKind The kind of the resource kind.
|
|
72
|
+
* @param action The action.
|
|
43
73
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
74
|
+
function isAllowedStudioMemberResource(resourceKind, action) {
|
|
75
|
+
return ALLOWED_STUDIO_MEMBER_RESOURCES_LOOKUP.has(`${resourceKind}.${action}`);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Gets the resources that need to be authorized when creating a resource with the given markers.
|
|
79
|
+
* @param markers The markers that will be placed on the resource.
|
|
80
|
+
*/
|
|
81
|
+
export function getMarkerResourcesForCreation(markers) {
|
|
82
|
+
// If the resource has the PUBLIC_READ_MARKER, then we only need the "create" permission and not the "assign" permission.
|
|
83
|
+
return markers
|
|
84
|
+
.filter((m) => m !== PUBLIC_READ_MARKER)
|
|
85
|
+
.map((m) => ({
|
|
86
|
+
resourceKind: 'marker',
|
|
87
|
+
resourceId: m,
|
|
88
|
+
action: 'assign',
|
|
89
|
+
markers: [ACCOUNT_MARKER],
|
|
90
|
+
}));
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Gets the resources that need to be authorized when updating a resource with the given markers.
|
|
94
|
+
* @param existingMarkers The markers that already exist on the resource.
|
|
95
|
+
* @param newMarkers The markers that will replace the existing markers. If null, then no markers will be added or removed.
|
|
96
|
+
*/
|
|
97
|
+
export function getMarkerResourcesForUpdate(existingMarkers, newMarkers) {
|
|
98
|
+
const addedMarkers = newMarkers
|
|
99
|
+
? without(newMarkers, ...existingMarkers)
|
|
100
|
+
: [];
|
|
101
|
+
const removedMarkers = newMarkers
|
|
102
|
+
? without(existingMarkers, ...newMarkers)
|
|
103
|
+
: [];
|
|
104
|
+
const resources = [];
|
|
105
|
+
for (let marker of addedMarkers) {
|
|
106
|
+
resources.push({
|
|
107
|
+
resourceKind: 'marker',
|
|
108
|
+
resourceId: marker,
|
|
109
|
+
action: 'assign',
|
|
110
|
+
markers: [ACCOUNT_MARKER],
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
for (let marker of removedMarkers) {
|
|
114
|
+
resources.push({
|
|
115
|
+
resourceKind: 'marker',
|
|
116
|
+
resourceId: marker,
|
|
117
|
+
action: 'unassign',
|
|
118
|
+
markers: [ACCOUNT_MARKER],
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return resources;
|
|
122
|
+
}
|
|
52
123
|
/**
|
|
53
124
|
* Defines a class that is able to calculate the policies and permissions that are allowed for specific actions.
|
|
54
125
|
*/
|
|
@@ -67,6 +138,7 @@ export class PolicyController {
|
|
|
67
138
|
return __awaiter(this, void 0, void 0, function* () {
|
|
68
139
|
let recordKeyResult = null;
|
|
69
140
|
let recordName;
|
|
141
|
+
let recordKeyCreatorId;
|
|
70
142
|
let ownerId;
|
|
71
143
|
let studioId;
|
|
72
144
|
let studioMembers = undefined;
|
|
@@ -76,6 +148,7 @@ export class PolicyController {
|
|
|
76
148
|
if (recordKeyResult.success === true) {
|
|
77
149
|
recordName = recordKeyResult.recordName;
|
|
78
150
|
ownerId = recordKeyResult.ownerId;
|
|
151
|
+
recordKeyCreatorId = recordKeyResult.keyCreatorId;
|
|
79
152
|
}
|
|
80
153
|
else {
|
|
81
154
|
return {
|
|
@@ -102,14 +175,43 @@ export class PolicyController {
|
|
|
102
175
|
const subjectPolicy = !!recordKeyResult && recordKeyResult.success
|
|
103
176
|
? recordKeyResult.policy
|
|
104
177
|
: 'subjectfull';
|
|
178
|
+
let recordOwnerPrivacyFeatures = null;
|
|
179
|
+
let userPrivacyFeatures = null;
|
|
180
|
+
if (ownerId) {
|
|
181
|
+
recordOwnerPrivacyFeatures =
|
|
182
|
+
yield this._policies.getUserPrivacyFeatures(ownerId);
|
|
183
|
+
}
|
|
184
|
+
if (!recordOwnerPrivacyFeatures) {
|
|
185
|
+
recordOwnerPrivacyFeatures = {
|
|
186
|
+
allowAI: true,
|
|
187
|
+
allowPublicData: true,
|
|
188
|
+
allowPublicInsts: true,
|
|
189
|
+
publishData: true,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (request.userId) {
|
|
193
|
+
userPrivacyFeatures = yield this._policies.getUserPrivacyFeatures(request.userId);
|
|
194
|
+
}
|
|
195
|
+
if (!userPrivacyFeatures) {
|
|
196
|
+
userPrivacyFeatures = {
|
|
197
|
+
allowAI: true,
|
|
198
|
+
allowPublicData: true,
|
|
199
|
+
allowPublicInsts: true,
|
|
200
|
+
publishData: true,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
105
203
|
const context = {
|
|
106
204
|
recordName,
|
|
107
205
|
recordKeyResult,
|
|
108
206
|
subjectPolicy,
|
|
109
207
|
recordKeyProvided,
|
|
208
|
+
recordKeyCreatorId,
|
|
110
209
|
recordOwnerId: ownerId,
|
|
210
|
+
recordOwnerPrivacyFeatures,
|
|
111
211
|
recordStudioId: studioId,
|
|
112
212
|
recordStudioMembers: studioMembers,
|
|
213
|
+
userId: request.userId,
|
|
214
|
+
userPrivacyFeatures,
|
|
113
215
|
};
|
|
114
216
|
return {
|
|
115
217
|
success: true,
|
|
@@ -118,28 +220,40 @@ export class PolicyController {
|
|
|
118
220
|
});
|
|
119
221
|
}
|
|
120
222
|
/**
|
|
121
|
-
* Attempts to authorize the given
|
|
122
|
-
* Returns a promise that resolves with information about the security properties of the request.
|
|
223
|
+
* Attempts to authorize the given user and instances for the action and resource(s).
|
|
123
224
|
* @param context The authorization context for the request.
|
|
124
225
|
* @param request The request.
|
|
125
226
|
*/
|
|
126
|
-
|
|
227
|
+
authorizeUserAndInstances(context, request) {
|
|
228
|
+
var _a;
|
|
127
229
|
return __awaiter(this, void 0, void 0, function* () {
|
|
128
230
|
try {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
231
|
+
const authorization = yield this.authorizeSubjects(context, {
|
|
232
|
+
action: request.action,
|
|
233
|
+
markers: request.markers,
|
|
234
|
+
resourceKind: request.resourceKind,
|
|
235
|
+
resourceId: request.resourceId,
|
|
236
|
+
subjects: [
|
|
237
|
+
{
|
|
238
|
+
subjectType: 'user',
|
|
239
|
+
subjectId: request.userId,
|
|
240
|
+
},
|
|
241
|
+
...((_a = request.instances) !== null && _a !== void 0 ? _a : []).map((i) => ({
|
|
242
|
+
subjectType: 'inst',
|
|
243
|
+
subjectId: i,
|
|
244
|
+
})),
|
|
245
|
+
],
|
|
246
|
+
});
|
|
247
|
+
if (authorization.success === false) {
|
|
248
|
+
return authorization;
|
|
136
249
|
}
|
|
137
|
-
|
|
250
|
+
const userResult = authorization.results.find((r) => r.subjectType === 'user' && r.subjectId === request.userId);
|
|
251
|
+
return Object.assign(Object.assign({}, authorization), { user: userResult });
|
|
138
252
|
}
|
|
139
253
|
catch (err) {
|
|
140
|
-
console.error('[PolicyController] A server error occurred.', err);
|
|
254
|
+
console.error('[PolicyController] A server error occurred while authorizing user and instances.', err);
|
|
141
255
|
return {
|
|
142
|
-
|
|
256
|
+
success: false,
|
|
143
257
|
errorCode: 'server_error',
|
|
144
258
|
errorMessage: 'A server error occurred.',
|
|
145
259
|
};
|
|
@@ -147,20 +261,131 @@ export class PolicyController {
|
|
|
147
261
|
});
|
|
148
262
|
}
|
|
149
263
|
/**
|
|
150
|
-
* Attempts to authorize the given
|
|
151
|
-
* Returns a promise that resolves with information about the security properties of the request.
|
|
264
|
+
* Attempts to authorize the given user and instances for the given resources.
|
|
152
265
|
* @param context The authorization context for the request.
|
|
153
266
|
* @param request The request.
|
|
154
267
|
*/
|
|
155
|
-
|
|
268
|
+
authorizeUserAndInstancesForResources(context, request) {
|
|
269
|
+
var _a;
|
|
156
270
|
return __awaiter(this, void 0, void 0, function* () {
|
|
157
271
|
try {
|
|
158
|
-
|
|
272
|
+
const subjects = [
|
|
273
|
+
{
|
|
274
|
+
subjectType: 'user',
|
|
275
|
+
subjectId: request.userId,
|
|
276
|
+
},
|
|
277
|
+
...((_a = request.instances) !== null && _a !== void 0 ? _a : []).map((i) => ({
|
|
278
|
+
subjectType: 'inst',
|
|
279
|
+
subjectId: i,
|
|
280
|
+
})),
|
|
281
|
+
];
|
|
282
|
+
const subjectPermission = new Map();
|
|
283
|
+
const results = [];
|
|
284
|
+
const recordName = context.recordName;
|
|
285
|
+
for (let resource of request.resources) {
|
|
286
|
+
let subjectsToAuthorize = [];
|
|
287
|
+
let authorizations = [];
|
|
288
|
+
for (let subject of subjects) {
|
|
289
|
+
const subjectKey = `${subject.subjectType}.${subject.subjectId}`;
|
|
290
|
+
const authorizedSubject = subjectPermission.get(subjectKey);
|
|
291
|
+
if (authorizedSubject) {
|
|
292
|
+
const permission = authorizedSubject.permission;
|
|
293
|
+
const isCorrectResourceKind = permission.resourceKind === null ||
|
|
294
|
+
permission.resourceKind === resource.resourceKind;
|
|
295
|
+
const isCorrectAction = permission.action === null ||
|
|
296
|
+
permission.action === resource.action;
|
|
297
|
+
const isCorrectMarker = !('marker' in permission) ||
|
|
298
|
+
resource.markers.includes(permission.marker);
|
|
299
|
+
const isCorrectResource = !('resourceId' in permission) ||
|
|
300
|
+
permission.resourceId === null ||
|
|
301
|
+
permission.resourceId === resource.resourceId;
|
|
302
|
+
if (isCorrectResourceKind &&
|
|
303
|
+
isCorrectAction &&
|
|
304
|
+
isCorrectMarker &&
|
|
305
|
+
isCorrectResource) {
|
|
306
|
+
// Record the authorization
|
|
307
|
+
authorizations.push(authorizedSubject);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
subjectsToAuthorize.push(subject);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
subjectsToAuthorize.push(subject);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (subjectsToAuthorize.length > 0) {
|
|
318
|
+
const result = yield this.authorizeSubjects(context, {
|
|
319
|
+
action: resource.action,
|
|
320
|
+
markers: resource.markers,
|
|
321
|
+
resourceKind: resource.resourceKind,
|
|
322
|
+
resourceId: resource.resourceId,
|
|
323
|
+
subjects: subjectsToAuthorize,
|
|
324
|
+
});
|
|
325
|
+
if (result.success === false) {
|
|
326
|
+
return result;
|
|
327
|
+
}
|
|
328
|
+
for (let authorization of result.results) {
|
|
329
|
+
const subjectKey = `${authorization.subjectType}.${authorization.subjectId}`;
|
|
330
|
+
authorizations.push(authorization);
|
|
331
|
+
const permission = authorization.permission;
|
|
332
|
+
const existingAuthorization = subjectPermission.get(subjectKey);
|
|
333
|
+
if (!existingAuthorization) {
|
|
334
|
+
subjectPermission.set(subjectKey, authorization);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
const existingPermission = existingAuthorization.permission;
|
|
338
|
+
const isResourceKindMoreGeneral = permission.resourceKind === null &&
|
|
339
|
+
existingPermission.resourceKind !== null;
|
|
340
|
+
const isActionMoreGeneral = permission.action === null &&
|
|
341
|
+
existingPermission.action !== null;
|
|
342
|
+
const isMarkerMoreGeneral = 'marker' in permission &&
|
|
343
|
+
'marker' in existingPermission &&
|
|
344
|
+
permission.marker === null &&
|
|
345
|
+
existingPermission.marker !== null;
|
|
346
|
+
const isResourceMoreGeneral = 'resourceId' in permission &&
|
|
347
|
+
'resourceId' in existingPermission &&
|
|
348
|
+
permission.resourceId === null &&
|
|
349
|
+
existingPermission.resourceId !== null;
|
|
350
|
+
if (isResourceKindMoreGeneral ||
|
|
351
|
+
isActionMoreGeneral ||
|
|
352
|
+
isMarkerMoreGeneral ||
|
|
353
|
+
isResourceMoreGeneral) {
|
|
354
|
+
subjectPermission.set(subjectKey, authorization);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (authorizations.length !== subjects.length) {
|
|
360
|
+
console.error('[PolicyController] [authorizeUserAndInstancesForResources] The number of authorizations does not match the number of subjects!');
|
|
361
|
+
return {
|
|
362
|
+
success: false,
|
|
363
|
+
errorCode: 'server_error',
|
|
364
|
+
errorMessage: 'A server error occurred.',
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
results.push({
|
|
368
|
+
success: true,
|
|
369
|
+
recordName: recordName,
|
|
370
|
+
resourceKind: resource.resourceKind,
|
|
371
|
+
resourceId: resource.resourceId,
|
|
372
|
+
action: resource.action,
|
|
373
|
+
markers: resource.markers,
|
|
374
|
+
results: authorizations,
|
|
375
|
+
user: authorizations.find((r) => r.subjectType === 'user' &&
|
|
376
|
+
r.subjectId === request.userId),
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
return {
|
|
380
|
+
success: true,
|
|
381
|
+
recordName: recordName,
|
|
382
|
+
results,
|
|
383
|
+
};
|
|
159
384
|
}
|
|
160
385
|
catch (err) {
|
|
161
|
-
console.error('[PolicyController] A server error occurred.', err);
|
|
386
|
+
console.error('[PolicyController] A server error occurred while authorizing user and instances for resources.', err);
|
|
162
387
|
return {
|
|
163
|
-
|
|
388
|
+
success: false,
|
|
164
389
|
errorCode: 'server_error',
|
|
165
390
|
errorMessage: 'A server error occurred.',
|
|
166
391
|
};
|
|
@@ -168,65 +393,36 @@ export class PolicyController {
|
|
|
168
393
|
});
|
|
169
394
|
}
|
|
170
395
|
/**
|
|
171
|
-
* Attempts to
|
|
172
|
-
* @param
|
|
396
|
+
* Attempts to authorize the given subjects for the action and resource(s).
|
|
397
|
+
* @param context The authorization context for the request.
|
|
398
|
+
* @param request The request.
|
|
173
399
|
*/
|
|
174
|
-
|
|
400
|
+
authorizeSubjects(context, request) {
|
|
175
401
|
return __awaiter(this, void 0, void 0, function* () {
|
|
176
402
|
try {
|
|
177
|
-
|
|
178
|
-
recordKeyOrRecordName: request.recordKeyOrRecordName,
|
|
179
|
-
userId: request.userId,
|
|
180
|
-
};
|
|
181
|
-
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
182
|
-
if (context.success === false) {
|
|
183
|
-
return {
|
|
184
|
-
success: false,
|
|
185
|
-
errorCode: context.errorCode,
|
|
186
|
-
errorMessage: context.errorMessage,
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
const authorization = yield this.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'policy.grantPermission' }, baseRequest), { policy: request.marker, instances: request.instances }));
|
|
190
|
-
if (authorization.allowed === false) {
|
|
191
|
-
return returnAuthorizationResult(authorization);
|
|
192
|
-
}
|
|
193
|
-
const policyResult = yield this._policies.getUserPolicy(context.context.recordName, request.marker);
|
|
194
|
-
if (policyResult.success === false &&
|
|
195
|
-
policyResult.errorCode !== 'policy_not_found') {
|
|
196
|
-
console.log(`[PolicyController] Failure while retrieving policy for ${context.context.recordName} and ${request.marker}.`, policyResult);
|
|
403
|
+
if (request.subjects.length <= 0) {
|
|
197
404
|
return {
|
|
198
405
|
success: false,
|
|
199
|
-
errorCode:
|
|
200
|
-
errorMessage:
|
|
406
|
+
errorCode: 'unacceptable_request',
|
|
407
|
+
errorMessage: 'You must provide at least one subject to authorize.',
|
|
201
408
|
};
|
|
202
409
|
}
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
:
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
},
|
|
209
|
-
markers: [ACCOUNT_MARKER],
|
|
210
|
-
};
|
|
211
|
-
const alreadyExists = policy.document.permissions.some((p) => isEqual(p, request.permission));
|
|
212
|
-
if (!alreadyExists) {
|
|
213
|
-
console.log(`[PolicyController] Adding permission to policy for ${context.context.recordName} and ${request.marker}.`, request.permission);
|
|
214
|
-
policy.document.permissions.push(request.permission);
|
|
215
|
-
const updateResult = yield this._policies.updateUserPolicy(context.context.recordName, request.marker, {
|
|
216
|
-
document: policy.document,
|
|
217
|
-
markers: policy.markers,
|
|
218
|
-
});
|
|
219
|
-
if (updateResult.success === false) {
|
|
220
|
-
console.log(`[PolicyController] Policy update failed:`, updateResult);
|
|
221
|
-
return updateResult;
|
|
410
|
+
const results = [];
|
|
411
|
+
for (let subject of request.subjects) {
|
|
412
|
+
const subjectResult = yield this.authorizeSubjectUsingContext(context, Object.assign(Object.assign({}, subject), { action: request.action, resourceKind: request.resourceKind, resourceId: request.resourceId, markers: request.markers }));
|
|
413
|
+
if (subjectResult.success === false) {
|
|
414
|
+
return subjectResult;
|
|
222
415
|
}
|
|
416
|
+
results.push(Object.assign(Object.assign({}, subjectResult), { subjectType: subject.subjectType, subjectId: subject.subjectId }));
|
|
223
417
|
}
|
|
224
418
|
return {
|
|
225
419
|
success: true,
|
|
420
|
+
recordName: context.recordName,
|
|
421
|
+
results: results,
|
|
226
422
|
};
|
|
227
423
|
}
|
|
228
424
|
catch (err) {
|
|
229
|
-
console.error('[PolicyController] A server error occurred.', err);
|
|
425
|
+
console.error('[PolicyController] A server error occurred while authorizing subjects.', err);
|
|
230
426
|
return {
|
|
231
427
|
success: false,
|
|
232
428
|
errorCode: 'server_error',
|
|
@@ -236,69 +432,457 @@ export class PolicyController {
|
|
|
236
432
|
});
|
|
237
433
|
}
|
|
238
434
|
/**
|
|
239
|
-
* Attempts to
|
|
240
|
-
*
|
|
435
|
+
* Attempts to authorize the given subject for the action and resource(s).
|
|
436
|
+
* Returns a promise that resolves with information about the security properties of the request.
|
|
437
|
+
* @param context The context for the request.
|
|
438
|
+
* @param request The request to authorize.
|
|
241
439
|
*/
|
|
242
|
-
|
|
440
|
+
authorizeSubject(context, request) {
|
|
243
441
|
return __awaiter(this, void 0, void 0, function* () {
|
|
244
442
|
try {
|
|
245
|
-
const baseRequest = {
|
|
246
|
-
recordKeyOrRecordName: request.recordKeyOrRecordName,
|
|
247
|
-
userId: request.userId,
|
|
248
|
-
};
|
|
249
|
-
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
250
443
|
if (context.success === false) {
|
|
444
|
+
return context;
|
|
445
|
+
}
|
|
446
|
+
return yield this.authorizeSubjectUsingContext(context.context, request);
|
|
447
|
+
}
|
|
448
|
+
catch (err) {
|
|
449
|
+
console.error('[PolicyController] A server error occurred while authorizing a subject.', err);
|
|
450
|
+
return {
|
|
451
|
+
success: false,
|
|
452
|
+
errorCode: 'server_error',
|
|
453
|
+
errorMessage: 'A server error occurred.',
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Attempts to authorize the given subject for the action and resource(s).
|
|
460
|
+
* Returns a promise that resolves with information about the security properties of the request.
|
|
461
|
+
* @param context The context for the request.
|
|
462
|
+
* @param request The request to authorize.
|
|
463
|
+
*/
|
|
464
|
+
authorizeSubjectUsingContext(context, request) {
|
|
465
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
466
|
+
const result = yield this._authorizeSubjectUsingContext(context, request);
|
|
467
|
+
if (result.success) {
|
|
468
|
+
console.log(`[PolicyController] [action: ${request.resourceKind}.${request.action} resourceId: ${request.resourceId} recordName: ${context.recordName}, userId: ${context.userId}] Request authorized.`);
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
console.log(`[PolicyController] [action: ${request.resourceKind}.${request.action} resourceId: ${request.resourceId} recordName: ${context.recordName}, userId: ${context.userId}] Request denied:`, result);
|
|
472
|
+
}
|
|
473
|
+
return result;
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Attempts to authorize the given subject for the action and resource(s).
|
|
478
|
+
* Returns a promise that resolves with information about the security properties of the request.
|
|
479
|
+
* @param context The context for the request.
|
|
480
|
+
* @param request The request to authorize.
|
|
481
|
+
*/
|
|
482
|
+
_authorizeSubjectUsingContext(context, request) {
|
|
483
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
484
|
+
try {
|
|
485
|
+
const markers = getRootMarkersOrDefault(request.markers);
|
|
486
|
+
if (request.action === 'list' && markers.length > 1) {
|
|
251
487
|
return {
|
|
252
488
|
success: false,
|
|
253
|
-
errorCode:
|
|
254
|
-
errorMessage:
|
|
489
|
+
errorCode: 'not_authorized',
|
|
490
|
+
errorMessage: `The "${request.action}" action cannot be used with multiple markers.`,
|
|
491
|
+
reason: {
|
|
492
|
+
type: 'too_many_markers',
|
|
493
|
+
},
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
if (!context.userPrivacyFeatures.publishData) {
|
|
497
|
+
return {
|
|
498
|
+
success: false,
|
|
499
|
+
errorCode: 'not_authorized',
|
|
500
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
501
|
+
reason: {
|
|
502
|
+
type: 'disabled_privacy_feature',
|
|
503
|
+
recordName: context.recordName,
|
|
504
|
+
subjectType: 'user',
|
|
505
|
+
subjectId: context.userId,
|
|
506
|
+
resourceKind: request.resourceKind,
|
|
507
|
+
action: request.action,
|
|
508
|
+
resourceId: request.resourceId,
|
|
509
|
+
privacyFeature: 'publishData',
|
|
510
|
+
},
|
|
255
511
|
};
|
|
256
512
|
}
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
513
|
+
const recordName = context.recordName;
|
|
514
|
+
const subjectType = request.subjectType;
|
|
515
|
+
let subjectId = request.subjectId;
|
|
516
|
+
if (subjectType === 'inst') {
|
|
517
|
+
subjectId = normalizeInstId(subjectId);
|
|
260
518
|
}
|
|
261
|
-
const
|
|
262
|
-
if (
|
|
263
|
-
|
|
519
|
+
const publicPermission = getPublicMarkersPermission(markers, request.resourceKind, request.action);
|
|
520
|
+
if (context.recordOwnerId &&
|
|
521
|
+
context.userId !== context.recordOwnerId) {
|
|
522
|
+
if (!context.recordOwnerPrivacyFeatures.allowPublicData) {
|
|
264
523
|
return {
|
|
265
|
-
success:
|
|
524
|
+
success: false,
|
|
525
|
+
errorCode: 'not_authorized',
|
|
526
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
527
|
+
reason: {
|
|
528
|
+
type: 'disabled_privacy_feature',
|
|
529
|
+
recordName: context.recordName,
|
|
530
|
+
subjectType: 'user',
|
|
531
|
+
subjectId: context.userId,
|
|
532
|
+
resourceKind: request.resourceKind,
|
|
533
|
+
action: request.action,
|
|
534
|
+
resourceId: request.resourceId,
|
|
535
|
+
privacyFeature: 'allowPublicData',
|
|
536
|
+
},
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
if (request.resourceKind === 'inst' &&
|
|
540
|
+
(!context.recordOwnerPrivacyFeatures.allowPublicInsts ||
|
|
541
|
+
!context.userPrivacyFeatures.allowPublicInsts)) {
|
|
542
|
+
return {
|
|
543
|
+
success: false,
|
|
544
|
+
errorCode: 'not_authorized',
|
|
545
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
546
|
+
reason: {
|
|
547
|
+
type: 'disabled_privacy_feature',
|
|
548
|
+
recordName: context.recordName,
|
|
549
|
+
subjectType: 'user',
|
|
550
|
+
subjectId: context.userId,
|
|
551
|
+
resourceKind: request.resourceKind,
|
|
552
|
+
action: request.action,
|
|
553
|
+
resourceId: request.resourceId,
|
|
554
|
+
privacyFeature: 'allowPublicInsts',
|
|
555
|
+
},
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
if (publicPermission) {
|
|
560
|
+
if (!context.userPrivacyFeatures.allowPublicData) {
|
|
561
|
+
return {
|
|
562
|
+
success: false,
|
|
563
|
+
errorCode: 'not_authorized',
|
|
564
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
565
|
+
reason: {
|
|
566
|
+
type: 'disabled_privacy_feature',
|
|
567
|
+
recordName: context.recordName,
|
|
568
|
+
subjectType: 'user',
|
|
569
|
+
subjectId: context.userId,
|
|
570
|
+
resourceKind: request.resourceKind,
|
|
571
|
+
action: request.action,
|
|
572
|
+
resourceId: request.resourceId,
|
|
573
|
+
privacyFeature: 'allowPublicData',
|
|
574
|
+
},
|
|
266
575
|
};
|
|
267
576
|
}
|
|
268
|
-
console.log(`[PolicyController] Failure while retrieving policy for ${context.context.recordName} and ${request.marker}.`, policyResult);
|
|
269
577
|
return {
|
|
270
|
-
success:
|
|
271
|
-
|
|
272
|
-
|
|
578
|
+
success: true,
|
|
579
|
+
recordName,
|
|
580
|
+
permission: {
|
|
581
|
+
id: null,
|
|
582
|
+
recordName: recordName,
|
|
583
|
+
userId: null,
|
|
584
|
+
subjectType: subjectType,
|
|
585
|
+
subjectId: subjectId,
|
|
586
|
+
resourceKind: publicPermission.resourceKind,
|
|
587
|
+
action: publicPermission.action,
|
|
588
|
+
marker: publicPermission.marker,
|
|
589
|
+
options: {},
|
|
590
|
+
expireTimeMs: null,
|
|
591
|
+
},
|
|
592
|
+
explanation: publicPermission.marker === PUBLIC_READ_MARKER
|
|
593
|
+
? 'Resource has the publicRead marker.'
|
|
594
|
+
: 'Resource has the publicWrite marker.',
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
if (subjectType === 'role' && subjectId === ADMIN_ROLE_NAME) {
|
|
598
|
+
return {
|
|
599
|
+
success: true,
|
|
600
|
+
recordName: recordName,
|
|
601
|
+
permission: {
|
|
602
|
+
id: null,
|
|
603
|
+
recordName: recordName,
|
|
604
|
+
userId: null,
|
|
605
|
+
// Record owners are treated as if they are admins in the record
|
|
606
|
+
subjectType: 'role',
|
|
607
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
608
|
+
// Admins get all access to all resources in a record
|
|
609
|
+
resourceKind: null,
|
|
610
|
+
action: null,
|
|
611
|
+
marker: markers[0],
|
|
612
|
+
options: {},
|
|
613
|
+
expireTimeMs: null,
|
|
614
|
+
},
|
|
615
|
+
explanation: `Role is "${ADMIN_ROLE_NAME}".`,
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
if (context.recordKeyProvided &&
|
|
619
|
+
context.recordKeyResult &&
|
|
620
|
+
context.recordKeyResult.success &&
|
|
621
|
+
isAllowedRecordKeyResource(request.resourceKind, request.action)) {
|
|
622
|
+
if (context.subjectPolicy === 'subjectfull' &&
|
|
623
|
+
subjectType === 'user' &&
|
|
624
|
+
!subjectId) {
|
|
625
|
+
return {
|
|
626
|
+
success: false,
|
|
627
|
+
errorCode: 'not_logged_in',
|
|
628
|
+
errorMessage: 'You must be logged in in order to use this record key.',
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
return {
|
|
632
|
+
success: true,
|
|
633
|
+
recordName: context.recordName,
|
|
634
|
+
permission: {
|
|
635
|
+
id: null,
|
|
636
|
+
recordName: recordName,
|
|
637
|
+
userId: null,
|
|
638
|
+
// Record owners are treated as if they are admins in the record
|
|
639
|
+
subjectType: 'role',
|
|
640
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
641
|
+
// Admins get all access to all resources in a record
|
|
642
|
+
resourceKind: request.resourceKind,
|
|
643
|
+
action: request.action,
|
|
644
|
+
marker: markers[0],
|
|
645
|
+
options: {},
|
|
646
|
+
expireTimeMs: null,
|
|
647
|
+
},
|
|
648
|
+
explanation: 'A recordKey was used.',
|
|
273
649
|
};
|
|
274
650
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
651
|
+
if (subjectType === 'user' && subjectId) {
|
|
652
|
+
if (subjectId === context.recordOwnerId) {
|
|
653
|
+
return {
|
|
654
|
+
success: true,
|
|
655
|
+
recordName: recordName,
|
|
656
|
+
permission: {
|
|
657
|
+
id: null,
|
|
658
|
+
recordName: recordName,
|
|
659
|
+
userId: null,
|
|
660
|
+
// Record owners are treated as if they are admins in the record
|
|
661
|
+
subjectType: 'role',
|
|
662
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
663
|
+
// Admins get all access to all resources in a record
|
|
664
|
+
resourceKind: null,
|
|
665
|
+
action: null,
|
|
666
|
+
marker: markers[0],
|
|
667
|
+
options: {},
|
|
668
|
+
expireTimeMs: null,
|
|
669
|
+
},
|
|
670
|
+
explanation: 'User is the owner of the record.',
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
else if (context.recordStudioMembers) {
|
|
674
|
+
const member = context.recordStudioMembers.find((m) => m.userId === subjectId);
|
|
675
|
+
if (member) {
|
|
676
|
+
if (member.role === 'admin') {
|
|
677
|
+
return {
|
|
678
|
+
success: true,
|
|
679
|
+
recordName: recordName,
|
|
680
|
+
permission: {
|
|
681
|
+
id: null,
|
|
682
|
+
recordName: recordName,
|
|
683
|
+
userId: null,
|
|
684
|
+
// Admins in a studio are treated as if they are admins in the record.
|
|
685
|
+
subjectType: 'role',
|
|
686
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
687
|
+
// Admins get all access to all resources in a record
|
|
688
|
+
resourceKind: null,
|
|
689
|
+
action: null,
|
|
690
|
+
marker: markers[0],
|
|
691
|
+
options: {},
|
|
692
|
+
// No expiration
|
|
693
|
+
expireTimeMs: null,
|
|
694
|
+
},
|
|
695
|
+
explanation: "User is an admin in the record's studio.",
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
else if (member.role === 'member' &&
|
|
699
|
+
isAllowedStudioMemberResource(request.resourceKind, request.action)) {
|
|
700
|
+
return {
|
|
701
|
+
success: true,
|
|
702
|
+
recordName: recordName,
|
|
703
|
+
permission: {
|
|
704
|
+
id: null,
|
|
705
|
+
recordName: recordName,
|
|
706
|
+
// Members in a studio are treated as if they are granted direct access to most resources
|
|
707
|
+
// in the record.
|
|
708
|
+
userId: subjectId,
|
|
709
|
+
subjectType: 'user',
|
|
710
|
+
subjectId: subjectId,
|
|
711
|
+
// Not all actions or resources are granted though
|
|
712
|
+
resourceKind: request.resourceKind,
|
|
713
|
+
action: request.action,
|
|
714
|
+
marker: markers[0],
|
|
715
|
+
options: {},
|
|
716
|
+
expireTimeMs: null,
|
|
717
|
+
},
|
|
718
|
+
explanation: "User is a member in the record's studio.",
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
}
|
|
283
722
|
}
|
|
284
723
|
}
|
|
285
|
-
if (
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
724
|
+
else if (subjectType === 'inst' && subjectId) {
|
|
725
|
+
const instId = parseInstId(subjectId);
|
|
726
|
+
if (!instId) {
|
|
727
|
+
return {
|
|
728
|
+
success: false,
|
|
729
|
+
errorCode: 'unacceptable_request',
|
|
730
|
+
errorMessage: 'Invalid inst ID. It must contain a forward slash',
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
if (instId.recordName) {
|
|
734
|
+
if (instId.recordName === recordName) {
|
|
735
|
+
return {
|
|
736
|
+
success: true,
|
|
737
|
+
recordName: recordName,
|
|
738
|
+
permission: {
|
|
739
|
+
id: null,
|
|
740
|
+
recordName: recordName,
|
|
741
|
+
userId: null,
|
|
742
|
+
subjectType: 'inst',
|
|
743
|
+
subjectId: subjectId,
|
|
744
|
+
// resourceKind and action are specified
|
|
745
|
+
// because insts don't necessarily have all permissions in the record
|
|
746
|
+
resourceKind: request.resourceKind,
|
|
747
|
+
action: request.action,
|
|
748
|
+
marker: markers[0],
|
|
749
|
+
options: {},
|
|
750
|
+
expireTimeMs: null,
|
|
751
|
+
},
|
|
752
|
+
explanation: `Inst is owned by the record.`,
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
const instRecord = yield this._records.validateRecordName(instId.recordName, context.userId);
|
|
756
|
+
if (instRecord.success === false) {
|
|
757
|
+
return instRecord;
|
|
758
|
+
}
|
|
759
|
+
else if (instRecord.ownerId &&
|
|
760
|
+
instRecord.ownerId === context.recordOwnerId) {
|
|
761
|
+
return {
|
|
762
|
+
success: true,
|
|
763
|
+
recordName: recordName,
|
|
764
|
+
permission: {
|
|
765
|
+
id: null,
|
|
766
|
+
recordName: recordName,
|
|
767
|
+
userId: null,
|
|
768
|
+
subjectType: 'inst',
|
|
769
|
+
subjectId: subjectId,
|
|
770
|
+
// resourceKind and action are specified
|
|
771
|
+
// because insts don't necessarily have all permissions in the record
|
|
772
|
+
resourceKind: request.resourceKind,
|
|
773
|
+
action: request.action,
|
|
774
|
+
marker: markers[0],
|
|
775
|
+
options: {},
|
|
776
|
+
expireTimeMs: null,
|
|
777
|
+
},
|
|
778
|
+
explanation: `Inst is owned by the record's (${recordName}) owner (${context.recordOwnerId}).`,
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
else if (instRecord.studioId &&
|
|
782
|
+
instRecord.studioId === context.recordStudioId) {
|
|
783
|
+
return {
|
|
784
|
+
success: true,
|
|
785
|
+
recordName: recordName,
|
|
786
|
+
permission: {
|
|
787
|
+
id: null,
|
|
788
|
+
recordName: recordName,
|
|
789
|
+
userId: null,
|
|
790
|
+
subjectType: 'inst',
|
|
791
|
+
subjectId: subjectId,
|
|
792
|
+
// resourceKind and action are specified
|
|
793
|
+
// because insts don't necessarily have all permissions in the record
|
|
794
|
+
resourceKind: request.resourceKind,
|
|
795
|
+
action: request.action,
|
|
796
|
+
marker: markers[0],
|
|
797
|
+
options: {},
|
|
798
|
+
expireTimeMs: null,
|
|
799
|
+
},
|
|
800
|
+
explanation: `Inst is owned by the record's (${recordName}) studio (${context.recordStudioId}).`,
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
if (subjectId) {
|
|
806
|
+
if (subjectType === 'inst' || subjectType === 'user') {
|
|
807
|
+
// check for admin role
|
|
808
|
+
const roles = subjectType === 'user'
|
|
809
|
+
? yield this._policies.listRolesForUser(recordName, subjectId)
|
|
810
|
+
: yield this._policies.listRolesForInst(recordName, subjectId);
|
|
811
|
+
const role = roles.find((r) => r.role === ADMIN_ROLE_NAME);
|
|
812
|
+
if (role) {
|
|
813
|
+
const kindString = subjectType === 'user' ? 'User' : 'Inst';
|
|
814
|
+
return {
|
|
815
|
+
success: true,
|
|
816
|
+
recordName: recordName,
|
|
817
|
+
permission: {
|
|
818
|
+
id: null,
|
|
819
|
+
recordName: recordName,
|
|
820
|
+
userId: null,
|
|
821
|
+
// Admins in a studio are treated as if they are admins in the record.
|
|
822
|
+
subjectType: 'role',
|
|
823
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
824
|
+
// Admins get all access to all resources in a record
|
|
825
|
+
resourceKind: null,
|
|
826
|
+
action: null,
|
|
827
|
+
marker: markers[0],
|
|
828
|
+
options: {},
|
|
829
|
+
// No expiration
|
|
830
|
+
expireTimeMs: role.expireTimeMs,
|
|
831
|
+
},
|
|
832
|
+
explanation: `${kindString} is assigned the "${ADMIN_ROLE_NAME}" role.`,
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
let permission = null;
|
|
837
|
+
if (request.resourceId) {
|
|
838
|
+
const result = yield this._policies.getPermissionForSubjectAndResource(subjectType, subjectId, recordName, request.resourceKind, request.resourceId, request.action, Date.now());
|
|
839
|
+
if (result.success === false) {
|
|
840
|
+
return result;
|
|
841
|
+
}
|
|
842
|
+
permission = result.permissionAssignment;
|
|
843
|
+
}
|
|
844
|
+
if (!permission) {
|
|
845
|
+
const result = yield this._policies.getPermissionForSubjectAndMarkers(subjectType, subjectId, recordName, request.resourceKind, markers, request.action, Date.now());
|
|
846
|
+
if (result.success === false) {
|
|
847
|
+
return result;
|
|
848
|
+
}
|
|
849
|
+
permission = result.permissionAssignment;
|
|
850
|
+
}
|
|
851
|
+
if (permission) {
|
|
852
|
+
return {
|
|
853
|
+
success: true,
|
|
854
|
+
recordName,
|
|
855
|
+
permission: permission,
|
|
856
|
+
explanation: explainationForPermissionAssignment(subjectType, permission),
|
|
857
|
+
};
|
|
294
858
|
}
|
|
295
859
|
}
|
|
860
|
+
if (!subjectId &&
|
|
861
|
+
(!context.recordKeyProvided ||
|
|
862
|
+
!isAllowedRecordKeyResource(request.resourceKind, request.action))) {
|
|
863
|
+
return {
|
|
864
|
+
success: false,
|
|
865
|
+
errorCode: 'not_logged_in',
|
|
866
|
+
errorMessage: 'The user must be logged in. Please provide a sessionKey or a recordKey.',
|
|
867
|
+
};
|
|
868
|
+
}
|
|
296
869
|
return {
|
|
297
|
-
success:
|
|
870
|
+
success: false,
|
|
871
|
+
errorCode: 'not_authorized',
|
|
872
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
873
|
+
reason: {
|
|
874
|
+
type: 'missing_permission',
|
|
875
|
+
recordName: recordName,
|
|
876
|
+
subjectType: subjectType,
|
|
877
|
+
subjectId: subjectId,
|
|
878
|
+
resourceKind: request.resourceKind,
|
|
879
|
+
resourceId: request.resourceId,
|
|
880
|
+
action: request.action,
|
|
881
|
+
},
|
|
298
882
|
};
|
|
299
883
|
}
|
|
300
884
|
catch (err) {
|
|
301
|
-
console.error('[PolicyController] A server error occurred.', err);
|
|
885
|
+
console.error('[PolicyController] A server error occurred while authorizing a subject.', err);
|
|
302
886
|
return {
|
|
303
887
|
success: false,
|
|
304
888
|
errorCode: 'server_error',
|
|
@@ -308,45 +892,65 @@ export class PolicyController {
|
|
|
308
892
|
});
|
|
309
893
|
}
|
|
310
894
|
/**
|
|
311
|
-
*
|
|
312
|
-
* @param recordKeyOrRecordName The
|
|
313
|
-
* @param userId The ID of the
|
|
314
|
-
* @param
|
|
315
|
-
* @param instances The instances that the request is being made from.
|
|
895
|
+
* Gets the list of permissions in the given record.
|
|
896
|
+
* @param recordKeyOrRecordName The name of the record.
|
|
897
|
+
* @param userId The ID of the currently logged in user.
|
|
898
|
+
* @param instances The instances that are loaded.
|
|
316
899
|
*/
|
|
317
|
-
|
|
900
|
+
listPermissions(recordKeyOrRecordName, userId, instances) {
|
|
318
901
|
return __awaiter(this, void 0, void 0, function* () {
|
|
319
902
|
try {
|
|
320
|
-
const
|
|
321
|
-
recordKeyOrRecordName
|
|
322
|
-
userId
|
|
323
|
-
};
|
|
324
|
-
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
903
|
+
const context = yield this.constructAuthorizationContext({
|
|
904
|
+
recordKeyOrRecordName,
|
|
905
|
+
userId,
|
|
906
|
+
});
|
|
325
907
|
if (context.success === false) {
|
|
326
|
-
return
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
908
|
+
return context;
|
|
909
|
+
}
|
|
910
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
911
|
+
userId,
|
|
912
|
+
instances,
|
|
913
|
+
resourceKind: 'marker',
|
|
914
|
+
action: 'list',
|
|
915
|
+
markers: [ACCOUNT_MARKER],
|
|
916
|
+
});
|
|
917
|
+
if (authorization.success === false) {
|
|
918
|
+
return authorization;
|
|
331
919
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const result = yield this._policies.getUserPolicy(context.context.recordName, marker);
|
|
920
|
+
const recordName = context.context.recordName;
|
|
921
|
+
const result = yield this._policies.listPermissionsInRecord(recordName);
|
|
335
922
|
if (result.success === false) {
|
|
336
923
|
return result;
|
|
337
924
|
}
|
|
338
|
-
const authorization = yield this.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'policy.read' }, baseRequest), { policy: marker, instances }));
|
|
339
|
-
if (authorization.allowed === false) {
|
|
340
|
-
return returnAuthorizationResult(authorization);
|
|
341
|
-
}
|
|
342
925
|
return {
|
|
343
926
|
success: true,
|
|
344
|
-
|
|
345
|
-
|
|
927
|
+
recordName,
|
|
928
|
+
resourcePermissions: result.resourceAssignments.map((r) => ({
|
|
929
|
+
id: r.id,
|
|
930
|
+
recordName: r.recordName,
|
|
931
|
+
subjectType: r.subjectType,
|
|
932
|
+
subjectId: r.subjectId,
|
|
933
|
+
resourceKind: r.resourceKind,
|
|
934
|
+
action: r.action,
|
|
935
|
+
resourceId: r.resourceId,
|
|
936
|
+
options: r.options,
|
|
937
|
+
expireTimeMs: r.expireTimeMs,
|
|
938
|
+
})),
|
|
939
|
+
markerPermissions: result.markerAssignments.map((r) => ({
|
|
940
|
+
id: r.id,
|
|
941
|
+
recordName: r.recordName,
|
|
942
|
+
subjectType: r.subjectType,
|
|
943
|
+
subjectId: r.subjectId,
|
|
944
|
+
resourceKind: r.resourceKind,
|
|
945
|
+
action: r.action,
|
|
946
|
+
marker: r.marker,
|
|
947
|
+
options: r.options,
|
|
948
|
+
expireTimeMs: r.expireTimeMs,
|
|
949
|
+
})),
|
|
346
950
|
};
|
|
347
951
|
}
|
|
348
952
|
catch (err) {
|
|
349
|
-
console.error('[PolicyController] A server error occurred.', err);
|
|
953
|
+
console.error('[PolicyController] A server error occurred while listing permissions.', err);
|
|
350
954
|
return {
|
|
351
955
|
success: false,
|
|
352
956
|
errorCode: 'server_error',
|
|
@@ -356,43 +960,53 @@ export class PolicyController {
|
|
|
356
960
|
});
|
|
357
961
|
}
|
|
358
962
|
/**
|
|
359
|
-
*
|
|
360
|
-
* @param recordKeyOrRecordName The
|
|
361
|
-
* @param
|
|
362
|
-
* @param
|
|
363
|
-
* @param instances The instances that
|
|
963
|
+
* Gets the list of permissions that have been assigned to the given marker.
|
|
964
|
+
* @param recordKeyOrRecordName The name of the record.
|
|
965
|
+
* @param marker The marker that the permissions should be listed for.
|
|
966
|
+
* @param userId The ID of the currently logged in user.
|
|
967
|
+
* @param instances The instances that are loaded.
|
|
364
968
|
*/
|
|
365
|
-
|
|
969
|
+
listPermissionsForMarker(recordKeyOrRecordName, marker, userId, instances) {
|
|
366
970
|
return __awaiter(this, void 0, void 0, function* () {
|
|
367
971
|
try {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
972
|
+
marker = getRootMarker(marker);
|
|
973
|
+
const context = yield this.constructAuthorizationContext({
|
|
974
|
+
recordKeyOrRecordName,
|
|
975
|
+
userId,
|
|
976
|
+
});
|
|
373
977
|
if (context.success === false) {
|
|
374
|
-
return
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (!result.success) {
|
|
386
|
-
return result;
|
|
978
|
+
return context;
|
|
979
|
+
}
|
|
980
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
981
|
+
userId,
|
|
982
|
+
instances,
|
|
983
|
+
resourceKind: 'marker',
|
|
984
|
+
action: 'list',
|
|
985
|
+
markers: [ACCOUNT_MARKER],
|
|
986
|
+
});
|
|
987
|
+
if (authorization.success === false) {
|
|
988
|
+
return authorization;
|
|
387
989
|
}
|
|
990
|
+
const recordName = context.context.recordName;
|
|
991
|
+
const result = yield this._policies.listPermissionsForMarker(recordName, marker);
|
|
388
992
|
return {
|
|
389
993
|
success: true,
|
|
390
|
-
|
|
391
|
-
|
|
994
|
+
recordName,
|
|
995
|
+
markerPermissions: result.map((r) => ({
|
|
996
|
+
id: r.id,
|
|
997
|
+
recordName: r.recordName,
|
|
998
|
+
subjectType: r.subjectType,
|
|
999
|
+
subjectId: r.subjectId,
|
|
1000
|
+
resourceKind: r.resourceKind,
|
|
1001
|
+
action: r.action,
|
|
1002
|
+
marker: r.marker,
|
|
1003
|
+
options: r.options,
|
|
1004
|
+
expireTimeMs: r.expireTimeMs,
|
|
1005
|
+
})),
|
|
392
1006
|
};
|
|
393
1007
|
}
|
|
394
1008
|
catch (err) {
|
|
395
|
-
console.error('[PolicyController] A server error occurred.', err);
|
|
1009
|
+
console.error('[PolicyController] A server error occurred while listing permissions for marker.', err);
|
|
396
1010
|
return {
|
|
397
1011
|
success: false,
|
|
398
1012
|
errorCode: 'server_error',
|
|
@@ -402,20 +1016,328 @@ export class PolicyController {
|
|
|
402
1016
|
});
|
|
403
1017
|
}
|
|
404
1018
|
/**
|
|
405
|
-
*
|
|
406
|
-
* @param recordKeyOrRecordName The
|
|
407
|
-
* @param
|
|
408
|
-
* @param
|
|
409
|
-
* @param
|
|
1019
|
+
* Gets the list of permissions that have been assigned to the given marker.
|
|
1020
|
+
* @param recordKeyOrRecordName The name of the record.
|
|
1021
|
+
* @param resourceKind The kind of the resource.
|
|
1022
|
+
* @param resourceId The ID of the resource.
|
|
1023
|
+
* @param userId The ID of the currently logged in user.
|
|
1024
|
+
* @param instances The instances that are loaded.
|
|
410
1025
|
*/
|
|
411
|
-
|
|
1026
|
+
listPermissionsForResource(recordKeyOrRecordName, resourceKind, resourceId, userId, instances) {
|
|
412
1027
|
return __awaiter(this, void 0, void 0, function* () {
|
|
413
1028
|
try {
|
|
414
|
-
const
|
|
415
|
-
recordKeyOrRecordName
|
|
416
|
-
userId
|
|
417
|
-
};
|
|
418
|
-
|
|
1029
|
+
const context = yield this.constructAuthorizationContext({
|
|
1030
|
+
recordKeyOrRecordName,
|
|
1031
|
+
userId,
|
|
1032
|
+
});
|
|
1033
|
+
if (context.success === false) {
|
|
1034
|
+
return context;
|
|
1035
|
+
}
|
|
1036
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1037
|
+
userId,
|
|
1038
|
+
instances,
|
|
1039
|
+
resourceKind: 'marker',
|
|
1040
|
+
action: 'list',
|
|
1041
|
+
markers: [ACCOUNT_MARKER],
|
|
1042
|
+
});
|
|
1043
|
+
if (authorization.success === false) {
|
|
1044
|
+
return authorization;
|
|
1045
|
+
}
|
|
1046
|
+
const recordName = context.context.recordName;
|
|
1047
|
+
const result = yield this._policies.listPermissionsForResource(recordName, resourceKind, resourceId);
|
|
1048
|
+
return {
|
|
1049
|
+
success: true,
|
|
1050
|
+
recordName,
|
|
1051
|
+
resourcePermissions: result.map((r) => ({
|
|
1052
|
+
id: r.id,
|
|
1053
|
+
recordName: r.recordName,
|
|
1054
|
+
subjectType: r.subjectType,
|
|
1055
|
+
subjectId: r.subjectId,
|
|
1056
|
+
resourceKind: r.resourceKind,
|
|
1057
|
+
action: r.action,
|
|
1058
|
+
resourceId: r.resourceId,
|
|
1059
|
+
options: r.options,
|
|
1060
|
+
expireTimeMs: r.expireTimeMs,
|
|
1061
|
+
})),
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
catch (err) {
|
|
1065
|
+
console.error('[PolicyController] A server error occurred while listing permissions for resource.', err);
|
|
1066
|
+
return {
|
|
1067
|
+
success: false,
|
|
1068
|
+
errorCode: 'server_error',
|
|
1069
|
+
errorMessage: 'A server error occurred.',
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
/**
|
|
1075
|
+
* Attempts to grant a permission to a marker.
|
|
1076
|
+
* @param request The request for the operation.
|
|
1077
|
+
*/
|
|
1078
|
+
grantMarkerPermission(request) {
|
|
1079
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1080
|
+
try {
|
|
1081
|
+
const baseRequest = {
|
|
1082
|
+
recordKeyOrRecordName: request.recordKeyOrRecordName,
|
|
1083
|
+
userId: request.userId,
|
|
1084
|
+
};
|
|
1085
|
+
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
1086
|
+
if (context.success === false) {
|
|
1087
|
+
return {
|
|
1088
|
+
success: false,
|
|
1089
|
+
errorCode: context.errorCode,
|
|
1090
|
+
errorMessage: context.errorMessage,
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
const marker = getRootMarker(request.marker);
|
|
1094
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1095
|
+
action: 'grantPermission',
|
|
1096
|
+
resourceKind: 'marker',
|
|
1097
|
+
resourceId: marker,
|
|
1098
|
+
markers: [ACCOUNT_MARKER],
|
|
1099
|
+
userId: request.userId,
|
|
1100
|
+
instances: request.instances,
|
|
1101
|
+
});
|
|
1102
|
+
if (authorization.success === false) {
|
|
1103
|
+
return authorization;
|
|
1104
|
+
}
|
|
1105
|
+
const recordName = context.context.recordName;
|
|
1106
|
+
const assignmentResult = yield this._policies.assignPermissionToSubjectAndMarker(recordName, request.permission.subjectType, request.permission.subjectId, request.permission.resourceKind, marker, request.permission.action, request.permission.options, request.permission.expireTimeMs);
|
|
1107
|
+
if (assignmentResult.success === false) {
|
|
1108
|
+
return assignmentResult;
|
|
1109
|
+
}
|
|
1110
|
+
return {
|
|
1111
|
+
success: true,
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
catch (err) {
|
|
1115
|
+
console.error('[PolicyController] A server error occurred while granting a marker permission.', err);
|
|
1116
|
+
return {
|
|
1117
|
+
success: false,
|
|
1118
|
+
errorCode: 'server_error',
|
|
1119
|
+
errorMessage: 'A server error occurred.',
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Attempts to revoke a permission from a marker.
|
|
1126
|
+
* @param request The request for the operation.
|
|
1127
|
+
*/
|
|
1128
|
+
revokeMarkerPermission(request) {
|
|
1129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1130
|
+
try {
|
|
1131
|
+
const permission = yield this._policies.getMarkerPermissionAssignmentById(request.permissionId);
|
|
1132
|
+
if (!permission) {
|
|
1133
|
+
return {
|
|
1134
|
+
success: false,
|
|
1135
|
+
errorCode: 'permission_not_found',
|
|
1136
|
+
errorMessage: 'The permission was not found.',
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
const baseRequest = {
|
|
1140
|
+
recordKeyOrRecordName: permission.recordName,
|
|
1141
|
+
userId: request.userId,
|
|
1142
|
+
};
|
|
1143
|
+
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
1144
|
+
if (context.success === false) {
|
|
1145
|
+
return {
|
|
1146
|
+
success: false,
|
|
1147
|
+
errorCode: context.errorCode,
|
|
1148
|
+
errorMessage: context.errorMessage,
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1152
|
+
action: 'revokePermission',
|
|
1153
|
+
resourceKind: 'marker',
|
|
1154
|
+
resourceId: permission.marker,
|
|
1155
|
+
markers: [ACCOUNT_MARKER],
|
|
1156
|
+
userId: request.userId,
|
|
1157
|
+
instances: request.instances,
|
|
1158
|
+
});
|
|
1159
|
+
if (authorization.success === false) {
|
|
1160
|
+
return authorization;
|
|
1161
|
+
}
|
|
1162
|
+
const deleteResult = yield this._policies.deleteMarkerPermissionAssignmentById(permission.id);
|
|
1163
|
+
if (!deleteResult.success) {
|
|
1164
|
+
return deleteResult;
|
|
1165
|
+
}
|
|
1166
|
+
return {
|
|
1167
|
+
success: true,
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
catch (err) {
|
|
1171
|
+
console.error('[PolicyController] A server error occurred while revoking a marker permission.', err);
|
|
1172
|
+
return {
|
|
1173
|
+
success: false,
|
|
1174
|
+
errorCode: 'server_error',
|
|
1175
|
+
errorMessage: 'A server error occurred.',
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
/**
|
|
1181
|
+
* Attempts to grant a permission to a resource.
|
|
1182
|
+
* @param request The request.
|
|
1183
|
+
*/
|
|
1184
|
+
grantResourcePermission(request) {
|
|
1185
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1186
|
+
try {
|
|
1187
|
+
const baseRequest = {
|
|
1188
|
+
recordKeyOrRecordName: request.recordKeyOrRecordName,
|
|
1189
|
+
userId: request.userId,
|
|
1190
|
+
};
|
|
1191
|
+
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
1192
|
+
if (context.success === false) {
|
|
1193
|
+
return {
|
|
1194
|
+
success: false,
|
|
1195
|
+
errorCode: context.errorCode,
|
|
1196
|
+
errorMessage: context.errorMessage,
|
|
1197
|
+
};
|
|
1198
|
+
}
|
|
1199
|
+
if (!request.permission.resourceId) {
|
|
1200
|
+
return {
|
|
1201
|
+
success: false,
|
|
1202
|
+
errorCode: 'unacceptable_request',
|
|
1203
|
+
errorMessage: 'You must provide a resourceId for the permission.',
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
else if (!request.permission.resourceKind) {
|
|
1207
|
+
return {
|
|
1208
|
+
success: false,
|
|
1209
|
+
errorCode: 'unacceptable_request',
|
|
1210
|
+
errorMessage: 'You must provide a resourceKind for the permission.',
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1214
|
+
action: 'grantPermission',
|
|
1215
|
+
// Resource permissions require access to the "account" marker
|
|
1216
|
+
// because there is currently no other marker that would make sense
|
|
1217
|
+
// for per-resource permissions.
|
|
1218
|
+
resourceKind: 'marker',
|
|
1219
|
+
resourceId: ACCOUNT_MARKER,
|
|
1220
|
+
markers: [ACCOUNT_MARKER],
|
|
1221
|
+
userId: request.userId,
|
|
1222
|
+
instances: request.instances,
|
|
1223
|
+
});
|
|
1224
|
+
if (authorization.success === false) {
|
|
1225
|
+
return authorization;
|
|
1226
|
+
}
|
|
1227
|
+
const recordName = context.context.recordName;
|
|
1228
|
+
const assignmentResult = yield this._policies.assignPermissionToSubjectAndResource(recordName, request.permission.subjectType, request.permission.subjectId, request.permission.resourceKind, request.permission.resourceId, request.permission.action, request.permission.options, request.permission.expireTimeMs);
|
|
1229
|
+
if (assignmentResult.success === false) {
|
|
1230
|
+
return assignmentResult;
|
|
1231
|
+
}
|
|
1232
|
+
return {
|
|
1233
|
+
success: true,
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
catch (err) {
|
|
1237
|
+
console.error('[PolicyController] A server error occurred while granting a resource permission.', err);
|
|
1238
|
+
return {
|
|
1239
|
+
success: false,
|
|
1240
|
+
errorCode: 'server_error',
|
|
1241
|
+
errorMessage: 'A server error occurred.',
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
/**
|
|
1247
|
+
* Attempts to revoke a permission from a resource.
|
|
1248
|
+
* @param request The request for the operation.
|
|
1249
|
+
*/
|
|
1250
|
+
revokeResourcePermission(request) {
|
|
1251
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1252
|
+
try {
|
|
1253
|
+
const permission = yield this._policies.getResourcePermissionAssignmentById(request.permissionId);
|
|
1254
|
+
if (!permission) {
|
|
1255
|
+
return {
|
|
1256
|
+
success: false,
|
|
1257
|
+
errorCode: 'permission_not_found',
|
|
1258
|
+
errorMessage: 'The permission was not found.',
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
const baseRequest = {
|
|
1262
|
+
recordKeyOrRecordName: permission.recordName,
|
|
1263
|
+
userId: request.userId,
|
|
1264
|
+
};
|
|
1265
|
+
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
1266
|
+
if (context.success === false) {
|
|
1267
|
+
return {
|
|
1268
|
+
success: false,
|
|
1269
|
+
errorCode: context.errorCode,
|
|
1270
|
+
errorMessage: context.errorMessage,
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1274
|
+
action: 'revokePermission',
|
|
1275
|
+
resourceKind: 'marker',
|
|
1276
|
+
resourceId: ACCOUNT_MARKER,
|
|
1277
|
+
markers: [ACCOUNT_MARKER],
|
|
1278
|
+
userId: request.userId,
|
|
1279
|
+
instances: request.instances,
|
|
1280
|
+
});
|
|
1281
|
+
if (authorization.success === false) {
|
|
1282
|
+
return authorization;
|
|
1283
|
+
}
|
|
1284
|
+
const deleteResult = yield this._policies.deleteResourcePermissionAssignmentById(permission.id);
|
|
1285
|
+
if (!deleteResult.success) {
|
|
1286
|
+
return deleteResult;
|
|
1287
|
+
}
|
|
1288
|
+
return {
|
|
1289
|
+
success: true,
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
catch (err) {
|
|
1293
|
+
console.error('[PolicyController] A server error occurred while revoking a resource permission.', err);
|
|
1294
|
+
return {
|
|
1295
|
+
success: false,
|
|
1296
|
+
errorCode: 'server_error',
|
|
1297
|
+
errorMessage: 'A server error occurred.',
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Attempts to revoke the permission with the given ID.
|
|
1304
|
+
* @param request The request for the operation.
|
|
1305
|
+
*/
|
|
1306
|
+
revokePermission(request) {
|
|
1307
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1308
|
+
try {
|
|
1309
|
+
const markerResult = yield this.revokeMarkerPermission(request);
|
|
1310
|
+
if (markerResult.success === false &&
|
|
1311
|
+
markerResult.errorCode === 'permission_not_found') {
|
|
1312
|
+
return yield this.revokeResourcePermission(request);
|
|
1313
|
+
}
|
|
1314
|
+
return markerResult;
|
|
1315
|
+
}
|
|
1316
|
+
catch (err) {
|
|
1317
|
+
console.error('[PolicyController] A server error occurred while revoking a permission.', err);
|
|
1318
|
+
return {
|
|
1319
|
+
success: false,
|
|
1320
|
+
errorCode: 'server_error',
|
|
1321
|
+
errorMessage: 'A server error occurred.',
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Attempts to list the roles that are assigned to a user.
|
|
1328
|
+
* @param recordKeyOrRecordName The record key or the name of the record.
|
|
1329
|
+
* @param userId The ID of the user that is currently logged in.
|
|
1330
|
+
* @param subjectId The ID of the user whose roles should be listed.
|
|
1331
|
+
* @param instances The instances that the request is being made from.
|
|
1332
|
+
*/
|
|
1333
|
+
listUserRoles(recordKeyOrRecordName, userId, subjectId, instances) {
|
|
1334
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1335
|
+
try {
|
|
1336
|
+
const baseRequest = {
|
|
1337
|
+
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1338
|
+
userId: userId,
|
|
1339
|
+
};
|
|
1340
|
+
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
419
1341
|
if (context.success === false) {
|
|
420
1342
|
return {
|
|
421
1343
|
success: false,
|
|
@@ -424,9 +1346,15 @@ export class PolicyController {
|
|
|
424
1346
|
};
|
|
425
1347
|
}
|
|
426
1348
|
if (userId !== subjectId || (!!instances && instances.length > 0)) {
|
|
427
|
-
const authorization = yield this.
|
|
428
|
-
|
|
429
|
-
|
|
1349
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1350
|
+
resourceKind: 'role',
|
|
1351
|
+
action: 'list',
|
|
1352
|
+
markers: [ACCOUNT_MARKER],
|
|
1353
|
+
userId: userId,
|
|
1354
|
+
instances: instances,
|
|
1355
|
+
});
|
|
1356
|
+
if (authorization.success === false) {
|
|
1357
|
+
return authorization;
|
|
430
1358
|
}
|
|
431
1359
|
}
|
|
432
1360
|
const result = yield this._policies.listRolesForUser(context.context.recordName, subjectId);
|
|
@@ -467,11 +1395,17 @@ export class PolicyController {
|
|
|
467
1395
|
errorMessage: context.errorMessage,
|
|
468
1396
|
};
|
|
469
1397
|
}
|
|
470
|
-
const authorization = yield this.
|
|
471
|
-
|
|
472
|
-
|
|
1398
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1399
|
+
resourceKind: 'role',
|
|
1400
|
+
action: 'list',
|
|
1401
|
+
markers: [ACCOUNT_MARKER],
|
|
1402
|
+
userId: userId,
|
|
1403
|
+
instances: instances,
|
|
1404
|
+
});
|
|
1405
|
+
if (authorization.success === false) {
|
|
1406
|
+
return authorization;
|
|
473
1407
|
}
|
|
474
|
-
const result = yield this._policies.listRolesForInst(context.context.recordName, subjectId);
|
|
1408
|
+
const result = yield this._policies.listRolesForInst(context.context.recordName, normalizeInstId(subjectId));
|
|
475
1409
|
return {
|
|
476
1410
|
success: true,
|
|
477
1411
|
roles: sortBy(result, (r) => r.role),
|
|
@@ -509,9 +1443,15 @@ export class PolicyController {
|
|
|
509
1443
|
errorMessage: context.errorMessage,
|
|
510
1444
|
};
|
|
511
1445
|
}
|
|
512
|
-
const authorization = yield this.
|
|
513
|
-
|
|
514
|
-
|
|
1446
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1447
|
+
resourceKind: 'role',
|
|
1448
|
+
action: 'list',
|
|
1449
|
+
markers: [ACCOUNT_MARKER],
|
|
1450
|
+
userId: userId,
|
|
1451
|
+
instances: instances,
|
|
1452
|
+
});
|
|
1453
|
+
if (authorization.success === false) {
|
|
1454
|
+
return authorization;
|
|
515
1455
|
}
|
|
516
1456
|
const result = yield this._policies.listAssignmentsForRole(context.context.recordName, role);
|
|
517
1457
|
return {
|
|
@@ -558,9 +1498,15 @@ export class PolicyController {
|
|
|
558
1498
|
errorMessage: context.errorMessage,
|
|
559
1499
|
};
|
|
560
1500
|
}
|
|
561
|
-
const authorization = yield this.
|
|
562
|
-
|
|
563
|
-
|
|
1501
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1502
|
+
resourceKind: 'role',
|
|
1503
|
+
action: 'list',
|
|
1504
|
+
markers: [ACCOUNT_MARKER],
|
|
1505
|
+
userId: userId,
|
|
1506
|
+
instances: instances,
|
|
1507
|
+
});
|
|
1508
|
+
if (authorization.success === false) {
|
|
1509
|
+
return authorization;
|
|
564
1510
|
}
|
|
565
1511
|
const result = yield this._policies.listAssignments(context.context.recordName, startingRole);
|
|
566
1512
|
return {
|
|
@@ -603,13 +1549,18 @@ export class PolicyController {
|
|
|
603
1549
|
}
|
|
604
1550
|
const recordName = context.context.recordName;
|
|
605
1551
|
const targetUserId = request.userId;
|
|
606
|
-
const targetInstance = request.instance;
|
|
1552
|
+
const targetInstance = normalizeInstId(request.instance);
|
|
607
1553
|
const expireTimeMs = getExpireTime(request.expireTimeMs);
|
|
608
|
-
const authorization = yield this.
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
1554
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1555
|
+
resourceKind: 'role',
|
|
1556
|
+
action: 'grant',
|
|
1557
|
+
resourceId: request.role,
|
|
1558
|
+
markers: [ACCOUNT_MARKER],
|
|
1559
|
+
userId: userId,
|
|
1560
|
+
instances: instances,
|
|
1561
|
+
});
|
|
1562
|
+
if (authorization.success === false) {
|
|
1563
|
+
return authorization;
|
|
613
1564
|
}
|
|
614
1565
|
if (targetUserId) {
|
|
615
1566
|
const result = yield this._policies.assignSubjectRole(recordName, targetUserId, 'user', {
|
|
@@ -675,11 +1626,17 @@ export class PolicyController {
|
|
|
675
1626
|
}
|
|
676
1627
|
const recordName = context.context.recordName;
|
|
677
1628
|
const targetUserId = request.userId;
|
|
678
|
-
const targetInstance = request.instance;
|
|
679
|
-
const authorization = yield this.
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
1629
|
+
const targetInstance = normalizeInstId(request.instance);
|
|
1630
|
+
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1631
|
+
resourceKind: 'role',
|
|
1632
|
+
action: 'revoke',
|
|
1633
|
+
resourceId: request.role,
|
|
1634
|
+
markers: [ACCOUNT_MARKER],
|
|
1635
|
+
userId: userId,
|
|
1636
|
+
instances: instances,
|
|
1637
|
+
});
|
|
1638
|
+
if (authorization.success === false) {
|
|
1639
|
+
return authorization;
|
|
683
1640
|
}
|
|
684
1641
|
if (targetUserId) {
|
|
685
1642
|
const result = yield this._policies.revokeSubjectRole(recordName, targetUserId, 'user', request.role);
|
|
@@ -715,2642 +1672,6 @@ export class PolicyController {
|
|
|
715
1672
|
}
|
|
716
1673
|
});
|
|
717
1674
|
}
|
|
718
|
-
/**
|
|
719
|
-
* Attempts to authorize the given request.
|
|
720
|
-
* Returns a promise that resolves with information about the security properties of the request.
|
|
721
|
-
* @param context The authorization context for the request.
|
|
722
|
-
* @param request The request.
|
|
723
|
-
*/
|
|
724
|
-
_authorizeRequestUsingContext(context, request) {
|
|
725
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
726
|
-
if (request.action === 'data.create') {
|
|
727
|
-
return this._authorizeDataCreateRequest(context, request);
|
|
728
|
-
}
|
|
729
|
-
else if (request.action === 'data.read') {
|
|
730
|
-
return this._authorizeDataReadRequest(context, request);
|
|
731
|
-
}
|
|
732
|
-
else if (request.action === 'data.update') {
|
|
733
|
-
return this._authorizeDataUpdateRequest(context, request);
|
|
734
|
-
}
|
|
735
|
-
else if (request.action === 'data.delete') {
|
|
736
|
-
return this._authorizeDataDeleteRequest(context, request);
|
|
737
|
-
}
|
|
738
|
-
else if (request.action === 'data.list') {
|
|
739
|
-
return this._authorizeDataListRequest(context, request);
|
|
740
|
-
}
|
|
741
|
-
else if (request.action === 'file.create') {
|
|
742
|
-
return this._authorizeFileCreateRequest(context, request);
|
|
743
|
-
}
|
|
744
|
-
else if (request.action === 'file.read') {
|
|
745
|
-
return this._authorizeFileReadRequest(context, request);
|
|
746
|
-
}
|
|
747
|
-
else if (request.action === 'file.list') {
|
|
748
|
-
return this._authorizeFileListRequest(context, request);
|
|
749
|
-
}
|
|
750
|
-
else if (request.action === 'file.update') {
|
|
751
|
-
return this._authorizeFileUpdateRequest(context, request);
|
|
752
|
-
}
|
|
753
|
-
else if (request.action === 'file.delete') {
|
|
754
|
-
return this._authorizeFileDeleteRequest(context, request);
|
|
755
|
-
}
|
|
756
|
-
else if (request.action === 'event.count') {
|
|
757
|
-
return this._authorizeEventCountRequest(context, request);
|
|
758
|
-
}
|
|
759
|
-
else if (request.action === 'event.increment') {
|
|
760
|
-
return this._authorizeEventIncrementRequest(context, request);
|
|
761
|
-
}
|
|
762
|
-
else if (request.action === 'event.update') {
|
|
763
|
-
return this._authorizeEventUpdateRequest(context, request);
|
|
764
|
-
}
|
|
765
|
-
else if (request.action === 'event.list') {
|
|
766
|
-
return this._authorizeEventListRequest(context, request);
|
|
767
|
-
}
|
|
768
|
-
else if (request.action === 'policy.grantPermission') {
|
|
769
|
-
return this._authorizePolicyGrantPermissionRequest(context, request);
|
|
770
|
-
}
|
|
771
|
-
else if (request.action === 'policy.revokePermission') {
|
|
772
|
-
return this._authorizePolicyRevokePermissionRequest(context, request);
|
|
773
|
-
}
|
|
774
|
-
else if (request.action === 'policy.read') {
|
|
775
|
-
return this._authorizePolicyReadRequest(context, request);
|
|
776
|
-
}
|
|
777
|
-
else if (request.action === 'policy.list') {
|
|
778
|
-
return this._authorizePolicyListRequest(context, request);
|
|
779
|
-
}
|
|
780
|
-
else if (request.action === 'role.list') {
|
|
781
|
-
return this._authorizeRoleListRequest(context, request);
|
|
782
|
-
}
|
|
783
|
-
else if (request.action === 'role.read') {
|
|
784
|
-
return this._authorizeRoleReadRequest(context, request);
|
|
785
|
-
}
|
|
786
|
-
else if (request.action === 'role.grant') {
|
|
787
|
-
return this._authorizeRoleGrantRequest(context, request);
|
|
788
|
-
}
|
|
789
|
-
else if (request.action === 'role.revoke') {
|
|
790
|
-
return this._authorizeRoleRevokeRequest(context, request);
|
|
791
|
-
}
|
|
792
|
-
else if (request.action === 'inst.create') {
|
|
793
|
-
return this._authorizeInstCreateRequest(context, request);
|
|
794
|
-
}
|
|
795
|
-
else if (request.action === 'inst.read') {
|
|
796
|
-
return this._authorizeInstReadRequest(context, request);
|
|
797
|
-
}
|
|
798
|
-
else if (request.action === 'inst.update') {
|
|
799
|
-
return this._authorizeInstUpdateRequest(context, request);
|
|
800
|
-
}
|
|
801
|
-
else if (request.action === 'inst.updateData') {
|
|
802
|
-
return this._authorizeInstUpdateDataRequest(context, request);
|
|
803
|
-
}
|
|
804
|
-
else if (request.action === 'inst.delete') {
|
|
805
|
-
return this._authorizeInstDeleteRequest(context, request);
|
|
806
|
-
}
|
|
807
|
-
else if (request.action === 'inst.list') {
|
|
808
|
-
return this._authorizeInstListRequest(context, request);
|
|
809
|
-
}
|
|
810
|
-
else if (request.action === 'inst.sendAction') {
|
|
811
|
-
return this._authorizeInstSendActionRequest(context, request);
|
|
812
|
-
}
|
|
813
|
-
return {
|
|
814
|
-
allowed: false,
|
|
815
|
-
errorCode: 'action_not_supported',
|
|
816
|
-
errorMessage: 'The given action is not supported.',
|
|
817
|
-
};
|
|
818
|
-
});
|
|
819
|
-
}
|
|
820
|
-
_authorizeDataCreateRequest(context, request) {
|
|
821
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
822
|
-
return this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
823
|
-
return this._authorizeCreateData(context, type, id);
|
|
824
|
-
});
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
/**
|
|
828
|
-
* Authorizes the given subject for data.create requests.
|
|
829
|
-
*
|
|
830
|
-
* @param context The context for the authorization.
|
|
831
|
-
* @param subjectType The type of subject that is being authorized.
|
|
832
|
-
* @param id The ID of the subject.
|
|
833
|
-
* @returns The authorization that approves the subject for the request. Null if the subject is not authorized.
|
|
834
|
-
*/
|
|
835
|
-
_authorizeCreateData(context, subjectType, id) {
|
|
836
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
837
|
-
const authorizations = [];
|
|
838
|
-
let role = null;
|
|
839
|
-
for (let marker of context.markers) {
|
|
840
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byData('data.create', context.request.address), role === null
|
|
841
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, subjectType, id), this._bySubjectRole(context, subjectType, context.recordName, id))
|
|
842
|
-
: this._byRole(role)));
|
|
843
|
-
if (!actionPermission) {
|
|
844
|
-
return {
|
|
845
|
-
success: false,
|
|
846
|
-
reason: {
|
|
847
|
-
type: 'missing_permission',
|
|
848
|
-
kind: subjectType,
|
|
849
|
-
id,
|
|
850
|
-
marker: marker.marker,
|
|
851
|
-
permission: 'data.create',
|
|
852
|
-
role,
|
|
853
|
-
},
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
if (role === null) {
|
|
857
|
-
role = actionPermission.permission.role;
|
|
858
|
-
}
|
|
859
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.assign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
860
|
-
if (!policyPermission) {
|
|
861
|
-
return {
|
|
862
|
-
success: false,
|
|
863
|
-
reason: {
|
|
864
|
-
type: 'missing_permission',
|
|
865
|
-
kind: subjectType,
|
|
866
|
-
id,
|
|
867
|
-
marker: marker.marker,
|
|
868
|
-
permission: 'policy.assign',
|
|
869
|
-
role,
|
|
870
|
-
},
|
|
871
|
-
};
|
|
872
|
-
}
|
|
873
|
-
authorizations.push({
|
|
874
|
-
marker: marker.marker,
|
|
875
|
-
actions: [
|
|
876
|
-
{
|
|
877
|
-
action: context.request.action,
|
|
878
|
-
grantingPolicy: actionPermission.policy,
|
|
879
|
-
grantingPermission: actionPermission.permission,
|
|
880
|
-
},
|
|
881
|
-
{
|
|
882
|
-
action: 'policy.assign',
|
|
883
|
-
grantingPolicy: policyPermission.policy,
|
|
884
|
-
grantingPermission: policyPermission.permission,
|
|
885
|
-
},
|
|
886
|
-
],
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
if (!role) {
|
|
890
|
-
return {
|
|
891
|
-
success: false,
|
|
892
|
-
reason: {
|
|
893
|
-
type: 'missing_role',
|
|
894
|
-
},
|
|
895
|
-
};
|
|
896
|
-
}
|
|
897
|
-
return {
|
|
898
|
-
success: true,
|
|
899
|
-
authorization: {
|
|
900
|
-
role,
|
|
901
|
-
markers: authorizations,
|
|
902
|
-
},
|
|
903
|
-
};
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
_authorizeDataReadRequest(context, request) {
|
|
907
|
-
return this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
908
|
-
return this._authorizeDataRead(context, type, id);
|
|
909
|
-
});
|
|
910
|
-
}
|
|
911
|
-
_authorizeDataRead(context, type, id) {
|
|
912
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
913
|
-
let role = null;
|
|
914
|
-
let denialReason;
|
|
915
|
-
for (let marker of context.markers) {
|
|
916
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byData('data.read', context.request.address), role === null
|
|
917
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
918
|
-
: this._byRole(role)));
|
|
919
|
-
if (!actionPermission) {
|
|
920
|
-
denialReason = {
|
|
921
|
-
type: 'missing_permission',
|
|
922
|
-
kind: type,
|
|
923
|
-
id,
|
|
924
|
-
marker: marker.marker,
|
|
925
|
-
permission: 'data.read',
|
|
926
|
-
role,
|
|
927
|
-
};
|
|
928
|
-
continue;
|
|
929
|
-
}
|
|
930
|
-
if (role === null) {
|
|
931
|
-
role = actionPermission.permission.role;
|
|
932
|
-
}
|
|
933
|
-
return {
|
|
934
|
-
success: true,
|
|
935
|
-
authorization: {
|
|
936
|
-
role,
|
|
937
|
-
markers: [
|
|
938
|
-
{
|
|
939
|
-
marker: marker.marker,
|
|
940
|
-
actions: [
|
|
941
|
-
{
|
|
942
|
-
action: context.request.action,
|
|
943
|
-
grantingPolicy: actionPermission.policy,
|
|
944
|
-
grantingPermission: actionPermission.permission,
|
|
945
|
-
},
|
|
946
|
-
],
|
|
947
|
-
},
|
|
948
|
-
],
|
|
949
|
-
},
|
|
950
|
-
};
|
|
951
|
-
}
|
|
952
|
-
return {
|
|
953
|
-
success: false,
|
|
954
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
955
|
-
type: 'missing_role',
|
|
956
|
-
},
|
|
957
|
-
};
|
|
958
|
-
});
|
|
959
|
-
}
|
|
960
|
-
_authorizeDataUpdateRequest(context, request) {
|
|
961
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
962
|
-
if (!willMarkersBeRemaining(request.existingMarkers, request.removedMarkers, request.addedMarkers)) {
|
|
963
|
-
return Object.assign(Object.assign({}, NOT_AUTHORIZED_RESULT), { reason: {
|
|
964
|
-
type: 'no_markers_remaining',
|
|
965
|
-
} });
|
|
966
|
-
}
|
|
967
|
-
return this._authorizeRequest(context, request, union(request.existingMarkers, request.addedMarkers, request.removedMarkers), (context, type, id) => {
|
|
968
|
-
return this._authorizeDataUpdate(context, type, id);
|
|
969
|
-
});
|
|
970
|
-
});
|
|
971
|
-
}
|
|
972
|
-
_authorizeDataUpdate(context, type, id) {
|
|
973
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
974
|
-
let authorizations = [];
|
|
975
|
-
let role = null;
|
|
976
|
-
// The denial reason for if the user does not have permission from an existing marker.
|
|
977
|
-
let denialReason;
|
|
978
|
-
let hasPermissionFromExistingMarker = false;
|
|
979
|
-
for (let marker of context.markers) {
|
|
980
|
-
const isAddedMarker = context.request.addedMarkers &&
|
|
981
|
-
context.request.addedMarkers.includes(marker.marker);
|
|
982
|
-
const isRemovedMarker = context.request.removedMarkers &&
|
|
983
|
-
context.request.removedMarkers.includes(marker.marker);
|
|
984
|
-
const isExistingMarker = context.request.existingMarkers.includes(marker.marker);
|
|
985
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byData('data.update', context.request.address), role === null
|
|
986
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
987
|
-
: this._byRole(role)));
|
|
988
|
-
if (!actionPermission) {
|
|
989
|
-
if (isAddedMarker || isRemovedMarker) {
|
|
990
|
-
// Deny because the user needs permission for all new & removed markers.
|
|
991
|
-
return {
|
|
992
|
-
success: false,
|
|
993
|
-
reason: {
|
|
994
|
-
type: 'missing_permission',
|
|
995
|
-
kind: type,
|
|
996
|
-
id,
|
|
997
|
-
marker: marker.marker,
|
|
998
|
-
permission: 'data.update',
|
|
999
|
-
role,
|
|
1000
|
-
},
|
|
1001
|
-
};
|
|
1002
|
-
}
|
|
1003
|
-
else {
|
|
1004
|
-
// Record that the user does not have permission from this marker.
|
|
1005
|
-
// May or may not be used depending on if a different existing marker
|
|
1006
|
-
// provides permission.
|
|
1007
|
-
denialReason = {
|
|
1008
|
-
type: 'missing_permission',
|
|
1009
|
-
kind: type,
|
|
1010
|
-
id,
|
|
1011
|
-
marker: marker.marker,
|
|
1012
|
-
permission: 'data.update',
|
|
1013
|
-
role,
|
|
1014
|
-
};
|
|
1015
|
-
continue;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
if (isExistingMarker) {
|
|
1019
|
-
hasPermissionFromExistingMarker = true;
|
|
1020
|
-
}
|
|
1021
|
-
if (role === null) {
|
|
1022
|
-
role = actionPermission.permission.role;
|
|
1023
|
-
}
|
|
1024
|
-
const actions = [
|
|
1025
|
-
{
|
|
1026
|
-
action: context.request.action,
|
|
1027
|
-
grantingPolicy: actionPermission.policy,
|
|
1028
|
-
grantingPermission: actionPermission.permission,
|
|
1029
|
-
},
|
|
1030
|
-
];
|
|
1031
|
-
if (isAddedMarker) {
|
|
1032
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.assign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
1033
|
-
if (!policyPermission) {
|
|
1034
|
-
return {
|
|
1035
|
-
success: false,
|
|
1036
|
-
reason: {
|
|
1037
|
-
type: 'missing_permission',
|
|
1038
|
-
kind: type,
|
|
1039
|
-
id,
|
|
1040
|
-
marker: marker.marker,
|
|
1041
|
-
permission: 'policy.assign',
|
|
1042
|
-
role,
|
|
1043
|
-
},
|
|
1044
|
-
};
|
|
1045
|
-
continue;
|
|
1046
|
-
}
|
|
1047
|
-
actions.push({
|
|
1048
|
-
action: 'policy.assign',
|
|
1049
|
-
grantingPolicy: policyPermission.policy,
|
|
1050
|
-
grantingPermission: policyPermission.permission,
|
|
1051
|
-
});
|
|
1052
|
-
}
|
|
1053
|
-
else if (isRemovedMarker) {
|
|
1054
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.unassign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
1055
|
-
if (!policyPermission) {
|
|
1056
|
-
return {
|
|
1057
|
-
success: false,
|
|
1058
|
-
reason: {
|
|
1059
|
-
type: 'missing_permission',
|
|
1060
|
-
kind: type,
|
|
1061
|
-
id,
|
|
1062
|
-
marker: marker.marker,
|
|
1063
|
-
permission: 'policy.unassign',
|
|
1064
|
-
role,
|
|
1065
|
-
},
|
|
1066
|
-
};
|
|
1067
|
-
}
|
|
1068
|
-
actions.push({
|
|
1069
|
-
action: 'policy.unassign',
|
|
1070
|
-
grantingPolicy: policyPermission.policy,
|
|
1071
|
-
grantingPermission: policyPermission.permission,
|
|
1072
|
-
});
|
|
1073
|
-
}
|
|
1074
|
-
authorizations.push({
|
|
1075
|
-
marker: marker.marker,
|
|
1076
|
-
actions,
|
|
1077
|
-
});
|
|
1078
|
-
}
|
|
1079
|
-
// Deny the request if the user does not have permission from at least one existing marker.
|
|
1080
|
-
if (!hasPermissionFromExistingMarker && denialReason) {
|
|
1081
|
-
return {
|
|
1082
|
-
success: false,
|
|
1083
|
-
reason: denialReason,
|
|
1084
|
-
};
|
|
1085
|
-
}
|
|
1086
|
-
if (!role) {
|
|
1087
|
-
return {
|
|
1088
|
-
success: false,
|
|
1089
|
-
reason: {
|
|
1090
|
-
type: 'missing_role',
|
|
1091
|
-
},
|
|
1092
|
-
};
|
|
1093
|
-
}
|
|
1094
|
-
return {
|
|
1095
|
-
success: true,
|
|
1096
|
-
authorization: {
|
|
1097
|
-
role,
|
|
1098
|
-
markers: authorizations,
|
|
1099
|
-
},
|
|
1100
|
-
};
|
|
1101
|
-
});
|
|
1102
|
-
}
|
|
1103
|
-
_authorizeDataDeleteRequest(context, request) {
|
|
1104
|
-
return this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
1105
|
-
return this._authorizeDataDelete(context, type, id);
|
|
1106
|
-
});
|
|
1107
|
-
}
|
|
1108
|
-
_authorizeDataDelete(context, type, id) {
|
|
1109
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1110
|
-
let role = null;
|
|
1111
|
-
let denialReason;
|
|
1112
|
-
for (let marker of context.markers) {
|
|
1113
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byData('data.delete', context.request.address), role === null
|
|
1114
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1115
|
-
: this._byRole(role)));
|
|
1116
|
-
if (!actionPermission) {
|
|
1117
|
-
denialReason = {
|
|
1118
|
-
type: 'missing_permission',
|
|
1119
|
-
kind: type,
|
|
1120
|
-
id,
|
|
1121
|
-
marker: marker.marker,
|
|
1122
|
-
permission: 'data.delete',
|
|
1123
|
-
role,
|
|
1124
|
-
};
|
|
1125
|
-
continue;
|
|
1126
|
-
}
|
|
1127
|
-
if (role === null) {
|
|
1128
|
-
role = actionPermission.permission.role;
|
|
1129
|
-
}
|
|
1130
|
-
return {
|
|
1131
|
-
success: true,
|
|
1132
|
-
authorization: {
|
|
1133
|
-
role,
|
|
1134
|
-
markers: [
|
|
1135
|
-
{
|
|
1136
|
-
marker: marker.marker,
|
|
1137
|
-
actions: [
|
|
1138
|
-
{
|
|
1139
|
-
action: context.request.action,
|
|
1140
|
-
grantingPolicy: actionPermission.policy,
|
|
1141
|
-
grantingPermission: actionPermission.permission,
|
|
1142
|
-
},
|
|
1143
|
-
],
|
|
1144
|
-
},
|
|
1145
|
-
],
|
|
1146
|
-
},
|
|
1147
|
-
};
|
|
1148
|
-
}
|
|
1149
|
-
return {
|
|
1150
|
-
success: false,
|
|
1151
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
1152
|
-
type: 'missing_role',
|
|
1153
|
-
},
|
|
1154
|
-
};
|
|
1155
|
-
});
|
|
1156
|
-
}
|
|
1157
|
-
_authorizeDataListRequest(context, request) {
|
|
1158
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1159
|
-
const allMarkers = union(...request.dataItems.map((i) => i.markers));
|
|
1160
|
-
return yield this._authorizeRequest(context, request, allMarkers, (context, type, id) => {
|
|
1161
|
-
return this._authorizeDataList(context, type, id);
|
|
1162
|
-
}, undefined, true);
|
|
1163
|
-
});
|
|
1164
|
-
}
|
|
1165
|
-
_authorizeDataList(context, type, id) {
|
|
1166
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1167
|
-
const authorizations = [];
|
|
1168
|
-
let role = null;
|
|
1169
|
-
const allowedDataItems = (context.allowedDataItems =
|
|
1170
|
-
[]);
|
|
1171
|
-
const markers = new Map();
|
|
1172
|
-
for (let marker of context.markers) {
|
|
1173
|
-
const authorization = {
|
|
1174
|
-
marker: marker.marker,
|
|
1175
|
-
actions: [],
|
|
1176
|
-
};
|
|
1177
|
-
authorizations.push(authorization);
|
|
1178
|
-
markers.set(marker.marker, {
|
|
1179
|
-
marker,
|
|
1180
|
-
authorization: authorization,
|
|
1181
|
-
usedPermissions: new Set(),
|
|
1182
|
-
});
|
|
1183
|
-
}
|
|
1184
|
-
for (let item of context.request.dataItems) {
|
|
1185
|
-
let itemPermission;
|
|
1186
|
-
for (let m of item.markers) {
|
|
1187
|
-
const a = markers.get(m);
|
|
1188
|
-
if (!a) {
|
|
1189
|
-
continue;
|
|
1190
|
-
}
|
|
1191
|
-
const { marker, authorization, usedPermissions } = a;
|
|
1192
|
-
itemPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byData('data.list', item.address), role === null
|
|
1193
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1194
|
-
: this._byRole(role)));
|
|
1195
|
-
if (!itemPermission) {
|
|
1196
|
-
continue;
|
|
1197
|
-
}
|
|
1198
|
-
if (role === null) {
|
|
1199
|
-
role = itemPermission.permission.role;
|
|
1200
|
-
}
|
|
1201
|
-
if (!usedPermissions.has(itemPermission.permission)) {
|
|
1202
|
-
usedPermissions.add(itemPermission.permission);
|
|
1203
|
-
authorization.actions.push({
|
|
1204
|
-
action: context.request.action,
|
|
1205
|
-
grantingPolicy: itemPermission.policy,
|
|
1206
|
-
grantingPermission: itemPermission.permission,
|
|
1207
|
-
});
|
|
1208
|
-
}
|
|
1209
|
-
if (itemPermission) {
|
|
1210
|
-
break;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
if (itemPermission) {
|
|
1214
|
-
allowedDataItems.push(item);
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
if (!role) {
|
|
1218
|
-
role = true;
|
|
1219
|
-
}
|
|
1220
|
-
return {
|
|
1221
|
-
success: true,
|
|
1222
|
-
authorization: {
|
|
1223
|
-
role,
|
|
1224
|
-
markers: authorizations,
|
|
1225
|
-
},
|
|
1226
|
-
};
|
|
1227
|
-
});
|
|
1228
|
-
}
|
|
1229
|
-
_authorizeFileCreateRequest(context, request) {
|
|
1230
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1231
|
-
return yield this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
1232
|
-
return this._authorizeFileCreate(context, type, id);
|
|
1233
|
-
});
|
|
1234
|
-
});
|
|
1235
|
-
}
|
|
1236
|
-
_authorizeFileCreate(context, subjectType, id) {
|
|
1237
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1238
|
-
const authorizations = [];
|
|
1239
|
-
let role = null;
|
|
1240
|
-
for (let marker of context.markers) {
|
|
1241
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byFile('file.create', context.request.fileSizeInBytes, context.request.fileMimeType), role === null
|
|
1242
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, subjectType, id), this._bySubjectRole(context, subjectType, context.recordName, id))
|
|
1243
|
-
: this._byRole(role)));
|
|
1244
|
-
if (!actionPermission) {
|
|
1245
|
-
return {
|
|
1246
|
-
success: false,
|
|
1247
|
-
reason: {
|
|
1248
|
-
type: 'missing_permission',
|
|
1249
|
-
kind: subjectType,
|
|
1250
|
-
id,
|
|
1251
|
-
marker: marker.marker,
|
|
1252
|
-
permission: 'file.create',
|
|
1253
|
-
role,
|
|
1254
|
-
},
|
|
1255
|
-
};
|
|
1256
|
-
}
|
|
1257
|
-
if (role === null) {
|
|
1258
|
-
role = actionPermission.permission.role;
|
|
1259
|
-
}
|
|
1260
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.assign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
1261
|
-
if (!policyPermission) {
|
|
1262
|
-
return {
|
|
1263
|
-
success: false,
|
|
1264
|
-
reason: {
|
|
1265
|
-
type: 'missing_permission',
|
|
1266
|
-
kind: subjectType,
|
|
1267
|
-
id,
|
|
1268
|
-
marker: marker.marker,
|
|
1269
|
-
permission: 'policy.assign',
|
|
1270
|
-
role,
|
|
1271
|
-
},
|
|
1272
|
-
};
|
|
1273
|
-
}
|
|
1274
|
-
authorizations.push({
|
|
1275
|
-
marker: marker.marker,
|
|
1276
|
-
actions: [
|
|
1277
|
-
{
|
|
1278
|
-
action: context.request.action,
|
|
1279
|
-
grantingPolicy: actionPermission.policy,
|
|
1280
|
-
grantingPermission: actionPermission.permission,
|
|
1281
|
-
},
|
|
1282
|
-
{
|
|
1283
|
-
action: 'policy.assign',
|
|
1284
|
-
grantingPolicy: policyPermission.policy,
|
|
1285
|
-
grantingPermission: policyPermission.permission,
|
|
1286
|
-
},
|
|
1287
|
-
],
|
|
1288
|
-
});
|
|
1289
|
-
}
|
|
1290
|
-
if (!role) {
|
|
1291
|
-
return {
|
|
1292
|
-
success: false,
|
|
1293
|
-
reason: {
|
|
1294
|
-
type: 'missing_role',
|
|
1295
|
-
},
|
|
1296
|
-
};
|
|
1297
|
-
}
|
|
1298
|
-
return {
|
|
1299
|
-
success: true,
|
|
1300
|
-
authorization: {
|
|
1301
|
-
role,
|
|
1302
|
-
markers: authorizations,
|
|
1303
|
-
},
|
|
1304
|
-
};
|
|
1305
|
-
});
|
|
1306
|
-
}
|
|
1307
|
-
_authorizeFileReadRequest(context, request) {
|
|
1308
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1309
|
-
return yield this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
1310
|
-
return this._authorizeFileRead(context, type, id);
|
|
1311
|
-
});
|
|
1312
|
-
});
|
|
1313
|
-
}
|
|
1314
|
-
_authorizeFileRead(context, type, id) {
|
|
1315
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1316
|
-
let role = null;
|
|
1317
|
-
let denialReason;
|
|
1318
|
-
for (let marker of context.markers) {
|
|
1319
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byFile('file.read', context.request.fileSizeInBytes, context.request.fileMimeType), role === null
|
|
1320
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1321
|
-
: this._byRole(role)));
|
|
1322
|
-
if (!actionPermission) {
|
|
1323
|
-
denialReason = {
|
|
1324
|
-
type: 'missing_permission',
|
|
1325
|
-
kind: type,
|
|
1326
|
-
id,
|
|
1327
|
-
marker: marker.marker,
|
|
1328
|
-
permission: 'file.read',
|
|
1329
|
-
role,
|
|
1330
|
-
};
|
|
1331
|
-
continue;
|
|
1332
|
-
}
|
|
1333
|
-
if (role === null) {
|
|
1334
|
-
role = actionPermission.permission.role;
|
|
1335
|
-
}
|
|
1336
|
-
return {
|
|
1337
|
-
success: true,
|
|
1338
|
-
authorization: {
|
|
1339
|
-
role,
|
|
1340
|
-
markers: [
|
|
1341
|
-
{
|
|
1342
|
-
marker: marker.marker,
|
|
1343
|
-
actions: [
|
|
1344
|
-
{
|
|
1345
|
-
action: context.request.action,
|
|
1346
|
-
grantingPolicy: actionPermission.policy,
|
|
1347
|
-
grantingPermission: actionPermission.permission,
|
|
1348
|
-
},
|
|
1349
|
-
],
|
|
1350
|
-
},
|
|
1351
|
-
],
|
|
1352
|
-
},
|
|
1353
|
-
};
|
|
1354
|
-
}
|
|
1355
|
-
return {
|
|
1356
|
-
success: false,
|
|
1357
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
1358
|
-
type: 'missing_role',
|
|
1359
|
-
},
|
|
1360
|
-
};
|
|
1361
|
-
});
|
|
1362
|
-
}
|
|
1363
|
-
_authorizeFileListRequest(context, request) {
|
|
1364
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1365
|
-
const allMarkers = union(...request.fileItems.map((i) => i.markers));
|
|
1366
|
-
return yield this._authorizeRequest(context, request, allMarkers, (context, type, id) => {
|
|
1367
|
-
return this._authorizeFileList(context, type, id);
|
|
1368
|
-
}, undefined, true);
|
|
1369
|
-
});
|
|
1370
|
-
}
|
|
1371
|
-
_authorizeFileList(context, type, id) {
|
|
1372
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1373
|
-
const authorizations = [];
|
|
1374
|
-
let role = null;
|
|
1375
|
-
const allowedFileItems = (context.allowedFileItems =
|
|
1376
|
-
[]);
|
|
1377
|
-
const markers = new Map();
|
|
1378
|
-
for (let marker of context.markers) {
|
|
1379
|
-
const authorization = {
|
|
1380
|
-
marker: marker.marker,
|
|
1381
|
-
actions: [],
|
|
1382
|
-
};
|
|
1383
|
-
authorizations.push(authorization);
|
|
1384
|
-
markers.set(marker.marker, {
|
|
1385
|
-
marker,
|
|
1386
|
-
authorization: authorization,
|
|
1387
|
-
usedPermissions: new Set(),
|
|
1388
|
-
});
|
|
1389
|
-
}
|
|
1390
|
-
for (let item of context.request.fileItems) {
|
|
1391
|
-
let itemPermission;
|
|
1392
|
-
for (let m of item.markers) {
|
|
1393
|
-
const a = markers.get(m);
|
|
1394
|
-
if (!a) {
|
|
1395
|
-
continue;
|
|
1396
|
-
}
|
|
1397
|
-
const { marker, authorization, usedPermissions } = a;
|
|
1398
|
-
itemPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byFile('file.list', item.fileSizeInBytes, item.fileMimeType), role === null
|
|
1399
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1400
|
-
: this._byRole(role)));
|
|
1401
|
-
if (!itemPermission) {
|
|
1402
|
-
continue;
|
|
1403
|
-
}
|
|
1404
|
-
if (role === null) {
|
|
1405
|
-
role = itemPermission.permission.role;
|
|
1406
|
-
}
|
|
1407
|
-
if (!usedPermissions.has(itemPermission.permission)) {
|
|
1408
|
-
usedPermissions.add(itemPermission.permission);
|
|
1409
|
-
authorization.actions.push({
|
|
1410
|
-
action: context.request.action,
|
|
1411
|
-
grantingPolicy: itemPermission.policy,
|
|
1412
|
-
grantingPermission: itemPermission.permission,
|
|
1413
|
-
});
|
|
1414
|
-
}
|
|
1415
|
-
if (itemPermission) {
|
|
1416
|
-
break;
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
if (itemPermission) {
|
|
1420
|
-
allowedFileItems.push(item);
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
if (!role) {
|
|
1424
|
-
role = true;
|
|
1425
|
-
}
|
|
1426
|
-
return {
|
|
1427
|
-
success: true,
|
|
1428
|
-
authorization: {
|
|
1429
|
-
role,
|
|
1430
|
-
markers: authorizations,
|
|
1431
|
-
},
|
|
1432
|
-
};
|
|
1433
|
-
});
|
|
1434
|
-
}
|
|
1435
|
-
_authorizeFileUpdateRequest(context, request) {
|
|
1436
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1437
|
-
const allMarkers = union(request.existingMarkers, request.addedMarkers, request.removedMarkers);
|
|
1438
|
-
return yield this._authorizeRequest(context, request, allMarkers, (context, type, id) => {
|
|
1439
|
-
return this._authorizeFileUpdate(context, type, id);
|
|
1440
|
-
});
|
|
1441
|
-
});
|
|
1442
|
-
}
|
|
1443
|
-
_authorizeFileUpdate(context, type, id) {
|
|
1444
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1445
|
-
if ((!context.request.addedMarkers ||
|
|
1446
|
-
context.request.addedMarkers.length <= 0) &&
|
|
1447
|
-
(!context.request.removedMarkers ||
|
|
1448
|
-
context.request.removedMarkers.length <= 0)) {
|
|
1449
|
-
return {
|
|
1450
|
-
success: false,
|
|
1451
|
-
reason: {
|
|
1452
|
-
type: 'no_markers',
|
|
1453
|
-
},
|
|
1454
|
-
};
|
|
1455
|
-
}
|
|
1456
|
-
if (!willMarkersBeRemaining(context.request.existingMarkers, context.request.removedMarkers, context.request.addedMarkers)) {
|
|
1457
|
-
return {
|
|
1458
|
-
success: false,
|
|
1459
|
-
reason: {
|
|
1460
|
-
type: 'no_markers_remaining',
|
|
1461
|
-
},
|
|
1462
|
-
};
|
|
1463
|
-
}
|
|
1464
|
-
const authorizations = [];
|
|
1465
|
-
let role = null;
|
|
1466
|
-
for (let marker of context.markers) {
|
|
1467
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byFile('file.update', context.request.fileSizeInBytes, context.request.fileMimeType), role === null
|
|
1468
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1469
|
-
: this._byRole(role)));
|
|
1470
|
-
if (!actionPermission) {
|
|
1471
|
-
return {
|
|
1472
|
-
success: false,
|
|
1473
|
-
reason: {
|
|
1474
|
-
type: 'missing_permission',
|
|
1475
|
-
kind: type,
|
|
1476
|
-
id,
|
|
1477
|
-
marker: marker.marker,
|
|
1478
|
-
permission: 'file.update',
|
|
1479
|
-
role,
|
|
1480
|
-
},
|
|
1481
|
-
};
|
|
1482
|
-
}
|
|
1483
|
-
if (role === null) {
|
|
1484
|
-
role = actionPermission.permission.role;
|
|
1485
|
-
}
|
|
1486
|
-
const isAddedMarker = context.request.addedMarkers &&
|
|
1487
|
-
context.request.addedMarkers.includes(marker.marker);
|
|
1488
|
-
const isRemovedMarker = context.request.removedMarkers &&
|
|
1489
|
-
context.request.removedMarkers.includes(marker.marker);
|
|
1490
|
-
const actions = [
|
|
1491
|
-
{
|
|
1492
|
-
action: context.request.action,
|
|
1493
|
-
grantingPolicy: actionPermission.policy,
|
|
1494
|
-
grantingPermission: actionPermission.permission,
|
|
1495
|
-
},
|
|
1496
|
-
];
|
|
1497
|
-
if (isAddedMarker) {
|
|
1498
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.assign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
1499
|
-
if (!policyPermission) {
|
|
1500
|
-
return {
|
|
1501
|
-
success: false,
|
|
1502
|
-
reason: {
|
|
1503
|
-
type: 'missing_permission',
|
|
1504
|
-
kind: type,
|
|
1505
|
-
id,
|
|
1506
|
-
marker: marker.marker,
|
|
1507
|
-
permission: 'policy.assign',
|
|
1508
|
-
role,
|
|
1509
|
-
},
|
|
1510
|
-
};
|
|
1511
|
-
}
|
|
1512
|
-
actions.push({
|
|
1513
|
-
action: 'policy.assign',
|
|
1514
|
-
grantingPolicy: policyPermission.policy,
|
|
1515
|
-
grantingPermission: policyPermission.permission,
|
|
1516
|
-
});
|
|
1517
|
-
}
|
|
1518
|
-
else if (isRemovedMarker) {
|
|
1519
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.unassign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
1520
|
-
if (!policyPermission) {
|
|
1521
|
-
return {
|
|
1522
|
-
success: false,
|
|
1523
|
-
reason: {
|
|
1524
|
-
type: 'missing_permission',
|
|
1525
|
-
kind: type,
|
|
1526
|
-
id,
|
|
1527
|
-
marker: marker.marker,
|
|
1528
|
-
permission: 'policy.unassign',
|
|
1529
|
-
role,
|
|
1530
|
-
},
|
|
1531
|
-
};
|
|
1532
|
-
}
|
|
1533
|
-
actions.push({
|
|
1534
|
-
action: 'policy.unassign',
|
|
1535
|
-
grantingPolicy: policyPermission.policy,
|
|
1536
|
-
grantingPermission: policyPermission.permission,
|
|
1537
|
-
});
|
|
1538
|
-
}
|
|
1539
|
-
authorizations.push({
|
|
1540
|
-
marker: marker.marker,
|
|
1541
|
-
actions,
|
|
1542
|
-
});
|
|
1543
|
-
}
|
|
1544
|
-
if (!role) {
|
|
1545
|
-
return {
|
|
1546
|
-
success: false,
|
|
1547
|
-
reason: {
|
|
1548
|
-
type: 'missing_role',
|
|
1549
|
-
},
|
|
1550
|
-
};
|
|
1551
|
-
}
|
|
1552
|
-
return {
|
|
1553
|
-
success: true,
|
|
1554
|
-
authorization: {
|
|
1555
|
-
role,
|
|
1556
|
-
markers: authorizations,
|
|
1557
|
-
},
|
|
1558
|
-
};
|
|
1559
|
-
});
|
|
1560
|
-
}
|
|
1561
|
-
_authorizeFileDeleteRequest(context, request) {
|
|
1562
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1563
|
-
return yield this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
1564
|
-
return this._authorizeFileDelete(context, type, id);
|
|
1565
|
-
});
|
|
1566
|
-
});
|
|
1567
|
-
}
|
|
1568
|
-
_authorizeFileDelete(context, type, id) {
|
|
1569
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1570
|
-
let role = null;
|
|
1571
|
-
let denialReason;
|
|
1572
|
-
for (let marker of context.markers) {
|
|
1573
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byFile('file.delete', context.request.fileSizeInBytes, context.request.fileMimeType), role === null
|
|
1574
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1575
|
-
: this._byRole(role)));
|
|
1576
|
-
if (!actionPermission) {
|
|
1577
|
-
denialReason = {
|
|
1578
|
-
type: 'missing_permission',
|
|
1579
|
-
kind: type,
|
|
1580
|
-
id,
|
|
1581
|
-
marker: marker.marker,
|
|
1582
|
-
permission: 'file.delete',
|
|
1583
|
-
role,
|
|
1584
|
-
};
|
|
1585
|
-
continue;
|
|
1586
|
-
}
|
|
1587
|
-
if (role === null) {
|
|
1588
|
-
role = actionPermission.permission.role;
|
|
1589
|
-
}
|
|
1590
|
-
return {
|
|
1591
|
-
success: true,
|
|
1592
|
-
authorization: {
|
|
1593
|
-
role,
|
|
1594
|
-
markers: [
|
|
1595
|
-
{
|
|
1596
|
-
marker: marker.marker,
|
|
1597
|
-
actions: [
|
|
1598
|
-
{
|
|
1599
|
-
action: context.request.action,
|
|
1600
|
-
grantingPolicy: actionPermission.policy,
|
|
1601
|
-
grantingPermission: actionPermission.permission,
|
|
1602
|
-
},
|
|
1603
|
-
],
|
|
1604
|
-
},
|
|
1605
|
-
],
|
|
1606
|
-
},
|
|
1607
|
-
};
|
|
1608
|
-
}
|
|
1609
|
-
return {
|
|
1610
|
-
success: false,
|
|
1611
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
1612
|
-
type: 'missing_role',
|
|
1613
|
-
},
|
|
1614
|
-
};
|
|
1615
|
-
});
|
|
1616
|
-
}
|
|
1617
|
-
_authorizeEventCountRequest(context, request) {
|
|
1618
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1619
|
-
return yield this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
1620
|
-
return this._authorizeEventCount(context, type, id);
|
|
1621
|
-
});
|
|
1622
|
-
});
|
|
1623
|
-
}
|
|
1624
|
-
_authorizeEventCount(context, type, id) {
|
|
1625
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1626
|
-
let role = null;
|
|
1627
|
-
let denialReason;
|
|
1628
|
-
for (let marker of context.markers) {
|
|
1629
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byEvent('event.count', context.request.eventName), role === null
|
|
1630
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1631
|
-
: this._byRole(role)));
|
|
1632
|
-
if (!actionPermission) {
|
|
1633
|
-
denialReason = {
|
|
1634
|
-
type: 'missing_permission',
|
|
1635
|
-
kind: type,
|
|
1636
|
-
id,
|
|
1637
|
-
marker: marker.marker,
|
|
1638
|
-
permission: 'event.count',
|
|
1639
|
-
role,
|
|
1640
|
-
};
|
|
1641
|
-
continue;
|
|
1642
|
-
}
|
|
1643
|
-
if (role === null) {
|
|
1644
|
-
role = actionPermission.permission.role;
|
|
1645
|
-
}
|
|
1646
|
-
return {
|
|
1647
|
-
success: true,
|
|
1648
|
-
authorization: {
|
|
1649
|
-
role,
|
|
1650
|
-
markers: [
|
|
1651
|
-
{
|
|
1652
|
-
marker: marker.marker,
|
|
1653
|
-
actions: [
|
|
1654
|
-
{
|
|
1655
|
-
action: context.request.action,
|
|
1656
|
-
grantingPolicy: actionPermission.policy,
|
|
1657
|
-
grantingPermission: actionPermission.permission,
|
|
1658
|
-
},
|
|
1659
|
-
],
|
|
1660
|
-
},
|
|
1661
|
-
],
|
|
1662
|
-
},
|
|
1663
|
-
};
|
|
1664
|
-
}
|
|
1665
|
-
return {
|
|
1666
|
-
success: false,
|
|
1667
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
1668
|
-
type: 'missing_role',
|
|
1669
|
-
},
|
|
1670
|
-
};
|
|
1671
|
-
});
|
|
1672
|
-
}
|
|
1673
|
-
_authorizeEventIncrementRequest(context, request) {
|
|
1674
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1675
|
-
return yield this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
1676
|
-
return this._authorizeEventIncrement(context, type, id);
|
|
1677
|
-
});
|
|
1678
|
-
});
|
|
1679
|
-
}
|
|
1680
|
-
_authorizeEventIncrement(context, type, id) {
|
|
1681
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1682
|
-
let role = null;
|
|
1683
|
-
let denialReason;
|
|
1684
|
-
for (let marker of context.markers) {
|
|
1685
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byEvent('event.increment', context.request.eventName), role === null
|
|
1686
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1687
|
-
: this._byRole(role)));
|
|
1688
|
-
if (!actionPermission) {
|
|
1689
|
-
denialReason = {
|
|
1690
|
-
type: 'missing_permission',
|
|
1691
|
-
kind: type,
|
|
1692
|
-
id,
|
|
1693
|
-
marker: marker.marker,
|
|
1694
|
-
permission: 'event.increment',
|
|
1695
|
-
role,
|
|
1696
|
-
};
|
|
1697
|
-
continue;
|
|
1698
|
-
}
|
|
1699
|
-
if (role === null) {
|
|
1700
|
-
role = actionPermission.permission.role;
|
|
1701
|
-
}
|
|
1702
|
-
return {
|
|
1703
|
-
success: true,
|
|
1704
|
-
authorization: {
|
|
1705
|
-
role,
|
|
1706
|
-
markers: [
|
|
1707
|
-
{
|
|
1708
|
-
marker: marker.marker,
|
|
1709
|
-
actions: [
|
|
1710
|
-
{
|
|
1711
|
-
action: context.request.action,
|
|
1712
|
-
grantingPolicy: actionPermission.policy,
|
|
1713
|
-
grantingPermission: actionPermission.permission,
|
|
1714
|
-
},
|
|
1715
|
-
],
|
|
1716
|
-
},
|
|
1717
|
-
],
|
|
1718
|
-
},
|
|
1719
|
-
};
|
|
1720
|
-
}
|
|
1721
|
-
return {
|
|
1722
|
-
success: false,
|
|
1723
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
1724
|
-
type: 'missing_role',
|
|
1725
|
-
},
|
|
1726
|
-
};
|
|
1727
|
-
});
|
|
1728
|
-
}
|
|
1729
|
-
_authorizeEventUpdateRequest(context, request) {
|
|
1730
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1731
|
-
if (!willMarkersBeRemaining(request.existingMarkers, request.removedMarkers, request.addedMarkers)) {
|
|
1732
|
-
return Object.assign(Object.assign({}, NOT_AUTHORIZED_RESULT), { reason: {
|
|
1733
|
-
type: 'no_markers_remaining',
|
|
1734
|
-
} });
|
|
1735
|
-
}
|
|
1736
|
-
return yield this._authorizeRequest(context, request, union(request.existingMarkers, request.addedMarkers, request.removedMarkers), (context, type, id) => {
|
|
1737
|
-
return this._authorizeEventUpdate(context, type, id);
|
|
1738
|
-
});
|
|
1739
|
-
});
|
|
1740
|
-
}
|
|
1741
|
-
_authorizeEventUpdate(context, type, id) {
|
|
1742
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1743
|
-
let authorizations = [];
|
|
1744
|
-
let role = null;
|
|
1745
|
-
// The denial reason for if the user does not have permission from an existing marker.
|
|
1746
|
-
let denialReason;
|
|
1747
|
-
let hasPermissionFromExistingMarker = false;
|
|
1748
|
-
for (let marker of context.markers) {
|
|
1749
|
-
const isAddedMarker = context.request.addedMarkers &&
|
|
1750
|
-
context.request.addedMarkers.includes(marker.marker);
|
|
1751
|
-
const isRemovedMarker = context.request.removedMarkers &&
|
|
1752
|
-
context.request.removedMarkers.includes(marker.marker);
|
|
1753
|
-
const isExistingMarker = context.request.existingMarkers.includes(marker.marker);
|
|
1754
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byEvent('event.update', context.request.eventName), role === null
|
|
1755
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1756
|
-
: this._byRole(role)));
|
|
1757
|
-
if (!actionPermission) {
|
|
1758
|
-
if (isAddedMarker || isRemovedMarker) {
|
|
1759
|
-
// Deny because the user needs permission for all new & removed markers.
|
|
1760
|
-
return {
|
|
1761
|
-
success: false,
|
|
1762
|
-
reason: {
|
|
1763
|
-
type: 'missing_permission',
|
|
1764
|
-
kind: type,
|
|
1765
|
-
id,
|
|
1766
|
-
marker: marker.marker,
|
|
1767
|
-
permission: 'event.update',
|
|
1768
|
-
role,
|
|
1769
|
-
},
|
|
1770
|
-
};
|
|
1771
|
-
}
|
|
1772
|
-
else {
|
|
1773
|
-
// Record that the user does not have permission from this marker.
|
|
1774
|
-
// May or may not be used depending on if a different existing marker
|
|
1775
|
-
// provides permission.
|
|
1776
|
-
denialReason = {
|
|
1777
|
-
type: 'missing_permission',
|
|
1778
|
-
kind: type,
|
|
1779
|
-
id,
|
|
1780
|
-
marker: marker.marker,
|
|
1781
|
-
permission: 'event.update',
|
|
1782
|
-
role,
|
|
1783
|
-
};
|
|
1784
|
-
continue;
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
if (isExistingMarker) {
|
|
1788
|
-
hasPermissionFromExistingMarker = true;
|
|
1789
|
-
}
|
|
1790
|
-
if (role === null) {
|
|
1791
|
-
role = actionPermission.permission.role;
|
|
1792
|
-
}
|
|
1793
|
-
const actions = [
|
|
1794
|
-
{
|
|
1795
|
-
action: context.request.action,
|
|
1796
|
-
grantingPolicy: actionPermission.policy,
|
|
1797
|
-
grantingPermission: actionPermission.permission,
|
|
1798
|
-
},
|
|
1799
|
-
];
|
|
1800
|
-
if (isAddedMarker) {
|
|
1801
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.assign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
1802
|
-
if (!policyPermission) {
|
|
1803
|
-
return {
|
|
1804
|
-
success: false,
|
|
1805
|
-
reason: {
|
|
1806
|
-
type: 'missing_permission',
|
|
1807
|
-
kind: type,
|
|
1808
|
-
id,
|
|
1809
|
-
marker: marker.marker,
|
|
1810
|
-
permission: 'policy.assign',
|
|
1811
|
-
role,
|
|
1812
|
-
},
|
|
1813
|
-
};
|
|
1814
|
-
continue;
|
|
1815
|
-
}
|
|
1816
|
-
actions.push({
|
|
1817
|
-
action: 'policy.assign',
|
|
1818
|
-
grantingPolicy: policyPermission.policy,
|
|
1819
|
-
grantingPermission: policyPermission.permission,
|
|
1820
|
-
});
|
|
1821
|
-
}
|
|
1822
|
-
else if (isRemovedMarker) {
|
|
1823
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.unassign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
1824
|
-
if (!policyPermission) {
|
|
1825
|
-
return {
|
|
1826
|
-
success: false,
|
|
1827
|
-
reason: {
|
|
1828
|
-
type: 'missing_permission',
|
|
1829
|
-
kind: type,
|
|
1830
|
-
id,
|
|
1831
|
-
marker: marker.marker,
|
|
1832
|
-
permission: 'policy.unassign',
|
|
1833
|
-
role,
|
|
1834
|
-
},
|
|
1835
|
-
};
|
|
1836
|
-
}
|
|
1837
|
-
actions.push({
|
|
1838
|
-
action: 'policy.unassign',
|
|
1839
|
-
grantingPolicy: policyPermission.policy,
|
|
1840
|
-
grantingPermission: policyPermission.permission,
|
|
1841
|
-
});
|
|
1842
|
-
}
|
|
1843
|
-
authorizations.push({
|
|
1844
|
-
marker: marker.marker,
|
|
1845
|
-
actions,
|
|
1846
|
-
});
|
|
1847
|
-
}
|
|
1848
|
-
// Deny the request if the user does not have permission from at least one existing marker.
|
|
1849
|
-
if (!hasPermissionFromExistingMarker && denialReason) {
|
|
1850
|
-
return {
|
|
1851
|
-
success: false,
|
|
1852
|
-
reason: denialReason,
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
if (!role) {
|
|
1856
|
-
return {
|
|
1857
|
-
success: false,
|
|
1858
|
-
reason: {
|
|
1859
|
-
type: 'missing_role',
|
|
1860
|
-
},
|
|
1861
|
-
};
|
|
1862
|
-
}
|
|
1863
|
-
return {
|
|
1864
|
-
success: true,
|
|
1865
|
-
authorization: {
|
|
1866
|
-
role,
|
|
1867
|
-
markers: authorizations,
|
|
1868
|
-
},
|
|
1869
|
-
};
|
|
1870
|
-
});
|
|
1871
|
-
}
|
|
1872
|
-
_authorizeEventListRequest(context, request) {
|
|
1873
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1874
|
-
const allMarkers = union(...request.eventItems.map((i) => i.markers));
|
|
1875
|
-
return yield this._authorizeRequest(context, request, allMarkers, (context, type, id) => {
|
|
1876
|
-
return this._authorizeEventList(context, type, id);
|
|
1877
|
-
}, undefined, true);
|
|
1878
|
-
});
|
|
1879
|
-
}
|
|
1880
|
-
_authorizeEventList(context, type, id) {
|
|
1881
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1882
|
-
const authorizations = [];
|
|
1883
|
-
let role = null;
|
|
1884
|
-
const allowedEventItems = (context.allowedEventItems =
|
|
1885
|
-
[]);
|
|
1886
|
-
const markers = new Map();
|
|
1887
|
-
for (let marker of context.markers) {
|
|
1888
|
-
const authorization = {
|
|
1889
|
-
marker: marker.marker,
|
|
1890
|
-
actions: [],
|
|
1891
|
-
};
|
|
1892
|
-
authorizations.push(authorization);
|
|
1893
|
-
markers.set(marker.marker, {
|
|
1894
|
-
marker,
|
|
1895
|
-
authorization: authorization,
|
|
1896
|
-
usedPermissions: new Set(),
|
|
1897
|
-
});
|
|
1898
|
-
}
|
|
1899
|
-
for (let item of context.request.eventItems) {
|
|
1900
|
-
let itemPermission;
|
|
1901
|
-
for (let m of item.markers) {
|
|
1902
|
-
const a = markers.get(m);
|
|
1903
|
-
if (!a) {
|
|
1904
|
-
continue;
|
|
1905
|
-
}
|
|
1906
|
-
const { marker, authorization, usedPermissions } = a;
|
|
1907
|
-
itemPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byEvent('event.list', item.eventName), role === null
|
|
1908
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
1909
|
-
: this._byRole(role)));
|
|
1910
|
-
if (!itemPermission) {
|
|
1911
|
-
continue;
|
|
1912
|
-
}
|
|
1913
|
-
if (role === null) {
|
|
1914
|
-
role = itemPermission.permission.role;
|
|
1915
|
-
}
|
|
1916
|
-
if (!usedPermissions.has(itemPermission.permission)) {
|
|
1917
|
-
usedPermissions.add(itemPermission.permission);
|
|
1918
|
-
authorization.actions.push({
|
|
1919
|
-
action: context.request.action,
|
|
1920
|
-
grantingPolicy: itemPermission.policy,
|
|
1921
|
-
grantingPermission: itemPermission.permission,
|
|
1922
|
-
});
|
|
1923
|
-
}
|
|
1924
|
-
if (itemPermission) {
|
|
1925
|
-
break;
|
|
1926
|
-
}
|
|
1927
|
-
}
|
|
1928
|
-
if (itemPermission) {
|
|
1929
|
-
allowedEventItems.push(item);
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
if (!role) {
|
|
1933
|
-
role = true;
|
|
1934
|
-
}
|
|
1935
|
-
return {
|
|
1936
|
-
success: true,
|
|
1937
|
-
authorization: {
|
|
1938
|
-
role,
|
|
1939
|
-
markers: authorizations,
|
|
1940
|
-
},
|
|
1941
|
-
};
|
|
1942
|
-
});
|
|
1943
|
-
}
|
|
1944
|
-
_authorizePolicyGrantPermissionRequest(context, request) {
|
|
1945
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1946
|
-
return yield this._authorizeRequest(context, request, [ACCOUNT_MARKER], (context, type, id) => {
|
|
1947
|
-
return this._authorizePolicyGrantPermission(context, type, id);
|
|
1948
|
-
}, false);
|
|
1949
|
-
});
|
|
1950
|
-
}
|
|
1951
|
-
_authorizePolicyGrantPermission(context, type, id) {
|
|
1952
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1953
|
-
let role = null;
|
|
1954
|
-
let denialReason;
|
|
1955
|
-
for (let marker of context.markers) {
|
|
1956
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.grantPermission', context.request.policy), role === null
|
|
1957
|
-
? this._some(this._byEveryoneRole(), this._bySubjectRole(context, type, context.recordName, id), this._byRecordOwner(context, type, id), this._byStudioRole(context, type, id, 'admin'))
|
|
1958
|
-
: this._byRole(role)));
|
|
1959
|
-
if (!actionPermission) {
|
|
1960
|
-
denialReason = {
|
|
1961
|
-
type: 'missing_permission',
|
|
1962
|
-
kind: type,
|
|
1963
|
-
id,
|
|
1964
|
-
marker: marker.marker,
|
|
1965
|
-
permission: 'policy.grantPermission',
|
|
1966
|
-
role,
|
|
1967
|
-
};
|
|
1968
|
-
continue;
|
|
1969
|
-
}
|
|
1970
|
-
if (role === null) {
|
|
1971
|
-
role = actionPermission.permission.role;
|
|
1972
|
-
}
|
|
1973
|
-
return {
|
|
1974
|
-
success: true,
|
|
1975
|
-
authorization: {
|
|
1976
|
-
role,
|
|
1977
|
-
markers: [
|
|
1978
|
-
{
|
|
1979
|
-
marker: marker.marker,
|
|
1980
|
-
actions: [
|
|
1981
|
-
{
|
|
1982
|
-
action: context.request.action,
|
|
1983
|
-
grantingPolicy: actionPermission.policy,
|
|
1984
|
-
grantingPermission: actionPermission.permission,
|
|
1985
|
-
},
|
|
1986
|
-
],
|
|
1987
|
-
},
|
|
1988
|
-
],
|
|
1989
|
-
},
|
|
1990
|
-
};
|
|
1991
|
-
}
|
|
1992
|
-
return {
|
|
1993
|
-
success: false,
|
|
1994
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
1995
|
-
type: 'missing_role',
|
|
1996
|
-
},
|
|
1997
|
-
};
|
|
1998
|
-
});
|
|
1999
|
-
}
|
|
2000
|
-
_authorizePolicyRevokePermissionRequest(context, request) {
|
|
2001
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2002
|
-
return yield this._authorizeRequest(context, request, [ACCOUNT_MARKER], (context, type, id) => {
|
|
2003
|
-
return this._authorizePolicyRevokePermission(context, type, id);
|
|
2004
|
-
}, false);
|
|
2005
|
-
});
|
|
2006
|
-
}
|
|
2007
|
-
_authorizePolicyRevokePermission(context, type, id) {
|
|
2008
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2009
|
-
let role = null;
|
|
2010
|
-
let denialReason;
|
|
2011
|
-
for (let marker of context.markers) {
|
|
2012
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.revokePermission', context.request.policy), role === null
|
|
2013
|
-
? this._some(this._byEveryoneRole(), this._bySubjectRole(context, type, context.recordName, id), this._byRecordOwner(context, type, id), this._byStudioRole(context, type, id, 'admin'))
|
|
2014
|
-
: this._byRole(role)));
|
|
2015
|
-
if (!actionPermission) {
|
|
2016
|
-
denialReason = {
|
|
2017
|
-
type: 'missing_permission',
|
|
2018
|
-
kind: type,
|
|
2019
|
-
id,
|
|
2020
|
-
marker: marker.marker,
|
|
2021
|
-
permission: 'policy.revokePermission',
|
|
2022
|
-
role,
|
|
2023
|
-
};
|
|
2024
|
-
continue;
|
|
2025
|
-
}
|
|
2026
|
-
if (role === null) {
|
|
2027
|
-
role = actionPermission.permission.role;
|
|
2028
|
-
}
|
|
2029
|
-
return {
|
|
2030
|
-
success: true,
|
|
2031
|
-
authorization: {
|
|
2032
|
-
role,
|
|
2033
|
-
markers: [
|
|
2034
|
-
{
|
|
2035
|
-
marker: marker.marker,
|
|
2036
|
-
actions: [
|
|
2037
|
-
{
|
|
2038
|
-
action: context.request.action,
|
|
2039
|
-
grantingPolicy: actionPermission.policy,
|
|
2040
|
-
grantingPermission: actionPermission.permission,
|
|
2041
|
-
},
|
|
2042
|
-
],
|
|
2043
|
-
},
|
|
2044
|
-
],
|
|
2045
|
-
},
|
|
2046
|
-
};
|
|
2047
|
-
}
|
|
2048
|
-
return {
|
|
2049
|
-
success: false,
|
|
2050
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2051
|
-
type: 'missing_role',
|
|
2052
|
-
},
|
|
2053
|
-
};
|
|
2054
|
-
});
|
|
2055
|
-
}
|
|
2056
|
-
_authorizePolicyReadRequest(context, request) {
|
|
2057
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2058
|
-
return yield this._authorizeRequest(context, request, [ACCOUNT_MARKER], (context, type, id) => {
|
|
2059
|
-
return this._authorizePolicyRead(context, type, id);
|
|
2060
|
-
}, false);
|
|
2061
|
-
});
|
|
2062
|
-
}
|
|
2063
|
-
_authorizePolicyRead(context, type, id) {
|
|
2064
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2065
|
-
let role = null;
|
|
2066
|
-
let denialReason;
|
|
2067
|
-
for (let marker of context.markers) {
|
|
2068
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.read', context.request.policy), role === null
|
|
2069
|
-
? this._some(this._byEveryoneRole(), this._bySubjectRole(context, type, context.recordName, id), this._byRecordOwner(context, type, id), this._byStudioRole(context, type, id, 'admin'))
|
|
2070
|
-
: this._byRole(role)));
|
|
2071
|
-
if (!actionPermission) {
|
|
2072
|
-
denialReason = {
|
|
2073
|
-
type: 'missing_permission',
|
|
2074
|
-
kind: type,
|
|
2075
|
-
id,
|
|
2076
|
-
marker: marker.marker,
|
|
2077
|
-
permission: 'policy.read',
|
|
2078
|
-
role,
|
|
2079
|
-
};
|
|
2080
|
-
continue;
|
|
2081
|
-
}
|
|
2082
|
-
if (role === null) {
|
|
2083
|
-
role = actionPermission.permission.role;
|
|
2084
|
-
}
|
|
2085
|
-
return {
|
|
2086
|
-
success: true,
|
|
2087
|
-
authorization: {
|
|
2088
|
-
role,
|
|
2089
|
-
markers: [
|
|
2090
|
-
{
|
|
2091
|
-
marker: marker.marker,
|
|
2092
|
-
actions: [
|
|
2093
|
-
{
|
|
2094
|
-
action: context.request.action,
|
|
2095
|
-
grantingPolicy: actionPermission.policy,
|
|
2096
|
-
grantingPermission: actionPermission.permission,
|
|
2097
|
-
},
|
|
2098
|
-
],
|
|
2099
|
-
},
|
|
2100
|
-
],
|
|
2101
|
-
},
|
|
2102
|
-
};
|
|
2103
|
-
}
|
|
2104
|
-
return {
|
|
2105
|
-
success: false,
|
|
2106
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2107
|
-
type: 'missing_role',
|
|
2108
|
-
},
|
|
2109
|
-
};
|
|
2110
|
-
});
|
|
2111
|
-
}
|
|
2112
|
-
_authorizePolicyListRequest(context, request) {
|
|
2113
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2114
|
-
return yield this._authorizeRequest(context, request, [ACCOUNT_MARKER], (context, type, id) => {
|
|
2115
|
-
return this._authorizePolicyList(context, type, id);
|
|
2116
|
-
}, false);
|
|
2117
|
-
});
|
|
2118
|
-
}
|
|
2119
|
-
_authorizePolicyList(context, type, id) {
|
|
2120
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2121
|
-
let role = null;
|
|
2122
|
-
let denialReason;
|
|
2123
|
-
for (let marker of context.markers) {
|
|
2124
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicyList('policy.list'), role === null
|
|
2125
|
-
? this._some(this._byEveryoneRole(), this._bySubjectRole(context, type, context.recordName, id), this._byRecordOwner(context, type, id), this._byStudioRole(context, type, id, 'admin'))
|
|
2126
|
-
: this._byRole(role)));
|
|
2127
|
-
if (!actionPermission) {
|
|
2128
|
-
denialReason = {
|
|
2129
|
-
type: 'missing_permission',
|
|
2130
|
-
kind: type,
|
|
2131
|
-
id,
|
|
2132
|
-
marker: marker.marker,
|
|
2133
|
-
permission: 'policy.list',
|
|
2134
|
-
role,
|
|
2135
|
-
};
|
|
2136
|
-
continue;
|
|
2137
|
-
}
|
|
2138
|
-
if (role === null) {
|
|
2139
|
-
role = actionPermission.permission.role;
|
|
2140
|
-
}
|
|
2141
|
-
return {
|
|
2142
|
-
success: true,
|
|
2143
|
-
authorization: {
|
|
2144
|
-
role,
|
|
2145
|
-
markers: [
|
|
2146
|
-
{
|
|
2147
|
-
marker: marker.marker,
|
|
2148
|
-
actions: [
|
|
2149
|
-
{
|
|
2150
|
-
action: context.request.action,
|
|
2151
|
-
grantingPolicy: actionPermission.policy,
|
|
2152
|
-
grantingPermission: actionPermission.permission,
|
|
2153
|
-
},
|
|
2154
|
-
],
|
|
2155
|
-
},
|
|
2156
|
-
],
|
|
2157
|
-
},
|
|
2158
|
-
};
|
|
2159
|
-
}
|
|
2160
|
-
return {
|
|
2161
|
-
success: false,
|
|
2162
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2163
|
-
type: 'missing_role',
|
|
2164
|
-
},
|
|
2165
|
-
};
|
|
2166
|
-
});
|
|
2167
|
-
}
|
|
2168
|
-
_authorizeRoleListRequest(context, request) {
|
|
2169
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2170
|
-
return yield this._authorizeRequest(context, request, [ACCOUNT_MARKER], (context, type, id) => {
|
|
2171
|
-
return this._authorizeRoleList(context, type, id);
|
|
2172
|
-
}, false);
|
|
2173
|
-
});
|
|
2174
|
-
}
|
|
2175
|
-
_authorizeRoleList(context, type, id) {
|
|
2176
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2177
|
-
let role = null;
|
|
2178
|
-
let denialReason;
|
|
2179
|
-
for (let marker of context.markers) {
|
|
2180
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byRoleList('role.list'), role === null
|
|
2181
|
-
? this._some(this._byEveryoneRole(), this._bySubjectRole(context, type, context.recordName, id), this._byRecordOwner(context, type, id), this._byStudioRole(context, type, id, 'admin'))
|
|
2182
|
-
: this._byRole(role)));
|
|
2183
|
-
if (!actionPermission) {
|
|
2184
|
-
denialReason = {
|
|
2185
|
-
type: 'missing_permission',
|
|
2186
|
-
kind: type,
|
|
2187
|
-
id,
|
|
2188
|
-
marker: marker.marker,
|
|
2189
|
-
permission: 'role.list',
|
|
2190
|
-
role,
|
|
2191
|
-
};
|
|
2192
|
-
continue;
|
|
2193
|
-
}
|
|
2194
|
-
if (role === null) {
|
|
2195
|
-
role = actionPermission.permission.role;
|
|
2196
|
-
}
|
|
2197
|
-
return {
|
|
2198
|
-
success: true,
|
|
2199
|
-
authorization: {
|
|
2200
|
-
role,
|
|
2201
|
-
markers: [
|
|
2202
|
-
{
|
|
2203
|
-
marker: marker.marker,
|
|
2204
|
-
actions: [
|
|
2205
|
-
{
|
|
2206
|
-
action: context.request.action,
|
|
2207
|
-
grantingPolicy: actionPermission.policy,
|
|
2208
|
-
grantingPermission: actionPermission.permission,
|
|
2209
|
-
},
|
|
2210
|
-
],
|
|
2211
|
-
},
|
|
2212
|
-
],
|
|
2213
|
-
},
|
|
2214
|
-
};
|
|
2215
|
-
}
|
|
2216
|
-
return {
|
|
2217
|
-
success: false,
|
|
2218
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2219
|
-
type: 'missing_role',
|
|
2220
|
-
},
|
|
2221
|
-
};
|
|
2222
|
-
});
|
|
2223
|
-
}
|
|
2224
|
-
_authorizeRoleReadRequest(context, request) {
|
|
2225
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2226
|
-
return yield this._authorizeRequest(context, request, [ACCOUNT_MARKER], (context, type, id) => {
|
|
2227
|
-
return this._authorizeRoleRead(context, type, id);
|
|
2228
|
-
}, false);
|
|
2229
|
-
});
|
|
2230
|
-
}
|
|
2231
|
-
_authorizeRoleRead(context, type, id) {
|
|
2232
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2233
|
-
let role = null;
|
|
2234
|
-
let denialReason;
|
|
2235
|
-
for (let marker of context.markers) {
|
|
2236
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byRolePermission('role.read', context.request.role), role === null
|
|
2237
|
-
? this._some(this._byEveryoneRole(), this._bySubjectRole(context, type, context.recordName, id), this._byRecordOwner(context, type, id), this._byStudioRole(context, type, id, 'admin'))
|
|
2238
|
-
: this._byRole(role)));
|
|
2239
|
-
if (!actionPermission) {
|
|
2240
|
-
denialReason = {
|
|
2241
|
-
type: 'missing_permission',
|
|
2242
|
-
kind: type,
|
|
2243
|
-
id,
|
|
2244
|
-
marker: marker.marker,
|
|
2245
|
-
permission: 'role.read',
|
|
2246
|
-
role,
|
|
2247
|
-
};
|
|
2248
|
-
continue;
|
|
2249
|
-
}
|
|
2250
|
-
if (role === null) {
|
|
2251
|
-
role = actionPermission.permission.role;
|
|
2252
|
-
}
|
|
2253
|
-
return {
|
|
2254
|
-
success: true,
|
|
2255
|
-
authorization: {
|
|
2256
|
-
role,
|
|
2257
|
-
markers: [
|
|
2258
|
-
{
|
|
2259
|
-
marker: marker.marker,
|
|
2260
|
-
actions: [
|
|
2261
|
-
{
|
|
2262
|
-
action: context.request.action,
|
|
2263
|
-
grantingPolicy: actionPermission.policy,
|
|
2264
|
-
grantingPermission: actionPermission.permission,
|
|
2265
|
-
},
|
|
2266
|
-
],
|
|
2267
|
-
},
|
|
2268
|
-
],
|
|
2269
|
-
},
|
|
2270
|
-
};
|
|
2271
|
-
}
|
|
2272
|
-
return {
|
|
2273
|
-
success: false,
|
|
2274
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2275
|
-
type: 'missing_role',
|
|
2276
|
-
},
|
|
2277
|
-
};
|
|
2278
|
-
});
|
|
2279
|
-
}
|
|
2280
|
-
_authorizeRoleGrantRequest(context, request) {
|
|
2281
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2282
|
-
return yield this._authorizeRequest(context, request, [ACCOUNT_MARKER], (context, type, id) => {
|
|
2283
|
-
return this._authorizeRoleGrant(context, type, id);
|
|
2284
|
-
}, false);
|
|
2285
|
-
});
|
|
2286
|
-
}
|
|
2287
|
-
_authorizeRoleGrant(context, type, id) {
|
|
2288
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2289
|
-
let role = null;
|
|
2290
|
-
let denialReason;
|
|
2291
|
-
const durationMs = getExpireTime(context.request.expireTimeMs) - Date.now();
|
|
2292
|
-
for (let marker of context.markers) {
|
|
2293
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byRoleGrant('role.grant', context.request.role, context.request.targetUserId, context.request.targetInstance, durationMs), role === null
|
|
2294
|
-
? this._some(this._byEveryoneRole(), this._bySubjectRole(context, type, context.recordName, id), this._byRecordOwner(context, type, id), this._byStudioRole(context, type, id, 'admin'))
|
|
2295
|
-
: this._byRole(role)));
|
|
2296
|
-
if (!actionPermission) {
|
|
2297
|
-
denialReason = {
|
|
2298
|
-
type: 'missing_permission',
|
|
2299
|
-
kind: type,
|
|
2300
|
-
id,
|
|
2301
|
-
marker: marker.marker,
|
|
2302
|
-
permission: 'role.grant',
|
|
2303
|
-
role,
|
|
2304
|
-
};
|
|
2305
|
-
continue;
|
|
2306
|
-
}
|
|
2307
|
-
if (role === null) {
|
|
2308
|
-
role = actionPermission.permission.role;
|
|
2309
|
-
}
|
|
2310
|
-
return {
|
|
2311
|
-
success: true,
|
|
2312
|
-
authorization: {
|
|
2313
|
-
role,
|
|
2314
|
-
markers: [
|
|
2315
|
-
{
|
|
2316
|
-
marker: marker.marker,
|
|
2317
|
-
actions: [
|
|
2318
|
-
{
|
|
2319
|
-
action: context.request.action,
|
|
2320
|
-
grantingPolicy: actionPermission.policy,
|
|
2321
|
-
grantingPermission: actionPermission.permission,
|
|
2322
|
-
},
|
|
2323
|
-
],
|
|
2324
|
-
},
|
|
2325
|
-
],
|
|
2326
|
-
},
|
|
2327
|
-
};
|
|
2328
|
-
}
|
|
2329
|
-
return {
|
|
2330
|
-
success: false,
|
|
2331
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2332
|
-
type: 'missing_role',
|
|
2333
|
-
},
|
|
2334
|
-
};
|
|
2335
|
-
});
|
|
2336
|
-
}
|
|
2337
|
-
_authorizeRoleRevokeRequest(context, request) {
|
|
2338
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2339
|
-
return yield this._authorizeRequest(context, request, [ACCOUNT_MARKER], (context, type, id) => {
|
|
2340
|
-
return this._authorizeRoleRevoke(context, type, id);
|
|
2341
|
-
}, false);
|
|
2342
|
-
});
|
|
2343
|
-
}
|
|
2344
|
-
_authorizeRoleRevoke(context, type, id) {
|
|
2345
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2346
|
-
let role = null;
|
|
2347
|
-
let denialReason;
|
|
2348
|
-
for (let marker of context.markers) {
|
|
2349
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byRoleRevoke('role.revoke', context.request.role, context.request.targetUserId, context.request.targetInstance), role === null
|
|
2350
|
-
? this._some(this._byEveryoneRole(), this._bySubjectRole(context, type, context.recordName, id), this._byRecordOwner(context, type, id), this._byStudioRole(context, type, id, 'admin'))
|
|
2351
|
-
: this._byRole(role)));
|
|
2352
|
-
if (!actionPermission) {
|
|
2353
|
-
denialReason = {
|
|
2354
|
-
type: 'missing_permission',
|
|
2355
|
-
kind: type,
|
|
2356
|
-
id,
|
|
2357
|
-
marker: marker.marker,
|
|
2358
|
-
permission: 'role.revoke',
|
|
2359
|
-
role,
|
|
2360
|
-
};
|
|
2361
|
-
continue;
|
|
2362
|
-
}
|
|
2363
|
-
if (role === null) {
|
|
2364
|
-
role = actionPermission.permission.role;
|
|
2365
|
-
}
|
|
2366
|
-
return {
|
|
2367
|
-
success: true,
|
|
2368
|
-
authorization: {
|
|
2369
|
-
role,
|
|
2370
|
-
markers: [
|
|
2371
|
-
{
|
|
2372
|
-
marker: marker.marker,
|
|
2373
|
-
actions: [
|
|
2374
|
-
{
|
|
2375
|
-
action: context.request.action,
|
|
2376
|
-
grantingPolicy: actionPermission.policy,
|
|
2377
|
-
grantingPermission: actionPermission.permission,
|
|
2378
|
-
},
|
|
2379
|
-
],
|
|
2380
|
-
},
|
|
2381
|
-
],
|
|
2382
|
-
},
|
|
2383
|
-
};
|
|
2384
|
-
}
|
|
2385
|
-
return {
|
|
2386
|
-
success: false,
|
|
2387
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2388
|
-
type: 'missing_role',
|
|
2389
|
-
},
|
|
2390
|
-
};
|
|
2391
|
-
});
|
|
2392
|
-
}
|
|
2393
|
-
_authorizeInstCreateRequest(context, request) {
|
|
2394
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2395
|
-
return this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
2396
|
-
return this._authorizeCreateInst(context, type, id);
|
|
2397
|
-
});
|
|
2398
|
-
});
|
|
2399
|
-
}
|
|
2400
|
-
/**
|
|
2401
|
-
* Authorizes the given subject for inst.create requests.
|
|
2402
|
-
*
|
|
2403
|
-
* @param context The context for the authorization.
|
|
2404
|
-
* @param subjectType The type of subject that is being authorized.
|
|
2405
|
-
* @param id The ID of the subject.
|
|
2406
|
-
* @returns The authorization that approves the subject for the request. Null if the subject is not authorized.
|
|
2407
|
-
*/
|
|
2408
|
-
_authorizeCreateInst(context, subjectType, id) {
|
|
2409
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2410
|
-
const authorizations = [];
|
|
2411
|
-
let role = null;
|
|
2412
|
-
for (let marker of context.markers) {
|
|
2413
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byInst('inst.create', context.request.inst), role === null
|
|
2414
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, subjectType, id), this._bySubjectRole(context, subjectType, context.recordName, id))
|
|
2415
|
-
: this._byRole(role)));
|
|
2416
|
-
if (!actionPermission) {
|
|
2417
|
-
return {
|
|
2418
|
-
success: false,
|
|
2419
|
-
reason: {
|
|
2420
|
-
type: 'missing_permission',
|
|
2421
|
-
kind: subjectType,
|
|
2422
|
-
id,
|
|
2423
|
-
marker: marker.marker,
|
|
2424
|
-
permission: 'inst.create',
|
|
2425
|
-
role,
|
|
2426
|
-
},
|
|
2427
|
-
};
|
|
2428
|
-
}
|
|
2429
|
-
if (role === null) {
|
|
2430
|
-
role = actionPermission.permission.role;
|
|
2431
|
-
}
|
|
2432
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.assign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
2433
|
-
if (!policyPermission) {
|
|
2434
|
-
return {
|
|
2435
|
-
success: false,
|
|
2436
|
-
reason: {
|
|
2437
|
-
type: 'missing_permission',
|
|
2438
|
-
kind: subjectType,
|
|
2439
|
-
id,
|
|
2440
|
-
marker: marker.marker,
|
|
2441
|
-
permission: 'policy.assign',
|
|
2442
|
-
role,
|
|
2443
|
-
},
|
|
2444
|
-
};
|
|
2445
|
-
}
|
|
2446
|
-
authorizations.push({
|
|
2447
|
-
marker: marker.marker,
|
|
2448
|
-
actions: [
|
|
2449
|
-
{
|
|
2450
|
-
action: context.request.action,
|
|
2451
|
-
grantingPolicy: actionPermission.policy,
|
|
2452
|
-
grantingPermission: actionPermission.permission,
|
|
2453
|
-
},
|
|
2454
|
-
{
|
|
2455
|
-
action: 'policy.assign',
|
|
2456
|
-
grantingPolicy: policyPermission.policy,
|
|
2457
|
-
grantingPermission: policyPermission.permission,
|
|
2458
|
-
},
|
|
2459
|
-
],
|
|
2460
|
-
});
|
|
2461
|
-
}
|
|
2462
|
-
if (!role) {
|
|
2463
|
-
return {
|
|
2464
|
-
success: false,
|
|
2465
|
-
reason: {
|
|
2466
|
-
type: 'missing_role',
|
|
2467
|
-
},
|
|
2468
|
-
};
|
|
2469
|
-
}
|
|
2470
|
-
return {
|
|
2471
|
-
success: true,
|
|
2472
|
-
authorization: {
|
|
2473
|
-
role,
|
|
2474
|
-
markers: authorizations,
|
|
2475
|
-
},
|
|
2476
|
-
};
|
|
2477
|
-
});
|
|
2478
|
-
}
|
|
2479
|
-
_authorizeInstReadRequest(context, request) {
|
|
2480
|
-
return this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
2481
|
-
return this._authorizeInstRead(context, type, id);
|
|
2482
|
-
});
|
|
2483
|
-
}
|
|
2484
|
-
_authorizeInstRead(context, type, id) {
|
|
2485
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2486
|
-
let role = null;
|
|
2487
|
-
let denialReason;
|
|
2488
|
-
for (let marker of context.markers) {
|
|
2489
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byInst('inst.read', context.request.inst), role === null
|
|
2490
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
2491
|
-
: this._byRole(role)));
|
|
2492
|
-
if (!actionPermission) {
|
|
2493
|
-
denialReason = {
|
|
2494
|
-
type: 'missing_permission',
|
|
2495
|
-
kind: type,
|
|
2496
|
-
id,
|
|
2497
|
-
marker: marker.marker,
|
|
2498
|
-
permission: 'inst.read',
|
|
2499
|
-
role,
|
|
2500
|
-
};
|
|
2501
|
-
continue;
|
|
2502
|
-
}
|
|
2503
|
-
if (role === null) {
|
|
2504
|
-
role = actionPermission.permission.role;
|
|
2505
|
-
}
|
|
2506
|
-
return {
|
|
2507
|
-
success: true,
|
|
2508
|
-
authorization: {
|
|
2509
|
-
role,
|
|
2510
|
-
markers: [
|
|
2511
|
-
{
|
|
2512
|
-
marker: marker.marker,
|
|
2513
|
-
actions: [
|
|
2514
|
-
{
|
|
2515
|
-
action: context.request.action,
|
|
2516
|
-
grantingPolicy: actionPermission.policy,
|
|
2517
|
-
grantingPermission: actionPermission.permission,
|
|
2518
|
-
},
|
|
2519
|
-
],
|
|
2520
|
-
},
|
|
2521
|
-
],
|
|
2522
|
-
},
|
|
2523
|
-
};
|
|
2524
|
-
}
|
|
2525
|
-
return {
|
|
2526
|
-
success: false,
|
|
2527
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2528
|
-
type: 'missing_role',
|
|
2529
|
-
},
|
|
2530
|
-
};
|
|
2531
|
-
});
|
|
2532
|
-
}
|
|
2533
|
-
_authorizeInstUpdateRequest(context, request) {
|
|
2534
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2535
|
-
if (!willMarkersBeRemaining(request.existingMarkers, request.removedMarkers, request.addedMarkers)) {
|
|
2536
|
-
return Object.assign(Object.assign({}, NOT_AUTHORIZED_RESULT), { reason: {
|
|
2537
|
-
type: 'no_markers_remaining',
|
|
2538
|
-
} });
|
|
2539
|
-
}
|
|
2540
|
-
return this._authorizeRequest(context, request, union(request.existingMarkers, request.addedMarkers, request.removedMarkers), (context, type, id) => {
|
|
2541
|
-
return this._authorizeInstUpdate(context, type, id);
|
|
2542
|
-
});
|
|
2543
|
-
});
|
|
2544
|
-
}
|
|
2545
|
-
_authorizeInstUpdate(context, type, id) {
|
|
2546
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2547
|
-
let authorizations = [];
|
|
2548
|
-
let role = null;
|
|
2549
|
-
// The denial reason for if the user does not have permission from an existing marker.
|
|
2550
|
-
let denialReason;
|
|
2551
|
-
let hasPermissionFromExistingMarker = false;
|
|
2552
|
-
for (let marker of context.markers) {
|
|
2553
|
-
const isAddedMarker = context.request.addedMarkers &&
|
|
2554
|
-
context.request.addedMarkers.includes(marker.marker);
|
|
2555
|
-
const isRemovedMarker = context.request.removedMarkers &&
|
|
2556
|
-
context.request.removedMarkers.includes(marker.marker);
|
|
2557
|
-
const isExistingMarker = context.request.existingMarkers.includes(marker.marker);
|
|
2558
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byInst('inst.update', context.request.inst), role === null
|
|
2559
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
2560
|
-
: this._byRole(role)));
|
|
2561
|
-
if (!actionPermission) {
|
|
2562
|
-
if (isAddedMarker || isRemovedMarker) {
|
|
2563
|
-
// Deny because the user needs permission for all new & removed markers.
|
|
2564
|
-
return {
|
|
2565
|
-
success: false,
|
|
2566
|
-
reason: {
|
|
2567
|
-
type: 'missing_permission',
|
|
2568
|
-
kind: type,
|
|
2569
|
-
id,
|
|
2570
|
-
marker: marker.marker,
|
|
2571
|
-
permission: 'inst.update',
|
|
2572
|
-
role,
|
|
2573
|
-
},
|
|
2574
|
-
};
|
|
2575
|
-
}
|
|
2576
|
-
else {
|
|
2577
|
-
// Record that the user does not have permission from this marker.
|
|
2578
|
-
// May or may not be used depending on if a different existing marker
|
|
2579
|
-
// provides permission.
|
|
2580
|
-
denialReason = {
|
|
2581
|
-
type: 'missing_permission',
|
|
2582
|
-
kind: type,
|
|
2583
|
-
id,
|
|
2584
|
-
marker: marker.marker,
|
|
2585
|
-
permission: 'inst.update',
|
|
2586
|
-
role,
|
|
2587
|
-
};
|
|
2588
|
-
continue;
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
|
-
if (isExistingMarker) {
|
|
2592
|
-
hasPermissionFromExistingMarker = true;
|
|
2593
|
-
}
|
|
2594
|
-
if (role === null) {
|
|
2595
|
-
role = actionPermission.permission.role;
|
|
2596
|
-
}
|
|
2597
|
-
const actions = [
|
|
2598
|
-
{
|
|
2599
|
-
action: context.request.action,
|
|
2600
|
-
grantingPolicy: actionPermission.policy,
|
|
2601
|
-
grantingPermission: actionPermission.permission,
|
|
2602
|
-
},
|
|
2603
|
-
];
|
|
2604
|
-
if (isAddedMarker) {
|
|
2605
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.assign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
2606
|
-
if (!policyPermission) {
|
|
2607
|
-
return {
|
|
2608
|
-
success: false,
|
|
2609
|
-
reason: {
|
|
2610
|
-
type: 'missing_permission',
|
|
2611
|
-
kind: type,
|
|
2612
|
-
id,
|
|
2613
|
-
marker: marker.marker,
|
|
2614
|
-
permission: 'policy.assign',
|
|
2615
|
-
role,
|
|
2616
|
-
},
|
|
2617
|
-
};
|
|
2618
|
-
continue;
|
|
2619
|
-
}
|
|
2620
|
-
actions.push({
|
|
2621
|
-
action: 'policy.assign',
|
|
2622
|
-
grantingPolicy: policyPermission.policy,
|
|
2623
|
-
grantingPermission: policyPermission.permission,
|
|
2624
|
-
});
|
|
2625
|
-
}
|
|
2626
|
-
else if (isRemovedMarker) {
|
|
2627
|
-
const policyPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byPolicy('policy.unassign', marker.marker), this._some(this._byEveryoneRole(), this._byRole(actionPermission.permission.role))));
|
|
2628
|
-
if (!policyPermission) {
|
|
2629
|
-
return {
|
|
2630
|
-
success: false,
|
|
2631
|
-
reason: {
|
|
2632
|
-
type: 'missing_permission',
|
|
2633
|
-
kind: type,
|
|
2634
|
-
id,
|
|
2635
|
-
marker: marker.marker,
|
|
2636
|
-
permission: 'policy.unassign',
|
|
2637
|
-
role,
|
|
2638
|
-
},
|
|
2639
|
-
};
|
|
2640
|
-
}
|
|
2641
|
-
actions.push({
|
|
2642
|
-
action: 'policy.unassign',
|
|
2643
|
-
grantingPolicy: policyPermission.policy,
|
|
2644
|
-
grantingPermission: policyPermission.permission,
|
|
2645
|
-
});
|
|
2646
|
-
}
|
|
2647
|
-
authorizations.push({
|
|
2648
|
-
marker: marker.marker,
|
|
2649
|
-
actions,
|
|
2650
|
-
});
|
|
2651
|
-
}
|
|
2652
|
-
// Deny the request if the user does not have permission from at least one existing marker.
|
|
2653
|
-
if (!hasPermissionFromExistingMarker && denialReason) {
|
|
2654
|
-
return {
|
|
2655
|
-
success: false,
|
|
2656
|
-
reason: denialReason,
|
|
2657
|
-
};
|
|
2658
|
-
}
|
|
2659
|
-
if (!role) {
|
|
2660
|
-
return {
|
|
2661
|
-
success: false,
|
|
2662
|
-
reason: {
|
|
2663
|
-
type: 'missing_role',
|
|
2664
|
-
},
|
|
2665
|
-
};
|
|
2666
|
-
}
|
|
2667
|
-
return {
|
|
2668
|
-
success: true,
|
|
2669
|
-
authorization: {
|
|
2670
|
-
role,
|
|
2671
|
-
markers: authorizations,
|
|
2672
|
-
},
|
|
2673
|
-
};
|
|
2674
|
-
});
|
|
2675
|
-
}
|
|
2676
|
-
_authorizeInstUpdateDataRequest(context, request) {
|
|
2677
|
-
return this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
2678
|
-
return this._authorizeInstUpdateData(context, type, id);
|
|
2679
|
-
});
|
|
2680
|
-
}
|
|
2681
|
-
_authorizeInstUpdateData(context, type, id) {
|
|
2682
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2683
|
-
let role = null;
|
|
2684
|
-
let denialReason;
|
|
2685
|
-
for (let marker of context.markers) {
|
|
2686
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byInst('inst.updateData', context.request.inst), role === null
|
|
2687
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
2688
|
-
: this._byRole(role)));
|
|
2689
|
-
if (!actionPermission) {
|
|
2690
|
-
denialReason = {
|
|
2691
|
-
type: 'missing_permission',
|
|
2692
|
-
kind: type,
|
|
2693
|
-
id,
|
|
2694
|
-
marker: marker.marker,
|
|
2695
|
-
permission: 'inst.updateData',
|
|
2696
|
-
role,
|
|
2697
|
-
};
|
|
2698
|
-
continue;
|
|
2699
|
-
}
|
|
2700
|
-
if (role === null) {
|
|
2701
|
-
role = actionPermission.permission.role;
|
|
2702
|
-
}
|
|
2703
|
-
return {
|
|
2704
|
-
success: true,
|
|
2705
|
-
authorization: {
|
|
2706
|
-
role,
|
|
2707
|
-
markers: [
|
|
2708
|
-
{
|
|
2709
|
-
marker: marker.marker,
|
|
2710
|
-
actions: [
|
|
2711
|
-
{
|
|
2712
|
-
action: context.request.action,
|
|
2713
|
-
grantingPolicy: actionPermission.policy,
|
|
2714
|
-
grantingPermission: actionPermission.permission,
|
|
2715
|
-
},
|
|
2716
|
-
],
|
|
2717
|
-
},
|
|
2718
|
-
],
|
|
2719
|
-
},
|
|
2720
|
-
};
|
|
2721
|
-
}
|
|
2722
|
-
return {
|
|
2723
|
-
success: false,
|
|
2724
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2725
|
-
type: 'missing_role',
|
|
2726
|
-
},
|
|
2727
|
-
};
|
|
2728
|
-
});
|
|
2729
|
-
}
|
|
2730
|
-
_authorizeInstDeleteRequest(context, request) {
|
|
2731
|
-
return this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
2732
|
-
return this._authorizeInstDelete(context, type, id);
|
|
2733
|
-
});
|
|
2734
|
-
}
|
|
2735
|
-
_authorizeInstDelete(context, type, id) {
|
|
2736
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2737
|
-
let role = null;
|
|
2738
|
-
let denialReason;
|
|
2739
|
-
for (let marker of context.markers) {
|
|
2740
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byInst('inst.delete', context.request.inst), role === null
|
|
2741
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
2742
|
-
: this._byRole(role)));
|
|
2743
|
-
if (!actionPermission) {
|
|
2744
|
-
denialReason = {
|
|
2745
|
-
type: 'missing_permission',
|
|
2746
|
-
kind: type,
|
|
2747
|
-
id,
|
|
2748
|
-
marker: marker.marker,
|
|
2749
|
-
permission: 'inst.delete',
|
|
2750
|
-
role,
|
|
2751
|
-
};
|
|
2752
|
-
continue;
|
|
2753
|
-
}
|
|
2754
|
-
if (role === null) {
|
|
2755
|
-
role = actionPermission.permission.role;
|
|
2756
|
-
}
|
|
2757
|
-
return {
|
|
2758
|
-
success: true,
|
|
2759
|
-
authorization: {
|
|
2760
|
-
role,
|
|
2761
|
-
markers: [
|
|
2762
|
-
{
|
|
2763
|
-
marker: marker.marker,
|
|
2764
|
-
actions: [
|
|
2765
|
-
{
|
|
2766
|
-
action: context.request.action,
|
|
2767
|
-
grantingPolicy: actionPermission.policy,
|
|
2768
|
-
grantingPermission: actionPermission.permission,
|
|
2769
|
-
},
|
|
2770
|
-
],
|
|
2771
|
-
},
|
|
2772
|
-
],
|
|
2773
|
-
},
|
|
2774
|
-
};
|
|
2775
|
-
}
|
|
2776
|
-
return {
|
|
2777
|
-
success: false,
|
|
2778
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2779
|
-
type: 'missing_role',
|
|
2780
|
-
},
|
|
2781
|
-
};
|
|
2782
|
-
});
|
|
2783
|
-
}
|
|
2784
|
-
_authorizeInstListRequest(context, request) {
|
|
2785
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2786
|
-
const allMarkers = union(...request.insts.map((i) => i.markers));
|
|
2787
|
-
return yield this._authorizeRequest(context, request, allMarkers, (context, type, id) => {
|
|
2788
|
-
return this._authorizeInstList(context, type, id);
|
|
2789
|
-
}, undefined, true);
|
|
2790
|
-
});
|
|
2791
|
-
}
|
|
2792
|
-
_authorizeInstList(context, type, id) {
|
|
2793
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2794
|
-
const authorizations = [];
|
|
2795
|
-
let role = null;
|
|
2796
|
-
const allowedInstItems = (context.allowedInstItems =
|
|
2797
|
-
[]);
|
|
2798
|
-
const markers = new Map();
|
|
2799
|
-
for (let marker of context.markers) {
|
|
2800
|
-
const authorization = {
|
|
2801
|
-
marker: marker.marker,
|
|
2802
|
-
actions: [],
|
|
2803
|
-
};
|
|
2804
|
-
authorizations.push(authorization);
|
|
2805
|
-
markers.set(marker.marker, {
|
|
2806
|
-
marker,
|
|
2807
|
-
authorization: authorization,
|
|
2808
|
-
usedPermissions: new Set(),
|
|
2809
|
-
});
|
|
2810
|
-
}
|
|
2811
|
-
for (let item of context.request.insts) {
|
|
2812
|
-
let itemPermission;
|
|
2813
|
-
for (let m of item.markers) {
|
|
2814
|
-
const a = markers.get(m);
|
|
2815
|
-
if (!a) {
|
|
2816
|
-
continue;
|
|
2817
|
-
}
|
|
2818
|
-
const { marker, authorization, usedPermissions } = a;
|
|
2819
|
-
itemPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byInst('inst.list', item.inst), role === null
|
|
2820
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
2821
|
-
: this._byRole(role)));
|
|
2822
|
-
if (!itemPermission) {
|
|
2823
|
-
continue;
|
|
2824
|
-
}
|
|
2825
|
-
if (role === null) {
|
|
2826
|
-
role = itemPermission.permission.role;
|
|
2827
|
-
}
|
|
2828
|
-
if (!usedPermissions.has(itemPermission.permission)) {
|
|
2829
|
-
usedPermissions.add(itemPermission.permission);
|
|
2830
|
-
authorization.actions.push({
|
|
2831
|
-
action: context.request.action,
|
|
2832
|
-
grantingPolicy: itemPermission.policy,
|
|
2833
|
-
grantingPermission: itemPermission.permission,
|
|
2834
|
-
});
|
|
2835
|
-
}
|
|
2836
|
-
if (itemPermission) {
|
|
2837
|
-
break;
|
|
2838
|
-
}
|
|
2839
|
-
}
|
|
2840
|
-
if (itemPermission) {
|
|
2841
|
-
allowedInstItems.push(item);
|
|
2842
|
-
}
|
|
2843
|
-
}
|
|
2844
|
-
if (!role) {
|
|
2845
|
-
role = true;
|
|
2846
|
-
}
|
|
2847
|
-
return {
|
|
2848
|
-
success: true,
|
|
2849
|
-
authorization: {
|
|
2850
|
-
role,
|
|
2851
|
-
markers: authorizations,
|
|
2852
|
-
},
|
|
2853
|
-
};
|
|
2854
|
-
});
|
|
2855
|
-
}
|
|
2856
|
-
_authorizeInstSendActionRequest(context, request) {
|
|
2857
|
-
return this._authorizeRequest(context, request, request.resourceMarkers, (context, type, id) => {
|
|
2858
|
-
return this._authorizeInstSendAction(context, type, id);
|
|
2859
|
-
});
|
|
2860
|
-
}
|
|
2861
|
-
_authorizeInstSendAction(context, type, id) {
|
|
2862
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2863
|
-
let role = null;
|
|
2864
|
-
let denialReason;
|
|
2865
|
-
for (let marker of context.markers) {
|
|
2866
|
-
const actionPermission = yield this._findPermissionByFilter(marker.permissions, this._every(this._byInst('inst.sendAction', context.request.inst), role === null
|
|
2867
|
-
? this._some(this._byEveryoneRole(), this._byAdminRole(context, type, id), this._bySubjectRole(context, type, context.recordName, id))
|
|
2868
|
-
: this._byRole(role)));
|
|
2869
|
-
if (!actionPermission) {
|
|
2870
|
-
denialReason = {
|
|
2871
|
-
type: 'missing_permission',
|
|
2872
|
-
kind: type,
|
|
2873
|
-
id,
|
|
2874
|
-
marker: marker.marker,
|
|
2875
|
-
permission: 'inst.sendAction',
|
|
2876
|
-
role,
|
|
2877
|
-
};
|
|
2878
|
-
continue;
|
|
2879
|
-
}
|
|
2880
|
-
if (role === null) {
|
|
2881
|
-
role = actionPermission.permission.role;
|
|
2882
|
-
}
|
|
2883
|
-
return {
|
|
2884
|
-
success: true,
|
|
2885
|
-
authorization: {
|
|
2886
|
-
role,
|
|
2887
|
-
markers: [
|
|
2888
|
-
{
|
|
2889
|
-
marker: marker.marker,
|
|
2890
|
-
actions: [
|
|
2891
|
-
{
|
|
2892
|
-
action: context.request.action,
|
|
2893
|
-
grantingPolicy: actionPermission.policy,
|
|
2894
|
-
grantingPermission: actionPermission.permission,
|
|
2895
|
-
},
|
|
2896
|
-
],
|
|
2897
|
-
},
|
|
2898
|
-
],
|
|
2899
|
-
},
|
|
2900
|
-
};
|
|
2901
|
-
}
|
|
2902
|
-
return {
|
|
2903
|
-
success: false,
|
|
2904
|
-
reason: denialReason !== null && denialReason !== void 0 ? denialReason : {
|
|
2905
|
-
type: 'missing_role',
|
|
2906
|
-
},
|
|
2907
|
-
};
|
|
2908
|
-
});
|
|
2909
|
-
}
|
|
2910
|
-
/**
|
|
2911
|
-
* Attempts to authorize the given request based on common request properties.
|
|
2912
|
-
*
|
|
2913
|
-
* Evaluates the recordKey, userId, and instances with the given resource markers and authorize function.
|
|
2914
|
-
* The given authorize function will be called with the User ID, and each inst and should return the authorization that should be used for each case.
|
|
2915
|
-
* If it returns null, then the request is not authorized and will be rejected as such.
|
|
2916
|
-
*
|
|
2917
|
-
* @param context The context for the request.
|
|
2918
|
-
* @param request The request that should be authorized.
|
|
2919
|
-
* @param resourceMarkers The list of markers that need to be validated.
|
|
2920
|
-
* @param authorize The function that should be used to authorize each subject in the request.
|
|
2921
|
-
* @param skipInstanceChecksWhenValidRecordKeyIsProvided Whether or not to skip instance checks when a valid record key is provided.
|
|
2922
|
-
* @param isListOperation Whether the request is a list operation.
|
|
2923
|
-
*/
|
|
2924
|
-
_authorizeRequest(context, request, resourceMarkers, authorize, skipInstanceChecksWhenValidRecordKeyIsProvided = true, isListOperation = false) {
|
|
2925
|
-
var _a, _b;
|
|
2926
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2927
|
-
if (request.instances &&
|
|
2928
|
-
request.instances.length > MAX_ALLOWED_INSTANCES) {
|
|
2929
|
-
console.log(`[PolicyController] [action: ${request.action} recordName: ${context.recordName}, userId: ${request.userId}] Request denied because too many instances were provided.`);
|
|
2930
|
-
// More than 2 instances should be auto-denied.
|
|
2931
|
-
// This is a "not_authorized" error instead of an "unacceptable_request" because
|
|
2932
|
-
// we want integrators to understand that this is an authentication issue, and not a configuration issue.
|
|
2933
|
-
// If more than 2 instances are loaded, we always want those passed to the controller, even if having more than 2 fails authentication.
|
|
2934
|
-
return NOT_AUTHORIZED_TO_MANY_INSTANCES_RESULT;
|
|
2935
|
-
}
|
|
2936
|
-
if (resourceMarkers.length <= 0 && !isListOperation) {
|
|
2937
|
-
console.log(`[PolicyController] [action: ${request.action} recordName: ${context.recordName}, userId: ${request.userId}] Request denied because there are no markers.`);
|
|
2938
|
-
return Object.assign(Object.assign({}, NOT_AUTHORIZED_RESULT), { reason: {
|
|
2939
|
-
type: 'no_markers',
|
|
2940
|
-
} });
|
|
2941
|
-
}
|
|
2942
|
-
const markers = yield this._listPermissionsForMarkers(context.recordName, request.userId, resourceMarkers);
|
|
2943
|
-
const rolesContext = Object.assign(Object.assign({}, context), { userRoles: null, instRoles: {}, markers,
|
|
2944
|
-
request });
|
|
2945
|
-
const userAuthorization = yield authorize(rolesContext, 'user', request.userId);
|
|
2946
|
-
if (userAuthorization.success === false) {
|
|
2947
|
-
if (!request.userId && !context.recordKeyProvided) {
|
|
2948
|
-
console.log(`[PolicyController] [action: ${request.action} recordName: ${context.recordName}] Request denied because the user is not signed in.`);
|
|
2949
|
-
return {
|
|
2950
|
-
allowed: false,
|
|
2951
|
-
errorCode: 'not_logged_in',
|
|
2952
|
-
errorMessage: 'The user must be logged in. Please provide a sessionKey or a recordKey.',
|
|
2953
|
-
};
|
|
2954
|
-
}
|
|
2955
|
-
console.log(`[PolicyController] [action: ${request.action} recordName: ${context.recordName}, userId: ${request.userId}] Request denied. Reason:`, userAuthorization.reason);
|
|
2956
|
-
return Object.assign(Object.assign({}, NOT_AUTHORIZED_RESULT), { reason: userAuthorization.reason });
|
|
2957
|
-
}
|
|
2958
|
-
const authorizedInstances = yield this._authorizeInstances(request.instances, context.recordKeyResult, (inst) => __awaiter(this, void 0, void 0, function* () {
|
|
2959
|
-
var _c, _d, _e, _f;
|
|
2960
|
-
let currentItems = (_c = rolesContext.allowedDataItems) === null || _c === void 0 ? void 0 : _c.slice();
|
|
2961
|
-
let currentFiles = (_d = rolesContext.allowedFileItems) === null || _d === void 0 ? void 0 : _d.slice();
|
|
2962
|
-
let currentEvents = (_e = rolesContext.allowedEventItems) === null || _e === void 0 ? void 0 : _e.slice();
|
|
2963
|
-
let currentInsts = (_f = rolesContext.allowedInstItems) === null || _f === void 0 ? void 0 : _f.slice();
|
|
2964
|
-
const result = yield authorize(rolesContext, 'inst', inst);
|
|
2965
|
-
if (currentItems) {
|
|
2966
|
-
rolesContext.allowedDataItems = intersectionBy(currentItems, rolesContext.allowedDataItems, (item) => item.address);
|
|
2967
|
-
}
|
|
2968
|
-
if (currentFiles) {
|
|
2969
|
-
rolesContext.allowedFileItems = intersectionBy(currentFiles, rolesContext.allowedFileItems, (item) => item.fileName);
|
|
2970
|
-
}
|
|
2971
|
-
if (currentEvents) {
|
|
2972
|
-
rolesContext.allowedEventItems = intersectionBy(currentEvents, rolesContext.allowedEventItems, (item) => item.eventName);
|
|
2973
|
-
}
|
|
2974
|
-
if (currentInsts) {
|
|
2975
|
-
rolesContext.allowedInstItems = intersectionBy(currentInsts, rolesContext.allowedInstItems, (item) => item.inst);
|
|
2976
|
-
}
|
|
2977
|
-
return result;
|
|
2978
|
-
}), skipInstanceChecksWhenValidRecordKeyIsProvided);
|
|
2979
|
-
if (!Array.isArray(authorizedInstances)) {
|
|
2980
|
-
console.log(`[PolicyController] [action: ${request.action} recordName: ${context.recordName}, userId: ${request.userId}] Request denied. Reason:`, authorizedInstances.reason);
|
|
2981
|
-
return Object.assign(Object.assign({}, NOT_AUTHORIZED_RESULT), { reason: authorizedInstances.reason });
|
|
2982
|
-
}
|
|
2983
|
-
const recordKeyOwnerId = ((_a = context.recordKeyResult) === null || _a === void 0 ? void 0 : _a.success)
|
|
2984
|
-
? context.recordKeyResult.keyCreatorId
|
|
2985
|
-
: null;
|
|
2986
|
-
const authorizerId = (_b = recordKeyOwnerId !== null && recordKeyOwnerId !== void 0 ? recordKeyOwnerId : request.userId) !== null && _b !== void 0 ? _b : null;
|
|
2987
|
-
console.log(`[PolicyController] [action: ${request.action} recordName: ${context.recordName}, userId: ${request.userId}] Request authorized.`);
|
|
2988
|
-
return {
|
|
2989
|
-
allowed: true,
|
|
2990
|
-
recordName: context.recordName,
|
|
2991
|
-
recordKeyOwnerId: recordKeyOwnerId,
|
|
2992
|
-
authorizerId: authorizerId,
|
|
2993
|
-
subject: Object.assign(Object.assign({}, userAuthorization.authorization), { userId: request.userId, subjectPolicy: context.subjectPolicy }),
|
|
2994
|
-
instances: authorizedInstances,
|
|
2995
|
-
allowedDataItems: rolesContext.allowedDataItems,
|
|
2996
|
-
allowedFileItems: rolesContext.allowedFileItems,
|
|
2997
|
-
allowedEventItems: rolesContext.allowedEventItems,
|
|
2998
|
-
allowedInstItems: rolesContext.allowedInstItems,
|
|
2999
|
-
};
|
|
3000
|
-
});
|
|
3001
|
-
}
|
|
3002
|
-
_authorizeInstances(instances, recordKeyResult, authorize, skipInstanceChecksWhenValidRecordKeyIsProvided) {
|
|
3003
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3004
|
-
const authorizedInstances = [];
|
|
3005
|
-
if (instances) {
|
|
3006
|
-
for (let inst of instances) {
|
|
3007
|
-
if (skipInstanceChecksWhenValidRecordKeyIsProvided &&
|
|
3008
|
-
(recordKeyResult === null || recordKeyResult === void 0 ? void 0 : recordKeyResult.success)) {
|
|
3009
|
-
authorizedInstances.push({
|
|
3010
|
-
authorizationType: 'not_required',
|
|
3011
|
-
inst,
|
|
3012
|
-
});
|
|
3013
|
-
continue;
|
|
3014
|
-
}
|
|
3015
|
-
const authorization = yield authorize(inst);
|
|
3016
|
-
if (authorization.success === false) {
|
|
3017
|
-
return authorization;
|
|
3018
|
-
}
|
|
3019
|
-
authorizedInstances.push(Object.assign({ inst, authorizationType: 'allowed' }, authorization.authorization));
|
|
3020
|
-
}
|
|
3021
|
-
}
|
|
3022
|
-
return authorizedInstances;
|
|
3023
|
-
});
|
|
3024
|
-
}
|
|
3025
|
-
_listPermissionsForMarkers(recordName, userId, resourceMarkers) {
|
|
3026
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3027
|
-
const promises = resourceMarkers.map((m) => __awaiter(this, void 0, void 0, function* () {
|
|
3028
|
-
const result = yield this._policies.listPoliciesForMarkerAndUser(recordName, userId, m);
|
|
3029
|
-
return {
|
|
3030
|
-
marker: m,
|
|
3031
|
-
result,
|
|
3032
|
-
};
|
|
3033
|
-
}));
|
|
3034
|
-
const markerPolicies = yield Promise.all(promises);
|
|
3035
|
-
const markers = filterAndMergeMarkerPermissions(markerPolicies);
|
|
3036
|
-
return markers;
|
|
3037
|
-
});
|
|
3038
|
-
}
|
|
3039
|
-
_every(...filters) {
|
|
3040
|
-
return (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
3041
|
-
for (let filter of filters) {
|
|
3042
|
-
if (!(yield filter(...args))) {
|
|
3043
|
-
return false;
|
|
3044
|
-
}
|
|
3045
|
-
}
|
|
3046
|
-
return true;
|
|
3047
|
-
});
|
|
3048
|
-
}
|
|
3049
|
-
_some(...filters) {
|
|
3050
|
-
return (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
3051
|
-
for (let filter of filters) {
|
|
3052
|
-
if (yield filter(...args)) {
|
|
3053
|
-
return true;
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
return false;
|
|
3057
|
-
});
|
|
3058
|
-
}
|
|
3059
|
-
_byType(type) {
|
|
3060
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3061
|
-
return permission.type === type;
|
|
3062
|
-
});
|
|
3063
|
-
}
|
|
3064
|
-
_byData(type, address) {
|
|
3065
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3066
|
-
if (permission.type !== type) {
|
|
3067
|
-
return false;
|
|
3068
|
-
}
|
|
3069
|
-
if (permission.addresses === true) {
|
|
3070
|
-
return true;
|
|
3071
|
-
}
|
|
3072
|
-
if (this._testRegex(permission.addresses, address)) {
|
|
3073
|
-
return true;
|
|
3074
|
-
}
|
|
3075
|
-
return false;
|
|
3076
|
-
});
|
|
3077
|
-
}
|
|
3078
|
-
_byFile(type, fileSizeInBytes, fileMimeType) {
|
|
3079
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3080
|
-
if (permission.type !== type) {
|
|
3081
|
-
return false;
|
|
3082
|
-
}
|
|
3083
|
-
if (typeof permission.maxFileSizeInBytes === 'number' &&
|
|
3084
|
-
fileSizeInBytes > permission.maxFileSizeInBytes) {
|
|
3085
|
-
return false;
|
|
3086
|
-
}
|
|
3087
|
-
if (typeof permission.allowedMimeTypes === 'object' &&
|
|
3088
|
-
Array.isArray(permission.allowedMimeTypes)) {
|
|
3089
|
-
if (!permission.allowedMimeTypes.includes(fileMimeType)) {
|
|
3090
|
-
return false;
|
|
3091
|
-
}
|
|
3092
|
-
}
|
|
3093
|
-
return true;
|
|
3094
|
-
});
|
|
3095
|
-
}
|
|
3096
|
-
_byEvent(type, eventName) {
|
|
3097
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3098
|
-
if (permission.type !== type) {
|
|
3099
|
-
return false;
|
|
3100
|
-
}
|
|
3101
|
-
if (permission.events === true) {
|
|
3102
|
-
return true;
|
|
3103
|
-
}
|
|
3104
|
-
if (this._testRegex(permission.events, eventName)) {
|
|
3105
|
-
return true;
|
|
3106
|
-
}
|
|
3107
|
-
return false;
|
|
3108
|
-
});
|
|
3109
|
-
}
|
|
3110
|
-
_byInst(type, inst) {
|
|
3111
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3112
|
-
if (permission.type !== type) {
|
|
3113
|
-
return false;
|
|
3114
|
-
}
|
|
3115
|
-
if (permission.insts === true) {
|
|
3116
|
-
return true;
|
|
3117
|
-
}
|
|
3118
|
-
if (this._testRegex(permission.insts, inst)) {
|
|
3119
|
-
return true;
|
|
3120
|
-
}
|
|
3121
|
-
return false;
|
|
3122
|
-
});
|
|
3123
|
-
}
|
|
3124
|
-
_byRecordOwner(context, subjectType, id) {
|
|
3125
|
-
if (subjectType === 'inst') {
|
|
3126
|
-
return () => __awaiter(this, void 0, void 0, function* () { return false; });
|
|
3127
|
-
}
|
|
3128
|
-
if (context.recordOwnerId === id) {
|
|
3129
|
-
return () => __awaiter(this, void 0, void 0, function* () { return true; });
|
|
3130
|
-
}
|
|
3131
|
-
return () => __awaiter(this, void 0, void 0, function* () { return false; });
|
|
3132
|
-
}
|
|
3133
|
-
_byStudioRole(context, subjectType, id, role) {
|
|
3134
|
-
if (subjectType === 'inst') {
|
|
3135
|
-
return () => __awaiter(this, void 0, void 0, function* () { return false; });
|
|
3136
|
-
}
|
|
3137
|
-
if (!context.recordStudioId ||
|
|
3138
|
-
!context.recordStudioMembers ||
|
|
3139
|
-
context.recordStudioMembers.length <= 0) {
|
|
3140
|
-
return () => __awaiter(this, void 0, void 0, function* () { return false; });
|
|
3141
|
-
}
|
|
3142
|
-
if (role) {
|
|
3143
|
-
return () => __awaiter(this, void 0, void 0, function* () {
|
|
3144
|
-
return context.recordStudioMembers.some((m) => m.userId === id && m.role === role);
|
|
3145
|
-
});
|
|
3146
|
-
}
|
|
3147
|
-
return () => __awaiter(this, void 0, void 0, function* () { return context.recordStudioMembers.some((m) => m.userId === id); });
|
|
3148
|
-
}
|
|
3149
|
-
_byEveryoneRole() {
|
|
3150
|
-
return this._byRole(true);
|
|
3151
|
-
}
|
|
3152
|
-
_byAdminRole(context, subjectType, id) {
|
|
3153
|
-
if (!!context.recordKeyResult && context.recordKeyResult.success) {
|
|
3154
|
-
return this._byRole(ADMIN_ROLE_NAME);
|
|
3155
|
-
}
|
|
3156
|
-
else if (context.recordStudioId) {
|
|
3157
|
-
return this._byStudioRole(context, subjectType, id);
|
|
3158
|
-
}
|
|
3159
|
-
else {
|
|
3160
|
-
return this._byRecordOwner(context, subjectType, id);
|
|
3161
|
-
}
|
|
3162
|
-
}
|
|
3163
|
-
_bySubjectRole(context, subjectType, recordName, id) {
|
|
3164
|
-
if (!id) {
|
|
3165
|
-
return () => __awaiter(this, void 0, void 0, function* () { return false; });
|
|
3166
|
-
}
|
|
3167
|
-
if (subjectType === 'user') {
|
|
3168
|
-
return this._byUserRole(context, recordName, id);
|
|
3169
|
-
}
|
|
3170
|
-
else {
|
|
3171
|
-
return this._byInstRole(context, recordName, id);
|
|
3172
|
-
}
|
|
3173
|
-
}
|
|
3174
|
-
_byUserRole(context, recordName, userId) {
|
|
3175
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3176
|
-
if (!context.userRoles) {
|
|
3177
|
-
const roles = yield this._policies.listRolesForUser(recordName, userId);
|
|
3178
|
-
context.userRoles = new Set(roles.map((r) => r.role));
|
|
3179
|
-
}
|
|
3180
|
-
return (typeof permission.role === 'string' &&
|
|
3181
|
-
context.userRoles.has(permission.role));
|
|
3182
|
-
});
|
|
3183
|
-
}
|
|
3184
|
-
_byInstRole(context, recordName, inst) {
|
|
3185
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3186
|
-
if (!context.instRoles[inst]) {
|
|
3187
|
-
const roles = yield this._policies.listRolesForInst(recordName, inst);
|
|
3188
|
-
context.instRoles[inst] = new Set(roles.map((r) => r.role));
|
|
3189
|
-
}
|
|
3190
|
-
return (typeof permission.role === 'string' &&
|
|
3191
|
-
context.instRoles[inst].has(permission.role));
|
|
3192
|
-
});
|
|
3193
|
-
}
|
|
3194
|
-
_byRole(role) {
|
|
3195
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3196
|
-
if (permission.role === role) {
|
|
3197
|
-
return true;
|
|
3198
|
-
}
|
|
3199
|
-
return false;
|
|
3200
|
-
});
|
|
3201
|
-
}
|
|
3202
|
-
_byPolicy(type, marker) {
|
|
3203
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3204
|
-
if (permission.type !== type) {
|
|
3205
|
-
return false;
|
|
3206
|
-
}
|
|
3207
|
-
if (permission.policies === true) {
|
|
3208
|
-
return true;
|
|
3209
|
-
}
|
|
3210
|
-
if (this._testRegex(permission.policies, marker)) {
|
|
3211
|
-
return true;
|
|
3212
|
-
}
|
|
3213
|
-
return false;
|
|
3214
|
-
});
|
|
3215
|
-
}
|
|
3216
|
-
_byRolePermission(type, marker) {
|
|
3217
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3218
|
-
if (permission.type !== type) {
|
|
3219
|
-
return false;
|
|
3220
|
-
}
|
|
3221
|
-
if (permission.roles === true) {
|
|
3222
|
-
return true;
|
|
3223
|
-
}
|
|
3224
|
-
if (this._testRegex(permission.roles, marker)) {
|
|
3225
|
-
return true;
|
|
3226
|
-
}
|
|
3227
|
-
return false;
|
|
3228
|
-
});
|
|
3229
|
-
}
|
|
3230
|
-
_byRoleGrant(type, role, targetUserId, targetInstance, durationMs) {
|
|
3231
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3232
|
-
if (permission.type !== type) {
|
|
3233
|
-
return false;
|
|
3234
|
-
}
|
|
3235
|
-
if (typeof permission.maxDurationMs === 'number' &&
|
|
3236
|
-
durationMs > permission.maxDurationMs) {
|
|
3237
|
-
return false;
|
|
3238
|
-
}
|
|
3239
|
-
if (!!targetUserId && !!targetInstance) {
|
|
3240
|
-
return false;
|
|
3241
|
-
}
|
|
3242
|
-
else if (!!targetUserId) {
|
|
3243
|
-
if (permission.userIds === false) {
|
|
3244
|
-
return false;
|
|
3245
|
-
}
|
|
3246
|
-
if (typeof permission.userIds === 'object' &&
|
|
3247
|
-
Array.isArray(permission.userIds)) {
|
|
3248
|
-
if (permission.userIds.every((id) => id !== targetUserId)) {
|
|
3249
|
-
return false;
|
|
3250
|
-
}
|
|
3251
|
-
}
|
|
3252
|
-
}
|
|
3253
|
-
else if (!!targetInstance) {
|
|
3254
|
-
if (permission.instances === false) {
|
|
3255
|
-
return false;
|
|
3256
|
-
}
|
|
3257
|
-
if (typeof permission.instances === 'string' &&
|
|
3258
|
-
!this._testRegex(permission.instances, targetInstance)) {
|
|
3259
|
-
return false;
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
else {
|
|
3263
|
-
return false;
|
|
3264
|
-
}
|
|
3265
|
-
if (permission.roles === true) {
|
|
3266
|
-
return true;
|
|
3267
|
-
}
|
|
3268
|
-
if (this._testRegex(permission.roles, role)) {
|
|
3269
|
-
return true;
|
|
3270
|
-
}
|
|
3271
|
-
return false;
|
|
3272
|
-
});
|
|
3273
|
-
}
|
|
3274
|
-
_byRoleRevoke(type, role, targetUserId, targetInstance) {
|
|
3275
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3276
|
-
if (permission.type !== type) {
|
|
3277
|
-
return false;
|
|
3278
|
-
}
|
|
3279
|
-
if (!!targetUserId && !!targetInstance) {
|
|
3280
|
-
return false;
|
|
3281
|
-
}
|
|
3282
|
-
else if (!!targetUserId) {
|
|
3283
|
-
if (permission.userIds === false) {
|
|
3284
|
-
return false;
|
|
3285
|
-
}
|
|
3286
|
-
if (typeof permission.userIds === 'object' &&
|
|
3287
|
-
Array.isArray(permission.userIds)) {
|
|
3288
|
-
if (permission.userIds.every((id) => id !== targetUserId)) {
|
|
3289
|
-
return false;
|
|
3290
|
-
}
|
|
3291
|
-
}
|
|
3292
|
-
}
|
|
3293
|
-
else if (!!targetInstance) {
|
|
3294
|
-
if (permission.instances === false) {
|
|
3295
|
-
return false;
|
|
3296
|
-
}
|
|
3297
|
-
if (typeof permission.instances === 'string' &&
|
|
3298
|
-
!this._testRegex(permission.instances, targetInstance)) {
|
|
3299
|
-
return false;
|
|
3300
|
-
}
|
|
3301
|
-
}
|
|
3302
|
-
else {
|
|
3303
|
-
return false;
|
|
3304
|
-
}
|
|
3305
|
-
if (permission.roles === true) {
|
|
3306
|
-
return true;
|
|
3307
|
-
}
|
|
3308
|
-
if (this._testRegex(permission.roles, role)) {
|
|
3309
|
-
return true;
|
|
3310
|
-
}
|
|
3311
|
-
return false;
|
|
3312
|
-
});
|
|
3313
|
-
}
|
|
3314
|
-
_byPolicyList(type) {
|
|
3315
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3316
|
-
if (permission.type !== type) {
|
|
3317
|
-
return false;
|
|
3318
|
-
}
|
|
3319
|
-
if (permission.policies === true) {
|
|
3320
|
-
return true;
|
|
3321
|
-
}
|
|
3322
|
-
return false;
|
|
3323
|
-
});
|
|
3324
|
-
}
|
|
3325
|
-
_byRoleList(type) {
|
|
3326
|
-
return (permission) => __awaiter(this, void 0, void 0, function* () {
|
|
3327
|
-
if (permission.type !== type) {
|
|
3328
|
-
return false;
|
|
3329
|
-
}
|
|
3330
|
-
if (permission.roles === true) {
|
|
3331
|
-
return true;
|
|
3332
|
-
}
|
|
3333
|
-
return false;
|
|
3334
|
-
});
|
|
3335
|
-
}
|
|
3336
|
-
_testRegex(regex, value) {
|
|
3337
|
-
try {
|
|
3338
|
-
return new RegExp(regex).test(value);
|
|
3339
|
-
}
|
|
3340
|
-
catch (err) {
|
|
3341
|
-
return false;
|
|
3342
|
-
}
|
|
3343
|
-
}
|
|
3344
|
-
_findPermissionByFilter(permissions, filter) {
|
|
3345
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3346
|
-
for (let permission of permissions) {
|
|
3347
|
-
if (yield filter(permission.permission)) {
|
|
3348
|
-
return permission;
|
|
3349
|
-
}
|
|
3350
|
-
}
|
|
3351
|
-
return null;
|
|
3352
|
-
});
|
|
3353
|
-
}
|
|
3354
1675
|
}
|
|
3355
1676
|
/**
|
|
3356
1677
|
* Determines if any markers will be remaining after the removal and addition of the specified markers.
|
|
@@ -3373,84 +1694,25 @@ export function willMarkersBeRemaining(existingMarkers, removedMarkers, addedMar
|
|
|
3373
1694
|
}
|
|
3374
1695
|
return false;
|
|
3375
1696
|
}
|
|
3376
|
-
export function returnAuthorizationResult(a) {
|
|
3377
|
-
if (a.errorCode === 'action_not_supported') {
|
|
3378
|
-
return {
|
|
3379
|
-
success: false,
|
|
3380
|
-
errorCode: 'server_error',
|
|
3381
|
-
errorMessage: 'A server error occurred.',
|
|
3382
|
-
};
|
|
3383
|
-
}
|
|
3384
|
-
const { allowed } = a, rest = __rest(a, ["allowed"]);
|
|
3385
|
-
return Object.assign(Object.assign({ success: false }, rest), { errorCode: a.errorCode });
|
|
3386
|
-
}
|
|
3387
1697
|
/**
|
|
3388
|
-
*
|
|
3389
|
-
* the privacy settings of the record owner and the user.
|
|
3390
|
-
* @param markerPolicies The marker policies that should be merged.
|
|
1698
|
+
* Gets a simple human readable explaination for the given permission assignment.
|
|
3391
1699
|
*/
|
|
3392
|
-
export function
|
|
3393
|
-
const
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
}
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
// policy contains a permission that allows everyone to access the data, but the user should not be able to publish public data.
|
|
3410
|
-
// skip all the policies for this marker.
|
|
3411
|
-
valid = false;
|
|
3412
|
-
break;
|
|
3413
|
-
}
|
|
3414
|
-
}
|
|
3415
|
-
for (let permission of policy.permissions) {
|
|
3416
|
-
if (denyPublicInsts) {
|
|
3417
|
-
if (permission.type.startsWith('inst.')) {
|
|
3418
|
-
if (!instsValid) {
|
|
3419
|
-
// Skip all inst permissions if any inst permissions are invalid.
|
|
3420
|
-
continue;
|
|
3421
|
-
}
|
|
3422
|
-
else if (permission.role === true) {
|
|
3423
|
-
// Mark all insts permissions for this marker as invalid if public insts
|
|
3424
|
-
// are not allowed and this permission is public.
|
|
3425
|
-
instsValid = false;
|
|
3426
|
-
continue;
|
|
3427
|
-
}
|
|
3428
|
-
}
|
|
3429
|
-
}
|
|
3430
|
-
permissions.push({
|
|
3431
|
-
policy,
|
|
3432
|
-
permission,
|
|
3433
|
-
});
|
|
3434
|
-
}
|
|
3435
|
-
}
|
|
3436
|
-
}
|
|
3437
|
-
if (!instsValid) {
|
|
3438
|
-
// Filter out any inst permissions if insts are invalid
|
|
3439
|
-
permissions = permissions.filter((p) => !p.permission.type.startsWith('inst.'));
|
|
3440
|
-
}
|
|
3441
|
-
if (valid) {
|
|
3442
|
-
markers.push({
|
|
3443
|
-
marker,
|
|
3444
|
-
permissions,
|
|
3445
|
-
});
|
|
3446
|
-
}
|
|
3447
|
-
else {
|
|
3448
|
-
markers.push({
|
|
3449
|
-
marker,
|
|
3450
|
-
permissions: [],
|
|
3451
|
-
});
|
|
3452
|
-
}
|
|
3453
|
-
}
|
|
3454
|
-
return markers;
|
|
1700
|
+
export function explainationForPermissionAssignment(subjectType, permissionAssignment) {
|
|
1701
|
+
const subjectString = subjectType === 'user'
|
|
1702
|
+
? 'User'
|
|
1703
|
+
: subjectType === 'inst'
|
|
1704
|
+
? 'Inst'
|
|
1705
|
+
: 'Role';
|
|
1706
|
+
let permissionString;
|
|
1707
|
+
if ('marker' in permissionAssignment) {
|
|
1708
|
+
permissionString = `${subjectString} was granted access to marker "${permissionAssignment.marker}" by "${permissionAssignment.id}"`;
|
|
1709
|
+
}
|
|
1710
|
+
else {
|
|
1711
|
+
permissionString = `${subjectString} was granted access to resource "${permissionAssignment.resourceId}" by "${permissionAssignment.id}"`;
|
|
1712
|
+
}
|
|
1713
|
+
if (permissionAssignment.subjectType === 'role') {
|
|
1714
|
+
permissionString += ` using role "${permissionAssignment.subjectId}"`;
|
|
1715
|
+
}
|
|
1716
|
+
return permissionString;
|
|
3455
1717
|
}
|
|
3456
1718
|
//# sourceMappingURL=PolicyController.js.map
|