k2hr3-api
Version:
K2HR3 REST API is K2hdkc based Resource and Roles and policy Rules
265 lines (264 loc) • 11 kB
JavaScript
;
/*
* K2HR3 REST API
*
* Copyright 2017 Yahoo Japan Corporation.
*
* K2HR3 is K2hdkc based Resource and Roles and policy Rules, gathers
* common management information for the cloud.
* K2HR3 can dynamically manage information as "who", "what", "operate".
* These are stored as roles, resources, policies in K2hdkc, and the
* client system can dynamically read and modify these information.
*
* For the full copyright and license information, please view
* the license file that was distributed with this source code.
*
* AUTHOR: Takeshi Nakatani
* CREATE: Mon Sep 11 2017
* REVISION:
*
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const k2hr3apiutil_1 = __importDefault(require("../lib/k2hr3apiutil"));
const k2hr3resutil_1 = __importDefault(require("../lib/k2hr3resutil"));
const k2hr3dkc_1 = __importDefault(require("../lib/k2hr3dkc"));
const k2hr3tokens_1 = __importDefault(require("../lib/k2hr3tokens"));
const dbglogging_1 = __importDefault(require("../lib/dbglogging"));
const express_1 = __importDefault(require("express"));
const k2hr3keys_1 = require("../lib/k2hr3keys");
const router = express_1.default.Router();
//---------------------------------------------------------
// Router GET/HEAD
//---------------------------------------------------------
//
// Common Utility function
//
const rawGetChildrenList = (req, expand) => {
let result = {
result: true,
message: null,
status: 200
};
if (!k2hr3apiutil_1.default.isPlainObject(req) ||
!k2hr3apiutil_1.default.isSafeString(req.baseUrl)) {
result.result = false;
result.message = 'GET/HEAD request or url is wrong';
result.status = 400; // 400: Bad Request
return result;
}
//------------------------------
// check token
//------------------------------
const token_result = k2hr3tokens_1.default.checkToken(req, true, true); // scoped, user token
if (!token_result.result) {
result.result = token_result.result;
result.message = k2hr3apiutil_1.default.getSafeString(token_result.message);
result.status = k2hr3apiutil_1.default.isSafeNumber(token_result.status) ? token_result.status : 400; // default : 400(Bad Request)
return result;
}
const token_info = token_result.token_info;
if (!k2hr3tokens_1.default.isResTypeCheckRoleToken(token_info)) {
result.result = false;
result.message = 'specified wrong token or it is not scoped user token';
result.status = k2hr3apiutil_1.default.isSafeNumber(token_result.status) ? token_result.status : 400; // default : 400(Bad Request)
return result;
}
const keys = (0, k2hr3keys_1.getK2hr3Keys)((k2hr3apiutil_1.default.isString(token_info.user) ? token_info.user : null), (k2hr3apiutil_1.default.isString(token_info.tenant) ? token_info.tenant : null));
//------------------------------
// parse uri
//------------------------------
const requestptn = new RegExp('^/v1/list/(.*)'); // regex = /^\/v1\/list\/(.*)/
const reqmatchs = decodeURI(req.baseUrl).match(requestptn);
if (!k2hr3apiutil_1.default.isArray(reqmatchs) || !k2hr3apiutil_1.default.isNotEmptyArray(reqmatchs) || reqmatchs.length < 2 || '' === k2hr3apiutil_1.default.getSafeString(reqmatchs[1])) {
result.result = false;
result.message = 'GET/HEAD request url does not have list type{role, resource, policy}';
result.status = 400; // 400: Bad Request
return result;
}
// parse type & path
let _pos = reqmatchs[1].indexOf('/');
let _secondpath = null;
let _path = null;
let _service = null;
let _firstpath;
let _type;
if (-1 !== _pos) {
_firstpath = reqmatchs[1].substr(0, _pos);
_secondpath = reqmatchs[1].substr(_pos + 1);
}
else {
_firstpath = reqmatchs[1];
}
// check
if (k2hr3apiutil_1.default.compareCaseString(keys.TYPE_ROLE, _firstpath)) {
_type = keys.TYPE_ROLE;
_path = _secondpath;
}
else if (k2hr3apiutil_1.default.compareCaseString(keys.TYPE_RESOURCE, _firstpath)) {
_type = keys.TYPE_RESOURCE;
_path = _secondpath;
}
else if (k2hr3apiutil_1.default.compareCaseString(keys.TYPE_POLICY, _firstpath)) {
_type = keys.TYPE_POLICY;
_path = _secondpath; // should be empty
}
else if (k2hr3apiutil_1.default.compareCaseString(keys.TYPE_SERVICE, _firstpath)) {
_type = keys.TYPE_SERVICE;
}
else if (null !== _secondpath && k2hr3apiutil_1.default.isSafeString(_secondpath)) {
// try to check firstpath is service name
let _thirdpath = null;
_pos = _secondpath.indexOf('/');
if (-1 !== _pos) {
_thirdpath = _secondpath.substr(_pos + 1);
_secondpath = _secondpath.substr(0, _pos);
}
_service = _firstpath.toLowerCase();
if (k2hr3apiutil_1.default.compareCaseString(keys.TYPE_ROLE, _secondpath)) {
_type = keys.TYPE_ROLE;
_path = _thirdpath;
}
else if (k2hr3apiutil_1.default.compareCaseString(keys.TYPE_RESOURCE, _secondpath)) {
_type = keys.TYPE_RESOURCE;
_path = _thirdpath;
}
else if (k2hr3apiutil_1.default.compareCaseString(keys.TYPE_POLICY, _secondpath)) {
_type = keys.TYPE_POLICY;
_path = _thirdpath; // should be empty
}
else {
result.result = false;
result.message = 'GET/HEAD request url has wrong list type, it must be "service/role" or "service/resource" or "service/policy"';
result.status = 400; // 400: Bad Request
return result;
}
}
else {
result.result = false;
result.message = 'GET/HEAD request url has wrong list type, it must be "role" or "resource" or "policy" or "service"';
result.status = 400; // 400: Bad Request
return result;
}
//------------------------------
// expand type(only user token type)
//------------------------------
let is_expand = false;
if (k2hr3apiutil_1.default.isBoolean(expand)) {
// Case for HEAD
is_expand = expand;
}
else if (k2hr3apiutil_1.default.isPlainObject(req.query) && k2hr3apiutil_1.default.isSafeString(req.query.expand)) {
if (k2hr3apiutil_1.default.compareCaseString(keys.VALUE_TRUE, req.query.expand)) {
is_expand = true;
}
else if (k2hr3apiutil_1.default.compareCaseString(keys.VALUE_FALSE, req.query.expand)) {
is_expand = false;
}
else {
result.result = false;
result.message = 'GET/HEAD expand url argument parameter(' + JSON.stringify(req.query.expand) + ') is wrong, it must be ' + keys.VALUE_TRUE + ' or ' + keys.VALUE_FALSE + '.';
result.status = 400; // 400: Bad Request
return result;
}
}
//------------------------------
// get children list
//------------------------------
const list_result = k2hr3dkc_1.default.getChildrenList(token_info.tenant, _service, _type, _path, is_expand);
if (k2hr3dkc_1.default.isResTypeChildrenTree(list_result)) {
result = list_result;
if (!result.result) {
result.message = k2hr3apiutil_1.default.isSafeString(result.message) ? result.message : 'Could not get error message in response from getChildrenList';
result.status = k2hr3apiutil_1.default.isSafeNumber(result.status) ? result.status : 400; // default : 400(Bad Request)
}
}
else {
result.result = false;
result.message = 'Could not get response from getChildrenList';
result.status = 400; // 400: Bad Request
}
return result;
};
//
// Mountpath : '/v1/list/{role, resource, policy, service}{/...}'
// : '/v1/list/<service>/{role, resource, policy}{/...}'
//
// GET '/v1/list/.../{path}' : get list on version 1
// HEADER : X-Auth-Token = User token
// URL arguments : expand = "true"(default) or "false"
//
// response body : result => true/false
// message => error message
// object => nested objects...
//
router.get('/', (req, res, next) => {
dbglogging_1.default.dlog('CALL:', req.method, req.url);
if ('GET' !== req.method) {
// HEAD request comes here, so it should be routed to head function.
next();
return;
}
res.type('application/json; charset=utf-8');
//
// get children list
//
const result = rawGetChildrenList(req);
const _message = k2hr3dkc_1.default.isResTypeChildrenTree(result) ? k2hr3apiutil_1.default.getSafeString(result.message) : 'Failed to get list.';
const _status = (k2hr3dkc_1.default.isResTypeChildrenTree(result) && k2hr3apiutil_1.default.isSafeNumber(result.status)) ? result.status : 500;
if (!k2hr3dkc_1.default.isResTypeChildrenTree(result) || !result.result) {
dbglogging_1.default.elog(_message);
k2hr3resutil_1.default.errResponse(req, res, _status, result);
return;
}
dbglogging_1.default.dlog('succeed : ' + _message);
res.status(200); // 200: OK
res.send(JSON.stringify(result));
});
//
// Mountpath : '/v1/list/{role, resource, policy, service}{/...}'
// : '/v1/list/<service>/{role, resource, policy}{/...}'
//
// HEAD '/v1/list/.../{path}' : get list on version 1
// HEADER : X-Auth-Token = User token
// URL arguments : expand = "true"(default) or "false"
//
router.head('/', (req, res, next) => {
dbglogging_1.default.dlog('CALL:', req.method, req.url);
if ('HEAD' !== req.method) {
next();
return;
}
res.type('application/json; charset=utf-8');
//
// get children list
//
const result = rawGetChildrenList(req, false); // Force set expand as false
const _message = k2hr3dkc_1.default.isResTypeChildrenTree(result) ? k2hr3apiutil_1.default.getSafeString(result.message) : 'Failed to get list.';
const _status = (k2hr3dkc_1.default.isResTypeChildrenTree(result) && k2hr3apiutil_1.default.isSafeNumber(result.status)) ? result.status : 500;
if (!k2hr3dkc_1.default.isResTypeChildrenTree(result) || !result.result) {
dbglogging_1.default.elog(_message);
k2hr3resutil_1.default.errResponse(req, res, _status);
return;
}
dbglogging_1.default.dlog('succeed : ' + _message);
res.status(204); // 204: No Content
res.send(JSON.stringify(result));
});
//---------------------------------------------------------
// Exports
//---------------------------------------------------------
//
// Functions
//
exports.default = router;
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noexpandtab sw=4 ts=4 fdm=marker
* vim<600: noexpandtab sw=4 ts=4
*/