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