k2hr3-api 1.0.42 → 2.0.0

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 (149) hide show
  1. package/config/k2hr3-init.sh.templ +2 -2
  2. package/dist/.gitkeep +0 -0
  3. package/dist/src/app.js +262 -0
  4. package/{bin → dist/src/bin}/run.sh +1 -1
  5. package/dist/src/bin/watcher.js +113 -0
  6. package/dist/src/bin/www.js +217 -0
  7. package/dist/src/lib/basicipcheck.js +392 -0
  8. package/dist/src/lib/cacerts.js +106 -0
  9. package/dist/src/lib/dbglogging.js +190 -0
  10. package/dist/src/lib/dummyuserapi.js +719 -0
  11. package/dist/src/lib/ipwatch.js +354 -0
  12. package/dist/src/lib/k2hr3acrutil.js +532 -0
  13. package/dist/src/lib/k2hr3apiutil.js +1444 -0
  14. package/dist/src/lib/k2hr3cliutil.js +183 -0
  15. package/dist/src/lib/k2hr3config.js +832 -0
  16. package/dist/src/lib/k2hr3cryptutil.js +258 -0
  17. package/dist/src/lib/k2hr3dkc.js +12121 -0
  18. package/dist/src/lib/k2hr3extdata.js +198 -0
  19. package/dist/src/lib/k2hr3keys.js +207 -0
  20. package/dist/src/lib/k2hr3resutil.js +111 -0
  21. package/dist/src/lib/k2hr3template.js +6546 -0
  22. package/dist/src/lib/k2hr3tokens.js +2643 -0
  23. package/dist/src/lib/k2hr3userdata.js +296 -0
  24. package/dist/src/lib/k8soidc.js +1000 -0
  25. package/dist/src/lib/openstackapiv2.js +695 -0
  26. package/dist/src/lib/openstackapiv3.js +932 -0
  27. package/dist/src/lib/openstackep.js +667 -0
  28. package/{tests/auto_common.js → dist/src/lib/types.js} +4 -38
  29. package/dist/src/routes/acr.js +704 -0
  30. package/dist/src/routes/debugVerify.js +294 -0
  31. package/dist/src/routes/extdata.js +219 -0
  32. package/dist/src/routes/list.js +264 -0
  33. package/dist/src/routes/policy.js +840 -0
  34. package/dist/src/routes/resource.js +1489 -0
  35. package/dist/src/routes/role.js +2627 -0
  36. package/dist/src/routes/service.js +908 -0
  37. package/dist/src/routes/tenant.js +1141 -0
  38. package/dist/src/routes/userTokens.js +482 -0
  39. package/dist/src/routes/userdata.js +212 -0
  40. package/dist/src/routes/version.js +103 -0
  41. package/package.json +152 -121
  42. package/ChangeLog +0 -378
  43. package/app.js +0 -292
  44. package/bin/watcher +0 -122
  45. package/bin/www +0 -180
  46. package/eslint.config.mjs +0 -68
  47. package/lib/basicipcheck.js +0 -376
  48. package/lib/cacerts.js +0 -71
  49. package/lib/dbglogging.js +0 -151
  50. package/lib/dummyuserapi.js +0 -766
  51. package/lib/ipwatch.js +0 -379
  52. package/lib/k2hr3acrutil.js +0 -516
  53. package/lib/k2hr3apiutil.js +0 -1494
  54. package/lib/k2hr3cliutil.js +0 -191
  55. package/lib/k2hr3config.js +0 -826
  56. package/lib/k2hr3cryptutil.js +0 -254
  57. package/lib/k2hr3dkc.js +0 -12632
  58. package/lib/k2hr3extdata.js +0 -198
  59. package/lib/k2hr3keys.js +0 -234
  60. package/lib/k2hr3resutil.js +0 -100
  61. package/lib/k2hr3template.js +0 -6925
  62. package/lib/k2hr3tokens.js +0 -2799
  63. package/lib/k2hr3userdata.js +0 -312
  64. package/lib/k8soidc.js +0 -1012
  65. package/lib/openstackapiv2.js +0 -764
  66. package/lib/openstackapiv3.js +0 -1032
  67. package/lib/openstackep.js +0 -553
  68. package/routes/acr.js +0 -738
  69. package/routes/debugVerify.js +0 -263
  70. package/routes/extdata.js +0 -232
  71. package/routes/list.js +0 -270
  72. package/routes/policy.js +0 -869
  73. package/routes/resource.js +0 -1441
  74. package/routes/role.js +0 -2664
  75. package/routes/service.js +0 -894
  76. package/routes/tenant.js +0 -1095
  77. package/routes/userTokens.js +0 -511
  78. package/routes/userdata.js +0 -218
  79. package/routes/version.js +0 -108
  80. package/templ/Dockerfile.templ +0 -71
  81. package/tests/auto_acr.js +0 -1101
  82. package/tests/auto_acr_spec.js +0 -79
  83. package/tests/auto_all_spec.js +0 -142
  84. package/tests/auto_control_subprocess.sh +0 -243
  85. package/tests/auto_extdata.js +0 -220
  86. package/tests/auto_extdata_spec.js +0 -79
  87. package/tests/auto_init_config_json.sh +0 -275
  88. package/tests/auto_k2hdkc_server.ini +0 -109
  89. package/tests/auto_k2hdkc_slave.ini +0 -83
  90. package/tests/auto_list.js +0 -439
  91. package/tests/auto_list_spec.js +0 -79
  92. package/tests/auto_policy.js +0 -1579
  93. package/tests/auto_policy_spec.js +0 -79
  94. package/tests/auto_resource.js +0 -10956
  95. package/tests/auto_resource_spec.js +0 -79
  96. package/tests/auto_role.js +0 -6150
  97. package/tests/auto_role_spec.js +0 -79
  98. package/tests/auto_service.js +0 -770
  99. package/tests/auto_service_spec.js +0 -79
  100. package/tests/auto_subprocesses.js +0 -114
  101. package/tests/auto_template.sh +0 -126
  102. package/tests/auto_tenant.js +0 -1100
  103. package/tests/auto_tenant_spec.js +0 -79
  104. package/tests/auto_token_util.js +0 -219
  105. package/tests/auto_userdata.js +0 -292
  106. package/tests/auto_userdata_spec.js +0 -79
  107. package/tests/auto_usertokens.js +0 -565
  108. package/tests/auto_usertokens_spec.js +0 -79
  109. package/tests/auto_version.js +0 -127
  110. package/tests/auto_version_spec.js +0 -79
  111. package/tests/auto_watcher.js +0 -157
  112. package/tests/auto_watcher_spec.js +0 -79
  113. package/tests/k2hdkc_test.data +0 -986
  114. package/tests/k2hdkc_test_load.sh +0 -255
  115. package/tests/k2hr3template_test.js +0 -187
  116. package/tests/k2hr3template_test.sh +0 -339
  117. package/tests/k2hr3template_test_async.js +0 -216
  118. package/tests/k2hr3template_test_template.result +0 -7117
  119. package/tests/k2hr3template_test_template.txt +0 -3608
  120. package/tests/k2hr3template_test_vars.js +0 -194
  121. package/tests/manual_acr_delete.js +0 -143
  122. package/tests/manual_acr_get.js +0 -297
  123. package/tests/manual_acr_postput.js +0 -215
  124. package/tests/manual_allusertenant_get.js +0 -113
  125. package/tests/manual_extdata_get.js +0 -191
  126. package/tests/manual_k2hr3keys_get.js +0 -84
  127. package/tests/manual_list_gethead.js +0 -230
  128. package/tests/manual_policy_delete.js +0 -132
  129. package/tests/manual_policy_gethead.js +0 -275
  130. package/tests/manual_policy_postput.js +0 -297
  131. package/tests/manual_resource_delete.js +0 -433
  132. package/tests/manual_resource_gethead.js +0 -423
  133. package/tests/manual_resource_postput.js +0 -487
  134. package/tests/manual_role_delete.js +0 -404
  135. package/tests/manual_role_gethead.js +0 -547
  136. package/tests/manual_role_postput.js +0 -544
  137. package/tests/manual_service_delete.js +0 -153
  138. package/tests/manual_service_gethead.js +0 -178
  139. package/tests/manual_service_postput.js +0 -348
  140. package/tests/manual_tenant_delete.js +0 -186
  141. package/tests/manual_tenant_gethead.js +0 -268
  142. package/tests/manual_tenant_postput.js +0 -293
  143. package/tests/manual_test.sh +0 -352
  144. package/tests/manual_userdata_get.js +0 -173
  145. package/tests/manual_usertoken_gethead.js +0 -136
  146. package/tests/manual_usertoken_postput.js +0 -310
  147. package/tests/manual_version_get.js +0 -127
  148. package/tests/run_local_test_k2hdkc.sh +0 -174
  149. package/tests/test.sh +0 -333
