@casual-simulation/aux-records 3.4.6-alpha.14601027727 → 3.5.0-alpha.15117651144
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AIController.js +835 -890
- package/AIController.js.map +1 -1
- package/AIHumeInterface.js +43 -54
- package/AIHumeInterface.js.map +1 -1
- package/AIOpenAIRealtimeInterface.js +60 -71
- package/AIOpenAIRealtimeInterface.js.map +1 -1
- package/AnthropicAIChatInterface.js +96 -142
- package/AnthropicAIChatInterface.js.map +1 -1
- package/AuthController.d.ts +3 -2
- package/AuthController.js +1907 -1933
- package/AuthController.js.map +1 -1
- package/AuthStore.d.ts +1 -10
- package/BlockadeLabsGenerateSkyboxInterface.js +57 -72
- package/BlockadeLabsGenerateSkyboxInterface.js.map +1 -1
- package/CachingConfigStore.js +30 -45
- package/CachingConfigStore.js.map +1 -1
- package/CachingPolicyStore.d.ts +8 -2
- package/CachingPolicyStore.js +108 -135
- package/CachingPolicyStore.js.map +1 -1
- package/ComIdConfig.d.ts +18 -18
- package/ComIdConfig.js.map +1 -1
- package/ConsoleAuthMessenger.js +7 -20
- package/ConsoleAuthMessenger.js.map +1 -1
- package/DataRecordsController.d.ts +2 -2
- package/DataRecordsController.js +369 -377
- package/DataRecordsController.js.map +1 -1
- package/DataRecordsStore.d.ts +1 -1
- package/DataRecordsStore.js +1 -1
- package/DataRecordsStore.js.map +1 -1
- package/EventRecordsController.js +226 -240
- package/EventRecordsController.js.map +1 -1
- package/FileRecordsController.d.ts +13 -2
- package/FileRecordsController.js +458 -450
- package/FileRecordsController.js.map +1 -1
- package/GoogleAIChatInterface.js +133 -179
- package/GoogleAIChatInterface.js.map +1 -1
- package/LivekitController.js +43 -54
- package/LivekitController.js.map +1 -1
- package/LoomController.js +64 -75
- package/LoomController.js.map +1 -1
- package/MemoryAuthMessenger.js +10 -23
- package/MemoryAuthMessenger.js.map +1 -1
- package/MemoryCache.js +18 -35
- package/MemoryCache.js.map +1 -1
- package/MemoryFileRecordsLookup.js +105 -125
- package/MemoryFileRecordsLookup.js.map +1 -1
- package/MemoryModerationJobProvider.js +17 -30
- package/MemoryModerationJobProvider.js.map +1 -1
- package/MemoryRateLimiter.js +12 -27
- package/MemoryRateLimiter.js.map +1 -1
- package/MemoryStore.d.ts +18 -6
- package/MemoryStore.js +1879 -1997
- package/MemoryStore.js.map +1 -1
- package/MetricsStore.d.ts +2 -2
- package/ModerationController.js +186 -200
- package/ModerationController.js.map +1 -1
- package/OpenAIChatInterface.js +105 -135
- package/OpenAIChatInterface.js.map +1 -1
- package/OpenAIImageInterface.js +57 -51
- package/OpenAIImageInterface.js.map +1 -1
- package/PolicyController.d.ts +150 -10
- package/PolicyController.js +1546 -1299
- package/PolicyController.js.map +1 -1
- package/PolicyStore.d.ts +110 -2
- package/PolicyStore.js +36 -1
- package/PolicyStore.js.map +1 -1
- package/PrivoClient.js +398 -435
- package/PrivoClient.js.map +1 -1
- package/RateLimitController.js +25 -36
- package/RateLimitController.js.map +1 -1
- package/RecordsClient.js +51 -74
- package/RecordsClient.js.map +1 -1
- package/RecordsController.d.ts +2 -42
- package/RecordsController.js +1026 -1182
- package/RecordsController.js.map +1 -1
- package/RecordsServer.d.ts +196 -27
- package/RecordsServer.js +1701 -1343
- package/RecordsServer.js.map +1 -1
- package/RecordsStore.d.ts +1 -10
- package/RecordsStore.js.map +1 -1
- package/ServerConfig.d.ts +339 -195
- package/ServerConfig.js +13 -0
- package/ServerConfig.js.map +1 -1
- package/SloydInterface.js +62 -75
- package/SloydInterface.js.map +1 -1
- package/StabilityAIImageInterface.js +150 -167
- package/StabilityAIImageInterface.js.map +1 -1
- package/SubscriptionConfigBuilder.d.ts +6 -1
- package/SubscriptionConfigBuilder.js +22 -0
- package/SubscriptionConfigBuilder.js.map +1 -1
- package/SubscriptionConfiguration.d.ts +266 -169
- package/SubscriptionConfiguration.js +101 -79
- package/SubscriptionConfiguration.js.map +1 -1
- package/SubscriptionController.d.ts +2 -1
- package/SubscriptionController.js +643 -650
- package/SubscriptionController.js.map +1 -1
- package/SystemNotificationMessenger.d.ts +21 -4
- package/SystemNotificationMessenger.js +36 -30
- package/SystemNotificationMessenger.js.map +1 -1
- package/TestUtils.d.ts +9 -1
- package/TestUtils.js +105 -129
- package/TestUtils.js.map +1 -1
- package/Utils.d.ts +2 -16
- package/Utils.js +21 -22
- package/Utils.js.map +1 -1
- package/crud/CrudHelpers.js +17 -26
- package/crud/CrudHelpers.js.map +1 -1
- package/crud/CrudRecordsController.d.ts +1 -1
- package/crud/CrudRecordsController.js +259 -267
- package/crud/CrudRecordsController.js.map +1 -1
- package/crud/CrudRecordsControllerTests.js +174 -185
- package/crud/CrudRecordsControllerTests.js.map +1 -1
- package/crud/CrudRecordsStore.d.ts +7 -3
- package/crud/MemoryCrudRecordsStore.d.ts +4 -4
- package/crud/MemoryCrudRecordsStore.js +98 -118
- package/crud/MemoryCrudRecordsStore.js.map +1 -1
- package/crud/sub/MemorySubCrudRecordsStore.d.ts +24 -0
- package/crud/sub/MemorySubCrudRecordsStore.js +146 -0
- package/crud/sub/MemorySubCrudRecordsStore.js.map +1 -0
- package/crud/sub/SubCrudRecordsController.d.ts +182 -0
- package/crud/sub/SubCrudRecordsController.js +360 -0
- package/crud/sub/SubCrudRecordsController.js.map +1 -0
- package/crud/sub/SubCrudRecordsControllerTests.d.ts +39 -0
- package/crud/sub/SubCrudRecordsControllerTests.js +821 -0
- package/crud/sub/SubCrudRecordsControllerTests.js.map +1 -0
- package/crud/sub/SubCrudRecordsStore.d.ts +95 -0
- package/{forms/index.js → crud/sub/SubCrudRecordsStore.js} +2 -2
- package/crud/sub/SubCrudRecordsStore.js.map +1 -0
- package/crud/sub/index.d.ts +3 -0
- package/crud/sub/index.js +20 -0
- package/{forms → crud/sub}/index.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/notifications/MemoryNotificationRecordsStore.js +189 -198
- package/notifications/MemoryNotificationRecordsStore.js.map +1 -1
- package/notifications/NotificationRecordsController.js +438 -460
- package/notifications/NotificationRecordsController.js.map +1 -1
- package/notifications/NotificationRecordsStore.d.ts +2 -1
- package/notifications/WebPushInterface.d.ts +0 -1
- package/notifications/WebPushInterface.js +0 -1
- package/notifications/WebPushInterface.js.map +1 -1
- package/package.json +6 -6
- package/packages/MemoryPackageRecordsStore.d.ts +10 -0
- package/packages/MemoryPackageRecordsStore.js +38 -0
- package/packages/MemoryPackageRecordsStore.js.map +1 -0
- package/packages/PackageRecordsController.d.ts +26 -0
- package/packages/PackageRecordsController.js +49 -0
- package/packages/PackageRecordsController.js.map +1 -0
- package/packages/PackageRecordsStore.d.ts +32 -0
- package/packages/PackageRecordsStore.js +19 -0
- package/packages/PackageRecordsStore.js.map +1 -0
- package/packages/index.d.ts +4 -0
- package/packages/index.js +21 -0
- package/packages/index.js.map +1 -0
- package/packages/version/MemoryPackageVersionRecordsStore.d.ts +21 -0
- package/packages/version/MemoryPackageVersionRecordsStore.js +177 -0
- package/packages/version/MemoryPackageVersionRecordsStore.js.map +1 -0
- package/packages/version/PackageVersionRecordsController.d.ts +144 -0
- package/packages/version/PackageVersionRecordsController.js +656 -0
- package/packages/version/PackageVersionRecordsController.js.map +1 -0
- package/packages/version/PackageVersionRecordsStore.d.ts +342 -0
- package/packages/version/PackageVersionRecordsStore.js +126 -0
- package/packages/version/PackageVersionRecordsStore.js.map +1 -0
- package/packages/version/index.d.ts +4 -0
- package/packages/version/index.js +21 -0
- package/packages/version/index.js.map +1 -0
- package/tracing/TracingDecorators.js +31 -40
- package/tracing/TracingDecorators.js.map +1 -1
- package/webhooks/MemoryWebhookRecordsStore.js +56 -72
- package/webhooks/MemoryWebhookRecordsStore.js.map +1 -1
- package/webhooks/WebhookEnvironment.d.ts +3 -3
- package/webhooks/WebhookRecordsController.d.ts +2 -1
- package/webhooks/WebhookRecordsController.js +389 -382
- package/webhooks/WebhookRecordsController.js.map +1 -1
- package/webhooks/WebhookRecordsStore.d.ts +2 -1
- package/websockets/InstRecordsStore.d.ts +50 -0
- package/websockets/InstRecordsStore.js +17 -0
- package/websockets/InstRecordsStore.js.map +1 -1
- package/websockets/MemoryTempInstRecordsStore.d.ts +5 -0
- package/websockets/MemoryTempInstRecordsStore.js +168 -179
- package/websockets/MemoryTempInstRecordsStore.js.map +1 -1
- package/websockets/MemoryWebsocketConnectionStore.js +98 -135
- package/websockets/MemoryWebsocketConnectionStore.js.map +1 -1
- package/websockets/MemoryWebsocketMessenger.js +29 -48
- package/websockets/MemoryWebsocketMessenger.js.map +1 -1
- package/websockets/SplitInstRecordsStore.d.ts +4 -1
- package/websockets/SplitInstRecordsStore.js +167 -185
- package/websockets/SplitInstRecordsStore.js.map +1 -1
- package/websockets/TemporaryInstRecordsStore.d.ts +19 -1
- package/websockets/TemporaryInstRecordsStore.js +17 -0
- package/websockets/TemporaryInstRecordsStore.js.map +1 -1
- package/websockets/WebsocketController.d.ts +147 -3
- package/websockets/WebsocketController.js +1735 -1391
- package/websockets/WebsocketController.js.map +1 -1
- package/websockets/index.d.ts +0 -1
- package/websockets/index.js +0 -1
- package/websockets/index.js.map +1 -1
- package/AAGUID.d.ts +0 -11
- package/AAGUID.js +0 -116
- package/AAGUID.js.map +0 -1
- package/AuthUtils.d.ts +0 -162
- package/AuthUtils.js +0 -327
- package/AuthUtils.js.map +0 -1
- package/forms/FormError.d.ts +0 -43
- package/forms/FormError.js +0 -56
- package/forms/FormError.js.map +0 -1
- package/forms/index.d.ts +0 -2
- package/websockets/Utils.d.ts +0 -33
- package/websockets/Utils.js +0 -82
- package/websockets/Utils.js.map +0 -1
package/PolicyController.js
CHANGED
|
@@ -4,23 +4,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
|
|
8
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
9
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
11
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
12
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
13
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14
|
-
});
|
|
15
|
-
};
|
|
16
|
-
import { isRecordKey } from './RecordsController';
|
|
17
|
-
import { ADMIN_ROLE_NAME, PUBLIC_READ_MARKER, ACCOUNT_MARKER, PRIVATE_MARKER, } from '@casual-simulation/aux-common';
|
|
7
|
+
import { ADMIN_ROLE_NAME, PUBLIC_READ_MARKER, ACCOUNT_MARKER, PRIVATE_MARKER, isRecordKey, isSuperUserRole, normalizeInstId, parseInstId, } from '@casual-simulation/aux-common';
|
|
18
8
|
import { getExpireTime, getPublicMarkersPermission } from './PolicyStore';
|
|
19
9
|
import { sortBy, without } from 'lodash';
|
|
20
10
|
import { getRootMarker, getRootMarkersOrDefault } from './Utils';
|
|
21
|
-
import { normalizeInstId, parseInstId } from './websockets';
|
|
22
11
|
import { traced } from './tracing/TracingDecorators';
|
|
23
12
|
import { SpanStatusCode, trace } from '@opentelemetry/api';
|
|
13
|
+
import { v7 as uuidv7 } from 'uuid';
|
|
24
14
|
const TRACE_NAME = 'PolicyController';
|
|
25
15
|
/**
|
|
26
16
|
* The maximum number of instances that can be authorized at once.
|
|
@@ -57,6 +47,8 @@ const ALLOWED_STUDIO_MEMBER_RESOURCES = [
|
|
|
57
47
|
],
|
|
58
48
|
['loom', ['create']],
|
|
59
49
|
['webhook', ['read', 'create', 'delete', 'update', 'list', 'run']],
|
|
50
|
+
['package', ['read', 'create', 'delete', 'update', 'list']],
|
|
51
|
+
['package.version', ['read', 'create', 'delete', 'update', 'list', 'run']],
|
|
60
52
|
];
|
|
61
53
|
const ALLOWED_MODERATOR_ACTIONS = new Set([
|
|
62
54
|
'read',
|
|
@@ -149,180 +141,142 @@ export function getMarkerResourcesForUpdate(existingMarkers, newMarkers) {
|
|
|
149
141
|
* Defines a class that is able to calculate the policies and permissions that are allowed for specific actions.
|
|
150
142
|
*/
|
|
151
143
|
export class PolicyController {
|
|
152
|
-
constructor(auth, records, policies) {
|
|
144
|
+
constructor(auth, records, policies, insts = null, packageVersions = null) {
|
|
153
145
|
this._auth = auth;
|
|
154
146
|
this._records = records;
|
|
155
147
|
this._policies = policies;
|
|
148
|
+
this._insts = insts;
|
|
149
|
+
this._packageVersions = packageVersions;
|
|
156
150
|
}
|
|
157
151
|
/**
|
|
158
152
|
* Constructs the authorization context that is needed for the given request.
|
|
159
153
|
* @param request The request that will be authorized.
|
|
160
154
|
* @returns The authorization context that will be used to evaluate whether the request is authorized.
|
|
161
155
|
*/
|
|
162
|
-
constructAuthorizationContext(request) {
|
|
156
|
+
async constructAuthorizationContext(request) {
|
|
163
157
|
var _a, _b;
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
recordKeyCreatorId = recordKeyResult.keyCreatorId;
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
return {
|
|
181
|
-
success: false,
|
|
182
|
-
errorCode: recordKeyResult.errorCode,
|
|
183
|
-
errorMessage: recordKeyResult.errorMessage,
|
|
184
|
-
};
|
|
185
|
-
}
|
|
158
|
+
let recordKeyResult = null;
|
|
159
|
+
let recordName;
|
|
160
|
+
let recordKeyCreatorId;
|
|
161
|
+
let ownerId;
|
|
162
|
+
let studioId;
|
|
163
|
+
let studioMembers = undefined;
|
|
164
|
+
const recordKeyProvided = isRecordKey(request.recordKeyOrRecordName);
|
|
165
|
+
if (recordKeyProvided) {
|
|
166
|
+
recordKeyResult = await this._records.validatePublicRecordKey(request.recordKeyOrRecordName);
|
|
167
|
+
if (recordKeyResult.success === true) {
|
|
168
|
+
recordName = recordKeyResult.recordName;
|
|
169
|
+
ownerId = recordKeyResult.ownerId;
|
|
170
|
+
recordKeyCreatorId = recordKeyResult.keyCreatorId;
|
|
186
171
|
}
|
|
187
172
|
else {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
errorMessage: result.errorMessage,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
recordName = result.recordName;
|
|
197
|
-
ownerId = result.ownerId;
|
|
198
|
-
studioId = result.studioId;
|
|
199
|
-
studioMembers = result.studioMembers;
|
|
200
|
-
}
|
|
201
|
-
const subjectPolicy = !!recordKeyResult && recordKeyResult.success
|
|
202
|
-
? recordKeyResult.policy
|
|
203
|
-
: 'subjectfull';
|
|
204
|
-
let recordOwnerPrivacyFeatures = null;
|
|
205
|
-
let userPrivacyFeatures = null;
|
|
206
|
-
if (ownerId) {
|
|
207
|
-
recordOwnerPrivacyFeatures =
|
|
208
|
-
yield this._policies.getUserPrivacyFeatures(ownerId);
|
|
209
|
-
}
|
|
210
|
-
if (!recordOwnerPrivacyFeatures) {
|
|
211
|
-
// The record owner will most likely have privacy features,
|
|
212
|
-
// but this is just a sanity check in case they dont.
|
|
213
|
-
if (this._auth.privoEnabled) {
|
|
214
|
-
recordOwnerPrivacyFeatures = {
|
|
215
|
-
allowAI: false,
|
|
216
|
-
allowPublicData: false,
|
|
217
|
-
allowPublicInsts: false,
|
|
218
|
-
publishData: false,
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
recordOwnerPrivacyFeatures = {
|
|
223
|
-
allowAI: true,
|
|
224
|
-
allowPublicData: true,
|
|
225
|
-
allowPublicInsts: true,
|
|
226
|
-
publishData: true,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
if (request.userId) {
|
|
231
|
-
userPrivacyFeatures = yield this._policies.getUserPrivacyFeatures(request.userId);
|
|
232
|
-
}
|
|
233
|
-
if (!userPrivacyFeatures) {
|
|
234
|
-
if (this._auth.privoEnabled) {
|
|
235
|
-
userPrivacyFeatures = {
|
|
236
|
-
allowAI: false,
|
|
237
|
-
allowPublicData: false,
|
|
238
|
-
allowPublicInsts: false,
|
|
239
|
-
publishData: false,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
userPrivacyFeatures = {
|
|
244
|
-
allowAI: true,
|
|
245
|
-
allowPublicData: true,
|
|
246
|
-
allowPublicInsts: true,
|
|
247
|
-
publishData: true,
|
|
248
|
-
};
|
|
249
|
-
}
|
|
173
|
+
return {
|
|
174
|
+
success: false,
|
|
175
|
+
errorCode: recordKeyResult.errorCode,
|
|
176
|
+
errorMessage: recordKeyResult.errorMessage,
|
|
177
|
+
};
|
|
250
178
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
recordKeyProvided,
|
|
256
|
-
recordKeyCreatorId,
|
|
257
|
-
recordOwnerId: ownerId,
|
|
258
|
-
recordOwnerPrivacyFeatures,
|
|
259
|
-
recordStudioId: studioId,
|
|
260
|
-
recordStudioMembers: studioMembers,
|
|
261
|
-
userId: request.userId,
|
|
262
|
-
userRole: (_a = userPrivacyFeatures === null || userPrivacyFeatures === void 0 ? void 0 : userPrivacyFeatures.userRole) !== null && _a !== void 0 ? _a : 'none',
|
|
263
|
-
userPrivacyFeatures,
|
|
264
|
-
sendNotLoggedIn: (_b = request.sendNotLoggedIn) !== null && _b !== void 0 ? _b : true,
|
|
265
|
-
};
|
|
266
|
-
return {
|
|
267
|
-
success: true,
|
|
268
|
-
context,
|
|
269
|
-
};
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Attempts to authorize the given user and instances for the action and resource(s).
|
|
274
|
-
* @param context The authorization context for the request.
|
|
275
|
-
* @param request The request.
|
|
276
|
-
*/
|
|
277
|
-
authorizeUserAndInstances(context, request) {
|
|
278
|
-
var _a;
|
|
279
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
280
|
-
try {
|
|
281
|
-
const authorization = yield this.authorizeSubjects(context, {
|
|
282
|
-
action: request.action,
|
|
283
|
-
markers: request.markers,
|
|
284
|
-
resourceKind: request.resourceKind,
|
|
285
|
-
resourceId: request.resourceId,
|
|
286
|
-
subjects: [
|
|
287
|
-
{
|
|
288
|
-
subjectType: 'user',
|
|
289
|
-
subjectId: request.userId,
|
|
290
|
-
},
|
|
291
|
-
...((_a = request.instances) !== null && _a !== void 0 ? _a : []).map((i) => ({
|
|
292
|
-
subjectType: 'inst',
|
|
293
|
-
subjectId: i,
|
|
294
|
-
})),
|
|
295
|
-
],
|
|
296
|
-
});
|
|
297
|
-
if (authorization.success === false) {
|
|
298
|
-
return authorization;
|
|
299
|
-
}
|
|
300
|
-
const userResult = authorization.results.find((r) => r.subjectType === 'user' && r.subjectId === request.userId);
|
|
301
|
-
return Object.assign(Object.assign({}, authorization), { user: userResult });
|
|
302
|
-
}
|
|
303
|
-
catch (err) {
|
|
304
|
-
const span = trace.getActiveSpan();
|
|
305
|
-
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
306
|
-
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
307
|
-
console.error('[PolicyController] A server error occurred while authorizing user and instances.', err);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
const result = await this._records.validateRecordName(request.recordKeyOrRecordName, request.userId);
|
|
182
|
+
if (result.success === false) {
|
|
308
183
|
return {
|
|
309
184
|
success: false,
|
|
310
|
-
errorCode:
|
|
311
|
-
errorMessage:
|
|
185
|
+
errorCode: result.errorCode,
|
|
186
|
+
errorMessage: result.errorMessage,
|
|
312
187
|
};
|
|
313
188
|
}
|
|
314
|
-
|
|
189
|
+
recordName = result.recordName;
|
|
190
|
+
ownerId = result.ownerId;
|
|
191
|
+
studioId = result.studioId;
|
|
192
|
+
studioMembers = result.studioMembers;
|
|
193
|
+
}
|
|
194
|
+
const subjectPolicy = !!recordKeyResult && recordKeyResult.success
|
|
195
|
+
? recordKeyResult.policy
|
|
196
|
+
: 'subjectfull';
|
|
197
|
+
let recordOwnerPrivacyFeatures = null;
|
|
198
|
+
let userPrivacyFeatures = null;
|
|
199
|
+
if (ownerId) {
|
|
200
|
+
recordOwnerPrivacyFeatures =
|
|
201
|
+
await this._policies.getUserPrivacyFeatures(ownerId);
|
|
202
|
+
}
|
|
203
|
+
if (!recordOwnerPrivacyFeatures) {
|
|
204
|
+
// The record owner will most likely have privacy features,
|
|
205
|
+
// but this is just a sanity check in case they dont.
|
|
206
|
+
if (this._auth.privoEnabled) {
|
|
207
|
+
recordOwnerPrivacyFeatures = {
|
|
208
|
+
allowAI: false,
|
|
209
|
+
allowPublicData: false,
|
|
210
|
+
allowPublicInsts: false,
|
|
211
|
+
publishData: false,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
recordOwnerPrivacyFeatures = {
|
|
216
|
+
allowAI: true,
|
|
217
|
+
allowPublicData: true,
|
|
218
|
+
allowPublicInsts: true,
|
|
219
|
+
publishData: true,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (request.userId) {
|
|
224
|
+
userPrivacyFeatures = await this._policies.getUserPrivacyFeatures(request.userId);
|
|
225
|
+
}
|
|
226
|
+
if (!userPrivacyFeatures) {
|
|
227
|
+
if (this._auth.privoEnabled) {
|
|
228
|
+
userPrivacyFeatures = {
|
|
229
|
+
allowAI: false,
|
|
230
|
+
allowPublicData: false,
|
|
231
|
+
allowPublicInsts: false,
|
|
232
|
+
publishData: false,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
userPrivacyFeatures = {
|
|
237
|
+
allowAI: true,
|
|
238
|
+
allowPublicData: true,
|
|
239
|
+
allowPublicInsts: true,
|
|
240
|
+
publishData: true,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const context = {
|
|
245
|
+
recordName,
|
|
246
|
+
recordKeyResult,
|
|
247
|
+
subjectPolicy,
|
|
248
|
+
recordKeyProvided,
|
|
249
|
+
recordKeyCreatorId,
|
|
250
|
+
recordOwnerId: ownerId,
|
|
251
|
+
recordOwnerPrivacyFeatures,
|
|
252
|
+
recordStudioId: studioId,
|
|
253
|
+
recordStudioMembers: studioMembers,
|
|
254
|
+
userId: request.userId,
|
|
255
|
+
userRole: (_a = (request.userId
|
|
256
|
+
? userPrivacyFeatures === null || userPrivacyFeatures === void 0 ? void 0 : userPrivacyFeatures.userRole
|
|
257
|
+
: request.userRole)) !== null && _a !== void 0 ? _a : 'none',
|
|
258
|
+
userPrivacyFeatures,
|
|
259
|
+
sendNotLoggedIn: (_b = request.sendNotLoggedIn) !== null && _b !== void 0 ? _b : true,
|
|
260
|
+
};
|
|
261
|
+
return {
|
|
262
|
+
success: true,
|
|
263
|
+
context,
|
|
264
|
+
};
|
|
315
265
|
}
|
|
316
266
|
/**
|
|
317
|
-
* Attempts to authorize the given user and instances for the
|
|
267
|
+
* Attempts to authorize the given user and instances for the action and resource(s).
|
|
318
268
|
* @param context The authorization context for the request.
|
|
319
269
|
* @param request The request.
|
|
320
270
|
*/
|
|
321
|
-
|
|
271
|
+
async authorizeUserAndInstances(context, request) {
|
|
322
272
|
var _a;
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
273
|
+
try {
|
|
274
|
+
const authorization = await this.authorizeSubjects(context, {
|
|
275
|
+
action: request.action,
|
|
276
|
+
markers: request.markers,
|
|
277
|
+
resourceKind: request.resourceKind,
|
|
278
|
+
resourceId: request.resourceId,
|
|
279
|
+
subjects: [
|
|
326
280
|
{
|
|
327
281
|
subjectType: 'user',
|
|
328
282
|
subjectId: request.userId,
|
|
@@ -331,164 +285,211 @@ export class PolicyController {
|
|
|
331
285
|
subjectType: 'inst',
|
|
332
286
|
subjectId: i,
|
|
333
287
|
})),
|
|
334
|
-
]
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
288
|
+
],
|
|
289
|
+
});
|
|
290
|
+
if (authorization.success === false) {
|
|
291
|
+
return authorization;
|
|
292
|
+
}
|
|
293
|
+
const userResult = authorization.results.find((r) => r.subjectType === 'user' && r.subjectId === request.userId);
|
|
294
|
+
return {
|
|
295
|
+
...authorization,
|
|
296
|
+
user: userResult,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
const span = trace.getActiveSpan();
|
|
301
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
302
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
303
|
+
console.error('[PolicyController] A server error occurred while authorizing user and instances.', err);
|
|
304
|
+
return {
|
|
305
|
+
success: false,
|
|
306
|
+
errorCode: 'server_error',
|
|
307
|
+
errorMessage: 'A server error occurred.',
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Attempts to authorize the given user and instances for the given resources.
|
|
313
|
+
* @param context The authorization context for the request.
|
|
314
|
+
* @param request The request.
|
|
315
|
+
*/
|
|
316
|
+
async authorizeUserAndInstancesForResources(context, request) {
|
|
317
|
+
var _a;
|
|
318
|
+
try {
|
|
319
|
+
const subjects = [
|
|
320
|
+
{
|
|
321
|
+
subjectType: 'user',
|
|
322
|
+
subjectId: request.userId,
|
|
323
|
+
},
|
|
324
|
+
...((_a = request.instances) !== null && _a !== void 0 ? _a : []).map((i) => ({
|
|
325
|
+
subjectType: 'inst',
|
|
326
|
+
subjectId: i,
|
|
327
|
+
})),
|
|
328
|
+
];
|
|
329
|
+
const subjectPermission = new Map();
|
|
330
|
+
const results = [];
|
|
331
|
+
const recordName = context.recordName;
|
|
332
|
+
for (let resource of request.resources) {
|
|
333
|
+
let subjectsToAuthorize = [];
|
|
334
|
+
let authorizations = [];
|
|
335
|
+
for (let subject of subjects) {
|
|
336
|
+
const subjectKey = `${subject.subjectType}.${subject.subjectId}`;
|
|
337
|
+
const authorizedSubject = subjectPermission.get(subjectKey);
|
|
338
|
+
if (authorizedSubject) {
|
|
339
|
+
const permission = authorizedSubject.permission;
|
|
340
|
+
const isCorrectResourceKind = permission.resourceKind === null ||
|
|
341
|
+
permission.resourceKind === resource.resourceKind;
|
|
342
|
+
const isCorrectAction = permission.action === null ||
|
|
343
|
+
permission.action === resource.action;
|
|
344
|
+
const isCorrectMarker = !('marker' in permission) ||
|
|
345
|
+
resource.markers.includes(permission.marker);
|
|
346
|
+
const isCorrectResource = !('resourceId' in permission) ||
|
|
347
|
+
permission.resourceId === null ||
|
|
348
|
+
permission.resourceId === resource.resourceId;
|
|
349
|
+
if (isCorrectResourceKind &&
|
|
350
|
+
isCorrectAction &&
|
|
351
|
+
isCorrectMarker &&
|
|
352
|
+
isCorrectResource) {
|
|
353
|
+
// Record the authorization
|
|
354
|
+
authorizations.push(authorizedSubject);
|
|
365
355
|
}
|
|
366
356
|
else {
|
|
367
357
|
subjectsToAuthorize.push(subject);
|
|
368
358
|
}
|
|
369
359
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
360
|
+
else {
|
|
361
|
+
subjectsToAuthorize.push(subject);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (subjectsToAuthorize.length > 0) {
|
|
365
|
+
const result = await this.authorizeSubjects(context, {
|
|
366
|
+
action: resource.action,
|
|
367
|
+
markers: resource.markers,
|
|
368
|
+
resourceKind: resource.resourceKind,
|
|
369
|
+
resourceId: resource.resourceId,
|
|
370
|
+
subjects: subjectsToAuthorize,
|
|
371
|
+
});
|
|
372
|
+
if (result.success === false) {
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
for (let authorization of result.results) {
|
|
376
|
+
const subjectKey = `${authorization.subjectType}.${authorization.subjectId}`;
|
|
377
|
+
authorizations.push(authorization);
|
|
378
|
+
const permission = authorization.permission;
|
|
379
|
+
const existingAuthorization = subjectPermission.get(subjectKey);
|
|
380
|
+
if (!existingAuthorization) {
|
|
381
|
+
subjectPermission.set(subjectKey, authorization);
|
|
380
382
|
}
|
|
381
|
-
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const
|
|
386
|
-
|
|
383
|
+
else {
|
|
384
|
+
const existingPermission = existingAuthorization.permission;
|
|
385
|
+
const isResourceKindMoreGeneral = permission.resourceKind === null &&
|
|
386
|
+
existingPermission.resourceKind !== null;
|
|
387
|
+
const isActionMoreGeneral = permission.action === null &&
|
|
388
|
+
existingPermission.action !== null;
|
|
389
|
+
const isMarkerMoreGeneral = 'marker' in permission &&
|
|
390
|
+
'marker' in existingPermission &&
|
|
391
|
+
permission.marker === null &&
|
|
392
|
+
existingPermission.marker !== null;
|
|
393
|
+
const isResourceMoreGeneral = 'resourceId' in permission &&
|
|
394
|
+
'resourceId' in existingPermission &&
|
|
395
|
+
permission.resourceId === null &&
|
|
396
|
+
existingPermission.resourceId !== null;
|
|
397
|
+
if (isResourceKindMoreGeneral ||
|
|
398
|
+
isActionMoreGeneral ||
|
|
399
|
+
isMarkerMoreGeneral ||
|
|
400
|
+
isResourceMoreGeneral) {
|
|
387
401
|
subjectPermission.set(subjectKey, authorization);
|
|
388
402
|
}
|
|
389
|
-
else {
|
|
390
|
-
const existingPermission = existingAuthorization.permission;
|
|
391
|
-
const isResourceKindMoreGeneral = permission.resourceKind === null &&
|
|
392
|
-
existingPermission.resourceKind !== null;
|
|
393
|
-
const isActionMoreGeneral = permission.action === null &&
|
|
394
|
-
existingPermission.action !== null;
|
|
395
|
-
const isMarkerMoreGeneral = 'marker' in permission &&
|
|
396
|
-
'marker' in existingPermission &&
|
|
397
|
-
permission.marker === null &&
|
|
398
|
-
existingPermission.marker !== null;
|
|
399
|
-
const isResourceMoreGeneral = 'resourceId' in permission &&
|
|
400
|
-
'resourceId' in existingPermission &&
|
|
401
|
-
permission.resourceId === null &&
|
|
402
|
-
existingPermission.resourceId !== null;
|
|
403
|
-
if (isResourceKindMoreGeneral ||
|
|
404
|
-
isActionMoreGeneral ||
|
|
405
|
-
isMarkerMoreGeneral ||
|
|
406
|
-
isResourceMoreGeneral) {
|
|
407
|
-
subjectPermission.set(subjectKey, authorization);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
403
|
}
|
|
411
404
|
}
|
|
412
|
-
if (authorizations.length !== subjects.length) {
|
|
413
|
-
console.error('[PolicyController] [authorizeUserAndInstancesForResources] The number of authorizations does not match the number of subjects!');
|
|
414
|
-
return {
|
|
415
|
-
success: false,
|
|
416
|
-
errorCode: 'server_error',
|
|
417
|
-
errorMessage: 'A server error occurred.',
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
results.push({
|
|
421
|
-
success: true,
|
|
422
|
-
recordName: recordName,
|
|
423
|
-
resourceKind: resource.resourceKind,
|
|
424
|
-
resourceId: resource.resourceId,
|
|
425
|
-
action: resource.action,
|
|
426
|
-
markers: resource.markers,
|
|
427
|
-
results: authorizations,
|
|
428
|
-
user: authorizations.find((r) => r.subjectType === 'user' &&
|
|
429
|
-
r.subjectId === request.userId),
|
|
430
|
-
});
|
|
431
405
|
}
|
|
432
|
-
|
|
406
|
+
if (authorizations.length !== subjects.length) {
|
|
407
|
+
console.error('[PolicyController] [authorizeUserAndInstancesForResources] The number of authorizations does not match the number of subjects!');
|
|
408
|
+
return {
|
|
409
|
+
success: false,
|
|
410
|
+
errorCode: 'server_error',
|
|
411
|
+
errorMessage: 'A server error occurred.',
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
results.push({
|
|
433
415
|
success: true,
|
|
434
416
|
recordName: recordName,
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
return {
|
|
444
|
-
success: false,
|
|
445
|
-
errorCode: 'server_error',
|
|
446
|
-
errorMessage: 'A server error occurred.',
|
|
447
|
-
};
|
|
417
|
+
resourceKind: resource.resourceKind,
|
|
418
|
+
resourceId: resource.resourceId,
|
|
419
|
+
action: resource.action,
|
|
420
|
+
markers: resource.markers,
|
|
421
|
+
results: authorizations,
|
|
422
|
+
user: authorizations.find((r) => r.subjectType === 'user' &&
|
|
423
|
+
r.subjectId === request.userId),
|
|
424
|
+
});
|
|
448
425
|
}
|
|
449
|
-
|
|
426
|
+
return {
|
|
427
|
+
success: true,
|
|
428
|
+
recordName: recordName,
|
|
429
|
+
results,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
catch (err) {
|
|
433
|
+
const span = trace.getActiveSpan();
|
|
434
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
435
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
436
|
+
console.error('[PolicyController] A server error occurred while authorizing user and instances for resources.', err);
|
|
437
|
+
return {
|
|
438
|
+
success: false,
|
|
439
|
+
errorCode: 'server_error',
|
|
440
|
+
errorMessage: 'A server error occurred.',
|
|
441
|
+
};
|
|
442
|
+
}
|
|
450
443
|
}
|
|
451
444
|
/**
|
|
452
445
|
* Attempts to authorize the given subjects for the action and resource(s).
|
|
453
446
|
* @param context The authorization context for the request.
|
|
454
447
|
* @param request The request.
|
|
455
448
|
*/
|
|
456
|
-
authorizeSubjects(context, request) {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
if (request.subjects.length <= 0) {
|
|
460
|
-
return {
|
|
461
|
-
success: false,
|
|
462
|
-
errorCode: 'unacceptable_request',
|
|
463
|
-
errorMessage: 'You must provide at least one subject to authorize.',
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
const results = [];
|
|
467
|
-
for (let subject of request.subjects) {
|
|
468
|
-
const subjectResult = yield this.authorizeSubjectUsingContext(context, Object.assign(Object.assign({}, subject), { action: request.action, resourceKind: request.resourceKind, resourceId: request.resourceId, markers: request.markers }));
|
|
469
|
-
if (subjectResult.success === false) {
|
|
470
|
-
return subjectResult;
|
|
471
|
-
}
|
|
472
|
-
results.push(Object.assign(Object.assign({}, subjectResult), { subjectType: subject.subjectType, subjectId: subject.subjectId }));
|
|
473
|
-
}
|
|
474
|
-
return {
|
|
475
|
-
success: true,
|
|
476
|
-
recordName: context.recordName,
|
|
477
|
-
results: results,
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
catch (err) {
|
|
481
|
-
const span = trace.getActiveSpan();
|
|
482
|
-
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
483
|
-
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
484
|
-
console.error('[PolicyController] A server error occurred while authorizing subjects.', err);
|
|
449
|
+
async authorizeSubjects(context, request) {
|
|
450
|
+
try {
|
|
451
|
+
if (request.subjects.length <= 0) {
|
|
485
452
|
return {
|
|
486
453
|
success: false,
|
|
487
|
-
errorCode: '
|
|
488
|
-
errorMessage: '
|
|
454
|
+
errorCode: 'unacceptable_request',
|
|
455
|
+
errorMessage: 'You must provide at least one subject to authorize.',
|
|
489
456
|
};
|
|
490
457
|
}
|
|
491
|
-
|
|
458
|
+
const results = [];
|
|
459
|
+
for (let subject of request.subjects) {
|
|
460
|
+
const subjectResult = await this.authorizeSubjectUsingContext(context, {
|
|
461
|
+
...subject,
|
|
462
|
+
action: request.action,
|
|
463
|
+
resourceKind: request.resourceKind,
|
|
464
|
+
resourceId: request.resourceId,
|
|
465
|
+
markers: request.markers,
|
|
466
|
+
});
|
|
467
|
+
if (subjectResult.success === false) {
|
|
468
|
+
return subjectResult;
|
|
469
|
+
}
|
|
470
|
+
results.push({
|
|
471
|
+
...subjectResult,
|
|
472
|
+
subjectType: subject.subjectType,
|
|
473
|
+
subjectId: subject.subjectId,
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
return {
|
|
477
|
+
success: true,
|
|
478
|
+
recordName: context.recordName,
|
|
479
|
+
results: results,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
catch (err) {
|
|
483
|
+
const span = trace.getActiveSpan();
|
|
484
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
485
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
486
|
+
console.error('[PolicyController] A server error occurred while authorizing subjects.', err);
|
|
487
|
+
return {
|
|
488
|
+
success: false,
|
|
489
|
+
errorCode: 'server_error',
|
|
490
|
+
errorMessage: 'A server error occurred.',
|
|
491
|
+
};
|
|
492
|
+
}
|
|
492
493
|
}
|
|
493
494
|
/**
|
|
494
495
|
* Attempts to authorize the given subject for the action and resource(s).
|
|
@@ -496,26 +497,24 @@ export class PolicyController {
|
|
|
496
497
|
* @param context The context for the request.
|
|
497
498
|
* @param request The request to authorize.
|
|
498
499
|
*/
|
|
499
|
-
authorizeSubject(context, request) {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
return context;
|
|
504
|
-
}
|
|
505
|
-
return yield this.authorizeSubjectUsingContext(context.context, request);
|
|
506
|
-
}
|
|
507
|
-
catch (err) {
|
|
508
|
-
const span = trace.getActiveSpan();
|
|
509
|
-
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
510
|
-
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
511
|
-
console.error('[PolicyController] A server error occurred while authorizing a subject.', err);
|
|
512
|
-
return {
|
|
513
|
-
success: false,
|
|
514
|
-
errorCode: 'server_error',
|
|
515
|
-
errorMessage: 'A server error occurred.',
|
|
516
|
-
};
|
|
500
|
+
async authorizeSubject(context, request) {
|
|
501
|
+
try {
|
|
502
|
+
if (context.success === false) {
|
|
503
|
+
return context;
|
|
517
504
|
}
|
|
518
|
-
|
|
505
|
+
return await this.authorizeSubjectUsingContext(context.context, request);
|
|
506
|
+
}
|
|
507
|
+
catch (err) {
|
|
508
|
+
const span = trace.getActiveSpan();
|
|
509
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
510
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
511
|
+
console.error('[PolicyController] A server error occurred while authorizing a subject.', err);
|
|
512
|
+
return {
|
|
513
|
+
success: false,
|
|
514
|
+
errorCode: 'server_error',
|
|
515
|
+
errorMessage: 'A server error occurred.',
|
|
516
|
+
};
|
|
517
|
+
}
|
|
519
518
|
}
|
|
520
519
|
/**
|
|
521
520
|
* Attempts to authorize the given subject for the action and resource(s).
|
|
@@ -523,17 +522,15 @@ export class PolicyController {
|
|
|
523
522
|
* @param context The context for the request.
|
|
524
523
|
* @param request The request to authorize.
|
|
525
524
|
*/
|
|
526
|
-
authorizeSubjectUsingContext(context, request) {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
return result;
|
|
536
|
-
});
|
|
525
|
+
async authorizeSubjectUsingContext(context, request) {
|
|
526
|
+
const result = await this._authorizeSubjectUsingContext(context, request);
|
|
527
|
+
if (result.success) {
|
|
528
|
+
console.log(`[PolicyController] [action: ${request.resourceKind}.${request.action} resourceId: ${request.resourceId} recordName: ${context.recordName}, ${request.subjectType}: ${request.subjectId}, userId: ${context.userId}] Request authorized: ${result.explanation}`);
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
console.log(`[PolicyController] [action: ${request.resourceKind}.${request.action} resourceId: ${request.resourceId} recordName: ${context.recordName}, ${request.subjectType}: ${request.subjectId}, userId: ${context.userId}] Request denied:`, result);
|
|
532
|
+
}
|
|
533
|
+
return result;
|
|
537
534
|
}
|
|
538
535
|
/**
|
|
539
536
|
* Attempts to authorize the given subject for the action and resource(s).
|
|
@@ -541,21 +538,143 @@ export class PolicyController {
|
|
|
541
538
|
* @param context The context for the request.
|
|
542
539
|
* @param request The request to authorize.
|
|
543
540
|
*/
|
|
544
|
-
_authorizeSubjectUsingContext(context, request) {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
541
|
+
async _authorizeSubjectUsingContext(context, request) {
|
|
542
|
+
var _a, _b, _c;
|
|
543
|
+
try {
|
|
544
|
+
const markers = getRootMarkersOrDefault(request.markers);
|
|
545
|
+
let recommendedEntitlement = undefined;
|
|
546
|
+
if (request.action === 'list' && markers.length > 1) {
|
|
547
|
+
return {
|
|
548
|
+
success: false,
|
|
549
|
+
errorCode: 'not_authorized',
|
|
550
|
+
errorMessage: `The "${request.action}" action cannot be used with multiple markers.`,
|
|
551
|
+
reason: {
|
|
552
|
+
type: 'too_many_markers',
|
|
553
|
+
},
|
|
554
|
+
recommendedEntitlement,
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
if (!context.userPrivacyFeatures.publishData) {
|
|
558
|
+
return {
|
|
559
|
+
success: false,
|
|
560
|
+
errorCode: 'not_authorized',
|
|
561
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
562
|
+
reason: {
|
|
563
|
+
type: 'disabled_privacy_feature',
|
|
564
|
+
recordName: context.recordName,
|
|
565
|
+
subjectType: 'user',
|
|
566
|
+
subjectId: context.userId,
|
|
567
|
+
resourceKind: request.resourceKind,
|
|
568
|
+
action: request.action,
|
|
569
|
+
resourceId: request.resourceId,
|
|
570
|
+
privacyFeature: 'publishData',
|
|
571
|
+
},
|
|
572
|
+
recommendedEntitlement,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
const recordName = context.recordName;
|
|
576
|
+
const subjectType = request.subjectType;
|
|
577
|
+
let subjectId = request.subjectId;
|
|
578
|
+
if (subjectType === 'inst') {
|
|
579
|
+
subjectId = normalizeInstId(subjectId);
|
|
580
|
+
}
|
|
581
|
+
if (context.userRole === 'superUser' &&
|
|
582
|
+
request.subjectType !== 'inst') {
|
|
583
|
+
// super users are allowed to do anything for any user
|
|
584
|
+
// insts need to be authorized separately so that a malicious inst can't just do anything
|
|
585
|
+
// if a super user happens to visit it
|
|
586
|
+
return {
|
|
587
|
+
success: true,
|
|
588
|
+
recordName: recordName,
|
|
589
|
+
permission: {
|
|
590
|
+
id: null,
|
|
591
|
+
recordName: recordName,
|
|
592
|
+
userId: null,
|
|
593
|
+
// Record owners are treated as if they are admins in the record
|
|
594
|
+
subjectType: 'role',
|
|
595
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
596
|
+
// Admins get all access to all resources in a record
|
|
597
|
+
resourceKind: null,
|
|
598
|
+
action: null,
|
|
599
|
+
marker: markers[0],
|
|
600
|
+
options: {},
|
|
601
|
+
expireTimeMs: null,
|
|
602
|
+
},
|
|
603
|
+
explanation: `User is a superUser.`,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
else if (context.userRole === 'system') {
|
|
607
|
+
return {
|
|
608
|
+
success: true,
|
|
609
|
+
recordName: recordName,
|
|
610
|
+
permission: {
|
|
611
|
+
id: null,
|
|
612
|
+
recordName: recordName,
|
|
613
|
+
userId: null,
|
|
614
|
+
// Record owners are treated as if they are admins in the record
|
|
615
|
+
subjectType: 'role',
|
|
616
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
617
|
+
// Admins get all access to all resources in a record
|
|
618
|
+
resourceKind: null,
|
|
619
|
+
action: null,
|
|
620
|
+
marker: markers[0],
|
|
621
|
+
options: {},
|
|
622
|
+
expireTimeMs: null,
|
|
623
|
+
},
|
|
624
|
+
explanation: `The system is requesting the action.`,
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
else if (context.userRole === 'moderator' &&
|
|
628
|
+
request.subjectType !== 'inst') {
|
|
629
|
+
// moderators are allowed to read anything for any user
|
|
630
|
+
// insts need to be authorized separately so that a malicious inst can't just read everything
|
|
631
|
+
// if a moderator happens to visit it
|
|
632
|
+
if (isAllowedModeratorResource(request.resourceKind, request.action)) {
|
|
633
|
+
return {
|
|
634
|
+
success: true,
|
|
635
|
+
recordName: recordName,
|
|
636
|
+
permission: {
|
|
637
|
+
id: null,
|
|
638
|
+
recordName: recordName,
|
|
639
|
+
userId: null,
|
|
640
|
+
// Record owners are treated as if they are admins in the record
|
|
641
|
+
subjectType: 'role',
|
|
642
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
643
|
+
// Admins get all access to all resources in a record
|
|
644
|
+
resourceKind: null,
|
|
645
|
+
action: request.action,
|
|
646
|
+
marker: markers[0],
|
|
647
|
+
options: {},
|
|
648
|
+
expireTimeMs: null,
|
|
649
|
+
},
|
|
650
|
+
explanation: `User is a moderator.`,
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
const publicPermission = getPublicMarkersPermission(markers, request.resourceKind, request.action);
|
|
655
|
+
if (context.recordOwnerId &&
|
|
656
|
+
context.userId !== context.recordOwnerId) {
|
|
657
|
+
if (!context.recordOwnerPrivacyFeatures.allowPublicData) {
|
|
549
658
|
return {
|
|
550
659
|
success: false,
|
|
551
660
|
errorCode: 'not_authorized',
|
|
552
|
-
errorMessage:
|
|
661
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
553
662
|
reason: {
|
|
554
|
-
type: '
|
|
663
|
+
type: 'disabled_privacy_feature',
|
|
664
|
+
recordName: context.recordName,
|
|
665
|
+
subjectType: 'user',
|
|
666
|
+
subjectId: context.userId,
|
|
667
|
+
resourceKind: request.resourceKind,
|
|
668
|
+
action: request.action,
|
|
669
|
+
resourceId: request.resourceId,
|
|
670
|
+
privacyFeature: 'allowPublicData',
|
|
555
671
|
},
|
|
672
|
+
recommendedEntitlement,
|
|
556
673
|
};
|
|
557
674
|
}
|
|
558
|
-
if (
|
|
675
|
+
if (request.resourceKind === 'inst' &&
|
|
676
|
+
(!context.recordOwnerPrivacyFeatures.allowPublicInsts ||
|
|
677
|
+
!context.userPrivacyFeatures.allowPublicInsts)) {
|
|
559
678
|
return {
|
|
560
679
|
success: false,
|
|
561
680
|
errorCode: 'not_authorized',
|
|
@@ -568,139 +687,107 @@ export class PolicyController {
|
|
|
568
687
|
resourceKind: request.resourceKind,
|
|
569
688
|
action: request.action,
|
|
570
689
|
resourceId: request.resourceId,
|
|
571
|
-
privacyFeature: '
|
|
690
|
+
privacyFeature: 'allowPublicInsts',
|
|
572
691
|
},
|
|
692
|
+
recommendedEntitlement,
|
|
573
693
|
};
|
|
574
694
|
}
|
|
575
|
-
|
|
576
|
-
|
|
695
|
+
}
|
|
696
|
+
if (publicPermission) {
|
|
697
|
+
if (!context.userPrivacyFeatures.allowPublicData) {
|
|
577
698
|
return {
|
|
578
|
-
success:
|
|
699
|
+
success: false,
|
|
700
|
+
errorCode: 'not_authorized',
|
|
701
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
702
|
+
reason: {
|
|
703
|
+
type: 'disabled_privacy_feature',
|
|
704
|
+
recordName: context.recordName,
|
|
705
|
+
subjectType: 'user',
|
|
706
|
+
subjectId: context.userId,
|
|
707
|
+
resourceKind: request.resourceKind,
|
|
708
|
+
action: request.action,
|
|
709
|
+
resourceId: request.resourceId,
|
|
710
|
+
privacyFeature: 'allowPublicData',
|
|
711
|
+
},
|
|
712
|
+
recommendedEntitlement,
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
return {
|
|
716
|
+
success: true,
|
|
717
|
+
recordName,
|
|
718
|
+
permission: {
|
|
719
|
+
id: null,
|
|
579
720
|
recordName: recordName,
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
if (subjectType === 'inst') {
|
|
623
|
-
subjectId = normalizeInstId(subjectId);
|
|
624
|
-
}
|
|
625
|
-
const publicPermission = getPublicMarkersPermission(markers, request.resourceKind, request.action);
|
|
626
|
-
if (context.recordOwnerId &&
|
|
627
|
-
context.userId !== context.recordOwnerId) {
|
|
628
|
-
if (!context.recordOwnerPrivacyFeatures.allowPublicData) {
|
|
629
|
-
return {
|
|
630
|
-
success: false,
|
|
631
|
-
errorCode: 'not_authorized',
|
|
632
|
-
errorMessage: 'You are not authorized to perform this action.',
|
|
633
|
-
reason: {
|
|
634
|
-
type: 'disabled_privacy_feature',
|
|
635
|
-
recordName: context.recordName,
|
|
636
|
-
subjectType: 'user',
|
|
637
|
-
subjectId: context.userId,
|
|
638
|
-
resourceKind: request.resourceKind,
|
|
639
|
-
action: request.action,
|
|
640
|
-
resourceId: request.resourceId,
|
|
641
|
-
privacyFeature: 'allowPublicData',
|
|
642
|
-
},
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
if (request.resourceKind === 'inst' &&
|
|
646
|
-
(!context.recordOwnerPrivacyFeatures.allowPublicInsts ||
|
|
647
|
-
!context.userPrivacyFeatures.allowPublicInsts)) {
|
|
648
|
-
return {
|
|
649
|
-
success: false,
|
|
650
|
-
errorCode: 'not_authorized',
|
|
651
|
-
errorMessage: 'You are not authorized to perform this action.',
|
|
652
|
-
reason: {
|
|
653
|
-
type: 'disabled_privacy_feature',
|
|
654
|
-
recordName: context.recordName,
|
|
655
|
-
subjectType: 'user',
|
|
656
|
-
subjectId: context.userId,
|
|
657
|
-
resourceKind: request.resourceKind,
|
|
658
|
-
action: request.action,
|
|
659
|
-
resourceId: request.resourceId,
|
|
660
|
-
privacyFeature: 'allowPublicInsts',
|
|
661
|
-
},
|
|
662
|
-
};
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
if (publicPermission) {
|
|
666
|
-
if (!context.userPrivacyFeatures.allowPublicData) {
|
|
667
|
-
return {
|
|
668
|
-
success: false,
|
|
669
|
-
errorCode: 'not_authorized',
|
|
670
|
-
errorMessage: 'You are not authorized to perform this action.',
|
|
671
|
-
reason: {
|
|
672
|
-
type: 'disabled_privacy_feature',
|
|
673
|
-
recordName: context.recordName,
|
|
674
|
-
subjectType: 'user',
|
|
675
|
-
subjectId: context.userId,
|
|
676
|
-
resourceKind: request.resourceKind,
|
|
677
|
-
action: request.action,
|
|
678
|
-
resourceId: request.resourceId,
|
|
679
|
-
privacyFeature: 'allowPublicData',
|
|
680
|
-
},
|
|
681
|
-
};
|
|
682
|
-
}
|
|
721
|
+
userId: null,
|
|
722
|
+
subjectType: subjectType,
|
|
723
|
+
subjectId: subjectId,
|
|
724
|
+
resourceKind: publicPermission.resourceKind,
|
|
725
|
+
action: publicPermission.action,
|
|
726
|
+
marker: publicPermission.marker,
|
|
727
|
+
options: {},
|
|
728
|
+
expireTimeMs: null,
|
|
729
|
+
},
|
|
730
|
+
explanation: publicPermission.marker === PUBLIC_READ_MARKER
|
|
731
|
+
? 'Resource has the publicRead marker.'
|
|
732
|
+
: 'Resource has the publicWrite marker.',
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
if (subjectType === 'role' && subjectId === ADMIN_ROLE_NAME) {
|
|
736
|
+
return {
|
|
737
|
+
success: true,
|
|
738
|
+
recordName: recordName,
|
|
739
|
+
permission: {
|
|
740
|
+
id: null,
|
|
741
|
+
recordName: recordName,
|
|
742
|
+
userId: null,
|
|
743
|
+
// Record owners are treated as if they are admins in the record
|
|
744
|
+
subjectType: 'role',
|
|
745
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
746
|
+
// Admins get all access to all resources in a record
|
|
747
|
+
resourceKind: null,
|
|
748
|
+
action: null,
|
|
749
|
+
marker: markers[0],
|
|
750
|
+
options: {},
|
|
751
|
+
expireTimeMs: null,
|
|
752
|
+
},
|
|
753
|
+
explanation: `Role is "${ADMIN_ROLE_NAME}".`,
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
if (context.recordKeyProvided &&
|
|
757
|
+
context.recordKeyResult &&
|
|
758
|
+
context.recordKeyResult.success &&
|
|
759
|
+
isAllowedRecordKeyResource(request.resourceKind, request.action)) {
|
|
760
|
+
if (context.subjectPolicy === 'subjectfull' &&
|
|
761
|
+
subjectType === 'user' &&
|
|
762
|
+
!subjectId) {
|
|
683
763
|
return {
|
|
684
|
-
success:
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
id: null,
|
|
688
|
-
recordName: recordName,
|
|
689
|
-
userId: null,
|
|
690
|
-
subjectType: subjectType,
|
|
691
|
-
subjectId: subjectId,
|
|
692
|
-
resourceKind: publicPermission.resourceKind,
|
|
693
|
-
action: publicPermission.action,
|
|
694
|
-
marker: publicPermission.marker,
|
|
695
|
-
options: {},
|
|
696
|
-
expireTimeMs: null,
|
|
697
|
-
},
|
|
698
|
-
explanation: publicPermission.marker === PUBLIC_READ_MARKER
|
|
699
|
-
? 'Resource has the publicRead marker.'
|
|
700
|
-
: 'Resource has the publicWrite marker.',
|
|
764
|
+
success: false,
|
|
765
|
+
errorCode: 'not_logged_in',
|
|
766
|
+
errorMessage: 'You must be logged in in order to use this record key.',
|
|
701
767
|
};
|
|
702
768
|
}
|
|
703
|
-
|
|
769
|
+
return {
|
|
770
|
+
success: true,
|
|
771
|
+
recordName: context.recordName,
|
|
772
|
+
permission: {
|
|
773
|
+
id: null,
|
|
774
|
+
recordName: recordName,
|
|
775
|
+
userId: null,
|
|
776
|
+
// Record owners are treated as if they are admins in the record
|
|
777
|
+
subjectType: 'role',
|
|
778
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
779
|
+
// Admins get all access to all resources in a record
|
|
780
|
+
resourceKind: request.resourceKind,
|
|
781
|
+
action: request.action,
|
|
782
|
+
marker: markers[0],
|
|
783
|
+
options: {},
|
|
784
|
+
expireTimeMs: null,
|
|
785
|
+
},
|
|
786
|
+
explanation: 'A recordKey was used.',
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
if (subjectType === 'user' && subjectId) {
|
|
790
|
+
if (subjectId === context.recordOwnerId) {
|
|
704
791
|
return {
|
|
705
792
|
success: true,
|
|
706
793
|
recordName: recordName,
|
|
@@ -718,130 +805,165 @@ export class PolicyController {
|
|
|
718
805
|
options: {},
|
|
719
806
|
expireTimeMs: null,
|
|
720
807
|
},
|
|
721
|
-
explanation:
|
|
808
|
+
explanation: 'User is the owner of the record.',
|
|
722
809
|
};
|
|
723
810
|
}
|
|
724
|
-
if (context.
|
|
725
|
-
context.
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
!subjectId) {
|
|
731
|
-
return {
|
|
732
|
-
success: false,
|
|
733
|
-
errorCode: 'not_logged_in',
|
|
734
|
-
errorMessage: 'You must be logged in in order to use this record key.',
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
return {
|
|
738
|
-
success: true,
|
|
739
|
-
recordName: context.recordName,
|
|
740
|
-
permission: {
|
|
741
|
-
id: null,
|
|
742
|
-
recordName: recordName,
|
|
743
|
-
userId: null,
|
|
744
|
-
// Record owners are treated as if they are admins in the record
|
|
745
|
-
subjectType: 'role',
|
|
746
|
-
subjectId: ADMIN_ROLE_NAME,
|
|
747
|
-
// Admins get all access to all resources in a record
|
|
748
|
-
resourceKind: request.resourceKind,
|
|
749
|
-
action: request.action,
|
|
750
|
-
marker: markers[0],
|
|
751
|
-
options: {},
|
|
752
|
-
expireTimeMs: null,
|
|
753
|
-
},
|
|
754
|
-
explanation: 'A recordKey was used.',
|
|
755
|
-
};
|
|
756
|
-
}
|
|
757
|
-
if (subjectType === 'user' && subjectId) {
|
|
758
|
-
if (subjectId === context.recordOwnerId) {
|
|
759
|
-
return {
|
|
760
|
-
success: true,
|
|
761
|
-
recordName: recordName,
|
|
762
|
-
permission: {
|
|
763
|
-
id: null,
|
|
811
|
+
else if (context.recordStudioMembers) {
|
|
812
|
+
const member = context.recordStudioMembers.find((m) => m.userId === subjectId);
|
|
813
|
+
if (member) {
|
|
814
|
+
if (member.role === 'admin') {
|
|
815
|
+
return {
|
|
816
|
+
success: true,
|
|
764
817
|
recordName: recordName,
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
818
|
+
permission: {
|
|
819
|
+
id: null,
|
|
820
|
+
recordName: recordName,
|
|
821
|
+
userId: null,
|
|
822
|
+
// Admins in a studio are treated as if they are admins in the record.
|
|
823
|
+
subjectType: 'role',
|
|
824
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
825
|
+
// Admins get all access to all resources in a record
|
|
826
|
+
resourceKind: null,
|
|
827
|
+
action: null,
|
|
828
|
+
marker: markers[0],
|
|
829
|
+
options: {},
|
|
830
|
+
// No expiration
|
|
831
|
+
expireTimeMs: null,
|
|
832
|
+
},
|
|
833
|
+
explanation: "User is an admin in the record's studio.",
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
else if (member.role === 'member') {
|
|
837
|
+
let isAssigningDefaultMarker = (request.resourceKind === 'marker' &&
|
|
838
|
+
request.resourceId ===
|
|
839
|
+
PUBLIC_READ_MARKER) ||
|
|
840
|
+
request.resourceId === PRIVATE_MARKER;
|
|
841
|
+
if (isAssigningDefaultMarker ||
|
|
842
|
+
isAllowedStudioMemberResource(request.resourceKind, request.action)) {
|
|
783
843
|
return {
|
|
784
844
|
success: true,
|
|
785
845
|
recordName: recordName,
|
|
786
846
|
permission: {
|
|
787
847
|
id: null,
|
|
788
848
|
recordName: recordName,
|
|
789
|
-
|
|
790
|
-
//
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
849
|
+
// Members in a studio are treated as if they are granted direct access to most resources
|
|
850
|
+
// in the record.
|
|
851
|
+
userId: subjectId,
|
|
852
|
+
subjectType: 'user',
|
|
853
|
+
subjectId: subjectId,
|
|
854
|
+
// Not all actions or resources are granted though
|
|
855
|
+
resourceKind: request.resourceKind,
|
|
856
|
+
action: request.action,
|
|
796
857
|
marker: markers[0],
|
|
797
858
|
options: {},
|
|
798
|
-
// No expiration
|
|
799
859
|
expireTimeMs: null,
|
|
800
860
|
},
|
|
801
|
-
explanation: "User is
|
|
861
|
+
explanation: "User is a member in the record's studio.",
|
|
802
862
|
};
|
|
803
863
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
else if (subjectType === 'inst' && subjectId) {
|
|
869
|
+
const instId = parseInstId(subjectId);
|
|
870
|
+
if (!instId) {
|
|
871
|
+
return {
|
|
872
|
+
success: false,
|
|
873
|
+
errorCode: 'unacceptable_request',
|
|
874
|
+
errorMessage: 'Invalid inst ID. It must contain a forward slash',
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
const entitlementFeature = getEntitlementFeatureForAction(request.resourceKind, request.action);
|
|
878
|
+
let hasPackages = false;
|
|
879
|
+
if (entitlementFeature) {
|
|
880
|
+
const loadedPackages = (_b = (await ((_a = this._insts) === null || _a === void 0 ? void 0 : _a.listLoadedPackages(instId.recordName, instId.inst)))) !== null && _b !== void 0 ? _b : [];
|
|
881
|
+
const grantedEntitlements = await this._policies.listGrantedEntitlementsByFeatureAndUserId(loadedPackages.map((p) => p.packageId), entitlementFeature, context.userId, context.recordName, Date.now());
|
|
882
|
+
if ((loadedPackages === null || loadedPackages === void 0 ? void 0 : loadedPackages.length) > 0 ||
|
|
883
|
+
(grantedEntitlements === null || grantedEntitlements === void 0 ? void 0 : grantedEntitlements.length) > 0) {
|
|
884
|
+
hasPackages = true;
|
|
885
|
+
}
|
|
886
|
+
if (grantedEntitlements && grantedEntitlements.length > 0) {
|
|
887
|
+
// check scope
|
|
888
|
+
const entitlement = grantedEntitlements.find((entitlement) => {
|
|
889
|
+
if (entitlement.revokeTimeMs === null &&
|
|
890
|
+
entitlement.scope === 'designated' &&
|
|
891
|
+
entitlement.recordName ===
|
|
892
|
+
context.recordName) {
|
|
893
|
+
// Entitlement is for the current record
|
|
894
|
+
return true;
|
|
895
|
+
}
|
|
896
|
+
else {
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
if (entitlement) {
|
|
901
|
+
const loadedPackage = loadedPackages.find((lp) => lp.packageId === entitlement.packageId);
|
|
902
|
+
return {
|
|
903
|
+
success: true,
|
|
904
|
+
recordName,
|
|
905
|
+
permission: {
|
|
906
|
+
id: null,
|
|
907
|
+
recordName,
|
|
908
|
+
userId: context.userId,
|
|
909
|
+
subjectType: 'inst',
|
|
910
|
+
subjectId: subjectId,
|
|
911
|
+
// Not all actions or resources are granted though
|
|
912
|
+
resourceKind: request.resourceKind,
|
|
913
|
+
resourceId: request.resourceId,
|
|
914
|
+
action: request.action,
|
|
915
|
+
options: {},
|
|
916
|
+
expireTimeMs: entitlement.expireTimeMs,
|
|
917
|
+
},
|
|
918
|
+
entitlementGrant: {
|
|
919
|
+
...entitlement,
|
|
920
|
+
loadedPackage,
|
|
921
|
+
},
|
|
922
|
+
explanation: `Inst has entitlement.`,
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
if (hasPackages) {
|
|
927
|
+
const firstPackage = loadedPackages[0];
|
|
928
|
+
const pkg = await ((_c = this._packageVersions) === null || _c === void 0 ? void 0 : _c.getItemById(firstPackage.packageVersionId));
|
|
929
|
+
if (pkg === null || pkg === void 0 ? void 0 : pkg.item) {
|
|
930
|
+
const canRecommendEntitlement = pkg.item.entitlements.some((e) => {
|
|
931
|
+
var _a, _b;
|
|
932
|
+
if (e.scope === 'personal' &&
|
|
933
|
+
context.userId === context.recordName) {
|
|
934
|
+
return true;
|
|
935
|
+
}
|
|
936
|
+
else if (e.scope === 'owned' &&
|
|
937
|
+
context.recordOwnerId === context.userId) {
|
|
938
|
+
return true;
|
|
939
|
+
}
|
|
940
|
+
else if (e.scope === 'studio' &&
|
|
941
|
+
((_a = context.recordStudioMembers) === null || _a === void 0 ? void 0 : _a.some((m) => m.userId === context.userId))) {
|
|
942
|
+
return true;
|
|
943
|
+
}
|
|
944
|
+
else if (e.scope === 'designated' &&
|
|
945
|
+
((_b = e.designatedRecords) === null || _b === void 0 ? void 0 : _b.includes(context.recordName))) {
|
|
946
|
+
return true;
|
|
947
|
+
}
|
|
948
|
+
else if (e.scope === 'shared') {
|
|
949
|
+
return true;
|
|
831
950
|
}
|
|
951
|
+
return false;
|
|
952
|
+
});
|
|
953
|
+
if (canRecommendEntitlement) {
|
|
954
|
+
recommendedEntitlement = {
|
|
955
|
+
feature: entitlementFeature,
|
|
956
|
+
scope: 'designated',
|
|
957
|
+
recordName: context.recordName,
|
|
958
|
+
packageId: loadedPackages[0].packageId,
|
|
959
|
+
};
|
|
832
960
|
}
|
|
833
961
|
}
|
|
834
962
|
}
|
|
835
963
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
return {
|
|
840
|
-
success: false,
|
|
841
|
-
errorCode: 'unacceptable_request',
|
|
842
|
-
errorMessage: 'Invalid inst ID. It must contain a forward slash',
|
|
843
|
-
};
|
|
844
|
-
}
|
|
964
|
+
// Automatic permissions don't apply to insts with packages
|
|
965
|
+
// TODO: Maybe add a flag for insts to choose whether they want automatic permissions or if they have to explicitly grant them or use packages
|
|
966
|
+
if (!hasPackages) {
|
|
845
967
|
if (instId.recordName) {
|
|
846
968
|
if (instId.recordName === recordName) {
|
|
847
969
|
return {
|
|
@@ -864,7 +986,7 @@ export class PolicyController {
|
|
|
864
986
|
explanation: `Inst is owned by the record.`,
|
|
865
987
|
};
|
|
866
988
|
}
|
|
867
|
-
const instRecord =
|
|
989
|
+
const instRecord = await this._records.validateRecordName(instId.recordName, context.userId);
|
|
868
990
|
if (instRecord.success === false) {
|
|
869
991
|
return instRecord;
|
|
870
992
|
}
|
|
@@ -914,95 +1036,96 @@ export class PolicyController {
|
|
|
914
1036
|
}
|
|
915
1037
|
}
|
|
916
1038
|
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
success: true,
|
|
928
|
-
recordName: recordName,
|
|
929
|
-
permission: {
|
|
930
|
-
id: null,
|
|
931
|
-
recordName: recordName,
|
|
932
|
-
userId: null,
|
|
933
|
-
// Admins in a studio are treated as if they are admins in the record.
|
|
934
|
-
subjectType: 'role',
|
|
935
|
-
subjectId: ADMIN_ROLE_NAME,
|
|
936
|
-
// Admins get all access to all resources in a record
|
|
937
|
-
resourceKind: null,
|
|
938
|
-
action: null,
|
|
939
|
-
marker: markers[0],
|
|
940
|
-
options: {},
|
|
941
|
-
// No expiration
|
|
942
|
-
expireTimeMs: role.expireTimeMs,
|
|
943
|
-
},
|
|
944
|
-
explanation: `${kindString} is assigned the "${ADMIN_ROLE_NAME}" role.`,
|
|
945
|
-
};
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
let permission = null;
|
|
949
|
-
if (request.resourceId) {
|
|
950
|
-
const result = yield this._policies.getPermissionForSubjectAndResource(subjectType, subjectId, recordName, request.resourceKind, request.resourceId, request.action, Date.now());
|
|
951
|
-
if (result.success === false) {
|
|
952
|
-
return result;
|
|
953
|
-
}
|
|
954
|
-
permission = result.permissionAssignment;
|
|
955
|
-
}
|
|
956
|
-
if (!permission) {
|
|
957
|
-
const result = yield this._policies.getPermissionForSubjectAndMarkers(subjectType, subjectId, recordName, request.resourceKind, markers, request.action, Date.now());
|
|
958
|
-
if (result.success === false) {
|
|
959
|
-
return result;
|
|
960
|
-
}
|
|
961
|
-
permission = result.permissionAssignment;
|
|
962
|
-
}
|
|
963
|
-
if (permission) {
|
|
1039
|
+
}
|
|
1040
|
+
if (subjectId) {
|
|
1041
|
+
if (subjectType === 'inst' || subjectType === 'user') {
|
|
1042
|
+
// check for admin role
|
|
1043
|
+
const roles = subjectType === 'user'
|
|
1044
|
+
? await this._policies.listRolesForUser(recordName, subjectId)
|
|
1045
|
+
: await this._policies.listRolesForInst(recordName, subjectId);
|
|
1046
|
+
const role = roles.find((r) => r.role === ADMIN_ROLE_NAME);
|
|
1047
|
+
if (role) {
|
|
1048
|
+
const kindString = subjectType === 'user' ? 'User' : 'Inst';
|
|
964
1049
|
return {
|
|
965
1050
|
success: true,
|
|
966
|
-
recordName,
|
|
967
|
-
permission:
|
|
968
|
-
|
|
1051
|
+
recordName: recordName,
|
|
1052
|
+
permission: {
|
|
1053
|
+
id: null,
|
|
1054
|
+
recordName: recordName,
|
|
1055
|
+
userId: null,
|
|
1056
|
+
// Admins in a studio are treated as if they are admins in the record.
|
|
1057
|
+
subjectType: 'role',
|
|
1058
|
+
subjectId: ADMIN_ROLE_NAME,
|
|
1059
|
+
// Admins get all access to all resources in a record
|
|
1060
|
+
resourceKind: null,
|
|
1061
|
+
action: null,
|
|
1062
|
+
marker: markers[0],
|
|
1063
|
+
options: {},
|
|
1064
|
+
// No expiration
|
|
1065
|
+
expireTimeMs: role.expireTimeMs,
|
|
1066
|
+
},
|
|
1067
|
+
explanation: `${kindString} is assigned the "${ADMIN_ROLE_NAME}" role.`,
|
|
969
1068
|
};
|
|
970
1069
|
}
|
|
971
1070
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
(
|
|
975
|
-
|
|
1071
|
+
let permission = null;
|
|
1072
|
+
if (request.resourceId) {
|
|
1073
|
+
const result = await this._policies.getPermissionForSubjectAndResource(subjectType, subjectId, recordName, request.resourceKind, request.resourceId, request.action, Date.now());
|
|
1074
|
+
if (result.success === false) {
|
|
1075
|
+
return result;
|
|
1076
|
+
}
|
|
1077
|
+
permission = result.permissionAssignment;
|
|
1078
|
+
}
|
|
1079
|
+
if (!permission) {
|
|
1080
|
+
const result = await this._policies.getPermissionForSubjectAndMarkers(subjectType, subjectId, recordName, request.resourceKind, markers, request.action, Date.now());
|
|
1081
|
+
if (result.success === false) {
|
|
1082
|
+
return result;
|
|
1083
|
+
}
|
|
1084
|
+
permission = result.permissionAssignment;
|
|
1085
|
+
}
|
|
1086
|
+
if (permission) {
|
|
976
1087
|
return {
|
|
977
|
-
success:
|
|
978
|
-
|
|
979
|
-
|
|
1088
|
+
success: true,
|
|
1089
|
+
recordName,
|
|
1090
|
+
permission: permission,
|
|
1091
|
+
explanation: explainationForPermissionAssignment(subjectType, permission),
|
|
980
1092
|
};
|
|
981
1093
|
}
|
|
982
|
-
return {
|
|
983
|
-
success: false,
|
|
984
|
-
errorCode: 'not_authorized',
|
|
985
|
-
errorMessage: 'You are not authorized to perform this action.',
|
|
986
|
-
reason: {
|
|
987
|
-
type: 'missing_permission',
|
|
988
|
-
recordName: recordName,
|
|
989
|
-
subjectType: subjectType,
|
|
990
|
-
subjectId: subjectId,
|
|
991
|
-
resourceKind: request.resourceKind,
|
|
992
|
-
resourceId: request.resourceId,
|
|
993
|
-
action: request.action,
|
|
994
|
-
},
|
|
995
|
-
};
|
|
996
1094
|
}
|
|
997
|
-
|
|
998
|
-
|
|
1095
|
+
if (context.sendNotLoggedIn &&
|
|
1096
|
+
!subjectId &&
|
|
1097
|
+
(!context.recordKeyProvided ||
|
|
1098
|
+
!isAllowedRecordKeyResource(request.resourceKind, request.action))) {
|
|
999
1099
|
return {
|
|
1000
1100
|
success: false,
|
|
1001
|
-
errorCode: '
|
|
1002
|
-
errorMessage: '
|
|
1101
|
+
errorCode: 'not_logged_in',
|
|
1102
|
+
errorMessage: 'The user must be logged in. Please provide a sessionKey or a recordKey.',
|
|
1003
1103
|
};
|
|
1004
1104
|
}
|
|
1005
|
-
|
|
1105
|
+
return {
|
|
1106
|
+
success: false,
|
|
1107
|
+
errorCode: 'not_authorized',
|
|
1108
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
1109
|
+
reason: {
|
|
1110
|
+
type: 'missing_permission',
|
|
1111
|
+
recordName: recordName,
|
|
1112
|
+
subjectType: subjectType,
|
|
1113
|
+
subjectId: subjectId,
|
|
1114
|
+
resourceKind: request.resourceKind,
|
|
1115
|
+
resourceId: request.resourceId,
|
|
1116
|
+
action: request.action,
|
|
1117
|
+
},
|
|
1118
|
+
recommendedEntitlement,
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
catch (err) {
|
|
1122
|
+
console.error('[PolicyController] A server error occurred while authorizing a subject.', err);
|
|
1123
|
+
return {
|
|
1124
|
+
success: false,
|
|
1125
|
+
errorCode: 'server_error',
|
|
1126
|
+
errorMessage: 'A server error occurred.',
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1006
1129
|
}
|
|
1007
1130
|
/**
|
|
1008
1131
|
* Gets the list of permissions in the given record.
|
|
@@ -1010,70 +1133,68 @@ export class PolicyController {
|
|
|
1010
1133
|
* @param userId The ID of the currently logged in user.
|
|
1011
1134
|
* @param instances The instances that are loaded.
|
|
1012
1135
|
*/
|
|
1013
|
-
listPermissions(recordKeyOrRecordName, userId, instances) {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
return context;
|
|
1022
|
-
}
|
|
1023
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1024
|
-
userId,
|
|
1025
|
-
instances,
|
|
1026
|
-
resourceKind: 'marker',
|
|
1027
|
-
action: 'list',
|
|
1028
|
-
markers: [ACCOUNT_MARKER],
|
|
1029
|
-
});
|
|
1030
|
-
if (authorization.success === false) {
|
|
1031
|
-
return authorization;
|
|
1032
|
-
}
|
|
1033
|
-
const recordName = context.context.recordName;
|
|
1034
|
-
const result = yield this._policies.listPermissionsInRecord(recordName);
|
|
1035
|
-
if (result.success === false) {
|
|
1036
|
-
return result;
|
|
1037
|
-
}
|
|
1038
|
-
return {
|
|
1039
|
-
success: true,
|
|
1040
|
-
recordName,
|
|
1041
|
-
resourcePermissions: result.resourceAssignments.map((r) => ({
|
|
1042
|
-
id: r.id,
|
|
1043
|
-
recordName: r.recordName,
|
|
1044
|
-
subjectType: r.subjectType,
|
|
1045
|
-
subjectId: r.subjectId,
|
|
1046
|
-
resourceKind: r.resourceKind,
|
|
1047
|
-
action: r.action,
|
|
1048
|
-
resourceId: r.resourceId,
|
|
1049
|
-
options: r.options,
|
|
1050
|
-
expireTimeMs: r.expireTimeMs,
|
|
1051
|
-
})),
|
|
1052
|
-
markerPermissions: result.markerAssignments.map((r) => ({
|
|
1053
|
-
id: r.id,
|
|
1054
|
-
recordName: r.recordName,
|
|
1055
|
-
subjectType: r.subjectType,
|
|
1056
|
-
subjectId: r.subjectId,
|
|
1057
|
-
resourceKind: r.resourceKind,
|
|
1058
|
-
action: r.action,
|
|
1059
|
-
marker: r.marker,
|
|
1060
|
-
options: r.options,
|
|
1061
|
-
expireTimeMs: r.expireTimeMs,
|
|
1062
|
-
})),
|
|
1063
|
-
};
|
|
1136
|
+
async listPermissions(recordKeyOrRecordName, userId, instances) {
|
|
1137
|
+
try {
|
|
1138
|
+
const context = await this.constructAuthorizationContext({
|
|
1139
|
+
recordKeyOrRecordName,
|
|
1140
|
+
userId,
|
|
1141
|
+
});
|
|
1142
|
+
if (context.success === false) {
|
|
1143
|
+
return context;
|
|
1064
1144
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
};
|
|
1145
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1146
|
+
userId,
|
|
1147
|
+
instances,
|
|
1148
|
+
resourceKind: 'marker',
|
|
1149
|
+
action: 'list',
|
|
1150
|
+
markers: [ACCOUNT_MARKER],
|
|
1151
|
+
});
|
|
1152
|
+
if (authorization.success === false) {
|
|
1153
|
+
return authorization;
|
|
1075
1154
|
}
|
|
1076
|
-
|
|
1155
|
+
const recordName = context.context.recordName;
|
|
1156
|
+
const result = await this._policies.listPermissionsInRecord(recordName);
|
|
1157
|
+
if (result.success === false) {
|
|
1158
|
+
return result;
|
|
1159
|
+
}
|
|
1160
|
+
return {
|
|
1161
|
+
success: true,
|
|
1162
|
+
recordName,
|
|
1163
|
+
resourcePermissions: result.resourceAssignments.map((r) => ({
|
|
1164
|
+
id: r.id,
|
|
1165
|
+
recordName: r.recordName,
|
|
1166
|
+
subjectType: r.subjectType,
|
|
1167
|
+
subjectId: r.subjectId,
|
|
1168
|
+
resourceKind: r.resourceKind,
|
|
1169
|
+
action: r.action,
|
|
1170
|
+
resourceId: r.resourceId,
|
|
1171
|
+
options: r.options,
|
|
1172
|
+
expireTimeMs: r.expireTimeMs,
|
|
1173
|
+
})),
|
|
1174
|
+
markerPermissions: result.markerAssignments.map((r) => ({
|
|
1175
|
+
id: r.id,
|
|
1176
|
+
recordName: r.recordName,
|
|
1177
|
+
subjectType: r.subjectType,
|
|
1178
|
+
subjectId: r.subjectId,
|
|
1179
|
+
resourceKind: r.resourceKind,
|
|
1180
|
+
action: r.action,
|
|
1181
|
+
marker: r.marker,
|
|
1182
|
+
options: r.options,
|
|
1183
|
+
expireTimeMs: r.expireTimeMs,
|
|
1184
|
+
})),
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
catch (err) {
|
|
1188
|
+
const span = trace.getActiveSpan();
|
|
1189
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1190
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1191
|
+
console.error('[PolicyController] A server error occurred while listing permissions.', err);
|
|
1192
|
+
return {
|
|
1193
|
+
success: false,
|
|
1194
|
+
errorCode: 'server_error',
|
|
1195
|
+
errorMessage: 'A server error occurred.',
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1077
1198
|
}
|
|
1078
1199
|
/**
|
|
1079
1200
|
* Gets the list of permissions that have been assigned to the given marker.
|
|
@@ -1082,57 +1203,55 @@ export class PolicyController {
|
|
|
1082
1203
|
* @param userId The ID of the currently logged in user.
|
|
1083
1204
|
* @param instances The instances that are loaded.
|
|
1084
1205
|
*/
|
|
1085
|
-
listPermissionsForMarker(recordKeyOrRecordName, marker, userId, instances) {
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
return context;
|
|
1095
|
-
}
|
|
1096
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1097
|
-
userId,
|
|
1098
|
-
instances,
|
|
1099
|
-
resourceKind: 'marker',
|
|
1100
|
-
action: 'list',
|
|
1101
|
-
markers: [ACCOUNT_MARKER],
|
|
1102
|
-
});
|
|
1103
|
-
if (authorization.success === false) {
|
|
1104
|
-
return authorization;
|
|
1105
|
-
}
|
|
1106
|
-
const recordName = context.context.recordName;
|
|
1107
|
-
const result = yield this._policies.listPermissionsForMarker(recordName, marker);
|
|
1108
|
-
return {
|
|
1109
|
-
success: true,
|
|
1110
|
-
recordName,
|
|
1111
|
-
markerPermissions: result.map((r) => ({
|
|
1112
|
-
id: r.id,
|
|
1113
|
-
recordName: r.recordName,
|
|
1114
|
-
subjectType: r.subjectType,
|
|
1115
|
-
subjectId: r.subjectId,
|
|
1116
|
-
resourceKind: r.resourceKind,
|
|
1117
|
-
action: r.action,
|
|
1118
|
-
marker: r.marker,
|
|
1119
|
-
options: r.options,
|
|
1120
|
-
expireTimeMs: r.expireTimeMs,
|
|
1121
|
-
})),
|
|
1122
|
-
};
|
|
1206
|
+
async listPermissionsForMarker(recordKeyOrRecordName, marker, userId, instances) {
|
|
1207
|
+
try {
|
|
1208
|
+
marker = getRootMarker(marker);
|
|
1209
|
+
const context = await this.constructAuthorizationContext({
|
|
1210
|
+
recordKeyOrRecordName,
|
|
1211
|
+
userId,
|
|
1212
|
+
});
|
|
1213
|
+
if (context.success === false) {
|
|
1214
|
+
return context;
|
|
1123
1215
|
}
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
};
|
|
1216
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1217
|
+
userId,
|
|
1218
|
+
instances,
|
|
1219
|
+
resourceKind: 'marker',
|
|
1220
|
+
action: 'list',
|
|
1221
|
+
markers: [ACCOUNT_MARKER],
|
|
1222
|
+
});
|
|
1223
|
+
if (authorization.success === false) {
|
|
1224
|
+
return authorization;
|
|
1134
1225
|
}
|
|
1135
|
-
|
|
1226
|
+
const recordName = context.context.recordName;
|
|
1227
|
+
const result = await this._policies.listPermissionsForMarker(recordName, marker);
|
|
1228
|
+
return {
|
|
1229
|
+
success: true,
|
|
1230
|
+
recordName,
|
|
1231
|
+
markerPermissions: result.map((r) => ({
|
|
1232
|
+
id: r.id,
|
|
1233
|
+
recordName: r.recordName,
|
|
1234
|
+
subjectType: r.subjectType,
|
|
1235
|
+
subjectId: r.subjectId,
|
|
1236
|
+
resourceKind: r.resourceKind,
|
|
1237
|
+
action: r.action,
|
|
1238
|
+
marker: r.marker,
|
|
1239
|
+
options: r.options,
|
|
1240
|
+
expireTimeMs: r.expireTimeMs,
|
|
1241
|
+
})),
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
catch (err) {
|
|
1245
|
+
const span = trace.getActiveSpan();
|
|
1246
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1247
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1248
|
+
console.error('[PolicyController] A server error occurred while listing permissions for marker.', err);
|
|
1249
|
+
return {
|
|
1250
|
+
success: false,
|
|
1251
|
+
errorCode: 'server_error',
|
|
1252
|
+
errorMessage: 'A server error occurred.',
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1136
1255
|
}
|
|
1137
1256
|
/**
|
|
1138
1257
|
* Gets the list of permissions that have been assigned to the given marker.
|
|
@@ -1142,406 +1261,341 @@ export class PolicyController {
|
|
|
1142
1261
|
* @param userId The ID of the currently logged in user.
|
|
1143
1262
|
* @param instances The instances that are loaded.
|
|
1144
1263
|
*/
|
|
1145
|
-
listPermissionsForResource(recordKeyOrRecordName, resourceKind, resourceId, userId, instances) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
return context;
|
|
1154
|
-
}
|
|
1155
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1156
|
-
userId,
|
|
1157
|
-
instances,
|
|
1158
|
-
resourceKind: 'marker',
|
|
1159
|
-
action: 'list',
|
|
1160
|
-
markers: [ACCOUNT_MARKER],
|
|
1161
|
-
});
|
|
1162
|
-
if (authorization.success === false) {
|
|
1163
|
-
return authorization;
|
|
1164
|
-
}
|
|
1165
|
-
const recordName = context.context.recordName;
|
|
1166
|
-
const result = yield this._policies.listPermissionsForResource(recordName, resourceKind, resourceId);
|
|
1167
|
-
return {
|
|
1168
|
-
success: true,
|
|
1169
|
-
recordName,
|
|
1170
|
-
resourcePermissions: result.map((r) => ({
|
|
1171
|
-
id: r.id,
|
|
1172
|
-
recordName: r.recordName,
|
|
1173
|
-
subjectType: r.subjectType,
|
|
1174
|
-
subjectId: r.subjectId,
|
|
1175
|
-
resourceKind: r.resourceKind,
|
|
1176
|
-
action: r.action,
|
|
1177
|
-
resourceId: r.resourceId,
|
|
1178
|
-
options: r.options,
|
|
1179
|
-
expireTimeMs: r.expireTimeMs,
|
|
1180
|
-
})),
|
|
1181
|
-
};
|
|
1264
|
+
async listPermissionsForResource(recordKeyOrRecordName, resourceKind, resourceId, userId, instances) {
|
|
1265
|
+
try {
|
|
1266
|
+
const context = await this.constructAuthorizationContext({
|
|
1267
|
+
recordKeyOrRecordName,
|
|
1268
|
+
userId,
|
|
1269
|
+
});
|
|
1270
|
+
if (context.success === false) {
|
|
1271
|
+
return context;
|
|
1182
1272
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
};
|
|
1273
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1274
|
+
userId,
|
|
1275
|
+
instances,
|
|
1276
|
+
resourceKind: 'marker',
|
|
1277
|
+
action: 'list',
|
|
1278
|
+
markers: [ACCOUNT_MARKER],
|
|
1279
|
+
});
|
|
1280
|
+
if (authorization.success === false) {
|
|
1281
|
+
return authorization;
|
|
1193
1282
|
}
|
|
1194
|
-
|
|
1283
|
+
const recordName = context.context.recordName;
|
|
1284
|
+
const result = await this._policies.listPermissionsForResource(recordName, resourceKind, resourceId);
|
|
1285
|
+
return {
|
|
1286
|
+
success: true,
|
|
1287
|
+
recordName,
|
|
1288
|
+
resourcePermissions: result.map((r) => ({
|
|
1289
|
+
id: r.id,
|
|
1290
|
+
recordName: r.recordName,
|
|
1291
|
+
subjectType: r.subjectType,
|
|
1292
|
+
subjectId: r.subjectId,
|
|
1293
|
+
resourceKind: r.resourceKind,
|
|
1294
|
+
action: r.action,
|
|
1295
|
+
resourceId: r.resourceId,
|
|
1296
|
+
options: r.options,
|
|
1297
|
+
expireTimeMs: r.expireTimeMs,
|
|
1298
|
+
})),
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
catch (err) {
|
|
1302
|
+
const span = trace.getActiveSpan();
|
|
1303
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1304
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1305
|
+
console.error('[PolicyController] A server error occurred while listing permissions for resource.', err);
|
|
1306
|
+
return {
|
|
1307
|
+
success: false,
|
|
1308
|
+
errorCode: 'server_error',
|
|
1309
|
+
errorMessage: 'A server error occurred.',
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1195
1312
|
}
|
|
1196
1313
|
/**
|
|
1197
1314
|
* Attempts to grant a permission to a marker.
|
|
1198
1315
|
* @param request The request for the operation.
|
|
1199
1316
|
*/
|
|
1200
|
-
grantMarkerPermission(request) {
|
|
1317
|
+
async grantMarkerPermission(request) {
|
|
1201
1318
|
var _a, _b, _c;
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
if (context.success === false) {
|
|
1210
|
-
return {
|
|
1211
|
-
success: false,
|
|
1212
|
-
errorCode: context.errorCode,
|
|
1213
|
-
errorMessage: context.errorMessage,
|
|
1214
|
-
};
|
|
1215
|
-
}
|
|
1216
|
-
const marker = getRootMarker(request.marker);
|
|
1217
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1218
|
-
action: 'grantPermission',
|
|
1219
|
-
resourceKind: 'marker',
|
|
1220
|
-
resourceId: marker,
|
|
1221
|
-
markers: [ACCOUNT_MARKER],
|
|
1222
|
-
userId: request.userId,
|
|
1223
|
-
instances: request.instances,
|
|
1224
|
-
});
|
|
1225
|
-
if (authorization.success === false) {
|
|
1226
|
-
return authorization;
|
|
1227
|
-
}
|
|
1228
|
-
const recordName = context.context.recordName;
|
|
1229
|
-
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);
|
|
1230
|
-
if (assignmentResult.success === false) {
|
|
1231
|
-
return assignmentResult;
|
|
1232
|
-
}
|
|
1233
|
-
console.log(`[PolicyController] [grantMarkerPermission] [userId: ${request.userId}, recordName: ${recordName}, subjectType: ${request.permission.subjectType}, subjectId: ${request.permission.subjectId}, marker: ${marker}, resourceKind: ${(_a = request.permission.resourceKind) !== null && _a !== void 0 ? _a : '(null)'}, action: ${(_b = request.permission.action) !== null && _b !== void 0 ? _b : '(null)'}, expireTimeMs: ${(_c = request.permission.expireTimeMs) !== null && _c !== void 0 ? _c : '(null)'}, permissionId: ${assignmentResult.permissionAssignment.id}] Granted marker permission.`);
|
|
1234
|
-
return {
|
|
1235
|
-
success: true,
|
|
1236
|
-
};
|
|
1237
|
-
}
|
|
1238
|
-
catch (err) {
|
|
1239
|
-
const span = trace.getActiveSpan();
|
|
1240
|
-
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1241
|
-
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1242
|
-
console.error('[PolicyController] A server error occurred while granting a marker permission.', err);
|
|
1319
|
+
try {
|
|
1320
|
+
const baseRequest = {
|
|
1321
|
+
recordKeyOrRecordName: request.recordKeyOrRecordName,
|
|
1322
|
+
userId: request.userId,
|
|
1323
|
+
};
|
|
1324
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1325
|
+
if (context.success === false) {
|
|
1243
1326
|
return {
|
|
1244
1327
|
success: false,
|
|
1245
|
-
errorCode:
|
|
1246
|
-
errorMessage:
|
|
1328
|
+
errorCode: context.errorCode,
|
|
1329
|
+
errorMessage: context.errorMessage,
|
|
1247
1330
|
};
|
|
1248
1331
|
}
|
|
1249
|
-
|
|
1332
|
+
const marker = getRootMarker(request.marker);
|
|
1333
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1334
|
+
action: 'grantPermission',
|
|
1335
|
+
resourceKind: 'marker',
|
|
1336
|
+
resourceId: marker,
|
|
1337
|
+
markers: [ACCOUNT_MARKER],
|
|
1338
|
+
userId: request.userId,
|
|
1339
|
+
instances: request.instances,
|
|
1340
|
+
});
|
|
1341
|
+
if (authorization.success === false) {
|
|
1342
|
+
return authorization;
|
|
1343
|
+
}
|
|
1344
|
+
const recordName = context.context.recordName;
|
|
1345
|
+
const assignmentResult = await this._policies.assignPermissionToSubjectAndMarker(recordName, request.permission.subjectType, request.permission.subjectId, request.permission.resourceKind, marker, request.permission.action, request.permission.options, request.permission.expireTimeMs);
|
|
1346
|
+
if (assignmentResult.success === false) {
|
|
1347
|
+
return assignmentResult;
|
|
1348
|
+
}
|
|
1349
|
+
console.log(`[PolicyController] [grantMarkerPermission] [userId: ${request.userId}, recordName: ${recordName}, subjectType: ${request.permission.subjectType}, subjectId: ${request.permission.subjectId}, marker: ${marker}, resourceKind: ${(_a = request.permission.resourceKind) !== null && _a !== void 0 ? _a : '(null)'}, action: ${(_b = request.permission.action) !== null && _b !== void 0 ? _b : '(null)'}, expireTimeMs: ${(_c = request.permission.expireTimeMs) !== null && _c !== void 0 ? _c : '(null)'}, permissionId: ${assignmentResult.permissionAssignment.id}] Granted marker permission.`);
|
|
1350
|
+
return {
|
|
1351
|
+
success: true,
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
catch (err) {
|
|
1355
|
+
const span = trace.getActiveSpan();
|
|
1356
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1357
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1358
|
+
console.error('[PolicyController] A server error occurred while granting a marker permission.', err);
|
|
1359
|
+
return {
|
|
1360
|
+
success: false,
|
|
1361
|
+
errorCode: 'server_error',
|
|
1362
|
+
errorMessage: 'A server error occurred.',
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1250
1365
|
}
|
|
1251
1366
|
/**
|
|
1252
1367
|
* Attempts to revoke a permission from a marker.
|
|
1253
1368
|
* @param request The request for the operation.
|
|
1254
1369
|
*/
|
|
1255
|
-
revokeMarkerPermission(request) {
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
if (!permission) {
|
|
1260
|
-
return {
|
|
1261
|
-
success: false,
|
|
1262
|
-
errorCode: 'permission_not_found',
|
|
1263
|
-
errorMessage: 'The permission was not found.',
|
|
1264
|
-
};
|
|
1265
|
-
}
|
|
1266
|
-
const baseRequest = {
|
|
1267
|
-
recordKeyOrRecordName: permission.recordName,
|
|
1268
|
-
userId: request.userId,
|
|
1269
|
-
};
|
|
1270
|
-
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
1271
|
-
if (context.success === false) {
|
|
1272
|
-
return {
|
|
1273
|
-
success: false,
|
|
1274
|
-
errorCode: context.errorCode,
|
|
1275
|
-
errorMessage: context.errorMessage,
|
|
1276
|
-
};
|
|
1277
|
-
}
|
|
1278
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1279
|
-
action: 'revokePermission',
|
|
1280
|
-
resourceKind: 'marker',
|
|
1281
|
-
resourceId: permission.marker,
|
|
1282
|
-
markers: [ACCOUNT_MARKER],
|
|
1283
|
-
userId: request.userId,
|
|
1284
|
-
instances: request.instances,
|
|
1285
|
-
});
|
|
1286
|
-
if (authorization.success === false) {
|
|
1287
|
-
return authorization;
|
|
1288
|
-
}
|
|
1289
|
-
const deleteResult = yield this._policies.deleteMarkerPermissionAssignmentById(permission.id);
|
|
1290
|
-
if (!deleteResult.success) {
|
|
1291
|
-
return deleteResult;
|
|
1292
|
-
}
|
|
1293
|
-
console.log(`[PolicyController] [revokeMarkerPermission] [userId: ${request.userId}, permissionId: ${request.permissionId}] Revoked marker permission.`);
|
|
1370
|
+
async revokeMarkerPermission(request) {
|
|
1371
|
+
try {
|
|
1372
|
+
const permission = await this._policies.getMarkerPermissionAssignmentById(request.permissionId);
|
|
1373
|
+
if (!permission) {
|
|
1294
1374
|
return {
|
|
1295
|
-
success:
|
|
1375
|
+
success: false,
|
|
1376
|
+
errorCode: 'permission_not_found',
|
|
1377
|
+
errorMessage: 'The permission was not found.',
|
|
1296
1378
|
};
|
|
1297
1379
|
}
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1380
|
+
const baseRequest = {
|
|
1381
|
+
recordKeyOrRecordName: permission.recordName,
|
|
1382
|
+
userId: request.userId,
|
|
1383
|
+
};
|
|
1384
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1385
|
+
if (context.success === false) {
|
|
1303
1386
|
return {
|
|
1304
1387
|
success: false,
|
|
1305
|
-
errorCode:
|
|
1306
|
-
errorMessage:
|
|
1388
|
+
errorCode: context.errorCode,
|
|
1389
|
+
errorMessage: context.errorMessage,
|
|
1307
1390
|
};
|
|
1308
1391
|
}
|
|
1309
|
-
|
|
1392
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1393
|
+
action: 'revokePermission',
|
|
1394
|
+
resourceKind: 'marker',
|
|
1395
|
+
resourceId: permission.marker,
|
|
1396
|
+
markers: [ACCOUNT_MARKER],
|
|
1397
|
+
userId: request.userId,
|
|
1398
|
+
instances: request.instances,
|
|
1399
|
+
});
|
|
1400
|
+
if (authorization.success === false) {
|
|
1401
|
+
return authorization;
|
|
1402
|
+
}
|
|
1403
|
+
const deleteResult = await this._policies.deleteMarkerPermissionAssignmentById(permission.id);
|
|
1404
|
+
if (!deleteResult.success) {
|
|
1405
|
+
return deleteResult;
|
|
1406
|
+
}
|
|
1407
|
+
console.log(`[PolicyController] [revokeMarkerPermission] [userId: ${request.userId}, permissionId: ${request.permissionId}] Revoked marker permission.`);
|
|
1408
|
+
return {
|
|
1409
|
+
success: true,
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
catch (err) {
|
|
1413
|
+
const span = trace.getActiveSpan();
|
|
1414
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1415
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1416
|
+
console.error('[PolicyController] A server error occurred while revoking a marker permission.', err);
|
|
1417
|
+
return {
|
|
1418
|
+
success: false,
|
|
1419
|
+
errorCode: 'server_error',
|
|
1420
|
+
errorMessage: 'A server error occurred.',
|
|
1421
|
+
};
|
|
1422
|
+
}
|
|
1310
1423
|
}
|
|
1311
1424
|
/**
|
|
1312
1425
|
* Attempts to grant a permission to a resource.
|
|
1313
1426
|
* @param request The request.
|
|
1314
1427
|
*/
|
|
1315
|
-
grantResourcePermission(request) {
|
|
1428
|
+
async grantResourcePermission(request) {
|
|
1316
1429
|
var _a, _b, _c, _d;
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1430
|
+
try {
|
|
1431
|
+
const baseRequest = {
|
|
1432
|
+
recordKeyOrRecordName: request.recordKeyOrRecordName,
|
|
1433
|
+
userId: request.userId,
|
|
1434
|
+
};
|
|
1435
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1436
|
+
if (context.success === false) {
|
|
1437
|
+
return {
|
|
1438
|
+
success: false,
|
|
1439
|
+
errorCode: context.errorCode,
|
|
1440
|
+
errorMessage: context.errorMessage,
|
|
1322
1441
|
};
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
return {
|
|
1326
|
-
success: false,
|
|
1327
|
-
errorCode: context.errorCode,
|
|
1328
|
-
errorMessage: context.errorMessage,
|
|
1329
|
-
};
|
|
1330
|
-
}
|
|
1331
|
-
if (!request.permission.resourceId) {
|
|
1332
|
-
return {
|
|
1333
|
-
success: false,
|
|
1334
|
-
errorCode: 'unacceptable_request',
|
|
1335
|
-
errorMessage: 'You must provide a resourceId for the permission.',
|
|
1336
|
-
};
|
|
1337
|
-
}
|
|
1338
|
-
else if (!request.permission.resourceKind) {
|
|
1339
|
-
return {
|
|
1340
|
-
success: false,
|
|
1341
|
-
errorCode: 'unacceptable_request',
|
|
1342
|
-
errorMessage: 'You must provide a resourceKind for the permission.',
|
|
1343
|
-
};
|
|
1344
|
-
}
|
|
1345
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1346
|
-
action: 'grantPermission',
|
|
1347
|
-
// Resource permissions require access to the "account" marker
|
|
1348
|
-
// because there is currently no other marker that would make sense
|
|
1349
|
-
// for per-resource permissions.
|
|
1350
|
-
resourceKind: 'marker',
|
|
1351
|
-
resourceId: ACCOUNT_MARKER,
|
|
1352
|
-
markers: [ACCOUNT_MARKER],
|
|
1353
|
-
userId: request.userId,
|
|
1354
|
-
instances: request.instances,
|
|
1355
|
-
});
|
|
1356
|
-
if (authorization.success === false) {
|
|
1357
|
-
return authorization;
|
|
1358
|
-
}
|
|
1359
|
-
const recordName = context.context.recordName;
|
|
1360
|
-
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);
|
|
1361
|
-
if (assignmentResult.success === false) {
|
|
1362
|
-
return assignmentResult;
|
|
1363
|
-
}
|
|
1364
|
-
console.log(`[PolicyController] [grantResourcePermission] [userId: ${request.userId}, recordName: ${recordName}, subjectType: ${request.permission.subjectType}, subjectId: ${request.permission.subjectId}, resourceKind: ${(_a = request.permission.resourceKind) !== null && _a !== void 0 ? _a : '(null)'}, resourceId: ${(_b = request.permission.resourceId) !== null && _b !== void 0 ? _b : '(null)'}, action: ${(_c = request.permission.action) !== null && _c !== void 0 ? _c : '(null)'}, expireTimeMs: ${(_d = request.permission.expireTimeMs) !== null && _d !== void 0 ? _d : '(null)'}, permissionId: ${assignmentResult.permissionAssignment.id}] Granted permission for resource.`);
|
|
1442
|
+
}
|
|
1443
|
+
if (!request.permission.resourceId) {
|
|
1365
1444
|
return {
|
|
1366
|
-
success:
|
|
1445
|
+
success: false,
|
|
1446
|
+
errorCode: 'unacceptable_request',
|
|
1447
|
+
errorMessage: 'You must provide a resourceId for the permission.',
|
|
1367
1448
|
};
|
|
1368
1449
|
}
|
|
1369
|
-
|
|
1370
|
-
const span = trace.getActiveSpan();
|
|
1371
|
-
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1372
|
-
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1373
|
-
console.error('[PolicyController] A server error occurred while granting a resource permission.', err);
|
|
1450
|
+
else if (!request.permission.resourceKind) {
|
|
1374
1451
|
return {
|
|
1375
1452
|
success: false,
|
|
1376
|
-
errorCode: '
|
|
1377
|
-
errorMessage: '
|
|
1453
|
+
errorCode: 'unacceptable_request',
|
|
1454
|
+
errorMessage: 'You must provide a resourceKind for the permission.',
|
|
1378
1455
|
};
|
|
1379
1456
|
}
|
|
1380
|
-
|
|
1457
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1458
|
+
action: 'grantPermission',
|
|
1459
|
+
// Resource permissions require access to the "account" marker
|
|
1460
|
+
// because there is currently no other marker that would make sense
|
|
1461
|
+
// for per-resource permissions.
|
|
1462
|
+
resourceKind: 'marker',
|
|
1463
|
+
resourceId: ACCOUNT_MARKER,
|
|
1464
|
+
markers: [ACCOUNT_MARKER],
|
|
1465
|
+
userId: request.userId,
|
|
1466
|
+
instances: request.instances,
|
|
1467
|
+
});
|
|
1468
|
+
if (authorization.success === false) {
|
|
1469
|
+
return authorization;
|
|
1470
|
+
}
|
|
1471
|
+
const recordName = context.context.recordName;
|
|
1472
|
+
const assignmentResult = await 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);
|
|
1473
|
+
if (assignmentResult.success === false) {
|
|
1474
|
+
return assignmentResult;
|
|
1475
|
+
}
|
|
1476
|
+
console.log(`[PolicyController] [grantResourcePermission] [userId: ${request.userId}, recordName: ${recordName}, subjectType: ${request.permission.subjectType}, subjectId: ${request.permission.subjectId}, resourceKind: ${(_a = request.permission.resourceKind) !== null && _a !== void 0 ? _a : '(null)'}, resourceId: ${(_b = request.permission.resourceId) !== null && _b !== void 0 ? _b : '(null)'}, action: ${(_c = request.permission.action) !== null && _c !== void 0 ? _c : '(null)'}, expireTimeMs: ${(_d = request.permission.expireTimeMs) !== null && _d !== void 0 ? _d : '(null)'}, permissionId: ${assignmentResult.permissionAssignment.id}] Granted permission for resource.`);
|
|
1477
|
+
return {
|
|
1478
|
+
success: true,
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
catch (err) {
|
|
1482
|
+
const span = trace.getActiveSpan();
|
|
1483
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1484
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1485
|
+
console.error('[PolicyController] A server error occurred while granting a resource permission.', err);
|
|
1486
|
+
return {
|
|
1487
|
+
success: false,
|
|
1488
|
+
errorCode: 'server_error',
|
|
1489
|
+
errorMessage: 'A server error occurred.',
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1381
1492
|
}
|
|
1382
1493
|
/**
|
|
1383
1494
|
* Attempts to revoke a permission from a resource.
|
|
1384
1495
|
* @param request The request for the operation.
|
|
1385
1496
|
*/
|
|
1386
|
-
revokeResourcePermission(request) {
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
if (!permission) {
|
|
1391
|
-
return {
|
|
1392
|
-
success: false,
|
|
1393
|
-
errorCode: 'permission_not_found',
|
|
1394
|
-
errorMessage: 'The permission was not found.',
|
|
1395
|
-
};
|
|
1396
|
-
}
|
|
1397
|
-
const baseRequest = {
|
|
1398
|
-
recordKeyOrRecordName: permission.recordName,
|
|
1399
|
-
userId: request.userId,
|
|
1400
|
-
};
|
|
1401
|
-
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
1402
|
-
if (context.success === false) {
|
|
1403
|
-
return {
|
|
1404
|
-
success: false,
|
|
1405
|
-
errorCode: context.errorCode,
|
|
1406
|
-
errorMessage: context.errorMessage,
|
|
1407
|
-
};
|
|
1408
|
-
}
|
|
1409
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1410
|
-
action: 'revokePermission',
|
|
1411
|
-
resourceKind: 'marker',
|
|
1412
|
-
resourceId: ACCOUNT_MARKER,
|
|
1413
|
-
markers: [ACCOUNT_MARKER],
|
|
1414
|
-
userId: request.userId,
|
|
1415
|
-
instances: request.instances,
|
|
1416
|
-
});
|
|
1417
|
-
if (authorization.success === false) {
|
|
1418
|
-
return authorization;
|
|
1419
|
-
}
|
|
1420
|
-
const deleteResult = yield this._policies.deleteResourcePermissionAssignmentById(permission.id);
|
|
1421
|
-
if (!deleteResult.success) {
|
|
1422
|
-
return deleteResult;
|
|
1423
|
-
}
|
|
1424
|
-
console.log(`[PolicyController] [revokeResourcePermission] [userId: ${request.userId}, permissionId: ${request.permissionId}] Revoked resource permission.`);
|
|
1497
|
+
async revokeResourcePermission(request) {
|
|
1498
|
+
try {
|
|
1499
|
+
const permission = await this._policies.getResourcePermissionAssignmentById(request.permissionId);
|
|
1500
|
+
if (!permission) {
|
|
1425
1501
|
return {
|
|
1426
|
-
success:
|
|
1502
|
+
success: false,
|
|
1503
|
+
errorCode: 'permission_not_found',
|
|
1504
|
+
errorMessage: 'The permission was not found.',
|
|
1427
1505
|
};
|
|
1428
1506
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1507
|
+
const baseRequest = {
|
|
1508
|
+
recordKeyOrRecordName: permission.recordName,
|
|
1509
|
+
userId: request.userId,
|
|
1510
|
+
};
|
|
1511
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1512
|
+
if (context.success === false) {
|
|
1434
1513
|
return {
|
|
1435
1514
|
success: false,
|
|
1436
|
-
errorCode:
|
|
1437
|
-
errorMessage:
|
|
1515
|
+
errorCode: context.errorCode,
|
|
1516
|
+
errorMessage: context.errorMessage,
|
|
1438
1517
|
};
|
|
1439
1518
|
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
if (markerResult.success === false &&
|
|
1451
|
-
markerResult.errorCode === 'permission_not_found') {
|
|
1452
|
-
return yield this.revokeResourcePermission(request);
|
|
1453
|
-
}
|
|
1454
|
-
return markerResult;
|
|
1519
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1520
|
+
action: 'revokePermission',
|
|
1521
|
+
resourceKind: 'marker',
|
|
1522
|
+
resourceId: ACCOUNT_MARKER,
|
|
1523
|
+
markers: [ACCOUNT_MARKER],
|
|
1524
|
+
userId: request.userId,
|
|
1525
|
+
instances: request.instances,
|
|
1526
|
+
});
|
|
1527
|
+
if (authorization.success === false) {
|
|
1528
|
+
return authorization;
|
|
1455
1529
|
}
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1460
|
-
console.error('[PolicyController] A server error occurred while revoking a permission.', err);
|
|
1461
|
-
return {
|
|
1462
|
-
success: false,
|
|
1463
|
-
errorCode: 'server_error',
|
|
1464
|
-
errorMessage: 'A server error occurred.',
|
|
1465
|
-
};
|
|
1530
|
+
const deleteResult = await this._policies.deleteResourcePermissionAssignmentById(permission.id);
|
|
1531
|
+
if (!deleteResult.success) {
|
|
1532
|
+
return deleteResult;
|
|
1466
1533
|
}
|
|
1467
|
-
|
|
1534
|
+
console.log(`[PolicyController] [revokeResourcePermission] [userId: ${request.userId}, permissionId: ${request.permissionId}] Revoked resource permission.`);
|
|
1535
|
+
return {
|
|
1536
|
+
success: true,
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
catch (err) {
|
|
1540
|
+
const span = trace.getActiveSpan();
|
|
1541
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1542
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1543
|
+
console.error('[PolicyController] A server error occurred while revoking a resource permission.', err);
|
|
1544
|
+
return {
|
|
1545
|
+
success: false,
|
|
1546
|
+
errorCode: 'server_error',
|
|
1547
|
+
errorMessage: 'A server error occurred.',
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1468
1550
|
}
|
|
1469
1551
|
/**
|
|
1470
|
-
* Attempts to
|
|
1471
|
-
* @param
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
const baseRequest = {
|
|
1480
|
-
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1481
|
-
userId: userId,
|
|
1482
|
-
};
|
|
1483
|
-
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
1484
|
-
if (context.success === false) {
|
|
1485
|
-
return {
|
|
1486
|
-
success: false,
|
|
1487
|
-
errorCode: context.errorCode,
|
|
1488
|
-
errorMessage: context.errorMessage,
|
|
1489
|
-
};
|
|
1490
|
-
}
|
|
1491
|
-
if (userId !== subjectId || (!!instances && instances.length > 0)) {
|
|
1492
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1493
|
-
resourceKind: 'role',
|
|
1494
|
-
action: 'list',
|
|
1495
|
-
markers: [ACCOUNT_MARKER],
|
|
1496
|
-
userId: userId,
|
|
1497
|
-
instances: instances,
|
|
1498
|
-
});
|
|
1499
|
-
if (authorization.success === false) {
|
|
1500
|
-
return authorization;
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
const result = yield this._policies.listRolesForUser(context.context.recordName, subjectId);
|
|
1504
|
-
return {
|
|
1505
|
-
success: true,
|
|
1506
|
-
roles: sortBy(result, (r) => r.role),
|
|
1507
|
-
};
|
|
1508
|
-
}
|
|
1509
|
-
catch (err) {
|
|
1510
|
-
const span = trace.getActiveSpan();
|
|
1511
|
-
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1512
|
-
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1513
|
-
console.error('[PolicyController] A server error occurred.', err);
|
|
1514
|
-
return {
|
|
1515
|
-
success: false,
|
|
1516
|
-
errorCode: 'server_error',
|
|
1517
|
-
errorMessage: 'A server error occurred.',
|
|
1518
|
-
};
|
|
1552
|
+
* Attempts to revoke the permission with the given ID.
|
|
1553
|
+
* @param request The request for the operation.
|
|
1554
|
+
*/
|
|
1555
|
+
async revokePermission(request) {
|
|
1556
|
+
try {
|
|
1557
|
+
const markerResult = await this.revokeMarkerPermission(request);
|
|
1558
|
+
if (markerResult.success === false &&
|
|
1559
|
+
markerResult.errorCode === 'permission_not_found') {
|
|
1560
|
+
return await this.revokeResourcePermission(request);
|
|
1519
1561
|
}
|
|
1520
|
-
|
|
1562
|
+
return markerResult;
|
|
1563
|
+
}
|
|
1564
|
+
catch (err) {
|
|
1565
|
+
const span = trace.getActiveSpan();
|
|
1566
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1567
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1568
|
+
console.error('[PolicyController] A server error occurred while revoking a permission.', err);
|
|
1569
|
+
return {
|
|
1570
|
+
success: false,
|
|
1571
|
+
errorCode: 'server_error',
|
|
1572
|
+
errorMessage: 'A server error occurred.',
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1521
1575
|
}
|
|
1522
1576
|
/**
|
|
1523
|
-
* Attempts to list the roles that are assigned to
|
|
1577
|
+
* Attempts to list the roles that are assigned to a user.
|
|
1524
1578
|
* @param recordKeyOrRecordName The record key or the name of the record.
|
|
1525
1579
|
* @param userId The ID of the user that is currently logged in.
|
|
1526
|
-
* @param subjectId The ID of the
|
|
1580
|
+
* @param subjectId The ID of the user whose roles should be listed.
|
|
1527
1581
|
* @param instances The instances that the request is being made from.
|
|
1528
1582
|
*/
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1583
|
+
async listUserRoles(recordKeyOrRecordName, userId, subjectId, instances) {
|
|
1584
|
+
try {
|
|
1585
|
+
const baseRequest = {
|
|
1586
|
+
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1587
|
+
userId: userId,
|
|
1588
|
+
};
|
|
1589
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1590
|
+
if (context.success === false) {
|
|
1591
|
+
return {
|
|
1592
|
+
success: false,
|
|
1593
|
+
errorCode: context.errorCode,
|
|
1594
|
+
errorMessage: context.errorMessage,
|
|
1535
1595
|
};
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
success: false,
|
|
1540
|
-
errorCode: context.errorCode,
|
|
1541
|
-
errorMessage: context.errorMessage,
|
|
1542
|
-
};
|
|
1543
|
-
}
|
|
1544
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1596
|
+
}
|
|
1597
|
+
if (userId !== subjectId || (!!instances && instances.length > 0)) {
|
|
1598
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1545
1599
|
resourceKind: 'role',
|
|
1546
1600
|
action: 'list',
|
|
1547
1601
|
markers: [ACCOUNT_MARKER],
|
|
@@ -1551,24 +1605,73 @@ export class PolicyController {
|
|
|
1551
1605
|
if (authorization.success === false) {
|
|
1552
1606
|
return authorization;
|
|
1553
1607
|
}
|
|
1554
|
-
const result = yield this._policies.listRolesForInst(context.context.recordName, normalizeInstId(subjectId));
|
|
1555
|
-
return {
|
|
1556
|
-
success: true,
|
|
1557
|
-
roles: sortBy(result, (r) => r.role),
|
|
1558
|
-
};
|
|
1559
1608
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1609
|
+
const result = await this._policies.listRolesForUser(context.context.recordName, subjectId);
|
|
1610
|
+
return {
|
|
1611
|
+
success: true,
|
|
1612
|
+
roles: sortBy(result, (r) => r.role),
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
catch (err) {
|
|
1616
|
+
const span = trace.getActiveSpan();
|
|
1617
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1618
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1619
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
1620
|
+
return {
|
|
1621
|
+
success: false,
|
|
1622
|
+
errorCode: 'server_error',
|
|
1623
|
+
errorMessage: 'A server error occurred.',
|
|
1624
|
+
};
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Attempts to list the roles that are assigned to an inst.
|
|
1629
|
+
* @param recordKeyOrRecordName The record key or the name of the record.
|
|
1630
|
+
* @param userId The ID of the user that is currently logged in.
|
|
1631
|
+
* @param subjectId The ID of the inst whose roles should be listed.
|
|
1632
|
+
* @param instances The instances that the request is being made from.
|
|
1633
|
+
*/
|
|
1634
|
+
async listInstRoles(recordKeyOrRecordName, userId, subjectId, instances) {
|
|
1635
|
+
try {
|
|
1636
|
+
const baseRequest = {
|
|
1637
|
+
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1638
|
+
userId: userId,
|
|
1639
|
+
};
|
|
1640
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1641
|
+
if (context.success === false) {
|
|
1565
1642
|
return {
|
|
1566
1643
|
success: false,
|
|
1567
|
-
errorCode:
|
|
1568
|
-
errorMessage:
|
|
1644
|
+
errorCode: context.errorCode,
|
|
1645
|
+
errorMessage: context.errorMessage,
|
|
1569
1646
|
};
|
|
1570
1647
|
}
|
|
1571
|
-
|
|
1648
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1649
|
+
resourceKind: 'role',
|
|
1650
|
+
action: 'list',
|
|
1651
|
+
markers: [ACCOUNT_MARKER],
|
|
1652
|
+
userId: userId,
|
|
1653
|
+
instances: instances,
|
|
1654
|
+
});
|
|
1655
|
+
if (authorization.success === false) {
|
|
1656
|
+
return authorization;
|
|
1657
|
+
}
|
|
1658
|
+
const result = await this._policies.listRolesForInst(context.context.recordName, normalizeInstId(subjectId));
|
|
1659
|
+
return {
|
|
1660
|
+
success: true,
|
|
1661
|
+
roles: sortBy(result, (r) => r.role),
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
catch (err) {
|
|
1665
|
+
const span = trace.getActiveSpan();
|
|
1666
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1667
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1668
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
1669
|
+
return {
|
|
1670
|
+
success: false,
|
|
1671
|
+
errorCode: 'server_error',
|
|
1672
|
+
errorMessage: 'A server error occurred.',
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1572
1675
|
}
|
|
1573
1676
|
/**
|
|
1574
1677
|
* Attempts to list the entities that are assigned the given role.
|
|
@@ -1577,49 +1680,47 @@ export class PolicyController {
|
|
|
1577
1680
|
* @param role The name of the role whose assigments should be listed.
|
|
1578
1681
|
* @param instances The instances that the request is being made from.
|
|
1579
1682
|
*/
|
|
1580
|
-
listAssignedRoles(recordKeyOrRecordName, userId, role, instances) {
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
if (context.success === false) {
|
|
1589
|
-
return {
|
|
1590
|
-
success: false,
|
|
1591
|
-
errorCode: context.errorCode,
|
|
1592
|
-
errorMessage: context.errorMessage,
|
|
1593
|
-
};
|
|
1594
|
-
}
|
|
1595
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1596
|
-
resourceKind: 'role',
|
|
1597
|
-
action: 'list',
|
|
1598
|
-
markers: [ACCOUNT_MARKER],
|
|
1599
|
-
userId: userId,
|
|
1600
|
-
instances: instances,
|
|
1601
|
-
});
|
|
1602
|
-
if (authorization.success === false) {
|
|
1603
|
-
return authorization;
|
|
1604
|
-
}
|
|
1605
|
-
const result = yield this._policies.listAssignmentsForRole(context.context.recordName, role);
|
|
1606
|
-
return {
|
|
1607
|
-
success: true,
|
|
1608
|
-
assignments: result.assignments,
|
|
1609
|
-
};
|
|
1610
|
-
}
|
|
1611
|
-
catch (err) {
|
|
1612
|
-
const span = trace.getActiveSpan();
|
|
1613
|
-
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1614
|
-
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1615
|
-
console.error('[PolicyController] A server error occurred.', err);
|
|
1683
|
+
async listAssignedRoles(recordKeyOrRecordName, userId, role, instances) {
|
|
1684
|
+
try {
|
|
1685
|
+
const baseRequest = {
|
|
1686
|
+
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1687
|
+
userId: userId,
|
|
1688
|
+
};
|
|
1689
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1690
|
+
if (context.success === false) {
|
|
1616
1691
|
return {
|
|
1617
1692
|
success: false,
|
|
1618
|
-
errorCode:
|
|
1619
|
-
errorMessage:
|
|
1693
|
+
errorCode: context.errorCode,
|
|
1694
|
+
errorMessage: context.errorMessage,
|
|
1620
1695
|
};
|
|
1621
1696
|
}
|
|
1622
|
-
|
|
1697
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1698
|
+
resourceKind: 'role',
|
|
1699
|
+
action: 'list',
|
|
1700
|
+
markers: [ACCOUNT_MARKER],
|
|
1701
|
+
userId: userId,
|
|
1702
|
+
instances: instances,
|
|
1703
|
+
});
|
|
1704
|
+
if (authorization.success === false) {
|
|
1705
|
+
return authorization;
|
|
1706
|
+
}
|
|
1707
|
+
const result = await this._policies.listAssignmentsForRole(context.context.recordName, role);
|
|
1708
|
+
return {
|
|
1709
|
+
success: true,
|
|
1710
|
+
assignments: result.assignments,
|
|
1711
|
+
};
|
|
1712
|
+
}
|
|
1713
|
+
catch (err) {
|
|
1714
|
+
const span = trace.getActiveSpan();
|
|
1715
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1716
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1717
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
1718
|
+
return {
|
|
1719
|
+
success: false,
|
|
1720
|
+
errorCode: 'server_error',
|
|
1721
|
+
errorMessage: 'A server error occurred.',
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1623
1724
|
}
|
|
1624
1725
|
/**
|
|
1625
1726
|
* Lists the role assignments that have been made in the given record.
|
|
@@ -1628,57 +1729,55 @@ export class PolicyController {
|
|
|
1628
1729
|
* @param startingRole The role that assignments should be returned after.
|
|
1629
1730
|
* @param instances The instances that the request is being made from.
|
|
1630
1731
|
*/
|
|
1631
|
-
listRoleAssignments(recordKeyOrRecordName, userId, startingRole, instances) {
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
if (!this._policies.listAssignments) {
|
|
1635
|
-
return {
|
|
1636
|
-
success: false,
|
|
1637
|
-
errorCode: 'not_supported',
|
|
1638
|
-
errorMessage: 'This operation is not supported.',
|
|
1639
|
-
};
|
|
1640
|
-
}
|
|
1641
|
-
const baseRequest = {
|
|
1642
|
-
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1643
|
-
userId: userId,
|
|
1644
|
-
};
|
|
1645
|
-
const context = yield this.constructAuthorizationContext(baseRequest);
|
|
1646
|
-
if (context.success === false) {
|
|
1647
|
-
return {
|
|
1648
|
-
success: false,
|
|
1649
|
-
errorCode: context.errorCode,
|
|
1650
|
-
errorMessage: context.errorMessage,
|
|
1651
|
-
};
|
|
1652
|
-
}
|
|
1653
|
-
const authorization = yield this.authorizeUserAndInstances(context.context, {
|
|
1654
|
-
resourceKind: 'role',
|
|
1655
|
-
action: 'list',
|
|
1656
|
-
markers: [ACCOUNT_MARKER],
|
|
1657
|
-
userId: userId,
|
|
1658
|
-
instances: instances,
|
|
1659
|
-
});
|
|
1660
|
-
if (authorization.success === false) {
|
|
1661
|
-
return authorization;
|
|
1662
|
-
}
|
|
1663
|
-
const result = yield this._policies.listAssignments(context.context.recordName, startingRole);
|
|
1732
|
+
async listRoleAssignments(recordKeyOrRecordName, userId, startingRole, instances) {
|
|
1733
|
+
try {
|
|
1734
|
+
if (!this._policies.listAssignments) {
|
|
1664
1735
|
return {
|
|
1665
|
-
success:
|
|
1666
|
-
|
|
1667
|
-
|
|
1736
|
+
success: false,
|
|
1737
|
+
errorCode: 'not_supported',
|
|
1738
|
+
errorMessage: 'This operation is not supported.',
|
|
1668
1739
|
};
|
|
1669
1740
|
}
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1741
|
+
const baseRequest = {
|
|
1742
|
+
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1743
|
+
userId: userId,
|
|
1744
|
+
};
|
|
1745
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1746
|
+
if (context.success === false) {
|
|
1675
1747
|
return {
|
|
1676
1748
|
success: false,
|
|
1677
|
-
errorCode:
|
|
1678
|
-
errorMessage:
|
|
1749
|
+
errorCode: context.errorCode,
|
|
1750
|
+
errorMessage: context.errorMessage,
|
|
1679
1751
|
};
|
|
1680
1752
|
}
|
|
1681
|
-
|
|
1753
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1754
|
+
resourceKind: 'role',
|
|
1755
|
+
action: 'list',
|
|
1756
|
+
markers: [ACCOUNT_MARKER],
|
|
1757
|
+
userId: userId,
|
|
1758
|
+
instances: instances,
|
|
1759
|
+
});
|
|
1760
|
+
if (authorization.success === false) {
|
|
1761
|
+
return authorization;
|
|
1762
|
+
}
|
|
1763
|
+
const result = await this._policies.listAssignments(context.context.recordName, startingRole);
|
|
1764
|
+
return {
|
|
1765
|
+
success: true,
|
|
1766
|
+
assignments: result.assignments,
|
|
1767
|
+
totalCount: result.totalCount,
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
catch (err) {
|
|
1771
|
+
const span = trace.getActiveSpan();
|
|
1772
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1773
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1774
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
1775
|
+
return {
|
|
1776
|
+
success: false,
|
|
1777
|
+
errorCode: 'server_error',
|
|
1778
|
+
errorMessage: 'A server error occurred.',
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1682
1781
|
}
|
|
1683
1782
|
/**
|
|
1684
1783
|
* Attempts to grant a role to a user.
|
|
@@ -1687,78 +1786,76 @@ export class PolicyController {
|
|
|
1687
1786
|
* @param request The request to grant the role.
|
|
1688
1787
|
* @param instances The instances that the request is being made from.
|
|
1689
1788
|
*/
|
|
1690
|
-
grantRole(recordKeyOrRecordName, userId, request, instances) {
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1789
|
+
async grantRole(recordKeyOrRecordName, userId, request, instances) {
|
|
1790
|
+
try {
|
|
1791
|
+
const baseRequest = {
|
|
1792
|
+
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1793
|
+
userId: userId,
|
|
1794
|
+
};
|
|
1795
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1796
|
+
if (context.success === false) {
|
|
1797
|
+
return {
|
|
1798
|
+
success: false,
|
|
1799
|
+
errorCode: context.errorCode,
|
|
1800
|
+
errorMessage: context.errorMessage,
|
|
1696
1801
|
};
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1802
|
+
}
|
|
1803
|
+
const recordName = context.context.recordName;
|
|
1804
|
+
const targetUserId = request.userId;
|
|
1805
|
+
const targetInstance = normalizeInstId(request.instance);
|
|
1806
|
+
const expireTimeMs = getExpireTime(request.expireTimeMs);
|
|
1807
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1808
|
+
resourceKind: 'role',
|
|
1809
|
+
action: 'grant',
|
|
1810
|
+
resourceId: request.role,
|
|
1811
|
+
markers: [ACCOUNT_MARKER],
|
|
1812
|
+
userId: userId,
|
|
1813
|
+
instances: instances,
|
|
1814
|
+
});
|
|
1815
|
+
if (authorization.success === false) {
|
|
1816
|
+
return authorization;
|
|
1817
|
+
}
|
|
1818
|
+
if (targetUserId) {
|
|
1819
|
+
const result = await this._policies.assignSubjectRole(recordName, targetUserId, 'user', {
|
|
1820
|
+
role: request.role,
|
|
1821
|
+
expireTimeMs,
|
|
1716
1822
|
});
|
|
1717
|
-
if (
|
|
1718
|
-
return
|
|
1719
|
-
}
|
|
1720
|
-
if (targetUserId) {
|
|
1721
|
-
const result = yield this._policies.assignSubjectRole(recordName, targetUserId, 'user', {
|
|
1722
|
-
role: request.role,
|
|
1723
|
-
expireTimeMs,
|
|
1724
|
-
});
|
|
1725
|
-
if (result.success === false) {
|
|
1726
|
-
return result;
|
|
1727
|
-
}
|
|
1728
|
-
return {
|
|
1729
|
-
success: true,
|
|
1730
|
-
};
|
|
1731
|
-
}
|
|
1732
|
-
else if (targetInstance) {
|
|
1733
|
-
const result = yield this._policies.assignSubjectRole(recordName, targetInstance, 'inst', {
|
|
1734
|
-
role: request.role,
|
|
1735
|
-
expireTimeMs,
|
|
1736
|
-
});
|
|
1737
|
-
if (result.success === false) {
|
|
1738
|
-
return result;
|
|
1739
|
-
}
|
|
1740
|
-
return {
|
|
1741
|
-
success: true,
|
|
1742
|
-
};
|
|
1823
|
+
if (result.success === false) {
|
|
1824
|
+
return result;
|
|
1743
1825
|
}
|
|
1744
1826
|
return {
|
|
1745
|
-
success:
|
|
1746
|
-
errorCode: 'unacceptable_request',
|
|
1747
|
-
errorMessage: 'Either a user ID or an instance must be specified.',
|
|
1827
|
+
success: true,
|
|
1748
1828
|
};
|
|
1749
1829
|
}
|
|
1750
|
-
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1830
|
+
else if (targetInstance) {
|
|
1831
|
+
const result = await this._policies.assignSubjectRole(recordName, targetInstance, 'inst', {
|
|
1832
|
+
role: request.role,
|
|
1833
|
+
expireTimeMs,
|
|
1834
|
+
});
|
|
1835
|
+
if (result.success === false) {
|
|
1836
|
+
return result;
|
|
1837
|
+
}
|
|
1755
1838
|
return {
|
|
1756
|
-
success:
|
|
1757
|
-
errorCode: 'server_error',
|
|
1758
|
-
errorMessage: 'A server error occurred.',
|
|
1839
|
+
success: true,
|
|
1759
1840
|
};
|
|
1760
1841
|
}
|
|
1761
|
-
|
|
1842
|
+
return {
|
|
1843
|
+
success: false,
|
|
1844
|
+
errorCode: 'unacceptable_request',
|
|
1845
|
+
errorMessage: 'Either a user ID or an instance must be specified.',
|
|
1846
|
+
};
|
|
1847
|
+
}
|
|
1848
|
+
catch (err) {
|
|
1849
|
+
const span = trace.getActiveSpan();
|
|
1850
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1851
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1852
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
1853
|
+
return {
|
|
1854
|
+
success: false,
|
|
1855
|
+
errorCode: 'server_error',
|
|
1856
|
+
errorMessage: 'A server error occurred.',
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1762
1859
|
}
|
|
1763
1860
|
/**
|
|
1764
1861
|
* Attempts to revoke a role from a user.
|
|
@@ -1767,71 +1864,191 @@ export class PolicyController {
|
|
|
1767
1864
|
* @param request The request to revoke the role.
|
|
1768
1865
|
* @param instances The instances that the request is being made from.
|
|
1769
1866
|
*/
|
|
1770
|
-
revokeRole(recordKeyOrRecordName, userId, request, instances) {
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1867
|
+
async revokeRole(recordKeyOrRecordName, userId, request, instances) {
|
|
1868
|
+
try {
|
|
1869
|
+
const baseRequest = {
|
|
1870
|
+
recordKeyOrRecordName: recordKeyOrRecordName,
|
|
1871
|
+
userId: userId,
|
|
1872
|
+
};
|
|
1873
|
+
const context = await this.constructAuthorizationContext(baseRequest);
|
|
1874
|
+
if (context.success === false) {
|
|
1875
|
+
return {
|
|
1876
|
+
success: false,
|
|
1877
|
+
errorCode: context.errorCode,
|
|
1878
|
+
errorMessage: context.errorMessage,
|
|
1776
1879
|
};
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1880
|
+
}
|
|
1881
|
+
const recordName = context.context.recordName;
|
|
1882
|
+
const targetUserId = request.userId;
|
|
1883
|
+
const targetInstance = normalizeInstId(request.instance);
|
|
1884
|
+
const authorization = await this.authorizeUserAndInstances(context.context, {
|
|
1885
|
+
resourceKind: 'role',
|
|
1886
|
+
action: 'revoke',
|
|
1887
|
+
resourceId: request.role,
|
|
1888
|
+
markers: [ACCOUNT_MARKER],
|
|
1889
|
+
userId: userId,
|
|
1890
|
+
instances: instances,
|
|
1891
|
+
});
|
|
1892
|
+
if (authorization.success === false) {
|
|
1893
|
+
return authorization;
|
|
1894
|
+
}
|
|
1895
|
+
if (targetUserId) {
|
|
1896
|
+
const result = await this._policies.revokeSubjectRole(recordName, targetUserId, 'user', request.role);
|
|
1897
|
+
if (result.success === false) {
|
|
1898
|
+
return result;
|
|
1784
1899
|
}
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
userId: userId,
|
|
1794
|
-
instances: instances,
|
|
1795
|
-
});
|
|
1796
|
-
if (authorization.success === false) {
|
|
1797
|
-
return authorization;
|
|
1900
|
+
return {
|
|
1901
|
+
success: true,
|
|
1902
|
+
};
|
|
1903
|
+
}
|
|
1904
|
+
else if (targetInstance) {
|
|
1905
|
+
const result = await this._policies.revokeSubjectRole(recordName, targetInstance, 'inst', request.role);
|
|
1906
|
+
if (result.success === false) {
|
|
1907
|
+
return result;
|
|
1798
1908
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1909
|
+
return {
|
|
1910
|
+
success: true,
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
return {
|
|
1914
|
+
success: false,
|
|
1915
|
+
errorCode: 'unacceptable_request',
|
|
1916
|
+
errorMessage: 'Either a user ID or an instance must be specified.',
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1919
|
+
catch (err) {
|
|
1920
|
+
const span = trace.getActiveSpan();
|
|
1921
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1922
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1923
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
1924
|
+
return {
|
|
1925
|
+
success: false,
|
|
1926
|
+
errorCode: 'server_error',
|
|
1927
|
+
errorMessage: 'A server error occurred.',
|
|
1928
|
+
};
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
/**
|
|
1932
|
+
* Attempts to grant an entitlement to a package.
|
|
1933
|
+
* @param request
|
|
1934
|
+
*/
|
|
1935
|
+
async grantEntitlement(request) {
|
|
1936
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1937
|
+
try {
|
|
1938
|
+
if (!isSuperUserRole(request.userRole)) {
|
|
1939
|
+
if (request.userId !== request.grantingUserId) {
|
|
1804
1940
|
return {
|
|
1805
|
-
success:
|
|
1941
|
+
success: false,
|
|
1942
|
+
errorCode: 'not_authorized',
|
|
1943
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
1806
1944
|
};
|
|
1807
1945
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1946
|
+
}
|
|
1947
|
+
const grant = await this._policies.findGrantedPackageEntitlementByUserIdPackageIdFeatureAndScope(request.grantingUserId, request.packageId, request.feature, request.scope, request.recordName);
|
|
1948
|
+
const grantId = (_a = grant === null || grant === void 0 ? void 0 : grant.id) !== null && _a !== void 0 ? _a : uuidv7();
|
|
1949
|
+
const feature = (_b = grant === null || grant === void 0 ? void 0 : grant.feature) !== null && _b !== void 0 ? _b : request.feature;
|
|
1950
|
+
await this._policies.saveGrantedPackageEntitlement({
|
|
1951
|
+
id: grantId,
|
|
1952
|
+
createdAtMs: (_c = grant === null || grant === void 0 ? void 0 : grant.createdAtMs) !== null && _c !== void 0 ? _c : Date.now(),
|
|
1953
|
+
expireTimeMs: Math.max(request.expireTimeMs, (_d = grant === null || grant === void 0 ? void 0 : grant.expireTimeMs) !== null && _d !== void 0 ? _d : 0),
|
|
1954
|
+
revokeTimeMs: null,
|
|
1955
|
+
scope: (_e = grant === null || grant === void 0 ? void 0 : grant.scope) !== null && _e !== void 0 ? _e : request.scope,
|
|
1956
|
+
packageId: (_f = grant === null || grant === void 0 ? void 0 : grant.packageId) !== null && _f !== void 0 ? _f : request.packageId,
|
|
1957
|
+
userId: (_g = grant === null || grant === void 0 ? void 0 : grant.userId) !== null && _g !== void 0 ? _g : request.grantingUserId,
|
|
1958
|
+
feature: feature,
|
|
1959
|
+
recordName: (_h = grant === null || grant === void 0 ? void 0 : grant.recordName) !== null && _h !== void 0 ? _h : request.recordName,
|
|
1960
|
+
});
|
|
1961
|
+
return {
|
|
1962
|
+
success: true,
|
|
1963
|
+
grantId,
|
|
1964
|
+
feature,
|
|
1965
|
+
};
|
|
1966
|
+
}
|
|
1967
|
+
catch (err) {
|
|
1968
|
+
const span = trace.getActiveSpan();
|
|
1969
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
1970
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1971
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
1972
|
+
return {
|
|
1973
|
+
success: false,
|
|
1974
|
+
errorCode: 'server_error',
|
|
1975
|
+
errorMessage: 'A server error occurred.',
|
|
1976
|
+
};
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
async revokeEntitlement(request) {
|
|
1980
|
+
try {
|
|
1981
|
+
const grant = await this._policies.findGrantedPackageEntitlementById(request.grantId);
|
|
1982
|
+
if (!grant) {
|
|
1983
|
+
return {
|
|
1984
|
+
success: false,
|
|
1985
|
+
errorCode: 'not_found',
|
|
1986
|
+
errorMessage: 'The entitlement grant could not be found.',
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
if (grant.userId !== request.userId) {
|
|
1990
|
+
if (!isSuperUserRole(request.userRole)) {
|
|
1813
1991
|
return {
|
|
1814
|
-
success:
|
|
1992
|
+
success: false,
|
|
1993
|
+
errorCode: 'not_authorized',
|
|
1994
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
1815
1995
|
};
|
|
1816
1996
|
}
|
|
1997
|
+
}
|
|
1998
|
+
if (grant.revokeTimeMs !== null) {
|
|
1999
|
+
// Already revoked
|
|
1817
2000
|
return {
|
|
1818
|
-
success:
|
|
1819
|
-
errorCode: 'unacceptable_request',
|
|
1820
|
-
errorMessage: 'Either a user ID or an instance must be specified.',
|
|
2001
|
+
success: true,
|
|
1821
2002
|
};
|
|
1822
2003
|
}
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
2004
|
+
await this._policies.saveGrantedPackageEntitlement({
|
|
2005
|
+
...grant,
|
|
2006
|
+
revokeTimeMs: Date.now(),
|
|
2007
|
+
});
|
|
2008
|
+
return {
|
|
2009
|
+
success: true,
|
|
2010
|
+
};
|
|
2011
|
+
}
|
|
2012
|
+
catch (err) {
|
|
2013
|
+
const span = trace.getActiveSpan();
|
|
2014
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
2015
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
2016
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
2017
|
+
return {
|
|
2018
|
+
success: false,
|
|
2019
|
+
errorCode: 'server_error',
|
|
2020
|
+
errorMessage: 'A server error occurred.',
|
|
2021
|
+
};
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
async listGrantedEntitlements(request) {
|
|
2025
|
+
try {
|
|
2026
|
+
if (!request.packageId) {
|
|
2027
|
+
const grants = await this._policies.listGrantedEntitlementsForUser(request.userId, Date.now());
|
|
1828
2028
|
return {
|
|
1829
|
-
success:
|
|
1830
|
-
|
|
1831
|
-
errorMessage: 'A server error occurred.',
|
|
2029
|
+
success: true,
|
|
2030
|
+
grants,
|
|
1832
2031
|
};
|
|
1833
2032
|
}
|
|
1834
|
-
|
|
2033
|
+
else {
|
|
2034
|
+
const grants = await this._policies.listGrantedEntitlementsForUserAndPackage(request.userId, request.packageId, Date.now());
|
|
2035
|
+
return {
|
|
2036
|
+
success: true,
|
|
2037
|
+
grants,
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
catch (err) {
|
|
2042
|
+
const span = trace.getActiveSpan();
|
|
2043
|
+
span === null || span === void 0 ? void 0 : span.recordException(err);
|
|
2044
|
+
span === null || span === void 0 ? void 0 : span.setStatus({ code: SpanStatusCode.ERROR });
|
|
2045
|
+
console.error('[PolicyController] A server error occurred.', err);
|
|
2046
|
+
return {
|
|
2047
|
+
success: false,
|
|
2048
|
+
errorCode: 'server_error',
|
|
2049
|
+
errorMessage: 'A server error occurred.',
|
|
2050
|
+
};
|
|
2051
|
+
}
|
|
1835
2052
|
}
|
|
1836
2053
|
}
|
|
1837
2054
|
__decorate([
|
|
@@ -1897,6 +2114,15 @@ __decorate([
|
|
|
1897
2114
|
__decorate([
|
|
1898
2115
|
traced(TRACE_NAME)
|
|
1899
2116
|
], PolicyController.prototype, "revokeRole", null);
|
|
2117
|
+
__decorate([
|
|
2118
|
+
traced(TRACE_NAME)
|
|
2119
|
+
], PolicyController.prototype, "grantEntitlement", null);
|
|
2120
|
+
__decorate([
|
|
2121
|
+
traced(TRACE_NAME)
|
|
2122
|
+
], PolicyController.prototype, "revokeEntitlement", null);
|
|
2123
|
+
__decorate([
|
|
2124
|
+
traced(TRACE_NAME)
|
|
2125
|
+
], PolicyController.prototype, "listGrantedEntitlements", null);
|
|
1900
2126
|
/**
|
|
1901
2127
|
* Determines if any markers will be remaining after the removal and addition of the specified markers.
|
|
1902
2128
|
* @param existingMarkers The markers that already exist.
|
|
@@ -1939,4 +2165,25 @@ export function explainationForPermissionAssignment(subjectType, permissionAssig
|
|
|
1939
2165
|
}
|
|
1940
2166
|
return permissionString;
|
|
1941
2167
|
}
|
|
2168
|
+
function getEntitlementFeatureForAction(resourceKind, action) {
|
|
2169
|
+
if (resourceKind === 'data' ||
|
|
2170
|
+
resourceKind === 'file' ||
|
|
2171
|
+
resourceKind === 'event' ||
|
|
2172
|
+
resourceKind === 'inst' ||
|
|
2173
|
+
resourceKind === 'notification' ||
|
|
2174
|
+
resourceKind === 'package' ||
|
|
2175
|
+
resourceKind === 'webhook') {
|
|
2176
|
+
return resourceKind;
|
|
2177
|
+
}
|
|
2178
|
+
else if (resourceKind === 'ai.hume' || resourceKind === 'ai.sloyd') {
|
|
2179
|
+
return 'ai';
|
|
2180
|
+
}
|
|
2181
|
+
else if (resourceKind === 'marker' || resourceKind === 'role') {
|
|
2182
|
+
return 'permissions';
|
|
2183
|
+
}
|
|
2184
|
+
else if (resourceKind === 'package.version') {
|
|
2185
|
+
return 'package';
|
|
2186
|
+
}
|
|
2187
|
+
return null;
|
|
2188
|
+
}
|
|
1942
2189
|
//# sourceMappingURL=PolicyController.js.map
|