@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.
Files changed (46) hide show
  1. package/AIController.d.ts +7 -4
  2. package/AIController.js +11 -0
  3. package/AIController.js.map +1 -1
  4. package/AuthController.d.ts +2 -1
  5. package/AuthController.js +6 -3
  6. package/AuthController.js.map +1 -1
  7. package/AuthStore.d.ts +1 -21
  8. package/CachingPolicyStore.d.ts +16 -5
  9. package/CachingPolicyStore.js +66 -39
  10. package/CachingPolicyStore.js.map +1 -1
  11. package/DataRecordsController.d.ts +67 -5
  12. package/DataRecordsController.js +141 -78
  13. package/DataRecordsController.js.map +1 -1
  14. package/DataRecordsStore.d.ts +35 -1
  15. package/DataRecordsStore.js.map +1 -1
  16. package/EventRecordsController.d.ts +5 -5
  17. package/EventRecordsController.js +54 -35
  18. package/EventRecordsController.js.map +1 -1
  19. package/FileRecordsController.d.ts +6 -6
  20. package/FileRecordsController.js +142 -76
  21. package/FileRecordsController.js.map +1 -1
  22. package/MemoryStore.d.ts +28 -17
  23. package/MemoryStore.js +457 -110
  24. package/MemoryStore.js.map +1 -1
  25. package/PolicyController.d.ts +512 -677
  26. package/PolicyController.js +1196 -2934
  27. package/PolicyController.js.map +1 -1
  28. package/PolicyStore.d.ts +319 -90
  29. package/PolicyStore.js +125 -0
  30. package/PolicyStore.js.map +1 -1
  31. package/RecordsServer.d.ts +3 -4
  32. package/RecordsServer.js +88 -111
  33. package/RecordsServer.js.map +1 -1
  34. package/RecordsStore.d.ts +3 -0
  35. package/TestUtils.d.ts +1 -1
  36. package/TestUtils.js.map +1 -1
  37. package/Utils.d.ts +21 -3
  38. package/Utils.js +42 -3
  39. package/Utils.js.map +1 -1
  40. package/package.json +3 -3
  41. package/websockets/InstRecordsStore.d.ts +21 -0
  42. package/websockets/InstRecordsStore.js +43 -1
  43. package/websockets/InstRecordsStore.js.map +1 -1
  44. package/websockets/WebsocketController.d.ts +7 -7
  45. package/websockets/WebsocketController.js +153 -82
  46. package/websockets/WebsocketController.js.map +1 -1
