k2hr3-api 1.0.41 → 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 -372
  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,908 @@
1
+ "use strict";
2
+ /*
3
+ * K2HR3 REST API
4
+ *
5
+ * Copyright 2017 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: Wed Nov 1 2017
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
+ // Common utility function
36
+ //
37
+ // Convert tenant yrn path to tenant name
38
+ //
39
+ const rawGetTenantNameFromYrn = (tenant) => {
40
+ if (!k2hr3apiutil_1.default.isSafeString(tenant)) {
41
+ return null;
42
+ }
43
+ const keys = r3keys();
44
+ const yrnptn = new RegExp('^' + keys.MATCH_ANY_TENANT_MAIN); // regex = /^yrn:yahoo:(.*)::(.*)/
45
+ const matches = tenant.match(yrnptn);
46
+ if (!k2hr3apiutil_1.default.isStringArray(matches) || !k2hr3apiutil_1.default.isNotEmptyArray(matches) || matches.length < 3) {
47
+ // not match tenant yrn, then return original tenant
48
+ return tenant;
49
+ }
50
+ tenant = matches[2]; // tenant name
51
+ if (!k2hr3apiutil_1.default.isSafeString(tenant)) {
52
+ return null;
53
+ }
54
+ return tenant;
55
+ };
56
+ //
57
+ // Common utility function
58
+ //
59
+ // Create or update service
60
+ //
61
+ // Result null(succeed) or error message(failed)
62
+ //
63
+ const rawUpdateService = (owner, servicename, verify, tenants, is_clear, is_create) => {
64
+ if (!k2hr3apiutil_1.default.isSafeString(owner) || !k2hr3apiutil_1.default.isSafeString(servicename)) {
65
+ const error = new Error('Internal error: rawUpdateService');
66
+ return error;
67
+ }
68
+ if (!k2hr3apiutil_1.default.isValTypeAll(verify)) {
69
+ verify = null;
70
+ }
71
+ if (!k2hr3apiutil_1.default.isStringArray(tenants) || !k2hr3apiutil_1.default.isNotEmptyArray(tenants)) {
72
+ tenants = null;
73
+ }
74
+ let processed = false;
75
+ //------------------------------
76
+ // set(update) all field / update verify field
77
+ //------------------------------
78
+ if (is_create || null !== verify) {
79
+ //
80
+ // [NOTE]
81
+ // initService() === updateServiceVerify()
82
+ //
83
+ const ini_result = k2hr3dkc_1.default.initService(owner, servicename, verify);
84
+ if (!k2hr3apiutil_1.default.isPlainObject(ini_result) || !k2hr3apiutil_1.default.isBoolean(ini_result.result) || false === ini_result.result) {
85
+ let error = null;
86
+ if (!k2hr3apiutil_1.default.isPlainObject(ini_result)) {
87
+ error = new Error('Could not get response from initService');
88
+ }
89
+ else {
90
+ if (!k2hr3apiutil_1.default.isString(ini_result.message)) {
91
+ error = new Error('Could not get error message in response from initService');
92
+ }
93
+ }
94
+ return error;
95
+ }
96
+ processed = true;
97
+ }
98
+ //------------------------------
99
+ // add tenants
100
+ //------------------------------
101
+ const allowtenants = (k2hr3apiutil_1.default.isStringArray(tenants) && k2hr3apiutil_1.default.isNotEmptyArray(tenants)) ? tenants : [];
102
+ const denytenants = [];
103
+ if (is_clear || k2hr3apiutil_1.default.isNotEmptyArray(allowtenants)) {
104
+ // get all service data
105
+ const allres = k2hr3dkc_1.default.getService(owner, servicename);
106
+ if (!k2hr3apiutil_1.default.isPlainObject(allres) || !k2hr3apiutil_1.default.isBoolean(allres.result) || false === allres.result) {
107
+ let error;
108
+ if (!k2hr3apiutil_1.default.isPlainObject(allres)) {
109
+ error = new Error('Could not get response from getService');
110
+ }
111
+ else {
112
+ if (!k2hr3apiutil_1.default.isString(allres.message)) {
113
+ error = new Error('Could not get error message in response from getService');
114
+ }
115
+ else {
116
+ error = new Error(k2hr3apiutil_1.default.getSafeString(allres.message));
117
+ }
118
+ }
119
+ return error;
120
+ }
121
+ // check
122
+ if (allres.service && k2hr3dkc_1.default.isDkcTypeServiceRawValue(allres.service) && k2hr3apiutil_1.default.isStringArray(allres.service.tenant)) {
123
+ const keys = r3keys(null, owner, null);
124
+ for (let cnt = 0; cnt < allres.service.tenant.length; ++cnt) {
125
+ let found = false;
126
+ for (let cnt2 = 0; cnt2 < allowtenants.length; ++cnt2) {
127
+ if (k2hr3apiutil_1.default.compareCaseString(allres.service.tenant[cnt], allowtenants[cnt2])) {
128
+ // cut already existing tenant
129
+ allowtenants.splice(cnt2, 1);
130
+ found = true;
131
+ break;
132
+ }
133
+ }
134
+ if (!found) {
135
+ // does not remove owner tenant
136
+ if (!k2hr3apiutil_1.default.compareCaseString(allres.service.tenant[cnt], keys.MASTER_TENANT_TOP_KEY)) {
137
+ // add new deny tenant
138
+ denytenants.push(allres.service.tenant[cnt]);
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+ // add new allow tenants
145
+ for (let cnt = 0; cnt < allowtenants.length; ++cnt) {
146
+ const addtenant = rawGetTenantNameFromYrn(allowtenants[cnt]);
147
+ if (!k2hr3apiutil_1.default.isSafeString(addtenant)) {
148
+ const error = new Error('To allow Tenant name(' + allowtenants[cnt] + ') is something wrong.');
149
+ return error;
150
+ }
151
+ const allow_result = k2hr3dkc_1.default.allowTenantToService(owner, servicename, addtenant);
152
+ if (!k2hr3apiutil_1.default.isPlainObject(allow_result) || !k2hr3apiutil_1.default.isBoolean(allow_result.result) || false === allow_result.result) {
153
+ let error;
154
+ if (!k2hr3apiutil_1.default.isPlainObject(allow_result)) {
155
+ error = new Error('Could not get response from allowTenantToService');
156
+ }
157
+ else {
158
+ error = new Error('Could not get error message in response from allowTenantToService');
159
+ }
160
+ return error;
161
+ }
162
+ processed = true;
163
+ }
164
+ // remove new deny tenants
165
+ if (is_clear && k2hr3apiutil_1.default.isNotEmptyArray(denytenants)) {
166
+ for (let cnt = 0; cnt < denytenants.length; ++cnt) {
167
+ const denytenant = rawGetTenantNameFromYrn(denytenants[cnt]);
168
+ if (!k2hr3apiutil_1.default.isSafeString(denytenant)) {
169
+ const error = new Error('To allow Tenant name(' + denytenants[cnt] + ') is something wrong.');
170
+ return error;
171
+ }
172
+ const deny_result = k2hr3dkc_1.default.denyTenantFromService(owner, servicename, denytenant);
173
+ if (!k2hr3apiutil_1.default.isPlainObject(deny_result) || !k2hr3apiutil_1.default.isBoolean(deny_result.result) || false === deny_result.result) {
174
+ let error;
175
+ if (!k2hr3apiutil_1.default.isPlainObject(deny_result)) {
176
+ error = new Error('Could not get response from denyTenantToService');
177
+ }
178
+ else {
179
+ error = new Error('Could not get error message in response from denyTenantToService');
180
+ }
181
+ return error;
182
+ }
183
+ processed = true;
184
+ }
185
+ }
186
+ if (!processed) {
187
+ const error = new Error('Internal error: rawUpdateService');
188
+ return error;
189
+ }
190
+ dbglogging_1.default.dlog('succeed');
191
+ return null;
192
+ };
193
+ //
194
+ // Mountpath : '/v1/service'
195
+ //
196
+ // POST '/v1/service' : post service on version 1
197
+ // HEADER : X-Auth-Token => Scoped User token
198
+ // response body : result => true/false
199
+ // message => messages
200
+ // body :
201
+ // {
202
+ // "name": <service name> => key is "yrn:yahoo::::service:<service>"
203
+ // "verify": <verify url> => key is "yrn:yahoo::::service:<service>:verify"
204
+ // when the value is URL, it is save as URL string.
205
+ // the value is allowed null or undefined, then verify url value is null.
206
+ // the value is allowed string(not URL), it is saved and converted by JSON.
207
+ // }
208
+ //
209
+ // POST '/v1/service/<service>' : post tenant or verify for service on version 1
210
+ // HEADER : X-Auth-Token => Scoped User token
211
+ // response body : result => true/false
212
+ // message => messages
213
+ // body :
214
+ // {
215
+ // "tenant": <tenant name> or array => key is "yrn:yahoo::::service:<service>:tenant"
216
+ // if this key is specified, adding tenants to service
217
+ // the value is string for tenant name, or array of tenant name list
218
+ // "clear_tenant": true/false => true means clear existing tenant without "tenant".
219
+ // default false
220
+ // "verify": <verify url> => key is "yrn:yahoo::::service:<service>:verify"
221
+ // if this key is specified, updating verify url.
222
+ // when the value is URL, it is save as URL string.
223
+ // the value is allowed string(not URL), it is saved and converted by JSON.
224
+ // }
225
+ // }
226
+ //
227
+ // [NOTE]
228
+ // Verify URL is used as following formatted:
229
+ //
230
+ // GET http://<verify host[:port]>{/<path>}?service=<service name>&tenant=<tenant name>&tenantid=<tenant id>&user=<user name>&userid=<user id>
231
+ //
232
+ // service : service name
233
+ // tenant : tenant name
234
+ // tenantid : tenant id
235
+ // user : user name
236
+ // userid : user id
237
+ //
238
+ // And it's response is following:
239
+ // response body = [ => undefined/null or resource array(if one element, allows only it not array)
240
+ // {
241
+ // name => resource name which is key name(path) for resource
242
+ // expire => undefined/null or integer
243
+ // type => resource data type(string or object), if date is null or '', this value must be string.
244
+ // data => resource data which must be string or object or null/undefined.
245
+ // keys = { => resource has keys(associative array), or null/undefined.
246
+ // 'foo': bar, => any value is allowed
247
+ // ...
248
+ // }
249
+ // },
250
+ // ...
251
+ // ]
252
+ //
253
+ router.post('/', (req, res, _) => {
254
+ dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
255
+ res.type('application/json; charset=utf-8');
256
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
257
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl) ||
258
+ !k2hr3apiutil_1.default.isPlainObject(req.body)) {
259
+ const result = {
260
+ result: false,
261
+ message: 'POST body does not exist'
262
+ };
263
+ dbglogging_1.default.elog(result.message);
264
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
265
+ return;
266
+ }
267
+ //------------------------------
268
+ // check token
269
+ //------------------------------
270
+ const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
271
+ if (!token_result.result) {
272
+ const result = {
273
+ result: token_result.result,
274
+ message: k2hr3apiutil_1.default.getSafeString(token_result.message),
275
+ };
276
+ dbglogging_1.default.elog(result.message);
277
+ k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
278
+ return;
279
+ }
280
+ const token_info = token_result.token_info;
281
+ if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
282
+ const result = {
283
+ result: false,
284
+ message: 'specified wrong token or it is not scoped user token'
285
+ };
286
+ dbglogging_1.default.elog(result.message);
287
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
288
+ return;
289
+ }
290
+ //------------------------------
291
+ // check service path in url
292
+ //------------------------------
293
+ let is_create;
294
+ let name = null;
295
+ const requestptn = new RegExp('^/v1/service/(.*)'); // regex = /^\/v1\/service\/(.*)/
296
+ const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
297
+ if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
298
+ is_create = true;
299
+ }
300
+ else {
301
+ name = reqmatchs[1].toLowerCase();
302
+ is_create = false;
303
+ }
304
+ //------------------------------
305
+ // check arguments
306
+ //------------------------------
307
+ let verify = null;
308
+ let tenant = null;
309
+ let is_clear = false;
310
+ if (is_create) {
311
+ if (!k2hr3apiutil_1.default.isSafeString(req.body.name)) {
312
+ const result = {
313
+ result: false,
314
+ message: 'service:name field is wrong : ' + JSON.stringify(req.body.name)
315
+ };
316
+ dbglogging_1.default.elog(result.message);
317
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
318
+ return;
319
+ }
320
+ name = req.body.name.toLowerCase();
321
+ if (k2hr3apiutil_1.default.isValTypeAll(req.body.verify)) {
322
+ verify = req.body.verify;
323
+ }
324
+ }
325
+ else {
326
+ if (k2hr3apiutil_1.default.isSafeString(req.body.tenant)) {
327
+ const tenant_tmp = req.body.tenant;
328
+ if (k2hr3apiutil_1.default.checkSimpleJSON(tenant_tmp)) {
329
+ const tenant_raw = JSON.parse(tenant_tmp);
330
+ if (k2hr3apiutil_1.default.isStringArray(tenant_raw)) {
331
+ tenant = [];
332
+ for (let cnt = 0; cnt < tenant_raw.length; ++cnt) {
333
+ tenant.push(tenant_raw[cnt].toLowerCase());
334
+ }
335
+ }
336
+ else if (k2hr3apiutil_1.default.isSafeString(tenant_raw)) {
337
+ tenant = [tenant_raw.toLowerCase()];
338
+ }
339
+ else {
340
+ tenant = null;
341
+ }
342
+ }
343
+ else {
344
+ tenant = [tenant_tmp.toLowerCase()];
345
+ }
346
+ if (!k2hr3apiutil_1.default.isNotEmptyArray(tenant)) {
347
+ tenant = null;
348
+ }
349
+ }
350
+ if (k2hr3apiutil_1.default.isBoolean(req.body.clear_tenant) && true === req.body.clear_tenant) {
351
+ is_clear = true;
352
+ }
353
+ if (k2hr3apiutil_1.default.isValTypeAll(req.body.verify)) {
354
+ verify = req.body.verify;
355
+ }
356
+ if (null === tenant && null === verify) {
357
+ const result = {
358
+ result: false,
359
+ message: 'both tenant and verify are not specified.'
360
+ };
361
+ dbglogging_1.default.elog(result.message);
362
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
363
+ return;
364
+ }
365
+ }
366
+ //------------------------------
367
+ // create/update service
368
+ //------------------------------
369
+ const error = rawUpdateService((token_info.tenant ?? null), name, verify, tenant, is_clear, is_create);
370
+ if (null !== error) {
371
+ const result = {
372
+ result: false,
373
+ message: error.message
374
+ };
375
+ dbglogging_1.default.elog(result.message);
376
+ k2hr3resutil_1.default.errResponse(req, res, 403, result); // 403: Forbidden(is this status OK?)
377
+ return;
378
+ }
379
+ const success_result = { result: true, message: null };
380
+ res.status(201); // 201: Created
381
+ res.send(JSON.stringify(success_result));
382
+ });
383
+ //
384
+ // Mountpath : '/v1/service/*'
385
+ //
386
+ // PUT '/v1/service' : post service on version 1
387
+ // HEADER : X-Auth-Token => Scoped User token
388
+ // response body : result => true/false
389
+ // message => messages
390
+ // URL argument
391
+ // "name" : <service name> => key is "yrn:yahoo::::service:<service>"
392
+ // "verify" : <verify url> => key is "yrn:yahoo::::service:<service>:verify"
393
+ // when the value is URL, it is save as URL string.
394
+ // the value is allowed null or undefined, then verify url value is null.
395
+ // the value is allowed string(not URL), it is saved and converted by JSON.
396
+ //
397
+ // PUT '/v1/service/<service>' : post tenant or verify for service on version 1
398
+ // HEADER : X-Auth-Token => Scoped User token
399
+ // response body : result => true/false
400
+ // message => messages
401
+ // URL argument
402
+ // "tenant" : <tenant name> => key is "yrn:yahoo::::service:<service>:tenant"
403
+ // if this key is specified, adding tenants to service
404
+ // the value is string for tenant name of tenant name list
405
+ // "clear_tenant" : true/false => true means clear existing tenant without "tenant".
406
+ // default false
407
+ // "verify" : <verify url> => key is "yrn:yahoo::::service:<service>:verify"
408
+ // when the value is URL, it is save as URL string.
409
+ // the value is allowed string(not URL), it is saved and converted by JSON.
410
+ //
411
+ // [NOTE] see POST
412
+ //
413
+ router.put('/', (req, res, _) => {
414
+ dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
415
+ res.type('application/json; charset=utf-8');
416
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
417
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl) ||
418
+ !k2hr3apiutil_1.default.isPlainObject(req.query)) {
419
+ const result = {
420
+ result: false,
421
+ message: 'PUT argument does not have any data'
422
+ };
423
+ dbglogging_1.default.elog(result.message);
424
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
425
+ return;
426
+ }
427
+ //------------------------------
428
+ // check token
429
+ //------------------------------
430
+ const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
431
+ if (!token_result.result) {
432
+ const result = {
433
+ result: token_result.result,
434
+ message: k2hr3apiutil_1.default.getSafeString(token_result.message),
435
+ };
436
+ dbglogging_1.default.elog(result.message);
437
+ k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
438
+ return;
439
+ }
440
+ const token_info = token_result.token_info;
441
+ if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
442
+ const result = {
443
+ result: false,
444
+ message: 'specified wrong token or it is not scoped user token'
445
+ };
446
+ dbglogging_1.default.elog(result.message);
447
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
448
+ return;
449
+ }
450
+ //------------------------------
451
+ // check service path in url
452
+ //------------------------------
453
+ let is_create;
454
+ let name = null;
455
+ const requestptn = new RegExp('^/v1/service/(.*)'); // regex = /^\/v1\/service\/(.*)/
456
+ const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
457
+ if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
458
+ is_create = true;
459
+ }
460
+ else {
461
+ name = reqmatchs[1].toLowerCase();
462
+ is_create = false;
463
+ }
464
+ //------------------------------
465
+ // check arguments
466
+ //------------------------------
467
+ let verify = null;
468
+ let tenant = null;
469
+ let is_clear = false;
470
+ if (is_create) {
471
+ if (!k2hr3apiutil_1.default.isSafeString(req.query.name)) {
472
+ const result = {
473
+ result: false,
474
+ message: 'name argument is wrong : ' + JSON.stringify(req.query.name)
475
+ };
476
+ dbglogging_1.default.elog(result.message);
477
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
478
+ return;
479
+ }
480
+ name = req.query.name.toLowerCase();
481
+ if (k2hr3apiutil_1.default.isValTypeAll(req.query.verify)) {
482
+ if (k2hr3apiutil_1.default.isString(req.query.verify) && k2hr3apiutil_1.default.checkSimpleJSON(req.query.verify)) {
483
+ const tmp_verify = JSON.parse(req.query.verify);
484
+ if (k2hr3apiutil_1.default.isValTypeAll(tmp_verify)) {
485
+ verify = tmp_verify;
486
+ }
487
+ }
488
+ else {
489
+ verify = req.query.verify;
490
+ }
491
+ }
492
+ }
493
+ else {
494
+ if (k2hr3apiutil_1.default.isSafeString(req.query.tenant)) {
495
+ const tenant_tmp = req.query.tenant;
496
+ if (k2hr3apiutil_1.default.checkSimpleJSON(tenant_tmp)) {
497
+ const tenant_raw = JSON.parse(tenant_tmp);
498
+ if (k2hr3apiutil_1.default.isStringArray(tenant_raw)) {
499
+ tenant = [];
500
+ for (let cnt = 0; cnt < tenant_raw.length; ++cnt) {
501
+ tenant.push(tenant_raw[cnt].toLowerCase());
502
+ }
503
+ }
504
+ else if (k2hr3apiutil_1.default.isSafeString(tenant_raw)) {
505
+ tenant = [tenant_raw.toLowerCase()];
506
+ }
507
+ else {
508
+ tenant = null;
509
+ }
510
+ }
511
+ else {
512
+ tenant = [tenant_tmp.toLowerCase()];
513
+ }
514
+ if (!k2hr3apiutil_1.default.isNotEmptyArray(tenant)) {
515
+ tenant = null;
516
+ }
517
+ }
518
+ if ((k2hr3apiutil_1.default.isBoolean(req.query.clear_tenant) && true === req.query.clear_tenant) ||
519
+ (k2hr3apiutil_1.default.isSafeString(req.query.clear_tenant) && (k2hr3apiutil_1.default.compareCaseString('true', req.query.clear_tenant) || k2hr3apiutil_1.default.compareCaseString('1', req.query.clear_tenant)))) {
520
+ is_clear = true;
521
+ }
522
+ if (k2hr3apiutil_1.default.isValTypeAll(req.query.verify)) {
523
+ if (k2hr3apiutil_1.default.isString(req.query.verify) && k2hr3apiutil_1.default.checkSimpleJSON(req.query.verify)) {
524
+ const tmp_verify = JSON.parse(req.query.verify);
525
+ if (k2hr3apiutil_1.default.isValTypeAll(tmp_verify)) {
526
+ verify = tmp_verify;
527
+ }
528
+ }
529
+ else {
530
+ verify = req.query.verify;
531
+ }
532
+ }
533
+ if (null === tenant && null === verify) {
534
+ const result = {
535
+ result: false,
536
+ message: 'both tenant and verify are not specified.'
537
+ };
538
+ dbglogging_1.default.elog(result.message);
539
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
540
+ return;
541
+ }
542
+ }
543
+ //------------------------------
544
+ // create/update service
545
+ //------------------------------
546
+ const error = rawUpdateService((token_info.tenant ?? null), name, verify, tenant, is_clear, is_create);
547
+ if (null !== error) {
548
+ const result = {
549
+ result: false,
550
+ message: error.message
551
+ };
552
+ dbglogging_1.default.elog(result.message);
553
+ k2hr3resutil_1.default.errResponse(req, res, 403, result); // 403: Forbidden(is this status OK?)
554
+ return;
555
+ }
556
+ const success_result = { result: true, message: null };
557
+ res.status(201); // 201: Created
558
+ res.send(JSON.stringify(success_result));
559
+ });
560
+ //
561
+ // Mountpath : '/v1/service/*'
562
+ //
563
+ // GET '/v1/service/<service>' : get service on version 1
564
+ // HEADER : X-Auth-Token => Scoped User token
565
+ // response body : result => true/false
566
+ // message => error message
567
+ // service => object
568
+ // service object
569
+ // {
570
+ // "verify": <verify url> or <verify object>
571
+ // "tenant": [
572
+ // <tenant yrn full path>,
573
+ // ...
574
+ // ]
575
+ // }
576
+ //
577
+ router.get('/', (req, res, next) => {
578
+ dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
579
+ if ('GET' !== req.method) {
580
+ // HEAD request comes here, so it should be routed to head function.
581
+ next();
582
+ return;
583
+ }
584
+ res.type('application/json; charset=utf-8');
585
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
586
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
587
+ const result = {
588
+ result: false,
589
+ message: 'GET request or url is wrong'
590
+ };
591
+ dbglogging_1.default.elog(result.message);
592
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
593
+ return;
594
+ }
595
+ //------------------------------
596
+ // check token
597
+ //------------------------------
598
+ const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
599
+ if (!token_result.result) {
600
+ const result = {
601
+ result: token_result.result,
602
+ message: k2hr3apiutil_1.default.getSafeString(token_result.message),
603
+ };
604
+ dbglogging_1.default.elog(result.message);
605
+ k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
606
+ return;
607
+ }
608
+ const token_info = token_result.token_info;
609
+ if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
610
+ const result = {
611
+ result: false,
612
+ message: 'specified wrong token or it is not scoped user token'
613
+ };
614
+ dbglogging_1.default.elog(result.message);
615
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
616
+ return;
617
+ }
618
+ //------------------------------
619
+ // check service path in url
620
+ //------------------------------
621
+ const requestptn = new RegExp('^/v1/service/(.*)'); // regex = /^\/v1\/service\/(.*)/
622
+ const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
623
+ if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
624
+ const result = {
625
+ result: false,
626
+ message: 'GET request url does not have service name'
627
+ };
628
+ dbglogging_1.default.elog(result.message);
629
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
630
+ return;
631
+ }
632
+ const servicename = reqmatchs[1].toLowerCase();
633
+ //------------------------------
634
+ // get all service
635
+ //------------------------------
636
+ const allres = k2hr3dkc_1.default.getService(token_info.tenant, servicename);
637
+ if (!k2hr3apiutil_1.default.isPlainObject(allres) || !k2hr3dkc_1.default.isDkcTypeServiceRawValue(allres.service) || !k2hr3apiutil_1.default.isBoolean(allres.result) || false === allres.result) {
638
+ if (!k2hr3apiutil_1.default.isPlainObject(allres)) {
639
+ const result = {
640
+ result: false,
641
+ message: 'Could not get service data from getService'
642
+ };
643
+ dbglogging_1.default.elog(result.message);
644
+ k2hr3resutil_1.default.errResponse(req, res, 403, result); // 403: Forbidden(is this status OK?)
645
+ }
646
+ else {
647
+ const result = {
648
+ result: k2hr3apiutil_1.default.isBoolean(allres.result) ? allres.result : false,
649
+ message: k2hr3apiutil_1.default.isString(allres.message) ? allres.message : 'Could not get error message in response from getService'
650
+ };
651
+ dbglogging_1.default.elog(result.message);
652
+ k2hr3resutil_1.default.errResponse(req, res, 403, result); // 403: Forbidden(is this status OK?)
653
+ }
654
+ return;
655
+ }
656
+ //
657
+ // Remove owner/name from result
658
+ //
659
+ dbglogging_1.default.dlog('succeed : ' + allres.message);
660
+ const service_info = {
661
+ verify: allres.service.verify,
662
+ tenant: allres.service.tenant
663
+ };
664
+ const success_result = {
665
+ result: true,
666
+ message: null,
667
+ service: service_info
668
+ };
669
+ res.status(200); // 200: OK
670
+ res.send(JSON.stringify(success_result));
671
+ });
672
+ //
673
+ // Mountpath : '/v1/service/*'
674
+ //
675
+ // HEAD '/v1/service/<service>' : head service on version 1
676
+ // HEADER : X-Auth-Token => Scoped User token
677
+ //
678
+ // HEAD '/v1/service/<service>' : head tenant is allowed in service's tenant list on version 1
679
+ // HEADER : X-Auth-Token => Scoped User token
680
+ // URL argument :
681
+ // "tenant" : <tenant name> => key is "yrn:yahoo::::service:<service>:tenant"
682
+ // if this key is specified, check tenant is allowed.
683
+ //
684
+ router.head('/', (req, res, next) => {
685
+ dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
686
+ if ('HEAD' !== req.method) {
687
+ // If other method request comes here, so it should be routed another function.
688
+ next();
689
+ return;
690
+ }
691
+ res.type('application/json; charset=utf-8');
692
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
693
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
694
+ const result = {
695
+ result: false,
696
+ message: 'HEAD request or url or query is wrong'
697
+ };
698
+ dbglogging_1.default.elog(result.message);
699
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
700
+ return;
701
+ }
702
+ //------------------------------
703
+ // check token
704
+ //------------------------------
705
+ const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
706
+ if (!token_result.result) {
707
+ const result = {
708
+ result: token_result.result,
709
+ message: k2hr3apiutil_1.default.getSafeString(token_result.message),
710
+ };
711
+ dbglogging_1.default.elog(result.message);
712
+ k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
713
+ return;
714
+ }
715
+ const token_info = token_result.token_info;
716
+ if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
717
+ const result = {
718
+ result: false,
719
+ message: 'specified wrong token or it is not scoped user token'
720
+ };
721
+ dbglogging_1.default.elog(result.message);
722
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
723
+ return;
724
+ }
725
+ //------------------------------
726
+ // check service path in url
727
+ //------------------------------
728
+ const requestptn = new RegExp('^/v1/service/(.*)'); // regex = /^\/v1\/service\/(.*)/
729
+ const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
730
+ if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
731
+ const result = {
732
+ result: false,
733
+ message: 'GET request url does not have service name'
734
+ };
735
+ dbglogging_1.default.elog(result.message);
736
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
737
+ return;
738
+ }
739
+ const servicename = reqmatchs[1].toLowerCase();
740
+ //------------------------------
741
+ // check arguments
742
+ //------------------------------
743
+ let tenantyrn = null;
744
+ if (k2hr3apiutil_1.default.isSafeString(req.query.tenant)) {
745
+ const keys = r3keys(null, req.query.tenant.toLowerCase(), null);
746
+ tenantyrn = keys.MASTER_TENANT_TOP_KEY; // tenant full yrn : "yrn:yahoo:::<tenant>"
747
+ }
748
+ //------------------------------
749
+ // get all service
750
+ //------------------------------
751
+ const allres = k2hr3dkc_1.default.getService(token_info.tenant, servicename);
752
+ if (!k2hr3apiutil_1.default.isPlainObject(allres) || !k2hr3apiutil_1.default.isBoolean(allres.result) || false === allres.result) {
753
+ if (!k2hr3apiutil_1.default.isSafeEntity(allres)) {
754
+ const result = {
755
+ result: false,
756
+ message: 'Could not get service data from getService'
757
+ };
758
+ dbglogging_1.default.elog(result.message);
759
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
760
+ }
761
+ else {
762
+ const result = {
763
+ result: k2hr3apiutil_1.default.isBoolean(allres.result) ? allres.result : false,
764
+ message: k2hr3apiutil_1.default.isString(allres.message) ? allres.message : 'Could not get error message in response from getService'
765
+ };
766
+ dbglogging_1.default.elog(result.message);
767
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
768
+ }
769
+ return;
770
+ }
771
+ if (k2hr3apiutil_1.default.isSafeString(tenantyrn)) {
772
+ // tenant check
773
+ if (!k2hr3dkc_1.default.isDkcTypeServiceRawValue(allres.service) || !k2hr3apiutil_1.default.isStringArray(allres.service.tenant) || !k2hr3apiutil_1.default.findStringInArray(allres.service.tenant, tenantyrn)) {
774
+ const result = {
775
+ result: false,
776
+ message: 'Deny tenant(' + k2hr3apiutil_1.default.getSafeString(req.query.tenant).toLowerCase() + ') for service(' + servicename + ')'
777
+ };
778
+ dbglogging_1.default.elog(result.message);
779
+ k2hr3resutil_1.default.errResponse(req, res, 403); // 403: Forbidden(is this status OK?)
780
+ return;
781
+ }
782
+ }
783
+ dbglogging_1.default.dlog('succeed : ' + k2hr3apiutil_1.default.getSafeString(allres.message));
784
+ res.status(204); // 204: No Content
785
+ res.send();
786
+ });
787
+ //
788
+ // Mountpath : '/v1/service/*'
789
+ //
790
+ // DELETE '/v1/service/<service>' : delete service on version 1
791
+ // remove service and all related to service.
792
+ // HEADER : X-Auth-Token => Scoped User token
793
+ //
794
+ // DELETE '/v1/service/<service>' : delete tenant from service's tenant list on version 1
795
+ // HEADER : X-Auth-Token => Scoped User token
796
+ // URL argument :
797
+ // "tenant" : <tenant name> => key is "yrn:yahoo::::service:<service>:tenant"
798
+ // if this key is specified, removing tenant from service
799
+ //
800
+ router.delete('/', (req, res, _) => {
801
+ dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
802
+ res.type('application/json; charset=utf-8');
803
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
804
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
805
+ const result = {
806
+ result: false,
807
+ message: 'DELETE request or url or query is wrong'
808
+ };
809
+ dbglogging_1.default.elog(result.message);
810
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
811
+ return;
812
+ }
813
+ //------------------------------
814
+ // check token
815
+ //------------------------------
816
+ const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
817
+ if (!token_result.result) {
818
+ const result = {
819
+ result: token_result.result,
820
+ message: k2hr3apiutil_1.default.getSafeString(token_result.message),
821
+ };
822
+ dbglogging_1.default.elog(result.message);
823
+ k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
824
+ return;
825
+ }
826
+ const token_info = token_result.token_info;
827
+ if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
828
+ const result = {
829
+ result: false,
830
+ message: 'specified wrong token or it is not scoped user token'
831
+ };
832
+ dbglogging_1.default.elog(result.message);
833
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
834
+ return;
835
+ }
836
+ //------------------------------
837
+ // check service path in url
838
+ //------------------------------
839
+ const requestptn = new RegExp('^/v1/service/(.*)'); // regex = /^\/v1\/service\/(.*)/
840
+ const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
841
+ if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
842
+ const result = {
843
+ result: false,
844
+ message: 'DELETE request url does not have service name'
845
+ };
846
+ dbglogging_1.default.elog(result.message);
847
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
848
+ return;
849
+ }
850
+ const servicename = reqmatchs[1].toLowerCase();
851
+ //------------------------------
852
+ // check arguments
853
+ //------------------------------
854
+ let tenantname = null;
855
+ if (k2hr3apiutil_1.default.isPlainObject(req.query) && k2hr3apiutil_1.default.isSafeString(req.query.tenant)) {
856
+ tenantname = req.query.tenant.toLowerCase();
857
+ }
858
+ const strRemoveType = k2hr3apiutil_1.default.isSafeString(tenantname) ? 'denyTenantFromService' : 'removeService';
859
+ //------------------------------
860
+ // Do remove
861
+ //------------------------------
862
+ let rm_result;
863
+ if (null === tenantname) {
864
+ // remove service and all
865
+ rm_result = k2hr3dkc_1.default.removeService(token_info.tenant, servicename);
866
+ }
867
+ else {
868
+ // remove tenant from service's tenant list
869
+ rm_result = k2hr3dkc_1.default.removeServiceTenant(token_info.user, tenantname, servicename);
870
+ }
871
+ if (!k2hr3apiutil_1.default.isPlainObject(rm_result) || !k2hr3apiutil_1.default.isBoolean(rm_result.result) || false === rm_result.result) {
872
+ if (!k2hr3apiutil_1.default.isPlainObject(rm_result)) {
873
+ const result = {
874
+ result: false,
875
+ message: 'Could not remove service data from ' + strRemoveType
876
+ };
877
+ dbglogging_1.default.elog(result.message);
878
+ k2hr3resutil_1.default.errResponse(req, res, 403); // 403: Forbidden(is this status OK?)
879
+ }
880
+ else {
881
+ const result = {
882
+ result: k2hr3apiutil_1.default.isBoolean(rm_result.result) ? rm_result.result : false,
883
+ message: k2hr3apiutil_1.default.isString(rm_result.message) ? rm_result.message : 'Could not get error message in response from ' + strRemoveType
884
+ };
885
+ dbglogging_1.default.elog(result.message);
886
+ k2hr3resutil_1.default.errResponse(req, res, 403); // 403: Forbidden(is this status OK?)
887
+ }
888
+ return;
889
+ }
890
+ dbglogging_1.default.dlog('succeed : ' + k2hr3apiutil_1.default.getSafeString(rm_result.message));
891
+ res.status(204); // 204: No Content
892
+ res.send();
893
+ });
894
+ //---------------------------------------------------------
895
+ // Exports
896
+ //---------------------------------------------------------
897
+ //
898
+ // Functions
899
+ //
900
+ exports.default = router;
901
+ /*
902
+ * Local variables:
903
+ * tab-width: 4
904
+ * c-basic-offset: 4
905
+ * End:
906
+ * vim600: noexpandtab sw=4 ts=4 fdm=marker
907
+ * vim<600: noexpandtab sw=4 ts=4
908
+ */