@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
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
import { rbacFlowTag } from './rbacFlowTag.js';
|
|
11
11
|
|
|
12
12
|
const FLOW_RBAC_YAML_PATH = 'app/sls_yaml/generatedCode/source/flow-rbac.yml';
|
|
13
|
+
const FLOW_LIMITS_YAML_PATH = 'app/sls_yaml/generatedCode/source/flow-limits.yml';
|
|
13
14
|
const CRUD_TEMPLATE_URL = new URL('../crud/templates/', import.meta.url);
|
|
14
15
|
const RBAC_TEMPLATE_URL = new URL('./templates/', import.meta.url);
|
|
15
16
|
|
|
@@ -23,7 +24,8 @@ export async function emitRbacApplicationArtifacts(objects) {
|
|
|
23
24
|
}
|
|
24
25
|
const hasSelfRbac = objects.some(hasSelfRbacAddOn);
|
|
25
26
|
const flowTags = [...new Set(rbacObjects.map(rbacFlowTag))];
|
|
26
|
-
|
|
27
|
+
|
|
28
|
+
const rbacHandlers = await Promise.all([
|
|
27
29
|
...(hasSelfRbac
|
|
28
30
|
? [
|
|
29
31
|
createTargetRoleHandler(),
|
|
@@ -34,23 +36,47 @@ export async function emitRbacApplicationArtifacts(objects) {
|
|
|
34
36
|
: []),
|
|
35
37
|
...flowTags.map(createUserRbacFlowHandler)
|
|
36
38
|
]);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
const limitHandlers = await Promise.all(
|
|
41
|
+
hasSelfRbac
|
|
42
|
+
? [
|
|
43
|
+
...LIMIT_LIST_DEFINITIONS.map(createLimitListHandler),
|
|
44
|
+
...LIMIT_MUTATION_DEFINITIONS.map(createLimitMutationHandler),
|
|
45
|
+
...ACCOUNT_LIMIT_HANDLERS.map(createAccountLimitHandler)
|
|
46
|
+
]
|
|
47
|
+
: []
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const artifacts = [
|
|
51
|
+
...rbacHandlers.flatMap((handler) => handler.artifacts),
|
|
52
|
+
...limitHandlers.flatMap((handler) => handler.artifacts),
|
|
39
53
|
{
|
|
40
54
|
path: FLOW_RBAC_YAML_PATH,
|
|
41
|
-
content:
|
|
55
|
+
content: rbacHandlers
|
|
42
56
|
.flatMap((handler) => handler.functions)
|
|
43
57
|
.map(renderFunctionYaml)
|
|
44
58
|
.join('\n')
|
|
45
59
|
}
|
|
46
60
|
];
|
|
61
|
+
|
|
62
|
+
if (hasSelfRbac) {
|
|
63
|
+
artifacts.push({
|
|
64
|
+
path: FLOW_LIMITS_YAML_PATH,
|
|
65
|
+
content: limitHandlers
|
|
66
|
+
.flatMap((handler) => handler.functions)
|
|
67
|
+
.map(renderFunctionYaml)
|
|
68
|
+
.join('\n')
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return artifacts;
|
|
47
73
|
}
|
|
48
74
|
|
|
49
75
|
const LIST_DEFINITIONS = [
|
|
50
76
|
{
|
|
51
77
|
flowTag: 'ListTargetRole',
|
|
52
78
|
tableName: 'TargetRoles',
|
|
53
|
-
requestProperty: '
|
|
79
|
+
requestProperty: 'identifiersConcat',
|
|
54
80
|
useContextUserId: true
|
|
55
81
|
},
|
|
56
82
|
{
|
|
@@ -64,6 +90,15 @@ const LIST_DEFINITIONS = [
|
|
|
64
90
|
requestProperty: 'roleIdKey'
|
|
65
91
|
}
|
|
66
92
|
];
|
|
93
|
+
|
|
94
|
+
const LIMIT_LIST_DEFINITIONS = [
|
|
95
|
+
{
|
|
96
|
+
flowTag: 'ListRoleLimits',
|
|
97
|
+
tableName: 'RoleLimit',
|
|
98
|
+
requestProperty: 'roleLimitId'
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
|
|
67
102
|
const MUTATION_DEFINITIONS = [
|
|
68
103
|
{
|
|
69
104
|
flowTag: 'CreateRolePermissions',
|
|
@@ -81,14 +116,36 @@ const MUTATION_DEFINITIONS = [
|
|
|
81
116
|
flowTag: 'DeleteTargetRole',
|
|
82
117
|
tableName: 'TargetRoles',
|
|
83
118
|
method: 'deleteItem',
|
|
84
|
-
fields: ['
|
|
119
|
+
fields: ['identifiersConcat', 'roleIdKey']
|
|
85
120
|
}
|
|
86
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
|
+
}
|
|
136
|
+
];
|
|
137
|
+
|
|
87
138
|
const USER_ROLE_MUTATIONS = [
|
|
88
139
|
{ flowTag: 'CreateUserRole', operation: 'Put' },
|
|
89
140
|
{ flowTag: 'DeleteUserFromRole', operation: 'Delete' }
|
|
90
141
|
];
|
|
91
142
|
|
|
143
|
+
const ACCOUNT_LIMIT_HANDLERS = [
|
|
144
|
+
'ReservedDynamicUsage',
|
|
145
|
+
'ConfirmUsage',
|
|
146
|
+
'CancelUsage'
|
|
147
|
+
];
|
|
148
|
+
|
|
92
149
|
const STATIC_RBAC_APPLICATION_PATHS = [
|
|
93
150
|
'app/src/generatedCode/FlowRbac/CreateTargetRole/source/CreateTargetRole_Main.js',
|
|
94
151
|
'app/src/generatedCode/FlowRbac/CreateTargetRole/source/CreateTargetRole_HdrSqs.js',
|
|
@@ -118,6 +175,27 @@ const STATIC_RBAC_APPLICATION_PATHS = [
|
|
|
118
175
|
FLOW_RBAC_YAML_PATH
|
|
119
176
|
];
|
|
120
177
|
|
|
178
|
+
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
|
+
...ACCOUNT_LIMIT_HANDLERS.flatMap((flowTag) => [
|
|
191
|
+
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_Main.js`,
|
|
192
|
+
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrSqs.js`,
|
|
193
|
+
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_WbsMain.js`,
|
|
194
|
+
`app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrWbs.js`
|
|
195
|
+
]),
|
|
196
|
+
FLOW_LIMITS_YAML_PATH
|
|
197
|
+
];
|
|
198
|
+
|
|
121
199
|
export function rbacApplicationManagedPaths(objects = []) {
|
|
122
200
|
if (!Array.isArray(objects)) {
|
|
123
201
|
throw new TypeError('objects must be an array');
|
|
@@ -131,7 +209,126 @@ export function rbacApplicationManagedPaths(objects = []) {
|
|
|
131
209
|
`${sourcePath}/${flowTag}_HdrSqs.js`
|
|
132
210
|
];
|
|
133
211
|
});
|
|
134
|
-
return [
|
|
212
|
+
return [
|
|
213
|
+
...new Set([
|
|
214
|
+
...STATIC_RBAC_APPLICATION_PATHS,
|
|
215
|
+
...STATIC_LIMIT_APPLICATION_PATHS,
|
|
216
|
+
...sourcePaths
|
|
217
|
+
])
|
|
218
|
+
];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async function createAccountLimitHandler(flowTag) {
|
|
222
|
+
const sourcePath = `app/src/generatedCode/FlowLimit/${flowTag}/source`;
|
|
223
|
+
const handlerPath = `src/generatedCode/FlowLimit/${flowTag}/source`;
|
|
224
|
+
const webSocket = await createWebSocketEntry(
|
|
225
|
+
flowTag,
|
|
226
|
+
sourcePath,
|
|
227
|
+
handlerPath
|
|
228
|
+
);
|
|
229
|
+
return {
|
|
230
|
+
artifacts: [
|
|
231
|
+
{
|
|
232
|
+
path: `${sourcePath}/${flowTag}_Main.js`,
|
|
233
|
+
content: await renderRbacTemplate(`${flowTag}_Main.ejs`, { flowTag })
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
path: `${sourcePath}/${flowTag}_HdrSqs.js`,
|
|
237
|
+
content: await renderRbacTemplate('ListRbac_HdrSqs.ejs', { flowTag })
|
|
238
|
+
},
|
|
239
|
+
...webSocket.artifacts
|
|
240
|
+
],
|
|
241
|
+
functions: [
|
|
242
|
+
{
|
|
243
|
+
type: 'sqs',
|
|
244
|
+
functionName: `${flowTag}HdrSqs`,
|
|
245
|
+
handlerPath: `${handlerPath}/${flowTag}_HdrSqs.main`,
|
|
246
|
+
roleName: 'FlowRbacRole',
|
|
247
|
+
queueName: `${flowTag}HdrSqs`,
|
|
248
|
+
flowTag: flowTag,
|
|
249
|
+
flowStepName: ''
|
|
250
|
+
},
|
|
251
|
+
...webSocket.functions
|
|
252
|
+
]
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function createLimitListHandler(definition) {
|
|
257
|
+
const sourcePath = `app/src/generatedCode/FlowLimit/${definition.flowTag}/source`;
|
|
258
|
+
const handlerPath = `src/generatedCode/FlowLimit/${definition.flowTag}/source`;
|
|
259
|
+
return {
|
|
260
|
+
artifacts: [
|
|
261
|
+
{
|
|
262
|
+
path: `${sourcePath}/${definition.flowTag}_Main.js`,
|
|
263
|
+
content: await renderRbacTemplate('ListRbac_Main.ejs', {
|
|
264
|
+
...definition,
|
|
265
|
+
useContextUserId: definition.useContextUserId ?? false
|
|
266
|
+
})
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
path: `${sourcePath}/${definition.flowTag}_HdrSqs.js`,
|
|
270
|
+
content: await renderRbacTemplate('ListRbac_HdrSqs.ejs', definition)
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
path: `${sourcePath}/${definition.flowTag}_HdrApi.js`,
|
|
274
|
+
content: await renderRbacTemplate('ListRbac_HdrApi.ejs', definition)
|
|
275
|
+
}
|
|
276
|
+
],
|
|
277
|
+
functions: [
|
|
278
|
+
{
|
|
279
|
+
type: 'sqs',
|
|
280
|
+
functionName: `${definition.flowTag}HdrSqs`,
|
|
281
|
+
handlerPath: `${handlerPath}/${definition.flowTag}_HdrSqs.main`,
|
|
282
|
+
roleName: 'FlowRbacRole',
|
|
283
|
+
queueName: `${definition.flowTag}HdrSqs`,
|
|
284
|
+
flowTag: definition.flowTag,
|
|
285
|
+
flowStepName: ''
|
|
286
|
+
},
|
|
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
|
+
}
|
|
295
|
+
]
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async function createLimitMutationHandler(definition) {
|
|
300
|
+
const sourcePath = `app/src/generatedCode/FlowLimit/${definition.flowTag}/source`;
|
|
301
|
+
const handlerPath = `src/generatedCode/FlowLimit/${definition.flowTag}/source`;
|
|
302
|
+
const webSocket = await createWebSocketEntry(
|
|
303
|
+
definition.flowTag,
|
|
304
|
+
sourcePath,
|
|
305
|
+
handlerPath
|
|
306
|
+
);
|
|
307
|
+
return {
|
|
308
|
+
artifacts: [
|
|
309
|
+
{
|
|
310
|
+
path: `${sourcePath}/${definition.flowTag}_Main.js`,
|
|
311
|
+
content: await renderRbacTemplate('RbacMutation_Main.ejs', definition)
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
path: `${sourcePath}/${definition.flowTag}_HdrSqs.js`,
|
|
315
|
+
content: await renderRbacTemplate('ListRbac_HdrSqs.ejs', definition)
|
|
316
|
+
},
|
|
317
|
+
...webSocket.artifacts
|
|
318
|
+
],
|
|
319
|
+
functions: [
|
|
320
|
+
{
|
|
321
|
+
type: 'sqs',
|
|
322
|
+
functionName: `${definition.flowTag}HdrSqs`,
|
|
323
|
+
handlerPath: `${handlerPath}/${definition.flowTag}_HdrSqs.main`,
|
|
324
|
+
roleName: 'FlowRbacRole',
|
|
325
|
+
queueName: `${definition.flowTag}HdrSqs`,
|
|
326
|
+
flowTag: definition.flowTag,
|
|
327
|
+
flowStepName: ''
|
|
328
|
+
},
|
|
329
|
+
...webSocket.functions
|
|
330
|
+
]
|
|
331
|
+
};
|
|
135
332
|
}
|
|
136
333
|
|
|
137
334
|
async function createTargetRoleHandler() {
|
|
@@ -0,0 +1,103 @@
|
|
|
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 CancelUsage(_izContext, requestParams) {
|
|
24
|
+
try {
|
|
25
|
+
const submittedByUserId =
|
|
26
|
+
requestParams.submittedByUserId ||
|
|
27
|
+
_izContext.correlationIds?.get(consts.SUBMITTED_BY_USER_ID);
|
|
28
|
+
const { limitTag, uniqueIdentify } = requestParams;
|
|
29
|
+
|
|
30
|
+
const targetIdentifiers = requestParams.targetIdentifiers;
|
|
31
|
+
let identifiersConcat = requestParams.identifiersConcat;
|
|
32
|
+
if (!identifiersConcat && targetIdentifiers && typeof targetIdentifiers === 'object') {
|
|
33
|
+
identifiersConcat = Object.entries(targetIdentifiers)
|
|
34
|
+
.map(([k, v]) => `${k}#${v}`)
|
|
35
|
+
.join('_');
|
|
36
|
+
}
|
|
37
|
+
if (!identifiersConcat) {
|
|
38
|
+
identifiersConcat = submittedByUserId;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!identifiersConcat || !limitTag || !uniqueIdentify) {
|
|
42
|
+
throw new NoRetryError(
|
|
43
|
+
'identifiersConcat, limitTag, and uniqueIdentify are required.'
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const runningTotalReservedId = `${identifiersConcat}_${limitTag}`;
|
|
48
|
+
const reservedRecord = await dynamodbSharedLib.getItem(
|
|
49
|
+
_izContext,
|
|
50
|
+
dynamodbSharedLib.tableName(_izContext, 'RunningTotalReservedUsage'),
|
|
51
|
+
{
|
|
52
|
+
runningTotalReservedId,
|
|
53
|
+
usedTimestampId: uniqueIdentify
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const usageCount = reservedRecord?.usageCount || 0;
|
|
58
|
+
|
|
59
|
+
await dynamodbSharedLib.updateItem(
|
|
60
|
+
_izContext,
|
|
61
|
+
dynamodbSharedLib.tableName(_izContext, 'RunningTotalReservedUsage'),
|
|
62
|
+
{
|
|
63
|
+
runningTotalReservedId,
|
|
64
|
+
usedTimestampId: uniqueIdentify
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
runningTotalUsageStatus: 'cancelled'
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (usageCount > 0) {
|
|
72
|
+
const usageRecord = await dynamodbSharedLib.getItem(
|
|
73
|
+
_izContext,
|
|
74
|
+
dynamodbSharedLib.tableName(_izContext, 'RunningTotalUsage'),
|
|
75
|
+
{ identifiersConcat, limitTag }
|
|
76
|
+
);
|
|
77
|
+
if (usageRecord) {
|
|
78
|
+
const newTotal = Math.max(0, (usageRecord.totalCount || 0) - usageCount);
|
|
79
|
+
await dynamodbSharedLib.putItem(
|
|
80
|
+
_izContext,
|
|
81
|
+
dynamodbSharedLib.tableName(_izContext, 'RunningTotalUsage'),
|
|
82
|
+
{
|
|
83
|
+
identifiersConcat,
|
|
84
|
+
limitTag,
|
|
85
|
+
totalCount: newTotal,
|
|
86
|
+
updateUuid: _izContext.uniqueRequestId || `${Date.now()}`
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
await sns.publishMessage(_izContext, {
|
|
93
|
+
message: { returnResult: { status: true, uniqueIdentify } },
|
|
94
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
95
|
+
_izContext,
|
|
96
|
+
'CancelUsage_Out'
|
|
97
|
+
)
|
|
98
|
+
});
|
|
99
|
+
} catch (error) {
|
|
100
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:CancelUsage] error:`, error);
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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 ConfirmUsage(_izContext, requestParams) {
|
|
24
|
+
try {
|
|
25
|
+
const submittedByUserId =
|
|
26
|
+
requestParams.submittedByUserId ||
|
|
27
|
+
_izContext.correlationIds?.get(consts.SUBMITTED_BY_USER_ID);
|
|
28
|
+
const { limitTag, uniqueIdentify } = requestParams;
|
|
29
|
+
|
|
30
|
+
const targetIdentifiers = requestParams.targetIdentifiers;
|
|
31
|
+
let identifiersConcat = requestParams.identifiersConcat;
|
|
32
|
+
if (!identifiersConcat && targetIdentifiers && typeof targetIdentifiers === 'object') {
|
|
33
|
+
identifiersConcat = Object.entries(targetIdentifiers)
|
|
34
|
+
.map(([k, v]) => `${k}#${v}`)
|
|
35
|
+
.join('_');
|
|
36
|
+
}
|
|
37
|
+
if (!identifiersConcat) {
|
|
38
|
+
identifiersConcat = submittedByUserId;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!identifiersConcat || !limitTag || !uniqueIdentify) {
|
|
42
|
+
throw new NoRetryError(
|
|
43
|
+
'identifiersConcat, limitTag, and uniqueIdentify are required.'
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const runningTotalReservedId = `${identifiersConcat}_${limitTag}`;
|
|
48
|
+
await dynamodbSharedLib.updateItem(
|
|
49
|
+
_izContext,
|
|
50
|
+
dynamodbSharedLib.tableName(_izContext, 'RunningTotalReservedUsage'),
|
|
51
|
+
{
|
|
52
|
+
runningTotalReservedId,
|
|
53
|
+
usedTimestampId: uniqueIdentify
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
runningTotalUsageStatus: 'confirmed'
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
await sns.publishMessage(_izContext, {
|
|
61
|
+
message: { returnResult: { status: true, uniqueIdentify } },
|
|
62
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
63
|
+
_izContext,
|
|
64
|
+
'ConfirmUsage_Out'
|
|
65
|
+
)
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:ConfirmUsage] error:`, error);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -23,23 +23,66 @@ import { consts } from '@izara_project/izara-core-library-core';
|
|
|
23
23
|
|
|
24
24
|
export default async function CreateTargetRole(_izContext, requestParams) {
|
|
25
25
|
try {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const submittedByUserId =
|
|
27
|
+
requestParams.submittedByUserId ||
|
|
28
|
+
_izContext.correlationIds?.get(consts.SUBMITTED_BY_USER_ID);
|
|
29
|
+
|
|
30
|
+
const targetIdentifiers = requestParams.targetIdentifiers;
|
|
31
|
+
let identifiersConcat = requestParams.identifiersConcat;
|
|
32
|
+
if (!identifiersConcat && targetIdentifiers && typeof targetIdentifiers === 'object') {
|
|
33
|
+
identifiersConcat = Object.entries(targetIdentifiers)
|
|
34
|
+
.map(([k, v]) => `${k}#${v}`)
|
|
35
|
+
.join('_');
|
|
36
|
+
}
|
|
37
|
+
if (!identifiersConcat) {
|
|
38
|
+
identifiersConcat = submittedByUserId;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const { roleName = 'owner', roleId: inputRoleId } = requestParams;
|
|
42
|
+
const roleId = inputRoleId || roleName || identifierUuid();
|
|
43
|
+
const roleIdKey = `${identifiersConcat}_${roleId}`;
|
|
44
|
+
|
|
29
45
|
await dynamodbSharedLib.putItem(
|
|
30
46
|
_izContext,
|
|
31
47
|
dynamodbSharedLib.tableName(_izContext, 'TargetRoles'),
|
|
32
|
-
{
|
|
48
|
+
{
|
|
49
|
+
identifiersConcat,
|
|
50
|
+
roleIdKey,
|
|
51
|
+
roleName,
|
|
52
|
+
submittedByUserId
|
|
53
|
+
}
|
|
33
54
|
);
|
|
55
|
+
|
|
56
|
+
if (submittedByUserId) {
|
|
57
|
+
try {
|
|
58
|
+
await dynamodbSharedLib.transactWriteItems(_izContext, [
|
|
59
|
+
{
|
|
60
|
+
Put: {
|
|
61
|
+
TableName: dynamodbSharedLib.tableName(_izContext, 'RoleUsers'),
|
|
62
|
+
Item: { roleIdKey, submittedByUserId }
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
Put: {
|
|
67
|
+
TableName: dynamodbSharedLib.tableName(_izContext, 'UserRoles'),
|
|
68
|
+
Item: { submittedByUserId, roleIdKey }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
]);
|
|
72
|
+
} catch (assignError) {
|
|
73
|
+
_izContext.logger.debug(`[${process.env.iz_serviceTag}:CreateTargetRole] UserRoles transactWrite ignored:', assignError);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
34
77
|
await sns.publishMessage(_izContext, {
|
|
35
|
-
message: { returnResult: { roleId } },
|
|
78
|
+
message: { returnResult: { roleId, roleIdKey } },
|
|
36
79
|
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
37
80
|
_izContext,
|
|
38
81
|
'CreateTargetRole_Out'
|
|
39
82
|
)
|
|
40
83
|
});
|
|
41
84
|
} catch (error) {
|
|
42
|
-
_izContext.logger.error(
|
|
85
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:CreateTargetRole] error:`, error);
|
|
43
86
|
throw error;
|
|
44
87
|
}
|
|
45
88
|
}
|
|
@@ -22,8 +22,14 @@ import { consts, NoRetryError } from '@izara_project/izara-core-library-core';
|
|
|
22
22
|
|
|
23
23
|
export default async function <%- flowTag %>(_izContext, requestParams) {
|
|
24
24
|
try {
|
|
25
|
-
<% if (
|
|
26
|
-
const userId = _izContext.correlationIds.get(consts.
|
|
25
|
+
<% if (flowTag === 'ListTargetRole') { -%>
|
|
26
|
+
const userId = requestParams.submittedByUserId || _izContext.correlationIds.get(consts.SUBMITTED_BY_USER_ID);
|
|
27
|
+
const identifiersConcat =
|
|
28
|
+
requestParams.identifiersConcat || requestParams.targetId || userId;
|
|
29
|
+
if (!identifiersConcat) throw new NoRetryError('Identifier not found.');
|
|
30
|
+
const queryParams = { identifiersConcat };
|
|
31
|
+
<% } else if (useContextUserId) { -%>
|
|
32
|
+
const userId = requestParams.submittedByUserId || _izContext.correlationIds.get(consts.SUBMITTED_BY_USER_ID);
|
|
27
33
|
if (!userId) throw new NoRetryError('User Id not found.');
|
|
28
34
|
const queryParams = { userId };
|
|
29
35
|
<% } else { -%>
|
|
@@ -43,7 +49,7 @@ export default async function <%- flowTag %>(_izContext, requestParams) {
|
|
|
43
49
|
)
|
|
44
50
|
});
|
|
45
51
|
} catch (error) {
|
|
46
|
-
_izContext.logger.error(
|
|
52
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:<%- flowTag %>] error:`, error);
|
|
47
53
|
throw error;
|
|
48
54
|
}
|
|
49
55
|
}
|
|
@@ -36,7 +36,7 @@ export default async function <%- flowTag %>(_izContext, requestParams) {
|
|
|
36
36
|
)
|
|
37
37
|
});
|
|
38
38
|
} catch (error) {
|
|
39
|
-
_izContext.logger.error(
|
|
39
|
+
_izContext.logger.error(`[${process.env.iz_serviceTag}:<%- flowTag %>] error:`, error);
|
|
40
40
|
throw error;
|
|
41
41
|
}
|
|
42
42
|
}
|