@izara_project/izara-core-generate-service-code 1.0.85 → 1.0.87
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/package.json +1 -1
- package/src/compile/compileProject.js +1 -2
- package/src/compile/loadSchemas.js +29 -17
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +2 -1
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +32 -14
- package/src/emit/crud/crudActionPlan.js +1 -1
- package/src/emit/crud/emitCrudApplicationArtifacts.js +10 -4
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +16 -8
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +12 -3
- package/src/emit/crud/templates/CreateLogicalLib.ejs +85 -20
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +48 -7
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +47 -6
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +754 -353
- package/src/emit/function/functionYamlArtifact.js +4 -2
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +5 -5
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +70 -89
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +14 -10
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +14 -10
- package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +56 -16
- package/src/emit/rbac/templates/DeleteTargetRole_Main.ejs +96 -0
- package/src/emit/rbac/templates/GetMyPermissions_Main.ejs +110 -0
- package/src/emit/rbac/templates/GetTargetRole_Main.ejs +62 -0
- package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +76 -34
- package/src/emit/rbac/templates/UpdateTargetRole_Main.ejs +107 -0
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +24 -21
- package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +12 -0
- package/src/emit/resource/emitResourceArtifacts.js +75 -8
- package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +4 -2
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +14 -18
- package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +4 -2
- package/src/emit/systemText/emitSystemTextSchemas.js +5 -2
- package/src/generate.js +18 -12
- package/src/generateResources/IntTest/generateResources/generateResources.js +1 -1
- package/src/generateResources/IntTest/generateTests/generateTemplate.js +1 -1
- package/src/generateResources/IntTest/upload/uploadIntTest.js +8 -2
- package/test/createTargetRoleHandler.test.js +42 -15
- package/test/crudApplicationArtifacts.test.js +62 -3
- package/test/customFlowApplicationArtifacts.test.js +3 -5
- package/test/dynamicCrudFlowSchemas.test.js +5 -17
- package/test/dynamicRbacFlowSchemas.test.js +5 -5
- package/test/functionYamlArtifact.test.js +4 -2
- package/test/publicApi.test.js +18 -14
- package/test/resourceArtifacts.test.js +7 -3
|
@@ -319,8 +319,10 @@ function _sqsFilterPatterns(
|
|
|
319
319
|
- body:
|
|
320
320
|
MessageAttributes:
|
|
321
321
|
callingFlow:
|
|
322
|
-
|
|
323
|
-
|
|
322
|
+
- exists: false
|
|
323
|
+
- body:
|
|
324
|
+
MessageAttributes:
|
|
325
|
+
- exists: false
|
|
324
326
|
#<#/${hookFunctionName}FilterPatterns#>
|
|
325
327
|
`;
|
|
326
328
|
}
|
|
@@ -4,20 +4,20 @@ import { rbacFlowTag } from './rbacFlowTag.js';
|
|
|
4
4
|
|
|
5
5
|
const RBAC_CORE_FLOW_DEFINITIONS = [
|
|
6
6
|
{ flowTag: 'CreateTargetRole', event: ['ownTopic'] },
|
|
7
|
-
{ flowTag: '
|
|
7
|
+
{ flowTag: 'UpdateTargetRole', event: ['ownTopic'] },
|
|
8
8
|
{ flowTag: 'DeleteTargetRole', event: ['ownTopic'] },
|
|
9
|
+
{ flowTag: 'GetTargetRole', event: ['lambdaSyncApi'] },
|
|
10
|
+
{ flowTag: 'ListTargetRole', event: ['lambdaSyncApi'] },
|
|
9
11
|
{ flowTag: 'CreateRolePermissions', event: ['ownTopic'] },
|
|
10
12
|
{ flowTag: 'ListRolePermissions', event: ['lambdaSyncApi'] },
|
|
11
13
|
{ flowTag: 'DeleteRolePermissions', event: ['ownTopic'] },
|
|
12
14
|
{ flowTag: 'CreateUserRole', event: ['ownTopic'] },
|
|
13
15
|
{ flowTag: 'ListUserInRoles', event: ['lambdaSyncApi'] },
|
|
14
|
-
{ flowTag: 'DeleteUserFromRole', event: ['ownTopic'] }
|
|
16
|
+
{ flowTag: 'DeleteUserFromRole', event: ['ownTopic'] },
|
|
17
|
+
{ flowTag: 'GetMyPermissions', event: ['lambdaSyncApi'] }
|
|
15
18
|
];
|
|
16
19
|
|
|
17
20
|
const LIMIT_FLOW_DEFINITIONS = [
|
|
18
|
-
{ flowTag: 'CreateRoleLimit', event: ['ownTopic'] },
|
|
19
|
-
{ flowTag: 'ListRoleLimits', event: ['lambdaSyncApi'] },
|
|
20
|
-
{ flowTag: 'DeleteRoleLimit', event: ['ownTopic'] },
|
|
21
21
|
{ flowTag: 'ReservedDynamicUsage', event: ['ownTopic'] },
|
|
22
22
|
{ flowTag: 'ConfirmUsage', event: ['ownTopic'] },
|
|
23
23
|
{ flowTag: 'CancelUsage', event: ['ownTopic'] }
|
|
@@ -29,6 +29,19 @@ export async function emitRbacApplicationArtifacts(objects) {
|
|
|
29
29
|
...(hasSelfRbac
|
|
30
30
|
? [
|
|
31
31
|
createTargetRoleHandler(),
|
|
32
|
+
createCustomRbacOwnTopicHandler(
|
|
33
|
+
'UpdateTargetRole',
|
|
34
|
+
'UpdateTargetRole_Main.ejs'
|
|
35
|
+
),
|
|
36
|
+
createCustomRbacOwnTopicHandler(
|
|
37
|
+
'DeleteTargetRole',
|
|
38
|
+
'DeleteTargetRole_Main.ejs'
|
|
39
|
+
),
|
|
40
|
+
createCustomRbacApiHandler('GetTargetRole', 'GetTargetRole_Main.ejs'),
|
|
41
|
+
createCustomRbacApiHandler(
|
|
42
|
+
'GetMyPermissions',
|
|
43
|
+
'GetMyPermissions_Main.ejs'
|
|
44
|
+
),
|
|
32
45
|
...LIST_DEFINITIONS.map(createListHandler),
|
|
33
46
|
...MUTATION_DEFINITIONS.map(createMutationHandler),
|
|
34
47
|
...USER_ROLE_MUTATIONS.map(createUserRoleMutationHandler)
|
|
@@ -39,11 +52,7 @@ export async function emitRbacApplicationArtifacts(objects) {
|
|
|
39
52
|
|
|
40
53
|
const limitHandlers = await Promise.all(
|
|
41
54
|
hasSelfRbac
|
|
42
|
-
?
|
|
43
|
-
...LIMIT_LIST_DEFINITIONS.map(createLimitListHandler),
|
|
44
|
-
...LIMIT_MUTATION_DEFINITIONS.map(createLimitMutationHandler),
|
|
45
|
-
...ACCOUNT_LIMIT_HANDLERS.map(createAccountLimitHandler)
|
|
46
|
-
]
|
|
55
|
+
? ACCOUNT_LIMIT_HANDLERS.map(createAccountLimitHandler)
|
|
47
56
|
: []
|
|
48
57
|
);
|
|
49
58
|
|
|
@@ -91,14 +100,6 @@ const LIST_DEFINITIONS = [
|
|
|
91
100
|
}
|
|
92
101
|
];
|
|
93
102
|
|
|
94
|
-
const LIMIT_LIST_DEFINITIONS = [
|
|
95
|
-
{
|
|
96
|
-
flowTag: 'ListRoleLimits',
|
|
97
|
-
tableName: 'RoleLimit',
|
|
98
|
-
requestProperty: 'roleLimitId'
|
|
99
|
-
}
|
|
100
|
-
];
|
|
101
|
-
|
|
102
103
|
const MUTATION_DEFINITIONS = [
|
|
103
104
|
{
|
|
104
105
|
flowTag: 'CreateRolePermissions',
|
|
@@ -111,27 +112,6 @@ const MUTATION_DEFINITIONS = [
|
|
|
111
112
|
tableName: 'RolePermissions',
|
|
112
113
|
method: 'deleteItem',
|
|
113
114
|
fields: ['roleIdKey', 'flowTypeConcat']
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
flowTag: 'DeleteTargetRole',
|
|
117
|
-
tableName: 'TargetRoles',
|
|
118
|
-
method: 'deleteItem',
|
|
119
|
-
fields: ['identifiersConcat', 'roleIdKey']
|
|
120
|
-
}
|
|
121
|
-
];
|
|
122
|
-
|
|
123
|
-
const LIMIT_MUTATION_DEFINITIONS = [
|
|
124
|
-
{
|
|
125
|
-
flowTag: 'CreateRoleLimit',
|
|
126
|
-
tableName: 'RoleLimit',
|
|
127
|
-
method: 'putItem',
|
|
128
|
-
fields: ['roleLimitId', 'limitType', 'limitValue', 'actionType']
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
flowTag: 'DeleteRoleLimit',
|
|
132
|
-
tableName: 'RoleLimit',
|
|
133
|
-
method: 'deleteItem',
|
|
134
|
-
fields: ['roleLimitId', 'limitType']
|
|
135
115
|
}
|
|
136
116
|
];
|
|
137
117
|
|
|
@@ -151,6 +131,20 @@ const STATIC_RBAC_APPLICATION_PATHS = [
|
|
|
151
131
|
'app/src/generatedCode/FlowRbac/CreateTargetRole/source/CreateTargetRole_HdrSqs.js',
|
|
152
132
|
'app/src/generatedCode/FlowRbac/CreateTargetRole/source/CreateTargetRole_WbsMain.js',
|
|
153
133
|
'app/src/generatedCode/FlowRbac/CreateTargetRole/source/CreateTargetRole_HdrWbs.js',
|
|
134
|
+
'app/src/generatedCode/FlowRbac/UpdateTargetRole/source/UpdateTargetRole_Main.js',
|
|
135
|
+
'app/src/generatedCode/FlowRbac/UpdateTargetRole/source/UpdateTargetRole_HdrSqs.js',
|
|
136
|
+
'app/src/generatedCode/FlowRbac/UpdateTargetRole/source/UpdateTargetRole_WbsMain.js',
|
|
137
|
+
'app/src/generatedCode/FlowRbac/UpdateTargetRole/source/UpdateTargetRole_HdrWbs.js',
|
|
138
|
+
'app/src/generatedCode/FlowRbac/DeleteTargetRole/source/DeleteTargetRole_Main.js',
|
|
139
|
+
'app/src/generatedCode/FlowRbac/DeleteTargetRole/source/DeleteTargetRole_HdrSqs.js',
|
|
140
|
+
'app/src/generatedCode/FlowRbac/DeleteTargetRole/source/DeleteTargetRole_WbsMain.js',
|
|
141
|
+
'app/src/generatedCode/FlowRbac/DeleteTargetRole/source/DeleteTargetRole_HdrWbs.js',
|
|
142
|
+
'app/src/generatedCode/FlowRbac/GetTargetRole/source/GetTargetRole_Main.js',
|
|
143
|
+
'app/src/generatedCode/FlowRbac/GetTargetRole/source/GetTargetRole_HdrSqs.js',
|
|
144
|
+
'app/src/generatedCode/FlowRbac/GetTargetRole/source/GetTargetRole_HdrApi.js',
|
|
145
|
+
'app/src/generatedCode/FlowRbac/GetMyPermissions/source/GetMyPermissions_Main.js',
|
|
146
|
+
'app/src/generatedCode/FlowRbac/GetMyPermissions/source/GetMyPermissions_HdrSqs.js',
|
|
147
|
+
'app/src/generatedCode/FlowRbac/GetMyPermissions/source/GetMyPermissions_HdrApi.js',
|
|
154
148
|
'app/src/generatedCode/FlowRbac/ValidatorRbac/source/ValidatorRbac_Main.js',
|
|
155
149
|
'app/src/generatedCode/FlowRbac/ValidatorRbac/source/ValidatorRbac_HdrSqs.js',
|
|
156
150
|
'app/src/generatedCode/FlowRbac/ValidatorRbac/source/ValidatorRbac_WbsMain.js',
|
|
@@ -176,17 +170,6 @@ const STATIC_RBAC_APPLICATION_PATHS = [
|
|
|
176
170
|
];
|
|
177
171
|
|
|
178
172
|
const STATIC_LIMIT_APPLICATION_PATHS = [
|
|
179
|
-
...LIMIT_LIST_DEFINITIONS.flatMap(({ flowTag }) => [
|
|
180
|
-
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_Main.js`,
|
|
181
|
-
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrSqs.js`,
|
|
182
|
-
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrApi.js`
|
|
183
|
-
]),
|
|
184
|
-
...LIMIT_MUTATION_DEFINITIONS.flatMap(({ flowTag }) => [
|
|
185
|
-
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_Main.js`,
|
|
186
|
-
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrSqs.js`,
|
|
187
|
-
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_WbsMain.js`,
|
|
188
|
-
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrWbs.js`
|
|
189
|
-
]),
|
|
190
173
|
...ACCOUNT_LIMIT_HANDLERS.flatMap((flowTag) => [
|
|
191
174
|
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_Main.js`,
|
|
192
175
|
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrSqs.js`,
|
|
@@ -253,80 +236,78 @@ async function createAccountLimitHandler(flowTag) {
|
|
|
253
236
|
};
|
|
254
237
|
}
|
|
255
238
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const
|
|
239
|
+
|
|
240
|
+
async function createCustomRbacOwnTopicHandler(flowTag, mainTemplateName) {
|
|
241
|
+
const sourcePath = `app/src/generatedCode/FlowRbac/${flowTag}/source`;
|
|
242
|
+
const handlerPath = `src/generatedCode/FlowRbac/${flowTag}/source`;
|
|
243
|
+
const webSocket = await createWebSocketEntry(
|
|
244
|
+
flowTag,
|
|
245
|
+
sourcePath,
|
|
246
|
+
handlerPath
|
|
247
|
+
);
|
|
259
248
|
return {
|
|
260
249
|
artifacts: [
|
|
261
250
|
{
|
|
262
|
-
path: `${sourcePath}/${
|
|
263
|
-
content: await renderRbacTemplate(
|
|
264
|
-
...definition,
|
|
265
|
-
useContextUserId: definition.useContextUserId ?? false
|
|
266
|
-
})
|
|
251
|
+
path: `${sourcePath}/${flowTag}_Main.js`,
|
|
252
|
+
content: await renderRbacTemplate(mainTemplateName, { flowTag })
|
|
267
253
|
},
|
|
268
254
|
{
|
|
269
|
-
path: `${sourcePath}/${
|
|
270
|
-
content: await renderRbacTemplate('ListRbac_HdrSqs.ejs',
|
|
255
|
+
path: `${sourcePath}/${flowTag}_HdrSqs.js`,
|
|
256
|
+
content: await renderRbacTemplate('ListRbac_HdrSqs.ejs', { flowTag })
|
|
271
257
|
},
|
|
272
|
-
|
|
273
|
-
path: `${sourcePath}/${definition.flowTag}_HdrApi.js`,
|
|
274
|
-
content: await renderRbacTemplate('ListRbac_HdrApi.ejs', definition)
|
|
275
|
-
}
|
|
258
|
+
...webSocket.artifacts
|
|
276
259
|
],
|
|
277
260
|
functions: [
|
|
278
261
|
{
|
|
279
262
|
type: 'sqs',
|
|
280
|
-
functionName: `${
|
|
281
|
-
handlerPath: `${handlerPath}/${
|
|
263
|
+
functionName: `${flowTag}HdrSqs`,
|
|
264
|
+
handlerPath: `${handlerPath}/${flowTag}_HdrSqs.main`,
|
|
282
265
|
roleName: 'FlowRbacRole',
|
|
283
|
-
queueName: `${
|
|
284
|
-
flowTag:
|
|
266
|
+
queueName: `${flowTag}HdrSqs`,
|
|
267
|
+
flowTag: flowTag,
|
|
285
268
|
flowStepName: ''
|
|
286
269
|
},
|
|
287
|
-
|
|
288
|
-
type: 'api',
|
|
289
|
-
functionName: `${definition.flowTag}HdrApi`,
|
|
290
|
-
handlerPath: `${handlerPath}/${definition.flowTag}_HdrApi.main`,
|
|
291
|
-
roleName: 'FlowRbacRole',
|
|
292
|
-
flowTag: definition.flowTag,
|
|
293
|
-
flowStepName: ''
|
|
294
|
-
}
|
|
270
|
+
...webSocket.functions
|
|
295
271
|
]
|
|
296
272
|
};
|
|
297
273
|
}
|
|
298
274
|
|
|
299
|
-
async function
|
|
300
|
-
const sourcePath = `app/src/generatedCode/
|
|
301
|
-
const handlerPath = `src/generatedCode/
|
|
302
|
-
const webSocket = await createWebSocketEntry(
|
|
303
|
-
definition.flowTag,
|
|
304
|
-
sourcePath,
|
|
305
|
-
handlerPath
|
|
306
|
-
);
|
|
275
|
+
async function createCustomRbacApiHandler(flowTag, mainTemplateName) {
|
|
276
|
+
const sourcePath = `app/src/generatedCode/FlowRbac/${flowTag}/source`;
|
|
277
|
+
const handlerPath = `src/generatedCode/FlowRbac/${flowTag}/source`;
|
|
307
278
|
return {
|
|
308
279
|
artifacts: [
|
|
309
280
|
{
|
|
310
|
-
path: `${sourcePath}/${
|
|
311
|
-
content: await renderRbacTemplate(
|
|
281
|
+
path: `${sourcePath}/${flowTag}_Main.js`,
|
|
282
|
+
content: await renderRbacTemplate(mainTemplateName, { flowTag })
|
|
312
283
|
},
|
|
313
284
|
{
|
|
314
|
-
path: `${sourcePath}/${
|
|
315
|
-
content: await renderRbacTemplate('ListRbac_HdrSqs.ejs',
|
|
285
|
+
path: `${sourcePath}/${flowTag}_HdrSqs.js`,
|
|
286
|
+
content: await renderRbacTemplate('ListRbac_HdrSqs.ejs', { flowTag })
|
|
316
287
|
},
|
|
317
|
-
|
|
288
|
+
{
|
|
289
|
+
path: `${sourcePath}/${flowTag}_HdrApi.js`,
|
|
290
|
+
content: await renderRbacTemplate('ListRbac_HdrApi.ejs', { flowTag })
|
|
291
|
+
}
|
|
318
292
|
],
|
|
319
293
|
functions: [
|
|
320
294
|
{
|
|
321
295
|
type: 'sqs',
|
|
322
|
-
functionName: `${
|
|
323
|
-
handlerPath: `${handlerPath}/${
|
|
296
|
+
functionName: `${flowTag}HdrSqs`,
|
|
297
|
+
handlerPath: `${handlerPath}/${flowTag}_HdrSqs.main`,
|
|
324
298
|
roleName: 'FlowRbacRole',
|
|
325
|
-
queueName: `${
|
|
326
|
-
flowTag:
|
|
299
|
+
queueName: `${flowTag}HdrSqs`,
|
|
300
|
+
flowTag: flowTag,
|
|
327
301
|
flowStepName: ''
|
|
328
302
|
},
|
|
329
|
-
|
|
303
|
+
{
|
|
304
|
+
type: 'api',
|
|
305
|
+
functionName: `${flowTag}HdrApi`,
|
|
306
|
+
handlerPath: `${handlerPath}/${flowTag}_HdrApi.main`,
|
|
307
|
+
roleName: 'FlowRbacRole',
|
|
308
|
+
flowTag: flowTag,
|
|
309
|
+
flowStepName: ''
|
|
310
|
+
}
|
|
330
311
|
]
|
|
331
312
|
};
|
|
332
313
|
}
|
|
@@ -39,21 +39,25 @@ export default async function CancelUsage(_izContext, requestParams) {
|
|
|
39
39
|
requestParams?.limitTag;
|
|
40
40
|
|
|
41
41
|
const targetIdentifiers = requestParams?.targetIdentifiers;
|
|
42
|
-
let identifiersConcat =
|
|
42
|
+
let identifiersConcat =
|
|
43
|
+
requestParams?.identifiersConcat || requestParams?.identifierConcat;
|
|
43
44
|
if (!identifiersConcat && targetIdentifiers && typeof targetIdentifiers === 'object') {
|
|
44
|
-
if (targetIdentifiers.identifierConcat) {
|
|
45
|
-
identifiersConcat =
|
|
45
|
+
if (targetIdentifiers.identifiersConcat || targetIdentifiers.identifierConcat) {
|
|
46
|
+
identifiersConcat =
|
|
47
|
+
targetIdentifiers.identifiersConcat || targetIdentifiers.identifierConcat;
|
|
46
48
|
} else {
|
|
47
|
-
const sortedKeys = Object.keys(targetIdentifiers)
|
|
49
|
+
const sortedKeys = Object.keys(targetIdentifiers)
|
|
50
|
+
.filter(
|
|
51
|
+
(k) =>
|
|
52
|
+
k !== 'submittedByUserId' &&
|
|
53
|
+
k !== 'identifierConcat' &&
|
|
54
|
+
k !== 'identifiersConcat'
|
|
55
|
+
)
|
|
56
|
+
.sort();
|
|
48
57
|
const parts = [];
|
|
49
58
|
for (const key of sortedKeys) {
|
|
50
59
|
const value = targetIdentifiers[key];
|
|
51
|
-
if (
|
|
52
|
-
key !== 'submittedByUserId' &&
|
|
53
|
-
key !== 'identifierConcat' &&
|
|
54
|
-
value !== undefined &&
|
|
55
|
-
value !== null
|
|
56
|
-
) {
|
|
60
|
+
if (value !== undefined && value !== null) {
|
|
57
61
|
parts.push(`${key}#${value}`);
|
|
58
62
|
}
|
|
59
63
|
}
|
|
@@ -39,21 +39,25 @@ export default async function ConfirmUsage(_izContext, requestParams) {
|
|
|
39
39
|
requestParams?.limitTag;
|
|
40
40
|
|
|
41
41
|
const targetIdentifiers = requestParams?.targetIdentifiers;
|
|
42
|
-
let identifiersConcat =
|
|
42
|
+
let identifiersConcat =
|
|
43
|
+
requestParams?.identifiersConcat || requestParams?.identifierConcat;
|
|
43
44
|
if (!identifiersConcat && targetIdentifiers && typeof targetIdentifiers === 'object') {
|
|
44
|
-
if (targetIdentifiers.identifierConcat) {
|
|
45
|
-
identifiersConcat =
|
|
45
|
+
if (targetIdentifiers.identifiersConcat || targetIdentifiers.identifierConcat) {
|
|
46
|
+
identifiersConcat =
|
|
47
|
+
targetIdentifiers.identifiersConcat || targetIdentifiers.identifierConcat;
|
|
46
48
|
} else {
|
|
47
|
-
const sortedKeys = Object.keys(targetIdentifiers)
|
|
49
|
+
const sortedKeys = Object.keys(targetIdentifiers)
|
|
50
|
+
.filter(
|
|
51
|
+
(k) =>
|
|
52
|
+
k !== 'submittedByUserId' &&
|
|
53
|
+
k !== 'identifierConcat' &&
|
|
54
|
+
k !== 'identifiersConcat'
|
|
55
|
+
)
|
|
56
|
+
.sort();
|
|
48
57
|
const parts = [];
|
|
49
58
|
for (const key of sortedKeys) {
|
|
50
59
|
const value = targetIdentifiers[key];
|
|
51
|
-
if (
|
|
52
|
-
key !== 'submittedByUserId' &&
|
|
53
|
-
key !== 'identifierConcat' &&
|
|
54
|
-
value !== undefined &&
|
|
55
|
-
value !== null
|
|
56
|
-
) {
|
|
60
|
+
if (value !== undefined && value !== null) {
|
|
57
61
|
parts.push(`${key}#${value}`);
|
|
58
62
|
}
|
|
59
63
|
}
|
|
@@ -28,21 +28,25 @@ export default async function CreateTargetRole(_izContext, requestParams) {
|
|
|
28
28
|
_izContext.correlationIds?.get(consts.SUBMITTED_BY_USER_ID);
|
|
29
29
|
|
|
30
30
|
const targetIdentifiers = requestParams.targetIdentifiers;
|
|
31
|
-
let identifiersConcat =
|
|
31
|
+
let identifiersConcat =
|
|
32
|
+
requestParams.identifiersConcat || requestParams.identifierConcat;
|
|
32
33
|
if (!identifiersConcat && targetIdentifiers && typeof targetIdentifiers === 'object') {
|
|
33
|
-
if (targetIdentifiers.identifierConcat) {
|
|
34
|
-
identifiersConcat =
|
|
34
|
+
if (targetIdentifiers.identifiersConcat || targetIdentifiers.identifierConcat) {
|
|
35
|
+
identifiersConcat =
|
|
36
|
+
targetIdentifiers.identifiersConcat || targetIdentifiers.identifierConcat;
|
|
35
37
|
} else {
|
|
36
|
-
const sortedKeys = Object.keys(targetIdentifiers)
|
|
38
|
+
const sortedKeys = Object.keys(targetIdentifiers)
|
|
39
|
+
.filter(
|
|
40
|
+
(k) =>
|
|
41
|
+
k !== 'submittedByUserId' &&
|
|
42
|
+
k !== 'identifierConcat' &&
|
|
43
|
+
k !== 'identifiersConcat'
|
|
44
|
+
)
|
|
45
|
+
.sort();
|
|
37
46
|
const parts = [];
|
|
38
47
|
for (const key of sortedKeys) {
|
|
39
48
|
const value = targetIdentifiers[key];
|
|
40
|
-
if (
|
|
41
|
-
key !== 'submittedByUserId' &&
|
|
42
|
-
key !== 'identifierConcat' &&
|
|
43
|
-
value !== undefined &&
|
|
44
|
-
value !== null
|
|
45
|
-
) {
|
|
49
|
+
if (value !== undefined && value !== null) {
|
|
46
50
|
parts.push(`${key}#${value}`);
|
|
47
51
|
}
|
|
48
52
|
}
|
|
@@ -55,8 +59,17 @@ export default async function CreateTargetRole(_izContext, requestParams) {
|
|
|
55
59
|
identifiersConcat = submittedByUserId;
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
const {
|
|
59
|
-
|
|
62
|
+
const {
|
|
63
|
+
roleName = 'owner',
|
|
64
|
+
roleId: inputRoleId,
|
|
65
|
+
permissions = [],
|
|
66
|
+
assignUserIds = []
|
|
67
|
+
} = requestParams;
|
|
68
|
+
let defaultRoleId = identifierUuid();
|
|
69
|
+
if (roleName === 'owner') {
|
|
70
|
+
defaultRoleId = 'owner';
|
|
71
|
+
}
|
|
72
|
+
const roleId = inputRoleId || defaultRoleId;
|
|
60
73
|
const roleIdKey = `${identifiersConcat}_${roleId}`;
|
|
61
74
|
|
|
62
75
|
await dynamodbSharedLib.putItem(
|
|
@@ -65,26 +78,53 @@ export default async function CreateTargetRole(_izContext, requestParams) {
|
|
|
65
78
|
{
|
|
66
79
|
identifiersConcat,
|
|
67
80
|
roleIdKey,
|
|
81
|
+
roleType: 'tenant_role',
|
|
68
82
|
roleName,
|
|
69
|
-
submittedByUserId
|
|
83
|
+
submittedByUserId,
|
|
84
|
+
createdAt: new Date().toISOString()
|
|
70
85
|
}
|
|
71
86
|
);
|
|
72
87
|
|
|
73
|
-
if (
|
|
88
|
+
if (Array.isArray(permissions) && permissions.length > 0) {
|
|
89
|
+
const rolePermissionsTable = dynamodbSharedLib.tableName(_izContext, 'RolePermissions');
|
|
90
|
+
for (const perm of permissions) {
|
|
91
|
+
const flowTypeConcat = typeof perm === 'string' ? perm : perm.flowTypeConcat;
|
|
92
|
+
if (flowTypeConcat) {
|
|
93
|
+
const permission =
|
|
94
|
+
typeof perm === 'object' && perm.permission !== undefined
|
|
95
|
+
? perm.permission
|
|
96
|
+
: true;
|
|
97
|
+
const parameterGroups = (typeof perm === 'object' && perm.parameterGroups) || {};
|
|
98
|
+
await dynamodbSharedLib.putItem(_izContext, rolePermissionsTable, {
|
|
99
|
+
roleIdKey,
|
|
100
|
+
flowTypeConcat,
|
|
101
|
+
permission,
|
|
102
|
+
parameterGroups
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const usersToAssign =
|
|
109
|
+
Array.isArray(assignUserIds) && assignUserIds.length > 0
|
|
110
|
+
? assignUserIds
|
|
111
|
+
: (roleName === 'owner' && submittedByUserId ? [submittedByUserId] : []);
|
|
112
|
+
|
|
113
|
+
for (const userId of usersToAssign) {
|
|
74
114
|
try {
|
|
75
115
|
await dynamodbSharedLib.transactWriteItems(_izContext, [
|
|
76
116
|
{
|
|
77
117
|
action: 'put',
|
|
78
118
|
params: {
|
|
79
119
|
tableName: dynamodbSharedLib.tableName(_izContext, 'RoleUsers'),
|
|
80
|
-
attributes: { roleIdKey, submittedByUserId }
|
|
120
|
+
attributes: { roleIdKey, userId, submittedByUserId }
|
|
81
121
|
}
|
|
82
122
|
},
|
|
83
123
|
{
|
|
84
124
|
action: 'put',
|
|
85
125
|
params: {
|
|
86
126
|
tableName: dynamodbSharedLib.tableName(_izContext, 'UserRoles'),
|
|
87
|
-
attributes: {
|
|
127
|
+
attributes: { userId, roleIdKey, submittedByUserId }
|
|
88
128
|
}
|
|
89
129
|
}
|
|
90
130
|
]);
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2020 Sven Mason <http://izara.io>
|
|
3
|
+
|
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU Affero General Public License as
|
|
6
|
+
published by the Free Software Foundation, either version 3 of the
|
|
7
|
+
License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU Affero General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
|
|
19
|
+
import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
20
|
+
import { sns } from '@izara_project/izara-core-library-external-request';
|
|
21
|
+
import { NoRetryError } from '@izara_project/izara-core-library-core';
|
|
22
|
+
|
|
23
|
+
export default async function DeleteTargetRole(_izContext, requestParams) {
|
|
24
|
+
try {
|
|
25
|
+
const { identifiersConcat, roleIdKey } = requestParams;
|
|
26
|
+
if (!roleIdKey) {
|
|
27
|
+
throw new NoRetryError('roleIdKey is required');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (roleIdKey.endsWith('_owner')) {
|
|
31
|
+
throw new NoRetryError('Cannot delete system owner role');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const targetRolesTable = dynamodbSharedLib.tableName(_izContext, 'TargetRoles');
|
|
35
|
+
const rolePermissionsTable = dynamodbSharedLib.tableName(_izContext, 'RolePermissions');
|
|
36
|
+
const roleUsersTable = dynamodbSharedLib.tableName(_izContext, 'RoleUsers');
|
|
37
|
+
const userRolesTable = dynamodbSharedLib.tableName(_izContext, 'UserRoles');
|
|
38
|
+
|
|
39
|
+
// 1. Delete from TargetRoles
|
|
40
|
+
await dynamodbSharedLib.deleteItem(
|
|
41
|
+
_izContext,
|
|
42
|
+
targetRolesTable,
|
|
43
|
+
{ identifiersConcat, roleIdKey }
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// 2. Cascade delete all permissions for this roleIdKey
|
|
47
|
+
const permsResult = await dynamodbSharedLib.query(_izContext, rolePermissionsTable, {
|
|
48
|
+
roleIdKey
|
|
49
|
+
});
|
|
50
|
+
for (const perm of (permsResult?.Items || [])) {
|
|
51
|
+
await dynamodbSharedLib.deleteItem(_izContext, rolePermissionsTable, {
|
|
52
|
+
roleIdKey,
|
|
53
|
+
flowTypeConcat: perm.flowTypeConcat
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 3. Cascade delete user assignments in RoleUsers and UserRoles
|
|
58
|
+
const usersResult = await dynamodbSharedLib.query(_izContext, roleUsersTable, {
|
|
59
|
+
roleIdKey
|
|
60
|
+
});
|
|
61
|
+
for (const userItem of (usersResult?.Items || [])) {
|
|
62
|
+
const userId = userItem.userId;
|
|
63
|
+
try {
|
|
64
|
+
await dynamodbSharedLib.transactWriteItems(_izContext, [
|
|
65
|
+
{
|
|
66
|
+
action: 'delete',
|
|
67
|
+
params: {
|
|
68
|
+
tableName: roleUsersTable,
|
|
69
|
+
keyValues: { roleIdKey, userId }
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
action: 'delete',
|
|
74
|
+
params: {
|
|
75
|
+
tableName: userRolesTable,
|
|
76
|
+
keyValues: { userId, roleIdKey }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
_izContext.logger.debug(`[${process.env.iz_serviceTag}:DeleteTargetRole] Cascade user cleanup ignored:`, err);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
await sns.publishMessage(_izContext, {
|
|
86
|
+
message: { returnResult: { identifiersConcat, roleIdKey, status: 'deleted' } },
|
|
87
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
88
|
+
_izContext,
|
|
89
|
+
'DeleteTargetRole_Out'
|
|
90
|
+
)
|
|
91
|
+
});
|
|
92
|
+
} catch (error) {
|
|
93
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:DeleteTargetRole] error:`, error);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2020 Sven Mason <http://izara.io>
|
|
3
|
+
|
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU Affero General Public License as
|
|
6
|
+
published by the Free Software Foundation, either version 3 of the
|
|
7
|
+
License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU Affero General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
|
|
19
|
+
import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
20
|
+
import { sns } from '@izara_project/izara-core-library-external-request';
|
|
21
|
+
import { consts, NoRetryError } from '@izara_project/izara-core-library-core';
|
|
22
|
+
|
|
23
|
+
export default async function GetMyPermissions(_izContext, requestParams) {
|
|
24
|
+
try {
|
|
25
|
+
const submittedByUserId =
|
|
26
|
+
requestParams.submittedByUserId ||
|
|
27
|
+
_izContext.correlationIds?.get(consts.SUBMITTED_BY_USER_ID);
|
|
28
|
+
|
|
29
|
+
if (!submittedByUserId) {
|
|
30
|
+
throw new NoRetryError('User identity not found in context.');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const targetIdentifiers = requestParams.targetIdentifiers;
|
|
34
|
+
let identifiersConcat =
|
|
35
|
+
requestParams.identifiersConcat || requestParams.identifierConcat;
|
|
36
|
+
if (!identifiersConcat && targetIdentifiers && typeof targetIdentifiers === 'object') {
|
|
37
|
+
if (targetIdentifiers.identifiersConcat || targetIdentifiers.identifierConcat) {
|
|
38
|
+
identifiersConcat =
|
|
39
|
+
targetIdentifiers.identifiersConcat || targetIdentifiers.identifierConcat;
|
|
40
|
+
} else {
|
|
41
|
+
const sortedKeys = Object.keys(targetIdentifiers)
|
|
42
|
+
.filter(
|
|
43
|
+
(k) =>
|
|
44
|
+
k !== 'submittedByUserId' &&
|
|
45
|
+
k !== 'identifierConcat' &&
|
|
46
|
+
k !== 'identifiersConcat'
|
|
47
|
+
)
|
|
48
|
+
.sort();
|
|
49
|
+
const parts = [];
|
|
50
|
+
for (const key of sortedKeys) {
|
|
51
|
+
const value = targetIdentifiers[key];
|
|
52
|
+
if (value !== undefined && value !== null) {
|
|
53
|
+
parts.push(`${key}#${value}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (parts.length > 0) {
|
|
57
|
+
identifiersConcat = parts.join('|');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const userRolesTable = dynamodbSharedLib.tableName(_izContext, 'UserRoles');
|
|
63
|
+
const rolePermissionsTable = dynamodbSharedLib.tableName(_izContext, 'RolePermissions');
|
|
64
|
+
|
|
65
|
+
const userRolesResult = await dynamodbSharedLib.query(_izContext, userRolesTable, {
|
|
66
|
+
userId: submittedByUserId
|
|
67
|
+
});
|
|
68
|
+
const userRoleItems = userRolesResult?.Items || [];
|
|
69
|
+
|
|
70
|
+
const matchingRoles = identifiersConcat
|
|
71
|
+
? userRoleItems.filter((item) => item.roleIdKey?.startsWith(identifiersConcat))
|
|
72
|
+
: userRoleItems;
|
|
73
|
+
|
|
74
|
+
const permissionsMap = {};
|
|
75
|
+
const rolesList = [];
|
|
76
|
+
|
|
77
|
+
for (const roleItem of matchingRoles) {
|
|
78
|
+
rolesList.push(roleItem.roleIdKey);
|
|
79
|
+
const permsResult = await dynamodbSharedLib.query(_izContext, rolePermissionsTable, {
|
|
80
|
+
roleIdKey: roleItem.roleIdKey
|
|
81
|
+
});
|
|
82
|
+
for (const p of (permsResult?.Items || [])) {
|
|
83
|
+
if (p.permission === true) {
|
|
84
|
+
permissionsMap[p.flowTypeConcat] = true;
|
|
85
|
+
} else if (permissionsMap[p.flowTypeConcat] === undefined) {
|
|
86
|
+
permissionsMap[p.flowTypeConcat] = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const result = {
|
|
92
|
+
userId: submittedByUserId,
|
|
93
|
+
identifiersConcat: identifiersConcat || null,
|
|
94
|
+
roles: rolesList,
|
|
95
|
+
permissions: permissionsMap
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
await sns.publishMessage(_izContext, {
|
|
99
|
+
message: { returnResult: result },
|
|
100
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
101
|
+
_izContext,
|
|
102
|
+
'GetMyPermissions_Out'
|
|
103
|
+
)
|
|
104
|
+
});
|
|
105
|
+
return result;
|
|
106
|
+
} catch (error) {
|
|
107
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:GetMyPermissions] error:`, error);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|