k2hr3-api 1.0.42 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 -378
- 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,840 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* K2HR3 REST API
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2017 Yahoo Japan Corporation.
|
|
6
|
+
*
|
|
7
|
+
* K2HR3 is K2hdkc based Resource and Roles and policy Rules, gathers
|
|
8
|
+
* common management information for the cloud.
|
|
9
|
+
* K2HR3 can dynamically manage information as "who", "what", "operate".
|
|
10
|
+
* These are stored as roles, resources, policies in K2hdkc, and the
|
|
11
|
+
* client system can dynamically read and modify these information.
|
|
12
|
+
*
|
|
13
|
+
* For the full copyright and license information, please view
|
|
14
|
+
* the license file that was distributed with this source code.
|
|
15
|
+
*
|
|
16
|
+
* AUTHOR: Takeshi Nakatani
|
|
17
|
+
* CREATE: Wed Jun 8 2017
|
|
18
|
+
* REVISION:
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
const k2hr3apiutil_1 = __importDefault(require("../lib/k2hr3apiutil"));
|
|
26
|
+
const k2hr3resutil_1 = __importDefault(require("../lib/k2hr3resutil"));
|
|
27
|
+
const k2hr3tokens_1 = __importDefault(require("../lib/k2hr3tokens"));
|
|
28
|
+
const k2hr3dkc_1 = __importDefault(require("../lib/k2hr3dkc"));
|
|
29
|
+
const dbglogging_1 = __importDefault(require("../lib/dbglogging"));
|
|
30
|
+
const express_1 = __importDefault(require("express"));
|
|
31
|
+
const k2hr3keys_1 = require("../lib/k2hr3keys");
|
|
32
|
+
const r3keys = k2hr3keys_1.getK2hr3Keys;
|
|
33
|
+
const router = express_1.default.Router();
|
|
34
|
+
// Mountpath : '/v1/policy'
|
|
35
|
+
// POST '/v1/policy' : post policy on version 1
|
|
36
|
+
// response body : result => true/false
|
|
37
|
+
// message => messages
|
|
38
|
+
// body :
|
|
39
|
+
// {
|
|
40
|
+
// "policy": {
|
|
41
|
+
// "name": <policy name> => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>"
|
|
42
|
+
// "effect": "allow" or "deny" => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>/effect"
|
|
43
|
+
// if null or undefined is specified, not update this member in policy when this policy exists.
|
|
44
|
+
// if '' or zero array, this member in policy is set default(default deny)..
|
|
45
|
+
// "action": [<action yrn full path>, ...] => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>/action"
|
|
46
|
+
// specify "yrn:yahoo::::action:read" or "yrn:yahoo::::action:write"
|
|
47
|
+
// if null or undefined is specified, not update this member in policy when this policy exists.
|
|
48
|
+
// if '' or zero array, this member in policy is set empty array.
|
|
49
|
+
// "resource": [<resource yrn full path>, ...] => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>/resource"
|
|
50
|
+
// specify "yrn:yahoo:<service>::<tenant>:resource:<resource>{/<resource>{...}}"
|
|
51
|
+
// if null or undefined is specified, not update this member in policy when this policy exists.
|
|
52
|
+
// if '' or zero array, this member in policy is set empty array.
|
|
53
|
+
// "condition": null or undefined => this member is reserved on v1, must be null or undefined.
|
|
54
|
+
// "alias": [<policy yrn full path>, ...] => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>/@"
|
|
55
|
+
// specify another policy as "yrn:yahoo:<service>::<tenant>:policy:<policy>"
|
|
56
|
+
// if null or undefined is specified, not update this member in policy when this policy exists.
|
|
57
|
+
// if '' or zero array, this member in policy is set empty array.
|
|
58
|
+
// }
|
|
59
|
+
// }
|
|
60
|
+
//
|
|
61
|
+
router.post('/', (req, res, _) => {
|
|
62
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url);
|
|
63
|
+
res.type('application/json; charset=utf-8');
|
|
64
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req) ||
|
|
65
|
+
!k2hr3apiutil_1.default.isPlainObject(req.body) ||
|
|
66
|
+
!k2hr3apiutil_1.default.isPlainObject(req.body.policy)) {
|
|
67
|
+
const result = {
|
|
68
|
+
result: false,
|
|
69
|
+
message: 'POST body does not have policy data'
|
|
70
|
+
};
|
|
71
|
+
dbglogging_1.default.elog(result.message);
|
|
72
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
//------------------------------
|
|
76
|
+
// check token
|
|
77
|
+
//------------------------------
|
|
78
|
+
const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
|
|
79
|
+
if (!token_result.result) {
|
|
80
|
+
const result = {
|
|
81
|
+
result: token_result.result,
|
|
82
|
+
message: k2hr3apiutil_1.default.getSafeString(token_result.message),
|
|
83
|
+
};
|
|
84
|
+
dbglogging_1.default.elog(result.message);
|
|
85
|
+
k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const token_info = token_result.token_info;
|
|
89
|
+
if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
|
|
90
|
+
const result = {
|
|
91
|
+
result: false,
|
|
92
|
+
message: 'specified wrong token or it is not scoped user token'
|
|
93
|
+
};
|
|
94
|
+
dbglogging_1.default.elog(result.message);
|
|
95
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
//------------------------------
|
|
99
|
+
// check arguments
|
|
100
|
+
//------------------------------
|
|
101
|
+
if (!k2hr3apiutil_1.default.isSafeString(req.body.policy.name)) {
|
|
102
|
+
const result = {
|
|
103
|
+
result: false,
|
|
104
|
+
message: 'policy:name field is wrong : ' + JSON.stringify(req.body.policy.name)
|
|
105
|
+
};
|
|
106
|
+
dbglogging_1.default.elog(result.message);
|
|
107
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const keys = r3keys(token_info.user, token_info.tenant);
|
|
111
|
+
let name = k2hr3apiutil_1.default.getSafeString(req.body.policy.name).toLowerCase();
|
|
112
|
+
// policy name is only name or full yrn path
|
|
113
|
+
let nameptn = new RegExp('^' + keys.POLICY_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:policy:(.*)/
|
|
114
|
+
const namematchs = name.match(nameptn);
|
|
115
|
+
if (k2hr3apiutil_1.default.isStringArray(namematchs) && k2hr3apiutil_1.default.isNotEmptyArray(namematchs) && 2 <= namematchs.length) {
|
|
116
|
+
name = namematchs[1];
|
|
117
|
+
}
|
|
118
|
+
// check token's tenant(if same tenant, name is not full yrn)
|
|
119
|
+
nameptn = new RegExp('^' + keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
|
|
120
|
+
if (name.match(nameptn)) {
|
|
121
|
+
const result = {
|
|
122
|
+
result: false,
|
|
123
|
+
message: 'POST request url has wrong yrn full path to policy'
|
|
124
|
+
};
|
|
125
|
+
dbglogging_1.default.elog(result.message);
|
|
126
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
let effect;
|
|
130
|
+
if (!k2hr3apiutil_1.default.isSafeEntity(req.body.policy.effect)) {
|
|
131
|
+
effect = null; // = not update if policy exists
|
|
132
|
+
}
|
|
133
|
+
else if (k2hr3apiutil_1.default.isString(req.body.policy.effect) && '' === req.body.policy.effect) {
|
|
134
|
+
effect = false; // = deny
|
|
135
|
+
}
|
|
136
|
+
else if (k2hr3apiutil_1.default.isString(req.body.policy.effect) && k2hr3apiutil_1.default.compareCaseString(req.body.policy.effect, keys.VALUE_ALLOW)) {
|
|
137
|
+
effect = true; // = allow
|
|
138
|
+
}
|
|
139
|
+
else if (k2hr3apiutil_1.default.isString(req.body.policy.effect) && k2hr3apiutil_1.default.compareCaseString(req.body.policy.effect, keys.VALUE_DENY)) {
|
|
140
|
+
effect = false; // = deny
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const result = {
|
|
144
|
+
result: false,
|
|
145
|
+
message: 'policy:effect field is wrong : ' + JSON.stringify(req.body.policy.effect)
|
|
146
|
+
};
|
|
147
|
+
dbglogging_1.default.elog(result.message);
|
|
148
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const actptns = [keys.ACTION_READ_KEY, keys.ACTION_WRITE_KEY]; // allow string as read/write yrn full path
|
|
152
|
+
const actpram = k2hr3apiutil_1.default.getNormalizeParameter(req.body.policy.action, null, actptns);
|
|
153
|
+
if (false === actpram.result) {
|
|
154
|
+
const result = {
|
|
155
|
+
result: false,
|
|
156
|
+
message: 'policy:action field is wrong : ' + JSON.stringify(req.body.policy.action)
|
|
157
|
+
};
|
|
158
|
+
dbglogging_1.default.elog(result.message);
|
|
159
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const actions = actpram.parameter;
|
|
163
|
+
const resptn = new RegExp('^' + keys.RESOURCE_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:resource:(.*)/
|
|
164
|
+
const respram = k2hr3apiutil_1.default.getNormalizeParameter(req.body.policy.resource, resptn, null);
|
|
165
|
+
if (false === respram.result) {
|
|
166
|
+
const result = {
|
|
167
|
+
result: false,
|
|
168
|
+
message: 'policy:resource field is wrong : ' + JSON.stringify(req.body.policy.resource)
|
|
169
|
+
};
|
|
170
|
+
dbglogging_1.default.elog(result.message);
|
|
171
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const resources = respram.parameter;
|
|
175
|
+
const condition = null; // now reserved this field
|
|
176
|
+
if (null !== req.body.policy.condition && undefined !== req.body.policy.condition && !k2hr3apiutil_1.default.isSafeString(req.body.policy.condition)) {
|
|
177
|
+
const result = {
|
|
178
|
+
result: false,
|
|
179
|
+
message: 'policy:condition field is wrong : ' + JSON.stringify(req.body.policy.condition)
|
|
180
|
+
};
|
|
181
|
+
dbglogging_1.default.elog(result.message);
|
|
182
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const aliasptn = new RegExp('^' + keys.POLICY_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:policy:(.*)/
|
|
186
|
+
const aliaspram = k2hr3apiutil_1.default.getNormalizeParameter(req.body.policy.alias, aliasptn, null);
|
|
187
|
+
if (false === aliaspram.result) {
|
|
188
|
+
const result = {
|
|
189
|
+
result: false,
|
|
190
|
+
message: 'policy:alias field is wrong : ' + JSON.stringify(req.body.policy.alias)
|
|
191
|
+
};
|
|
192
|
+
dbglogging_1.default.elog(result.message);
|
|
193
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const aliases = aliaspram.parameter;
|
|
197
|
+
//------------------------------
|
|
198
|
+
// set all field to policy
|
|
199
|
+
//------------------------------
|
|
200
|
+
const pol_result = k2hr3dkc_1.default.setPolicyAll(token_info.user, token_info.tenant, name, effect, actions, resources, condition, aliases);
|
|
201
|
+
if (!k2hr3apiutil_1.default.isPlainObject(pol_result) || !k2hr3apiutil_1.default.isBoolean(pol_result.result) || false === pol_result.result) {
|
|
202
|
+
if (!k2hr3apiutil_1.default.isPlainObject(pol_result)) {
|
|
203
|
+
const result = {
|
|
204
|
+
result: false,
|
|
205
|
+
message: 'Could not get response from setPolicyAll'
|
|
206
|
+
};
|
|
207
|
+
dbglogging_1.default.elog(result.message);
|
|
208
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
const result = {
|
|
212
|
+
result: k2hr3apiutil_1.default.isBoolean(pol_result.result) ? pol_result.result : false,
|
|
213
|
+
message: k2hr3apiutil_1.default.isString(pol_result.message) ? pol_result.message : 'Could not get error message in response from setPolicyAll'
|
|
214
|
+
};
|
|
215
|
+
dbglogging_1.default.elog(result.message);
|
|
216
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
217
|
+
}
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
dbglogging_1.default.dlog('succeed : ' + pol_result.message);
|
|
221
|
+
res.status(201); // 201: Created
|
|
222
|
+
res.send(JSON.stringify(pol_result));
|
|
223
|
+
});
|
|
224
|
+
// Mountpath : '/v1/policy'
|
|
225
|
+
// PUT '/v1/policy' : put policy on version 1
|
|
226
|
+
// response body : result => true/false
|
|
227
|
+
// message => messages
|
|
228
|
+
// url argument
|
|
229
|
+
// "name" : <policy name> => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>"
|
|
230
|
+
// "effect" : "allow" or "deny" => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>/effect"
|
|
231
|
+
// if null or undefined is specified, not update this member in policy when this policy exists.
|
|
232
|
+
// if '' or zero array, this member in policy is set default(default deny)..
|
|
233
|
+
// "action" : [<action yrn full path>, ...] => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>/action"
|
|
234
|
+
// specify "yrn:yahoo::::action:read" or "yrn:yahoo::::action:write"
|
|
235
|
+
// if null or undefined is specified, not update this member in policy when this policy exists.
|
|
236
|
+
// if '' or zero array, this member in policy is set empty array.
|
|
237
|
+
// "resource" : [<resource yrn full path>, ...] => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>/resource"
|
|
238
|
+
// specify "yrn:yahoo:<service>::<tenant>:resource:<resource>{/<resource>{...}}"
|
|
239
|
+
// if null or undefined is specified, not update this member in policy when this policy exists.
|
|
240
|
+
// if '' or zero array, this member in policy is set empty array.
|
|
241
|
+
// "condition" : null or undefined => this member is reserved on v1, must be null or undefined.
|
|
242
|
+
// "alias" : [<policy yrn full path>, ...] => key is "yrn:yahoo:<service>::<tenant>:policy:<policy>/@"
|
|
243
|
+
// specify another policy as "yrn:yahoo:<service>::<tenant>:policy:<policy>"
|
|
244
|
+
// if null or undefined is specified, not update this member in policy when this policy exists.
|
|
245
|
+
// if '' or zero array, this member in policy is set empty array.
|
|
246
|
+
//
|
|
247
|
+
router.put('/', (req, res, _) => {
|
|
248
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url);
|
|
249
|
+
res.type('application/json; charset=utf-8');
|
|
250
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req) ||
|
|
251
|
+
!k2hr3apiutil_1.default.isSafeEntity(req.query)) {
|
|
252
|
+
const result = {
|
|
253
|
+
result: false,
|
|
254
|
+
message: 'PUT argument does not have any data'
|
|
255
|
+
};
|
|
256
|
+
dbglogging_1.default.elog(result.message);
|
|
257
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
//------------------------------
|
|
261
|
+
// check token
|
|
262
|
+
//------------------------------
|
|
263
|
+
const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
|
|
264
|
+
if (!token_result.result) {
|
|
265
|
+
const result = {
|
|
266
|
+
result: token_result.result,
|
|
267
|
+
message: k2hr3apiutil_1.default.getSafeString(token_result.message),
|
|
268
|
+
};
|
|
269
|
+
dbglogging_1.default.elog(result.message);
|
|
270
|
+
k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const token_info = token_result.token_info;
|
|
274
|
+
if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
|
|
275
|
+
const result = {
|
|
276
|
+
result: false,
|
|
277
|
+
message: 'specified wrong token or it is not scoped user token'
|
|
278
|
+
};
|
|
279
|
+
dbglogging_1.default.elog(result.message);
|
|
280
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
//------------------------------
|
|
284
|
+
// check arguments
|
|
285
|
+
//------------------------------
|
|
286
|
+
if (!k2hr3apiutil_1.default.isSafeString(req.query.name)) {
|
|
287
|
+
const result = {
|
|
288
|
+
result: false,
|
|
289
|
+
message: 'policy:name field is wrong : ' + JSON.stringify(req.query.name)
|
|
290
|
+
};
|
|
291
|
+
dbglogging_1.default.elog(result.message);
|
|
292
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const keys = r3keys(token_info.user, token_info.tenant);
|
|
296
|
+
let name = k2hr3apiutil_1.default.getSafeString(req.query.name).toLowerCase();
|
|
297
|
+
// policy name is only name or full yrn path
|
|
298
|
+
let nameptn = new RegExp('^' + keys.POLICY_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:policy:(.*)/
|
|
299
|
+
const namematchs = name.match(nameptn);
|
|
300
|
+
if (k2hr3apiutil_1.default.isStringArray(namematchs) && k2hr3apiutil_1.default.isNotEmptyArray(namematchs) && 2 <= namematchs.length) {
|
|
301
|
+
name = namematchs[1];
|
|
302
|
+
}
|
|
303
|
+
// check token's tenant(if same tenant, name is not full yrn)
|
|
304
|
+
nameptn = new RegExp('^' + keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
|
|
305
|
+
if (name.match(nameptn)) {
|
|
306
|
+
const result = {
|
|
307
|
+
result: false,
|
|
308
|
+
message: 'PUT request url has wrong yrn full path to policy'
|
|
309
|
+
};
|
|
310
|
+
dbglogging_1.default.elog(result.message);
|
|
311
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
let effect;
|
|
315
|
+
if (!k2hr3apiutil_1.default.isString(req.query.effect)) {
|
|
316
|
+
effect = null; // = not update if policy exists
|
|
317
|
+
}
|
|
318
|
+
else if (!k2hr3apiutil_1.default.isSafeString(req.query.effect)) {
|
|
319
|
+
effect = false; // = deny
|
|
320
|
+
}
|
|
321
|
+
else if (k2hr3apiutil_1.default.compareCaseString(req.query.effect, keys.VALUE_ALLOW)) {
|
|
322
|
+
effect = true; // = allow
|
|
323
|
+
}
|
|
324
|
+
else if (k2hr3apiutil_1.default.compareCaseString(req.query.effect, keys.VALUE_DENY)) {
|
|
325
|
+
effect = false; // = deny
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
const result = {
|
|
329
|
+
result: false,
|
|
330
|
+
message: 'policy:effect field is wrong : ' + JSON.stringify(req.query.effect)
|
|
331
|
+
};
|
|
332
|
+
dbglogging_1.default.elog(result.message);
|
|
333
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const actptns = [keys.ACTION_READ_KEY, keys.ACTION_WRITE_KEY]; // allow string as read/write yrn full path
|
|
337
|
+
const actpram = k2hr3apiutil_1.default.getNormalizeParameter(req.query.action, null, actptns);
|
|
338
|
+
if (false === actpram.result) {
|
|
339
|
+
const result = {
|
|
340
|
+
result: false,
|
|
341
|
+
message: 'policy:action field is wrong : ' + JSON.stringify(req.query.action)
|
|
342
|
+
};
|
|
343
|
+
dbglogging_1.default.elog(result.message);
|
|
344
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
const actions = actpram.parameter;
|
|
348
|
+
const resptn = new RegExp('^' + keys.RESOURCE_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:resource:(.*)/
|
|
349
|
+
const respram = k2hr3apiutil_1.default.getNormalizeParameter(req.query.resource, resptn, null);
|
|
350
|
+
if (false === respram.result) {
|
|
351
|
+
const result = {
|
|
352
|
+
result: false,
|
|
353
|
+
message: 'policy:resource field is wrong : ' + JSON.stringify(req.query.resource)
|
|
354
|
+
};
|
|
355
|
+
dbglogging_1.default.elog(result.message);
|
|
356
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const resources = respram.parameter;
|
|
360
|
+
const condition = null; // now reserved this field
|
|
361
|
+
if (null !== req.query.condition && undefined !== req.query.condition && !k2hr3apiutil_1.default.isSafeString(req.query.condition)) {
|
|
362
|
+
const result = {
|
|
363
|
+
result: false,
|
|
364
|
+
message: 'policy:condition field is wrong : ' + JSON.stringify(req.query.condition)
|
|
365
|
+
};
|
|
366
|
+
dbglogging_1.default.elog(result.message);
|
|
367
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const aliasptn = new RegExp('^' + keys.POLICY_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:policy:(.*)/
|
|
371
|
+
const aliaspram = k2hr3apiutil_1.default.getNormalizeParameter(req.query.alias, aliasptn, null);
|
|
372
|
+
if (false === aliaspram.result) {
|
|
373
|
+
const result = {
|
|
374
|
+
result: false,
|
|
375
|
+
message: 'policy:alias field is wrong : ' + JSON.stringify(req.query.alias)
|
|
376
|
+
};
|
|
377
|
+
dbglogging_1.default.elog(result.message);
|
|
378
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const aliases = aliaspram.parameter;
|
|
382
|
+
//------------------------------
|
|
383
|
+
// set all field to policy
|
|
384
|
+
//------------------------------
|
|
385
|
+
const pol_result = k2hr3dkc_1.default.setPolicyAll(token_info.user, token_info.tenant, name, effect, actions, resources, condition, aliases);
|
|
386
|
+
if (!k2hr3apiutil_1.default.isPlainObject(pol_result) || !k2hr3apiutil_1.default.isBoolean(pol_result.result) || false === pol_result.result) {
|
|
387
|
+
if (!k2hr3apiutil_1.default.isPlainObject(pol_result)) {
|
|
388
|
+
const result = {
|
|
389
|
+
result: false,
|
|
390
|
+
message: 'Could not get response from setPolicyAll'
|
|
391
|
+
};
|
|
392
|
+
dbglogging_1.default.elog(result.message);
|
|
393
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
const result = {
|
|
397
|
+
result: k2hr3apiutil_1.default.isBoolean(pol_result.result) ? pol_result.result : false,
|
|
398
|
+
message: k2hr3apiutil_1.default.isString(pol_result.message) ? pol_result.message : 'Could not get error message in response from setPolicyAll'
|
|
399
|
+
};
|
|
400
|
+
dbglogging_1.default.elog(result.message);
|
|
401
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
402
|
+
}
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
dbglogging_1.default.dlog('succeed : ' + pol_result.message);
|
|
406
|
+
res.status(201); // 201: Created
|
|
407
|
+
res.send(JSON.stringify(pol_result));
|
|
408
|
+
});
|
|
409
|
+
// Mountpath : '/v1/policy/*'
|
|
410
|
+
// GET '/v1/policy/name' : get policy on version 1(name is allowed full yrn path)
|
|
411
|
+
// URL arguments : service => undefined or service name
|
|
412
|
+
// response body : result => true/false
|
|
413
|
+
// message => error message
|
|
414
|
+
// policy => object
|
|
415
|
+
// policy object
|
|
416
|
+
// {
|
|
417
|
+
// "name": <policy name>
|
|
418
|
+
// "effect": "allow" or "deny"
|
|
419
|
+
// "action": [<action yrn full path>, ...]
|
|
420
|
+
// "resource": [<resource yrn full path>, ...]
|
|
421
|
+
// "condition": null or undefined
|
|
422
|
+
// "alias": [<policy yrn full path>, ...]
|
|
423
|
+
// }
|
|
424
|
+
//
|
|
425
|
+
router.get('/', (req, res, next) => {
|
|
426
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
|
|
427
|
+
if ('GET' !== req.method) {
|
|
428
|
+
// HEAD request comes here, so it should be routed to head function.
|
|
429
|
+
next();
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
res.type('application/json; charset=utf-8');
|
|
433
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req) ||
|
|
434
|
+
!k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
|
|
435
|
+
const result = {
|
|
436
|
+
result: false,
|
|
437
|
+
message: 'GET request or url is wrong'
|
|
438
|
+
};
|
|
439
|
+
dbglogging_1.default.elog(result.message);
|
|
440
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
//------------------------------
|
|
444
|
+
// service name
|
|
445
|
+
//------------------------------
|
|
446
|
+
let service = null;
|
|
447
|
+
if (k2hr3apiutil_1.default.isPlainObject(req.query) && k2hr3apiutil_1.default.isSafeString(req.query.service)) {
|
|
448
|
+
service = k2hr3apiutil_1.default.getSafeString(req.query.service).toLowerCase();
|
|
449
|
+
}
|
|
450
|
+
//------------------------------
|
|
451
|
+
// check token
|
|
452
|
+
//------------------------------
|
|
453
|
+
const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
|
|
454
|
+
if (!token_result.result) {
|
|
455
|
+
const result = {
|
|
456
|
+
result: token_result.result,
|
|
457
|
+
message: k2hr3apiutil_1.default.getSafeString(token_result.message),
|
|
458
|
+
};
|
|
459
|
+
dbglogging_1.default.elog(result.message);
|
|
460
|
+
k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const token_info = token_result.token_info;
|
|
464
|
+
if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
|
|
465
|
+
const result = {
|
|
466
|
+
result: false,
|
|
467
|
+
message: 'specified wrong token or it is not scoped user token'
|
|
468
|
+
};
|
|
469
|
+
dbglogging_1.default.elog(result.message);
|
|
470
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
const keys = r3keys(token_info.user, token_info.tenant, service);
|
|
474
|
+
//------------------------------
|
|
475
|
+
// check policy name
|
|
476
|
+
//------------------------------
|
|
477
|
+
const requestptn = new RegExp('^/v1/policy/(.*)'); // regex = /^\/v1\/policy\/(.*)/
|
|
478
|
+
const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
|
|
479
|
+
if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
|
|
480
|
+
const result = {
|
|
481
|
+
result: false,
|
|
482
|
+
message: 'GET request url does not have policy name'
|
|
483
|
+
};
|
|
484
|
+
dbglogging_1.default.elog(result.message);
|
|
485
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
let name = reqmatchs[1].toLowerCase();
|
|
489
|
+
//
|
|
490
|
+
// make policy name from policy yrn
|
|
491
|
+
//
|
|
492
|
+
let nameptn = new RegExp('^' + keys.MATCH_ANY_TENANT_POLICY); // regex = /^yrn:yahoo:(.*)::(.*):policy:(.*)/
|
|
493
|
+
const namematchs = name.match(nameptn);
|
|
494
|
+
if (!k2hr3apiutil_1.default.isStringArray(namematchs) || !k2hr3apiutil_1.default.isNotEmptyArray(namematchs) || namematchs.length < 4) {
|
|
495
|
+
// name is not full yrn to policy, then check wrong policy name
|
|
496
|
+
nameptn = new RegExp('^' + keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
|
|
497
|
+
if (name.match(nameptn)) {
|
|
498
|
+
const result = {
|
|
499
|
+
result: false,
|
|
500
|
+
message: 'Request query has wrong yrn full path to policy'
|
|
501
|
+
};
|
|
502
|
+
dbglogging_1.default.elog(result.message);
|
|
503
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
// no token need full yrn to policy(other token has tenant name)
|
|
507
|
+
if (!k2hr3apiutil_1.default.isString(token_result.token_type)) {
|
|
508
|
+
const result = {
|
|
509
|
+
result: false,
|
|
510
|
+
message: 'Request query does not have yrn full path to policy'
|
|
511
|
+
};
|
|
512
|
+
dbglogging_1.default.elog(result.message);
|
|
513
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
// no problem, name is policy name
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
// name is full yrn to policy, then need to check tenant name
|
|
520
|
+
if (k2hr3apiutil_1.default.isString(token_result.token_type) && !k2hr3apiutil_1.default.compareCaseString(namematchs[2], token_info.tenant)) {
|
|
521
|
+
const result = {
|
|
522
|
+
result: false,
|
|
523
|
+
message: 'Request query has wrong yrn full path(tenant=' + namematchs[2] + ') to policy(tenant=' + k2hr3apiutil_1.default.getSafeString(token_info.tenant) + ')'
|
|
524
|
+
};
|
|
525
|
+
dbglogging_1.default.elog(result.message);
|
|
526
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
// check service name
|
|
530
|
+
if (k2hr3apiutil_1.default.isSafeString(service)) {
|
|
531
|
+
if (!k2hr3apiutil_1.default.compareCaseString(service, namematchs[1])) {
|
|
532
|
+
const result = {
|
|
533
|
+
result: false,
|
|
534
|
+
message: 'Request query has service name(' + (service ?? '') + ') and path has service name(' + namematchs[1] + '), but both are not same service name.'
|
|
535
|
+
};
|
|
536
|
+
dbglogging_1.default.elog(result.message);
|
|
537
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
else if (k2hr3apiutil_1.default.isSafeString(namematchs[1])) {
|
|
542
|
+
// set service name
|
|
543
|
+
service = k2hr3apiutil_1.default.getSafeString(namematchs[1]).trim().toLowerCase();
|
|
544
|
+
//keys = r3keys(token_info.user, token_info.tenant, service);
|
|
545
|
+
}
|
|
546
|
+
// set name
|
|
547
|
+
name = namematchs[3].toLowerCase();
|
|
548
|
+
}
|
|
549
|
+
//------------------------------
|
|
550
|
+
// get all policy
|
|
551
|
+
//------------------------------
|
|
552
|
+
const pol_result = k2hr3dkc_1.default.getPolicyAll(token_info.user, token_info.tenant, service, name);
|
|
553
|
+
if (!k2hr3apiutil_1.default.isPlainObject(pol_result) || !k2hr3apiutil_1.default.isBoolean(pol_result.result) || false === pol_result.result) {
|
|
554
|
+
if (!k2hr3apiutil_1.default.isPlainObject(pol_result)) {
|
|
555
|
+
const result = {
|
|
556
|
+
result: false,
|
|
557
|
+
message: 'Could not get response from getPolicyAll'
|
|
558
|
+
};
|
|
559
|
+
dbglogging_1.default.elog(result.message);
|
|
560
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
const result = {
|
|
564
|
+
result: k2hr3apiutil_1.default.isBoolean(pol_result.result) ? pol_result.result : false,
|
|
565
|
+
message: k2hr3apiutil_1.default.isString(pol_result.message) ? pol_result.message : 'Could not get error message in response from getPolicyAll'
|
|
566
|
+
};
|
|
567
|
+
dbglogging_1.default.elog(result.message);
|
|
568
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
569
|
+
}
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
dbglogging_1.default.dlog('succeed : ' + pol_result.message);
|
|
573
|
+
res.status(200); // 200: OK
|
|
574
|
+
res.send(JSON.stringify(pol_result));
|
|
575
|
+
});
|
|
576
|
+
// Mountpath : '/v1/policy/*'
|
|
577
|
+
// HEAD '/v1/policy/name' : head policy on version 1(name is allowed full yrn path)
|
|
578
|
+
// Url arguments
|
|
579
|
+
// tenant : optional for policy/resource not full yrn
|
|
580
|
+
// resource : resource to full yrn(or name)
|
|
581
|
+
// action : action(read/write)
|
|
582
|
+
// service : undefined or service name
|
|
583
|
+
//
|
|
584
|
+
router.head('/', (req, res, next) => {
|
|
585
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
|
|
586
|
+
if ('HEAD' !== req.method) {
|
|
587
|
+
// If other method request comes here, so it should be routed another function.
|
|
588
|
+
next();
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
res.type('application/json; charset=utf-8');
|
|
592
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req) ||
|
|
593
|
+
!k2hr3apiutil_1.default.isSafeString(req.baseUrl) ||
|
|
594
|
+
!k2hr3apiutil_1.default.isPlainObject(req.query)) {
|
|
595
|
+
dbglogging_1.default.elog('HEAD request or url or query is wrong');
|
|
596
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
//------------------------------
|
|
600
|
+
// check arguments
|
|
601
|
+
//------------------------------
|
|
602
|
+
// first tenant name
|
|
603
|
+
let tenant = null;
|
|
604
|
+
if (req.query.tenant && k2hr3apiutil_1.default.isSafeString(req.query.tenant)) {
|
|
605
|
+
tenant = k2hr3apiutil_1.default.getSafeString(req.query.tenant).trim().toLowerCase();
|
|
606
|
+
}
|
|
607
|
+
// service name
|
|
608
|
+
let service = null;
|
|
609
|
+
if (k2hr3apiutil_1.default.isSafeString(req.query.service)) {
|
|
610
|
+
service = k2hr3apiutil_1.default.getSafeString(req.query.service).trim().toLowerCase();
|
|
611
|
+
}
|
|
612
|
+
// keys
|
|
613
|
+
let keys = r3keys(null, tenant, service);
|
|
614
|
+
// policy name from path
|
|
615
|
+
const requestptn = new RegExp('^/v1/policy/(.*)'); // regex = /^\/v1\/policy\/(.*)/
|
|
616
|
+
const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
|
|
617
|
+
if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
|
|
618
|
+
dbglogging_1.default.elog('HEAD request url does not have policy name');
|
|
619
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
// check policy name is only name or full yrn path
|
|
623
|
+
let name = reqmatchs[1].toLowerCase();
|
|
624
|
+
//
|
|
625
|
+
// make policy name and full yrn path
|
|
626
|
+
//
|
|
627
|
+
let policy_yrn;
|
|
628
|
+
let nameptn = new RegExp('^' + keys.MATCH_ANY_TENANT_POLICY); // regex = /^yrn:yahoo:(.*)::(.*):policy:(.*)/
|
|
629
|
+
const namematchs = name.match(nameptn);
|
|
630
|
+
if (!k2hr3apiutil_1.default.isStringArray(namematchs) || !k2hr3apiutil_1.default.isNotEmptyArray(namematchs) || namematchs.length < 4) {
|
|
631
|
+
// name is not full yrn to policy, then check wrong policy name
|
|
632
|
+
nameptn = new RegExp('^' + keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
|
|
633
|
+
if (name.match(nameptn)) {
|
|
634
|
+
dbglogging_1.default.elog('Request query has wrong yrn full path to policy');
|
|
635
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
// no token need full yrn to policy(other token has tenant name)
|
|
639
|
+
if (!k2hr3apiutil_1.default.isSafeString(tenant)) {
|
|
640
|
+
dbglogging_1.default.elog('Request query does not have yrn full path to policy');
|
|
641
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
// no problem, name is policy name
|
|
645
|
+
policy_yrn = keys.POLICY_TOP_KEY + ':' + name;
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
// name is full yrn to policy, then need to check tenant name
|
|
649
|
+
if (k2hr3apiutil_1.default.isSafeString(tenant) && !k2hr3apiutil_1.default.compareCaseString(namematchs[2], tenant)) {
|
|
650
|
+
dbglogging_1.default.elog('Request query has wrong yrn full path(tenant=' + namematchs[2] + ') to policy(tenant=' + k2hr3apiutil_1.default.getSafeString(tenant) + ')');
|
|
651
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
// check service name
|
|
655
|
+
if (k2hr3apiutil_1.default.isSafeString(service)) {
|
|
656
|
+
if (!k2hr3apiutil_1.default.compareCaseString(service, namematchs[1])) {
|
|
657
|
+
dbglogging_1.default.elog('Request query has service name(' + k2hr3apiutil_1.default.getSafeString(service) + ') and path has service name(' + namematchs[1] + '), but both are not same service name.');
|
|
658
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
else if (k2hr3apiutil_1.default.isSafeString(namematchs[1])) {
|
|
663
|
+
// set service name
|
|
664
|
+
service = k2hr3apiutil_1.default.getSafeString(namematchs[1]).trim().toLowerCase();
|
|
665
|
+
keys = r3keys(null, tenant, service);
|
|
666
|
+
}
|
|
667
|
+
// set name
|
|
668
|
+
name = namematchs[3].toLowerCase();
|
|
669
|
+
policy_yrn = keys.POLICY_TOP_KEY + ':' + name;
|
|
670
|
+
}
|
|
671
|
+
// resource
|
|
672
|
+
if (!k2hr3apiutil_1.default.isSafeString(req.query.resource)) {
|
|
673
|
+
dbglogging_1.default.elog('HEAD request argument does not have resource parameter');
|
|
674
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
// check resource is only resource name or full yrn path
|
|
678
|
+
let resource = k2hr3apiutil_1.default.getSafeString(req.query.resource);
|
|
679
|
+
let resourceptn = new RegExp('^' + keys.MATCH_ANY_TENANT_RESOURCE); // regex = /^yrn:yahoo:(.*)::(.*):resource:(.*)/
|
|
680
|
+
const resourcematchs = resource.match(resourceptn);
|
|
681
|
+
if (!k2hr3apiutil_1.default.isStringArray(resourcematchs) || !k2hr3apiutil_1.default.isNotEmptyArray(resourcematchs) || resourcematchs.length < 4) {
|
|
682
|
+
// resource is not matched resource(maybe not full yrn), thus we need tenant parameter
|
|
683
|
+
if (!k2hr3apiutil_1.default.isSafeString(tenant)) {
|
|
684
|
+
dbglogging_1.default.elog('HEAD request query does not have resource by full yrn(if you want to set only resource name, you must specify tenant url argument)');
|
|
685
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
// if resource is yrn full path, then it is wrong policy resource
|
|
689
|
+
resourceptn = new RegExp('^' + keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
|
|
690
|
+
if (resource.match(resourceptn)) {
|
|
691
|
+
dbglogging_1.default.elog('HEAD request query has wrong yrn full path to resource');
|
|
692
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
// make full yrn for policy resource
|
|
696
|
+
resource = keys.RESOURCE_TOP_KEY + ':' + resource;
|
|
697
|
+
}
|
|
698
|
+
// action
|
|
699
|
+
if (!k2hr3apiutil_1.default.isSafeString(req.query.action)) {
|
|
700
|
+
dbglogging_1.default.elog('HEAD request argument does not have action parameter');
|
|
701
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
// check action is only action name or full yrn path
|
|
705
|
+
let action = k2hr3apiutil_1.default.getSafeString(req.query.action);
|
|
706
|
+
if (keys.VALUE_READ === action) {
|
|
707
|
+
action = keys.ACTION_READ_KEY;
|
|
708
|
+
}
|
|
709
|
+
else if (keys.VALUE_WRITE === action) {
|
|
710
|
+
action = keys.ACTION_WRITE_KEY;
|
|
711
|
+
}
|
|
712
|
+
else if (keys.ACTION_READ_KEY !== action && keys.ACTION_WRITE_KEY !== action) {
|
|
713
|
+
dbglogging_1.default.elog('HEAD request query has wrong action value');
|
|
714
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
//------------------------------
|
|
718
|
+
// check policy
|
|
719
|
+
//------------------------------
|
|
720
|
+
const result = k2hr3dkc_1.default.checkPolicy(policy_yrn, resource, action);
|
|
721
|
+
if (!result.result) {
|
|
722
|
+
dbglogging_1.default.dlog('action(' + JSON.stringify(action) + ') to resource(' + JSON.stringify(resource) + ') is not allowed by policy(' + JSON.stringify(name) + ') : message=' + k2hr3apiutil_1.default.getSafeString(result.message));
|
|
723
|
+
k2hr3resutil_1.default.errResponse(req, res, 403); // 403: Forbidden
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
dbglogging_1.default.dlog('action(' + JSON.stringify(action) + ') to resource(' + JSON.stringify(resource) + ') is allowed by policy(' + JSON.stringify(name) + ')');
|
|
727
|
+
res.status(204); // 204: No Content
|
|
728
|
+
res.send();
|
|
729
|
+
});
|
|
730
|
+
//
|
|
731
|
+
// Mountpath : '/v1/policy/*'
|
|
732
|
+
// DELETE '/v1/policy/name' : delete policy on version 1
|
|
733
|
+
//
|
|
734
|
+
router.delete('/', (req, res, _) => {
|
|
735
|
+
dbglogging_1.default.dlog('CALL:', req.method, req.url, req.baseUrl);
|
|
736
|
+
res.type('application/json; charset=utf-8');
|
|
737
|
+
if (!k2hr3apiutil_1.default.isPlainObject(req) ||
|
|
738
|
+
!k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
|
|
739
|
+
dbglogging_1.default.elog('DELETE request or url or query is wrong');
|
|
740
|
+
k2hr3resutil_1.default.errResponse(req, res, 400); // 400: Bad Request
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
//------------------------------
|
|
744
|
+
// check token
|
|
745
|
+
//------------------------------
|
|
746
|
+
const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
|
|
747
|
+
if (!token_result.result) {
|
|
748
|
+
const result = {
|
|
749
|
+
result: token_result.result,
|
|
750
|
+
message: k2hr3apiutil_1.default.getSafeString(token_result.message),
|
|
751
|
+
};
|
|
752
|
+
dbglogging_1.default.elog(result.message);
|
|
753
|
+
k2hr3resutil_1.default.errResponse(req, res, token_result.status, result);
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const token_info = token_result.token_info;
|
|
757
|
+
if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
|
|
758
|
+
const result = {
|
|
759
|
+
result: false,
|
|
760
|
+
message: 'specified wrong token or it is not scoped user token'
|
|
761
|
+
};
|
|
762
|
+
dbglogging_1.default.elog(result.message);
|
|
763
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
const keys = r3keys(token_info.user, token_info.tenant);
|
|
767
|
+
//------------------------------
|
|
768
|
+
// check policy name
|
|
769
|
+
//------------------------------
|
|
770
|
+
const requestptn = new RegExp('^/v1/policy/(.*)'); // regex = /^\/v1\/policy\/(.*)/
|
|
771
|
+
const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
|
|
772
|
+
if (!k2hr3apiutil_1.default.isStringArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
|
|
773
|
+
const result = {
|
|
774
|
+
result: false,
|
|
775
|
+
message: 'GET request url does not have policy name'
|
|
776
|
+
};
|
|
777
|
+
dbglogging_1.default.elog(result.message);
|
|
778
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
let name = reqmatchs[1].toLowerCase();
|
|
782
|
+
// policy name is only name or full yrn path
|
|
783
|
+
let nameptn = new RegExp('^' + keys.POLICY_TOP_KEY + ':(.*)'); // regex = /^yrn:yahoo:<service>::<tenant>:policy:(.*)/
|
|
784
|
+
const namematchs = name.match(nameptn);
|
|
785
|
+
if (k2hr3apiutil_1.default.isStringArray(namematchs) && k2hr3apiutil_1.default.isNotEmptyArray(namematchs) && 2 <= namematchs.length) {
|
|
786
|
+
name = namematchs[1];
|
|
787
|
+
}
|
|
788
|
+
// check yrn full path(it is NG)
|
|
789
|
+
nameptn = new RegExp('^' + keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
|
|
790
|
+
if (name.match(nameptn)) {
|
|
791
|
+
const result = {
|
|
792
|
+
result: false,
|
|
793
|
+
message: 'DELETE request url has wrong yrn full path to policy'
|
|
794
|
+
};
|
|
795
|
+
dbglogging_1.default.elog(result.message);
|
|
796
|
+
k2hr3resutil_1.default.errResponse(req, res, 400, result); // 400: Bad Request
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
//------------------------------
|
|
800
|
+
// delete policy
|
|
801
|
+
//------------------------------
|
|
802
|
+
const pol_result = k2hr3dkc_1.default.removePolicy(token_info.user, token_info.tenant, name);
|
|
803
|
+
if (!k2hr3apiutil_1.default.isPlainObject(pol_result) || !k2hr3apiutil_1.default.isBoolean(pol_result.result) || false === pol_result.result) {
|
|
804
|
+
if (!k2hr3apiutil_1.default.isPlainObject(pol_result)) {
|
|
805
|
+
const result = {
|
|
806
|
+
result: false,
|
|
807
|
+
message: 'Could not get response from removePolicy'
|
|
808
|
+
};
|
|
809
|
+
dbglogging_1.default.elog(result.message);
|
|
810
|
+
k2hr3resutil_1.default.errResponse(req, res, 403); // 403: Forbidden(is this status OK?)
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
const result = {
|
|
814
|
+
result: k2hr3apiutil_1.default.isBoolean(pol_result.result) ? pol_result.result : false,
|
|
815
|
+
message: k2hr3apiutil_1.default.isString(pol_result.message) ? pol_result.message : 'Could not get error message in response from removePolicy'
|
|
816
|
+
};
|
|
817
|
+
dbglogging_1.default.elog(result.message);
|
|
818
|
+
k2hr3resutil_1.default.errResponse(req, res, 403); // 403: Forbidden(is this status OK?)
|
|
819
|
+
}
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
dbglogging_1.default.dlog('succeed : ' + pol_result.message);
|
|
823
|
+
res.status(204); // 204: No Content
|
|
824
|
+
res.send();
|
|
825
|
+
});
|
|
826
|
+
//---------------------------------------------------------
|
|
827
|
+
// Exports
|
|
828
|
+
//---------------------------------------------------------
|
|
829
|
+
//
|
|
830
|
+
// Functions
|
|
831
|
+
//
|
|
832
|
+
exports.default = router;
|
|
833
|
+
/*
|
|
834
|
+
* Local variables:
|
|
835
|
+
* tab-width: 4
|
|
836
|
+
* c-basic-offset: 4
|
|
837
|
+
* End:
|
|
838
|
+
* vim600: noexpandtab sw=4 ts=4 fdm=marker
|
|
839
|
+
* vim<600: noexpandtab sw=4 ts=4
|
|
840
|
+
*/
|