@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.
Files changed (60) hide show
  1. package/package.json +4 -4
  2. package/src/compile/flowValidator.js +34 -0
  3. package/src/compile/loadSchemas.js +121 -7
  4. package/src/emit/attributeTree/emitAttributeTreeSchemas.js +388 -0
  5. package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +29 -1
  6. package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +16 -3
  7. package/src/emit/crud/crudActionPlan.js +43 -7
  8. package/src/emit/crud/emitCrudApplicationArtifacts.js +19 -4
  9. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +27 -6
  10. package/src/emit/crud/generateCrudApplicationArtifacts.js +3 -2
  11. package/src/emit/crud/generateDynamicCrudFlowSchemas.js +3 -2
  12. package/src/emit/crud/loadLocalSchemaArrays.js +3 -3
  13. package/src/emit/crud/templates/CreateComplete_Main.ejs +1 -1
  14. package/src/emit/crud/templates/CreateEndpoint_Main.ejs +75 -21
  15. package/src/emit/crud/templates/CreateLogicalLib.ejs +73 -8
  16. package/src/emit/crud/templates/DeleteComplete_Main.ejs +1 -1
  17. package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +39 -11
  18. package/src/emit/crud/templates/DeleteLogicalLib.ejs +6 -3
  19. package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +2 -2
  20. package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +7 -0
  21. package/src/emit/crud/templates/FlowMain_Wbs.ejs +5 -2
  22. package/src/emit/crud/templates/GetEndpoint_Main.ejs +13 -0
  23. package/src/emit/crud/templates/UpdateComplete_Main.ejs +1 -1
  24. package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +53 -4
  25. package/src/emit/crud/templates/UpdateLogicalLib.ejs +4 -3
  26. package/src/emit/custom/customFlows.js +49 -0
  27. package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +168 -49
  28. package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +1 -1
  29. package/src/emit/custom/templates/FlowEndpointRbacCallback_Main.ejs +194 -0
  30. package/src/emit/custom/templates/FlowEndpoint_Main.ejs +14 -22
  31. package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
  32. package/src/emit/function/templates/WbsFunction_Yaml.ejs +0 -2
  33. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +33 -8
  34. package/src/emit/rbac/emitRbacApplicationArtifacts.js +204 -7
  35. package/src/emit/rbac/templates/CancelUsage_Main.ejs +103 -0
  36. package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +71 -0
  37. package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +49 -6
  38. package/src/emit/rbac/templates/ListRbac_Main.ejs +9 -3
  39. package/src/emit/rbac/templates/RbacMutation_Main.ejs +1 -1
  40. package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +147 -0
  41. package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +59 -23
  42. package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +1 -1
  43. package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +1 -1
  44. package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +10 -3
  45. package/src/emit/resource/emitResourceArtifacts.js +350 -112
  46. package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +53 -2
  47. package/src/emit/system/emitSystemWebSocketArtifacts.js +6 -4
  48. package/src/emit/system/templates/WebSocketConnect.ejs +71 -12
  49. package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +7 -0
  50. package/src/emit/systemText/emitSystemTextSchemas.js +3 -2
  51. package/src/generate.js +41 -10
  52. package/test/attributeTreeSchemas.test.js +219 -0
  53. package/test/createTargetRoleHandler.test.js +59 -4
  54. package/test/crudApplicationArtifacts.test.js +23 -6
  55. package/test/customFlowApplicationArtifacts.test.js +5 -5
  56. package/test/dynamicCrudFlowSchemas.test.js +110 -13
  57. package/test/dynamicRbacFlowSchemas.test.js +15 -2
  58. package/test/publicApi.test.js +7 -7
  59. package/test/resourceArtifacts.test.js +70 -29
  60. 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
- return {
422
- artifacts: [
423
- {
424
- path: `${source}/${mainFileName}.js`,
425
- content: await renderEndpointMain(flow, mainFileName, objects)
426
- },
427
- {
428
- path: `${source}/${tag}_HdrSqs.js`,
429
- content: await renderShared('FlowHandler_HdrSqs.ejs', {
430
- ...shared,
431
- functionName: mainFileName,
432
- mainFileName,
433
- queueName: `${tag}HdrSqs`
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}/${wbsMainFileName}.js`,
438
- content: await renderCrudTemplate('FlowMain_Wbs.ejs', {
439
- ...shared,
440
- functionName: wbsMainFileName
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}_HdrWbs.js`,
445
- content: await renderCrudTemplate('FlowEndpoint_HdrWbs.ejs', {
446
- ...shared,
447
- functionName: tag,
448
- mainFileName: wbsMainFileName,
449
- route: tag
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
- functions: [
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}HdrSqs`,
464
- handlerPath: `${handlerRoot}/${tag}_HdrSqs.main`,
547
+ functionName: `${tag}RbacCallbackHdrSqs`,
548
+ handlerPath: `${handlerRoot}/${tag}RbacCallback_HdrSqs.main`,
465
549
  roleName: customFlowRoleName(flow.flowTag),
466
- queueName: `${tag}HdrSqs`,
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
- return [
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('<%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %> _izContext', _izContext);
70
- _izContext.logger.debug('<%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %> requestParams', requestParams);
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
- '<%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %> callingFlowConfig',
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: '<%- flow.flowTag %>RbacCallback'
130
+ nextFlowStepName: '<%- upperCaseFlowTag %>RbacCallback'
131
131
  }
132
132
  );
133
133
 
134
134
  _izContext.logger.debug(
135
- '[lib:auth:checkRbacPermission] resultPermissionCheck:',
135
+ `[${process.env.iz_serviceTag}:<%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %>] checkRbacPermission result:`,
136
136
  resultPermissionCheck
137
137
  );
138
138
 
139
- if (resultPermissionCheck.permission === false) {
140
- //(<messageOutPutPermissionCheckFailed>)
141
- const message = {};
142
- //(</messageOutPutPermissionCheckFailed>)
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('error WebSocketInvoke: ', err);
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('error <%= functionName %>Main: ', err);
55
+ _izContext.logger.error(`[${process.env.iz_serviceTag}:<%= functionName %>] error:`, err);
56
56
  throw err;
57
57
  }
58
58
  }
@@ -6,5 +6,3 @@
6
6
  events:
7
7
  - websocket:
8
8
  route: <%= routeName %>
9
- # authorizer: \${self:custom.iz_authorizerAppLevel}
10
- # identifierResource: 'route.request.header.Auth'
@@ -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 RBAC_FLOW_DEFINITIONS = [
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 = RBAC_FLOW_DEFINITIONS.map(
19
- ({ flowTag }) =>
20
- `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${flowTag}.js`
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/FlowRbac/${flowTag}.js`,
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: 'system',
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: 'system',
147
+ initiateBy: 'systemNoUser',
123
148
  handleObj: 'one',
124
149
  statusType: 'none',
125
150
  outputTopic: true,