@@ -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 { intersectionBy, isEqual, sortBy, union } from 'lodash';
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
- * A generic not_authorized result.
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
- export const NOT_AUTHORIZED_RESULT = {
37
- allowed: false,
38
- errorCode: 'not_authorized',
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
- * A not_authorized result that indicates too many instances were used.
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
- export const NOT_AUTHORIZED_TO_MANY_INSTANCES_RESULT = {
45
- allowed: false,
46
- errorCode: 'not_authorized',
47
- errorMessage: `This action is not authorized because more than ${MAX_ALLOWED_INSTANCES} instances are loaded.`,
48
- reason: {
49
- type: 'too_many_insts',
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 request.
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
- authorizeRequest(request) {
227
+ authorizeUserAndInstances(context, request) {
228
+ var _a;
127
229
  return __awaiter(this, void 0, void 0, function* () {
128
230
  try {
129
- const context = yield this.constructAuthorizationContext(request);
130
- if (context.success === false) {
131
- return {
132
- allowed: false,
133
- errorCode: context.errorCode,
134
- errorMessage: context.errorMessage,
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
- return yield this._authorizeRequestUsingContext(context.context, request);
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
- allowed: false,
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 request.
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
- authorizeRequestUsingContext(context, request) {
268
+ authorizeUserAndInstancesForResources(context, request) {
269
+ var _a;
156
270
  return __awaiter(this, void 0, void 0, function* () {
157
271
  try {
158
- return this._authorizeRequestUsingContext(context, request);
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
- allowed: false,
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 grant a permission to a marker.
172
- * @param request The request for the operation.
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
- grantMarkerPermission(request) {
400
+ authorizeSubjects(context, request) {
175
401
  return __awaiter(this, void 0, void 0, function* () {
176
402
  try {
177
- const baseRequest = {
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: policyResult.errorCode,
200
- errorMessage: policyResult.errorMessage,
406
+ errorCode: 'unacceptable_request',
407
+ errorMessage: 'You must provide at least one subject to authorize.',
201
408
  };
202
409
  }
203
- const policy = policyResult.success
204
- ? policyResult
205
- : {
206
- document: {
207
- permissions: [],
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 revoke a permission from a marker.
240
- * @param request The request for the operation.
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
- revokeMarkerPermission(request) {
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: context.errorCode,
254
- errorMessage: context.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 authorization = yield this.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'policy.revokePermission' }, baseRequest), { policy: request.marker, instances: request.instances }));
258
- if (authorization.allowed === false) {
259
- return returnAuthorizationResult(authorization);
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 policyResult = yield this._policies.getUserPolicy(context.context.recordName, request.marker);
262
- if (policyResult.success === false) {
263
- if (policyResult.errorCode === 'policy_not_found') {
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: true,
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: false,
271
- errorCode: policyResult.errorCode,
272
- errorMessage: policyResult.errorMessage,
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
- const policy = policyResult;
276
- let hasUpdate = false;
277
- for (let i = 0; i < policy.document.permissions.length; i++) {
278
- const p = policy.document.permissions[i];
279
- if (isEqual(p, request.permission)) {
280
- hasUpdate = true;
281
- policy.document.permissions.splice(i, 1);
282
- i--;
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 (hasUpdate) {
286
- console.log(`[PolicyController] Removing permission from policy for ${context.context.recordName} and ${request.marker}.`, request.permission);
287
- const updateResult = yield this._policies.updateUserPolicy(context.context.recordName, request.marker, {
288
- document: policy.document,
289
- markers: policy.markers,
290
- });
291
- if (updateResult.success === false) {
292
- console.log(`[PolicyController] Policy update failed:`, updateResult);
293
- return updateResult;
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: true,
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
- * Attempts to read the policy for a marker.
312
- * @param recordKeyOrRecordName The record key or record name.
313
- * @param userId The ID of the user that is currently logged in.
314
- * @param marker The marker.
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
- readUserPolicy(recordKeyOrRecordName, userId, marker, instances) {
900
+ listPermissions(recordKeyOrRecordName, userId, instances) {
318
901
  return __awaiter(this, void 0, void 0, function* () {
319
902
  try {
320
- const baseRequest = {
321
- recordKeyOrRecordName: recordKeyOrRecordName,
322
- userId: 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
- success: false,
328
- errorCode: context.errorCode,
329
- errorMessage: context.errorMessage,
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
- // Fetch the policy before authorizing because we will need to know which
333
- // markers are applied to the policy
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
- document: result.document,
345
- markers: result.markers,
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
- * Attempts to list the policies for a record.
360
- * @param recordKeyOrRecordName The record key or the name of the record.
361
- * @param userId The ID of the user that is currently logged in.
362
- * @param startingMarker The marker that policies should be returned after.
363
- * @param instances The instances that the request is being made from.
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
- listUserPolicies(recordKeyOrRecordName, userId, startingMarker, instances) {
969
+ listPermissionsForMarker(recordKeyOrRecordName, marker, userId, instances) {
366
970
  return __awaiter(this, void 0, void 0, function* () {
367
971
  try {
368
- const baseRequest = {
369
- recordKeyOrRecordName: recordKeyOrRecordName,
370
- userId: userId,
371
- };
372
- const context = yield this.constructAuthorizationContext(baseRequest);
972
+ marker = getRootMarker(marker);
973
+ const context = yield this.constructAuthorizationContext({
974
+ recordKeyOrRecordName,
975
+ userId,
976
+ });
373
977
  if (context.success === false) {
374
- return {
375
- success: false,
376
- errorCode: context.errorCode,
377
- errorMessage: context.errorMessage,
378
- };
379
- }
380
- const authorization = yield this.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'policy.list' }, baseRequest), { instances }));
381
- if (authorization.allowed === false) {
382
- return returnAuthorizationResult(authorization);
383
- }
384
- const result = yield this._policies.listUserPolicies(context.context.recordName, startingMarker);
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
- policies: result.policies,
391
- totalCount: result.totalCount,
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
- * Attempts to list the roles that are assigned to a user.
406
- * @param recordKeyOrRecordName The record key or the name of the record.
407
- * @param userId The ID of the user that is currently logged in.
408
- * @param subjectId The ID of the user whose roles should be listed.
409
- * @param instances The instances that the request is being made from.
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
- listUserRoles(recordKeyOrRecordName, userId, subjectId, instances) {
1026
+ listPermissionsForResource(recordKeyOrRecordName, resourceKind, resourceId, userId, instances) {
412
1027
  return __awaiter(this, void 0, void 0, function* () {
413
1028
  try {
414
- const baseRequest = {
415
- recordKeyOrRecordName: recordKeyOrRecordName,
416
- userId: userId,
417
- };
418
- const context = yield this.constructAuthorizationContext(baseRequest);
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.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'role.list' }, baseRequest), { instances }));
428
- if (authorization.allowed === false) {
429
- return returnAuthorizationResult(authorization);
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.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'role.list' }, baseRequest), { instances }));
471
- if (authorization.allowed === false) {
472
- return returnAuthorizationResult(authorization);
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.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'role.list' }, baseRequest), { instances }));
513
- if (authorization.allowed === false) {
514
- return returnAuthorizationResult(authorization);
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.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'role.list' }, baseRequest), { instances }));
562
- if (authorization.allowed === false) {
563
- return returnAuthorizationResult(authorization);
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.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'role.grant' }, baseRequest), { instances, role: request.role, targetUserId,
609
- targetInstance,
610
- expireTimeMs }));
611
- if (authorization.allowed === false) {
612
- return returnAuthorizationResult(authorization);
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.authorizeRequestUsingContext(context.context, Object.assign(Object.assign({ action: 'role.revoke' }, baseRequest), { instances, role: request.role, targetUserId,
680
- targetInstance }));
681
- if (authorization.allowed === false) {
682
- return returnAuthorizationResult(authorization);
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
- * Merges the permissions from the given marker policies and filters out any permissions that are not allowed according to
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 filterAndMergeMarkerPermissions(markerPolicies) {
3393
- const markers = [];
3394
- for (let { marker, result } of markerPolicies) {
3395
- let permissions = [];
3396
- let valid = true;
3397
- const denyPublicInsts = !result.recordOwnerPrivacyFeatures.allowPublicInsts ||
3398
- !result.userPrivacyFeatures.allowPublicInsts;
3399
- let instsValid = true;
3400
- if (!result.recordOwnerPrivacyFeatures.publishData ||
3401
- !result.userPrivacyFeatures.publishData) {
3402
- valid = false;
3403
- }
3404
- if (valid) {
3405
- for (let policy of result.policies) {
3406
- if (!result.recordOwnerPrivacyFeatures.allowPublicData ||
3407
- !result.userPrivacyFeatures.allowPublicData) {
3408
- if (policy.permissions.some((p) => p.role === true)) {
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