k2hr3-api 1.0.42 → 2.0.1

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