@izara_project/izara-core-generate-service-code 1.0.82 → 1.0.84
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 +4 -4
- package/src/compile/flowValidator.js +34 -0
- package/src/compile/loadSchemas.js +121 -7
- package/src/emit/attributeTree/emitAttributeTreeSchemas.js +388 -0
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +29 -1
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +16 -3
- package/src/emit/crud/crudActionPlan.js +43 -7
- package/src/emit/crud/emitCrudApplicationArtifacts.js +19 -4
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +27 -6
- package/src/emit/crud/generateCrudApplicationArtifacts.js +3 -2
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +3 -2
- package/src/emit/crud/loadLocalSchemaArrays.js +3 -3
- package/src/emit/crud/templates/CreateComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +75 -21
- package/src/emit/crud/templates/CreateLogicalLib.ejs +73 -8
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +39 -11
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +6 -3
- package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +2 -2
- package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +7 -0
- package/src/emit/crud/templates/FlowMain_Wbs.ejs +5 -2
- package/src/emit/crud/templates/GetEndpoint_Main.ejs +13 -0
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +53 -4
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +4 -3
- package/src/emit/custom/customFlows.js +49 -0
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +168 -49
- package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +1 -1
- package/src/emit/custom/templates/FlowEndpointRbacCallback_Main.ejs +194 -0
- package/src/emit/custom/templates/FlowEndpoint_Main.ejs +14 -22
- package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
- package/src/emit/function/templates/WbsFunction_Yaml.ejs +0 -2
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +33 -8
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +204 -7
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +103 -0
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +71 -0
- package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +49 -6
- package/src/emit/rbac/templates/ListRbac_Main.ejs +9 -3
- package/src/emit/rbac/templates/RbacMutation_Main.ejs +1 -1
- package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +147 -0
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +59 -23
- package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +1 -1
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +1 -1
- package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +10 -3
- package/src/emit/resource/emitResourceArtifacts.js +350 -112
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +53 -2
- package/src/emit/system/emitSystemWebSocketArtifacts.js +6 -4
- package/src/emit/system/templates/WebSocketConnect.ejs +71 -12
- package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +7 -0
- package/src/emit/systemText/emitSystemTextSchemas.js +3 -2
- package/src/generate.js +41 -10
- package/test/attributeTreeSchemas.test.js +219 -0
- package/test/createTargetRoleHandler.test.js +59 -4
- package/test/crudApplicationArtifacts.test.js +23 -6
- package/test/customFlowApplicationArtifacts.test.js +5 -5
- package/test/dynamicCrudFlowSchemas.test.js +110 -13
- package/test/dynamicRbacFlowSchemas.test.js +15 -2
- package/test/publicApi.test.js +7 -7
- package/test/resourceArtifacts.test.js +70 -29
- package/test/systemTextSchemas.test.js +1 -1
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
generatedDsqFlows,
|
|
17
17
|
generatedOwnTopicFlows,
|
|
18
18
|
supportedCustomFlows,
|
|
19
|
-
upperFirst
|
|
19
|
+
upperFirst,
|
|
20
|
+
flowHasRbac
|
|
20
21
|
} from './customFlows.js';
|
|
21
22
|
|
|
22
23
|
const YAML_PATH = 'app/sls_yaml/generatedCode/source/flow-schema.yml';
|
|
@@ -67,10 +68,10 @@ export async function emitCustomFlowApplicationArtifacts(
|
|
|
67
68
|
];
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
export function customFlowApplicationManagedPaths(flows) {
|
|
71
|
+
export function customFlowApplicationManagedPaths(flows, { objects = [] } = {}) {
|
|
71
72
|
return [
|
|
72
|
-
...supportedCustomFlows(flows).flatMap((flow) => flowPaths(flow)),
|
|
73
|
-
...generatedOwnTopicFlows(flows).flatMap(ownTopicRootPaths),
|
|
73
|
+
...supportedCustomFlows(flows).flatMap((flow) => flowPaths(flow, objects)),
|
|
74
|
+
...generatedOwnTopicFlows(flows).flatMap((flow) => ownTopicRootPaths(flow, objects)),
|
|
74
75
|
...flowExtTopicSteps(flows).flatMap(({ flowTag, stepName }) => {
|
|
75
76
|
const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
76
77
|
return [
|
|
@@ -122,6 +123,45 @@ async function emitFlow(flow, objects) {
|
|
|
122
123
|
: [];
|
|
123
124
|
const functions = [];
|
|
124
125
|
|
|
126
|
+
const isRbac = flowHasRbac(flow, objects);
|
|
127
|
+
if (isRbac && !flow.event.includes('ownTopic')) {
|
|
128
|
+
const rbacStep = (flow.flowSteps || []).find(
|
|
129
|
+
(s) => typeof s?.stepName === 'string' && s.stepName.toLowerCase() === 'rbaccallback'
|
|
130
|
+
);
|
|
131
|
+
const rbacConfig = rbacStep ? stepConfig(flow, rbacStep) : null;
|
|
132
|
+
artifacts.push(
|
|
133
|
+
{
|
|
134
|
+
path: `${source}/${tag}RbacCallback_Main.js`,
|
|
135
|
+
content: await renderCustom('FlowEndpointRbacCallback_Main.ejs', {
|
|
136
|
+
flowTag: flow.flowTag,
|
|
137
|
+
upperCaseFlowTag: tag,
|
|
138
|
+
functionName: `${tag}RbacCallbackMain`
|
|
139
|
+
})
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
path: `${source}/${tag}RbacCallback_HdrSqs.js`,
|
|
143
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
144
|
+
flowTag: flow.flowTag,
|
|
145
|
+
flowStepName: 'RbacCallback',
|
|
146
|
+
mainFileName: `${tag}RbacCallback_Main`,
|
|
147
|
+
functionName: `${tag}RbacCallbackMain`,
|
|
148
|
+
queueName: `${tag}RbacCallbackHdrSqs`,
|
|
149
|
+
startConfig: rbacConfig
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
functions.push(
|
|
154
|
+
renderSqsFunctionYaml({
|
|
155
|
+
functionName: `${tag}RbacCallbackHdrSqs`,
|
|
156
|
+
handlerPath: `${handlerRoot}/${tag}RbacCallback_HdrSqs.main`,
|
|
157
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
158
|
+
queueName: `${tag}RbacCallbackHdrSqs`,
|
|
159
|
+
flowTag: flow.flowTag,
|
|
160
|
+
flowStepName: 'RbacCallback'
|
|
161
|
+
})
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
125
165
|
if (flow.event.includes('extTopic') && !flow.event.includes('ownTopic')) {
|
|
126
166
|
artifacts.push({
|
|
127
167
|
path: `${source}/${process}_HdrSqs.js`,
|
|
@@ -219,7 +259,7 @@ async function emitFlow(flow, objects) {
|
|
|
219
259
|
return { artifacts, functions };
|
|
220
260
|
}
|
|
221
261
|
|
|
222
|
-
function flowPaths(flow) {
|
|
262
|
+
function flowPaths(flow, objects = []) {
|
|
223
263
|
const tag = upperFirst(flow.flowTag);
|
|
224
264
|
const process = tag;
|
|
225
265
|
const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
|
|
@@ -227,6 +267,12 @@ function flowPaths(flow) {
|
|
|
227
267
|
if (needsProcessMain(flow)) {
|
|
228
268
|
paths.push(`${source}/${process}_Main.js`);
|
|
229
269
|
}
|
|
270
|
+
if (flowHasRbac(flow, objects)) {
|
|
271
|
+
paths.push(
|
|
272
|
+
`${source}/${tag}RbacCallback_Main.js`,
|
|
273
|
+
`${source}/${tag}RbacCallback_HdrSqs.js`
|
|
274
|
+
);
|
|
275
|
+
}
|
|
230
276
|
if (flow.event.includes('extTopic') && !flow.event.includes('ownTopic')) {
|
|
231
277
|
paths.push(`${source}/${process}_HdrSqs.js`);
|
|
232
278
|
}
|
|
@@ -418,68 +464,118 @@ async function emitOwnTopicRoot(flow, objects) {
|
|
|
418
464
|
upperCaseFlowTag: tag,
|
|
419
465
|
startConfig: _startConfig(flow)
|
|
420
466
|
};
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
467
|
+
const isRbac = flowHasRbac(flow, objects);
|
|
468
|
+
const ownArtifacts = [
|
|
469
|
+
{
|
|
470
|
+
path: `${source}/${mainFileName}.js`,
|
|
471
|
+
content: await renderEndpointMain(flow, mainFileName, objects)
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
path: `${source}/${tag}_HdrSqs.js`,
|
|
475
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
476
|
+
...shared,
|
|
477
|
+
functionName: mainFileName,
|
|
478
|
+
mainFileName,
|
|
479
|
+
queueName: `${tag}HdrSqs`
|
|
480
|
+
})
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
path: `${source}/${wbsMainFileName}.js`,
|
|
484
|
+
content: await renderCrudTemplate('FlowMain_Wbs.ejs', {
|
|
485
|
+
...shared,
|
|
486
|
+
functionName: wbsMainFileName
|
|
487
|
+
})
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
path: `${source}/${tag}_HdrWbs.js`,
|
|
491
|
+
content: await renderCrudTemplate('FlowEndpoint_HdrWbs.ejs', {
|
|
492
|
+
...shared,
|
|
493
|
+
functionName: tag,
|
|
494
|
+
mainFileName: wbsMainFileName,
|
|
495
|
+
route: tag
|
|
496
|
+
})
|
|
497
|
+
}
|
|
498
|
+
];
|
|
499
|
+
|
|
500
|
+
const ownFunctions = [
|
|
501
|
+
renderWbsFunctionYaml({
|
|
502
|
+
functionName: `${tag}HdrWbs`,
|
|
503
|
+
handlerPath: `${handlerRoot}/${tag}_HdrWbs.main`,
|
|
504
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
505
|
+
routeName: tag,
|
|
506
|
+
flowTag: flow.flowTag,
|
|
507
|
+
flowStepName: ''
|
|
508
|
+
}),
|
|
509
|
+
renderSqsFunctionYaml({
|
|
510
|
+
functionName: `${tag}HdrSqs`,
|
|
511
|
+
handlerPath: `${handlerRoot}/${tag}_HdrSqs.main`,
|
|
512
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
513
|
+
queueName: `${tag}HdrSqs`,
|
|
514
|
+
flowTag: flow.flowTag,
|
|
515
|
+
flowStepName: ''
|
|
516
|
+
})
|
|
517
|
+
];
|
|
518
|
+
|
|
519
|
+
if (isRbac) {
|
|
520
|
+
const rbacStep = (flow.flowSteps || []).find(
|
|
521
|
+
(s) => typeof s?.stepName === 'string' && s.stepName.toLowerCase() === 'rbaccallback'
|
|
522
|
+
);
|
|
523
|
+
const rbacConfig = rbacStep ? stepConfig(flow, rbacStep) : null;
|
|
524
|
+
ownArtifacts.push(
|
|
436
525
|
{
|
|
437
|
-
path: `${source}/${
|
|
438
|
-
content: await
|
|
439
|
-
|
|
440
|
-
|
|
526
|
+
path: `${source}/${tag}RbacCallback_Main.js`,
|
|
527
|
+
content: await renderCustom('FlowEndpointRbacCallback_Main.ejs', {
|
|
528
|
+
flowTag: flow.flowTag,
|
|
529
|
+
upperCaseFlowTag: tag,
|
|
530
|
+
functionName: `${tag}RbacCallbackMain`
|
|
441
531
|
})
|
|
442
532
|
},
|
|
443
533
|
{
|
|
444
|
-
path: `${source}/${tag}
|
|
445
|
-
content: await
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
mainFileName:
|
|
449
|
-
|
|
534
|
+
path: `${source}/${tag}RbacCallback_HdrSqs.js`,
|
|
535
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
536
|
+
flowTag: flow.flowTag,
|
|
537
|
+
flowStepName: 'RbacCallback',
|
|
538
|
+
mainFileName: `${tag}RbacCallback_Main`,
|
|
539
|
+
functionName: `${tag}RbacCallbackMain`,
|
|
540
|
+
queueName: `${tag}RbacCallbackHdrSqs`,
|
|
541
|
+
startConfig: rbacConfig
|
|
450
542
|
})
|
|
451
543
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
renderWbsFunctionYaml({
|
|
455
|
-
functionName: `${tag}HdrWbs`,
|
|
456
|
-
handlerPath: `${handlerRoot}/${tag}_HdrWbs.main`,
|
|
457
|
-
roleName: customFlowRoleName(flow.flowTag),
|
|
458
|
-
routeName: tag,
|
|
459
|
-
flowTag: flow.flowTag,
|
|
460
|
-
flowStepName: ''
|
|
461
|
-
}),
|
|
544
|
+
);
|
|
545
|
+
ownFunctions.push(
|
|
462
546
|
renderSqsFunctionYaml({
|
|
463
|
-
functionName: `${tag}
|
|
464
|
-
handlerPath: `${handlerRoot}/${tag}
|
|
547
|
+
functionName: `${tag}RbacCallbackHdrSqs`,
|
|
548
|
+
handlerPath: `${handlerRoot}/${tag}RbacCallback_HdrSqs.main`,
|
|
465
549
|
roleName: customFlowRoleName(flow.flowTag),
|
|
466
|
-
queueName: `${tag}
|
|
550
|
+
queueName: `${tag}RbacCallbackHdrSqs`,
|
|
467
551
|
flowTag: flow.flowTag,
|
|
468
|
-
flowStepName: ''
|
|
552
|
+
flowStepName: 'RbacCallback'
|
|
469
553
|
})
|
|
470
|
-
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return {
|
|
558
|
+
artifacts: ownArtifacts,
|
|
559
|
+
functions: ownFunctions
|
|
471
560
|
};
|
|
472
561
|
}
|
|
473
562
|
|
|
474
|
-
function ownTopicRootPaths(flow) {
|
|
563
|
+
function ownTopicRootPaths(flow, objects = []) {
|
|
475
564
|
const tag = upperFirst(flow.flowTag);
|
|
476
565
|
const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
|
|
477
|
-
|
|
566
|
+
const paths = [
|
|
478
567
|
`${source}/${tag}_Main.js`,
|
|
479
568
|
`${source}/${tag}_HdrSqs.js`,
|
|
480
569
|
`${source}/${tag}_WbsMain.js`,
|
|
481
570
|
`${source}/${tag}_HdrWbs.js`
|
|
482
571
|
];
|
|
572
|
+
if (flowHasRbac(flow, objects)) {
|
|
573
|
+
paths.push(
|
|
574
|
+
`${source}/${tag}RbacCallback_Main.js`,
|
|
575
|
+
`${source}/${tag}RbacCallback_HdrSqs.js`
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
return paths;
|
|
483
579
|
}
|
|
484
580
|
|
|
485
581
|
function needsProcessMain(flow) {
|
|
@@ -694,12 +790,35 @@ function isS3Only(flow) {
|
|
|
694
790
|
return flow.event.length === 1 && flow.event[0] === 's3';
|
|
695
791
|
}
|
|
696
792
|
|
|
697
|
-
async function renderEndpointMain(flow, functionName, objects) {
|
|
793
|
+
async function renderEndpointMain(flow, functionName, objects = []) {
|
|
794
|
+
const isRbac = flowHasRbac(flow, objects);
|
|
795
|
+
const matchedObject = objects.find(
|
|
796
|
+
(o) => o.objectType === flow.objType?.objectType
|
|
797
|
+
);
|
|
798
|
+
let rbacServiceTag = null;
|
|
799
|
+
if (matchedObject) {
|
|
800
|
+
const belongTo = matchedObject.belongTo;
|
|
801
|
+
if (belongTo) {
|
|
802
|
+
rbacServiceTag = Array.isArray(belongTo)
|
|
803
|
+
? belongTo[0]?.serviceTag
|
|
804
|
+
: belongTo?.serviceTag;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
if (!rbacServiceTag) {
|
|
808
|
+
rbacServiceTag = flow.objType?.serviceTag || flow.serviceTag || 'Rbac';
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
const enrichedFlow = {
|
|
812
|
+
...flow,
|
|
813
|
+
isRbac
|
|
814
|
+
};
|
|
815
|
+
|
|
698
816
|
return renderCustom('FlowEndpoint_Main.ejs', {
|
|
699
|
-
flow,
|
|
817
|
+
flow: enrichedFlow,
|
|
700
818
|
flowTag: flow.flowTag,
|
|
701
819
|
upperCaseFlowTag: upperFirst(flow.flowTag),
|
|
702
820
|
functionName,
|
|
821
|
+
rbacServiceTag,
|
|
703
822
|
tableName: storedCacheTableName(flow, objects),
|
|
704
823
|
startConfig: _startConfig(flow)
|
|
705
824
|
});
|
|
@@ -32,7 +32,7 @@ export async function generateCustomFlowApplicationArtifacts(
|
|
|
32
32
|
managedPaths: [
|
|
33
33
|
...systemWebSocketManagedPaths(),
|
|
34
34
|
...customFlowApplicationManagedPaths(flows, {
|
|
35
|
-
includeYaml: hasSystemWebSocket(flows)
|
|
35
|
+
includeYaml: hasSystemWebSocket(flows), objects
|
|
36
36
|
})
|
|
37
37
|
],
|
|
38
38
|
managedScope: 'custom-flow-application'
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2021 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 asyncFlowSharedLib from '@izara_project/izara-core-library-asynchronous-flow';
|
|
19
|
+
import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
20
|
+
import { sns } from '@izara_project/izara-core-library-external-request';
|
|
21
|
+
|
|
22
|
+
//(<optionalRequire>)
|
|
23
|
+
//(</optionalRequire>)
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Handles callback after RbacCallback phase for custom flow — verifies awaitingStep then proceeds to next flow steps
|
|
27
|
+
* @param {Object} _izContext - Context object with logger
|
|
28
|
+
* @param {Object} requestParams - Request parameters
|
|
29
|
+
* @param {string} flowTag - Flow tag
|
|
30
|
+
* @param {Object} callingFlowConfig - Calling flow configuration
|
|
31
|
+
* @returns {Promise<Object>}
|
|
32
|
+
*/
|
|
33
|
+
export default async function <%- functionName %>(
|
|
34
|
+
_izContext,
|
|
35
|
+
requestParams,
|
|
36
|
+
flowTag,
|
|
37
|
+
callingFlowConfig = {}
|
|
38
|
+
) {
|
|
39
|
+
try {
|
|
40
|
+
_izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- functionName %>] Started with params:`, {
|
|
41
|
+
requestParams,
|
|
42
|
+
flowTag,
|
|
43
|
+
callingFlowConfig
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const parts = requestParams.parentFlowId.split('_');
|
|
47
|
+
const rbacType = parts.pop();
|
|
48
|
+
const rbacPendingStepId = '<%- flowTag %>RbacCallback_' + parts.join('_');
|
|
49
|
+
const currentAwaitingStepId = requestParams.parentFlowId;
|
|
50
|
+
|
|
51
|
+
_izContext.logger.debug(
|
|
52
|
+
`[${process.env.iz_serviceTag}:<%- functionName %>] Parsed RBAC pending details:`,
|
|
53
|
+
{
|
|
54
|
+
rbacType,
|
|
55
|
+
rbacPendingStepId,
|
|
56
|
+
currentAwaitingStepId,
|
|
57
|
+
parentFlowId: requestParams.parentFlowId
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const rbacAwaitingStepsResult =
|
|
62
|
+
await asyncFlowSharedLib.checkAllAwaitingStepsFinishedWithReturnParams(
|
|
63
|
+
_izContext,
|
|
64
|
+
rbacPendingStepId,
|
|
65
|
+
currentAwaitingStepId,
|
|
66
|
+
requestParams.errorsFound,
|
|
67
|
+
{
|
|
68
|
+
returnValue: requestParams.returnValue,
|
|
69
|
+
rbacType
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
_izContext.logger.debug(
|
|
74
|
+
`[${process.env.iz_serviceTag}:<%- functionName %>] checkAllAwaitingStepsFinishedWithReturnParams result:`,
|
|
75
|
+
{
|
|
76
|
+
rbacAwaitingStepsResult
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const {
|
|
81
|
+
isComplete,
|
|
82
|
+
collectedReturnValueByAwaitingStepId,
|
|
83
|
+
collectedErrors: errorsFound = [],
|
|
84
|
+
additionalAttributes
|
|
85
|
+
} = rbacAwaitingStepsResult;
|
|
86
|
+
|
|
87
|
+
if (isComplete === false) {
|
|
88
|
+
_izContext.logger.debug(
|
|
89
|
+
`[${process.env.iz_serviceTag}:<%- functionName %>] Awaiting steps still pending completion:`,
|
|
90
|
+
{
|
|
91
|
+
rbacPendingStepId,
|
|
92
|
+
isComplete
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
return 'all task not completed';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
_izContext.logger.debug(
|
|
100
|
+
`[${process.env.iz_serviceTag}:<%- functionName %>] All awaiting steps completed — clearing awaiting steps:`,
|
|
101
|
+
{
|
|
102
|
+
rbacPendingStepId
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
await asyncFlowSharedLib.clearAllAwaitingSteps(
|
|
107
|
+
_izContext,
|
|
108
|
+
rbacPendingStepId
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const originalRequestParams = additionalAttributes?.requestParams || {};
|
|
112
|
+
|
|
113
|
+
_izContext.logger.debug(
|
|
114
|
+
`[${process.env.iz_serviceTag}:<%- functionName %>] Retrieved originalRequestParams:`,
|
|
115
|
+
{
|
|
116
|
+
originalRequestParams
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const rbacResults = Object.fromEntries(
|
|
121
|
+
Object.entries(collectedReturnValueByAwaitingStepId || {}).map(
|
|
122
|
+
([stepId, attrs]) => {
|
|
123
|
+
const type = stepId.split('_').pop();
|
|
124
|
+
return [type, attrs];
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const rbacCallbackResults = {};
|
|
130
|
+
const hasError = Object.entries(rbacResults).some(([type, result]) => {
|
|
131
|
+
if (result && result.error) {
|
|
132
|
+
errorsFound.push(result.error);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
rbacCallbackResults[type] = result;
|
|
136
|
+
return false;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const isAllowed = Object.values(rbacCallbackResults).some(
|
|
140
|
+
item => item?.returnValue?.permission === true
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
if (!isAllowed) {
|
|
144
|
+
errorsFound.push('Permission denied');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
_izContext.logger.debug(
|
|
148
|
+
`[${process.env.iz_serviceTag}:<%- functionName %>] Final rbacCallbackResults:`,
|
|
149
|
+
{
|
|
150
|
+
rbacCallbackResults,
|
|
151
|
+
isAllowed,
|
|
152
|
+
errorsFound
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
if (hasError || errorsFound.length > 0) {
|
|
157
|
+
const errorResult = {
|
|
158
|
+
errorsFound,
|
|
159
|
+
status: 'rejected',
|
|
160
|
+
requestParams: originalRequestParams
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
_izContext.logger.debug(
|
|
164
|
+
`[${process.env.iz_serviceTag}:<%- functionName %>] RBAC check failed, publishing rejected status:`,
|
|
165
|
+
errorResult
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
await sns.publishAsync(_izContext, {
|
|
169
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
170
|
+
_izContext,
|
|
171
|
+
'<%- upperCaseFlowTag %>_Out',
|
|
172
|
+
process.env.iz_serviceTag
|
|
173
|
+
),
|
|
174
|
+
Message: JSON.stringify(errorResult)
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return errorResult;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//(<rbacCallbackMain>)
|
|
181
|
+
//(</rbacCallbackMain>)
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
status: 'complete',
|
|
185
|
+
requestParams: originalRequestParams,
|
|
186
|
+
rbacCallbackResults
|
|
187
|
+
};
|
|
188
|
+
} catch (err) {
|
|
189
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:<%- functionName %>] Error caught:`, {
|
|
190
|
+
error: err
|
|
191
|
+
});
|
|
192
|
+
throw err;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -66,10 +66,10 @@ export default async function <%- typeof functionName !== 'undefined' ? function
|
|
|
66
66
|
//(</additionalParams>)
|
|
67
67
|
) {
|
|
68
68
|
try {
|
|
69
|
-
_izContext.logger.debug(
|
|
70
|
-
_izContext.logger.debug(
|
|
69
|
+
_izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %>] _izContext:`, _izContext);
|
|
70
|
+
_izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %>] requestParams:`, requestParams);
|
|
71
71
|
_izContext.logger.debug(
|
|
72
|
-
|
|
72
|
+
`[${process.env.iz_serviceTag}:<%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %>] callingFlowConfig:`,
|
|
73
73
|
callingFlowConfig
|
|
74
74
|
);
|
|
75
75
|
|
|
@@ -120,42 +120,34 @@ export default async function <%- typeof functionName !== 'undefined' ? function
|
|
|
120
120
|
|
|
121
121
|
const resultPermissionCheck = await checkRbacPermission(
|
|
122
122
|
_izContext,
|
|
123
|
-
{ flowTag: '<%- flow.flowTag %>', serviceTag: '<%- flow.serviceTag || (flow.objType ? flow.objType.serviceTag : "") %>' },
|
|
123
|
+
{ flowTag: '<%- flow.flowTag %>', serviceTag: process.env.iz_serviceTag || '<%- flow.serviceTag || (flow.objType ? flow.objType.serviceTag : "") %>' },
|
|
124
124
|
parameterGroups,
|
|
125
125
|
{
|
|
126
126
|
rbacObjType: {
|
|
127
|
-
serviceTag: '<%- (flow.objType?.belongTo ? (Array.isArray(flow.objType.belongTo) ? flow.objType.belongTo[0]?.serviceTag : flow.objType.belongTo?.serviceTag) : null) || flow.serviceTag || (flow.objType ? flow.objType.serviceTag : "") %>'
|
|
127
|
+
serviceTag: '<%- (typeof rbacServiceTag !== "undefined" && rbacServiceTag) ? rbacServiceTag : ((flow.objType?.belongTo ? (Array.isArray(flow.objType.belongTo) ? flow.objType.belongTo[0]?.serviceTag : flow.objType.belongTo?.serviceTag) : null) || flow.serviceTag || (flow.objType ? flow.objType.serviceTag : "")) %>'
|
|
128
128
|
},
|
|
129
129
|
requestParams: typeof requestParams !== 'undefined' ? requestParams : {},
|
|
130
|
-
nextFlowStepName: '<%-
|
|
130
|
+
nextFlowStepName: '<%- upperCaseFlowTag %>RbacCallback'
|
|
131
131
|
}
|
|
132
132
|
);
|
|
133
133
|
|
|
134
134
|
_izContext.logger.debug(
|
|
135
|
-
'
|
|
135
|
+
`[${process.env.iz_serviceTag}:<%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %>] checkRbacPermission result:`,
|
|
136
136
|
resultPermissionCheck
|
|
137
137
|
);
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return await sns.publishAsync(_izContext, {
|
|
145
|
-
Message: JSON.stringify(message),
|
|
146
|
-
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
147
|
-
_izContext,
|
|
148
|
-
'<%- flow.flowTag %>_Out'
|
|
149
|
-
)
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
<% } -%>
|
|
139
|
+
//(<rbacPublish_<%- flowTag %>)
|
|
140
|
+
//(</rbacPublish_<%- flowTag %>)
|
|
141
|
+
|
|
142
|
+
return resultPermissionCheck;
|
|
143
|
+
<% } else { -%>
|
|
153
144
|
|
|
154
145
|
//(<endpointHook>)
|
|
155
146
|
//(</endpointHook>)
|
|
147
|
+
<% } -%>
|
|
156
148
|
|
|
157
149
|
} catch (err) {
|
|
158
|
-
_izContext.logger.error(
|
|
150
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:<%- typeof functionName !== undefined ? functionName : upperCaseFlowTag %>] error:`, err);
|
|
159
151
|
throw err;
|
|
160
152
|
}
|
|
161
153
|
}
|
|
@@ -52,7 +52,7 @@ export default async function <%= functionName %>(
|
|
|
52
52
|
//(<hookCode>)
|
|
53
53
|
//(</hookCode>)
|
|
54
54
|
} catch (err) {
|
|
55
|
-
_izContext.logger.error(
|
|
55
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:<%= functionName %>] error:`, err);
|
|
56
56
|
throw err;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -2,7 +2,7 @@ import ejsLib from 'ejs';
|
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { rbacFlowTag } from './rbacFlowTag.js';
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const RBAC_CORE_FLOW_DEFINITIONS = [
|
|
6
6
|
{ flowTag: 'CreateTargetRole', event: ['ownTopic'] },
|
|
7
7
|
{ flowTag: 'ListTargetRole', event: ['lambdaSyncApi'] },
|
|
8
8
|
{ flowTag: 'DeleteTargetRole', event: ['ownTopic'] },
|
|
@@ -13,12 +13,33 @@ const RBAC_FLOW_DEFINITIONS = [
|
|
|
13
13
|
{ flowTag: 'ListUserInRoles', event: ['lambdaSyncApi'] },
|
|
14
14
|
{ flowTag: 'DeleteUserFromRole', event: ['ownTopic'] }
|
|
15
15
|
];
|
|
16
|
+
|
|
17
|
+
const LIMIT_FLOW_DEFINITIONS = [
|
|
18
|
+
{ flowTag: 'CreateRoleLimit', event: ['ownTopic'] },
|
|
19
|
+
{ flowTag: 'ListRoleLimits', event: ['lambdaSyncApi'] },
|
|
20
|
+
{ flowTag: 'DeleteRoleLimit', event: ['ownTopic'] },
|
|
21
|
+
{ flowTag: 'ReservedDynamicUsage', event: ['ownTopic'] },
|
|
22
|
+
{ flowTag: 'ConfirmUsage', event: ['ownTopic'] },
|
|
23
|
+
{ flowTag: 'CancelUsage', event: ['ownTopic'] }
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const RBAC_FLOW_DEFINITIONS = [
|
|
27
|
+
...RBAC_CORE_FLOW_DEFINITIONS,
|
|
28
|
+
...LIMIT_FLOW_DEFINITIONS
|
|
29
|
+
];
|
|
30
|
+
|
|
16
31
|
const TEMPLATE_URL = new URL('./templates/', import.meta.url);
|
|
17
32
|
|
|
18
|
-
export const dynamicRbacFlowSchemaPaths =
|
|
19
|
-
(
|
|
20
|
-
|
|
21
|
-
|
|
33
|
+
export const dynamicRbacFlowSchemaPaths = [
|
|
34
|
+
...RBAC_CORE_FLOW_DEFINITIONS.map(
|
|
35
|
+
({ flowTag }) =>
|
|
36
|
+
`app/src/schemas/FlowSchemas/generateCode/FlowRbac/${flowTag}.js`
|
|
37
|
+
),
|
|
38
|
+
...LIMIT_FLOW_DEFINITIONS.map(
|
|
39
|
+
({ flowTag }) =>
|
|
40
|
+
`app/src/schemas/FlowSchemas/generateCode/FlowLimit/${flowTag}.js`
|
|
41
|
+
)
|
|
42
|
+
];
|
|
22
43
|
|
|
23
44
|
export function rbacFlowSchemaManagedPaths(objects = []) {
|
|
24
45
|
if (!Array.isArray(objects)) {
|
|
@@ -78,8 +99,12 @@ function _hasRbacAddOn(object) {
|
|
|
78
99
|
}
|
|
79
100
|
|
|
80
101
|
async function _artifact(flowTag, flow) {
|
|
102
|
+
const isLimit = LIMIT_FLOW_DEFINITIONS.some(
|
|
103
|
+
(def) => def.flowTag === flowTag
|
|
104
|
+
);
|
|
105
|
+
const folder = isLimit ? 'FlowLimit' : 'FlowRbac';
|
|
81
106
|
return {
|
|
82
|
-
path: `app/src/schemas/FlowSchemas/generateCode
|
|
107
|
+
path: `app/src/schemas/FlowSchemas/generateCode/${folder}/${flowTag}.js`,
|
|
83
108
|
content: ejsLib.render(
|
|
84
109
|
await readFile(
|
|
85
110
|
new URL('DynamicRbacFlowSchema.ejs', TEMPLATE_URL),
|
|
@@ -93,7 +118,7 @@ async function _artifact(flowTag, flow) {
|
|
|
93
118
|
function _createSharedRbacFlow(flowTag, event) {
|
|
94
119
|
return {
|
|
95
120
|
flowTag,
|
|
96
|
-
initiateBy: '
|
|
121
|
+
initiateBy: 'systemNoUser',
|
|
97
122
|
statusType: 'none',
|
|
98
123
|
event,
|
|
99
124
|
outputTopic: true,
|
|
@@ -119,7 +144,7 @@ function _createUserRbacFlow(flowTag, serviceTag, objectType) {
|
|
|
119
144
|
flowTag,
|
|
120
145
|
objType: { serviceTag, objectType },
|
|
121
146
|
event: ['ownTopic'],
|
|
122
|
-
initiateBy: '
|
|
147
|
+
initiateBy: 'systemNoUser',
|
|
123
148
|
handleObj: 'one',
|
|
124
149
|
statusType: 'none',
|
|
125
150
|
outputTopic: true,
|