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,1489 @@
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 Jun 8 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
+ // Utility for parsing common input parameters
36
+ //
37
+ // This function parse token(user or role or not have this) from HTTP request(req),
38
+ // and role name/resource name(and yrn), etc.
39
+ // If request URI has resource name(path), do not specify default_resource_name value.
40
+ // The other hand, when default_resource_name is specified, the request URI can not
41
+ // have resource name(path) in it.
42
+ //
43
+ // return : {
44
+ // res_obj: {
45
+ // result: true/false
46
+ // message: null or error message
47
+ // },
48
+ // status: status code(default 200)
49
+ // parameters: {
50
+ // token_type: null or 'user' or 'role'
51
+ // token_str: token string(if user token or role token)
52
+ // token_info: null or object(returned from checkToken)
53
+ // user_name: null or user name(if user token)
54
+ // tenant_name: null or user name(if user token or role token)
55
+ // keys: k2hr3keys object
56
+ // res_yrn: target resource yrn
57
+ // res_name: target resource name
58
+ // res_tenant: resource's tenant
59
+ // res_service: resource's service when resource is full yrn, null when not full yrn
60
+ // }
61
+ // }
62
+ //
63
+ const rawParseBaseParamRequestAPI = (req, is_allow_service, default_resource_name) => {
64
+ const parameters = {
65
+ token_type: null,
66
+ token_str: null,
67
+ token_info: null,
68
+ user_name: null,
69
+ tenant_name: null,
70
+ keys: r3keys(),
71
+ res_yrn: null,
72
+ res_name: null,
73
+ res_tenant: null,
74
+ res_service: null
75
+ };
76
+ const result = {
77
+ result: true,
78
+ message: null,
79
+ status: 200,
80
+ parameters: parameters
81
+ };
82
+ //
83
+ // check token for API mode
84
+ //
85
+ if (k2hr3tokens_1.default.hasAuthTokenHeader(req)) {
86
+ const token_result = k2hr3tokens_1.default.checkToken(req, true); // scoped, both token
87
+ if (!token_result.result) {
88
+ result.result = token_result.result;
89
+ result.message = token_result.message;
90
+ result.status = token_result.status;
91
+ dbglogging_1.default.elog(result.message);
92
+ return result;
93
+ }
94
+ const token_info = token_result.token_info;
95
+ if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
96
+ result.result = false;
97
+ result.message = 'specified wrong token or it is not scoped user token';
98
+ result.status = 400; // 400: Bad Request
99
+ dbglogging_1.default.elog(result.message);
100
+ return result;
101
+ }
102
+ result.parameters.token_type = k2hr3apiutil_1.default.isSafeString(token_result.token_type) ? token_result.token_type : null;
103
+ result.parameters.token_str = k2hr3apiutil_1.default.isSafeString(token_result.token) ? token_result.token : null;
104
+ result.parameters.token_info = token_info;
105
+ result.parameters.user_name = k2hr3apiutil_1.default.getSafeString(token_info.user);
106
+ result.parameters.tenant_name = k2hr3apiutil_1.default.getSafeString(token_info.tenant).toLowerCase();
107
+ result.parameters.keys = r3keys(token_info.user, token_info.tenant);
108
+ }
109
+ const tmpTenant = k2hr3tokens_1.default.isResTypeCheckRoleToken(result.parameters.token_info) ? (k2hr3apiutil_1.default.isSafeString(result.parameters.token_info.tenant) ? result.parameters.token_info.tenant : null) : null;
110
+ const tmpUser = k2hr3tokens_1.default.isResTypeCheckRoleToken(result.parameters.token_info) ? (k2hr3apiutil_1.default.isSafeString(result.parameters.token_info.user) ? result.parameters.token_info.user : null) : null;
111
+ //
112
+ // check service parameter in request
113
+ //
114
+ let service_param = null;
115
+ if (is_allow_service) {
116
+ if (k2hr3apiutil_1.default.compareCaseString('POST', req.method)) {
117
+ if (k2hr3apiutil_1.default.isPlainObject(req.body) && k2hr3apiutil_1.default.isSafeString(req.body.service)) {
118
+ service_param = k2hr3apiutil_1.default.getSafeString(req.body.service).trim();
119
+ }
120
+ }
121
+ else {
122
+ if (k2hr3apiutil_1.default.isPlainObject(req.query) && k2hr3apiutil_1.default.isSafeString(req.query.service)) {
123
+ service_param = k2hr3apiutil_1.default.getSafeString(req.query.service).trim();
124
+ }
125
+ }
126
+ }
127
+ //
128
+ // get resource full yrn
129
+ //
130
+ const requestptn = new RegExp('^/v1/resource/(.*)'); // regex = /^\/v1\/resource\/(.*)/
131
+ const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
132
+ if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
133
+ if (!k2hr3apiutil_1.default.isSafeString(default_resource_name)) {
134
+ result.result = false;
135
+ result.message = 'Default resource name is not specified or wrong value : ' + JSON.stringify(default_resource_name);
136
+ result.status = 400; // 400: Bad Request
137
+ dbglogging_1.default.elog(result.message);
138
+ return result;
139
+ }
140
+ result.parameters.res_yrn = k2hr3apiutil_1.default.getSafeString(default_resource_name).toLowerCase();
141
+ }
142
+ else {
143
+ result.parameters.res_yrn = reqmatchs[1].toLowerCase();
144
+ }
145
+ //
146
+ // make resource name from resource yrn
147
+ //
148
+ let nameptn = new RegExp('^' + result.parameters.keys.MATCH_ANY_TENANT_RESOURCE); // regex = /^yrn:yahoo:(.*)::(.*):resource:(.*)/
149
+ const namematchs = result.parameters.res_yrn.match(nameptn);
150
+ if (!k2hr3apiutil_1.default.isStringArray(namematchs) || !k2hr3apiutil_1.default.isNotEmptyArray(namematchs) || namematchs.length < 4) {
151
+ // res_yrn is not full yrn to resource, then check wrong resource name
152
+ nameptn = new RegExp('^' + result.parameters.keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
153
+ if (result.parameters.res_yrn.match(nameptn)) {
154
+ result.result = false;
155
+ result.message = 'Request query has wrong yrn full path to resource';
156
+ result.status = 400; // 400: Bad Request
157
+ dbglogging_1.default.elog(result.message);
158
+ return result;
159
+ }
160
+ // no token need full yrn to resource(other token has tenant name)
161
+ if (!k2hr3apiutil_1.default.isSafeString(result.parameters.token_type)) {
162
+ result.result = false;
163
+ result.message = 'Request query does not have yrn full path to resource';
164
+ result.status = 400; // 400: Bad Request
165
+ dbglogging_1.default.elog(result.message);
166
+ return result;
167
+ }
168
+ // make resource yrn from resource name(sometimes, a case of user token come here.)
169
+ result.parameters.res_name = result.parameters.res_yrn;
170
+ result.parameters.res_tenant = result.parameters.tenant_name; // resource is only name, then resource's tenant is same.
171
+ result.parameters.res_service = k2hr3apiutil_1.default.isSafeString(service_param) ? service_param.toLowerCase() : null;
172
+ result.parameters.keys = r3keys(tmpUser, result.parameters.res_tenant, result.parameters.res_service);
173
+ result.parameters.res_yrn = result.parameters.keys.RESOURCE_TOP_KEY + ':' + result.parameters.res_name;
174
+ }
175
+ else {
176
+ // res_yrn is full yrn to resource, then need to check tenant name
177
+ if (k2hr3apiutil_1.default.isSafeString(result.parameters.token_type) && !k2hr3apiutil_1.default.compareCaseString(namematchs[2], tmpTenant)) {
178
+ result.result = false;
179
+ result.message = 'Request query has wrong yrn full path(tenant=' + namematchs[2] + ') to resource(tenant=' + k2hr3apiutil_1.default.getSafeString(tmpTenant) + ')';
180
+ result.status = 400; // 400: Bad Request
181
+ dbglogging_1.default.elog(result.message);
182
+ return result;
183
+ }
184
+ // check service name
185
+ if (k2hr3apiutil_1.default.isSafeString(service_param) && !k2hr3apiutil_1.default.compareCaseString(service_param, namematchs[1])) {
186
+ result.result = false;
187
+ result.message = 'Request query has service name(' + service_param + ') and path has service name(' + namematchs[1] + '), but both are not same service name.';
188
+ result.status = 400; // 400: Bad Request
189
+ dbglogging_1.default.elog(result.message);
190
+ return result;
191
+ }
192
+ result.parameters.res_name = namematchs[3].toLowerCase();
193
+ result.parameters.res_tenant = namematchs[2].toLowerCase(); // resource is yrn, then resource's tenant is set from yrn.
194
+ result.parameters.res_service = namematchs[1].toLowerCase(); // resource is not yrn, then service is not specified.
195
+ result.parameters.keys = r3keys(tmpUser, tmpTenant, result.parameters.res_service);
196
+ }
197
+ return result;
198
+ };
199
+ //
200
+ // Mountpath : '/v1/resource'
201
+ //
202
+ // POST '/v1/resource' : post resource on version 1
203
+ // HEADER : X-Auth-Token => User token
204
+ // body : {
205
+ // "resource": {
206
+ // "name": <resource name> => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>"
207
+ // <resource> can include '/' for hierarchical path
208
+ // "type": <data type> => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/type"
209
+ // data type must be string or json.
210
+ // if data is null or not specified, this value is not used.
211
+ // "data": <resource data> => value for "yrn:yahoo:<service>::<tenant>:resource:<resource>"
212
+ // data must be encoded by encodeURI, because data is allowed CR, control code etc.
213
+ // but nodejs is decodeURI automatically
214
+ // "keys": {foo: bar, ...} => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/keys"
215
+ // specify any associative array(SSL certificate, host key, etc)
216
+ // if null or undefined is specified, not update this member in resource when this resource exists.
217
+ // if '' or string(JSON), this member is set into "keys".
218
+ // "alias": [<resource yrn full path>, ...] => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/@"
219
+ // specify another resource as "yrn:yahoo:<service>::<tenant>:resource:<resource>"
220
+ // if null or undefined is specified, not update this member in resource when this resource exists.
221
+ // if '' or zero array, this member in resource is set empty array.
222
+ // }
223
+ // }
224
+ // response body : {
225
+ // result: true/false
226
+ // message: messages
227
+ // }
228
+ //
229
+ // POST '/v1/resource/name' : post resource on version 1
230
+ // HEADER : X-Auth-Token => Role token
231
+ // body : {
232
+ // "resource": {
233
+ // "type": <data type> => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/type"
234
+ // data type must be string or json.
235
+ // if data is null or not specified, this value is not used.
236
+ // "data": <resource data> => value for "yrn:yahoo:<service>::<tenant>:resource:<resource>"
237
+ // data must be encoded by encodeURI, because data is allowed CR, control code etc.
238
+ // but nodejs is decodeURI automatically
239
+ // "keys": {foo: bar, ...} => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/keys"
240
+ // specify any associative array(SSL certificate, host key, etc)
241
+ // if null or undefined is specified, not update this member in resource when this resource exists.
242
+ // if '' or string(JSON), this member is set into "keys".
243
+ // }
244
+ // }
245
+ // response body : {
246
+ // result: true/false
247
+ // message: messages
248
+ // }
249
+ //
250
+ //
251
+ // POST '/v1/resource/name' : post resource on version 1 => name is full yrn to resource
252
+ // HEADER : X-Auth-Token => undefined
253
+ // body : {
254
+ // "resource": {
255
+ // "port": <port number> => undefined(null) is allowed. if empty value, default port is 0(any)
256
+ // "cuk": <container unique key> => undefined(null) is allowed. if empty value, any value.
257
+ // "role": <role full yrn> => key is "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>...}"
258
+ // "type": <data type> => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/type"
259
+ // data type must be string or json.
260
+ // if data is null or not specified, this value is not used.
261
+ // "data": <resource data> => value for "yrn:yahoo:<service>::<tenant>:resource:<resource>"
262
+ // data must be encoded by encodeURI, because data is allowed CR, control code etc.
263
+ // but nodejs is decodeURI automatically
264
+ // "keys": {foo: bar, ...} => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/keys"
265
+ // specify any associative array(SSL certificate, host key, etc)
266
+ // if null or undefined is specified, not update this member in resource when this resource exists.
267
+ // if '' or string(JSON), this member is set into "keys".
268
+ // }
269
+ // }
270
+ // response body : {
271
+ // result: true/false
272
+ // message: messages
273
+ // }
274
+ //
275
+ //
276
+ router.post('/', (req, res, _) => {
277
+ dbglogging_1.default.dlog('CALL:', req.method, req.url);
278
+ res.type('application/json; charset=utf-8');
279
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
280
+ !k2hr3apiutil_1.default.isPlainObject(req.body) ||
281
+ !k2hr3apiutil_1.default.isPlainObject(req.body.resource)) {
282
+ const result = {
283
+ result: false,
284
+ message: 'POST body does not have resource data'
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 common parameters(token, role, resource etc)
292
+ //------------------------------
293
+ const resobj = rawParseBaseParamRequestAPI(req, false, k2hr3apiutil_1.default.isSafeString(req.body.resource.name) ? req.body.resource.name : null);
294
+ if (!resobj.result) {
295
+ const result = {
296
+ result: false,
297
+ message: resobj.message
298
+ };
299
+ dbglogging_1.default.elog(result.message);
300
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status, result);
301
+ return;
302
+ }
303
+ const comparam = resobj.parameters;
304
+ //------------------------------
305
+ // check resource
306
+ //------------------------------
307
+ if (k2hr3apiutil_1.default.isString(comparam.token_type) &&
308
+ (k2hr3apiutil_1.default.isSafeString(comparam.tenant_name) !== k2hr3apiutil_1.default.isSafeString(comparam.res_tenant) ||
309
+ k2hr3apiutil_1.default.getSafeString(comparam.tenant_name) !== k2hr3apiutil_1.default.getSafeString(comparam.res_tenant) ||
310
+ k2hr3apiutil_1.default.isSafeString(comparam.res_service))) {
311
+ const result = {
312
+ result: false,
313
+ message: 'POST request resource(' + JSON.stringify(comparam.res_name) + ') is under tenant(' + JSON.stringify(comparam.res_tenant) + ') and service(' + JSON.stringify(comparam.res_service) + '), it is not under tenant(' + JSON.stringify(comparam.tenant_name) + ').'
314
+ };
315
+ dbglogging_1.default.elog(result.message);
316
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
317
+ return;
318
+ }
319
+ //------------------------------
320
+ // check arguments
321
+ //------------------------------
322
+ // data type
323
+ let type;
324
+ if (k2hr3apiutil_1.default.isSafeString(req.body.resource.type)) {
325
+ type = k2hr3apiutil_1.default.getSafeString(req.body.resource.type);
326
+ if (!k2hr3apiutil_1.default.compareCaseString('string', type) && !k2hr3apiutil_1.default.compareCaseString('object', type)) {
327
+ const result = {
328
+ result: false,
329
+ message: 'POST resource:type field is wrong : ' + JSON.stringify(req.body.resource.type)
330
+ };
331
+ dbglogging_1.default.elog(result.message);
332
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
333
+ return;
334
+ }
335
+ }
336
+ else {
337
+ type = comparam.keys.VALUE_STRING_TYPE; // default type is string
338
+ }
339
+ // data
340
+ let data = null;
341
+ if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_STRING_TYPE, type)) {
342
+ if (k2hr3apiutil_1.default.isString(req.body.resource.data) && '' === req.body.resource.data) {
343
+ data = '';
344
+ }
345
+ else if (k2hr3apiutil_1.default.isSafeString(req.body.resource.data)) {
346
+ // data is string(nodejs is decodeURI automatically)
347
+ // this value includes control codes(\n, etc)
348
+ data = k2hr3apiutil_1.default.getSafeString(req.body.resource.data);
349
+ }
350
+ }
351
+ else { // type == object
352
+ if (k2hr3apiutil_1.default.isValTypeAll(req.body.resource.data)) {
353
+ data = req.body.resource.data;
354
+ }
355
+ }
356
+ // keys
357
+ let resource_keys = null;
358
+ if (k2hr3apiutil_1.default.isSafeEntity(req.body.resource.keys)) {
359
+ if (k2hr3apiutil_1.default.isString(req.body.resource.keys) && '' === req.body.resource.keys) {
360
+ resource_keys = '';
361
+ }
362
+ else if (k2hr3dkc_1.default.isDkcTypeResourceRawKeysValue(req.body.resource.keys)) {
363
+ resource_keys = req.body.resource.keys;
364
+ }
365
+ else if (k2hr3apiutil_1.default.isSafeString(req.body.resource.keys)) {
366
+ const tmp_keys = k2hr3apiutil_1.default.getSafeString(req.body.resource.keys);
367
+ if (k2hr3apiutil_1.default.checkSimpleJSON(tmp_keys)) {
368
+ const tmp_parsed_keys = JSON.parse(tmp_keys);
369
+ if (k2hr3apiutil_1.default.isSafeString(tmp_parsed_keys)) {
370
+ resource_keys = tmp_parsed_keys;
371
+ }
372
+ else if (k2hr3dkc_1.default.isDkcTypeResourceRawKeysValue(tmp_parsed_keys)) {
373
+ resource_keys = tmp_parsed_keys;
374
+ }
375
+ else {
376
+ resource_keys = null;
377
+ }
378
+ }
379
+ else {
380
+ resource_keys = tmp_keys;
381
+ }
382
+ }
383
+ else {
384
+ const result = {
385
+ result: false,
386
+ message: 'POST resource:keys field is wrong : ' + JSON.stringify(req.body.resource.keys)
387
+ };
388
+ dbglogging_1.default.elog(result.message);
389
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
390
+ return;
391
+ }
392
+ }
393
+ // alias
394
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type) && k2hr3apiutil_1.default.isSafeEntity(req.body.resource.alias)) {
395
+ const result = {
396
+ result: false,
397
+ message: 'POST resource:alias field is specified, but it is not allowed by not user token : ' + JSON.stringify(req.body.resource.alias)
398
+ };
399
+ dbglogging_1.default.elog(result.message);
400
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
401
+ return;
402
+ }
403
+ let aliases = null;
404
+ if ('user' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
405
+ const aliasptn = new RegExp('^' + comparam.keys.RESOURCE_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:resource:(.*)/
406
+ const aliaspram = k2hr3apiutil_1.default.getNormalizeParameter(req.body.resource.alias, aliasptn, null);
407
+ if (false === aliaspram.result) {
408
+ const result = {
409
+ result: false,
410
+ message: 'POST resource:alias field is wrong : ' + JSON.stringify(req.body.resource.alias)
411
+ };
412
+ dbglogging_1.default.elog(result.message);
413
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
414
+ return;
415
+ }
416
+ aliases = aliaspram.parameter ?? null;
417
+ }
418
+ // role yrn/ip address/port for no token
419
+ let clientip = null;
420
+ let port = 0;
421
+ let cuk = null;
422
+ let role_yrn = null;
423
+ if (k2hr3apiutil_1.default.isSafeString(comparam.token_type) && (k2hr3apiutil_1.default.isSafeEntity(req.body.resource.port) || k2hr3apiutil_1.default.isSafeEntity(req.body.resource.cuk) || k2hr3apiutil_1.default.isSafeEntity(req.body.resource.role))) {
424
+ const result = {
425
+ result: false,
426
+ message: 'POST resource:port/cuk/role field is specified, but it is not allowed by no token : port=' + JSON.stringify(req.body.resource.port) + ', cuk=' + JSON.stringify(req.body.resource.cuk) + ', role=' + JSON.stringify(req.body.resource.role)
427
+ };
428
+ dbglogging_1.default.elog(result.message);
429
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
430
+ return;
431
+ }
432
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.token_type)) {
433
+ // role
434
+ if (!k2hr3apiutil_1.default.isSafeString(req.body.resource.role)) {
435
+ const result = {
436
+ result: false,
437
+ message: 'POST request does not have role yrn in post data.'
438
+ };
439
+ dbglogging_1.default.elog(result.message);
440
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
441
+ return;
442
+ }
443
+ // [NOTE]
444
+ // not check role is full yrn here.
445
+ role_yrn = k2hr3apiutil_1.default.getSafeString(req.body.resource.role);
446
+ // ip
447
+ clientip = k2hr3apiutil_1.default.getClientIpAddress(req);
448
+ if (!k2hr3apiutil_1.default.isSafeString(clientip)) {
449
+ const result = {
450
+ result: false,
451
+ message: 'POST request does not have ip address for client.'
452
+ };
453
+ dbglogging_1.default.elog(result.message);
454
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
455
+ return;
456
+ }
457
+ // port
458
+ if (k2hr3apiutil_1.default.isSafeNumeric(req.body.resource.port)) {
459
+ const tmpPort = k2hr3apiutil_1.default.cvtToNumber(req.body.resource.port);
460
+ if (k2hr3apiutil_1.default.isSafeNumber(tmpPort)) {
461
+ port = tmpPort;
462
+ }
463
+ else {
464
+ port = 0;
465
+ }
466
+ }
467
+ else {
468
+ port = 0;
469
+ }
470
+ // cuk
471
+ if (k2hr3apiutil_1.default.isSafeString(req.body.resource.cuk) && k2hr3apiutil_1.default.isSafeString(req.body.resource.cuk.trim())) {
472
+ cuk = req.body.resource.cuk.trim();
473
+ }
474
+ }
475
+ //------------------------------
476
+ // set all field to resource
477
+ //------------------------------
478
+ let res_result;
479
+ if ('user' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
480
+ res_result = k2hr3dkc_1.default.setResourceAll(comparam.user_name, comparam.tenant_name, comparam.res_name, type, data, resource_keys, aliases);
481
+ }
482
+ else if ('role' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
483
+ res_result = k2hr3dkc_1.default.setResourceAllByRole((comparam.token_info?.role ?? null), comparam.tenant_name, comparam.res_name, type, data, resource_keys);
484
+ }
485
+ else if (!k2hr3apiutil_1.default.isSafeString(comparam.token_type)) {
486
+ res_result = k2hr3dkc_1.default.setResourceAllByIP(clientip, port, cuk, role_yrn, comparam.res_name, type, data, resource_keys);
487
+ }
488
+ else {
489
+ // broken token
490
+ const result = {
491
+ result: false,
492
+ message: 'POST request is failure by internal error(token data broken).'
493
+ };
494
+ dbglogging_1.default.elog(result.message);
495
+ k2hr3resutil_1.default.errResponse(req, res, 500, result); // 500: Internal Error
496
+ return;
497
+ }
498
+ if (!k2hr3apiutil_1.default.isPlainObject(res_result) || !k2hr3apiutil_1.default.isBoolean(res_result.result) || false === res_result.result) {
499
+ if (!k2hr3apiutil_1.default.isPlainObject(res_result)) {
500
+ const result = {
501
+ result: false,
502
+ message: 'POST Could not get response from setResourceAll'
503
+ };
504
+ dbglogging_1.default.elog(result.message);
505
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
506
+ }
507
+ else {
508
+ const result = {
509
+ result: false,
510
+ message: k2hr3apiutil_1.default.isSafeString(res_result.message) ? res_result.message : 'POST Could not get error message in response from setResourceAll'
511
+ };
512
+ dbglogging_1.default.elog(result.message);
513
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
514
+ }
515
+ return;
516
+ }
517
+ dbglogging_1.default.dlog('succeed : ' + k2hr3apiutil_1.default.getSafeString(res_result.message));
518
+ const success_result = {
519
+ result: true,
520
+ message: null
521
+ };
522
+ res.status(201); // 201: Created
523
+ res.send(JSON.stringify(success_result));
524
+ });
525
+ //
526
+ // Mountpath : '/v1/resource'
527
+ //
528
+ // PUT '/v1/resource' : post resource on version 1
529
+ // HEADER : X-Auth-Token => User token
530
+ // url argument :
531
+ // "name": <resource name> => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>"
532
+ // <resource> can include '/' for hierarchical path
533
+ // "type": <data type> => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/type"
534
+ // type is object or string, default is string.
535
+ // "data": <resource data> => value for "yrn:yahoo:<service>::<tenant>:resource:<resource>"
536
+ // data must be formatted by JSON, and it is allowed CR, control code etc.
537
+ // "keys": {foo: bar, ...} => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/keys"
538
+ // specify any associative array(SSL certificate, host key, etc), it is formatted by JSON.
539
+ // if null or undefined is specified, not update this member in resource when this resource exists.
540
+ // if '' or associative array, this member is set into "keys".
541
+ // "alias": [<resource yrn full path>, ...] => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/@"
542
+ // specify another resource array as "yrn:yahoo:<service>::<tenant>:resource:<resource>", it is formatted by JSON.
543
+ // if null or undefined is specified, not update this member in resource when this resource exists.
544
+ // if '' or zero array, this member in resource is set empty array.
545
+ // response body : {
546
+ // result: true/false
547
+ // message: messages
548
+ // }
549
+ //
550
+ // PUT '/v1/resource/name' : post resource on version 1
551
+ // HEADER : X-Auth-Token => Role token
552
+ // url argument :
553
+ // "type": <data type> => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/type"
554
+ // type is object or string, default is string.
555
+ // "data": <resource data> => value for "yrn:yahoo:<service>::<tenant>:resource:<resource>"
556
+ // data must be formatted by JSON, and it is allowed CR, control code etc.
557
+ // "keys": {foo: bar, ...} => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/keys"
558
+ // specify any associative array(SSL certificate, host key, etc), it is formatted by JSON.
559
+ // if null or undefined is specified, not update this member in resource when this resource exists.
560
+ // if '' or associative array, this member is set into "keys".
561
+ // response body : {
562
+ // result: true/false
563
+ // message: messages
564
+ // }
565
+ //
566
+ // PUT '/v1/resource/name' : post resource on version 1 => name is full yrn to resource
567
+ // HEADER : X-Auth-Token => undefined
568
+ // url argument :
569
+ // "port": <port number> => undefined(null) is allowed. if empty value, default port is 0(any)
570
+ // "cuk": <container unique key> => undefined(null) is allowed. if empty value, any value.
571
+ // "role": <role full yrn> => key is "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>...}"
572
+ // "type": <data type> => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/type"
573
+ // type is object or string, default is string.
574
+ // "data": <resource data> => value for "yrn:yahoo:<service>::<tenant>:resource:<resource>"
575
+ // data must be formatted by JSON, and it is allowed CR, control code etc.
576
+ // "keys": {foo: bar, ...} => key is "yrn:yahoo:<service>::<tenant>:resource:<resource>/keys"
577
+ // specify any associative array(SSL certificate, host key, etc), it is formatted by JSON.
578
+ // if null or undefined is specified, not update this member in resource when this resource exists.
579
+ // if '' or associative array, this member is set into "keys".
580
+ // response body : {
581
+ // result: true/false
582
+ // message: messages
583
+ // }
584
+ //
585
+ router.put('/', (req, res, _) => {
586
+ dbglogging_1.default.dlog('CALL:', req.method, req.url);
587
+ res.type('application/json; charset=utf-8');
588
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
589
+ !k2hr3apiutil_1.default.isPlainObject(req.query)) {
590
+ const result = {
591
+ result: false,
592
+ message: 'PUT argument does not have any data'
593
+ };
594
+ dbglogging_1.default.elog(result.message);
595
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
596
+ return;
597
+ }
598
+ //------------------------------
599
+ // check common parameters(token, role, resource etc)
600
+ //------------------------------
601
+ const resobj = rawParseBaseParamRequestAPI(req, false, (k2hr3apiutil_1.default.isString(req.query.name) ? req.query.name : null));
602
+ if (!resobj.result) {
603
+ const result = {
604
+ result: false,
605
+ message: resobj.message
606
+ };
607
+ dbglogging_1.default.elog(result.message);
608
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status, result);
609
+ return;
610
+ }
611
+ const comparam = resobj.parameters;
612
+ //------------------------------
613
+ // check resource
614
+ //------------------------------
615
+ if (k2hr3apiutil_1.default.isString(comparam.token_type) &&
616
+ (k2hr3apiutil_1.default.isSafeString(comparam.tenant_name) !== k2hr3apiutil_1.default.isSafeString(comparam.res_tenant) ||
617
+ k2hr3apiutil_1.default.getSafeString(comparam.tenant_name) !== k2hr3apiutil_1.default.getSafeString(comparam.res_tenant) ||
618
+ k2hr3apiutil_1.default.isSafeString(comparam.res_service))) {
619
+ const result = {
620
+ result: false,
621
+ message: 'PUT request resource(' + JSON.stringify(comparam.res_name) + ') is under tenant(' + JSON.stringify(comparam.res_tenant) + ') and service(' + JSON.stringify(comparam.res_service) + '), it is not under tenant(' + JSON.stringify(comparam.tenant_name) + ').'
622
+ };
623
+ dbglogging_1.default.elog(result.message);
624
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
625
+ return;
626
+ }
627
+ //------------------------------
628
+ // check arguments
629
+ //------------------------------
630
+ // data type
631
+ let type;
632
+ if (k2hr3apiutil_1.default.isSafeString(req.query.type)) {
633
+ type = k2hr3apiutil_1.default.getSafeString(req.query.type);
634
+ if (!k2hr3apiutil_1.default.compareCaseString('string', type) && !k2hr3apiutil_1.default.compareCaseString('object', type)) {
635
+ const result = {
636
+ result: false,
637
+ message: 'PUT resource:type field is wrong : ' + JSON.stringify(req.query.type)
638
+ };
639
+ dbglogging_1.default.elog(result.message);
640
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
641
+ return;
642
+ }
643
+ }
644
+ else {
645
+ type = comparam.keys.VALUE_STRING_TYPE; // default type is string
646
+ }
647
+ // data
648
+ let data = null;
649
+ if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_STRING_TYPE, type)) {
650
+ if (k2hr3apiutil_1.default.isString(req.query.data) && '' === req.query.data) {
651
+ data = '';
652
+ }
653
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.data)) {
654
+ const tmpData = k2hr3apiutil_1.default.getSafeString(req.query.data);
655
+ if (k2hr3apiutil_1.default.checkSimpleJSON(tmpData)) {
656
+ data = JSON.parse(tmpData); // decode JSON
657
+ }
658
+ else if (k2hr3apiutil_1.default.isSafeString(tmpData)) {
659
+ data = tmpData;
660
+ }
661
+ }
662
+ }
663
+ else { // type == object
664
+ if (k2hr3apiutil_1.default.isSafeString(req.query.data)) {
665
+ const tmpData = k2hr3apiutil_1.default.getSafeString(req.query.data);
666
+ if (k2hr3apiutil_1.default.checkSimpleJSON(tmpData)) {
667
+ data = JSON.parse(tmpData); // decode JSON
668
+ }
669
+ else if (k2hr3apiutil_1.default.isSafeString(tmpData)) {
670
+ data = tmpData;
671
+ }
672
+ }
673
+ }
674
+ // keys
675
+ let resource_keys = null;
676
+ if (k2hr3apiutil_1.default.isString(req.query.keys) && '' === req.query.keys) {
677
+ resource_keys = '';
678
+ }
679
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.keys)) {
680
+ // keys is encoded by JSON, this value is associative array.
681
+ //
682
+ const tmp_keys = k2hr3apiutil_1.default.getSafeString(req.query.keys);
683
+ if (k2hr3apiutil_1.default.checkSimpleJSON(tmp_keys)) {
684
+ const tmp_parsed_keys = JSON.parse(tmp_keys);
685
+ if (k2hr3apiutil_1.default.isSafeString(tmp_parsed_keys)) {
686
+ resource_keys = tmp_parsed_keys;
687
+ }
688
+ else if (k2hr3dkc_1.default.isDkcTypeResourceRawKeysValue(tmp_parsed_keys)) {
689
+ resource_keys = tmp_parsed_keys;
690
+ }
691
+ else {
692
+ resource_keys = null;
693
+ }
694
+ }
695
+ else {
696
+ resource_keys = tmp_keys;
697
+ }
698
+ }
699
+ // alias
700
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type) && k2hr3apiutil_1.default.isSafeEntity(req.query.alias)) {
701
+ const result = {
702
+ result: false,
703
+ message: 'PUT resource:alias field is specified, but it is not allowed by not user token : ' + JSON.stringify(req.query.alias)
704
+ };
705
+ dbglogging_1.default.elog(result.message);
706
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
707
+ return;
708
+ }
709
+ let aliases = null;
710
+ if ('user' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
711
+ if (k2hr3apiutil_1.default.isString(req.query.alias) && '' === req.query.alias) {
712
+ aliases = '';
713
+ }
714
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.alias)) {
715
+ // alias is encoded by JSON, this value is array.
716
+ //
717
+ let tmpaliases = k2hr3apiutil_1.default.getSafeString(req.query.alias);
718
+ if (k2hr3apiutil_1.default.checkSimpleJSON(tmpaliases)) {
719
+ tmpaliases = JSON.parse(tmpaliases);
720
+ }
721
+ const aliasptn = new RegExp('^' + comparam.keys.RESOURCE_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:resource:(.*)/
722
+ const aliaspram = k2hr3apiutil_1.default.getNormalizeParameter(tmpaliases, aliasptn, null);
723
+ if (false === aliaspram.result) {
724
+ const result = {
725
+ result: false,
726
+ message: 'PUT resource:alias field is wrong : ' + req.query.alias
727
+ };
728
+ dbglogging_1.default.elog(result.message);
729
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
730
+ return;
731
+ }
732
+ aliases = aliaspram.parameter ?? null;
733
+ }
734
+ }
735
+ // role yrn/ip address/port for no token
736
+ let clientip = null;
737
+ let port = 0;
738
+ let cuk = null;
739
+ let role_yrn = null;
740
+ if (k2hr3apiutil_1.default.isSafeString(comparam.token_type) && (k2hr3apiutil_1.default.isSafeEntity(req.query.port) || k2hr3apiutil_1.default.isSafeEntity(req.query.cuk) || k2hr3apiutil_1.default.isSafeEntity(req.query.role))) {
741
+ const result = {
742
+ result: false,
743
+ message: 'PUT resource:port/cuk/role field is specified, but it is not allowed by no token : port=' + JSON.stringify(req.query.port) + ', cuk=' + JSON.stringify(req.query.cuk) + ', role=' + JSON.stringify(req.query.role)
744
+ };
745
+ dbglogging_1.default.elog(result.message);
746
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
747
+ return;
748
+ }
749
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.token_type)) {
750
+ // role
751
+ if (!k2hr3apiutil_1.default.isSafeString(req.query.role)) {
752
+ const result = {
753
+ result: false,
754
+ message: 'PUT request does not have role yrn in post data.'
755
+ };
756
+ dbglogging_1.default.elog(result.message);
757
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
758
+ return;
759
+ }
760
+ // [NOTE]
761
+ // not check role is full yrn here.
762
+ role_yrn = k2hr3apiutil_1.default.getSafeString(req.query.role);
763
+ // ip
764
+ clientip = k2hr3apiutil_1.default.getClientIpAddress(req);
765
+ if (!k2hr3apiutil_1.default.isSafeString(clientip)) {
766
+ const result = {
767
+ result: false,
768
+ message: 'PUT request does not have ip address for client.'
769
+ };
770
+ dbglogging_1.default.elog(result.message);
771
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
772
+ return;
773
+ }
774
+ // port
775
+ if (k2hr3apiutil_1.default.isSafeNumeric(req.query.port)) {
776
+ const tmpPort = k2hr3apiutil_1.default.cvtToNumber(req.query.port);
777
+ if (k2hr3apiutil_1.default.isSafeNumber(tmpPort)) {
778
+ port = tmpPort;
779
+ }
780
+ else {
781
+ port = 0;
782
+ }
783
+ }
784
+ else {
785
+ port = 0;
786
+ }
787
+ // cuk
788
+ if (k2hr3apiutil_1.default.isSafeString(req.query.cuk) && k2hr3apiutil_1.default.isSafeString(req.query.cuk.trim())) {
789
+ cuk = req.query.cuk.trim();
790
+ }
791
+ }
792
+ //------------------------------
793
+ // set all field to resource
794
+ //------------------------------
795
+ let res_result;
796
+ if ('user' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
797
+ res_result = k2hr3dkc_1.default.setResourceAll(comparam.user_name, comparam.tenant_name, comparam.res_name, type, data, resource_keys, aliases);
798
+ }
799
+ else if ('role' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
800
+ res_result = k2hr3dkc_1.default.setResourceAllByRole((comparam.token_info?.role ?? null), comparam.tenant_name, comparam.res_name, type, data, resource_keys);
801
+ }
802
+ else if (!k2hr3apiutil_1.default.isSafeString(comparam.token_type)) {
803
+ res_result = k2hr3dkc_1.default.setResourceAllByIP(clientip, port, cuk, role_yrn, comparam.res_name, type, data, resource_keys);
804
+ }
805
+ else {
806
+ // broken token
807
+ const result = {
808
+ result: false,
809
+ message: 'PUT request is failure by internal error(token data broken).'
810
+ };
811
+ dbglogging_1.default.elog(result.message);
812
+ k2hr3resutil_1.default.errResponse(req, res, 500, result); // 500: Internal Error
813
+ return;
814
+ }
815
+ if (!k2hr3apiutil_1.default.isPlainObject(res_result) || !k2hr3apiutil_1.default.isBoolean(res_result.result) || false === res_result.result) {
816
+ if (!k2hr3apiutil_1.default.isPlainObject(res_result)) {
817
+ const result = {
818
+ result: false,
819
+ message: 'PUT Could not get response from setResourceAll'
820
+ };
821
+ dbglogging_1.default.elog(result.message);
822
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
823
+ }
824
+ else {
825
+ const result = {
826
+ result: false,
827
+ message: k2hr3apiutil_1.default.isSafeEntity(res_result.message) ? res_result.message : 'PUT Could not get error message in response from setResourceAll'
828
+ };
829
+ dbglogging_1.default.elog(result.message);
830
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
831
+ }
832
+ return;
833
+ }
834
+ dbglogging_1.default.dlog('succeed : ' + k2hr3apiutil_1.default.getSafeString(res_result.message));
835
+ const success_result = {
836
+ result: true,
837
+ message: null
838
+ };
839
+ res.status(201); // 201: Created
840
+ res.send(JSON.stringify(success_result));
841
+ });
842
+ //
843
+ // Mountpath : '/v1/resource/*'
844
+ //
845
+ // GET '/v1/resource/name' : get resource on version 1(name is allowed full yrn path)
846
+ // HEADER : X-Auth-Token = User token
847
+ // URL arguments : expand = "true"(default) or "false"
848
+ // service = service name(optional)
849
+ // result : {
850
+ // "result": true or false
851
+ // "message": error message
852
+ // "resource": {
853
+ // string: "string",
854
+ // object: object
855
+ // keys: object
856
+ // aliases: array <--- only not expand
857
+ // }
858
+ // }
859
+ //
860
+ // GET '/v1/resource/name' : get resource on version 1(name is allowed full yrn path)
861
+ // HEADER : X-Auth-Token = Role token
862
+ // URL arguments : type = "string"(default) or "object" or "keys"
863
+ // keyname = key name(if type is "keys")
864
+ // service = service name(optional)
865
+ // result : {
866
+ // "result": true or false
867
+ // "message": error message
868
+ // "resource": string or object
869
+ // }
870
+ //
871
+ // GET '/v1/resource/name' : get resource on version 1(name is allowed full yrn path)
872
+ // HEADER : X-Auth-Token = undefined
873
+ // URL arguments : port = port number(undefined is default 0(any))
874
+ // cuk = container unique key(empty value, any value)
875
+ // role = role full yrn
876
+ // type = "string"(default) or "object" or "keys"
877
+ // keyname = key name(if type is "keys")
878
+ // service = service name(optional)
879
+ // result : {
880
+ // "result": true or false
881
+ // "message": error message
882
+ // "resource": string or object
883
+ // }
884
+ //
885
+ // [NOTE]
886
+ // The name in '/v1/resource/name' path is allowed resource name or resource full yrn path.
887
+ // If the name is not yrn path, resource path created by including tenant and service which
888
+ // are specified in role.
889
+ //
890
+ router.get('/', (req, res, next) => {
891
+ dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
892
+ if ('GET' !== req.method) {
893
+ // HEAD request comes here, so it should be routed to head function.
894
+ next();
895
+ return;
896
+ }
897
+ res.type('application/json; charset=utf-8');
898
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
899
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
900
+ const result = {
901
+ result: false,
902
+ message: 'GET request or url is wrong'
903
+ };
904
+ dbglogging_1.default.elog(result.message);
905
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
906
+ return;
907
+ }
908
+ //------------------------------
909
+ // check common parameters(token, role, resource etc)
910
+ //------------------------------
911
+ const resobj = rawParseBaseParamRequestAPI(req, true, null);
912
+ if (!resobj.result) {
913
+ const result = {
914
+ result: false,
915
+ message: resobj.message
916
+ };
917
+ dbglogging_1.default.elog(result.message);
918
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status, result);
919
+ return;
920
+ }
921
+ const comparam = resobj.parameters;
922
+ //------------------------------
923
+ // check arguments
924
+ //------------------------------
925
+ // expand type(only user token type)
926
+ let is_expand = true;
927
+ if (k2hr3apiutil_1.default.isPlainObject(req.query) && k2hr3apiutil_1.default.isSafeString(req.query.expand)) {
928
+ if ('user' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
929
+ if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_TRUE, req.query.expand)) {
930
+ is_expand = true;
931
+ }
932
+ else if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_FALSE, req.query.expand)) {
933
+ is_expand = false;
934
+ }
935
+ else {
936
+ const result = {
937
+ result: false,
938
+ message: 'GET expand url argument parameter(' + JSON.stringify(req.query.expand) + ') is wrong, it must be ' + comparam.keys.VALUE_TRUE + ' or ' + comparam.keys.VALUE_FALSE + '.'
939
+ };
940
+ dbglogging_1.default.elog(result.message);
941
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
942
+ return;
943
+ }
944
+ }
945
+ else {
946
+ dbglogging_1.default.wlog('GET found unnessesary expand(' + JSON.stringify(req.query.expand) + ') parameter, skip this.');
947
+ }
948
+ }
949
+ // type, key parameter(role token/no token type)
950
+ let restype = null;
951
+ let reskeyname = null;
952
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.token_type) || 'role' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
953
+ if (!k2hr3apiutil_1.default.isPlainObject(req.query) || !k2hr3apiutil_1.default.isSafeString(req.query.type)) {
954
+ restype = comparam.keys.VALUE_STRING_TYPE;
955
+ }
956
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.type) && k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_STRING_TYPE, req.query.type)) {
957
+ restype = comparam.keys.VALUE_STRING_TYPE;
958
+ }
959
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.type) && k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_OBJECT_TYPE, req.query.type)) {
960
+ restype = comparam.keys.VALUE_OBJECT_TYPE;
961
+ }
962
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.type) && k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_KEYS_TYPE, req.query.type)) {
963
+ restype = comparam.keys.VALUE_KEYS_TYPE;
964
+ // key name
965
+ if (!k2hr3apiutil_1.default.isPlainObject(req.query) || !k2hr3apiutil_1.default.isSafeString(req.query.keyname)) {
966
+ const result = {
967
+ result: false,
968
+ message: 'GET request type=keys, but keyname(' + req.query.keyname + ') parameter is empty.'
969
+ };
970
+ dbglogging_1.default.elog(result.message);
971
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
972
+ return;
973
+ }
974
+ reskeyname = req.query.keyname;
975
+ }
976
+ else {
977
+ const result = {
978
+ result: false,
979
+ message: 'GET request type(' + req.query.type + ') parameter is wrong.'
980
+ };
981
+ dbglogging_1.default.elog(result.message);
982
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
983
+ return;
984
+ }
985
+ }
986
+ // role yrn/ip address/port for no token
987
+ let clientip = null;
988
+ let port = 0;
989
+ let cuk = null;
990
+ let role_yrn = null;
991
+ if (k2hr3apiutil_1.default.isSafeString(comparam.token_type) && (k2hr3apiutil_1.default.isSafeEntity(req.query.port) || k2hr3apiutil_1.default.isSafeEntity(req.query.cuk) || k2hr3apiutil_1.default.isSafeEntity(req.query.role))) {
992
+ const result = {
993
+ result: false,
994
+ message: 'GET resource:port/cuk/role field is specified, but it is not allowed by no token : port=' + JSON.stringify(req.query.port) + ', cuk=' + JSON.stringify(req.query.cuk) + ', role=' + JSON.stringify(req.query.role)
995
+ };
996
+ dbglogging_1.default.elog(result.message);
997
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
998
+ return;
999
+ }
1000
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.token_type)) {
1001
+ // role
1002
+ if (!k2hr3apiutil_1.default.isSafeString(req.query.role)) {
1003
+ const result = {
1004
+ result: false,
1005
+ message: 'GET request does not have role yrn in post data.'
1006
+ };
1007
+ dbglogging_1.default.elog(result.message);
1008
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
1009
+ return;
1010
+ }
1011
+ // [NOTE]
1012
+ // not check role is full yrn here.
1013
+ role_yrn = k2hr3apiutil_1.default.getSafeString(req.query.role);
1014
+ // ip
1015
+ clientip = k2hr3apiutil_1.default.getClientIpAddress(req);
1016
+ if (!k2hr3apiutil_1.default.isSafeString(clientip)) {
1017
+ const result = {
1018
+ result: false,
1019
+ message: 'GET request does not have ip address for client.'
1020
+ };
1021
+ dbglogging_1.default.elog(result.message);
1022
+ k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
1023
+ return;
1024
+ }
1025
+ // port
1026
+ if (k2hr3apiutil_1.default.isSafeNumeric(req.query.port)) {
1027
+ const tmpPort = k2hr3apiutil_1.default.cvtToNumber(req.query.port);
1028
+ if (k2hr3apiutil_1.default.isSafeNumber(tmpPort)) {
1029
+ port = tmpPort;
1030
+ }
1031
+ else {
1032
+ port = 0;
1033
+ }
1034
+ }
1035
+ else {
1036
+ port = 0;
1037
+ }
1038
+ // cuk
1039
+ if (k2hr3apiutil_1.default.isSafeString(req.query.cuk) && k2hr3apiutil_1.default.isSafeString(req.query.cuk.trim())) {
1040
+ cuk = req.query.cuk.trim();
1041
+ }
1042
+ }
1043
+ //------------------------------
1044
+ // Run
1045
+ //------------------------------
1046
+ let jsonres;
1047
+ let result_value;
1048
+ let result_msg;
1049
+ if ('user' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1050
+ const res_result = k2hr3dkc_1.default.getResource(comparam.user_name, comparam.tenant_name, comparam.res_service, comparam.res_name, is_expand);
1051
+ result_value = res_result.result;
1052
+ result_msg = res_result.message;
1053
+ jsonres = JSON.stringify(res_result);
1054
+ }
1055
+ else if ('role' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1056
+ // [NOTE]
1057
+ // comparam.token_info.role is role full yrn path, it does not include service name.
1058
+ // Because we do not put role token for role under service path.
1059
+ //
1060
+ const res_result = k2hr3dkc_1.default.getResourceByRole((comparam.token_info?.role ?? null), comparam.res_yrn, restype, reskeyname);
1061
+ result_value = res_result.result;
1062
+ result_msg = res_result.message;
1063
+ jsonres = JSON.stringify(res_result);
1064
+ }
1065
+ else if (!k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1066
+ // [NOTE]
1067
+ // role_yrn allows a path containing service.
1068
+ // However, the case is rare and should not be used.
1069
+ //
1070
+ const res_result = k2hr3dkc_1.default.getResourceByIP(clientip, port, cuk, role_yrn, comparam.res_yrn, restype, reskeyname);
1071
+ result_value = res_result.result;
1072
+ result_msg = res_result.message;
1073
+ jsonres = JSON.stringify(res_result);
1074
+ }
1075
+ else {
1076
+ // broken token
1077
+ const result = {
1078
+ result: false,
1079
+ message: 'GET request is failure by internal error(token data broken).'
1080
+ };
1081
+ dbglogging_1.default.elog(result.message);
1082
+ k2hr3resutil_1.default.errResponse(req, res, 500, result); // 500: Internal Error
1083
+ return;
1084
+ }
1085
+ if (false === result_value) {
1086
+ const result = {
1087
+ result: false,
1088
+ message: k2hr3apiutil_1.default.isString(result_msg) ? result_msg : 'GET Could not get error message in response from getResource'
1089
+ };
1090
+ dbglogging_1.default.elog(result.message);
1091
+ k2hr3resutil_1.default.errResponse(req, res, 404, result); // 404: Not Found
1092
+ return;
1093
+ }
1094
+ dbglogging_1.default.dlog('succeed : ' + k2hr3apiutil_1.default.getSafeString(result_msg));
1095
+ res.status(200); // 200: OK
1096
+ res.send(jsonres);
1097
+ });
1098
+ //
1099
+ // Mountpath : '/v1/resource/*'
1100
+ //
1101
+ // HEAD '/v1/resource/name' : get resource on version 1(name is allowed full yrn path)
1102
+ // HEADER : X-Auth-Token = User token
1103
+ // URL arguments : type = "string"(default) or "object" or "keys"
1104
+ // keyname = key name(if type is "keys")
1105
+ // service = service name(if resource is under service)
1106
+ //
1107
+ // HEAD '/v1/resource/name' : get resource on version 1(name is allowed full yrn path)
1108
+ // HEADER : X-Auth-Token = Role token
1109
+ // URL arguments : type = "string"(default) or "object" or "keys"
1110
+ // keyname = key name(if type is "keys")
1111
+ // service = service name(optional)
1112
+ //
1113
+ // HEAD '/v1/resource/name' : get resource on version 1(name is allowed full yrn path)
1114
+ // HEADER : X-Auth-Token = undefined
1115
+ // URL arguments : port = port number(undefined is default 0(any))
1116
+ // cuk = container unique key(empty value, any value)
1117
+ // role = role full yrn
1118
+ // type = "string"(default) or "object" or "keys"
1119
+ // keyname = key name(if type is "keys")
1120
+ // service = service name(optional)
1121
+ //
1122
+ router.head('/', (req, res, next) => {
1123
+ dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
1124
+ if ('HEAD' !== req.method) {
1125
+ // If other method request comes here, so it should be routed another function.
1126
+ next();
1127
+ return;
1128
+ }
1129
+ res.type('application/json; charset=utf-8');
1130
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
1131
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
1132
+ dbglogging_1.default.elog('HEAD request or url or query is wrong');
1133
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1134
+ return;
1135
+ }
1136
+ //------------------------------
1137
+ // check common parameters(token, role, resource etc)
1138
+ //------------------------------
1139
+ const resobj = rawParseBaseParamRequestAPI(req, true, null);
1140
+ if (!resobj.result) {
1141
+ dbglogging_1.default.elog(resobj.message);
1142
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status);
1143
+ return;
1144
+ }
1145
+ const comparam = resobj.parameters;
1146
+ //------------------------------
1147
+ // check arguments
1148
+ //------------------------------
1149
+ // type, key parameter
1150
+ let restype;
1151
+ let reskeyname = null;
1152
+ if (!k2hr3apiutil_1.default.isPlainObject(req.query) || !k2hr3apiutil_1.default.isSafeString(req.query.type)) {
1153
+ restype = comparam.keys.VALUE_STRING_TYPE;
1154
+ }
1155
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.type) && k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_STRING_TYPE, req.query.type)) {
1156
+ restype = comparam.keys.VALUE_STRING_TYPE;
1157
+ }
1158
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.type) && k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_OBJECT_TYPE, req.query.type)) {
1159
+ restype = comparam.keys.VALUE_OBJECT_TYPE;
1160
+ }
1161
+ else if (k2hr3apiutil_1.default.isSafeString(req.query.type) && k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_KEYS_TYPE, req.query.type)) {
1162
+ restype = comparam.keys.VALUE_KEYS_TYPE;
1163
+ // key name
1164
+ if (!k2hr3apiutil_1.default.isPlainObject(req.query) || !k2hr3apiutil_1.default.isSafeString(req.query.keyname)) {
1165
+ dbglogging_1.default.elog('HEAD request type=keys, but keyname(' + JSON.stringify(req.query.keyname) + ') parameter is empty.');
1166
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1167
+ return;
1168
+ }
1169
+ reskeyname = k2hr3apiutil_1.default.isString(req.query.keyname) ? req.query.keyname : null;
1170
+ }
1171
+ else {
1172
+ dbglogging_1.default.elog('HEAD request type(' + JSON.stringify(req.query.type) + ') parameter is wrong.');
1173
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1174
+ return;
1175
+ }
1176
+ // role yrn/ip address/port for no token
1177
+ let clientip = null;
1178
+ let port = 0;
1179
+ let cuk = null;
1180
+ let role_yrn = null;
1181
+ if (k2hr3apiutil_1.default.isSafeString(comparam.token_type) && (k2hr3apiutil_1.default.isSafeEntity(req.query.port) || k2hr3apiutil_1.default.isSafeEntity(req.query.cuk) || k2hr3apiutil_1.default.isSafeEntity(req.query.role))) {
1182
+ dbglogging_1.default.elog('HEAD resource:port/cuk/role field is specified, but it is not allowed by no token : port=' + JSON.stringify(req.query.port) + ', cuk=' + JSON.stringify(req.query.cuk) + ', role=' + JSON.stringify(req.query.role));
1183
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1184
+ return;
1185
+ }
1186
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.token_type)) {
1187
+ // role
1188
+ if (!k2hr3apiutil_1.default.isSafeString(req.query.role)) {
1189
+ dbglogging_1.default.elog('HEAD request does not have role yrn in post data.');
1190
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1191
+ return;
1192
+ }
1193
+ // [NOTE]
1194
+ // not check role is full yrn here.
1195
+ role_yrn = k2hr3apiutil_1.default.getSafeString(req.query.role);
1196
+ // ip
1197
+ clientip = k2hr3apiutil_1.default.getClientIpAddress(req);
1198
+ if (!k2hr3apiutil_1.default.isSafeString(clientip)) {
1199
+ dbglogging_1.default.elog('HEAD request does not have ip address for client.');
1200
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1201
+ return;
1202
+ }
1203
+ // port
1204
+ if (k2hr3apiutil_1.default.isSafeNumeric(req.query.port)) {
1205
+ const tmpPort = k2hr3apiutil_1.default.cvtToNumber(req.query.port);
1206
+ if (k2hr3apiutil_1.default.isSafeNumber(tmpPort)) {
1207
+ port = tmpPort;
1208
+ }
1209
+ else {
1210
+ port = 0;
1211
+ }
1212
+ }
1213
+ else {
1214
+ port = 0;
1215
+ }
1216
+ // cuk
1217
+ if (k2hr3apiutil_1.default.isSafeString(req.query.cuk) && k2hr3apiutil_1.default.isSafeString(req.query.cuk.trim())) {
1218
+ cuk = req.query.cuk.trim();
1219
+ }
1220
+ }
1221
+ //------------------------------
1222
+ // Run
1223
+ //------------------------------
1224
+ let result_value;
1225
+ let result_msg;
1226
+ if ('user' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1227
+ const res_result = k2hr3dkc_1.default.checkResource(comparam.user_name, comparam.tenant_name, comparam.res_service, comparam.res_name, restype, reskeyname);
1228
+ result_value = res_result.result;
1229
+ result_msg = res_result.message;
1230
+ }
1231
+ else if ('role' === k2hr3apiutil_1.default.getSafeString(comparam.token_type) && k2hr3apiutil_1.default.isPlainObject(comparam.token_info) && k2hr3apiutil_1.default.isString(comparam.token_info.role)) {
1232
+ // [NOTE]
1233
+ // comparam.token_info.role is role full yrn path, it does not include service name.
1234
+ // Because we do not put role token for role under service path.
1235
+ //
1236
+ const res_result = k2hr3dkc_1.default.checkResourceByRole(comparam.token_info.role, comparam.tenant_name, comparam.res_yrn, restype, reskeyname);
1237
+ result_value = res_result.result;
1238
+ result_msg = res_result.message;
1239
+ }
1240
+ else if (!k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1241
+ // [NOTE]
1242
+ // role_yrn allows a path containing service.
1243
+ // However, the case is rare and should not be used.
1244
+ //
1245
+ const res_result = k2hr3dkc_1.default.checkResourceByIP(clientip, port, cuk, role_yrn, comparam.res_yrn, restype, reskeyname);
1246
+ result_value = res_result.result;
1247
+ result_msg = res_result.message;
1248
+ }
1249
+ else {
1250
+ // broken token
1251
+ dbglogging_1.default.elog('HEAD request is failure by internal error(token data broken).');
1252
+ k2hr3resutil_1.default.errResponse(req, res, 500); // 500: Internal Error
1253
+ return;
1254
+ }
1255
+ if (false === result_value) {
1256
+ dbglogging_1.default.elog(k2hr3apiutil_1.default.isString(result_msg) ? result_msg : 'HEAD Could not get error message in response from checkResource');
1257
+ k2hr3resutil_1.default.errResponse(req, res, 403); // 403: Forbidden
1258
+ return;
1259
+ }
1260
+ dbglogging_1.default.dlog('succeed : ' + k2hr3apiutil_1.default.getSafeString(result_msg));
1261
+ res.status(204); // 204: No Content
1262
+ res.send();
1263
+ });
1264
+ //
1265
+ // Mountpath : '/v1/resource/*'
1266
+ //
1267
+ // DELETE '/v1/resource/name' : get resource on version 1
1268
+ // HEADER : X-Auth-Token = User token
1269
+ // URL arguments : type = null(all), "anytype"(=any type data), "string"(=only string data), "object"(=only object data), "keys"(=key), "aliases"(=aliases)
1270
+ // keynames = null or keyname string or keyname array when type="keys"
1271
+ // aliases = null or alias key string or alias key array when type="aliases"
1272
+ //
1273
+ // DELETE '/v1/resource/name' : get resource on version 1
1274
+ // HEADER : X-Auth-Token = Role token
1275
+ // URL arguments : type = "anytype"(=any type data), "string"(=only string data), "object"(=only object data), "keys"(=key)
1276
+ // keynames = null or keyname string or keyname array when type="keys"
1277
+ //
1278
+ // DELETE '/v1/resource/name' : get resource on version 1
1279
+ // HEADER : X-Auth-Token = undefined
1280
+ // URL arguments : port = port number(undefined is default 0(any))
1281
+ // cuk = container unique key(empty value, any value)
1282
+ // role = role full yrn
1283
+ // type = "anytype"(=any type data), "string"(=only string data), "object"(=only object data), "keys"(=key)
1284
+ // keynames = null or keyname string or keyname array when type="keys"
1285
+ //
1286
+ router.delete('/', (req, res, _) => {
1287
+ dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
1288
+ res.type('application/json; charset=utf-8');
1289
+ if (!k2hr3apiutil_1.default.isPlainObject(req) ||
1290
+ !k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
1291
+ dbglogging_1.default.elog('DELETE request or url or query is wrong');
1292
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1293
+ return;
1294
+ }
1295
+ //------------------------------
1296
+ // check common parameters(token, role, resource etc)
1297
+ //------------------------------
1298
+ const resobj = rawParseBaseParamRequestAPI(req, false, null);
1299
+ if (!resobj.result) {
1300
+ dbglogging_1.default.elog(resobj.message);
1301
+ k2hr3resutil_1.default.errResponse(req, res, resobj.status);
1302
+ return;
1303
+ }
1304
+ const comparam = resobj.parameters;
1305
+ //------------------------------
1306
+ // check resource(must be same tenant)
1307
+ //------------------------------
1308
+ if (k2hr3apiutil_1.default.isString(comparam.token_type) &&
1309
+ (k2hr3apiutil_1.default.isSafeString(comparam.tenant_name) !== k2hr3apiutil_1.default.isSafeString(comparam.res_tenant) ||
1310
+ k2hr3apiutil_1.default.getSafeString(comparam.tenant_name) !== k2hr3apiutil_1.default.getSafeString(comparam.res_tenant) ||
1311
+ k2hr3apiutil_1.default.isSafeString(comparam.res_service))) {
1312
+ dbglogging_1.default.elog('DELETE request resource(' + JSON.stringify(comparam.res_name) + ') is under tenant(' + JSON.stringify(comparam.res_tenant) + ') and service(' + JSON.stringify(comparam.res_service) + '), it is not under tenant(' + JSON.stringify(comparam.tenant_name) + ').');
1313
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1314
+ return;
1315
+ }
1316
+ //------------------------------
1317
+ // check arguments
1318
+ //------------------------------
1319
+ // type, key parameter(role token/no token type)
1320
+ let datatype;
1321
+ let keynames = null;
1322
+ let aliases = null;
1323
+ if (!k2hr3apiutil_1.default.isPlainObject(req.query) || !k2hr3apiutil_1.default.isSafeString(req.query.type)) {
1324
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1325
+ dbglogging_1.default.elog('DELETE request type=all(null), this type needs user token.');
1326
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1327
+ return;
1328
+ }
1329
+ datatype = null;
1330
+ }
1331
+ else if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_ANYDATA_TYPE, req.query.type)) {
1332
+ datatype = comparam.keys.VALUE_ANYDATA_TYPE;
1333
+ }
1334
+ else if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_STRING_TYPE, req.query.type)) {
1335
+ datatype = comparam.keys.VALUE_STRING_TYPE;
1336
+ }
1337
+ else if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_OBJECT_TYPE, req.query.type)) {
1338
+ datatype = comparam.keys.VALUE_OBJECT_TYPE;
1339
+ }
1340
+ else if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_KEYS_TYPE, req.query.type)) {
1341
+ datatype = comparam.keys.VALUE_KEYS_TYPE;
1342
+ // key name
1343
+ if (k2hr3apiutil_1.default.isPlainObject(req.query) && k2hr3apiutil_1.default.isSafeString(req.query.keynames)) {
1344
+ const keynames_tmp = req.query.keynames;
1345
+ if (k2hr3apiutil_1.default.checkSimpleJSON(keynames_tmp)) {
1346
+ const keynames_parsed = JSON.parse(keynames_tmp);
1347
+ if (!k2hr3apiutil_1.default.isStringArray(keynames_parsed) || !k2hr3apiutil_1.default.isNotEmptyArray(keynames_parsed)) {
1348
+ dbglogging_1.default.elog('DELETE request type(' + req.query.type + ') parameter keynames(' + JSON.stringify(req.query.keynames) + ') is wrong.');
1349
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1350
+ return;
1351
+ }
1352
+ keynames = keynames_parsed;
1353
+ }
1354
+ else {
1355
+ keynames = [keynames_tmp];
1356
+ }
1357
+ }
1358
+ }
1359
+ else if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_ALIAS_TYPE, req.query.type)) {
1360
+ datatype = comparam.keys.VALUE_ALIAS_TYPE;
1361
+ if ('user' !== k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1362
+ dbglogging_1.default.elog('DELETE request type=aliases, this type needs user token.');
1363
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1364
+ return;
1365
+ }
1366
+ // aliases
1367
+ if (k2hr3apiutil_1.default.isPlainObject(req.query) && k2hr3apiutil_1.default.isSafeString(req.query.aliases)) {
1368
+ const aliases_tmp = req.query.aliases;
1369
+ if (k2hr3apiutil_1.default.checkSimpleJSON(aliases_tmp)) {
1370
+ const aliases_parsed = JSON.parse(aliases_tmp);
1371
+ if (!k2hr3apiutil_1.default.isStringArray(aliases_parsed) || !k2hr3apiutil_1.default.isNotEmptyArray(aliases_parsed)) {
1372
+ dbglogging_1.default.elog('DELETE request type(' + req.query.type + ') parameter aliases(' + JSON.stringify(req.query.alias) + ') is wrong.');
1373
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1374
+ return;
1375
+ }
1376
+ aliases = aliases_parsed;
1377
+ }
1378
+ else {
1379
+ aliases = [aliases_tmp];
1380
+ }
1381
+ }
1382
+ }
1383
+ else if (k2hr3apiutil_1.default.compareCaseString(comparam.keys.VALUE_EXPIRE_TYPE, req.query.type)) {
1384
+ datatype = comparam.keys.VALUE_EXPIRE_TYPE;
1385
+ }
1386
+ else {
1387
+ dbglogging_1.default.elog('DELETE request type(' + req.query.type + ') parameter is wrong.');
1388
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1389
+ return;
1390
+ }
1391
+ // role yrn/ip address/port for no token
1392
+ let clientip = null;
1393
+ let port = 0;
1394
+ let cuk = null;
1395
+ let role_yrn = null;
1396
+ if (k2hr3apiutil_1.default.isSafeString(comparam.token_type) && (k2hr3apiutil_1.default.isSafeEntity(req.query.port) || k2hr3apiutil_1.default.isSafeEntity(req.query.cuk) || k2hr3apiutil_1.default.isSafeEntity(req.query.role))) {
1397
+ dbglogging_1.default.elog('DELETE resource:port/cuk/role field is specified, but it is not allowed by no token : port=' + JSON.stringify(req.query.port) + ', cuk=' + JSON.stringify(req.query.cuk) + ', role=' + JSON.stringify(req.query.role));
1398
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1399
+ return;
1400
+ }
1401
+ if (!k2hr3apiutil_1.default.isSafeString(comparam.token_type)) {
1402
+ // role
1403
+ if (!k2hr3apiutil_1.default.isSafeString(req.query.role)) {
1404
+ dbglogging_1.default.elog('DELETE request does not have role yrn in post data.');
1405
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1406
+ return;
1407
+ }
1408
+ // [NOTE]
1409
+ // not check role is full yrn here.
1410
+ role_yrn = k2hr3apiutil_1.default.getSafeString(req.query.role);
1411
+ // ip
1412
+ clientip = k2hr3apiutil_1.default.getClientIpAddress(req);
1413
+ if (!k2hr3apiutil_1.default.isSafeString(clientip)) {
1414
+ dbglogging_1.default.elog('DELETE request does not have ip address for client.');
1415
+ k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
1416
+ return;
1417
+ }
1418
+ // port
1419
+ if (k2hr3apiutil_1.default.isSafeNumeric(req.query.port)) {
1420
+ const tmpPort = k2hr3apiutil_1.default.cvtToNumber(req.query.port);
1421
+ if (k2hr3apiutil_1.default.isSafeNumber(tmpPort)) {
1422
+ port = tmpPort;
1423
+ }
1424
+ else {
1425
+ port = 0;
1426
+ }
1427
+ }
1428
+ else {
1429
+ port = 0;
1430
+ }
1431
+ // cuk
1432
+ if (k2hr3apiutil_1.default.isSafeString(req.query.cuk) && k2hr3apiutil_1.default.isSafeString(req.query.cuk.trim())) {
1433
+ cuk = req.query.cuk.trim();
1434
+ }
1435
+ }
1436
+ //------------------------------
1437
+ // Run
1438
+ //------------------------------
1439
+ let result_value;
1440
+ let result_msg;
1441
+ if ('user' === k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1442
+ const res_result = k2hr3dkc_1.default.removeResource(comparam.user_name, comparam.tenant_name, comparam.res_name, datatype, keynames, aliases);
1443
+ result_value = res_result.result;
1444
+ result_msg = res_result.message;
1445
+ }
1446
+ else if ('role' === k2hr3apiutil_1.default.getSafeString(comparam.token_type) && k2hr3apiutil_1.default.isPlainObject(comparam.token_info) && k2hr3apiutil_1.default.isString(comparam.token_info.role)) {
1447
+ const res_result = k2hr3dkc_1.default.removeResourceByRole(comparam.token_info.role, comparam.tenant_name, comparam.res_name, datatype, keynames);
1448
+ result_value = res_result.result;
1449
+ result_msg = res_result.message;
1450
+ }
1451
+ else if (!k2hr3apiutil_1.default.getSafeString(comparam.token_type)) {
1452
+ const res_result = k2hr3dkc_1.default.removeResourceByIP(clientip, port, cuk, role_yrn, comparam.res_name, datatype, keynames);
1453
+ result_value = res_result.result;
1454
+ result_msg = res_result.message;
1455
+ }
1456
+ else {
1457
+ // broken token
1458
+ dbglogging_1.default.elog('DELETE request is failure by internal error(token data broken).');
1459
+ k2hr3resutil_1.default.errResponse(req, res, 500); // 500: Internal Error
1460
+ return;
1461
+ }
1462
+ if (false === result_value) {
1463
+ const result = {
1464
+ result: false,
1465
+ message: k2hr3apiutil_1.default.isString(result_msg) ? result_msg : 'DELETE Could not get error message in response from removeResource'
1466
+ };
1467
+ dbglogging_1.default.elog(result.message);
1468
+ k2hr3resutil_1.default.errResponse(req, res, 404, result); // 404: Not Found
1469
+ return;
1470
+ }
1471
+ dbglogging_1.default.dlog('succeed : ' + k2hr3apiutil_1.default.getSafeString(result_msg));
1472
+ res.status(204); // 204: No Content
1473
+ res.send();
1474
+ });
1475
+ //---------------------------------------------------------
1476
+ // Exports
1477
+ //---------------------------------------------------------
1478
+ //
1479
+ // Functions
1480
+ //
1481
+ exports.default = router;
1482
+ /*
1483
+ * Local variables:
1484
+ * tab-width: 4
1485
+ * c-basic-offset: 4
1486
+ * End:
1487
+ * vim600: noexpandtab sw=4 ts=4 fdm=marker
1488
+ * vim<600: noexpandtab sw=4 ts=4
1489
+ */