@uipath/admin-tool 1.203.0-preview.205 → 1.204.0-preview.206
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index-0t7092fj.js +2375 -0
- package/dist/index-40a6zw4t.js +2246 -0
- package/dist/index-esy280as.js +634 -0
- package/dist/index-f7cp1ap1.js +2411 -0
- package/dist/index-m2vj29s2.js +6501 -0
- package/dist/index-xd0zd702.js +2740 -0
- package/dist/jmespath-v0jttxep.js +1485 -0
- package/dist/js-yaml-qv0npwpc.js +3153 -0
- package/dist/tool-016jy57n.js +1376 -0
- package/dist/tool-1yh8g550.js +52 -0
- package/dist/tool-687d8jq8.js +2531 -0
- package/dist/tool-mhb6cezm.js +2859 -0
- package/dist/tool-pmf56f99.js +1977 -0
- package/dist/tool-v13kh7v7.js +6601 -0
- package/dist/tool.js +70 -48739
- package/package.json +2 -2
|
@@ -0,0 +1,2740 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UserApi,
|
|
3
|
+
createApiClient
|
|
4
|
+
} from "./tool-mhb6cezm.js";
|
|
5
|
+
import {
|
|
6
|
+
getLoginStatusAsync
|
|
7
|
+
} from "./tool-016jy57n.js";
|
|
8
|
+
import {
|
|
9
|
+
InvalidArgumentError,
|
|
10
|
+
Option,
|
|
11
|
+
OutputFormatter,
|
|
12
|
+
RESULTS,
|
|
13
|
+
addSdkUserAgentHeader,
|
|
14
|
+
catchError,
|
|
15
|
+
extractErrorMessage,
|
|
16
|
+
getFileSystem,
|
|
17
|
+
getSdkUserAgentToken,
|
|
18
|
+
installSdkUserAgentHeader,
|
|
19
|
+
processContext
|
|
20
|
+
} from "./tool-v13kh7v7.js";
|
|
21
|
+
import"./tool-1yh8g550.js";
|
|
22
|
+
|
|
23
|
+
// ../authz-sdk/generated/src/runtime.ts
|
|
24
|
+
var BASE_PATH = "http://localhost".replace(/\/+$/, "");
|
|
25
|
+
|
|
26
|
+
class Configuration {
|
|
27
|
+
configuration;
|
|
28
|
+
constructor(configuration = {}) {
|
|
29
|
+
this.configuration = configuration;
|
|
30
|
+
}
|
|
31
|
+
set config(configuration) {
|
|
32
|
+
this.configuration = configuration;
|
|
33
|
+
}
|
|
34
|
+
get basePath() {
|
|
35
|
+
return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH;
|
|
36
|
+
}
|
|
37
|
+
get fetchApi() {
|
|
38
|
+
return this.configuration.fetchApi;
|
|
39
|
+
}
|
|
40
|
+
get middleware() {
|
|
41
|
+
return this.configuration.middleware || [];
|
|
42
|
+
}
|
|
43
|
+
get queryParamsStringify() {
|
|
44
|
+
return this.configuration.queryParamsStringify || querystring;
|
|
45
|
+
}
|
|
46
|
+
get username() {
|
|
47
|
+
return this.configuration.username;
|
|
48
|
+
}
|
|
49
|
+
get password() {
|
|
50
|
+
return this.configuration.password;
|
|
51
|
+
}
|
|
52
|
+
get apiKey() {
|
|
53
|
+
const apiKey = this.configuration.apiKey;
|
|
54
|
+
if (apiKey) {
|
|
55
|
+
return typeof apiKey === "function" ? apiKey : () => apiKey;
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
get accessToken() {
|
|
60
|
+
const accessToken = this.configuration.accessToken;
|
|
61
|
+
if (accessToken) {
|
|
62
|
+
return typeof accessToken === "function" ? accessToken : async () => accessToken;
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
get headers() {
|
|
67
|
+
return this.configuration.headers;
|
|
68
|
+
}
|
|
69
|
+
get credentials() {
|
|
70
|
+
return this.configuration.credentials;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
var DefaultConfig = new Configuration;
|
|
74
|
+
|
|
75
|
+
class BaseAPI {
|
|
76
|
+
configuration;
|
|
77
|
+
static jsonRegex = new RegExp("^(:?application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$", "i");
|
|
78
|
+
middleware;
|
|
79
|
+
constructor(configuration = DefaultConfig) {
|
|
80
|
+
this.configuration = configuration;
|
|
81
|
+
this.middleware = configuration.middleware;
|
|
82
|
+
}
|
|
83
|
+
withMiddleware(...middlewares) {
|
|
84
|
+
const next = this.clone();
|
|
85
|
+
next.middleware = next.middleware.concat(...middlewares);
|
|
86
|
+
return next;
|
|
87
|
+
}
|
|
88
|
+
withPreMiddleware(...preMiddlewares) {
|
|
89
|
+
const middlewares = preMiddlewares.map((pre) => ({ pre }));
|
|
90
|
+
return this.withMiddleware(...middlewares);
|
|
91
|
+
}
|
|
92
|
+
withPostMiddleware(...postMiddlewares) {
|
|
93
|
+
const middlewares = postMiddlewares.map((post) => ({ post }));
|
|
94
|
+
return this.withMiddleware(...middlewares);
|
|
95
|
+
}
|
|
96
|
+
isJsonMime(mime) {
|
|
97
|
+
if (!mime) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return BaseAPI.jsonRegex.test(mime);
|
|
101
|
+
}
|
|
102
|
+
async request(context, initOverrides) {
|
|
103
|
+
const { url, init } = await this.createFetchParams(context, initOverrides);
|
|
104
|
+
const response = await this.fetchApi(url, init);
|
|
105
|
+
if (response && (response.status >= 200 && response.status < 300)) {
|
|
106
|
+
return response;
|
|
107
|
+
}
|
|
108
|
+
throw new ResponseError(response, "Response returned an error code");
|
|
109
|
+
}
|
|
110
|
+
async createFetchParams(context, initOverrides) {
|
|
111
|
+
let url = this.configuration.basePath + context.path;
|
|
112
|
+
if (context.query !== undefined && Object.keys(context.query).length !== 0) {
|
|
113
|
+
url += "?" + this.configuration.queryParamsStringify(context.query);
|
|
114
|
+
}
|
|
115
|
+
const headers = Object.assign({}, this.configuration.headers, context.headers);
|
|
116
|
+
Object.keys(headers).forEach((key) => headers[key] === undefined ? delete headers[key] : {});
|
|
117
|
+
const initOverrideFn = typeof initOverrides === "function" ? initOverrides : async () => initOverrides;
|
|
118
|
+
const initParams = {
|
|
119
|
+
method: context.method,
|
|
120
|
+
headers,
|
|
121
|
+
body: context.body,
|
|
122
|
+
credentials: this.configuration.credentials
|
|
123
|
+
};
|
|
124
|
+
const overriddenInit = {
|
|
125
|
+
...initParams,
|
|
126
|
+
...await initOverrideFn({
|
|
127
|
+
init: initParams,
|
|
128
|
+
context
|
|
129
|
+
})
|
|
130
|
+
};
|
|
131
|
+
let body;
|
|
132
|
+
if (isFormData(overriddenInit.body) || overriddenInit.body instanceof URLSearchParams || isBlob(overriddenInit.body)) {
|
|
133
|
+
body = overriddenInit.body;
|
|
134
|
+
} else if (this.isJsonMime(headers["Content-Type"])) {
|
|
135
|
+
body = JSON.stringify(overriddenInit.body);
|
|
136
|
+
} else {
|
|
137
|
+
body = overriddenInit.body;
|
|
138
|
+
}
|
|
139
|
+
const init = {
|
|
140
|
+
...overriddenInit,
|
|
141
|
+
body
|
|
142
|
+
};
|
|
143
|
+
return { url, init };
|
|
144
|
+
}
|
|
145
|
+
fetchApi = async (url, init) => {
|
|
146
|
+
let fetchParams = { url, init };
|
|
147
|
+
for (const middleware of this.middleware) {
|
|
148
|
+
if (middleware.pre) {
|
|
149
|
+
fetchParams = await middleware.pre({
|
|
150
|
+
fetch: this.fetchApi,
|
|
151
|
+
...fetchParams
|
|
152
|
+
}) || fetchParams;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
let response = undefined;
|
|
156
|
+
try {
|
|
157
|
+
response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init);
|
|
158
|
+
} catch (e) {
|
|
159
|
+
for (const middleware of this.middleware) {
|
|
160
|
+
if (middleware.onError) {
|
|
161
|
+
response = await middleware.onError({
|
|
162
|
+
fetch: this.fetchApi,
|
|
163
|
+
url: fetchParams.url,
|
|
164
|
+
init: fetchParams.init,
|
|
165
|
+
error: e,
|
|
166
|
+
response: response ? response.clone() : undefined
|
|
167
|
+
}) || response;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (response === undefined) {
|
|
171
|
+
if (e instanceof Error) {
|
|
172
|
+
throw new FetchError(e, "The request failed and the interceptors did not return an alternative response");
|
|
173
|
+
} else {
|
|
174
|
+
throw e;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const middleware of this.middleware) {
|
|
179
|
+
if (middleware.post) {
|
|
180
|
+
response = await middleware.post({
|
|
181
|
+
fetch: this.fetchApi,
|
|
182
|
+
url: fetchParams.url,
|
|
183
|
+
init: fetchParams.init,
|
|
184
|
+
response: response.clone()
|
|
185
|
+
}) || response;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return response;
|
|
189
|
+
};
|
|
190
|
+
clone() {
|
|
191
|
+
const constructor = this.constructor;
|
|
192
|
+
const next = new constructor(this.configuration);
|
|
193
|
+
next.middleware = this.middleware.slice();
|
|
194
|
+
return next;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function isBlob(value) {
|
|
198
|
+
return typeof Blob !== "undefined" && value instanceof Blob;
|
|
199
|
+
}
|
|
200
|
+
function isFormData(value) {
|
|
201
|
+
return typeof FormData !== "undefined" && value instanceof FormData;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
class ResponseError extends Error {
|
|
205
|
+
response;
|
|
206
|
+
name = "ResponseError";
|
|
207
|
+
constructor(response, msg) {
|
|
208
|
+
super(msg);
|
|
209
|
+
this.response = response;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
class FetchError extends Error {
|
|
214
|
+
cause;
|
|
215
|
+
name = "FetchError";
|
|
216
|
+
constructor(cause, msg) {
|
|
217
|
+
super(msg);
|
|
218
|
+
this.cause = cause;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
class RequiredError extends Error {
|
|
223
|
+
field;
|
|
224
|
+
name = "RequiredError";
|
|
225
|
+
constructor(field, msg) {
|
|
226
|
+
super(msg);
|
|
227
|
+
this.field = field;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function querystring(params, prefix = "") {
|
|
231
|
+
return Object.keys(params).map((key) => querystringSingleKey(key, params[key], prefix)).filter((part) => part.length > 0).join("&");
|
|
232
|
+
}
|
|
233
|
+
function querystringSingleKey(key, value, keyPrefix = "") {
|
|
234
|
+
const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key);
|
|
235
|
+
if (value instanceof Array) {
|
|
236
|
+
const multiValue = value.map((singleValue) => encodeURIComponent(String(singleValue))).join(`&${encodeURIComponent(fullKey)}=`);
|
|
237
|
+
return `${encodeURIComponent(fullKey)}=${multiValue}`;
|
|
238
|
+
}
|
|
239
|
+
if (value instanceof Set) {
|
|
240
|
+
const valueAsArray = Array.from(value);
|
|
241
|
+
return querystringSingleKey(key, valueAsArray, keyPrefix);
|
|
242
|
+
}
|
|
243
|
+
if (value instanceof Date) {
|
|
244
|
+
return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`;
|
|
245
|
+
}
|
|
246
|
+
if (value instanceof Object) {
|
|
247
|
+
return querystring(value, fullKey);
|
|
248
|
+
}
|
|
249
|
+
return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`;
|
|
250
|
+
}
|
|
251
|
+
class JSONApiResponse {
|
|
252
|
+
raw;
|
|
253
|
+
transformer;
|
|
254
|
+
constructor(raw, transformer = (jsonValue) => jsonValue) {
|
|
255
|
+
this.raw = raw;
|
|
256
|
+
this.transformer = transformer;
|
|
257
|
+
}
|
|
258
|
+
async value() {
|
|
259
|
+
return this.transformer(await this.raw.json());
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
class VoidApiResponse {
|
|
264
|
+
raw;
|
|
265
|
+
constructor(raw) {
|
|
266
|
+
this.raw = raw;
|
|
267
|
+
}
|
|
268
|
+
async value() {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// ../authz-sdk/package.json
|
|
273
|
+
var package_default = {
|
|
274
|
+
name: "@uipath/authz-sdk",
|
|
275
|
+
author: "UiPath",
|
|
276
|
+
license: "SEE LICENSE IN LICENSE.txt",
|
|
277
|
+
version: "1.204.0",
|
|
278
|
+
description: "SDK for the UiPath Authorization Service API.",
|
|
279
|
+
repository: {
|
|
280
|
+
type: "git",
|
|
281
|
+
url: "https://github.com/UiPath/cli.git",
|
|
282
|
+
directory: "packages/admin/authz-sdk"
|
|
283
|
+
},
|
|
284
|
+
publishConfig: {
|
|
285
|
+
registry: "https://npm.pkg.github.com/@uipath"
|
|
286
|
+
},
|
|
287
|
+
keywords: [
|
|
288
|
+
"uipath",
|
|
289
|
+
"authorization",
|
|
290
|
+
"authz",
|
|
291
|
+
"sdk"
|
|
292
|
+
],
|
|
293
|
+
type: "module",
|
|
294
|
+
main: "./dist/index.js",
|
|
295
|
+
types: "./dist/src/index.d.ts",
|
|
296
|
+
exports: {
|
|
297
|
+
".": {
|
|
298
|
+
types: "./dist/src/index.d.ts",
|
|
299
|
+
default: "./dist/index.js"
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
files: [
|
|
303
|
+
"dist"
|
|
304
|
+
],
|
|
305
|
+
private: true,
|
|
306
|
+
scripts: {
|
|
307
|
+
build: "bun build ./src/index.ts --outdir dist --format esm --target node --sourcemap=linked && tsc -p tsconfig.build.json --noCheck",
|
|
308
|
+
typecheck: "tsc --noEmit",
|
|
309
|
+
generate: "bun run src/scripts/generate-sdk.ts",
|
|
310
|
+
lint: "biome check ."
|
|
311
|
+
},
|
|
312
|
+
devDependencies: {
|
|
313
|
+
"@openapitools/openapi-generator-cli": "^2.31.1",
|
|
314
|
+
"@types/node": "^25.5.2",
|
|
315
|
+
"@uipath/auth": "workspace:*",
|
|
316
|
+
"@uipath/common": "workspace:*",
|
|
317
|
+
"@uipath/filesystem": "workspace:*",
|
|
318
|
+
typescript: "^7.0.2"
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// ../authz-sdk/src/user-agent.ts
|
|
323
|
+
var SDK_USER_AGENT = getSdkUserAgentToken(package_default);
|
|
324
|
+
installSdkUserAgentHeader(BaseAPI, SDK_USER_AGENT);
|
|
325
|
+
|
|
326
|
+
// ../authz-sdk/generated/src/models/ActionDetailDto.ts
|
|
327
|
+
function ActionDetailDtoFromJSON(json) {
|
|
328
|
+
return ActionDetailDtoFromJSONTyped(json, false);
|
|
329
|
+
}
|
|
330
|
+
function ActionDetailDtoFromJSONTyped(json, ignoreDiscriminator) {
|
|
331
|
+
if (json == null) {
|
|
332
|
+
return json;
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
id: json["id"],
|
|
336
|
+
name: json["name"],
|
|
337
|
+
namespace: json["namespace"],
|
|
338
|
+
serviceDisplayName: json["serviceDisplayName"],
|
|
339
|
+
resourceType: json["resourceType"],
|
|
340
|
+
resourceAction: json["resourceAction"],
|
|
341
|
+
resourceGroup: json["resourceGroup"],
|
|
342
|
+
description: json["description"],
|
|
343
|
+
scopeType: json["scopeType"] == null ? undefined : json["scopeType"],
|
|
344
|
+
originalResourceAction: json["originalResourceAction"] == null ? undefined : json["originalResourceAction"]
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// ../authz-sdk/generated/src/models/AddCustomRoleRequestDto.ts
|
|
349
|
+
function AddCustomRoleRequestDtoToJSON(json) {
|
|
350
|
+
return AddCustomRoleRequestDtoToJSONTyped(json, false);
|
|
351
|
+
}
|
|
352
|
+
function AddCustomRoleRequestDtoToJSONTyped(value, ignoreDiscriminator = false) {
|
|
353
|
+
if (value == null) {
|
|
354
|
+
return value;
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
id: value["id"],
|
|
358
|
+
roleName: value["roleName"],
|
|
359
|
+
roleService: value["roleService"],
|
|
360
|
+
roleDescription: value["roleDescription"],
|
|
361
|
+
tenantId: value["tenantId"],
|
|
362
|
+
organizationId: value["organizationId"],
|
|
363
|
+
actionsGrantedByRole: value["actionsGrantedByRole"],
|
|
364
|
+
roleScopeType: value["roleScopeType"]
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// ../authz-sdk/generated/src/models/PrincipalType.ts
|
|
369
|
+
var PrincipalType = {
|
|
370
|
+
User: "User",
|
|
371
|
+
Group: "Group",
|
|
372
|
+
ExternalApplication: "ExternalApplication",
|
|
373
|
+
Robot: "Robot"
|
|
374
|
+
};
|
|
375
|
+
function PrincipalTypeToJSON(value) {
|
|
376
|
+
return value;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// ../authz-sdk/generated/src/models/AddRoleAssignmentRequest.ts
|
|
380
|
+
function AddRoleAssignmentRequestToJSON(json) {
|
|
381
|
+
return AddRoleAssignmentRequestToJSONTyped(json, false);
|
|
382
|
+
}
|
|
383
|
+
function AddRoleAssignmentRequestToJSONTyped(value, ignoreDiscriminator = false) {
|
|
384
|
+
if (value == null) {
|
|
385
|
+
return value;
|
|
386
|
+
}
|
|
387
|
+
return {
|
|
388
|
+
roleId: value["roleId"],
|
|
389
|
+
roleName: value["roleName"],
|
|
390
|
+
scope: value["scope"],
|
|
391
|
+
type: value["type"],
|
|
392
|
+
securityPrincipalType: PrincipalTypeToJSON(value["securityPrincipalType"]),
|
|
393
|
+
securityPrincipalId: value["securityPrincipalId"],
|
|
394
|
+
createdOn: value["createdOn"] == null ? value["createdOn"] : value["createdOn"].toISOString(),
|
|
395
|
+
tenantId: value["tenantId"]
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// ../authz-sdk/generated/src/models/BulkDeleteRoleAssignmentRequestDto.ts
|
|
400
|
+
function BulkDeleteRoleAssignmentRequestDtoToJSON(json) {
|
|
401
|
+
return BulkDeleteRoleAssignmentRequestDtoToJSONTyped(json, false);
|
|
402
|
+
}
|
|
403
|
+
function BulkDeleteRoleAssignmentRequestDtoToJSONTyped(value, ignoreDiscriminator = false) {
|
|
404
|
+
if (value == null) {
|
|
405
|
+
return value;
|
|
406
|
+
}
|
|
407
|
+
return {
|
|
408
|
+
serviceId: value["serviceId"],
|
|
409
|
+
scopeToDelete: value["scopeToDelete"],
|
|
410
|
+
securityPrincipalToDelete: value["securityPrincipalToDelete"]
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// ../authz-sdk/generated/src/models/BulkUpdateRoleAssignmentsDto.ts
|
|
415
|
+
function BulkUpdateRoleAssignmentsDtoToJSON(json) {
|
|
416
|
+
return BulkUpdateRoleAssignmentsDtoToJSONTyped(json, false);
|
|
417
|
+
}
|
|
418
|
+
function BulkUpdateRoleAssignmentsDtoToJSONTyped(value, ignoreDiscriminator = false) {
|
|
419
|
+
if (value == null) {
|
|
420
|
+
return value;
|
|
421
|
+
}
|
|
422
|
+
return {
|
|
423
|
+
roleAssignmentsToAdd: value["roleAssignmentsToAdd"].map(AddRoleAssignmentRequestToJSON),
|
|
424
|
+
roleAssignmentsToDelete: value["roleAssignmentsToDelete"]
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// ../authz-sdk/generated/src/models/RoleApiDto.ts
|
|
429
|
+
function RoleApiDtoFromJSON(json) {
|
|
430
|
+
return RoleApiDtoFromJSONTyped(json, false);
|
|
431
|
+
}
|
|
432
|
+
function RoleApiDtoFromJSONTyped(json, ignoreDiscriminator) {
|
|
433
|
+
if (json == null) {
|
|
434
|
+
return json;
|
|
435
|
+
}
|
|
436
|
+
return {
|
|
437
|
+
id: json["id"],
|
|
438
|
+
name: json["name"],
|
|
439
|
+
description: json["description"],
|
|
440
|
+
type: json["type"],
|
|
441
|
+
scopeType: json["scopeType"],
|
|
442
|
+
createdBy: json["createdBy"],
|
|
443
|
+
createdOn: new Date(json["createdOn"]),
|
|
444
|
+
tenantId: json["tenantId"],
|
|
445
|
+
ownerServiceId: json["ownerServiceId"],
|
|
446
|
+
ownerServiceName: json["ownerServiceName"],
|
|
447
|
+
actionDetails: json["actionDetails"].map(ActionDetailDtoFromJSON)
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// ../authz-sdk/generated/src/models/RoleApiDtoPagedResult.ts
|
|
452
|
+
function RoleApiDtoPagedResultFromJSON(json) {
|
|
453
|
+
return RoleApiDtoPagedResultFromJSONTyped(json, false);
|
|
454
|
+
}
|
|
455
|
+
function RoleApiDtoPagedResultFromJSONTyped(json, ignoreDiscriminator) {
|
|
456
|
+
if (json == null) {
|
|
457
|
+
return json;
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
totalCount: json["totalCount"] == null ? undefined : json["totalCount"],
|
|
461
|
+
results: json["results"] == null ? undefined : json["results"].map(RoleApiDtoFromJSON)
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// ../authz-sdk/generated/src/models/RoleAssignmentDto.ts
|
|
466
|
+
function RoleAssignmentDtoFromJSON(json) {
|
|
467
|
+
return RoleAssignmentDtoFromJSONTyped(json, false);
|
|
468
|
+
}
|
|
469
|
+
function RoleAssignmentDtoFromJSONTyped(json, ignoreDiscriminator) {
|
|
470
|
+
if (json == null) {
|
|
471
|
+
return json;
|
|
472
|
+
}
|
|
473
|
+
return {
|
|
474
|
+
id: json["id"],
|
|
475
|
+
securityPrincipalId: json["securityPrincipalId"],
|
|
476
|
+
securityPrincipalType: json["securityPrincipalType"],
|
|
477
|
+
type: json["type"],
|
|
478
|
+
scope: json["scope"],
|
|
479
|
+
roleId: json["roleId"],
|
|
480
|
+
roleName: json["roleName"],
|
|
481
|
+
roleType: json["roleType"],
|
|
482
|
+
createdBy: json["createdBy"],
|
|
483
|
+
createdOn: new Date(json["createdOn"]),
|
|
484
|
+
inherited: json["inherited"] == null ? undefined : json["inherited"],
|
|
485
|
+
mutable: json["mutable"] == null ? undefined : json["mutable"]
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// ../authz-sdk/generated/src/models/RoleAssignmentDtoPerSecurityPrincipalIdDto.ts
|
|
490
|
+
function RoleAssignmentDtoPerSecurityPrincipalIdDtoFromJSON(json) {
|
|
491
|
+
return RoleAssignmentDtoPerSecurityPrincipalIdDtoFromJSONTyped(json, false);
|
|
492
|
+
}
|
|
493
|
+
function RoleAssignmentDtoPerSecurityPrincipalIdDtoFromJSONTyped(json, ignoreDiscriminator) {
|
|
494
|
+
if (json == null) {
|
|
495
|
+
return json;
|
|
496
|
+
}
|
|
497
|
+
return {
|
|
498
|
+
securityPrincipalId: json["securityPrincipalId"],
|
|
499
|
+
roleAssignmentDtos: json["roleAssignmentDtos"].map(RoleAssignmentDtoFromJSON),
|
|
500
|
+
displayName: json["displayName"],
|
|
501
|
+
email: json["email"],
|
|
502
|
+
type: json["type"],
|
|
503
|
+
source: json["source"]
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// ../authz-sdk/generated/src/models/RoleAssignmentDtoPerSecurityPrincipalIdDtoPagedResult.ts
|
|
508
|
+
function RoleAssignmentDtoPerSecurityPrincipalIdDtoPagedResultFromJSON(json) {
|
|
509
|
+
return RoleAssignmentDtoPerSecurityPrincipalIdDtoPagedResultFromJSONTyped(json, false);
|
|
510
|
+
}
|
|
511
|
+
function RoleAssignmentDtoPerSecurityPrincipalIdDtoPagedResultFromJSONTyped(json, ignoreDiscriminator) {
|
|
512
|
+
if (json == null) {
|
|
513
|
+
return json;
|
|
514
|
+
}
|
|
515
|
+
return {
|
|
516
|
+
totalCount: json["totalCount"] == null ? undefined : json["totalCount"],
|
|
517
|
+
results: json["results"] == null ? undefined : json["results"].map(RoleAssignmentDtoPerSecurityPrincipalIdDtoFromJSON)
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// ../authz-sdk/generated/src/apis/ActionApi.ts
|
|
522
|
+
class ActionApi extends BaseAPI {
|
|
523
|
+
async apiActionsGetRaw(requestParameters, initOverrides) {
|
|
524
|
+
const queryParameters = {};
|
|
525
|
+
if (requestParameters["serviceName"] != null) {
|
|
526
|
+
queryParameters["serviceName"] = requestParameters["serviceName"];
|
|
527
|
+
}
|
|
528
|
+
if (requestParameters["scopeType"] != null) {
|
|
529
|
+
queryParameters["scopeType"] = requestParameters["scopeType"];
|
|
530
|
+
}
|
|
531
|
+
const headerParameters = {};
|
|
532
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
533
|
+
const token = this.configuration.accessToken;
|
|
534
|
+
const tokenString = await token("bearerAuth", []);
|
|
535
|
+
if (tokenString) {
|
|
536
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
let urlPath = `/api/actions`;
|
|
540
|
+
const response = await this.request({
|
|
541
|
+
path: urlPath,
|
|
542
|
+
method: "GET",
|
|
543
|
+
headers: headerParameters,
|
|
544
|
+
query: queryParameters
|
|
545
|
+
}, initOverrides);
|
|
546
|
+
return new JSONApiResponse(response, (jsonValue) => jsonValue.map(ActionDetailDtoFromJSON));
|
|
547
|
+
}
|
|
548
|
+
async apiActionsGet(requestParameters = {}, initOverrides) {
|
|
549
|
+
const response = await this.apiActionsGetRaw(requestParameters, initOverrides);
|
|
550
|
+
return await response.value();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// ../authz-sdk/generated/src/apis/RoleApi.ts
|
|
555
|
+
class RoleApi extends BaseAPI {
|
|
556
|
+
async apiRolesGetRaw(requestParameters, initOverrides) {
|
|
557
|
+
const queryParameters = {};
|
|
558
|
+
if (requestParameters["scopeType"] != null) {
|
|
559
|
+
queryParameters["scopeType"] = requestParameters["scopeType"];
|
|
560
|
+
}
|
|
561
|
+
if (requestParameters["serviceName"] != null) {
|
|
562
|
+
queryParameters["serviceName"] = requestParameters["serviceName"];
|
|
563
|
+
}
|
|
564
|
+
if (requestParameters["contains"] != null) {
|
|
565
|
+
queryParameters["contains"] = requestParameters["contains"];
|
|
566
|
+
}
|
|
567
|
+
if (requestParameters["tenantId"] != null) {
|
|
568
|
+
queryParameters["tenantId"] = requestParameters["tenantId"];
|
|
569
|
+
}
|
|
570
|
+
if (requestParameters["top"] != null) {
|
|
571
|
+
queryParameters["top"] = requestParameters["top"];
|
|
572
|
+
}
|
|
573
|
+
if (requestParameters["skip"] != null) {
|
|
574
|
+
queryParameters["skip"] = requestParameters["skip"];
|
|
575
|
+
}
|
|
576
|
+
if (requestParameters["sortBy"] != null) {
|
|
577
|
+
queryParameters["sortBy"] = requestParameters["sortBy"];
|
|
578
|
+
}
|
|
579
|
+
if (requestParameters["sortOrder"] != null) {
|
|
580
|
+
queryParameters["sortOrder"] = requestParameters["sortOrder"];
|
|
581
|
+
}
|
|
582
|
+
if (requestParameters["roleType"] != null) {
|
|
583
|
+
queryParameters["roleType"] = requestParameters["roleType"];
|
|
584
|
+
}
|
|
585
|
+
const headerParameters = {};
|
|
586
|
+
if (requestParameters["xUipathInternalAccountid"] != null) {
|
|
587
|
+
headerParameters["x-uipath-internal-accountid"] = String(requestParameters["xUipathInternalAccountid"]);
|
|
588
|
+
}
|
|
589
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
590
|
+
const token = this.configuration.accessToken;
|
|
591
|
+
const tokenString = await token("bearerAuth", []);
|
|
592
|
+
if (tokenString) {
|
|
593
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
let urlPath = `/api/roles`;
|
|
597
|
+
const response = await this.request({
|
|
598
|
+
path: urlPath,
|
|
599
|
+
method: "GET",
|
|
600
|
+
headers: headerParameters,
|
|
601
|
+
query: queryParameters
|
|
602
|
+
}, initOverrides);
|
|
603
|
+
return new JSONApiResponse(response, (jsonValue) => RoleApiDtoPagedResultFromJSON(jsonValue));
|
|
604
|
+
}
|
|
605
|
+
async apiRolesGet(requestParameters = {}, initOverrides) {
|
|
606
|
+
const response = await this.apiRolesGetRaw(requestParameters, initOverrides);
|
|
607
|
+
return await response.value();
|
|
608
|
+
}
|
|
609
|
+
async apiRolesPutRaw(requestParameters, initOverrides) {
|
|
610
|
+
const queryParameters = {};
|
|
611
|
+
const headerParameters = {};
|
|
612
|
+
headerParameters["Content-Type"] = "application/json";
|
|
613
|
+
if (requestParameters["xUipathInternalAccountid"] != null) {
|
|
614
|
+
headerParameters["x-uipath-internal-accountid"] = String(requestParameters["xUipathInternalAccountid"]);
|
|
615
|
+
}
|
|
616
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
617
|
+
const token = this.configuration.accessToken;
|
|
618
|
+
const tokenString = await token("bearerAuth", []);
|
|
619
|
+
if (tokenString) {
|
|
620
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
let urlPath = `/api/roles`;
|
|
624
|
+
const response = await this.request({
|
|
625
|
+
path: urlPath,
|
|
626
|
+
method: "PUT",
|
|
627
|
+
headers: headerParameters,
|
|
628
|
+
query: queryParameters,
|
|
629
|
+
body: AddCustomRoleRequestDtoToJSON(requestParameters["addCustomRoleRequestDto"])
|
|
630
|
+
}, initOverrides);
|
|
631
|
+
return new VoidApiResponse(response);
|
|
632
|
+
}
|
|
633
|
+
async apiRolesPut(requestParameters = {}, initOverrides) {
|
|
634
|
+
await this.apiRolesPutRaw(requestParameters, initOverrides);
|
|
635
|
+
}
|
|
636
|
+
async apiRolesRoleIdDeleteRaw(requestParameters, initOverrides) {
|
|
637
|
+
if (requestParameters["roleId"] == null) {
|
|
638
|
+
throw new RequiredError("roleId", 'Required parameter "roleId" was null or undefined when calling apiRolesRoleIdDelete().');
|
|
639
|
+
}
|
|
640
|
+
const queryParameters = {};
|
|
641
|
+
const headerParameters = {};
|
|
642
|
+
if (requestParameters["xUipathInternalAccountid"] != null) {
|
|
643
|
+
headerParameters["x-uipath-internal-accountid"] = String(requestParameters["xUipathInternalAccountid"]);
|
|
644
|
+
}
|
|
645
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
646
|
+
const token = this.configuration.accessToken;
|
|
647
|
+
const tokenString = await token("bearerAuth", []);
|
|
648
|
+
if (tokenString) {
|
|
649
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
let urlPath = `/api/roles/{roleId}`;
|
|
653
|
+
urlPath = urlPath.replace(`{${"roleId"}}`, encodeURIComponent(String(requestParameters["roleId"])));
|
|
654
|
+
const response = await this.request({
|
|
655
|
+
path: urlPath,
|
|
656
|
+
method: "DELETE",
|
|
657
|
+
headers: headerParameters,
|
|
658
|
+
query: queryParameters
|
|
659
|
+
}, initOverrides);
|
|
660
|
+
return new VoidApiResponse(response);
|
|
661
|
+
}
|
|
662
|
+
async apiRolesRoleIdDelete(requestParameters, initOverrides) {
|
|
663
|
+
await this.apiRolesRoleIdDeleteRaw(requestParameters, initOverrides);
|
|
664
|
+
}
|
|
665
|
+
async apiRolesRoleIdGetRaw(requestParameters, initOverrides) {
|
|
666
|
+
if (requestParameters["roleId"] == null) {
|
|
667
|
+
throw new RequiredError("roleId", 'Required parameter "roleId" was null or undefined when calling apiRolesRoleIdGet().');
|
|
668
|
+
}
|
|
669
|
+
const queryParameters = {};
|
|
670
|
+
const headerParameters = {};
|
|
671
|
+
if (requestParameters["xUipathInternalAccountid"] != null) {
|
|
672
|
+
headerParameters["x-uipath-internal-accountid"] = String(requestParameters["xUipathInternalAccountid"]);
|
|
673
|
+
}
|
|
674
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
675
|
+
const token = this.configuration.accessToken;
|
|
676
|
+
const tokenString = await token("bearerAuth", []);
|
|
677
|
+
if (tokenString) {
|
|
678
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
let urlPath = `/api/roles/{roleId}`;
|
|
682
|
+
urlPath = urlPath.replace(`{${"roleId"}}`, encodeURIComponent(String(requestParameters["roleId"])));
|
|
683
|
+
const response = await this.request({
|
|
684
|
+
path: urlPath,
|
|
685
|
+
method: "GET",
|
|
686
|
+
headers: headerParameters,
|
|
687
|
+
query: queryParameters
|
|
688
|
+
}, initOverrides);
|
|
689
|
+
return new JSONApiResponse(response, (jsonValue) => RoleApiDtoFromJSON(jsonValue));
|
|
690
|
+
}
|
|
691
|
+
async apiRolesRoleIdGet(requestParameters, initOverrides) {
|
|
692
|
+
const response = await this.apiRolesRoleIdGetRaw(requestParameters, initOverrides);
|
|
693
|
+
return await response.value();
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// ../authz-sdk/generated/src/apis/RoleAssignmentApi.ts
|
|
698
|
+
class RoleAssignmentApi extends BaseAPI {
|
|
699
|
+
async apiUserroleassignmentsBulkdeletePostRaw(requestParameters, initOverrides) {
|
|
700
|
+
const queryParameters = {};
|
|
701
|
+
const headerParameters = {};
|
|
702
|
+
headerParameters["Content-Type"] = "application/json";
|
|
703
|
+
if (requestParameters["xUipathInternalAccountid"] != null) {
|
|
704
|
+
headerParameters["x-uipath-internal-accountid"] = String(requestParameters["xUipathInternalAccountid"]);
|
|
705
|
+
}
|
|
706
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
707
|
+
const token = this.configuration.accessToken;
|
|
708
|
+
const tokenString = await token("bearerAuth", []);
|
|
709
|
+
if (tokenString) {
|
|
710
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
let urlPath = `/api/userroleassignments/bulkdelete`;
|
|
714
|
+
const response = await this.request({
|
|
715
|
+
path: urlPath,
|
|
716
|
+
method: "POST",
|
|
717
|
+
headers: headerParameters,
|
|
718
|
+
query: queryParameters,
|
|
719
|
+
body: BulkDeleteRoleAssignmentRequestDtoToJSON(requestParameters["bulkDeleteRoleAssignmentRequestDto"])
|
|
720
|
+
}, initOverrides);
|
|
721
|
+
return new VoidApiResponse(response);
|
|
722
|
+
}
|
|
723
|
+
async apiUserroleassignmentsBulkdeletePost(requestParameters = {}, initOverrides) {
|
|
724
|
+
await this.apiUserroleassignmentsBulkdeletePostRaw(requestParameters, initOverrides);
|
|
725
|
+
}
|
|
726
|
+
async apiUserroleassignmentsExportGetRaw(requestParameters, initOverrides) {
|
|
727
|
+
const queryParameters = {};
|
|
728
|
+
if (requestParameters["exportOutputType"] != null) {
|
|
729
|
+
queryParameters["exportOutputType"] = requestParameters["exportOutputType"];
|
|
730
|
+
}
|
|
731
|
+
if (requestParameters["expandGroupMemberships"] != null) {
|
|
732
|
+
queryParameters["expandGroupMemberships"] = requestParameters["expandGroupMemberships"];
|
|
733
|
+
}
|
|
734
|
+
const headerParameters = {};
|
|
735
|
+
if (requestParameters["xUipathInternalAccountid"] != null) {
|
|
736
|
+
headerParameters["x-uipath-internal-accountid"] = String(requestParameters["xUipathInternalAccountid"]);
|
|
737
|
+
}
|
|
738
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
739
|
+
const token = this.configuration.accessToken;
|
|
740
|
+
const tokenString = await token("bearerAuth", []);
|
|
741
|
+
if (tokenString) {
|
|
742
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
let urlPath = `/api/userroleassignments/export`;
|
|
746
|
+
const response = await this.request({
|
|
747
|
+
path: urlPath,
|
|
748
|
+
method: "GET",
|
|
749
|
+
headers: headerParameters,
|
|
750
|
+
query: queryParameters
|
|
751
|
+
}, initOverrides);
|
|
752
|
+
return new VoidApiResponse(response);
|
|
753
|
+
}
|
|
754
|
+
async apiUserroleassignmentsExportGet(requestParameters = {}, initOverrides) {
|
|
755
|
+
await this.apiUserroleassignmentsExportGetRaw(requestParameters, initOverrides);
|
|
756
|
+
}
|
|
757
|
+
async apiUserroleassignmentsGetRaw(requestParameters, initOverrides) {
|
|
758
|
+
const queryParameters = {};
|
|
759
|
+
if (requestParameters["scope"] != null) {
|
|
760
|
+
queryParameters["scope"] = requestParameters["scope"];
|
|
761
|
+
}
|
|
762
|
+
if (requestParameters["serviceName"] != null) {
|
|
763
|
+
queryParameters["serviceName"] = requestParameters["serviceName"];
|
|
764
|
+
}
|
|
765
|
+
if (requestParameters["securityPrincipalId"] != null) {
|
|
766
|
+
queryParameters["securityPrincipalId"] = requestParameters["securityPrincipalId"];
|
|
767
|
+
}
|
|
768
|
+
if (requestParameters["roleIds"] != null) {
|
|
769
|
+
queryParameters["roleIds"] = requestParameters["roleIds"];
|
|
770
|
+
}
|
|
771
|
+
if (requestParameters["top"] != null) {
|
|
772
|
+
queryParameters["top"] = requestParameters["top"];
|
|
773
|
+
}
|
|
774
|
+
if (requestParameters["skip"] != null) {
|
|
775
|
+
queryParameters["skip"] = requestParameters["skip"];
|
|
776
|
+
}
|
|
777
|
+
if (requestParameters["noInheritance"] != null) {
|
|
778
|
+
queryParameters["noInheritance"] = requestParameters["noInheritance"];
|
|
779
|
+
}
|
|
780
|
+
if (requestParameters["roleScopeType"] != null) {
|
|
781
|
+
queryParameters["roleScopeType"] = requestParameters["roleScopeType"];
|
|
782
|
+
}
|
|
783
|
+
const headerParameters = {};
|
|
784
|
+
if (requestParameters["xUipathInternalAccountid"] != null) {
|
|
785
|
+
headerParameters["x-uipath-internal-accountid"] = String(requestParameters["xUipathInternalAccountid"]);
|
|
786
|
+
}
|
|
787
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
788
|
+
const token = this.configuration.accessToken;
|
|
789
|
+
const tokenString = await token("bearerAuth", []);
|
|
790
|
+
if (tokenString) {
|
|
791
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
let urlPath = `/api/userroleassignments`;
|
|
795
|
+
const response = await this.request({
|
|
796
|
+
path: urlPath,
|
|
797
|
+
method: "GET",
|
|
798
|
+
headers: headerParameters,
|
|
799
|
+
query: queryParameters
|
|
800
|
+
}, initOverrides);
|
|
801
|
+
return new JSONApiResponse(response, (jsonValue) => RoleAssignmentDtoPerSecurityPrincipalIdDtoPagedResultFromJSON(jsonValue));
|
|
802
|
+
}
|
|
803
|
+
async apiUserroleassignmentsGet(requestParameters = {}, initOverrides) {
|
|
804
|
+
const response = await this.apiUserroleassignmentsGetRaw(requestParameters, initOverrides);
|
|
805
|
+
return await response.value();
|
|
806
|
+
}
|
|
807
|
+
async apiUserroleassignmentsPatchRaw(requestParameters, initOverrides) {
|
|
808
|
+
const queryParameters = {};
|
|
809
|
+
const headerParameters = {};
|
|
810
|
+
headerParameters["Content-Type"] = "application/json";
|
|
811
|
+
if (requestParameters["xUipathInternalAccountid"] != null) {
|
|
812
|
+
headerParameters["x-uipath-internal-accountid"] = String(requestParameters["xUipathInternalAccountid"]);
|
|
813
|
+
}
|
|
814
|
+
if (this.configuration && this.configuration.accessToken) {
|
|
815
|
+
const token = this.configuration.accessToken;
|
|
816
|
+
const tokenString = await token("bearerAuth", []);
|
|
817
|
+
if (tokenString) {
|
|
818
|
+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
let urlPath = `/api/userroleassignments`;
|
|
822
|
+
const response = await this.request({
|
|
823
|
+
path: urlPath,
|
|
824
|
+
method: "PATCH",
|
|
825
|
+
headers: headerParameters,
|
|
826
|
+
query: queryParameters,
|
|
827
|
+
body: BulkUpdateRoleAssignmentsDtoToJSON(requestParameters["bulkUpdateRoleAssignmentsDto"])
|
|
828
|
+
}, initOverrides);
|
|
829
|
+
return new VoidApiResponse(response);
|
|
830
|
+
}
|
|
831
|
+
async apiUserroleassignmentsPatch(requestParameters = {}, initOverrides) {
|
|
832
|
+
await this.apiUserroleassignmentsPatchRaw(requestParameters, initOverrides);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
// ../authz-sdk/src/client-factory.ts
|
|
836
|
+
async function resolveConfig(plane, options) {
|
|
837
|
+
const status = await getLoginStatusAsync({
|
|
838
|
+
ensureTokenValidityMinutes: options?.loginValidity
|
|
839
|
+
});
|
|
840
|
+
if (status.loginStatus !== "Logged in" || !status.baseUrl || !status.accessToken) {
|
|
841
|
+
throw new Error(status.hint ? `Not logged in. ${status.hint}` : "Not logged in. Run 'uip login' first.");
|
|
842
|
+
}
|
|
843
|
+
if (!status.organizationId) {
|
|
844
|
+
throw new Error("Organization ID not available. Ensure you are logged in with an organization context.");
|
|
845
|
+
}
|
|
846
|
+
const basePath = `${status.baseUrl}/${status.organizationId}/${plane}_`;
|
|
847
|
+
const bearerToken = options?.s2sToken ?? status.accessToken;
|
|
848
|
+
return {
|
|
849
|
+
config: new Configuration({
|
|
850
|
+
basePath,
|
|
851
|
+
accessToken: async () => bearerToken,
|
|
852
|
+
headers: addSdkUserAgentHeader(undefined, SDK_USER_AGENT)
|
|
853
|
+
}),
|
|
854
|
+
organizationId: status.organizationId,
|
|
855
|
+
tenantId: status.tenantId,
|
|
856
|
+
tenantName: status.tenantName
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
async function createAuthzConfig(plane, options) {
|
|
860
|
+
const { config } = await resolveConfig(plane, options);
|
|
861
|
+
return config;
|
|
862
|
+
}
|
|
863
|
+
async function createApiClient2(ApiClass, plane, options) {
|
|
864
|
+
const { config, organizationId, tenantId, tenantName } = await resolveConfig(plane, options);
|
|
865
|
+
return {
|
|
866
|
+
api: new ApiClass(config),
|
|
867
|
+
organizationId,
|
|
868
|
+
tenantId,
|
|
869
|
+
tenantName
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
async function createPapClient(ApiClass, options) {
|
|
873
|
+
return createApiClient2(ApiClass, "pap", options);
|
|
874
|
+
}
|
|
875
|
+
// ../authz-commands/src/commands/_shared.ts
|
|
876
|
+
var LOGIN_INSTRUCTIONS = "Ensure you are logged in with 'uip login' and have access to the Authorization service.";
|
|
877
|
+
var NON_NEGATIVE_INTEGER_RE = /^\d+$/;
|
|
878
|
+
var parseIntOption = (raw) => {
|
|
879
|
+
const trimmed = raw.trim();
|
|
880
|
+
if (!NON_NEGATIVE_INTEGER_RE.test(trimmed)) {
|
|
881
|
+
throw new Error(`Expected a non-negative integer, got '${raw}'.`);
|
|
882
|
+
}
|
|
883
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
884
|
+
if (!Number.isFinite(parsed)) {
|
|
885
|
+
throw new Error(`Expected a non-negative integer, got '${raw}'.`);
|
|
886
|
+
}
|
|
887
|
+
return parsed;
|
|
888
|
+
};
|
|
889
|
+
var withLoginValidity = (cmd) => {
|
|
890
|
+
cmd.option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", parseIntOption);
|
|
891
|
+
return cmd;
|
|
892
|
+
};
|
|
893
|
+
async function loadJsonFile(file, typeLabel) {
|
|
894
|
+
const fs = getFileSystem();
|
|
895
|
+
const [readErr, content] = await catchError(fs.readFile(file, "utf-8"));
|
|
896
|
+
if (readErr || content === null) {
|
|
897
|
+
return [
|
|
898
|
+
{
|
|
899
|
+
message: readErr?.message ?? `File not found: ${file}`,
|
|
900
|
+
instructions: `Verify the file exists at '${file}' and is readable.`
|
|
901
|
+
},
|
|
902
|
+
null
|
|
903
|
+
];
|
|
904
|
+
}
|
|
905
|
+
const [parseErr, parsed] = catchError(() => JSON.parse(content));
|
|
906
|
+
if (parseErr) {
|
|
907
|
+
return [
|
|
908
|
+
{
|
|
909
|
+
message: parseErr.message,
|
|
910
|
+
instructions: `The file must be valid JSON conforming to ${typeLabel}.`
|
|
911
|
+
},
|
|
912
|
+
null
|
|
913
|
+
];
|
|
914
|
+
}
|
|
915
|
+
return [null, parsed];
|
|
916
|
+
}
|
|
917
|
+
var emitLoadError = (err) => {
|
|
918
|
+
OutputFormatter.error({
|
|
919
|
+
Result: RESULTS.Failure,
|
|
920
|
+
Message: err.message,
|
|
921
|
+
Instructions: err.instructions
|
|
922
|
+
});
|
|
923
|
+
processContext.exit(1);
|
|
924
|
+
};
|
|
925
|
+
var emitFailure = async (error, instructions) => {
|
|
926
|
+
OutputFormatter.error({
|
|
927
|
+
Result: RESULTS.Failure,
|
|
928
|
+
Message: await extractErrorMessage(error),
|
|
929
|
+
Instructions: instructions
|
|
930
|
+
});
|
|
931
|
+
processContext.exit(1);
|
|
932
|
+
};
|
|
933
|
+
var GUID_RE = /^[0-9a-fA-F-]{36}$/;
|
|
934
|
+
async function extractResponseData(response) {
|
|
935
|
+
const [readErr, text] = await catchError(response.raw.clone().text());
|
|
936
|
+
if (readErr || !text)
|
|
937
|
+
return;
|
|
938
|
+
const [, parsed] = catchError(() => JSON.parse(text));
|
|
939
|
+
if (typeof parsed === "string" && GUID_RE.test(parsed)) {
|
|
940
|
+
return { operationId: parsed };
|
|
941
|
+
}
|
|
942
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
943
|
+
return parsed;
|
|
944
|
+
}
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
var ORG_SCOPE_TYPE = "Organization";
|
|
948
|
+
var TENANT_SCOPE_TYPE = "Tenant";
|
|
949
|
+
var FOLDER_SCOPE_TYPE = "Folder";
|
|
950
|
+
var PROJECT_SCOPE_TYPE = "Project";
|
|
951
|
+
var KNOWN_SERVICES = [
|
|
952
|
+
"apps",
|
|
953
|
+
"authz",
|
|
954
|
+
"automationops",
|
|
955
|
+
"casemanagement",
|
|
956
|
+
"centralizedaccess",
|
|
957
|
+
"dataservice",
|
|
958
|
+
"documentunderstanding",
|
|
959
|
+
"identity",
|
|
960
|
+
"insights",
|
|
961
|
+
"licensing",
|
|
962
|
+
"oms",
|
|
963
|
+
"orchestrator",
|
|
964
|
+
"platform",
|
|
965
|
+
"processmining",
|
|
966
|
+
"reinfer",
|
|
967
|
+
"studio",
|
|
968
|
+
"taskmining",
|
|
969
|
+
"testmanager"
|
|
970
|
+
];
|
|
971
|
+
var TENANT_SERVICES = new Set([
|
|
972
|
+
"orchestrator",
|
|
973
|
+
"dataservice",
|
|
974
|
+
"insights",
|
|
975
|
+
"taskmining",
|
|
976
|
+
"testmanager",
|
|
977
|
+
"documentunderstanding",
|
|
978
|
+
"processmining",
|
|
979
|
+
"reinfer",
|
|
980
|
+
"casemanagement"
|
|
981
|
+
]);
|
|
982
|
+
var ORG_SERVICES = new Set([
|
|
983
|
+
"apps",
|
|
984
|
+
"automationops",
|
|
985
|
+
"identity",
|
|
986
|
+
"licensing",
|
|
987
|
+
"oms",
|
|
988
|
+
"platform",
|
|
989
|
+
"authz",
|
|
990
|
+
"centralizedaccess",
|
|
991
|
+
"studio"
|
|
992
|
+
]);
|
|
993
|
+
var DELTA_SYNC_SERVICES = new Set([
|
|
994
|
+
"orchestrator",
|
|
995
|
+
"dataservice",
|
|
996
|
+
"insights",
|
|
997
|
+
"taskmining",
|
|
998
|
+
"testmanager",
|
|
999
|
+
"automationops",
|
|
1000
|
+
"casemanagement",
|
|
1001
|
+
"processmining"
|
|
1002
|
+
]);
|
|
1003
|
+
var PLATFORM_SERVICES = new Set([
|
|
1004
|
+
"authz",
|
|
1005
|
+
"oms",
|
|
1006
|
+
"platform",
|
|
1007
|
+
"identity",
|
|
1008
|
+
"licensing"
|
|
1009
|
+
]);
|
|
1010
|
+
var isRoleAuthoringBlocked = (name) => {
|
|
1011
|
+
if (name === undefined || name === null)
|
|
1012
|
+
return null;
|
|
1013
|
+
const lower = name.toLowerCase();
|
|
1014
|
+
if (DELTA_SYNC_SERVICES.has(lower))
|
|
1015
|
+
return "delta-sync";
|
|
1016
|
+
if (PLATFORM_SERVICES.has(lower))
|
|
1017
|
+
return "platform";
|
|
1018
|
+
return null;
|
|
1019
|
+
};
|
|
1020
|
+
var ROLE_AUTHORING_HINTS = {
|
|
1021
|
+
orchestrator: "Use `uip or roles create | edit | delete` instead.",
|
|
1022
|
+
dataservice: "Manage Data Service roles via the Data Service UI or API — the CLI does not expose role management for this service.",
|
|
1023
|
+
insights: "Manage Insights roles via the Insights UI or API — the CLI does not expose role management for this service.",
|
|
1024
|
+
taskmining: "Manage Task Mining roles via the Task Mining UI or API — the CLI does not expose role management for this service.",
|
|
1025
|
+
testmanager: "Manage Test Manager roles via the Test Manager UI or API — the CLI does not expose role management for this service.",
|
|
1026
|
+
automationops: "Manage Automation Ops roles via the Automation Ops UI or API — the CLI does not expose role management for this service.",
|
|
1027
|
+
casemanagement: "Manage Case Management roles via the Case Management UI or API — the CLI does not expose role management for this service.",
|
|
1028
|
+
processmining: "Manage Process Mining roles via the Process Mining UI or API — the CLI does not expose role management for this service.",
|
|
1029
|
+
authz: "Roles for the Authorization service are platform-owned and cannot be customized.",
|
|
1030
|
+
oms: "Roles for OMS are platform-owned and cannot be customized.",
|
|
1031
|
+
platform: "Roles for the Platform service are platform-owned and cannot be customized.",
|
|
1032
|
+
identity: "Roles for Identity are platform-owned and cannot be customized.",
|
|
1033
|
+
licensing: "Roles for Licensing are platform-owned and cannot be customized."
|
|
1034
|
+
};
|
|
1035
|
+
var SERVICE_OPTION_HINT = `Known services: ${KNOWN_SERVICES.join(", ")} (free-form — other names accepted).`;
|
|
1036
|
+
var inferRoleService = (role) => {
|
|
1037
|
+
const raw = role;
|
|
1038
|
+
const namespaces = raw?.actionDetails?.map((a) => a.namespace?.toLowerCase()).filter((x) => x !== undefined && x.length > 0) ?? [];
|
|
1039
|
+
const nonAuthz = Array.from(new Set(namespaces.filter((ns) => ns !== "authz")));
|
|
1040
|
+
if (nonAuthz.length === 1)
|
|
1041
|
+
return nonAuthz[0];
|
|
1042
|
+
if (nonAuthz.length > 1)
|
|
1043
|
+
return;
|
|
1044
|
+
return namespaces.includes("authz") ? "authz" : undefined;
|
|
1045
|
+
};
|
|
1046
|
+
var rejectIfRoleAuthoringBlocked = (serviceName, action) => {
|
|
1047
|
+
const reason = isRoleAuthoringBlocked(serviceName);
|
|
1048
|
+
if (reason === null)
|
|
1049
|
+
return false;
|
|
1050
|
+
const lower = serviceName.toLowerCase();
|
|
1051
|
+
const message = reason === "delta-sync" ? `Custom roles for '${lower}' are owned by the '${lower}' service itself and cannot be ${action}d through 'uip admin authorization roles'.` : `'${lower}' is a platform-level service; its roles are platform-owned and cannot be ${action}d by tenants.`;
|
|
1052
|
+
OutputFormatter.error({
|
|
1053
|
+
Result: RESULTS.Failure,
|
|
1054
|
+
Message: message,
|
|
1055
|
+
Instructions: ROLE_AUTHORING_HINTS[lower] ?? "This service does not allow custom-role authoring through the Authorization CLI."
|
|
1056
|
+
});
|
|
1057
|
+
processContext.exit(1);
|
|
1058
|
+
return true;
|
|
1059
|
+
};
|
|
1060
|
+
var CENTRALIZED_ACCESS_SERVICE = "centralizedaccess";
|
|
1061
|
+
var EMPTY_TENANT_GUID = "00000000-0000-0000-0000-000000000000";
|
|
1062
|
+
var ROLE_AUTHORING_SCOPES = [
|
|
1063
|
+
"Organization",
|
|
1064
|
+
"TenantGlobal",
|
|
1065
|
+
"Tenant",
|
|
1066
|
+
"Project"
|
|
1067
|
+
];
|
|
1068
|
+
var ROLE_LIST_SCOPES = [
|
|
1069
|
+
"Organization",
|
|
1070
|
+
"TenantGlobal",
|
|
1071
|
+
"Tenant",
|
|
1072
|
+
"Project",
|
|
1073
|
+
"Folder"
|
|
1074
|
+
];
|
|
1075
|
+
var makeScopeCanonicalizer = (scopes) => (value) => {
|
|
1076
|
+
const lower = value.toLowerCase();
|
|
1077
|
+
const match = scopes.find((s) => s.toLowerCase() === lower);
|
|
1078
|
+
if (match === undefined) {
|
|
1079
|
+
throw new InvalidArgumentError(`Allowed choices are ${scopes.join(", ")} (case-insensitive).`);
|
|
1080
|
+
}
|
|
1081
|
+
return match;
|
|
1082
|
+
};
|
|
1083
|
+
var canonicalizeRoleAuthoringScope = makeScopeCanonicalizer(ROLE_AUTHORING_SCOPES);
|
|
1084
|
+
var canonicalizeRoleListScope = makeScopeCanonicalizer(ROLE_LIST_SCOPES);
|
|
1085
|
+
var ASSIGNMENT_LIST_SCOPES = [
|
|
1086
|
+
"Organization",
|
|
1087
|
+
"Tenant",
|
|
1088
|
+
"Project",
|
|
1089
|
+
"Folder",
|
|
1090
|
+
"App"
|
|
1091
|
+
];
|
|
1092
|
+
var canonicalizeAssignmentListScope = (value) => {
|
|
1093
|
+
if (value.toLowerCase() === "tenantglobal") {
|
|
1094
|
+
throw new InvalidArgumentError("TenantGlobal is not a valid assignment scope. Pass --scope Tenant for tenant-wide assignments.");
|
|
1095
|
+
}
|
|
1096
|
+
return makeScopeCanonicalizer(ASSIGNMENT_LIST_SCOPES)(value);
|
|
1097
|
+
};
|
|
1098
|
+
var ASSIGNMENT_CREATE_SCOPES = [
|
|
1099
|
+
"Organization",
|
|
1100
|
+
"TenantGlobal",
|
|
1101
|
+
"Tenant",
|
|
1102
|
+
"Project",
|
|
1103
|
+
"Folder",
|
|
1104
|
+
"App"
|
|
1105
|
+
];
|
|
1106
|
+
var canonicalizeAssignmentCreateScope = makeScopeCanonicalizer(ASSIGNMENT_CREATE_SCOPES);
|
|
1107
|
+
var eligibleAuthoringServices = () => KNOWN_SERVICES.filter((s) => s !== CENTRALIZED_ACCESS_SERVICE && !DELTA_SYNC_SERVICES.has(s) && !PLATFORM_SERVICES.has(s));
|
|
1108
|
+
var emitShapeError = (message, instructions) => {
|
|
1109
|
+
OutputFormatter.error({
|
|
1110
|
+
Result: RESULTS.Failure,
|
|
1111
|
+
Message: message,
|
|
1112
|
+
Instructions: instructions
|
|
1113
|
+
});
|
|
1114
|
+
processContext.exit(1);
|
|
1115
|
+
return null;
|
|
1116
|
+
};
|
|
1117
|
+
var shapeCustomRoleBody = (ctx) => {
|
|
1118
|
+
const { scope, serviceFlag, tenantIdFlag, loginTenantId } = ctx;
|
|
1119
|
+
const validatedService = (() => {
|
|
1120
|
+
const s = serviceFlag?.toLowerCase();
|
|
1121
|
+
if (s === undefined || s.length === 0)
|
|
1122
|
+
return;
|
|
1123
|
+
if (s === CENTRALIZED_ACCESS_SERVICE) {
|
|
1124
|
+
emitShapeError(`'${s}' is not a valid --service value.`, "For roles not bound to a specific service, use --scope Organization, --scope TenantGlobal, or --scope Tenant (without --service) instead.");
|
|
1125
|
+
return null;
|
|
1126
|
+
}
|
|
1127
|
+
if (isRoleAuthoringBlocked(s) !== null) {
|
|
1128
|
+
rejectIfRoleAuthoringBlocked(s, "create");
|
|
1129
|
+
return null;
|
|
1130
|
+
}
|
|
1131
|
+
if (!TENANT_SERVICES.has(s) && !ORG_SERVICES.has(s)) {
|
|
1132
|
+
emitShapeError(`Unknown service '${s}'.`, `Pass --service set to one of: ${eligibleAuthoringServices().join(", ")}.`);
|
|
1133
|
+
return null;
|
|
1134
|
+
}
|
|
1135
|
+
return s;
|
|
1136
|
+
})();
|
|
1137
|
+
if (validatedService === null)
|
|
1138
|
+
return null;
|
|
1139
|
+
let resolvedScope;
|
|
1140
|
+
if (scope !== undefined) {
|
|
1141
|
+
resolvedScope = scope;
|
|
1142
|
+
} else if (validatedService !== undefined) {
|
|
1143
|
+
resolvedScope = TENANT_SERVICES.has(validatedService) ? "Tenant" : "Organization";
|
|
1144
|
+
} else {
|
|
1145
|
+
return emitShapeError("Either --scope or --service must be provided.", "Pass --scope <Organization|TenantGlobal|Tenant|Project>, or --service <name> to infer the scope from the service registry.");
|
|
1146
|
+
}
|
|
1147
|
+
if (resolvedScope === "Project" && validatedService === undefined) {
|
|
1148
|
+
return emitShapeError("--scope Project requires --service <service>.", `Pass --service set to a service that registers Project-scoped permissions (e.g. documentunderstanding, reinfer).`);
|
|
1149
|
+
}
|
|
1150
|
+
const roleService = validatedService ?? CENTRALIZED_ACCESS_SERVICE;
|
|
1151
|
+
if (resolvedScope === "Organization") {
|
|
1152
|
+
if (tenantIdFlag !== undefined) {
|
|
1153
|
+
return emitShapeError("--tenant-id is not allowed for an Organization-scope role; this shape is not bound to a single tenant.", "Drop --tenant-id, or pass --scope Tenant / --scope Project for a tenant-bound role.");
|
|
1154
|
+
}
|
|
1155
|
+
return { roleService, roleScopeType: ORG_SCOPE_TYPE };
|
|
1156
|
+
}
|
|
1157
|
+
if (resolvedScope === "TenantGlobal") {
|
|
1158
|
+
if (tenantIdFlag !== undefined) {
|
|
1159
|
+
return emitShapeError("--tenant-id is not allowed for --scope TenantGlobal; this shape is a cross-tenant template.", "Drop --tenant-id, or pass --scope Tenant for a tenant-bound role.");
|
|
1160
|
+
}
|
|
1161
|
+
return { roleService, roleScopeType: TENANT_SCOPE_TYPE };
|
|
1162
|
+
}
|
|
1163
|
+
const tenantId = tenantIdFlag ?? loginTenantId;
|
|
1164
|
+
if (tenantId === undefined) {
|
|
1165
|
+
return emitShapeError(`--scope ${resolvedScope} requires a tenant id, but --tenant-id was not provided and the login context has no tenant.`, "Pass --tenant-id <guid>, or log in to a tenant before retrying.");
|
|
1166
|
+
}
|
|
1167
|
+
return {
|
|
1168
|
+
roleService,
|
|
1169
|
+
roleScopeType: resolvedScope === "Project" ? PROJECT_SCOPE_TYPE : TENANT_SCOPE_TYPE,
|
|
1170
|
+
tenantId
|
|
1171
|
+
};
|
|
1172
|
+
};
|
|
1173
|
+
var shapePermissionsListFilter = (ctx) => {
|
|
1174
|
+
const { scope, serviceFlag } = ctx;
|
|
1175
|
+
if (scope === undefined && serviceFlag === undefined) {
|
|
1176
|
+
return { scopeType: undefined, serviceName: undefined };
|
|
1177
|
+
}
|
|
1178
|
+
const service = serviceFlag?.toLowerCase();
|
|
1179
|
+
if (service === CENTRALIZED_ACCESS_SERVICE) {
|
|
1180
|
+
return emitShapeError(`'${service}' is not a valid --service value.`, "For non-service-specific permissions, use --scope Organization, --scope TenantGlobal, or --scope Tenant (without --service) instead.");
|
|
1181
|
+
}
|
|
1182
|
+
let resolvedScope;
|
|
1183
|
+
if (scope !== undefined) {
|
|
1184
|
+
resolvedScope = scope;
|
|
1185
|
+
} else if (service !== undefined) {
|
|
1186
|
+
if (TENANT_SERVICES.has(service))
|
|
1187
|
+
resolvedScope = "Tenant";
|
|
1188
|
+
else if (ORG_SERVICES.has(service))
|
|
1189
|
+
resolvedScope = "Organization";
|
|
1190
|
+
}
|
|
1191
|
+
const scopeType = resolvedScope === "Organization" ? ORG_SCOPE_TYPE : resolvedScope === "TenantGlobal" || resolvedScope === "Tenant" ? TENANT_SCOPE_TYPE : resolvedScope === "Project" ? PROJECT_SCOPE_TYPE : undefined;
|
|
1192
|
+
return {
|
|
1193
|
+
scopeType,
|
|
1194
|
+
serviceName: service
|
|
1195
|
+
};
|
|
1196
|
+
};
|
|
1197
|
+
var shapeRoleListFilter = (ctx) => {
|
|
1198
|
+
const { scope, serviceFlag, tenantIdFlag, loginTenantId } = ctx;
|
|
1199
|
+
if (scope === undefined && serviceFlag === undefined) {
|
|
1200
|
+
return {
|
|
1201
|
+
scopeType: undefined,
|
|
1202
|
+
serviceName: undefined,
|
|
1203
|
+
tenantId: tenantIdFlag
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
const service = serviceFlag?.toLowerCase();
|
|
1207
|
+
if (service === CENTRALIZED_ACCESS_SERVICE) {
|
|
1208
|
+
return emitShapeError(`'${service}' is not a valid --service value.`, "For roles not bound to a specific service, use --scope Organization, --scope TenantGlobal, or --scope Tenant (without --service) instead.");
|
|
1209
|
+
}
|
|
1210
|
+
let resolvedScope;
|
|
1211
|
+
if (scope !== undefined) {
|
|
1212
|
+
resolvedScope = scope;
|
|
1213
|
+
} else if (service !== undefined) {
|
|
1214
|
+
if (TENANT_SERVICES.has(service))
|
|
1215
|
+
resolvedScope = "Tenant";
|
|
1216
|
+
else if (ORG_SERVICES.has(service))
|
|
1217
|
+
resolvedScope = "Organization";
|
|
1218
|
+
}
|
|
1219
|
+
const serviceName = service ?? CENTRALIZED_ACCESS_SERVICE;
|
|
1220
|
+
if (resolvedScope === undefined) {
|
|
1221
|
+
return {
|
|
1222
|
+
scopeType: undefined,
|
|
1223
|
+
serviceName: service,
|
|
1224
|
+
tenantId: tenantIdFlag
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
if (resolvedScope === "Organization") {
|
|
1228
|
+
if (tenantIdFlag !== undefined) {
|
|
1229
|
+
return emitShapeError("--tenant-id is not allowed for an Organization-scope role filter; the server fixes tenantId for org-scope queries.", "Drop --tenant-id, or pass --scope Tenant / --scope Project / --scope Folder.");
|
|
1230
|
+
}
|
|
1231
|
+
return {
|
|
1232
|
+
scopeType: [ORG_SCOPE_TYPE],
|
|
1233
|
+
serviceName,
|
|
1234
|
+
tenantId: service === undefined ? undefined : EMPTY_TENANT_GUID
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
if (resolvedScope === "TenantGlobal") {
|
|
1238
|
+
if (tenantIdFlag !== undefined) {
|
|
1239
|
+
return emitShapeError("--tenant-id is not allowed for --scope TenantGlobal; the server fixes tenantId to the zero-GUID marker.", "Drop --tenant-id, or pass --scope Tenant for a tenant-bound filter.");
|
|
1240
|
+
}
|
|
1241
|
+
return {
|
|
1242
|
+
scopeType: [TENANT_SCOPE_TYPE],
|
|
1243
|
+
serviceName,
|
|
1244
|
+
tenantId: EMPTY_TENANT_GUID
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
const tenantId = tenantIdFlag ?? loginTenantId;
|
|
1248
|
+
if (tenantId === undefined) {
|
|
1249
|
+
return emitShapeError(`--scope ${resolvedScope} requires a tenant id, but --tenant-id was not provided and the login context has no tenant.`, "Pass --tenant-id <guid>, or log in to a tenant before retrying.");
|
|
1250
|
+
}
|
|
1251
|
+
const scopeTypeValue = resolvedScope === "Project" ? PROJECT_SCOPE_TYPE : resolvedScope === "Folder" ? FOLDER_SCOPE_TYPE : TENANT_SCOPE_TYPE;
|
|
1252
|
+
return {
|
|
1253
|
+
scopeType: [scopeTypeValue],
|
|
1254
|
+
serviceName,
|
|
1255
|
+
tenantId
|
|
1256
|
+
};
|
|
1257
|
+
};
|
|
1258
|
+
var shapeAssignmentListFilter = (ctx) => {
|
|
1259
|
+
const {
|
|
1260
|
+
scope,
|
|
1261
|
+
serviceFlag,
|
|
1262
|
+
scopeIdFlag,
|
|
1263
|
+
scopePathFlag,
|
|
1264
|
+
tenantIdFlag,
|
|
1265
|
+
loginTenantId
|
|
1266
|
+
} = ctx;
|
|
1267
|
+
const service = serviceFlag?.toLowerCase();
|
|
1268
|
+
if (service === CENTRALIZED_ACCESS_SERVICE) {
|
|
1269
|
+
return emitShapeError(`'${service}' is not a valid --service value.`, "For assignments not bound to a specific service, use --scope Organization or --scope Tenant (without --service) instead.");
|
|
1270
|
+
}
|
|
1271
|
+
if (scopePathFlag !== undefined) {
|
|
1272
|
+
return {
|
|
1273
|
+
scope: scopePathFlag,
|
|
1274
|
+
serviceName: service,
|
|
1275
|
+
roleScopeType: undefined
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
const isSubScope = scope === "Project" || scope === "Folder" || scope === "App";
|
|
1279
|
+
if (isSubScope) {
|
|
1280
|
+
if (service === undefined) {
|
|
1281
|
+
return emitShapeError(`--scope ${scope} requires --service <service>.`, "Sub-scope assignment queries are always service-bound; pass --service <name>, or use --scope-path <path> for verbatim filtering.");
|
|
1282
|
+
}
|
|
1283
|
+
if (scopeIdFlag === undefined) {
|
|
1284
|
+
return emitShapeError(`--scope ${scope} requires --scope-id <id>.`, `Pass --scope-id with the ${scope === "Project" ? "project id" : scope === "Folder" ? "folder name/id" : "app id"} to compose the scope path, or use --scope-path <path> for a verbatim match.`);
|
|
1285
|
+
}
|
|
1286
|
+
const tenantId2 = tenantIdFlag ?? loginTenantId;
|
|
1287
|
+
if (tenantId2 === undefined) {
|
|
1288
|
+
return emitShapeError(`--scope ${scope} requires a tenant id, but --tenant-id was not provided and the login context has no tenant.`, "Pass --tenant-id <guid>, or log in to a tenant before retrying.");
|
|
1289
|
+
}
|
|
1290
|
+
const segment = scope.toLowerCase();
|
|
1291
|
+
return {
|
|
1292
|
+
scope: `/tenant/${tenantId2}/${service}/${segment}/${scopeIdFlag}`,
|
|
1293
|
+
serviceName: service,
|
|
1294
|
+
roleScopeType: undefined
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
if (service !== undefined) {
|
|
1298
|
+
const explicitOrg = scope === "Organization";
|
|
1299
|
+
const inferredOrg = scope === undefined && ORG_SERVICES.has(service);
|
|
1300
|
+
if (explicitOrg || inferredOrg) {
|
|
1301
|
+
if (tenantIdFlag !== undefined) {
|
|
1302
|
+
return emitShapeError("--tenant-id is not allowed for an Organization-scope assignment query (scope=/ has no tenant binding).", "Drop --tenant-id, or pass --scope Tenant / Project / Folder / App for a tenant-bound query.");
|
|
1303
|
+
}
|
|
1304
|
+
return {
|
|
1305
|
+
scope: "/",
|
|
1306
|
+
serviceName: service,
|
|
1307
|
+
roleScopeType: "organization"
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
const tenantId2 = tenantIdFlag ?? loginTenantId;
|
|
1311
|
+
if (tenantId2 === undefined) {
|
|
1312
|
+
return emitShapeError("Tenant-scope assignment query requires a tenant id, but --tenant-id was not provided and the login context has no tenant.", "Pass --tenant-id <guid>, or log in to a tenant before retrying.");
|
|
1313
|
+
}
|
|
1314
|
+
return {
|
|
1315
|
+
scope: `/tenant/${tenantId2}/${service}`,
|
|
1316
|
+
serviceName: service,
|
|
1317
|
+
roleScopeType: undefined
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
if (scope === "Organization") {
|
|
1321
|
+
if (tenantIdFlag !== undefined) {
|
|
1322
|
+
return emitShapeError("--tenant-id is not allowed for --scope Organization; the assignment query is scoped to / (whole org).", "Drop --tenant-id, or pass --scope Tenant for a tenant-bound query.");
|
|
1323
|
+
}
|
|
1324
|
+
return {
|
|
1325
|
+
scope: "/",
|
|
1326
|
+
serviceName: CENTRALIZED_ACCESS_SERVICE,
|
|
1327
|
+
roleScopeType: "organization"
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
if (scope === "Tenant") {
|
|
1331
|
+
const tenantId2 = tenantIdFlag ?? loginTenantId;
|
|
1332
|
+
if (tenantId2 === undefined) {
|
|
1333
|
+
return emitShapeError("--scope Tenant requires a tenant id, but --tenant-id was not provided and the login context has no tenant.", "Pass --tenant-id <guid>, or log in to a tenant before retrying.");
|
|
1334
|
+
}
|
|
1335
|
+
return {
|
|
1336
|
+
scope: `/tenant/${tenantId2}`,
|
|
1337
|
+
serviceName: CENTRALIZED_ACCESS_SERVICE,
|
|
1338
|
+
roleScopeType: undefined
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
const tenantId = tenantIdFlag ?? loginTenantId;
|
|
1342
|
+
if (tenantId === undefined) {
|
|
1343
|
+
return emitShapeError("assignments list needs --scope, --service, --scope-path, or --tenant-id; the login context has no tenant to default to.", "Pass --tenant-id <guid>, --scope Organization|Tenant, --service <name>, or --scope-path <path>. See `assignments list --help`.");
|
|
1344
|
+
}
|
|
1345
|
+
return {
|
|
1346
|
+
scope: `/tenant/${tenantId}`,
|
|
1347
|
+
serviceName: CENTRALIZED_ACCESS_SERVICE,
|
|
1348
|
+
roleScopeType: undefined
|
|
1349
|
+
};
|
|
1350
|
+
};
|
|
1351
|
+
var shapeAssignmentCreateScope = (ctx) => {
|
|
1352
|
+
const {
|
|
1353
|
+
scope,
|
|
1354
|
+
serviceFlag,
|
|
1355
|
+
scopeIdFlag,
|
|
1356
|
+
scopePathFlag,
|
|
1357
|
+
tenantIdFlag,
|
|
1358
|
+
loginTenantId
|
|
1359
|
+
} = ctx;
|
|
1360
|
+
const service = serviceFlag?.toLowerCase();
|
|
1361
|
+
if (service === CENTRALIZED_ACCESS_SERVICE) {
|
|
1362
|
+
return emitShapeError(`'${service}' is not a valid --service value.`, "For assignments not bound to a specific service, use --scope Organization, --scope Tenant, or --scope TenantGlobal (without --service) instead.");
|
|
1363
|
+
}
|
|
1364
|
+
if (scopePathFlag !== undefined) {
|
|
1365
|
+
return { scope: scopePathFlag, tenantId: undefined };
|
|
1366
|
+
}
|
|
1367
|
+
if (service !== undefined) {
|
|
1368
|
+
const reason = isRoleAuthoringBlocked(service);
|
|
1369
|
+
if (reason !== null) {
|
|
1370
|
+
const message = reason === "delta-sync" ? `Role assignments for '${service}' are owned by the '${service}' service itself and cannot be created through 'uip admin authorization roles assignments'.` : `'${service}' is a platform-level service; its role assignments are platform-owned and cannot be created by tenants.`;
|
|
1371
|
+
return emitShapeError(message, ROLE_AUTHORING_HINTS[service] ?? "This service does not allow assignment authoring through the Authorization CLI.");
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
const isSubScope = scope === "Project" || scope === "Folder" || scope === "App";
|
|
1375
|
+
if (isSubScope) {
|
|
1376
|
+
if (service === undefined) {
|
|
1377
|
+
return emitShapeError(`--scope ${scope} requires --service <service>.`, "Sub-scope assignments are always service-bound; pass --service <name>, or use --scope-path <path> for verbatim assignment.");
|
|
1378
|
+
}
|
|
1379
|
+
if (scopeIdFlag === undefined) {
|
|
1380
|
+
return emitShapeError(`--scope ${scope} requires --scope-id <id>.`, `Pass --scope-id with the ${scope === "Project" ? "project id" : scope === "Folder" ? "folder name/id" : "app id"} to compose the scope path, or use --scope-path <path> for a verbatim assignment.`);
|
|
1381
|
+
}
|
|
1382
|
+
const tenantId2 = tenantIdFlag ?? loginTenantId;
|
|
1383
|
+
if (tenantId2 === undefined) {
|
|
1384
|
+
return emitShapeError(`--scope ${scope} requires a tenant id, but --tenant-id was not provided and the login context has no tenant.`, "Pass --tenant-id <guid>, or log in to a tenant before retrying.");
|
|
1385
|
+
}
|
|
1386
|
+
const segment = scope.toLowerCase();
|
|
1387
|
+
return {
|
|
1388
|
+
scope: `/tenant/${tenantId2}/${service}/${segment}/${scopeIdFlag}`,
|
|
1389
|
+
tenantId: tenantId2
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
if (service !== undefined) {
|
|
1393
|
+
const explicitOrg = scope === "Organization";
|
|
1394
|
+
const inferredOrg = scope === undefined && ORG_SERVICES.has(service);
|
|
1395
|
+
if (explicitOrg || inferredOrg) {
|
|
1396
|
+
if (tenantIdFlag !== undefined) {
|
|
1397
|
+
return emitShapeError("--tenant-id is not allowed for an Organization-scope assignment (scope=/ has no tenant binding).", "Drop --tenant-id, or pass --scope Tenant / Project / Folder / App for a tenant-bound assignment.");
|
|
1398
|
+
}
|
|
1399
|
+
return { scope: "/", tenantId: undefined };
|
|
1400
|
+
}
|
|
1401
|
+
const tenantId2 = tenantIdFlag ?? loginTenantId;
|
|
1402
|
+
if (tenantId2 === undefined) {
|
|
1403
|
+
return emitShapeError("Tenant-scope assignment requires a tenant id, but --tenant-id was not provided and the login context has no tenant.", "Pass --tenant-id <guid>, or log in to a tenant before retrying.");
|
|
1404
|
+
}
|
|
1405
|
+
return {
|
|
1406
|
+
scope: `/tenant/${tenantId2}/${service}`,
|
|
1407
|
+
tenantId: tenantId2
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
if (scope === "Organization") {
|
|
1411
|
+
if (tenantIdFlag !== undefined) {
|
|
1412
|
+
return emitShapeError("--tenant-id is not allowed for --scope Organization; the assignment is bound to / (whole org).", "Drop --tenant-id, or pass --scope Tenant / TenantGlobal for a tenant-bound assignment.");
|
|
1413
|
+
}
|
|
1414
|
+
return { scope: "/", tenantId: undefined };
|
|
1415
|
+
}
|
|
1416
|
+
if (scope === "Tenant" || scope === "TenantGlobal") {
|
|
1417
|
+
const tenantId2 = tenantIdFlag ?? loginTenantId;
|
|
1418
|
+
if (tenantId2 === undefined) {
|
|
1419
|
+
return emitShapeError(`--scope ${scope} requires a tenant id, but --tenant-id was not provided and the login context has no tenant.`, "Pass --tenant-id <guid>, or log in to a tenant before retrying.");
|
|
1420
|
+
}
|
|
1421
|
+
return { scope: `/tenant/${tenantId2}`, tenantId: tenantId2 };
|
|
1422
|
+
}
|
|
1423
|
+
const tenantId = tenantIdFlag ?? loginTenantId;
|
|
1424
|
+
if (tenantId === undefined) {
|
|
1425
|
+
return emitShapeError("assignments create (inline) requires --tenant-id, --scope, --service, or --scope-path; the login context has no tenant to default to.", "Pass --tenant-id <guid>, --scope <Organization|TenantGlobal|Tenant|Project|Folder|App>, --service <name>, or --scope-path <path>. See `assignments create --help`.");
|
|
1426
|
+
}
|
|
1427
|
+
return { scope: `/tenant/${tenantId}`, tenantId };
|
|
1428
|
+
};
|
|
1429
|
+
async function loadActionsFile(file) {
|
|
1430
|
+
const [parseErr, parsed] = await loadJsonFile(file, "string[]");
|
|
1431
|
+
if (parseErr)
|
|
1432
|
+
return [parseErr, null];
|
|
1433
|
+
if (!Array.isArray(parsed)) {
|
|
1434
|
+
return [
|
|
1435
|
+
{
|
|
1436
|
+
message: `Expected --file to contain a JSON array of action strings, got ${parsed === null ? "null" : typeof parsed}.`,
|
|
1437
|
+
instructions: 'The file must be a JSON array of action names, e.g. ["STUDIO.X.Y", "STUDIO.A.B"].'
|
|
1438
|
+
},
|
|
1439
|
+
null
|
|
1440
|
+
];
|
|
1441
|
+
}
|
|
1442
|
+
const nonStrings = parsed.filter((v) => typeof v !== "string");
|
|
1443
|
+
if (nonStrings.length > 0) {
|
|
1444
|
+
return [
|
|
1445
|
+
{
|
|
1446
|
+
message: `--file contains non-string elements; every action must be a string.`,
|
|
1447
|
+
instructions: 'The file must be a JSON array of action names, e.g. ["STUDIO.X.Y", "STUDIO.A.B"].'
|
|
1448
|
+
},
|
|
1449
|
+
null
|
|
1450
|
+
];
|
|
1451
|
+
}
|
|
1452
|
+
return [null, parsed];
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
// ../authz-commands/src/commands/check-access.ts
|
|
1456
|
+
var SCOPE_CHOICES = [TENANT_SCOPE_TYPE, FOLDER_SCOPE_TYPE];
|
|
1457
|
+
var CHECK_ACCESS_EXAMPLES = [
|
|
1458
|
+
{
|
|
1459
|
+
Description: "Effective permissions for a user (by UUID) at the login tenant (default scope)",
|
|
1460
|
+
Command: "uip admin authorization check-access <user-guid>",
|
|
1461
|
+
Output: {
|
|
1462
|
+
Code: "AuthzCheckAccess",
|
|
1463
|
+
Data: {
|
|
1464
|
+
roleAssignments: { totalCount: 0, results: [] },
|
|
1465
|
+
grantedServicesMetadata: [],
|
|
1466
|
+
grantedRolesMetadata: []
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
},
|
|
1470
|
+
{
|
|
1471
|
+
Description: "Resolve the user by email substring — the identity API does the lookup",
|
|
1472
|
+
Command: "uip admin authorization check-access alice@example.com",
|
|
1473
|
+
Output: {
|
|
1474
|
+
Code: "AuthzCheckAccess",
|
|
1475
|
+
Data: {
|
|
1476
|
+
roleAssignments: { totalCount: 0, results: [] },
|
|
1477
|
+
grantedServicesMetadata: [],
|
|
1478
|
+
grantedRolesMetadata: []
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
},
|
|
1482
|
+
{
|
|
1483
|
+
Description: "Target a non-login tenant explicitly",
|
|
1484
|
+
Command: "uip admin authorization check-access <user-guid> --tenant-id <tenant-guid>",
|
|
1485
|
+
Output: {
|
|
1486
|
+
Code: "AuthzCheckAccess",
|
|
1487
|
+
Data: {
|
|
1488
|
+
roleAssignments: { totalCount: 0, results: [] },
|
|
1489
|
+
grantedServicesMetadata: [],
|
|
1490
|
+
grantedRolesMetadata: []
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
},
|
|
1494
|
+
{
|
|
1495
|
+
Description: "Restrict the result to a single service",
|
|
1496
|
+
Command: "uip admin authorization check-access <user-guid> --service orchestrator",
|
|
1497
|
+
Output: {
|
|
1498
|
+
Code: "AuthzCheckAccess",
|
|
1499
|
+
Data: {
|
|
1500
|
+
roleAssignments: { totalCount: 0, results: [] },
|
|
1501
|
+
grantedServicesMetadata: [],
|
|
1502
|
+
grantedRolesMetadata: []
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
Description: "Folder scope — folder id required, parent tenant defaults to login tenant",
|
|
1508
|
+
Command: "uip admin authorization check-access <user-guid> --scope Folder --folder-id <folder-guid>",
|
|
1509
|
+
Output: {
|
|
1510
|
+
Code: "AuthzCheckAccess",
|
|
1511
|
+
Data: {
|
|
1512
|
+
roleAssignments: { totalCount: 0, results: [] },
|
|
1513
|
+
grantedServicesMetadata: [],
|
|
1514
|
+
grantedRolesMetadata: []
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
},
|
|
1518
|
+
{
|
|
1519
|
+
Description: "Pass a full request body (advanced — e.g. RoleNameStartsWith filter)",
|
|
1520
|
+
Command: "uip admin authorization check-access --file ./check-access.json",
|
|
1521
|
+
Output: {
|
|
1522
|
+
Code: "AuthzCheckAccess",
|
|
1523
|
+
Data: {
|
|
1524
|
+
roleAssignments: { totalCount: 0, results: [] },
|
|
1525
|
+
grantedServicesMetadata: [],
|
|
1526
|
+
grantedRolesMetadata: []
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
];
|
|
1531
|
+
async function postPdpJson(path, body, options) {
|
|
1532
|
+
const config = await createAuthzConfig("pdp", {
|
|
1533
|
+
loginValidity: options.loginValidity
|
|
1534
|
+
});
|
|
1535
|
+
if (!config.accessToken) {
|
|
1536
|
+
throw new Error("No access token resolved from login context. Re-run 'uip login' and retry.");
|
|
1537
|
+
}
|
|
1538
|
+
const token = await config.accessToken("bearerAuth", []);
|
|
1539
|
+
if (!token) {
|
|
1540
|
+
throw new Error("Empty access token from login context. Re-run 'uip login' and retry.");
|
|
1541
|
+
}
|
|
1542
|
+
const response = await fetch(`${config.basePath}${path}`, {
|
|
1543
|
+
method: "POST",
|
|
1544
|
+
headers: {
|
|
1545
|
+
"Content-Type": "application/json",
|
|
1546
|
+
Authorization: `Bearer ${token}`
|
|
1547
|
+
},
|
|
1548
|
+
body: JSON.stringify(body)
|
|
1549
|
+
});
|
|
1550
|
+
if (!response.ok) {
|
|
1551
|
+
const errorText = await response.text();
|
|
1552
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
1553
|
+
}
|
|
1554
|
+
if (response.status === 204) {
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
return await response.json();
|
|
1558
|
+
}
|
|
1559
|
+
var GUID_RE2 = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
1560
|
+
var formatCandidate = (u) => {
|
|
1561
|
+
const label = u.email ?? u.userName ?? u.displayName ?? "(no email)";
|
|
1562
|
+
return `${label} (${u.id ?? "no-id"})`;
|
|
1563
|
+
};
|
|
1564
|
+
async function resolveIdentityToId(identity, options) {
|
|
1565
|
+
if (GUID_RE2.test(identity))
|
|
1566
|
+
return identity;
|
|
1567
|
+
const [clientErr, client] = await catchError(createApiClient(UserApi, {
|
|
1568
|
+
loginValidity: options.loginValidity
|
|
1569
|
+
}));
|
|
1570
|
+
if (clientErr) {
|
|
1571
|
+
await emitFailure(clientErr, "Failed to initialize the identity API client for user lookup. Re-run 'uip login' and retry, or pass a user UUID directly.");
|
|
1572
|
+
return null;
|
|
1573
|
+
}
|
|
1574
|
+
const [searchErr, result] = await catchError(client.api.userGetUsers({
|
|
1575
|
+
partitionGlobalId: client.organizationId,
|
|
1576
|
+
searchTerm: identity,
|
|
1577
|
+
top: 25,
|
|
1578
|
+
skip: 0
|
|
1579
|
+
}));
|
|
1580
|
+
if (searchErr) {
|
|
1581
|
+
await emitFailure(searchErr, `User lookup for '${identity}' failed. Pass the user UUID directly to skip the search.`);
|
|
1582
|
+
return null;
|
|
1583
|
+
}
|
|
1584
|
+
const users = result?.results ?? [];
|
|
1585
|
+
if (users.length === 0) {
|
|
1586
|
+
OutputFormatter.error({
|
|
1587
|
+
Result: RESULTS.Failure,
|
|
1588
|
+
Message: `No user matched '${identity}'.`,
|
|
1589
|
+
Instructions: "Pass a user UUID, or a substring of the user's name/email. Use 'uip admin users list --search <fragment>' to discover ids."
|
|
1590
|
+
});
|
|
1591
|
+
processContext.exit(1);
|
|
1592
|
+
return null;
|
|
1593
|
+
}
|
|
1594
|
+
if (users.length === 1) {
|
|
1595
|
+
const id = users[0].id;
|
|
1596
|
+
if (id !== undefined && id !== "")
|
|
1597
|
+
return id;
|
|
1598
|
+
} else {
|
|
1599
|
+
const lower = identity.toLowerCase();
|
|
1600
|
+
const exact = users.find((u) => u.email?.toLowerCase() === lower || u.userName?.toLowerCase() === lower);
|
|
1601
|
+
if (exact?.id !== undefined && exact.id !== "")
|
|
1602
|
+
return exact.id;
|
|
1603
|
+
const preview = users.slice(0, 5).map(formatCandidate).join("; ");
|
|
1604
|
+
const more = users.length > 5 ? `; ... (+${users.length - 5} more)` : "";
|
|
1605
|
+
OutputFormatter.error({
|
|
1606
|
+
Result: RESULTS.Failure,
|
|
1607
|
+
Message: `Multiple users matched '${identity}'. Pass a UUID or a more specific value.`,
|
|
1608
|
+
Instructions: `Candidates: ${preview}${more}.`
|
|
1609
|
+
});
|
|
1610
|
+
processContext.exit(1);
|
|
1611
|
+
return null;
|
|
1612
|
+
}
|
|
1613
|
+
OutputFormatter.error({
|
|
1614
|
+
Result: RESULTS.Failure,
|
|
1615
|
+
Message: `User search matched '${identity}' but the result has no id field.`,
|
|
1616
|
+
Instructions: "Pass the user UUID directly. Verify the identity service is responding correctly."
|
|
1617
|
+
});
|
|
1618
|
+
processContext.exit(1);
|
|
1619
|
+
return null;
|
|
1620
|
+
}
|
|
1621
|
+
async function resolveTenantId(options) {
|
|
1622
|
+
if (options.tenantId !== undefined)
|
|
1623
|
+
return options.tenantId;
|
|
1624
|
+
const [loginErr, status] = await catchError(getLoginStatusAsync({
|
|
1625
|
+
ensureTokenValidityMinutes: options.loginValidity
|
|
1626
|
+
}));
|
|
1627
|
+
if (loginErr) {
|
|
1628
|
+
await emitFailure(loginErr, "Re-run 'uip login' and retry.");
|
|
1629
|
+
return null;
|
|
1630
|
+
}
|
|
1631
|
+
if (status?.tenantId !== undefined && status.tenantId !== "") {
|
|
1632
|
+
return status.tenantId;
|
|
1633
|
+
}
|
|
1634
|
+
OutputFormatter.error({
|
|
1635
|
+
Result: RESULTS.Failure,
|
|
1636
|
+
Message: "No tenant id resolved: --tenant-id was not provided and the login session is not bound to a tenant.",
|
|
1637
|
+
Instructions: "Pass --tenant-id <guid>, or re-run 'uip login' and select a tenant."
|
|
1638
|
+
});
|
|
1639
|
+
processContext.exit(1);
|
|
1640
|
+
return null;
|
|
1641
|
+
}
|
|
1642
|
+
var registerCheckAccessCommand = (authz) => {
|
|
1643
|
+
withLoginValidity(authz.command("check-access").description([
|
|
1644
|
+
"Compute the effective permissions a security principal has within a",
|
|
1645
|
+
"tenant or folder scope, via the Policy Decision Point (PDP).",
|
|
1646
|
+
"",
|
|
1647
|
+
"The positional `<identity>` is either a user UUID (used as-is) or a",
|
|
1648
|
+
"substring against user name/email; the latter is resolved via the",
|
|
1649
|
+
"identity user-search API. Pass a UUID when the substring is ambiguous.",
|
|
1650
|
+
"",
|
|
1651
|
+
"Scope (default Tenant):",
|
|
1652
|
+
" --scope Tenant — both Id and ParentId on the PDP request are the",
|
|
1653
|
+
" tenant id. Use --tenant-id <guid> to target a",
|
|
1654
|
+
" non-login tenant; otherwise the login tenant is",
|
|
1655
|
+
" used.",
|
|
1656
|
+
" --scope Folder — requires --folder-id <guid> (the Id). ParentId is",
|
|
1657
|
+
" the owning tenant; --tenant-id overrides, else",
|
|
1658
|
+
" the login tenant is used.",
|
|
1659
|
+
"",
|
|
1660
|
+
"Use --service to restrict the result to a single service",
|
|
1661
|
+
"(sets ServiceName on the request body). For advanced filters",
|
|
1662
|
+
"(RoleNameStartsWith) pass --file <path> with the full request body:",
|
|
1663
|
+
" {",
|
|
1664
|
+
' "SecurityPrincipalId": "<guid>",',
|
|
1665
|
+
' "RoleNameStartsWith": "<filter>",',
|
|
1666
|
+
' "ServiceName": "<filter>",',
|
|
1667
|
+
' "ScopeIdentifier": {',
|
|
1668
|
+
' "ScopeType": "Tenant" | "Folder",',
|
|
1669
|
+
' "Value": { "Id": "<guid>", "ParentId": "<guid>" }',
|
|
1670
|
+
" }",
|
|
1671
|
+
" }"
|
|
1672
|
+
].join(`
|
|
1673
|
+
`)).argument("[identity]", "User UUID, name, or email. Required unless --file is supplied.").option("--file <path>", "Path to a JSON file containing the full check-access request body. Mutually exclusive with the positional and scope flags.").addOption(new Option("--scope <type>", "Scope at which to evaluate access. Defaults to Tenant when omitted.").choices(SCOPE_CHOICES)).option("--tenant-id <guid>", "Tenant UUID. Defaults to the login tenant. For Tenant scope it is used as both Id and ParentId; for Folder scope it is the ParentId.").option("--folder-id <guid>", "Folder UUID. Required when --scope Folder. Used as the scope Id.").option("--service <service>", `Restrict the result to a specific service (sets ServiceName on the request body). ${SERVICE_OPTION_HINT}`).examples(CHECK_ACCESS_EXAMPLES)).trackedAction(processContext, async (identityArg, options) => {
|
|
1674
|
+
const inlineProvided = identityArg !== undefined || options.scope !== undefined || options.tenantId !== undefined || options.folderId !== undefined || options.service !== undefined;
|
|
1675
|
+
if (options.file !== undefined && inlineProvided) {
|
|
1676
|
+
OutputFormatter.error({
|
|
1677
|
+
Result: RESULTS.Failure,
|
|
1678
|
+
Message: "--file is mutually exclusive with the <identity> positional and inline flags (--scope / --tenant-id / --folder-id / --service).",
|
|
1679
|
+
Instructions: "Pass either --file for the full request body, or the positional + inline flags for the typical query."
|
|
1680
|
+
});
|
|
1681
|
+
processContext.exit(1);
|
|
1682
|
+
return;
|
|
1683
|
+
}
|
|
1684
|
+
if (options.file === undefined && !inlineProvided) {
|
|
1685
|
+
OutputFormatter.error({
|
|
1686
|
+
Result: RESULTS.Failure,
|
|
1687
|
+
Message: "Provide either <identity> or --file.",
|
|
1688
|
+
Instructions: "Inline (minimum): check-access <user-uuid-or-name>. File: --file <path>."
|
|
1689
|
+
});
|
|
1690
|
+
processContext.exit(1);
|
|
1691
|
+
return;
|
|
1692
|
+
}
|
|
1693
|
+
let body;
|
|
1694
|
+
if (options.file !== undefined) {
|
|
1695
|
+
const [loadErr, loaded] = await loadJsonFile(options.file, "GetEffectiveAccessRoleAssignmentsRequestDto");
|
|
1696
|
+
if (loadErr) {
|
|
1697
|
+
emitLoadError(loadErr);
|
|
1698
|
+
return;
|
|
1699
|
+
}
|
|
1700
|
+
body = loaded;
|
|
1701
|
+
} else {
|
|
1702
|
+
if (identityArg === undefined) {
|
|
1703
|
+
OutputFormatter.error({
|
|
1704
|
+
Result: RESULTS.Failure,
|
|
1705
|
+
Message: "Inline mode requires <identity>.",
|
|
1706
|
+
Instructions: "Pass a user UUID or a substring of the user's name/email as the positional argument."
|
|
1707
|
+
});
|
|
1708
|
+
processContext.exit(1);
|
|
1709
|
+
return;
|
|
1710
|
+
}
|
|
1711
|
+
const scope = options.scope ?? TENANT_SCOPE_TYPE;
|
|
1712
|
+
if (scope === FOLDER_SCOPE_TYPE && options.folderId === undefined) {
|
|
1713
|
+
OutputFormatter.error({
|
|
1714
|
+
Result: RESULTS.Failure,
|
|
1715
|
+
Message: "--scope Folder requires --folder-id.",
|
|
1716
|
+
Instructions: "Pass --folder-id <folder-guid>. Use --tenant-id <tenant-guid> to target a non-login tenant."
|
|
1717
|
+
});
|
|
1718
|
+
processContext.exit(1);
|
|
1719
|
+
return;
|
|
1720
|
+
}
|
|
1721
|
+
const securityPrincipalId = await resolveIdentityToId(identityArg, options);
|
|
1722
|
+
if (securityPrincipalId === null)
|
|
1723
|
+
return;
|
|
1724
|
+
const tenantId = await resolveTenantId(options);
|
|
1725
|
+
if (tenantId === null)
|
|
1726
|
+
return;
|
|
1727
|
+
const value = scope === FOLDER_SCOPE_TYPE ? {
|
|
1728
|
+
Id: options.folderId,
|
|
1729
|
+
ParentId: tenantId
|
|
1730
|
+
} : { Id: tenantId, ParentId: tenantId };
|
|
1731
|
+
const inlineBody = {
|
|
1732
|
+
SecurityPrincipalId: securityPrincipalId,
|
|
1733
|
+
ScopeIdentifier: {
|
|
1734
|
+
ScopeType: scope,
|
|
1735
|
+
Value: value
|
|
1736
|
+
}
|
|
1737
|
+
};
|
|
1738
|
+
if (options.service !== undefined) {
|
|
1739
|
+
inlineBody.ServiceName = options.service;
|
|
1740
|
+
}
|
|
1741
|
+
body = inlineBody;
|
|
1742
|
+
}
|
|
1743
|
+
const [error, result] = await catchError(postPdpJson("/api/geteffectiveaccess", body, options));
|
|
1744
|
+
if (error) {
|
|
1745
|
+
await emitFailure(error, "Verify the request shape and that ScopeType is 'Tenant' or 'Folder'.");
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1748
|
+
OutputFormatter.success({
|
|
1749
|
+
Result: RESULTS.Success,
|
|
1750
|
+
Code: "AuthzCheckAccess",
|
|
1751
|
+
Data: result ?? {}
|
|
1752
|
+
});
|
|
1753
|
+
});
|
|
1754
|
+
};
|
|
1755
|
+
|
|
1756
|
+
// ../authz-commands/src/commands/permissions.ts
|
|
1757
|
+
var LIST_EXAMPLES = [
|
|
1758
|
+
{
|
|
1759
|
+
Description: "List every permission definition known to the platform",
|
|
1760
|
+
Command: "uip admin authorization permissions list",
|
|
1761
|
+
Output: {
|
|
1762
|
+
Code: "AuthzPermissionsList",
|
|
1763
|
+
Data: [
|
|
1764
|
+
{
|
|
1765
|
+
id: "<action-guid>",
|
|
1766
|
+
name: "OR.FOLDERS.READ",
|
|
1767
|
+
namespace: "ORCHESTRATOR",
|
|
1768
|
+
serviceDisplayName: "Orchestrator",
|
|
1769
|
+
resourceType: "Folders",
|
|
1770
|
+
resourceAction: "Read",
|
|
1771
|
+
resourceGroup: "Folder",
|
|
1772
|
+
description: "View folders",
|
|
1773
|
+
scopeType: "Folder"
|
|
1774
|
+
}
|
|
1775
|
+
]
|
|
1776
|
+
}
|
|
1777
|
+
},
|
|
1778
|
+
{
|
|
1779
|
+
Description: "Permissions usable in an Organization-shape role (e.g. for `roles create --scope Organization`)",
|
|
1780
|
+
Command: "uip admin authorization permissions list --scope Organization",
|
|
1781
|
+
Output: { Code: "AuthzPermissionsList", Data: [] }
|
|
1782
|
+
},
|
|
1783
|
+
{
|
|
1784
|
+
Description: "Permissions for an org-service role — scope is inferred (apps → Organization)",
|
|
1785
|
+
Command: "uip admin authorization permissions list --service apps",
|
|
1786
|
+
Output: { Code: "AuthzPermissionsList", Data: [] }
|
|
1787
|
+
},
|
|
1788
|
+
{
|
|
1789
|
+
Description: "Permissions for a tenant-service role — scope is inferred (documentunderstanding → Tenant)",
|
|
1790
|
+
Command: "uip admin authorization permissions list --service documentunderstanding",
|
|
1791
|
+
Output: { Code: "AuthzPermissionsList", Data: [] }
|
|
1792
|
+
},
|
|
1793
|
+
{
|
|
1794
|
+
Description: "Project-scope override for a service that registers Project perms (DU, Reinfer)",
|
|
1795
|
+
Command: "uip admin authorization permissions list --scope Project --service documentunderstanding",
|
|
1796
|
+
Output: { Code: "AuthzPermissionsList", Data: [] }
|
|
1797
|
+
}
|
|
1798
|
+
];
|
|
1799
|
+
var registerPermissionsCommands = (authz) => {
|
|
1800
|
+
const perms = authz.command("permissions").description("Read-only catalog of permission definitions across services.");
|
|
1801
|
+
withLoginValidity(perms.command("list").description([
|
|
1802
|
+
"List permission definitions, optionally filtered to those usable in a",
|
|
1803
|
+
"given custom-role shape.",
|
|
1804
|
+
"",
|
|
1805
|
+
"`--scope` mirrors `roles create --scope`:",
|
|
1806
|
+
"",
|
|
1807
|
+
" Organization All Organization-scoped permissions.",
|
|
1808
|
+
" TenantGlobal All Tenant-scoped permissions.",
|
|
1809
|
+
" Tenant All Tenant-scoped permissions.",
|
|
1810
|
+
" Project All Project-scoped permissions.",
|
|
1811
|
+
"",
|
|
1812
|
+
"`--service` is optional and combines with any scope. When --scope is",
|
|
1813
|
+
"omitted, --service alone infers the scope from the service registry",
|
|
1814
|
+
"(tenant-service → Tenant; org-service → Organization), so the result",
|
|
1815
|
+
"matches what `roles create --service <svc>` would accept. Pass an",
|
|
1816
|
+
"explicit --scope to override — e.g. `--scope Project --service",
|
|
1817
|
+
"documentunderstanding` lists DU's Project-scope permissions."
|
|
1818
|
+
].join(`
|
|
1819
|
+
`)).option("--service <service>", "Owning service (e.g. apps, documentunderstanding). Combines with --scope, or used alone sets the scope from the service registry.").addOption(new Option("--scope <type>", "Filter by role shape: Organization, TenantGlobal, Tenant, or Project (case-insensitive). Optional when --service is provided (the registry infers the scope).").argParser(canonicalizeRoleAuthoringScope)).examples(LIST_EXAMPLES)).trackedAction(processContext, async (options) => {
|
|
1820
|
+
const [err, client] = await catchError(createPapClient(ActionApi, {
|
|
1821
|
+
loginValidity: options.loginValidity
|
|
1822
|
+
}));
|
|
1823
|
+
if (err) {
|
|
1824
|
+
await emitFailure(err, LOGIN_INSTRUCTIONS);
|
|
1825
|
+
return;
|
|
1826
|
+
}
|
|
1827
|
+
const filter = shapePermissionsListFilter({
|
|
1828
|
+
scope: options.scope,
|
|
1829
|
+
serviceFlag: options.service
|
|
1830
|
+
});
|
|
1831
|
+
if (filter === null)
|
|
1832
|
+
return;
|
|
1833
|
+
const [error, result] = await catchError(client.api.apiActionsGet({
|
|
1834
|
+
serviceName: filter.serviceName,
|
|
1835
|
+
scopeType: filter.scopeType
|
|
1836
|
+
}));
|
|
1837
|
+
if (error) {
|
|
1838
|
+
await emitFailure(error, "Verify --service and --scope values; the catalog should always be readable when logged in.");
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1841
|
+
OutputFormatter.success({
|
|
1842
|
+
Result: RESULTS.Success,
|
|
1843
|
+
Code: "AuthzPermissionsList",
|
|
1844
|
+
Data: result ?? []
|
|
1845
|
+
});
|
|
1846
|
+
});
|
|
1847
|
+
};
|
|
1848
|
+
|
|
1849
|
+
// ../authz-commands/src/commands/assignments.ts
|
|
1850
|
+
var PRINCIPAL_TYPE_VALUES = Object.values(PrincipalType);
|
|
1851
|
+
var LIST_EXAMPLES2 = [
|
|
1852
|
+
{
|
|
1853
|
+
Description: "List direct role assignments at the login tenant scope (default)",
|
|
1854
|
+
Command: "uip admin authorization roles assignments list",
|
|
1855
|
+
Output: {
|
|
1856
|
+
Code: "AuthzAssignmentsList",
|
|
1857
|
+
Data: {
|
|
1858
|
+
totalCount: 1,
|
|
1859
|
+
results: [
|
|
1860
|
+
{
|
|
1861
|
+
securityPrincipalId: "<user-guid>",
|
|
1862
|
+
displayName: "Jane Doe",
|
|
1863
|
+
email: "jane.doe@acme.example",
|
|
1864
|
+
type: "User",
|
|
1865
|
+
source: "Local",
|
|
1866
|
+
roleAssignmentDtos: [
|
|
1867
|
+
{
|
|
1868
|
+
id: "<assignment-guid>",
|
|
1869
|
+
securityPrincipalId: "<user-guid>",
|
|
1870
|
+
securityPrincipalType: "User",
|
|
1871
|
+
type: "Direct",
|
|
1872
|
+
scope: "/tenant/<tenant-guid>",
|
|
1873
|
+
roleId: "<role-guid>",
|
|
1874
|
+
roleName: "Tenant Administrator",
|
|
1875
|
+
roleType: "BuiltIn",
|
|
1876
|
+
createdBy: "<user-guid>",
|
|
1877
|
+
createdOn: "<iso-date>",
|
|
1878
|
+
inherited: false,
|
|
1879
|
+
mutable: true
|
|
1880
|
+
}
|
|
1881
|
+
]
|
|
1882
|
+
}
|
|
1883
|
+
]
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
},
|
|
1887
|
+
{
|
|
1888
|
+
Description: "List a different tenant's direct assignments (target a tenant by UUID)",
|
|
1889
|
+
Command: "uip admin authorization roles assignments list --scope Tenant --tenant-id 11111111-2222-3333-4444-555555555555",
|
|
1890
|
+
Output: {
|
|
1891
|
+
Code: "AuthzAssignmentsList",
|
|
1892
|
+
Data: { totalCount: 0, results: [] }
|
|
1893
|
+
}
|
|
1894
|
+
},
|
|
1895
|
+
{
|
|
1896
|
+
Description: "List tenant assignments including inherited (organization-level) ones",
|
|
1897
|
+
Command: "uip admin authorization roles assignments list --include-inherited",
|
|
1898
|
+
Output: {
|
|
1899
|
+
Code: "AuthzAssignmentsList",
|
|
1900
|
+
Data: { totalCount: 0, results: [] }
|
|
1901
|
+
}
|
|
1902
|
+
},
|
|
1903
|
+
{
|
|
1904
|
+
Description: "List organization-scope assignments (root)",
|
|
1905
|
+
Command: "uip admin authorization roles assignments list --scope Organization",
|
|
1906
|
+
Output: {
|
|
1907
|
+
Code: "AuthzAssignmentsList",
|
|
1908
|
+
Data: { totalCount: 0, results: [] }
|
|
1909
|
+
}
|
|
1910
|
+
},
|
|
1911
|
+
{
|
|
1912
|
+
Description: "List Folder-scope assignments for a service (--service and --scope-id are both required; scope is composed server-side)",
|
|
1913
|
+
Command: "uip admin authorization roles assignments list --scope Folder --service orchestrator --scope-id Insights",
|
|
1914
|
+
Output: {
|
|
1915
|
+
Code: "AuthzAssignmentsList",
|
|
1916
|
+
Data: { totalCount: 0, results: [] }
|
|
1917
|
+
}
|
|
1918
|
+
},
|
|
1919
|
+
{
|
|
1920
|
+
Description: "List Project-scope assignments for a service (--service and --scope-id are both required; scope is composed server-side)",
|
|
1921
|
+
Command: "uip admin authorization roles assignments list --scope Project --service documentunderstanding --scope-id f4d490de3a697c65",
|
|
1922
|
+
Output: {
|
|
1923
|
+
Code: "AuthzAssignmentsList",
|
|
1924
|
+
Data: { totalCount: 0, results: [] }
|
|
1925
|
+
}
|
|
1926
|
+
},
|
|
1927
|
+
{
|
|
1928
|
+
Description: "Advanced: send an exact scope path verbatim to the API (overrides --scope, --service, --scope-id, and --tenant-id)",
|
|
1929
|
+
Command: "uip admin authorization roles assignments list --scope-path /tenant/11111111-2222-3333-4444-555555555555/reinfer",
|
|
1930
|
+
Output: {
|
|
1931
|
+
Code: "AuthzAssignmentsList",
|
|
1932
|
+
Data: { totalCount: 0, results: [] }
|
|
1933
|
+
}
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
Description: "Filter assignments by service — scope is inferred from the service registry (apps → Organization, documentunderstanding → Tenant)",
|
|
1937
|
+
Command: "uip admin authorization roles assignments list --service apps",
|
|
1938
|
+
Output: {
|
|
1939
|
+
Code: "AuthzAssignmentsList",
|
|
1940
|
+
Data: { totalCount: 0, results: [] }
|
|
1941
|
+
}
|
|
1942
|
+
},
|
|
1943
|
+
{
|
|
1944
|
+
Description: "Filter assignments by identity (user / group / robot)",
|
|
1945
|
+
Command: "uip admin authorization roles assignments list --identity-id b44fc962-d544-4c99-b520-71121070ec17",
|
|
1946
|
+
Output: {
|
|
1947
|
+
Code: "AuthzAssignmentsList",
|
|
1948
|
+
Data: { totalCount: 0, results: [] }
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
];
|
|
1952
|
+
var CREATE_EXAMPLES = [
|
|
1953
|
+
{
|
|
1954
|
+
Description: "Assign a tenant-scoped role to a user (tenant id auto-fills from the login session)",
|
|
1955
|
+
Command: "uip admin authorization roles assignments create --role-id 98dc776b-835c-407f-9d58-6676318ac968 --identity-id b44fc962-d544-4c99-b520-71121070ec17 --identity-type User",
|
|
1956
|
+
Output: { Code: "AuthzAssignmentCreated", Data: {} }
|
|
1957
|
+
},
|
|
1958
|
+
{
|
|
1959
|
+
Description: "Assign a role on a specific tenant (override the auto-fill)",
|
|
1960
|
+
Command: "uip admin authorization roles assignments create --role-id <role-guid> --identity-id <user-guid> --identity-type User --tenant-id 11111111-2222-3333-4444-555555555555",
|
|
1961
|
+
Output: { Code: "AuthzAssignmentCreated", Data: {} }
|
|
1962
|
+
},
|
|
1963
|
+
{
|
|
1964
|
+
Description: "Assign a role at a project/folder/app scope (--scope + --service + --scope-id, or pass an exact path via --scope-path)",
|
|
1965
|
+
Command: "uip admin authorization roles assignments create --role-id <role-guid> --identity-id <group-guid> --identity-type Group --scope Project --service documentunderstanding --scope-id <project-id>",
|
|
1966
|
+
Output: { Code: "AuthzAssignmentCreated", Data: {} }
|
|
1967
|
+
},
|
|
1968
|
+
{
|
|
1969
|
+
Description: "Batch: create multiple role assignments from a JSON file (array of AddRoleAssignmentRequest). Schema per entry: { roleId, securityPrincipalId, securityPrincipalType: 'User'|'Group'|'Robot'|'ExternalApplication', scope?: '<scope-path>' }",
|
|
1970
|
+
Command: "uip admin authorization roles assignments create --file ./assignments.json",
|
|
1971
|
+
Output: { Code: "AuthzAssignmentCreated", Data: {} }
|
|
1972
|
+
}
|
|
1973
|
+
];
|
|
1974
|
+
var DELETE_EXAMPLES = [
|
|
1975
|
+
{
|
|
1976
|
+
Description: "Delete a single role assignment by id (find ids via `roles assignments list`)",
|
|
1977
|
+
Command: "uip admin authorization roles assignments delete 0fae98e1-0f2e-4f8d-bdab-7ce1cf475676",
|
|
1978
|
+
Output: { Code: "AuthzAssignmentDeleted", Data: {} }
|
|
1979
|
+
},
|
|
1980
|
+
{
|
|
1981
|
+
Description: 'Batch: delete multiple role assignments from a JSON file. The file must be a JSON array of assignment-id strings, e.g. ["0fae...","1aab..."]',
|
|
1982
|
+
Command: "uip admin authorization roles assignments delete --file ./assignment-ids.json",
|
|
1983
|
+
Output: { Code: "AuthzAssignmentDeleted", Data: {} }
|
|
1984
|
+
}
|
|
1985
|
+
];
|
|
1986
|
+
async function getApi(options) {
|
|
1987
|
+
const [err, client] = await catchError(createPapClient(RoleAssignmentApi, {
|
|
1988
|
+
loginValidity: options.loginValidity
|
|
1989
|
+
}));
|
|
1990
|
+
if (err) {
|
|
1991
|
+
await emitFailure(err, LOGIN_INSTRUCTIONS);
|
|
1992
|
+
return null;
|
|
1993
|
+
}
|
|
1994
|
+
return client;
|
|
1995
|
+
}
|
|
1996
|
+
var registerAssignmentsCommands = (roles) => {
|
|
1997
|
+
const assignments = roles.command("assignments").description("Manage who-has-what-role within the organization (Policy Administration Point).");
|
|
1998
|
+
withLoginValidity(assignments.command("list").description([
|
|
1999
|
+
"List role assignments for the caller's organization, grouped by",
|
|
2000
|
+
"identity. The /api/userroleassignments endpoint takes an exact-match",
|
|
2001
|
+
"`scope` path; the CLI composes it from --scope, --service, --scope-id",
|
|
2002
|
+
"and --tenant-id along the same scope/service axes as `roles list`",
|
|
2003
|
+
"(note: `assignments list` defaults to the login tenant when those",
|
|
2004
|
+
"flags are omitted; `roles list` returns an unfiltered pass-through):",
|
|
2005
|
+
"",
|
|
2006
|
+
" (no scope flags) scope=/tenant/<tid> (default),",
|
|
2007
|
+
" serviceName=centralizedaccess",
|
|
2008
|
+
" --scope Organization (no --service) scope=/, serviceName=centralizedaccess,",
|
|
2009
|
+
" roleScopeType=organization",
|
|
2010
|
+
" --scope Tenant (no --service) scope=/tenant/<tid>,",
|
|
2011
|
+
" serviceName=centralizedaccess",
|
|
2012
|
+
" --service <org-svc> scope=/, serviceName=<svc>,",
|
|
2013
|
+
" roleScopeType=organization",
|
|
2014
|
+
" --service <tenant-svc> scope=/tenant/<tid>/<svc>,",
|
|
2015
|
+
" serviceName=<svc>",
|
|
2016
|
+
" --scope Project|Folder|App scope=/tenant/<tid>/<svc>/",
|
|
2017
|
+
" --service <svc> --scope-id <id> <project|folder|app>/<id>,",
|
|
2018
|
+
" serviceName=<svc>",
|
|
2019
|
+
" --scope-path <path> verbatim (advanced escape hatch)",
|
|
2020
|
+
"",
|
|
2021
|
+
"TenantGlobal is not a valid assignment scope. Listing works for every",
|
|
2022
|
+
"service (including services that manage their own role assignments",
|
|
2023
|
+
"and platform-level services); only authoring is blocked.",
|
|
2024
|
+
"",
|
|
2025
|
+
"By default `noInheritance=true` so only direct assignments at the",
|
|
2026
|
+
"requested scope are returned. Pass --include-inherited to walk up the",
|
|
2027
|
+
"scope tree (Org -> Tenant -> sub-scope)."
|
|
2028
|
+
].join(`
|
|
2029
|
+
`)).option("--limit <n>", "Page size — maximum number of assignment groups to return (server caps at 10).", parseIntOption, 10).option("--offset <n>", "Number of records to skip before the returned page (zero-based).", parseIntOption, 0).option("--service <service>", "Owning service (e.g. apps, documentunderstanding). Combines with --scope, or used alone sets the scope path from the service registry.").option("--identity-id <id>", "Restrict to assignments for a single identity (user / group / external app).").addOption(new Option("--scope <type>", "Scope: Organization, Tenant, Project, Folder, or App (case-insensitive). TenantGlobal is not allowed. Project/Folder/App require --service and --scope-id. Defaults to the login tenant when all of --scope, --service, and --scope-path are omitted.").argParser(canonicalizeAssignmentListScope)).option("--scope-id <id>", "Project id / folder name/id / app id for --scope Project|Folder|App. Combined with --service to build the sub-scope path.").option("--scope-path <path>", "Advanced: send this exact path verbatim to the API (server-side exact match). Overrides --scope, --tenant-id, and --scope-id.").option("--tenant-id <guid>", "Tenant UUID. Used for Tenant / Project / Folder / App scopes; defaults to the login tenant when omitted.").option("--include-inherited", "Include assignments inherited from parent scopes (default: direct only).").examples(LIST_EXAMPLES2)).trackedAction(processContext, async (options) => {
|
|
2030
|
+
const client = await getApi(options);
|
|
2031
|
+
if (!client)
|
|
2032
|
+
return;
|
|
2033
|
+
const filter = shapeAssignmentListFilter({
|
|
2034
|
+
scope: options.scope,
|
|
2035
|
+
serviceFlag: options.service,
|
|
2036
|
+
scopeIdFlag: options.scopeId,
|
|
2037
|
+
scopePathFlag: options.scopePath,
|
|
2038
|
+
tenantIdFlag: options.tenantId,
|
|
2039
|
+
loginTenantId: client.tenantId
|
|
2040
|
+
});
|
|
2041
|
+
if (filter === null)
|
|
2042
|
+
return;
|
|
2043
|
+
const noInheritance = options.includeInherited !== true;
|
|
2044
|
+
const [error, result] = await catchError(client.api.apiUserroleassignmentsGet({
|
|
2045
|
+
xUipathInternalAccountid: client.organizationId,
|
|
2046
|
+
top: options.limit,
|
|
2047
|
+
skip: options.offset,
|
|
2048
|
+
serviceName: filter.serviceName,
|
|
2049
|
+
securityPrincipalId: options.identityId,
|
|
2050
|
+
scope: filter.scope,
|
|
2051
|
+
roleScopeType: filter.roleScopeType,
|
|
2052
|
+
noInheritance
|
|
2053
|
+
}));
|
|
2054
|
+
if (error) {
|
|
2055
|
+
await emitFailure(error, "Verify --service / --identity-id / --scope / --tenant-id values; ensure the organization has assignments to list.");
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
2058
|
+
OutputFormatter.success({
|
|
2059
|
+
Result: RESULTS.Success,
|
|
2060
|
+
Code: "AuthzAssignmentsList",
|
|
2061
|
+
Data: result
|
|
2062
|
+
});
|
|
2063
|
+
});
|
|
2064
|
+
withLoginValidity(assignments.command("create").description([
|
|
2065
|
+
"Create one or more role assignments.",
|
|
2066
|
+
"",
|
|
2067
|
+
"Inline mode: --role-id + --identity-id + --identity-type, plus the same",
|
|
2068
|
+
"scope-composition flags as `assignments list` (--scope / --service /",
|
|
2069
|
+
"--scope-id / --scope-path / --tenant-id). The CLI composes the body's",
|
|
2070
|
+
"`scope` path using the same matrix:",
|
|
2071
|
+
"",
|
|
2072
|
+
" (no scope flags) scope=/tenant/<tid> (default)",
|
|
2073
|
+
" --scope Organization scope=/",
|
|
2074
|
+
" --scope Tenant | TenantGlobal scope=/tenant/<tid>",
|
|
2075
|
+
" --service <org-svc> scope=/",
|
|
2076
|
+
" --service <tenant-svc> scope=/tenant/<tid>/<svc>",
|
|
2077
|
+
" --scope Project|Folder|App scope=/tenant/<tid>/<svc>/",
|
|
2078
|
+
" --service <svc> --scope-id <id> <project|folder|app>/<id>",
|
|
2079
|
+
" --scope-path <path> verbatim (advanced)",
|
|
2080
|
+
"",
|
|
2081
|
+
"TenantGlobal is accepted on create (assigns a TenantGlobal-shape role",
|
|
2082
|
+
"to a specific tenant); the resulting path is /tenant/<tid>, same as",
|
|
2083
|
+
"--scope Tenant.",
|
|
2084
|
+
"",
|
|
2085
|
+
"Services that manage their own role assignments (orchestrator,",
|
|
2086
|
+
"dataservice, insights, taskmining, testmanager, automationops,",
|
|
2087
|
+
"casemanagement, processmining) and platform-level services (authz,",
|
|
2088
|
+
"oms, platform, identity, licensing) are rejected when passed via",
|
|
2089
|
+
"--service — same rule as `roles create`. Use --scope-path for",
|
|
2090
|
+
"verbatim assignments against those services.",
|
|
2091
|
+
"",
|
|
2092
|
+
"Batch mode (--file): pass a JSON array of AddRoleAssignmentRequest;",
|
|
2093
|
+
"each entry carries its own `scope` field, so the inline flags above",
|
|
2094
|
+
"are not used. All entries are sent atomically.",
|
|
2095
|
+
" {",
|
|
2096
|
+
' "roleId": "<role-guid>",',
|
|
2097
|
+
' "securityPrincipalId": "<identity-guid>",',
|
|
2098
|
+
' "securityPrincipalType": "User" | "Group" | "Robot" | "ExternalApplication",',
|
|
2099
|
+
' "scope": "<scope-path>",',
|
|
2100
|
+
' "tenantId": "<tenant-guid>" // optional',
|
|
2101
|
+
" }"
|
|
2102
|
+
].join(`
|
|
2103
|
+
`)).option("--file <path>", "Path to a JSON file containing an array of AddRoleAssignmentRequest objects (batch mode).").option("--role-id <guid>", "Role UUID to assign.").option("--identity-id <guid>", "Security principal UUID (user / group / external app / robot).").addOption(new Option("--identity-type <type>", "Type of the security principal.").choices(PRINCIPAL_TYPE_VALUES)).option("--service <service>", "Owning service (e.g. apps, documentunderstanding). Combines with --scope, or used alone sets the scope path from the service registry.").addOption(new Option("--scope <type>", "Scope: Organization, TenantGlobal, Tenant, Project, Folder, or App (case-insensitive). Project/Folder/App require --service and --scope-id. Defaults to the login tenant when all of --scope, --service, and --scope-path are omitted.").argParser(canonicalizeAssignmentCreateScope)).option("--scope-id <id>", "Project id / folder name/id / app id for --scope Project|Folder|App. Combined with --service to build the sub-scope path.").option("--scope-path <path>", "Advanced: send this exact path verbatim in the assignment body (overrides --scope, --service, --scope-id, --tenant-id).").option("--tenant-id <guid>", "Tenant UUID for Tenant / TenantGlobal / Project / Folder / App scopes. Defaults to the login tenant when omitted.").examples(CREATE_EXAMPLES)).trackedAction(processContext, async (options) => {
|
|
2104
|
+
const inlineProvided = options.roleId !== undefined || options.identityId !== undefined || options.identityType !== undefined || options.scope !== undefined || options.service !== undefined || options.scopeId !== undefined || options.scopePath !== undefined || options.tenantId !== undefined;
|
|
2105
|
+
if (options.file !== undefined && inlineProvided) {
|
|
2106
|
+
OutputFormatter.error({
|
|
2107
|
+
Result: RESULTS.Failure,
|
|
2108
|
+
Message: "--file is mutually exclusive with the inline flags (--role-id / --identity-id / --identity-type / --scope / --service / --scope-id / --scope-path / --tenant-id).",
|
|
2109
|
+
Instructions: "Pass either --file for batch mode, or the inline flags for a single assignment."
|
|
2110
|
+
});
|
|
2111
|
+
processContext.exit(1);
|
|
2112
|
+
return;
|
|
2113
|
+
}
|
|
2114
|
+
if (options.file === undefined && !inlineProvided) {
|
|
2115
|
+
OutputFormatter.error({
|
|
2116
|
+
Result: RESULTS.Failure,
|
|
2117
|
+
Message: "Provide either --file or the inline flags (--role-id, --identity-id, --identity-type, plus --scope/--service/--scope-path).",
|
|
2118
|
+
Instructions: "Single assignment: --role-id <guid> --identity-id <guid> --identity-type User|Group|ExternalApplication|Robot, plus --scope/--service/--scope-path. Batch: --file <path>."
|
|
2119
|
+
});
|
|
2120
|
+
processContext.exit(1);
|
|
2121
|
+
return;
|
|
2122
|
+
}
|
|
2123
|
+
const client = await getApi(options);
|
|
2124
|
+
if (!client)
|
|
2125
|
+
return;
|
|
2126
|
+
let body;
|
|
2127
|
+
if (options.file !== undefined) {
|
|
2128
|
+
const [loadErr, loaded] = await loadJsonFile(options.file, "AddRoleAssignmentRequest[]");
|
|
2129
|
+
if (loadErr) {
|
|
2130
|
+
emitLoadError(loadErr);
|
|
2131
|
+
return;
|
|
2132
|
+
}
|
|
2133
|
+
if (!Array.isArray(loaded) || loaded.length === 0) {
|
|
2134
|
+
OutputFormatter.error({
|
|
2135
|
+
Result: RESULTS.Failure,
|
|
2136
|
+
Message: "Expected --file to contain a non-empty JSON array of AddRoleAssignmentRequest objects.",
|
|
2137
|
+
Instructions: "Wrap each assignment in a `[]` array; use `roles assignments delete` for removals."
|
|
2138
|
+
});
|
|
2139
|
+
processContext.exit(1);
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
body = loaded;
|
|
2143
|
+
} else {
|
|
2144
|
+
if (options.roleId === undefined || options.identityId === undefined || options.identityType === undefined) {
|
|
2145
|
+
OutputFormatter.error({
|
|
2146
|
+
Result: RESULTS.Failure,
|
|
2147
|
+
Message: "Inline mode requires --role-id, --identity-id and --identity-type.",
|
|
2148
|
+
Instructions: "Add the missing flag(s), or switch to --file for batch mode."
|
|
2149
|
+
});
|
|
2150
|
+
processContext.exit(1);
|
|
2151
|
+
return;
|
|
2152
|
+
}
|
|
2153
|
+
const shaped = shapeAssignmentCreateScope({
|
|
2154
|
+
scope: options.scope,
|
|
2155
|
+
serviceFlag: options.service,
|
|
2156
|
+
scopeIdFlag: options.scopeId,
|
|
2157
|
+
scopePathFlag: options.scopePath,
|
|
2158
|
+
tenantIdFlag: options.tenantId,
|
|
2159
|
+
loginTenantId: client.tenantId
|
|
2160
|
+
});
|
|
2161
|
+
if (shaped === null)
|
|
2162
|
+
return;
|
|
2163
|
+
body = [
|
|
2164
|
+
{
|
|
2165
|
+
roleId: options.roleId,
|
|
2166
|
+
securityPrincipalId: options.identityId,
|
|
2167
|
+
securityPrincipalType: options.identityType,
|
|
2168
|
+
scope: shaped.scope,
|
|
2169
|
+
tenantId: shaped.tenantId
|
|
2170
|
+
}
|
|
2171
|
+
];
|
|
2172
|
+
}
|
|
2173
|
+
const [error, response] = await catchError(client.api.apiUserroleassignmentsPatchRaw({
|
|
2174
|
+
xUipathInternalAccountid: client.organizationId,
|
|
2175
|
+
bulkUpdateRoleAssignmentsDto: {
|
|
2176
|
+
roleAssignmentsToAdd: body,
|
|
2177
|
+
roleAssignmentsToDelete: []
|
|
2178
|
+
}
|
|
2179
|
+
}));
|
|
2180
|
+
if (error || !response) {
|
|
2181
|
+
await emitFailure(error ?? new Error("Empty response"), "Verify the assignment fields (roleId / securityPrincipalId / securityPrincipalType / scope-path).");
|
|
2182
|
+
return;
|
|
2183
|
+
}
|
|
2184
|
+
const responseBody = await extractResponseData(response);
|
|
2185
|
+
OutputFormatter.success({
|
|
2186
|
+
Result: RESULTS.Success,
|
|
2187
|
+
Code: "AuthzAssignmentCreated",
|
|
2188
|
+
Data: responseBody ?? {}
|
|
2189
|
+
});
|
|
2190
|
+
});
|
|
2191
|
+
withLoginValidity(assignments.command("delete").description([
|
|
2192
|
+
"Delete one or more role assignments by id.",
|
|
2193
|
+
"",
|
|
2194
|
+
"Single removal: pass the assignment UUID positionally.",
|
|
2195
|
+
"Batch: pass --file with a JSON array of assignment-id",
|
|
2196
|
+
" strings, e.g.",
|
|
2197
|
+
' ["0fae98e1-...", "1aab33cf-..."]',
|
|
2198
|
+
"",
|
|
2199
|
+
"All ids are sent to the bulk-update endpoint atomically; partial",
|
|
2200
|
+
"failure rolls back the whole batch (best-effort, per the API contract).",
|
|
2201
|
+
"Discover assignment ids with `uip admin authorization roles",
|
|
2202
|
+
"assignments list`.",
|
|
2203
|
+
"",
|
|
2204
|
+
"Idempotency note: the bulk-update endpoint silently no-ops on",
|
|
2205
|
+
"unknown / already-deleted ids and still returns Success — this",
|
|
2206
|
+
"command does NOT verify the ids existed beforehand. If you need",
|
|
2207
|
+
"to confirm the deletion happened, list before/after."
|
|
2208
|
+
].join(`
|
|
2209
|
+
`)).argument("[id]", "Single assignment UUID. Mutually exclusive with --file.").option("--file <path>", "Path to a JSON file containing an array of assignment-id strings (batch mode).").examples(DELETE_EXAMPLES)).trackedAction(processContext, async (idArg, options) => {
|
|
2210
|
+
if (options.file !== undefined && idArg !== undefined) {
|
|
2211
|
+
OutputFormatter.error({
|
|
2212
|
+
Result: RESULTS.Failure,
|
|
2213
|
+
Message: "Positional <id> is mutually exclusive with --file.",
|
|
2214
|
+
Instructions: "Pass either the positional UUID for a single deletion, or --file <path> for batch mode."
|
|
2215
|
+
});
|
|
2216
|
+
processContext.exit(1);
|
|
2217
|
+
return;
|
|
2218
|
+
}
|
|
2219
|
+
if (options.file === undefined && idArg === undefined) {
|
|
2220
|
+
OutputFormatter.error({
|
|
2221
|
+
Result: RESULTS.Failure,
|
|
2222
|
+
Message: "Provide either a positional assignment UUID or --file.",
|
|
2223
|
+
Instructions: "Single deletion: pass the UUID positionally. Batch: --file <path>."
|
|
2224
|
+
});
|
|
2225
|
+
processContext.exit(1);
|
|
2226
|
+
return;
|
|
2227
|
+
}
|
|
2228
|
+
let body;
|
|
2229
|
+
if (options.file !== undefined) {
|
|
2230
|
+
const [loadErr, loaded] = await loadJsonFile(options.file, "string[] (assignment ids)");
|
|
2231
|
+
if (loadErr) {
|
|
2232
|
+
emitLoadError(loadErr);
|
|
2233
|
+
return;
|
|
2234
|
+
}
|
|
2235
|
+
if (!Array.isArray(loaded) || loaded.length === 0 || loaded.some((entry) => typeof entry !== "string")) {
|
|
2236
|
+
OutputFormatter.error({
|
|
2237
|
+
Result: RESULTS.Failure,
|
|
2238
|
+
Message: "Expected --file to contain a non-empty JSON array of assignment-id strings.",
|
|
2239
|
+
Instructions: 'Format: ["<assignment-guid>", ...]. Use `roles assignments create` to add assignments.'
|
|
2240
|
+
});
|
|
2241
|
+
processContext.exit(1);
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
body = loaded;
|
|
2245
|
+
} else {
|
|
2246
|
+
body = [idArg];
|
|
2247
|
+
}
|
|
2248
|
+
const client = await getApi(options);
|
|
2249
|
+
if (!client)
|
|
2250
|
+
return;
|
|
2251
|
+
const [error, response] = await catchError(client.api.apiUserroleassignmentsPatchRaw({
|
|
2252
|
+
xUipathInternalAccountid: client.organizationId,
|
|
2253
|
+
bulkUpdateRoleAssignmentsDto: {
|
|
2254
|
+
roleAssignmentsToAdd: [],
|
|
2255
|
+
roleAssignmentsToDelete: body
|
|
2256
|
+
}
|
|
2257
|
+
}));
|
|
2258
|
+
if (error || !response) {
|
|
2259
|
+
await emitFailure(error ?? new Error("Empty response"), "Verify each id is a valid assignment id obtained from `roles assignments list`.");
|
|
2260
|
+
return;
|
|
2261
|
+
}
|
|
2262
|
+
const responseBody = await extractResponseData(response);
|
|
2263
|
+
OutputFormatter.success({
|
|
2264
|
+
Result: RESULTS.Success,
|
|
2265
|
+
Code: "AuthzAssignmentDeleted",
|
|
2266
|
+
Data: responseBody ?? {}
|
|
2267
|
+
});
|
|
2268
|
+
});
|
|
2269
|
+
};
|
|
2270
|
+
|
|
2271
|
+
// ../authz-commands/src/commands/roles.ts
|
|
2272
|
+
var SAMPLE_ID = "11111111-2222-3333-4444-555555555555";
|
|
2273
|
+
var LIST_EXAMPLES3 = [
|
|
2274
|
+
{
|
|
2275
|
+
Description: "List the first 20 roles in the organization",
|
|
2276
|
+
Command: "uip admin authorization roles list",
|
|
2277
|
+
Output: {
|
|
2278
|
+
Code: "AuthzRolesList",
|
|
2279
|
+
Data: {
|
|
2280
|
+
totalCount: 1,
|
|
2281
|
+
results: [
|
|
2282
|
+
{
|
|
2283
|
+
id: SAMPLE_ID,
|
|
2284
|
+
name: "Folder Admin",
|
|
2285
|
+
description: "Folder admin role",
|
|
2286
|
+
type: "BuiltIn",
|
|
2287
|
+
scopeType: "Folder",
|
|
2288
|
+
ownerServiceName: "orchestrator",
|
|
2289
|
+
ownerServiceId: "<service-guid>",
|
|
2290
|
+
tenantId: "<tenant-guid>",
|
|
2291
|
+
createdBy: "<user-guid>",
|
|
2292
|
+
createdOn: "<iso-date>",
|
|
2293
|
+
actionDetails: []
|
|
2294
|
+
}
|
|
2295
|
+
]
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
},
|
|
2299
|
+
{
|
|
2300
|
+
Description: "Filter by role shape — org-wide roles only",
|
|
2301
|
+
Command: "uip admin authorization roles list --scope Organization",
|
|
2302
|
+
Output: {
|
|
2303
|
+
Code: "AuthzRolesList",
|
|
2304
|
+
Data: { totalCount: 0, results: [] }
|
|
2305
|
+
}
|
|
2306
|
+
},
|
|
2307
|
+
{
|
|
2308
|
+
Description: "Filter by service — scope is inferred from the service registry (apps → Organization)",
|
|
2309
|
+
Command: "uip admin authorization roles list --service apps --filter Admin",
|
|
2310
|
+
Output: {
|
|
2311
|
+
Code: "AuthzRolesList",
|
|
2312
|
+
Data: { totalCount: 0, results: [] }
|
|
2313
|
+
}
|
|
2314
|
+
},
|
|
2315
|
+
{
|
|
2316
|
+
Description: "Filter by tenant-service — scope is inferred (documentunderstanding → Tenant)",
|
|
2317
|
+
Command: "uip admin authorization roles list --service documentunderstanding",
|
|
2318
|
+
Output: {
|
|
2319
|
+
Code: "AuthzRolesList",
|
|
2320
|
+
Data: { totalCount: 0, results: [] }
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
];
|
|
2324
|
+
var GET_EXAMPLES = [
|
|
2325
|
+
{
|
|
2326
|
+
Description: "Fetch a role by id",
|
|
2327
|
+
Command: `uip admin authorization roles get ${SAMPLE_ID}`,
|
|
2328
|
+
Output: {
|
|
2329
|
+
Code: "AuthzRoleGet",
|
|
2330
|
+
Data: {
|
|
2331
|
+
id: SAMPLE_ID,
|
|
2332
|
+
name: "Folder Admin",
|
|
2333
|
+
description: "Folder admin role",
|
|
2334
|
+
type: "BuiltIn",
|
|
2335
|
+
scopeType: "Folder",
|
|
2336
|
+
ownerServiceName: "orchestrator",
|
|
2337
|
+
ownerServiceId: "<service-guid>",
|
|
2338
|
+
tenantId: "<tenant-guid>",
|
|
2339
|
+
createdBy: "<user-guid>",
|
|
2340
|
+
createdOn: "<iso-date>",
|
|
2341
|
+
actionDetails: [
|
|
2342
|
+
{
|
|
2343
|
+
id: "<action-guid>",
|
|
2344
|
+
name: "OR.FOLDERS.READ",
|
|
2345
|
+
namespace: "ORCHESTRATOR",
|
|
2346
|
+
serviceDisplayName: "Orchestrator",
|
|
2347
|
+
resourceType: "Folders",
|
|
2348
|
+
resourceAction: "Read",
|
|
2349
|
+
resourceGroup: "Folder",
|
|
2350
|
+
description: "View folders"
|
|
2351
|
+
}
|
|
2352
|
+
]
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
];
|
|
2357
|
+
var CREATE_EXAMPLES2 = [
|
|
2358
|
+
{
|
|
2359
|
+
Description: "Organization role — actions in --file, identity via inline flags.",
|
|
2360
|
+
Command: 'uip admin authorization roles create --scope Organization --name "Org Reader" --description "Read-only org admin" --file ./actions.json',
|
|
2361
|
+
Output: {
|
|
2362
|
+
Code: "AuthzRoleCreated",
|
|
2363
|
+
Data: { createdRoleId: "<new-role-guid>" }
|
|
2364
|
+
}
|
|
2365
|
+
},
|
|
2366
|
+
{
|
|
2367
|
+
Description: "Tenant-wide role within the login tenant (default) or a specific tenant via --tenant-id.",
|
|
2368
|
+
Command: 'uip admin authorization roles create --scope Tenant --name "Tenant Reader" --file ./actions.json',
|
|
2369
|
+
Output: {
|
|
2370
|
+
Code: "AuthzRoleCreated",
|
|
2371
|
+
Data: { createdRoleId: "<new-role-guid>" }
|
|
2372
|
+
}
|
|
2373
|
+
},
|
|
2374
|
+
{
|
|
2375
|
+
Description: "Tenant-global template (Tenant scope, no tenant id) — applies across tenants.",
|
|
2376
|
+
Command: 'uip admin authorization roles create --scope TenantGlobal --name "Tenant Reader Template" --file ./actions.json',
|
|
2377
|
+
Output: {
|
|
2378
|
+
Code: "AuthzRoleCreated",
|
|
2379
|
+
Data: { createdRoleId: "<new-role-guid>" }
|
|
2380
|
+
}
|
|
2381
|
+
},
|
|
2382
|
+
{
|
|
2383
|
+
Description: "Org-service role — --service names the owning service; the CLI infers the scope from the service registry (apps → Organization).",
|
|
2384
|
+
Command: 'uip admin authorization roles create --service apps --name "Apps Author" --file ./actions.json',
|
|
2385
|
+
Output: {
|
|
2386
|
+
Code: "AuthzRoleCreated",
|
|
2387
|
+
Data: { createdRoleId: "<new-role-guid>" }
|
|
2388
|
+
}
|
|
2389
|
+
},
|
|
2390
|
+
{
|
|
2391
|
+
Description: "Tenant-service role — the CLI infers Tenant scope from the registry (documentunderstanding → Tenant).",
|
|
2392
|
+
Command: 'uip admin authorization roles create --service documentunderstanding --name "DU Tenant Editor" --file ./actions.json',
|
|
2393
|
+
Output: {
|
|
2394
|
+
Code: "AuthzRoleCreated",
|
|
2395
|
+
Data: { createdRoleId: "<new-role-guid>" }
|
|
2396
|
+
}
|
|
2397
|
+
},
|
|
2398
|
+
{
|
|
2399
|
+
Description: "Project-scoped role for a service that registers Project-scope permissions (e.g. Document Understanding, Reinfer).",
|
|
2400
|
+
Command: 'uip admin authorization roles create --scope Project --service documentunderstanding --name "DU Project Editor" --file ./actions.json',
|
|
2401
|
+
Output: {
|
|
2402
|
+
Code: "AuthzRoleCreated",
|
|
2403
|
+
Data: { createdRoleId: "<new-role-guid>" }
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
];
|
|
2407
|
+
var UPDATE_EXAMPLES = [
|
|
2408
|
+
{
|
|
2409
|
+
Description: "Update an existing tenant-wide role by id; CLI re-derives scope/tenant from --scope.",
|
|
2410
|
+
Command: `uip admin authorization roles update ${SAMPLE_ID} --scope Tenant --name "Tenant Reader" --file ./actions.json`,
|
|
2411
|
+
Output: {
|
|
2412
|
+
Code: "AuthzRoleUpdated",
|
|
2413
|
+
Data: { createdRoleId: SAMPLE_ID }
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
];
|
|
2417
|
+
var DELETE_EXAMPLES2 = [
|
|
2418
|
+
{
|
|
2419
|
+
Description: "Delete a custom role by id",
|
|
2420
|
+
Command: `uip admin authorization roles delete ${SAMPLE_ID}`,
|
|
2421
|
+
Output: { Code: "AuthzRoleDeleted", Data: {} }
|
|
2422
|
+
}
|
|
2423
|
+
];
|
|
2424
|
+
async function getApi2(options) {
|
|
2425
|
+
const [err, client] = await catchError(createPapClient(RoleApi, { loginValidity: options.loginValidity }));
|
|
2426
|
+
if (err) {
|
|
2427
|
+
await emitFailure(err, LOGIN_INSTRUCTIONS);
|
|
2428
|
+
return null;
|
|
2429
|
+
}
|
|
2430
|
+
return client;
|
|
2431
|
+
}
|
|
2432
|
+
var registerRolesCommands = (authz) => {
|
|
2433
|
+
const roles = authz.command("roles").description("Manage custom role definitions on the Policy Administration Point (PAP).");
|
|
2434
|
+
withLoginValidity(roles.command("list").description([
|
|
2435
|
+
"List roles for the caller's organization. Returns both built-in and",
|
|
2436
|
+
"custom roles by default; pass `--role-type BuiltIn|Custom` to restrict.",
|
|
2437
|
+
"",
|
|
2438
|
+
"Filter by `--scope` and `--service` (with `--tenant-id` for Tenant /",
|
|
2439
|
+
"Project / Folder scopes). The CLI maps the flags directly to the PAP",
|
|
2440
|
+
"`GET /api/roles` query parameters:",
|
|
2441
|
+
"",
|
|
2442
|
+
" --scope Organization (no --service) serviceName=centralizedaccess,",
|
|
2443
|
+
" scopeType=Organization",
|
|
2444
|
+
" --scope TenantGlobal (no --service) serviceName=centralizedaccess,",
|
|
2445
|
+
" scopeType=Tenant,",
|
|
2446
|
+
" tenantId=00000000-…",
|
|
2447
|
+
" --scope Tenant (no --service) serviceName=centralizedaccess,",
|
|
2448
|
+
" scopeType=Tenant,",
|
|
2449
|
+
" tenantId=<login>",
|
|
2450
|
+
" --service <org-svc> scopeType=Organization,",
|
|
2451
|
+
" tenantId=00000000-…",
|
|
2452
|
+
" --service <tenant-svc> scopeType=Tenant (default;",
|
|
2453
|
+
" Project/Folder via --scope),",
|
|
2454
|
+
" tenantId=<login>",
|
|
2455
|
+
"",
|
|
2456
|
+
"Listing works for every service, including services that manage their",
|
|
2457
|
+
"own role catalog (orchestrator, dataservice, insights, taskmining,",
|
|
2458
|
+
"testmanager, automationops, casemanagement, processmining) and",
|
|
2459
|
+
"platform-level services (authz, oms, platform, identity, licensing)",
|
|
2460
|
+
"— only authoring is blocked.",
|
|
2461
|
+
"",
|
|
2462
|
+
"`--filter` is a substring match on role name."
|
|
2463
|
+
].join(`
|
|
2464
|
+
`)).option("--limit <n>", "Page size — maximum number of roles to return.", parseIntOption, 20).option("--offset <n>", "Number of records to skip before the returned page (zero-based).", parseIntOption, 0).option("--filter <fragment>", "Substring filter on role name.").option("--service <service>", "Owning service (e.g. apps, documentunderstanding). Combines with --scope, or sets the scope from the service registry when used alone.").addOption(new Option("--scope <type>", "Filter by role shape: Organization, TenantGlobal, Tenant, Project, or Folder (case-insensitive). Optional when --service is provided (the registry infers the scope).").argParser(canonicalizeRoleListScope)).addOption(new Option("--role-type <type>", "Filter by role type (BuiltIn / Custom).").choices(["BuiltIn", "Custom"])).option("--tenant-id <guid>", "Restrict to roles scoped to a specific tenant UUID. Use `uip admin tenants list --filter <name>` to look up a UUID by name.").examples(LIST_EXAMPLES3)).trackedAction(processContext, async (options) => {
|
|
2465
|
+
const client = await getApi2(options);
|
|
2466
|
+
if (!client)
|
|
2467
|
+
return;
|
|
2468
|
+
const filter = shapeRoleListFilter({
|
|
2469
|
+
scope: options.scope,
|
|
2470
|
+
serviceFlag: options.service,
|
|
2471
|
+
tenantIdFlag: options.tenantId,
|
|
2472
|
+
loginTenantId: client.tenantId
|
|
2473
|
+
});
|
|
2474
|
+
if (filter === null)
|
|
2475
|
+
return;
|
|
2476
|
+
const [error, result] = await catchError(client.api.apiRolesGet({
|
|
2477
|
+
xUipathInternalAccountid: client.organizationId,
|
|
2478
|
+
top: options.limit,
|
|
2479
|
+
skip: options.offset,
|
|
2480
|
+
contains: options.filter,
|
|
2481
|
+
serviceName: filter.serviceName,
|
|
2482
|
+
scopeType: filter.scopeType,
|
|
2483
|
+
roleType: options.roleType,
|
|
2484
|
+
tenantId: filter.tenantId
|
|
2485
|
+
}));
|
|
2486
|
+
if (error) {
|
|
2487
|
+
await emitFailure(error, "Verify the filter values; if --filter contains special characters, quote the value.");
|
|
2488
|
+
return;
|
|
2489
|
+
}
|
|
2490
|
+
OutputFormatter.success({
|
|
2491
|
+
Result: RESULTS.Success,
|
|
2492
|
+
Code: "AuthzRolesList",
|
|
2493
|
+
Data: result
|
|
2494
|
+
});
|
|
2495
|
+
});
|
|
2496
|
+
withLoginValidity(roles.command("get").description("Fetch a single role by id. Built-in roles are read-only and have a fixed id.").argument("<id>", "Role UUID. Obtain from `roles list`.").examples(GET_EXAMPLES)).trackedAction(processContext, async (id, options) => {
|
|
2497
|
+
const client = await getApi2(options);
|
|
2498
|
+
if (!client)
|
|
2499
|
+
return;
|
|
2500
|
+
const [error, result] = await catchError(client.api.apiRolesRoleIdGet({
|
|
2501
|
+
roleId: id,
|
|
2502
|
+
xUipathInternalAccountid: client.organizationId
|
|
2503
|
+
}));
|
|
2504
|
+
if (error) {
|
|
2505
|
+
await emitFailure(error, "Check the role UUID with 'uip admin authorization roles list'.");
|
|
2506
|
+
return;
|
|
2507
|
+
}
|
|
2508
|
+
OutputFormatter.success({
|
|
2509
|
+
Result: RESULTS.Success,
|
|
2510
|
+
Code: "AuthzRoleGet",
|
|
2511
|
+
Data: result
|
|
2512
|
+
});
|
|
2513
|
+
});
|
|
2514
|
+
withLoginValidity(roles.command("create").description([
|
|
2515
|
+
"Create a custom role. The endpoint is a PUT-style upsert; this command",
|
|
2516
|
+
"always creates (the role id is generated server-side). Use",
|
|
2517
|
+
"`roles update <id>` to modify an existing role.",
|
|
2518
|
+
"",
|
|
2519
|
+
"Role identity is supplied via inline flags (--name, --description,",
|
|
2520
|
+
"--service) and the role's granted actions come from --file, which",
|
|
2521
|
+
"must contain a JSON array of action names, e.g.",
|
|
2522
|
+
'`["STUDIO.X.Y", "STUDIO.A.B"]`.',
|
|
2523
|
+
"",
|
|
2524
|
+
"The role's shape comes from `--scope` and/or `--service` (at least",
|
|
2525
|
+
"one is required):",
|
|
2526
|
+
"",
|
|
2527
|
+
" --scope Organization Org-wide role. --tenant-id not",
|
|
2528
|
+
" allowed.",
|
|
2529
|
+
" --scope TenantGlobal Tenant-wide template applied across",
|
|
2530
|
+
" all tenants. --tenant-id not allowed.",
|
|
2531
|
+
" --scope Tenant Tenant-wide role within one tenant.",
|
|
2532
|
+
" --tenant-id selects the tenant",
|
|
2533
|
+
" (defaults to the login tenant).",
|
|
2534
|
+
" --scope Project --service <svc> Project-scoped role for a service",
|
|
2535
|
+
" that registers Project-scope perms",
|
|
2536
|
+
" (e.g. documentunderstanding, reinfer).",
|
|
2537
|
+
" --tenant-id selects the tenant",
|
|
2538
|
+
" (defaults to login).",
|
|
2539
|
+
" --service <svc> Service-specific role. The scope is",
|
|
2540
|
+
" inferred from the service registry —",
|
|
2541
|
+
" tenant-service → Tenant scope,",
|
|
2542
|
+
" org-service → Organization scope.",
|
|
2543
|
+
" Combine with --scope to override.",
|
|
2544
|
+
"",
|
|
2545
|
+
"Examples of the inference (the CLI passes --service through verbatim",
|
|
2546
|
+
"as the roleService — no abbreviation):",
|
|
2547
|
+
" --service apps → Organization scope, roleService=apps",
|
|
2548
|
+
" --service documentunderstanding → Tenant scope, roleService=documentunderstanding",
|
|
2549
|
+
" --scope Project",
|
|
2550
|
+
" --service documentunderstanding → Project scope, roleService=documentunderstanding",
|
|
2551
|
+
"",
|
|
2552
|
+
"When --scope is given without --service, roleService defaults to the",
|
|
2553
|
+
"platform's centralized-access marker (cross-cutting role).",
|
|
2554
|
+
"",
|
|
2555
|
+
"Services that manage their own role catalog (orchestrator, dataservice,",
|
|
2556
|
+
"insights, taskmining, testmanager, automationops, casemanagement,",
|
|
2557
|
+
"processmining) and platform-level services (authz, oms, platform,",
|
|
2558
|
+
"identity, licensing) cannot be used with --service."
|
|
2559
|
+
].join(`
|
|
2560
|
+
`)).requiredOption("--name <name>", "Role display name.").option("--description <text>", "Optional human-readable description of the role.").option("--service <service>", "Owning service (e.g. apps, documentunderstanding). Used alone, infers the scope from the service registry; combine with --scope to override.").requiredOption("--file <path>", `Path to a JSON file containing the role's granted actions as an array of strings, e.g. ["STUDIO.X.Y", "STUDIO.A.B"].`).addOption(new Option("--scope <type>", "Role shape: Organization, TenantGlobal, Tenant, or Project (case-insensitive). Optional when --service is provided (inferred from the service registry).").argParser(canonicalizeRoleAuthoringScope)).option("--tenant-id <guid>", "Tenant UUID. Only valid when the resolved scope is Tenant or Project. Defaults to the login tenant when omitted.").examples(CREATE_EXAMPLES2)).trackedAction(processContext, async (options) => {
|
|
2561
|
+
const client = await getApi2(options);
|
|
2562
|
+
if (!client)
|
|
2563
|
+
return;
|
|
2564
|
+
const shaped = shapeCustomRoleBody({
|
|
2565
|
+
scope: options.scope,
|
|
2566
|
+
serviceFlag: options.service,
|
|
2567
|
+
tenantIdFlag: options.tenantId,
|
|
2568
|
+
loginTenantId: client.tenantId
|
|
2569
|
+
});
|
|
2570
|
+
if (shaped === null)
|
|
2571
|
+
return;
|
|
2572
|
+
const [loadErr, actions] = await loadActionsFile(options.file);
|
|
2573
|
+
if (loadErr) {
|
|
2574
|
+
emitLoadError(loadErr);
|
|
2575
|
+
return;
|
|
2576
|
+
}
|
|
2577
|
+
const requestBody = {
|
|
2578
|
+
roleName: options.name,
|
|
2579
|
+
roleDescription: options.description ?? "",
|
|
2580
|
+
roleService: shaped.roleService,
|
|
2581
|
+
roleScopeType: shaped.roleScopeType,
|
|
2582
|
+
tenantId: shaped.tenantId ?? null,
|
|
2583
|
+
organizationId: client.organizationId,
|
|
2584
|
+
actionsGrantedByRole: actions
|
|
2585
|
+
};
|
|
2586
|
+
const [error, response] = await catchError(client.api.apiRolesPutRaw({
|
|
2587
|
+
xUipathInternalAccountid: client.organizationId,
|
|
2588
|
+
addCustomRoleRequestDto: requestBody
|
|
2589
|
+
}));
|
|
2590
|
+
if (error || !response) {
|
|
2591
|
+
await emitFailure(error ?? new Error("Empty response"), "Verify --file contains a JSON array of action strings, and that --name and --scope are correct.");
|
|
2592
|
+
return;
|
|
2593
|
+
}
|
|
2594
|
+
const responseBody = await extractResponseData(response);
|
|
2595
|
+
OutputFormatter.success({
|
|
2596
|
+
Result: RESULTS.Success,
|
|
2597
|
+
Code: "AuthzRoleCreated",
|
|
2598
|
+
Data: responseBody ?? {}
|
|
2599
|
+
});
|
|
2600
|
+
});
|
|
2601
|
+
withLoginValidity(roles.command("update").description([
|
|
2602
|
+
"Update an existing custom role by id. The endpoint is the same",
|
|
2603
|
+
"PUT-style upsert as `create`; the positional id is sent on the body.",
|
|
2604
|
+
"",
|
|
2605
|
+
"Role identity is supplied via inline flags (--name, --description,",
|
|
2606
|
+
"--service) and the role's granted actions come from --file (a JSON",
|
|
2607
|
+
"array of action names, same shape as `roles create`).",
|
|
2608
|
+
"",
|
|
2609
|
+
"Pass `--scope` and/or `--service` to declare the role's shape after",
|
|
2610
|
+
"the update. The CLI re-derives roleService / roleScopeType / tenantId",
|
|
2611
|
+
"from those flags + the login context using the same matrix as",
|
|
2612
|
+
"`roles create` — see `roles create --help` for the full mapping.",
|
|
2613
|
+
"",
|
|
2614
|
+
"Same authoring restrictions as `create`: --service rejects services",
|
|
2615
|
+
"that manage their own role catalog (orchestrator, dataservice,",
|
|
2616
|
+
"insights, taskmining, testmanager, automationops, casemanagement,",
|
|
2617
|
+
"processmining) and platform-level services (authz, oms, platform,",
|
|
2618
|
+
"identity, licensing)."
|
|
2619
|
+
].join(`
|
|
2620
|
+
`)).argument("<id>", "Role UUID. Obtain from `roles list`.").requiredOption("--name <name>", "Role display name.").option("--description <text>", "Human-readable description of the role. When omitted, the role's current description is preserved (the CLI fetches the role first to read its current value). Pass an empty string to explicitly clear the description.").option("--service <service>", "Owning service (e.g. apps, documentunderstanding). Used alone, infers the scope from the service registry; combine with --scope to override.").requiredOption("--file <path>", `Path to a JSON file containing the role's granted actions as an array of strings, e.g. ["STUDIO.X.Y", "STUDIO.A.B"].`).addOption(new Option("--scope <type>", "Role shape: Organization, TenantGlobal, Tenant, or Project (case-insensitive). Optional when --service is provided.").argParser(canonicalizeRoleAuthoringScope)).option("--tenant-id <guid>", "Tenant UUID. Only valid when the resolved scope is Tenant or Project. Defaults to the login tenant when omitted.").examples(UPDATE_EXAMPLES)).trackedAction(processContext, async (id, options) => {
|
|
2621
|
+
const client = await getApi2(options);
|
|
2622
|
+
if (!client)
|
|
2623
|
+
return;
|
|
2624
|
+
const shaped = shapeCustomRoleBody({
|
|
2625
|
+
scope: options.scope,
|
|
2626
|
+
serviceFlag: options.service,
|
|
2627
|
+
tenantIdFlag: options.tenantId,
|
|
2628
|
+
loginTenantId: client.tenantId
|
|
2629
|
+
});
|
|
2630
|
+
if (shaped === null)
|
|
2631
|
+
return;
|
|
2632
|
+
const [loadErr, actions] = await loadActionsFile(options.file);
|
|
2633
|
+
if (loadErr) {
|
|
2634
|
+
emitLoadError(loadErr);
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2637
|
+
let resolvedDescription;
|
|
2638
|
+
if (options.description !== undefined) {
|
|
2639
|
+
resolvedDescription = options.description;
|
|
2640
|
+
} else {
|
|
2641
|
+
const [fetchErr, role] = await catchError(client.api.apiRolesRoleIdGet({
|
|
2642
|
+
roleId: id,
|
|
2643
|
+
xUipathInternalAccountid: client.organizationId
|
|
2644
|
+
}));
|
|
2645
|
+
if (fetchErr) {
|
|
2646
|
+
await emitFailure(fetchErr, "Check the role UUID with 'uip admin authorization roles list'.");
|
|
2647
|
+
return;
|
|
2648
|
+
}
|
|
2649
|
+
resolvedDescription = role.description;
|
|
2650
|
+
}
|
|
2651
|
+
const [error, response] = await catchError(client.api.apiRolesPutRaw({
|
|
2652
|
+
xUipathInternalAccountid: client.organizationId,
|
|
2653
|
+
addCustomRoleRequestDto: {
|
|
2654
|
+
id,
|
|
2655
|
+
roleName: options.name,
|
|
2656
|
+
roleDescription: resolvedDescription,
|
|
2657
|
+
roleService: shaped.roleService,
|
|
2658
|
+
roleScopeType: shaped.roleScopeType,
|
|
2659
|
+
tenantId: shaped.tenantId ?? null,
|
|
2660
|
+
organizationId: client.organizationId,
|
|
2661
|
+
actionsGrantedByRole: actions
|
|
2662
|
+
}
|
|
2663
|
+
}));
|
|
2664
|
+
if (error || !response) {
|
|
2665
|
+
await emitFailure(error ?? new Error("Empty response"), "Verify the role UUID and that --file contains a JSON array of action strings.");
|
|
2666
|
+
return;
|
|
2667
|
+
}
|
|
2668
|
+
const responseBody = await extractResponseData(response);
|
|
2669
|
+
OutputFormatter.success({
|
|
2670
|
+
Result: RESULTS.Success,
|
|
2671
|
+
Code: "AuthzRoleUpdated",
|
|
2672
|
+
Data: responseBody ?? {}
|
|
2673
|
+
});
|
|
2674
|
+
});
|
|
2675
|
+
withLoginValidity(roles.command("delete").description([
|
|
2676
|
+
"Delete a custom role by id. Built-in and host-organization roles",
|
|
2677
|
+
"cannot be deleted; nor can roles owned by their originating service",
|
|
2678
|
+
"or by platform-level services (the CLI pre-fetches the role and",
|
|
2679
|
+
"refuses with a redirect)."
|
|
2680
|
+
].join(`
|
|
2681
|
+
`)).argument("<id>", "Role UUID. Obtain from `roles list`.").examples(DELETE_EXAMPLES2)).trackedAction(processContext, async (id, options) => {
|
|
2682
|
+
const client = await getApi2(options);
|
|
2683
|
+
if (!client)
|
|
2684
|
+
return;
|
|
2685
|
+
const [fetchErr, role] = await catchError(client.api.apiRolesRoleIdGet({
|
|
2686
|
+
roleId: id,
|
|
2687
|
+
xUipathInternalAccountid: client.organizationId
|
|
2688
|
+
}));
|
|
2689
|
+
if (fetchErr) {
|
|
2690
|
+
await emitFailure(fetchErr, "Check the role UUID with 'uip admin authorization roles list'.");
|
|
2691
|
+
return;
|
|
2692
|
+
}
|
|
2693
|
+
const ownerServiceName = role.ownerServiceName;
|
|
2694
|
+
const owningService = typeof ownerServiceName === "string" && ownerServiceName.length > 0 ? ownerServiceName : inferRoleService(role);
|
|
2695
|
+
if (rejectIfRoleAuthoringBlocked(owningService, "delete"))
|
|
2696
|
+
return;
|
|
2697
|
+
const [error, response] = await catchError(client.api.apiRolesRoleIdDeleteRaw({
|
|
2698
|
+
roleId: id,
|
|
2699
|
+
xUipathInternalAccountid: client.organizationId
|
|
2700
|
+
}));
|
|
2701
|
+
if (error || !response) {
|
|
2702
|
+
await emitFailure(error ?? new Error("Empty response"), "Check the role UUID with 'uip admin authorization roles list'.");
|
|
2703
|
+
return;
|
|
2704
|
+
}
|
|
2705
|
+
const responseBody = await extractResponseData(response);
|
|
2706
|
+
OutputFormatter.success({
|
|
2707
|
+
Result: RESULTS.Success,
|
|
2708
|
+
Code: "AuthzRoleDeleted",
|
|
2709
|
+
Data: responseBody ?? {}
|
|
2710
|
+
});
|
|
2711
|
+
});
|
|
2712
|
+
registerAssignmentsCommands(roles);
|
|
2713
|
+
};
|
|
2714
|
+
|
|
2715
|
+
// ../authz-commands/src/commands/authz.ts
|
|
2716
|
+
var registerAuthzCommands = (program) => {
|
|
2717
|
+
const authorization = program.command("authorization").description([
|
|
2718
|
+
"Manage UiPath Authorization-service primitives (roles, role assignments,",
|
|
2719
|
+
"permissions catalog, and effective-access lookups).",
|
|
2720
|
+
"",
|
|
2721
|
+
"Subcommand groups:",
|
|
2722
|
+
" roles — custom role CRUD plus nested `assignments` (PAP).",
|
|
2723
|
+
" permissions — read-only catalog of permission definitions.",
|
|
2724
|
+
" check-access — compute effective permissions for a principal (PDP)."
|
|
2725
|
+
].join(`
|
|
2726
|
+
`));
|
|
2727
|
+
registerRolesCommands(authorization);
|
|
2728
|
+
registerPermissionsCommands(authorization);
|
|
2729
|
+
registerCheckAccessCommand(authorization);
|
|
2730
|
+
};
|
|
2731
|
+
|
|
2732
|
+
// ../authz-commands/src/index.ts
|
|
2733
|
+
var registerCommands = async (program) => {
|
|
2734
|
+
registerAuthzCommands(program);
|
|
2735
|
+
};
|
|
2736
|
+
export {
|
|
2737
|
+
registerCommands
|
|
2738
|
+
};
|
|
2739
|
+
|
|
2740
|
+
//# debugId=BC57231B618E4E9864756E2164756E21
|