@@ -0,0 +1,1141 @@
1
+ "use strict";
2
+ /*
3
+ * K2HR3 REST API
4
+ *
5
+ * Copyright 2023 Yahoo Japan Corporation.
6
+ *
7
+ * K2HR3 is K2hdkc based Resource and Roles and policy Rules, gathers
8
+ * common management information for the cloud.
9
+ * K2HR3 can dynamically manage information as "who", "what", "operate".
10
+ * These are stored as roles, resources, policies in K2hdkc, and the
11
+ * client system can dynamically read and modify these information.
12
+ *
13
+ * For the full copyright and license information, please view
14
+ * the license file that was distributed with this source code.
15
+ *
16
+ * AUTHOR: Takeshi Nakatani
17
+ * CREATE: Mon Sep 3 2023
18
+ * REVISION:
19
+ *
20
+ */
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ const k2hr3apiutil_1 = __importDefault(require("../lib/k2hr3apiutil"));
26
+ const k2hr3resutil_1 = __importDefault(require("../lib/k2hr3resutil"));
27
+ const k2hr3tokens_1 = __importDefault(require("../lib/k2hr3tokens"));
28
+ const k2hr3dkc_1 = __importDefault(require("../lib/k2hr3dkc"));
29
+ const dbglogging_1 = __importDefault(require("../lib/dbglogging"));
30
+ const express_1 = __importDefault(require("express"));
31
+ const k2hr3keys_1 = require("../lib/k2hr3keys");
32
+ const r3keys = k2hr3keys_1.getK2hr3Keys;
33
+ const router = express_1.default.Router();
34
+ //=========================================================
35
+ // CAUTION
36
+ //---------------------------------------------------------
37
+ // This note is common to the TENANT API.
38
+ //
39
+ // TENANT API requires User Unscoped Token or User Scoped
40
+ // Token.
41
+ // Note that even if a User Scoped Token is specified, that
42
+ // scoped Tenant will be ignored.
43
+ // To specify the tenant of each API, use URI path or parameter
44
+ // instead of Token.
45
+ // Specify the tenant only by the tenant name, not by the YRN
46
+ // full path.
47
+ //
48
+ //=========================================================
49
+ // Common Utility function
50
+ //=========================================================
51
+ //
52
+ // Utility for parsing common input parameters
53
+ //
54
+ // This function parse token(user or role or not have this) from HTTP request(req),
55
+ // and tenant name, etc.
56
+ //
57
+ // return {
58
+ // result: true/false
59
+ // message: null or error message
60
+ // status: status code(default 200)
61
+ // parameters: {
62
+ // token_type: null or 'user' or 'role'
63
+ // token_str: token string(if user token or role token)
64
+ // token_info: null or object(returned from checkToken)
65
+ // user_name: null or user name(if user token)
66
+ // tenant_name: null or tenant name in request uri path
67
+ // keys: k2hr3keys object
68
+ // }
69
+ // }
70
+ //
71
+ const rawParseBaseParamInRequest = (req) => {
72
+ const parameters = {
73
+ token_type: null,
74
+ token_str: null,
75
+ token_info: null,
76
+ token_tenant: null,
77
+ user_name: null,
78
+ tenant_name: null,
79
+ keys: r3keys() // temporary
80
+ };
81
+ const result = {
82
+ result: true,
83
+ message: null,
84
+ status: 200,
85
+ parameters: parameters
86
+ };
87
+ //
88
+ // check token for API mode
89
+ //
90
+ if (k2hr3tokens_1.default.hasAuthTokenHeader(req)) {
91
+ const token_result = k2hr3tokens_1.default.checkToken(req, false, true); // (un)scoped, user
92
+ if (!token_result.result) {
93
+ result.result = token_result.result;
94
+ result.message = token_result.message;
95
+ result.status = token_result.status;
96
+ dbglogging_1.default.elog(result.message);
97
+ return result;
98
+ }
99
+ if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_result.token_info)) {
100
+ result.result = false;
101
+ result.message = 'specified wrong token or it is not scoped user token';
102
+ result.status = 400; // 400: Bad Request
103
+ dbglogging_1.default.elog(result.message);
104
+ return result;
105
+ }
106
+ result.parameters.token_str = token_result.token ?? null;
107
+ result.parameters.token_type = token_result.token_type ?? null;
108
+ result.parameters.token_info = token_result.token_info;
109
+ result.parameters.user_name = k2hr3apiutil_1.default.getSafeString(result.parameters.token_info.user);
110
+ }
111
+ //
112
+ // get tenant name from uri
113
+ //
114
+ const requestptn = new RegExp('^/v1/tenant/(.*)'); // regex = /^\/v1\/tenant\/(.*)/
115
+ const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
116
+ if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
117
+ result.parameters.tenant_name = null;
118
+ }
119
+ else {
120
+ // check tenant name
121
+ if (0 !== reqmatchs[1].indexOf(result.parameters.keys.VALUE_PREFIX_LOCAL_TENANT)) {
122
+ // Not have prefix("local@")
123
+ const tmp_tenant_name = result.parameters.keys.VALUE_PREFIX_LOCAL_TENANT + reqmatchs[1];
124
+ result.parameters.tenant_name = tmp_tenant_name.toLowerCase();
125
+ }
126
+ else {
127
+ result.parameters.tenant_name = reqmatchs[1].toLowerCase();
128
+ }
129
+ }
130
+ // keys
131
+ result.parameters.keys = r3keys(result.parameters.user_name, result.parameters.tenant_name);
132
+ return result;
133
+ };
134
+ //
135
+ // Utility for Create/Update tenant for POST/PUT
136
+ //
137
+ // is_create : true/false
138
+ // user_name : add main user name for tenant
139
+ // tenant_name : tenant name
140
+ // tenant_id : tenant id
141
+ // tenant_desc : tenant description
142
+ // tenant_display : tenant display name
143
+ // tenant_users : other tenant user names
144
+ //
145
+ // result {
146
+ // result: true/false
147
+ // message: error message
148
+ // rescode: 200/201/4xx/5xx
149
+ // }
150
+ //
151
+ const rawCreateUpdateTenant = (is_create, user_name, tenant_name, tenant_id, tenant_desc, tenant_display, tenant_users) => {
152
+ let result_status;
153
+ if (is_create) {
154
+ //
155
+ // Create tenant
156
+ //
157
+ const resobj = k2hr3dkc_1.default.findTenant(tenant_name);
158
+ if (k2hr3apiutil_1.default.isPlainObject(resobj) && k2hr3apiutil_1.default.isBoolean(resobj.result) && true === resobj.result) {
159
+ const result = {
160
+ result: false,
161
+ message: 'failed to create tenant by already tenant(' + tenant_name + ') existed',
162
+ status: 400
163
+ };
164
+ dbglogging_1.default.elog(result.message);
165
+ return result;
166
+ }
167
+ result_status = 201; // 201: Created
168
+ }
169
+ else {
170
+ //
171
+ // Update tenant
172
+ //
173
+ const resobj = k2hr3dkc_1.default.findTenant(tenant_name, user_name, tenant_id);
174
+ if (!k2hr3apiutil_1.default.isPlainObject(resobj) || !k2hr3apiutil_1.default.isBoolean(resobj.result) || false === resobj.result) {
175
+ if (k2hr3apiutil_1.default.isPlainObject(resobj) && k2hr3apiutil_1.default.isSafeString(resobj.message)) {
176
+ const result = {
177
+ result: false,
178
+ message: 'failed to update tenant by ' + k2hr3apiutil_1.default.getSafeString(resobj.message),
179
+ status: 400
180
+ };
181
+ dbglogging_1.default.elog(result.message);
182
+ return result;
183
+ }
184
+ else {
185
+ const result = {
186
+ result: false,
187
+ message: 'failed to update tenant by unknown reason',
188
+ status: 400
189
+ };
190
+ dbglogging_1.default.elog(result.message);
191
+ return result;
192
+ }
193
+ }
194
+ result_status = 200; // 200: OK
195
+ }
196
+ //
197
+ // Create/Update tenant
198
+ //
199
+ const init_resobj = k2hr3dkc_1.default.initTenant(tenant_name, tenant_id, tenant_desc, tenant_display, user_name, tenant_users);
200
+ if (!k2hr3apiutil_1.default.isPlainObject(init_resobj) || !k2hr3apiutil_1.default.isBoolean(init_resobj.result) || false === init_resobj.result) {
201
+ if (k2hr3apiutil_1.default.isPlainObject(init_resobj) && k2hr3apiutil_1.default.isSafeString(init_resobj.message)) {
202
+ const result = {
203
+ result: false,
204
+ message: 'failed to create tenant by ' + k2hr3apiutil_1.default.getSafeString(init_resobj.message),
205
+ status: 400
206
+ };
207
+ dbglogging_1.default.elog(result.message);
208
+ return result;
209
+ }
210
+ else {
211
+ const result = {
212
+ result: false,
213
+ message: 'failed to create tenant by unknown reason',
214
+ status: 400
215
+ };
216
+ dbglogging_1.default.elog(result.message);
217
+ return result;
218
+ }
219
+ }
220
+ const resobj = {
221
+ result: true,
222
+ message: null,
223
+ status: result_status
224
+ };
225
+ return resobj;
226
+ };
227
+ //=========================================================
228
+ // Router POST
229
+ //=========================================================
230
+ //
231
+ // Mountpath : '/v1/tenant'
232
+ //
233
+ //---------------------------------------------------------
234
+ // [POST] No tenant path
235
+ //---------------------------------------------------------
236
+ // POST '/v1/tenant' : create tenant version 1
237
+ // HEADER : X-Auth-Token = <User token>
238
+ // body : {
239
+ // "tenant": {
240
+ // "name": <tenant> => key is "yrn:yahoo:::<tenant>"
241
+ // thix value type must be string.
242
+ // "desc": <description> => value for "yrn:yahoo:::<tenant>:desc"
243
+ // thix value type must be string.
244
+ // "display": <display name> => key is "yrn:yahoo:::<tenant>:display"
245
+ // thix value type must be string.
246
+ // "users": <user> or [user, ...] => key is "yrn:yahoo::::user:<user>"
247
+ // specify adding user array which is yrn path as "yrn:yahoo::::user:<user>" or "user name"
248
+ // }
249
+ // }
250
+ //
251
+ // response status code : 201 or 4xx/5xx
252
+ // response body : {
253
+ // result: true/false
254
+ // message: messages
255
+ // }
256
+ //
257
+ // Create a tenant as <K2HR3 cluster LOCAL> tenant.
258
+ //
259
+ // [NOTE]
260
+ // If the <K2HR3 cluster LOCAL> tenant already exists, this repsponses an error.
261
+ //
262
+ // Tenant names must start with "local@"(if not set it, this prefix adds automatically).
263
+ // Specify the user by YRN full path or user name.
264
+ // If the user indicated by <User Token> does not exist, it will be added.
265
+ // New tenant id is set automatically.
266
+ //
267
+ //---------------------------------------------------------
268
+ // [POST] With tenant path
269
+ //---------------------------------------------------------
270
+ // POST '/v1/tenant/tenant' : update tenant version 1
271
+ // HEADER : X-Auth-Token = <User token>
272
+ // body : {
273
+ // "tenant": {
274
+ // "id": <id> => key is "yrn:yahoo:::<tenant>:id"
275
+ // this value type must be string.
276
+ // "desc": <description> => value for "yrn:yahoo:::<tenant>:desc"
277
+ // thix value type must be string.
278
+ // "display": <display name> => key is "yrn:yahoo:::<tenant>:display"
279
+ // thix value type must be string.
280
+ // "users": <user> or [user, ...] => key is "yrn:yahoo::::user:<user>"
281
+ // specify adding user array which is yrn path as "yrn:yahoo::::user:<user>" or "user name"
282
+ // }
283
+ // }
284
+ //
285
+ // response status code : 200 or 4xx/5xx
286
+ // response body : {
287
+ // result: true/false
288
+ // message: messages
289
+ // }
290
+ //
291
+ // Update existed tenant as <K2HR3 cluster LOCAL> tenant.
292
+ //
293
+ // [NOTE]
294
+ // If the <K2HR3 cluster LOCAL> tenant does not exist, this repsponses an error.
295
+ // Tenant names must start with "local@"(if not set it, this prefix adds automatically for search).
296
+ // The <User Token> user must be included in the tenant's user list.
297
+ //
298
+ // Specify the user by YRN full path or user name.
299
+ // If the user indicated by <User Token> does not exist, it will be added.
300
+ //
301
+ router.post('/', (req, res, _) => {
302
+ dbglogging_1.default.dlog('CALL:', req.method, req.url);
303
+ res.type('application/json; charset=utf-8');
304
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
305
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl) ||
306
+ !k2hr3apiutil_1.default.isPlainObject(req.body) ||
307
+ !k2hr3apiutil_1.default.isPlainObject(req.body.tenant)) {
308
+ const result = {
309
+ result: false,
310
+ message: 'POST body does not have tenant data'
311
+ };
312
+ dbglogging_1.default.elog(result.message);
313
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
314
+ return;
315
+ }
316
+ //------------------------------
317
+ // check common parameters(token, tenant etc)
318
+ //------------------------------
319
+ const resobj = rawParseBaseParamInRequest(req);
320
+ if (!resobj.result) {
321
+ const result = {
322
+ result: resobj.result,
323
+ message: resobj.message
324
+ };
325
+ dbglogging_1.default.elog(resobj.message);
326
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status, result);
327
+ return;
328
+ }
329
+ const comparam = resobj.parameters;
330
+ //------------------------------
331
+ // check token type
332
+ //------------------------------
333
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
334
+ const result = {
335
+ result: false,
336
+ message: 'POST request tenant must specify <User Token>'
337
+ };
338
+ dbglogging_1.default.elog(result.message);
339
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
340
+ return;
341
+ }
342
+ //------------------------------
343
+ // check arguments
344
+ //------------------------------
345
+ let is_create;
346
+ let tenant_name;
347
+ let tenant_id;
348
+ let tenant_desc;
349
+ let tenant_display;
350
+ let tenant_users = [];
351
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.tenant_name)) {
352
+ //
353
+ // Create mode
354
+ //
355
+ is_create = true;
356
+ tenant_name = k2hr3apiutil_1.default.getSafeString(req.body.tenant.name).toLowerCase();
357
+ tenant_id = k2hr3apiutil_1.default.getStrUuid4(); // Create new id here.
358
+ if (!k2hr3apiutil_1.default.isSafeString(tenant_name)) {
359
+ const result = {
360
+ result: false,
361
+ message: 'POST request tenant body does not have tenant.name string object.'
362
+ };
363
+ dbglogging_1.default.elog(result.message);
364
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
365
+ return;
366
+ }
367
+ if (0 !== tenant_name.indexOf(comparam.keys.VALUE_PREFIX_LOCAL_TENANT)) {
368
+ // Not have prefix("local@")
369
+ tenant_name = comparam.keys.VALUE_PREFIX_LOCAL_TENANT + tenant_name;
370
+ }
371
+ }
372
+ else {
373
+ //
374
+ // Update mode
375
+ //
376
+ is_create = false;
377
+ tenant_name = comparam.tenant_name;
378
+ tenant_id = k2hr3apiutil_1.default.getSafeString(req.body.tenant.id);
379
+ if (!k2hr3apiutil_1.default.isSafeString(tenant_id)) {
380
+ const result = {
381
+ result: false,
382
+ message: 'POST request tenant(' + tenant_name + ') body does not have tenant.id string object.'
383
+ };
384
+ dbglogging_1.default.elog(result.message);
385
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
386
+ return;
387
+ }
388
+ }
389
+ if (k2hr3apiutil_1.default.isSafeString(req.body.tenant.desc)) {
390
+ tenant_desc = k2hr3apiutil_1.default.getSafeString(req.body.tenant.desc);
391
+ }
392
+ else {
393
+ tenant_desc = 'K2HR3 Cluster Local tenant';
394
+ }
395
+ if (k2hr3apiutil_1.default.isSafeString(req.body.tenant.display)) {
396
+ tenant_display = k2hr3apiutil_1.default.getSafeString(req.body.tenant.display);
397
+ }
398
+ else {
399
+ tenant_display = tenant_name;
400
+ }
401
+ //
402
+ // Check users
403
+ //
404
+ if (k2hr3apiutil_1.default.isSafeString(req.body.tenant.users)) {
405
+ tenant_users = [req.body.tenant.users.trim()];
406
+ }
407
+ else if (k2hr3apiutil_1.default.isStringArray(req.body.tenant.users)) {
408
+ tenant_users = k2hr3apiutil_1.default.getSafeArray(req.body.tenant.users);
409
+ }
410
+ if (is_create) {
411
+ // add own user
412
+ if (k2hr3apiutil_1.default.isSafeString(comparam.user_name)) {
413
+ k2hr3apiutil_1.default.tryAddStringToArray(tenant_users, comparam.user_name);
414
+ }
415
+ }
416
+ else {
417
+ if (!k2hr3apiutil_1.default.isStringArray(tenant_users) || !k2hr3apiutil_1.default.isNotEmptyArray(tenant_users)) {
418
+ const result = {
419
+ result: false,
420
+ message: 'POST request tenant(' + JSON.stringify(tenant_name) + ') does not have any user list.'
421
+ };
422
+ dbglogging_1.default.elog(result.message);
423
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
424
+ return;
425
+ }
426
+ const findobj = k2hr3dkc_1.default.findTenant(tenant_name, comparam.user_name, tenant_id);
427
+ if (!k2hr3apiutil_1.default.isPlainObject(findobj) ||
428
+ !k2hr3apiutil_1.default.isBoolean(findobj.result) ||
429
+ false === findobj.result ||
430
+ !k2hr3dkc_1.default.isDkcTypeTenantInfo(findobj.tenant) ||
431
+ !k2hr3apiutil_1.default.isSafeString(findobj.tenant.name) ||
432
+ !k2hr3apiutil_1.default.isStringArray(findobj.tenant.users) ||
433
+ !k2hr3apiutil_1.default.findStringInArray(findobj.tenant.users, comparam.user_name)) {
434
+ const result = {
435
+ result: false,
436
+ message: 'POST request tenant(' + tenant_name + ') does not allow user(' + comparam.user_name + ').'
437
+ };
438
+ dbglogging_1.default.elog(result.message);
439
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
440
+ return;
441
+ }
442
+ }
443
+ if (k2hr3apiutil_1.default.isArray(tenant_users)) {
444
+ tenant_users.sort();
445
+ }
446
+ //------------------------------
447
+ // Processing
448
+ //------------------------------
449
+ const create_result = rawCreateUpdateTenant(is_create, (comparam.user_name ?? ''), tenant_name, tenant_id, tenant_desc, tenant_display, tenant_users);
450
+ if (!k2hr3apiutil_1.default.isPlainObject(create_result) || !k2hr3apiutil_1.default.isBoolean(create_result.result) || !k2hr3apiutil_1.default.isSafeNumber(create_result.status) || false === create_result.result) {
451
+ if (k2hr3apiutil_1.default.isPlainObject(create_result) && k2hr3apiutil_1.default.isSafeString(create_result.message)) {
452
+ const result = {
453
+ result: false,
454
+ message: 'POST request failed to update tenant by ' + k2hr3apiutil_1.default.getSafeString(create_result.message)
455
+ };
456
+ dbglogging_1.default.elog(result.message);
457
+ k2hr3resutil_1.default.errResponse(req, res, (create_result?.status ?? 500), result);
458
+ }
459
+ else {
460
+ const result = {
461
+ result: false,
462
+ message: 'POST request failed to update tenant by unknown reason'
463
+ };
464
+ dbglogging_1.default.elog(result.message);
465
+ k2hr3resutil_1.default.errResponse(req, res, (k2hr3apiutil_1.default.isSafeNumber(create_result.status) ? create_result.status : 500), result);
466
+ }
467
+ return;
468
+ }
469
+ dbglogging_1.default.dlog('succeed : create/update tenant(' + JSON.stringify(tenant_name) + ') by user(' + JSON.stringify(comparam.user_name) + ')');
470
+ const success_result = {
471
+ result: true,
472
+ message: null
473
+ };
474
+ res.status(create_result.status ?? 200); // 200 or 201
475
+ res.send(JSON.stringify(success_result));
476
+ });
477
+ //=========================================================
478
+ // Router PUT
479
+ //=========================================================
480
+ //
481
+ // Mountpath : '/v1/tenant'
482
+ //
483
+ //---------------------------------------------------------
484
+ // [PUT] No tenant path
485
+ //---------------------------------------------------------
486
+ // PUT '/v1/tenant' : create tenant version 1
487
+ // HEADER : X-Auth-Token = <User token>
488
+ // url argument :
489
+ // "name": <tenant> => key is "yrn:yahoo:::<tenant>"
490
+ // <tenant> must include the prefix "R3CLUSTERLOCAL-".
491
+ // "desc": <description> => value for "yrn:yahoo:::<tenant>:desc"
492
+ // thix value type must be string.
493
+ // "display": <display name> => key is "yrn:yahoo:::<tenant>:display"
494
+ // thix value type must be string.
495
+ // "users": <user> or [user, ...] => key is "yrn:yahoo::::user:<user>"
496
+ // specify adding user array which is yrn path as "yrn:yahoo::::user:<user>" or "user name"
497
+ //
498
+ // response status code : 201 or 4xx/5xx
499
+ // response body : {
500
+ // result: true/false
501
+ // message: messages
502
+ // }
503
+ //
504
+ // Create a tenant as <K2HR3 cluster LOCAL> tenant.
505
+ //
506
+ // [NOTE]
507
+ // If the <K2HR3 cluster LOCAL> tenant already exists, this repsponses an error.
508
+ //
509
+ // Tenant names must start with "R3CLUSTERLOCAL-".
510
+ // Specify the user by YRN full path or user name.
511
+ // If the user indicated by <User Token> does not exist, it will be added.
512
+ // New tenant id("R3CLUSTERLOCAL-xxxxxx") is set automatically.
513
+ //
514
+ //---------------------------------------------------------
515
+ // [PUT] With tenant path
516
+ //---------------------------------------------------------
517
+ // PUT '/v1/tenant/tenant' : update tenant version 1
518
+ // HEADER : X-Auth-Token = <User token>
519
+ // url argument :
520
+ // "id": <id> => key is "yrn:yahoo:::<tenant>:id"
521
+ // this value type must be string.
522
+ // "desc": <description> => value for "yrn:yahoo:::<tenant>:desc"
523
+ // thix value type must be string.
524
+ // "display": <display name> => key is "yrn:yahoo:::<tenant>:display"
525
+ // thix value type must be string.
526
+ // "users": <user> or [user, ...] => key is "yrn:yahoo::::user:<user>"
527
+ // specify adding user array which is yrn path as "yrn:yahoo::::user:<user>" or "user name"
528
+ //
529
+ // response status code : 200 or 4xx/5xx
530
+ // response body : {
531
+ // result: true/false
532
+ // message: messages
533
+ // }
534
+ //
535
+ // Update existed tenant as <K2HR3 cluster LOCAL> tenant.
536
+ //
537
+ // [NOTE]
538
+ // If the <K2HR3 cluster LOCAL> tenant does not exist, this repsponses an error.
539
+ // The <User Token> user must be included in the tenant's user list.
540
+ //
541
+ // Specify the user by YRN full path or user name.
542
+ // If the user indicated by <User Token> does not exist, it will be added.
543
+ //
544
+ router.put('/', (req, res, _) => {
545
+ dbglogging_1.default.dlog('CALL:', req.method, req.url);
546
+ res.type('application/json; charset=utf-8');
547
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
548
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl) ||
549
+ !k2hr3apiutil_1.default.isPlainObject(req.query)) {
550
+ const result = {
551
+ result: false,
552
+ message: 'PUT request is something wrong'
553
+ };
554
+ dbglogging_1.default.elog(result.message);
555
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
556
+ return;
557
+ }
558
+ //------------------------------
559
+ // check common parameters(token, tenant etc)
560
+ //------------------------------
561
+ const resobj = rawParseBaseParamInRequest(req);
562
+ if (!resobj.result) {
563
+ const result = {
564
+ result: resobj.result,
565
+ message: resobj.message
566
+ };
567
+ dbglogging_1.default.elog(resobj.message);
568
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status, result);
569
+ return;
570
+ }
571
+ const comparam = resobj.parameters;
572
+ //------------------------------
573
+ // check token type
574
+ //------------------------------
575
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
576
+ const result = {
577
+ result: false,
578
+ message: 'PUT request tenant must specify <User Token>'
579
+ };
580
+ dbglogging_1.default.elog(result.message);
581
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
582
+ return;
583
+ }
584
+ //------------------------------
585
+ // check arguments
586
+ //------------------------------
587
+ let is_create;
588
+ let tenant_name;
589
+ let tenant_id;
590
+ let tenant_desc;
591
+ let tenant_display;
592
+ let tenant_users = [];
593
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.tenant_name)) {
594
+ //
595
+ // Create mode
596
+ //
597
+ is_create = true;
598
+ tenant_name = k2hr3apiutil_1.default.getSafeString(req.query.name).toLowerCase();
599
+ tenant_id = k2hr3apiutil_1.default.getStrUuid4(); // Create new id here.
600
+ if (!k2hr3apiutil_1.default.isSafeString(tenant_name)) {
601
+ const result = {
602
+ result: false,
603
+ message: 'PUT request tenant body does not have tenant.name string object.'
604
+ };
605
+ dbglogging_1.default.elog(result.message);
606
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
607
+ return;
608
+ }
609
+ if (0 !== tenant_name.indexOf(comparam.keys.VALUE_PREFIX_LOCAL_TENANT)) {
610
+ // Not have prefix("local@")
611
+ tenant_name = comparam.keys.VALUE_PREFIX_LOCAL_TENANT + tenant_name;
612
+ }
613
+ }
614
+ else {
615
+ //
616
+ // Update mode
617
+ //
618
+ is_create = false;
619
+ tenant_name = comparam.tenant_name;
620
+ tenant_id = k2hr3apiutil_1.default.getSafeString(req.query.id);
621
+ if (!k2hr3apiutil_1.default.isSafeString(tenant_id)) {
622
+ const result = {
623
+ result: false,
624
+ message: 'PUT request tenant(' + tenant_name + ') body does not have tenant.id string object.'
625
+ };
626
+ dbglogging_1.default.elog(result.message);
627
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
628
+ return;
629
+ }
630
+ }
631
+ if (k2hr3apiutil_1.default.isSafeString(req.query.desc)) {
632
+ tenant_desc = k2hr3apiutil_1.default.getSafeString(req.query.desc);
633
+ }
634
+ else {
635
+ tenant_desc = 'K2HR3 Cluster Local tenant';
636
+ }
637
+ if (k2hr3apiutil_1.default.isSafeString(req.query.display)) {
638
+ tenant_display = k2hr3apiutil_1.default.getSafeString(req.query.display);
639
+ }
640
+ else {
641
+ tenant_display = tenant_name;
642
+ }
643
+ //
644
+ // Check users
645
+ //
646
+ if (k2hr3apiutil_1.default.checkSimpleJSON(req.query.users)) {
647
+ const tenant_users_tmp = k2hr3apiutil_1.default.parseJSON(req.query.users);
648
+ if (k2hr3apiutil_1.default.isSafeString(tenant_users_tmp)) {
649
+ tenant_users = [tenant_users_tmp];
650
+ }
651
+ else if (k2hr3apiutil_1.default.isStringArray(tenant_users_tmp)) {
652
+ tenant_users = k2hr3apiutil_1.default.getSafeArray(tenant_users_tmp);
653
+ }
654
+ }
655
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.users)) {
656
+ tenant_users = [req.query.users];
657
+ }
658
+ else if (k2hr3apiutil_1.default.isStringArray(req.query.users)) {
659
+ tenant_users = k2hr3apiutil_1.default.getSafeArray(req.query.users);
660
+ }
661
+ if (is_create) {
662
+ // add own user
663
+ if (k2hr3apiutil_1.default.isSafeString(comparam.user_name)) {
664
+ k2hr3apiutil_1.default.tryAddStringToArray(tenant_users, comparam.user_name);
665
+ }
666
+ }
667
+ else {
668
+ // check user in current tenant users
669
+ if (!k2hr3apiutil_1.default.isStringArray(tenant_users) || !k2hr3apiutil_1.default.isNotEmptyArray(tenant_users)) {
670
+ const result = {
671
+ result: false,
672
+ message: 'PUT request tenant(' + JSON.stringify(tenant_name) + ') does not have any user list.'
673
+ };
674
+ dbglogging_1.default.elog(result.message);
675
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
676
+ return;
677
+ }
678
+ const findobj = k2hr3dkc_1.default.findTenant(tenant_name, comparam.user_name, tenant_id);
679
+ if (!k2hr3apiutil_1.default.isPlainObject(findobj) ||
680
+ !k2hr3apiutil_1.default.isBoolean(findobj.result) ||
681
+ false === findobj.result ||
682
+ !k2hr3dkc_1.default.isDkcTypeTenantInfo(findobj.tenant) ||
683
+ !k2hr3apiutil_1.default.isSafeString(findobj.tenant.name) ||
684
+ !k2hr3apiutil_1.default.isStringArray(findobj.tenant.users) ||
685
+ !k2hr3apiutil_1.default.findStringInArray(findobj.tenant.users, comparam.user_name)) {
686
+ const result = {
687
+ result: false,
688
+ message: 'PUT request tenant(' + tenant_name + ') does not allow user(' + comparam.user_name + ').'
689
+ };
690
+ dbglogging_1.default.elog(result.message);
691
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
692
+ return;
693
+ }
694
+ }
695
+ if (k2hr3apiutil_1.default.isArray(tenant_users)) {
696
+ tenant_users.sort();
697
+ }
698
+ //------------------------------
699
+ // Processing
700
+ //------------------------------
701
+ const create_result = rawCreateUpdateTenant(is_create, (comparam.user_name ?? ''), tenant_name, tenant_id, tenant_desc, tenant_display, tenant_users);
702
+ if (!k2hr3apiutil_1.default.isPlainObject(create_result) || !k2hr3apiutil_1.default.isBoolean(create_result.result) || !k2hr3apiutil_1.default.isSafeNumber(create_result.status) || false === create_result.result) {
703
+ if (k2hr3apiutil_1.default.isPlainObject(create_result) && k2hr3apiutil_1.default.isSafeString(create_result.message)) {
704
+ const result = {
705
+ result: false,
706
+ message: 'PUT request failed to update tenant by ' + k2hr3apiutil_1.default.getSafeString(create_result.message)
707
+ };
708
+ dbglogging_1.default.elog(result.message);
709
+ k2hr3resutil_1.default.errResponse(req, res, (create_result?.status ?? 500), result);
710
+ }
711
+ else {
712
+ const result = {
713
+ result: false,
714
+ message: 'PUT request failed to update tenant by unknown reason'
715
+ };
716
+ dbglogging_1.default.elog(result.message);
717
+ k2hr3resutil_1.default.errResponse(req, res, (k2hr3apiutil_1.default.isSafeNumber(create_result.status) ? create_result.status : 500), result);
718
+ }
719
+ return;
720
+ }
721
+ dbglogging_1.default.dlog('succeed : create/update tenant(' + JSON.stringify(tenant_name) + ') by user(' + JSON.stringify(comparam.user_name) + ')');
722
+ const success_result = {
723
+ result: true,
724
+ message: null
725
+ };
726
+ res.status(create_result.status ?? 200); // 200 or 201
727
+ res.send(JSON.stringify(success_result));
728
+ });
729
+ //=========================================================
730
+ // Router GET
731
+ //=========================================================
732
+ //
733
+ // Mountpath : '/v1/tenant{/tenant}'
734
+ //
735
+ //---------------------------------------------------------
736
+ // [GET] No tenant path
737
+ //---------------------------------------------------------
738
+ // GET '/v1/tenant' : get tenant list version 1
739
+ // HEADER : X-Auth-Token = <User token>
740
+ // URL arguments : expand = "true"(default) or "false"
741
+ // response status code : 200 or 4xx/5xx
742
+ // response : nothing
743
+ // response body : {
744
+ // result: true/false,
745
+ // message: null or error message string
746
+ // tenants: [
747
+ // {
748
+ // name: "string",
749
+ // id: "string",
750
+ // desc: "string",
751
+ // display: "string",
752
+ // user: array[users...]
753
+ // },
754
+ // ...
755
+ // ]
756
+ // }
757
+ // or
758
+ // {
759
+ // result: true/false,
760
+ // message: null or error message string
761
+ // tenants: [
762
+ // "tenant",
763
+ // ...
764
+ // ]
765
+ // }
766
+ //
767
+ // This mount point retrieves a list of tenants and information about each.
768
+ //
769
+ //---------------------------------------------------------
770
+ // [GET] With tenant path
771
+ //---------------------------------------------------------
772
+ // GET '/v1/tenant/<tenant>' : get tenant information on version 1
773
+ // HEADER : X-Auth-Token = <User token>
774
+ // URL arguments : nothing
775
+ // response status code : 200 or 4xx/5xx
776
+ // response : nothing
777
+ // response body : {
778
+ // result: true/false,
779
+ // message: null or error message string
780
+ // tenant: {
781
+ // name: "string",
782
+ // id: "string",
783
+ // desc: "string",
784
+ // display: "string",
785
+ // user: array[users...]
786
+ // }
787
+ // }
788
+ //
789
+ router.get('/', (req, res, next) => {
790
+ dbglogging_1.default.dlog('CALL:', req.method, req.url);
791
+ if ('GET' !== req.method) {
792
+ // HEAD request comes here, so it should be routed to head function.
793
+ next();
794
+ return;
795
+ }
796
+ res.type('application/json; charset=utf-8');
797
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
798
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
799
+ const result = {
800
+ result: false,
801
+ message: 'GET request is something wrong'
802
+ };
803
+ dbglogging_1.default.elog(result.message);
804
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
805
+ return;
806
+ }
807
+ //------------------------------
808
+ // check common parameters(token, tenant etc)
809
+ //------------------------------
810
+ const resobj = rawParseBaseParamInRequest(req);
811
+ if (!resobj.result) {
812
+ const result = {
813
+ result: resobj.result,
814
+ message: resobj.message
815
+ };
816
+ dbglogging_1.default.elog(resobj.message);
817
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status, result);
818
+ return;
819
+ }
820
+ const comparam = resobj.parameters;
821
+ //------------------------------
822
+ // check token type
823
+ //------------------------------
824
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
825
+ const result = {
826
+ result: false,
827
+ message: 'GET request tenant must specify <User Token>'
828
+ };
829
+ dbglogging_1.default.elog(result.message);
830
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
831
+ return;
832
+ }
833
+ //------------------------------
834
+ // Processing
835
+ //------------------------------
836
+ let jsonres;
837
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.tenant_name)) {
838
+ //
839
+ // List mode
840
+ //
841
+ const keys = r3keys(comparam.user_name);
842
+ //
843
+ // Check expand type
844
+ //
845
+ let is_expand = true;
846
+ if (k2hr3apiutil_1.default.isPlainObject(req.query) && k2hr3apiutil_1.default.isSafeString(req.query.expand)) {
847
+ if (k2hr3apiutil_1.default.compareCaseString(keys.VALUE_TRUE, req.query.expand)) {
848
+ is_expand = true;
849
+ }
850
+ else if (k2hr3apiutil_1.default.compareCaseString(keys.VALUE_FALSE, req.query.expand)) {
851
+ is_expand = false;
852
+ }
853
+ else {
854
+ const result = {
855
+ result: false,
856
+ message: 'GET expand url argument parameter(' + JSON.stringify(req.query.expand) + ') is wrong, it must be ' + keys.VALUE_TRUE + ' or ' + keys.VALUE_FALSE + '.'
857
+ };
858
+ dbglogging_1.default.elog(result.message);
859
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
860
+ return;
861
+ }
862
+ }
863
+ //
864
+ // Get list
865
+ //
866
+ const resobj = k2hr3dkc_1.default.listLocalTenant(comparam.user_name, is_expand);
867
+ if (!k2hr3apiutil_1.default.isPlainObject(resobj) || !k2hr3apiutil_1.default.isBoolean(resobj.result) || (!is_expand && !k2hr3apiutil_1.default.isStringArray(resobj.tenants)) || (is_expand && !k2hr3dkc_1.default.isDkcTypeTenantInfoList(resobj.tenants)) || false === resobj.result) {
868
+ if (k2hr3apiutil_1.default.isPlainObject(resobj) && k2hr3apiutil_1.default.isSafeString(resobj.message)) {
869
+ const result = {
870
+ result: false,
871
+ message: 'GET request failed to update tenant by ' + k2hr3apiutil_1.default.getSafeString(resobj.message)
872
+ };
873
+ dbglogging_1.default.elog(result.message);
874
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
875
+ }
876
+ else {
877
+ const result = {
878
+ result: false,
879
+ message: 'GET request failed to update tenant by unknown reason'
880
+ };
881
+ dbglogging_1.default.elog(result.message);
882
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
883
+ }
884
+ return;
885
+ }
886
+ const result = {
887
+ result: true,
888
+ message: null,
889
+ tenants: resobj.tenants
890
+ };
891
+ jsonres = JSON.stringify(result);
892
+ }
893
+ else {
894
+ //
895
+ // One tenant
896
+ //
897
+ const resobj = k2hr3dkc_1.default.findTenant(comparam.tenant_name);
898
+ if (!k2hr3apiutil_1.default.isPlainObject(resobj) || !k2hr3apiutil_1.default.isBoolean(resobj.result) || !k2hr3dkc_1.default.isDkcTypeTenantInfo(resobj.tenant) || false === resobj.result) {
899
+ if (k2hr3apiutil_1.default.isPlainObject(resobj) && k2hr3apiutil_1.default.isSafeString(resobj.message)) {
900
+ const result = {
901
+ result: false,
902
+ message: 'GET request failed to update tenant by ' + k2hr3apiutil_1.default.getSafeString(resobj.message)
903
+ };
904
+ dbglogging_1.default.elog(result.message);
905
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
906
+ }
907
+ else {
908
+ const result = {
909
+ result: false,
910
+ message: 'GET request failed to update tenant by unknown reason'
911
+ };
912
+ dbglogging_1.default.elog(result.message);
913
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
914
+ }
915
+ return;
916
+ }
917
+ const result = {
918
+ result: true,
919
+ message: null,
920
+ tenant: resobj.tenant
921
+ };
922
+ jsonres = JSON.stringify(result);
923
+ }
924
+ dbglogging_1.default.dlog('succeed : get tenant(s) by user(' + JSON.stringify(comparam.user_name) + ')');
925
+ res.status(200); // 200: OK
926
+ res.send(jsonres);
927
+ });
928
+ //=========================================================
929
+ // Router HEAD
930
+ //=========================================================
931
+ //
932
+ // Mountpath : '/v1/tenant/tenant'
933
+ //
934
+ // HEAD '/v1/tenant/<tenant>' : head tenant on version 1
935
+ // HEADER : X-Auth-Token = <User token>
936
+ // response status code : 204 or 4xx/5xx
937
+ // response body : nothing
938
+ //
939
+ // This mount point is an API for checking the existence of a tenant.
940
+ // If the tenant is given, this returns a 204 if that tenant exists and is allowed to be seen.
941
+ // If no tenant is given, returns 204 if at least one target tenant exists.
942
+ //
943
+ router.head('/', (req, res, next) => {
944
+ dbglogging_1.default.dlog('CALL:', req.method, req.url);
945
+ if ('HEAD' !== req.method) {
946
+ // If other method request comes here, so it should be routed another function.
947
+ next();
948
+ return;
949
+ }
950
+ res.type('application/json; charset=utf-8');
951
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
952
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
953
+ dbglogging_1.default.elog('HEAD request is something wrong');
954
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
955
+ return;
956
+ }
957
+ //------------------------------
958
+ // check common parameters(token, tenant etc)
959
+ //------------------------------
960
+ const resobj = rawParseBaseParamInRequest(req);
961
+ if (!resobj.result) {
962
+ dbglogging_1.default.elog(resobj.message);
963
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status);
964
+ return;
965
+ }
966
+ const comparam = resobj.parameters;
967
+ //------------------------------
968
+ // check token type
969
+ //------------------------------
970
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
971
+ dbglogging_1.default.elog('HEAD request tenant must specify <User Token>');
972
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
973
+ return;
974
+ }
975
+ //------------------------------
976
+ // Check uri paths(tenant name)
977
+ //------------------------------
978
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.tenant_name)) {
979
+ dbglogging_1.default.elog('HEAD request tenant must specify <tenant> path');
980
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
981
+ return;
982
+ }
983
+ //------------------------------
984
+ // Processing
985
+ //------------------------------
986
+ const find_result = k2hr3dkc_1.default.findTenant(comparam.tenant_name);
987
+ if (!k2hr3apiutil_1.default.isPlainObject(find_result) || !k2hr3apiutil_1.default.isBoolean(find_result.result) || !k2hr3dkc_1.default.isDkcTypeTenantInfo(find_result.tenant) || false === find_result.result) {
988
+ if (k2hr3apiutil_1.default.isPlainObject(find_result) && k2hr3apiutil_1.default.isSafeString(find_result.message)) {
989
+ dbglogging_1.default.elog('HEAD request failed to update tenant by ' + k2hr3apiutil_1.default.getSafeString(find_result.message));
990
+ }
991
+ else {
992
+ dbglogging_1.default.elog('HEAD request failed to update tenant by unknown reason');
993
+ }
994
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
995
+ return;
996
+ }
997
+ dbglogging_1.default.dlog('HEAD request succeed - check tenant(' + JSON.stringify(comparam.tenant_name) + ') exists');
998
+ res.status(204); // 204: No Content
999
+ res.send();
1000
+ });
1001
+ //=========================================================
1002
+ // Router DELETE
1003
+ //=========================================================
1004
+ //
1005
+ // Mountpath : '/v1/tenant'
1006
+ //
1007
+ //---------------------------------------------------------
1008
+ // [DELETE] No tenant path
1009
+ //---------------------------------------------------------
1010
+ // DELETE '/v1/tenant' : delete tenant version 1
1011
+ // HEADER : X-Auth-Token = <User token>
1012
+ // url argument : "tenant" = <tenant name>
1013
+ // url argument : "id" = <id> => key is "yrn:yahoo:::<tenant>:id"
1014
+ // response status code : 204 or 4xx/5xx
1015
+ // response body : nothing
1016
+ //
1017
+ // This mount point deletes the specified <K2HR3 cluster LOCAL> tenant.
1018
+ //
1019
+ //---------------------------------------------------------
1020
+ // [DELETE] With tenant path
1021
+ //---------------------------------------------------------
1022
+ // DELETE '/v1/tenant/tenant' : delete tenant version 1
1023
+ // HEADER : X-Auth-Token = <User token>
1024
+ // url argument : "id" = <id> => key is "yrn:yahoo:::<tenant>:id"
1025
+ // response status code : 204 or 4xx/5xx
1026
+ // response body : nothing
1027
+ //
1028
+ // This mount point deletes the specified <K2HR3 cluster LOCAL> tenant.
1029
+ //
1030
+ // [NOTE]
1031
+ // Only users registered in the tenant to be deleted can delete this tenant.
1032
+ //
1033
+ router.delete('/', (req, res, _) => {
1034
+ dbglogging_1.default.dlog('CALL:', req.method, req.url);
1035
+ res.type('application/json; charset=utf-8');
1036
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
1037
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
1038
+ dbglogging_1.default.elog('DELETE request or url or query is wrong');
1039
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1040
+ return;
1041
+ }
1042
+ //------------------------------
1043
+ // check common parameters(token, tenant etc)
1044
+ //------------------------------
1045
+ const resobj = rawParseBaseParamInRequest(req);
1046
+ if (!resobj.result) {
1047
+ dbglogging_1.default.elog(resobj.message);
1048
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status);
1049
+ return;
1050
+ }
1051
+ const comparam = resobj.parameters;
1052
+ //------------------------------
1053
+ // check token type
1054
+ //------------------------------
1055
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1056
+ dbglogging_1.default.elog('DELETE request tenant must specify <User Token>');
1057
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1058
+ return;
1059
+ }
1060
+ //------------------------------
1061
+ // Check uri paths
1062
+ //------------------------------
1063
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.tenant_name)) {
1064
+ //------------------------------
1065
+ // Check argments(tenant)
1066
+ //------------------------------
1067
+ const tenant_name = k2hr3apiutil_1.default.isPlainObject(req.query) ? k2hr3apiutil_1.default.getSafeString(req.query.tenant) : '';
1068
+ if (!k2hr3apiutil_1.default.isSafeString(tenant_name)) {
1069
+ dbglogging_1.default.elog('DELETE request tenant must specify in argument');
1070
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1071
+ return;
1072
+ }
1073
+ //------------------------------
1074
+ // Check argments(id)
1075
+ //------------------------------
1076
+ const tenant_id = k2hr3apiutil_1.default.isPlainObject(req.query) ? k2hr3apiutil_1.default.getSafeString(req.query.id) : '';
1077
+ if (!k2hr3apiutil_1.default.isSafeString(tenant_id)) {
1078
+ dbglogging_1.default.elog('DELETE request id must specify in argument');
1079
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1080
+ return;
1081
+ }
1082
+ //------------------------------
1083
+ // Processing
1084
+ //------------------------------
1085
+ const resobj = k2hr3dkc_1.default.removeLocalTenant(tenant_name, comparam.user_name, tenant_id);
1086
+ if (!k2hr3apiutil_1.default.isPlainObject(resobj) || !k2hr3apiutil_1.default.isBoolean(resobj.result) || false === resobj.result) {
1087
+ if (k2hr3apiutil_1.default.isPlainObject(resobj) && k2hr3apiutil_1.default.isSafeString(resobj.message)) {
1088
+ dbglogging_1.default.elog('DELETE request failed to remove user from tenant by ' + k2hr3apiutil_1.default.getSafeString(resobj.message));
1089
+ }
1090
+ else {
1091
+ dbglogging_1.default.elog('DELETE request failed to remove user from tenant by unknown reason');
1092
+ }
1093
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1094
+ return;
1095
+ }
1096
+ dbglogging_1.default.dlog('DELETE request succeed - remove tenant');
1097
+ }
1098
+ else {
1099
+ //------------------------------
1100
+ // Check argments(id)
1101
+ //------------------------------
1102
+ const tenant_id = k2hr3apiutil_1.default.isPlainObject(req.query) ? k2hr3apiutil_1.default.getSafeString(req.query.id) : '';
1103
+ if (!k2hr3apiutil_1.default.isSafeString(tenant_id)) {
1104
+ dbglogging_1.default.elog('DELETE request id must specify in argument');
1105
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1106
+ return;
1107
+ }
1108
+ //------------------------------
1109
+ // Processing
1110
+ //------------------------------
1111
+ const resobj = k2hr3dkc_1.default.removeUserFromLocalTenant(comparam.tenant_name, comparam.user_name, tenant_id);
1112
+ if (!k2hr3apiutil_1.default.isPlainObject(resobj) || !k2hr3apiutil_1.default.isBoolean(resobj.result) || false === resobj.result) {
1113
+ if (k2hr3apiutil_1.default.isPlainObject(resobj) && k2hr3apiutil_1.default.isSafeString(resobj.message)) {
1114
+ dbglogging_1.default.elog('DELETE request failed to remove user from tenant by ' + k2hr3apiutil_1.default.getSafeString(resobj.message));
1115
+ }
1116
+ else {
1117
+ dbglogging_1.default.elog('DELETE request failed to remove user from tenant by unknown reason');
1118
+ }
1119
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1120
+ return;
1121
+ }
1122
+ dbglogging_1.default.dlog('DELETE request succeed - remove user from tenant');
1123
+ }
1124
+ res.status(204); // 204: No Content
1125
+ res.send();
1126
+ });
1127
+ //---------------------------------------------------------
1128
+ // Exports
1129
+ //---------------------------------------------------------
1130
+ //
1131
+ // Functions
1132
+ //
1133
+ exports.default = router;
1134
+ /*
1135
+ * Local variables:
1136
+ * tab-width: 4
1137
+ * c-basic-offset: 4
1138
+ * End:
1139
+ * vim600: noexpandtab sw=4 ts=4 fdm=marker
1140
+ * vim<600: noexpandtab sw=4 ts=4
1141
+ */