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,482 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* K2HR3 REST API
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2017 Yahoo Japan Corporation.
|
|
6
|
+
*
|
|
7
|
+
* K2HR3 is K2hdkc based Resource and Roles and policy Rules, gathers
|
|
8
|
+
* common management information for the cloud.
|
|
9
|
+
* K2HR3 can dynamically manage information as "who", "what", "operate".
|
|
10
|
+
* These are stored as roles, resources, policies in K2hdkc, and the
|
|
11
|
+
* client system can dynamically read and modify these information.
|
|
12
|
+
*
|
|
13
|
+
* For the full copyright and license information, please view
|
|
14
|
+
* the license file that was distributed with this source code.
|
|
15
|
+
*
|
|
16
|
+
* AUTHOR: Takeshi Nakatani
|
|
17
|
+
* CREATE: Wed Jun 8 2017
|
|
18
|
+
* REVISION:
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
const k2hr3apiutil_1 = __importDefault(require("../lib/k2hr3apiutil"));
|
|
26
|
+
const k2hr3resutil_1 = __importDefault(require("../lib/k2hr3resutil"));
|
|
27
|
+
const k2hr3tokens_1 = __importDefault(require("../lib/k2hr3tokens"));
|
|
28
|
+
const dbglogging_1 = __importDefault(require("../lib/dbglogging"));
|
|
29
|
+
const express_1 = __importDefault(require("express"));
|
|
30
|
+
const router = express_1.default.Router();
|
|
31
|
+
//
|
|
32
|
+
// Common utility function
|
|
33
|
+
//
|
|
34
|
+
const rawCommonGetUserToken = (req, res, unscopedToken, otherToken, username, passwd, tenant) => {
|
|
35
|
+
// arguments
|
|
36
|
+
const _req = req;
|
|
37
|
+
const _res = res;
|
|
38
|
+
const _unscopedToken = k2hr3apiutil_1.default.getSafeString(unscopedToken);
|
|
39
|
+
const _otherToken = k2hr3apiutil_1.default.getSafeString(otherToken);
|
|
40
|
+
const _username = k2hr3apiutil_1.default.getSafeString(username);
|
|
41
|
+
const _passwd = k2hr3apiutil_1.default.getSafeString(passwd);
|
|
42
|
+
const _tenant = k2hr3apiutil_1.default.getSafeString(tenant);
|
|
43
|
+
if (!k2hr3apiutil_1.default.isSafeString(_unscopedToken) && !k2hr3apiutil_1.default.isSafeString(_otherToken)) {
|
|
44
|
+
//
|
|
45
|
+
// Get token from User Credentials
|
|
46
|
+
//
|
|
47
|
+
if (!k2hr3apiutil_1.default.isSafeString(_username)) {
|
|
48
|
+
const error = {
|
|
49
|
+
result: false,
|
|
50
|
+
message: 'Some parameter(user name or unscoped token) is wrong.'
|
|
51
|
+
};
|
|
52
|
+
dbglogging_1.default.elog(error.message);
|
|
53
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, error); // 400: Bad Request
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
k2hr3tokens_1.default.getUserToken(_username, _passwd, _tenant, (err, token) => {
|
|
57
|
+
if (null !== err || null === token) {
|
|
58
|
+
const error = {
|
|
59
|
+
result: false,
|
|
60
|
+
message: 'could not get scoped user token for user=' + _username + ', tenant=' + _tenant + ' by ' + (err?.message ?? '')
|
|
61
|
+
};
|
|
62
|
+
dbglogging_1.default.elog(error.message);
|
|
63
|
+
k2hr3resutil_1.default.errResponse(_req, _res, 404, error); // 404: Not Found
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
dbglogging_1.default.dlog('get user token jsonres = ' + JSON.stringify(token));
|
|
67
|
+
const result = {
|
|
68
|
+
result: true,
|
|
69
|
+
message: 'succeed',
|
|
70
|
+
scoped: k2hr3apiutil_1.default.isSafeString(_tenant),
|
|
71
|
+
token: token
|
|
72
|
+
};
|
|
73
|
+
_res.status(201); // 201: Created
|
|
74
|
+
_res.send(JSON.stringify(result));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (k2hr3apiutil_1.default.isSafeString(_unscopedToken)) {
|
|
78
|
+
//
|
|
79
|
+
// Get Scoped token from Unscoped token
|
|
80
|
+
//
|
|
81
|
+
if (!k2hr3apiutil_1.default.isSafeString(_username)) {
|
|
82
|
+
const error = {
|
|
83
|
+
result: false,
|
|
84
|
+
message: 'Some parameter(user name or unscoped token) is wrong.'
|
|
85
|
+
};
|
|
86
|
+
dbglogging_1.default.elog(error.message);
|
|
87
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, error); // 400: Bad Request
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
k2hr3tokens_1.default.getScopedUserToken(_unscopedToken, _username, _tenant, (err, token) => {
|
|
91
|
+
if (null !== err || null === token) {
|
|
92
|
+
const error = {
|
|
93
|
+
result: false,
|
|
94
|
+
message: 'could not get scoped user token for user=' + _username + ', tenant=' + _tenant + ' by ' + (err?.message ?? '')
|
|
95
|
+
};
|
|
96
|
+
dbglogging_1.default.elog(error.message);
|
|
97
|
+
k2hr3resutil_1.default.errResponse(_req, _res, 404, error); // 404: Not Found
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
dbglogging_1.default.dlog('get user token jsonres = ' + JSON.stringify(token));
|
|
101
|
+
const result = {
|
|
102
|
+
result: true,
|
|
103
|
+
message: 'succeed',
|
|
104
|
+
scoped: k2hr3apiutil_1.default.isSafeString(_tenant),
|
|
105
|
+
token: token
|
|
106
|
+
};
|
|
107
|
+
_res.status(201); // 201: Created
|
|
108
|
+
_res.send(JSON.stringify(result));
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else if (k2hr3apiutil_1.default.isSafeString(_otherToken)) {
|
|
112
|
+
//
|
|
113
|
+
// Get Scoped/Unscoped token from other token
|
|
114
|
+
//
|
|
115
|
+
k2hr3tokens_1.default.getUserTokenByToken(_otherToken, _tenant, (err, token) => {
|
|
116
|
+
if (null !== err || null === token) {
|
|
117
|
+
const error = {
|
|
118
|
+
result: false,
|
|
119
|
+
message: 'could not get scoped user token for other token, tenant=' + _tenant + ' by ' + (err?.message ?? '')
|
|
120
|
+
};
|
|
121
|
+
dbglogging_1.default.elog(error.message);
|
|
122
|
+
k2hr3resutil_1.default.errResponse(_req, _res, 404, error); // 404: Not Found
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
dbglogging_1.default.dlog('get user token jsonres = ' + JSON.stringify(token));
|
|
126
|
+
const result = {
|
|
127
|
+
result: true,
|
|
128
|
+
message: 'succeed',
|
|
129
|
+
scoped: k2hr3apiutil_1.default.isSafeString(_tenant),
|
|
130
|
+
token: token
|
|
131
|
+
};
|
|
132
|
+
_res.status(201); // 201: Created
|
|
133
|
+
_res.send(JSON.stringify(result));
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
//
|
|
138
|
+
// Common utility function
|
|
139
|
+
//
|
|
140
|
+
const rawGetUnscopedUserToken = (req) => {
|
|
141
|
+
// check unscoped token in request
|
|
142
|
+
const resobj = k2hr3tokens_1.default.checkToken(req, false, true);
|
|
143
|
+
if (!resobj.result) {
|
|
144
|
+
const result = {
|
|
145
|
+
result: resobj.result,
|
|
146
|
+
message: k2hr3apiutil_1.default.getSafeString(resobj.message),
|
|
147
|
+
status: resobj.status,
|
|
148
|
+
token: ''
|
|
149
|
+
};
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
const token_info = resobj.token_info;
|
|
153
|
+
if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
|
|
154
|
+
const result = {
|
|
155
|
+
result: false,
|
|
156
|
+
message: 'could not get unscoped user token in request.',
|
|
157
|
+
status: 400, // 400: Bad Request
|
|
158
|
+
token: ''
|
|
159
|
+
};
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
const func_result = {
|
|
163
|
+
result: true,
|
|
164
|
+
message: '',
|
|
165
|
+
status: 200,
|
|
166
|
+
token: k2hr3apiutil_1.default.getSafeString(resobj.token),
|
|
167
|
+
username: k2hr3apiutil_1.default.getSafeString(token_info.user)
|
|
168
|
+
};
|
|
169
|
+
return func_result;
|
|
170
|
+
};
|
|
171
|
+
// Mountpath : '/v1/user/tokens'
|
|
172
|
+
// POST '/v1/user/tokens' : post(create) user token on version 1
|
|
173
|
+
// response body : result => true/false
|
|
174
|
+
// message => messages
|
|
175
|
+
// scoped => true/false
|
|
176
|
+
// token => token(unscoped or scoped)
|
|
177
|
+
//
|
|
178
|
+
router.post('/', (req, res, _) => {
|
|
179
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url);
|
|
180
|
+
res.type('application/json; charset=utf-8');
|
|
181
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req) ||
|
|
182
|
+
!k2hr3apiutil_1.default.isPlainObject(req.body)) {
|
|
183
|
+
const error = {
|
|
184
|
+
result: false,
|
|
185
|
+
message: 'POST body does not have auth key'
|
|
186
|
+
};
|
|
187
|
+
dbglogging_1.default.elog(error.message);
|
|
188
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, error); // 400: Bad Request
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
// arguments
|
|
192
|
+
const tenant = (k2hr3apiutil_1.default.isPlainObject(req.body.auth) && k2hr3apiutil_1.default.isSafeString(req.body.auth.tenantName)) ? k2hr3apiutil_1.default.getSafeString(req.body.auth.tenantName) : null;
|
|
193
|
+
let unscopedtoken = null;
|
|
194
|
+
let otherToken = null;
|
|
195
|
+
let username = null;
|
|
196
|
+
let passwd = null;
|
|
197
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req.body.auth) || !k2hr3apiutil_1.default.isPlainObject(req.body.auth.passwordCredentials)) {
|
|
198
|
+
//
|
|
199
|
+
// Token is required if no user credentials are specified.
|
|
200
|
+
//
|
|
201
|
+
// [NOTE]
|
|
202
|
+
// There are two cases in this case:
|
|
203
|
+
// (1) Specify the UnscopedToken registered in k2hr3 to get the ScopedToken(must specify the tenant name)
|
|
204
|
+
// (2) Specify a token other than k2hr3 (OpenStack, etc.) and perform Unauthenticated Token after user authentication.
|
|
205
|
+
// In this case, if tenant is specified, ScopedToken can be obtained directly.
|
|
206
|
+
//
|
|
207
|
+
// get unscoped token
|
|
208
|
+
const resobj = rawGetUnscopedUserToken(req);
|
|
209
|
+
if (resobj.result) {
|
|
210
|
+
//
|
|
211
|
+
// (1) case of unscoped token registered in k2hr3
|
|
212
|
+
//
|
|
213
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req.body.auth) || !k2hr3apiutil_1.default.isSafeString(req.body.auth.tenantName)) {
|
|
214
|
+
const error = {
|
|
215
|
+
result: false,
|
|
216
|
+
message: 'POST body does not have tenant name(or user credentials)'
|
|
217
|
+
};
|
|
218
|
+
dbglogging_1.default.elog(error.message);
|
|
219
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, error); // 400: Bad Request
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
username = k2hr3apiutil_1.default.getSafeString(resobj.username);
|
|
223
|
+
unscopedtoken = resobj.token;
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
//
|
|
227
|
+
// (2) get (un)scoped token from other a token other than k2hr3(OpenStack, etc.)
|
|
228
|
+
//
|
|
229
|
+
otherToken = k2hr3tokens_1.default.getAuthTokenHeader(req, false);
|
|
230
|
+
if (!k2hr3apiutil_1.default.isSafeString(otherToken)) {
|
|
231
|
+
const error = {
|
|
232
|
+
result: false,
|
|
233
|
+
message: resobj.message
|
|
234
|
+
};
|
|
235
|
+
dbglogging_1.default.elog(resobj.message);
|
|
236
|
+
k2hr3resutil_1.default.errResponse(req, res, resobj.status, error); // 40X
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
//
|
|
243
|
+
// case of user credentials
|
|
244
|
+
//
|
|
245
|
+
username = k2hr3apiutil_1.default.getSafeString(req.body.auth.passwordCredentials.username);
|
|
246
|
+
passwd = k2hr3apiutil_1.default.getSafeString(req.body.auth.passwordCredentials.password); // password is allowed empty, it depends on the authentication system.
|
|
247
|
+
}
|
|
248
|
+
return rawCommonGetUserToken(req, res, unscopedtoken, otherToken, username, passwd, tenant);
|
|
249
|
+
});
|
|
250
|
+
// Mountpath : '/v1/user/tokens'
|
|
251
|
+
// PUT '/v1/user/tokens' : put(create) user token on version 1
|
|
252
|
+
// response body : result => true/false
|
|
253
|
+
// message => messages
|
|
254
|
+
// scoped => true/false
|
|
255
|
+
// token => token(unscoped or scoped)
|
|
256
|
+
//
|
|
257
|
+
router.put('/', (req, res, _) => {
|
|
258
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url);
|
|
259
|
+
res.type('application/json; charset=utf-8');
|
|
260
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req) ||
|
|
261
|
+
!k2hr3apiutil_1.default.isPlainObject(req.query)) {
|
|
262
|
+
const error = {
|
|
263
|
+
result: false,
|
|
264
|
+
message: 'PUT argument does not have any data'
|
|
265
|
+
};
|
|
266
|
+
dbglogging_1.default.elog(error.message);
|
|
267
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, error); // 400: Bad Request
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
// arguments
|
|
271
|
+
const tenant = k2hr3apiutil_1.default.getSafeString(req.query.tenantname);
|
|
272
|
+
let unscopedtoken = null;
|
|
273
|
+
let otherToken = null;
|
|
274
|
+
let username = null;
|
|
275
|
+
let passwd = null;
|
|
276
|
+
if (!k2hr3apiutil_1.default.isSafeString(req.query.username)) {
|
|
277
|
+
//
|
|
278
|
+
// Token is required if no user credentials are specified.
|
|
279
|
+
//
|
|
280
|
+
// [NOTE]
|
|
281
|
+
// There are two cases in this case:
|
|
282
|
+
// (1) Specify the UnscopedToken registered in k2hr3 to get the ScopedToken(must specify the tenant name)
|
|
283
|
+
// (2) Specify a token other than k2hr3 (OpenStack, etc.) and perform Unauthenticated Token after user authentication.
|
|
284
|
+
// In this case, if tenant is specified, ScopedToken can be obtained directly.
|
|
285
|
+
//
|
|
286
|
+
// get unscoped token
|
|
287
|
+
const resobj = rawGetUnscopedUserToken(req);
|
|
288
|
+
if (resobj.result) {
|
|
289
|
+
//
|
|
290
|
+
// (1) case of unscoped token registered in k2hr3
|
|
291
|
+
//
|
|
292
|
+
if (!k2hr3apiutil_1.default.isSafeString(req.query.tenantname)) {
|
|
293
|
+
const error = {
|
|
294
|
+
result: false,
|
|
295
|
+
message: 'POST body does not have tenant name(or user credentials)'
|
|
296
|
+
};
|
|
297
|
+
dbglogging_1.default.elog(error.message);
|
|
298
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, error); // 400: Bad Request
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
username = k2hr3apiutil_1.default.getSafeString(resobj.username);
|
|
302
|
+
unscopedtoken = resobj.token;
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
//
|
|
306
|
+
// (2) get (un)scoped token from other a token other than k2hr3(OpenStack, etc.)
|
|
307
|
+
//
|
|
308
|
+
otherToken = k2hr3tokens_1.default.getAuthTokenHeader(req, false);
|
|
309
|
+
if (!k2hr3apiutil_1.default.isSafeString(otherToken)) {
|
|
310
|
+
const error = {
|
|
311
|
+
result: false,
|
|
312
|
+
message: resobj.message
|
|
313
|
+
};
|
|
314
|
+
dbglogging_1.default.elog(resobj.message);
|
|
315
|
+
k2hr3resutil_1.default.errResponse(req, res, resobj.status, error); // 40X
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
//
|
|
322
|
+
// case of user credentials
|
|
323
|
+
//
|
|
324
|
+
username = k2hr3apiutil_1.default.getSafeString(req.query.username);
|
|
325
|
+
passwd = k2hr3apiutil_1.default.isSafeEntity(req.query.password) ? decodeURIComponent(k2hr3apiutil_1.default.getSafeString(req.query.password)) : null; // password is allowed empty, it depends on the authentication system.
|
|
326
|
+
}
|
|
327
|
+
return rawCommonGetUserToken(req, res, unscopedtoken, otherToken, username, passwd, tenant);
|
|
328
|
+
});
|
|
329
|
+
//
|
|
330
|
+
// Mountpath : '/v1/user/tokens'
|
|
331
|
+
//
|
|
332
|
+
// GET '/v1/user/tokens' : get user token on version 1
|
|
333
|
+
// response body : result => true/false
|
|
334
|
+
// message => messages
|
|
335
|
+
// scoped => true/false
|
|
336
|
+
// user => user name
|
|
337
|
+
// tenants => [
|
|
338
|
+
// {
|
|
339
|
+
// name: "tenant name"
|
|
340
|
+
// display: "display name"
|
|
341
|
+
// id: "tenant id"
|
|
342
|
+
// description: "tenant description"
|
|
343
|
+
// },
|
|
344
|
+
// ...
|
|
345
|
+
// ]
|
|
346
|
+
//
|
|
347
|
+
// [NOTE]
|
|
348
|
+
// If token is scoped, tenants array has only 1 element.
|
|
349
|
+
// Which element has name and display member, but display is as same as name.
|
|
350
|
+
// It is not real display name, because we take a cost getting it from APIs.
|
|
351
|
+
//
|
|
352
|
+
router.get('/', (req, res, next) => {
|
|
353
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url);
|
|
354
|
+
if ('HEAD' === req.method) {
|
|
355
|
+
// HEAD request comes here, so it should be routed to head function.
|
|
356
|
+
next();
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const _res = res;
|
|
360
|
+
const _req = req;
|
|
361
|
+
_res.type('application/json; charset=utf-8');
|
|
362
|
+
//------------------------------
|
|
363
|
+
// get token
|
|
364
|
+
//------------------------------
|
|
365
|
+
const token_result = k2hr3tokens_1.default.checkToken(_req, false, true); // not scope check, user token
|
|
366
|
+
if (!token_result.result) {
|
|
367
|
+
const result = {
|
|
368
|
+
result: token_result.result,
|
|
369
|
+
message: k2hr3apiutil_1.default.getSafeString(token_result.message),
|
|
370
|
+
};
|
|
371
|
+
dbglogging_1.default.elog(result.message);
|
|
372
|
+
k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const token_info = token_result.token_info;
|
|
376
|
+
if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
|
|
377
|
+
const result = {
|
|
378
|
+
result: false,
|
|
379
|
+
message: 'specified wrong token or it is not scoped user token'
|
|
380
|
+
};
|
|
381
|
+
dbglogging_1.default.elog(result.message);
|
|
382
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
// build response body
|
|
386
|
+
if (token_info.scoped) {
|
|
387
|
+
// scoped token
|
|
388
|
+
const tenant_info = {
|
|
389
|
+
name: k2hr3apiutil_1.default.getSafeString(token_info.tenant),
|
|
390
|
+
display: k2hr3apiutil_1.default.isSafeString(token_info.display) ? token_info.display : null,
|
|
391
|
+
id: k2hr3apiutil_1.default.getSafeString(token_info.id),
|
|
392
|
+
description: k2hr3apiutil_1.default.isSafeString(token_info.description) ? token_info.description : null
|
|
393
|
+
};
|
|
394
|
+
const result = {
|
|
395
|
+
result: true,
|
|
396
|
+
message: 'succeed',
|
|
397
|
+
scoped: true,
|
|
398
|
+
user: k2hr3apiutil_1.default.getSafeString(token_info.user),
|
|
399
|
+
tenants: [tenant_info]
|
|
400
|
+
};
|
|
401
|
+
_res.status(200); // 200: OK
|
|
402
|
+
_res.send(JSON.stringify(result));
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
// check and initialize tenant list
|
|
406
|
+
k2hr3tokens_1.default.initializeTenantList((k2hr3apiutil_1.default.isSafeString(token_result.token) ? token_result.token : null), token_info.user, (err, tenant_list) => {
|
|
407
|
+
if (null !== err || null === tenant_list) {
|
|
408
|
+
const result = {
|
|
409
|
+
result: false,
|
|
410
|
+
message: 'failed to get tenant list for user (' + token_info.user + ') by unscoped token(' + token_result.token + ') : ' + (err?.message ?? '')
|
|
411
|
+
};
|
|
412
|
+
dbglogging_1.default.elog(result.message);
|
|
413
|
+
k2hr3resutil_1.default.errResponse(_req, _res, 404, result); // 404: Not Found
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
// reget tenant list
|
|
417
|
+
const tenant_info_list = k2hr3tokens_1.default.getTenantList(token_info.user);
|
|
418
|
+
if (!k2hr3apiutil_1.default.isArray(tenant_info_list) || !k2hr3apiutil_1.default.isNotEmptyArray(tenant_info_list)) {
|
|
419
|
+
const result = {
|
|
420
|
+
result: false,
|
|
421
|
+
message: 'token(' + token_result.token + ') for user (' + token_info.user + ') does not have any tenant.'
|
|
422
|
+
};
|
|
423
|
+
dbglogging_1.default.elog(result.message);
|
|
424
|
+
k2hr3resutil_1.default.errResponse(_req, _res, 404, result); // 404: Not Found
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const resobj = {
|
|
428
|
+
result: true,
|
|
429
|
+
message: 'succeed',
|
|
430
|
+
scoped: false,
|
|
431
|
+
user: k2hr3apiutil_1.default.getSafeString(token_info.user),
|
|
432
|
+
tenants: tenant_info_list
|
|
433
|
+
};
|
|
434
|
+
_res.status(200); // 200: OK
|
|
435
|
+
_res.send(JSON.stringify(resobj));
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
// Mountpath : '/v1/user/tokens'
|
|
440
|
+
// HEAD '/v1/user/tokens' : check user token on version 1
|
|
441
|
+
// response body : no
|
|
442
|
+
//
|
|
443
|
+
router.head('/', (req, res, _) => {
|
|
444
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url);
|
|
445
|
+
const _res = res;
|
|
446
|
+
const _req = req;
|
|
447
|
+
_res.type('application/json; charset=utf-8');
|
|
448
|
+
//------------------------------
|
|
449
|
+
// get token
|
|
450
|
+
//------------------------------
|
|
451
|
+
const token_result = k2hr3tokens_1.default.checkToken(_req, false, true); // not scope check, user token
|
|
452
|
+
if (!token_result.result) {
|
|
453
|
+
dbglogging_1.default.elog(token_result.message);
|
|
454
|
+
k2hr3resutil_1.default.errResponse(_req, _res, token_result.status);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
const token_info = token_result.token_info;
|
|
458
|
+
if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
|
|
459
|
+
dbglogging_1.default.elog('specified wrong token or it is not scoped user token');
|
|
460
|
+
k2hr3resutil_1.default.errResponse(_req, _res, 400); // 400: Bad Request
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
// token is not expired and it is safe.
|
|
464
|
+
dbglogging_1.default.mlog(dbglogging_1.default.dump(token_info));
|
|
465
|
+
_res.status(204); // 204: No Content
|
|
466
|
+
_res.send();
|
|
467
|
+
});
|
|
468
|
+
//---------------------------------------------------------
|
|
469
|
+
// Exports
|
|
470
|
+
//---------------------------------------------------------
|
|
471
|
+
//
|
|
472
|
+
// Functions
|
|
473
|
+
//
|
|
474
|
+
exports.default = router;
|
|
475
|
+
/*
|
|
476
|
+
* Local variables:
|
|
477
|
+
* tab-width: 4
|
|
478
|
+
* c-basic-offset: 4
|
|
479
|
+
* End:
|
|
480
|
+
* vim600: noexpandtab sw=4 ts=4 fdm=marker
|
|
481
|
+
* vim<600: noexpandtab sw=4 ts=4
|
|
482
|
+
*/
|