k2hr3-api
Version:
K2HR3 REST API is K2hdkc based Resource and Roles and policy Rules
1,313 lines (1,206 loc) • 101 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: Wed Jun 8 2017
* REVISION:
*
*/
'use strict';
var k2hr3 = require('./k2hr3dkc');
var r3keys = require('./k2hr3keys').getK2hr3Keys;
var apiutil = require('./k2hr3apiutil');
// Debug logging objects
var r3logger = require('../lib/dbglogging');
//---------------------------------------------------------
// Configuration
// * Keystone api wrapper
// * Get expiration for role tokens
//---------------------------------------------------------
// [NOTE]
// We use config which has keystone.type value.
// Default value is "keystone_v3".
//
var osapi = null;
var expire_rtoken = 0;
var expire_reg_rtoken = 0;
(function()
{
var r3Conf = require('./k2hr3config').r3ApiConfig;
var apiConf = new r3Conf();
var keystone_type = './' + apiConf.getKeystoneType();
osapi = require(keystone_type);
expire_rtoken = apiConf.getExpireTimeRoleToken();
expire_reg_rtoken = apiConf.getExpireTimeRegRoleToken();
}());
//---------------------------------------------------------
// Get User Token
//---------------------------------------------------------
//
// Get scoped/unscoped user token from keystone
//
function rawGetUserToken(user, passwd, tenant, callback)
{
var _callback = callback;
if(!apiutil.isSafeString(user)){
var error = new Error('user parameter is wrong');
r3logger.elog(error.message);
_callback(error, null);
return;
}
var _tenant = apiutil.isSafeString(tenant) ? tenant.toLowerCase() : '';
var _user = user;
var _passwd = apiutil.isSafeString(passwd) ? passwd : '';
// get unscoped token
rawGetUserUnscopedTokenWrap(_user, _passwd, function(err, jsonres)
{
var error;
if(null !== err){
error = new Error('could not get user access token by ' + err.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
// save to local val
_user = jsonres.user; // over write
var _userid = jsonres.userid;
var _username = jsonres.user;
var _unscopedtoken = jsonres.token;
var _tokenexpire = jsonres.expire; // eslint-disable-line no-unused-vars
var _region = jsonres.region; // eslint-disable-line no-unused-vars
// break when unscoped token
if(!apiutil.isSafeString(_tenant)){
_callback(null, _unscopedtoken);
return;
}
// get scoped user token
return rawGetScopedUserToken(_unscopedtoken, _username, _userid, _tenant, _callback);
});
}
//---------------------------------------------------------
// Get User Token from token issued by another authentication system
//---------------------------------------------------------
//
// Get scoped/unscoped user token from token issued by another authentication system
// (ex. openstack identity token which is not registered in k2hr3 yet.)
//
function rawGetUserTokenByToken(token, tenant, callback)
{
var _callback = callback;
if(!apiutil.isSafeString(token)){
var error = new Error('token parameter is wrong');
r3logger.elog(error.message);
_callback(error, null);
return;
}
var _tenant = apiutil.isSafeString(tenant) ? tenant.toLowerCase() : '';
var _orgtoken = token;
// get unscoped token
rawGetUserUnscopedTokenbyTokenWrap(_orgtoken, function(err, jsonres)
{
var error;
if(null !== err){
error = new Error('could not get user access token by ' + err.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
// save to local val
var _userid = jsonres.userid;
var _username = jsonres.user;
var _unscopedtoken = jsonres.token;
var _tokenexpire = jsonres.expire; // eslint-disable-line no-unused-vars
var _region = jsonres.region; // eslint-disable-line no-unused-vars
// break when unscoped token
if(!apiutil.isSafeString(_tenant)){
_callback(null, _unscopedtoken);
return;
}
// get scoped user token
return rawGetScopedUserToken(_unscopedtoken, _username, _userid, _tenant, _callback);
});
}
//
// Get scoped user token from unscoped user token
//
function rawGetScopedUserTokenByUnscoped(unscopedtoken, username, tenant, callback)
{
var error;
if(!apiutil.isSafeStrings(unscopedtoken, username, tenant)){
error = new Error('unscopedtoken or username or tenant parameters are wrong');
r3logger.elog(error.message);
callback(error, null);
return;
}
// user id from user name
var _tenant = tenant.toLowerCase();
var user_info = k2hr3.getUserId(username); // user id from user name
if(null === user_info || !apiutil.isSafeEntity(user_info.name) || !apiutil.isSafeEntity(user_info.id)){
error = new Error('could not find username(' + username + ') from unscoped token in k2hdkc.');
r3logger.elog(error.message);
callback(error, null);
return;
}
// get scoped user token
return rawGetScopedUserToken(unscopedtoken, user_info.name, user_info.id, _tenant, callback);
}
//
// Get scoped user token from keystone
//
function rawGetScopedUserToken(unscopedtoken, username, userid, tenant, callback)
{
if(!apiutil.isSafeStrings(unscopedtoken, username, userid, tenant)){
var error = new Error('unscopedtoken or username or userid or tenant parameters are wrong');
r3logger.elog(error.message);
_callback(error, null);
return;
}
var _unscopedtoken = unscopedtoken;
var _username = username;
var _userid = userid;
var _tenant = apiutil.isSafeString(tenant) ? tenant.toLowerCase() : '';
var _callback = callback;
// get tenant list for check
osapi.getUserTenantList(_unscopedtoken, _userid, function(err, jsonres)
{
var error;
if(null !== err){
error = new Error('could not get tenant list for user ' + _username + '(token=' + _unscopedtoken + ') by ' + err.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
//r3logger.dlog('get user tenant list jsonres=\n' + JSON.stringify(jsonres));
// check tenants(and initialize tenants)
var _tenant_id = null;
var _tenant_name = null;
var _tenant_desc = null;
var _tenant_display = null;
var _tenant_list = new Array(0);
for(var cnt = 0; cnt < jsonres.length; ++cnt){
if(!apiutil.isSafeEntity(jsonres[cnt])){
continue;
}
// over write
var resobj = k2hr3.initUserTenant(_username, _userid, _username, jsonres[cnt].name, jsonres[cnt].id, jsonres[cnt].description, jsonres[cnt].display);
if(!resobj.result){
error = new Error(resobj.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
if(apiutil.compareCaseString(jsonres[cnt].name, _tenant)){
// find target tenant
_tenant_id = jsonres[cnt].id;
_tenant_name = jsonres[cnt].name;
_tenant_desc = jsonres[cnt].description;
_tenant_display = jsonres[cnt].display;
}
_tenant_list.push(jsonres[cnt].name);
}
// get and add local tenants
var tmpresobj = k2hr3.listLocalTenant(_username, true);
if(!apiutil.isSafeEntity(tmpresobj) || !apiutil.isSafeEntity(tmpresobj.result) || false === tmpresobj.result){
if(apiutil.isSafeEntity(tmpresobj) && apiutil.isSafeString(tmpresobj.message)){
r3logger.wlog('failed to get local tenant list by ' + tmpresobj.message);
}else{
r3logger.wlog('failed to get local tenant list.');
}
}else{
if(!apiutil.isEmptyArray(tmpresobj.tenants)){
for(var cnt2 = 0; cnt2 < tmpresobj.tenants.length; ++cnt2){
var one_tenant = tmpresobj.tenants[cnt2];
if(!apiutil.isSafeEntity(tmpresobj.tenants[cnt2])){
continue;
}
if(apiutil.compareCaseString(tmpresobj.tenants[cnt2].name, _tenant)){
// find target tenant
_tenant_id = tmpresobj.tenants[cnt2].id;
_tenant_name = tmpresobj.tenants[cnt2].name;
_tenant_desc = tmpresobj.tenants[cnt2].desc; // eslint-disable-line no-unused-vars
_tenant_display = tmpresobj.tenants[cnt2].display; // eslint-disable-line no-unused-vars
}
_tenant_list.push(one_tenant);
}
}
}
// check and remove old tenant for user
if(!k2hr3.removeComprehensionByNewTenants(_username, _tenant_list)){
r3logger.elog('failed to remove some tenant for user, but continue...');
}
// get scoped token
osapi.getUserScopedToken(_unscopedtoken, _tenant_name, _tenant_id, function(err, jsonres)
{
var error;
if(null !== err){
error = new Error('could not get scoped user token for user ' + _username + ' by ' + err.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
//r3logger.dlog('get user scoped token jsonres=\n' + JSON.stringify(jsonres));
var token_seed = apiutil.isSafeString(jsonres.token_seed) ? jsonres.token_seed : null;
if(!rawSetUserToken(_username, _tenant_name, jsonres.token, jsonres.expire, jsonres.region, token_seed)){
error = new Error('failed to set unscoped/scoped user token');
r3logger.elog(error.message);
_callback(error, null);
return;
}
// succeed
_callback(null, jsonres.token);
return;
});
});
}
//---------------------------------------------------------
// set user/tenant token
//---------------------------------------------------------
// tenant undefined(or null) thus token must be unscoped.
// expire UTC ISO 8601 format
//
// [NOTE] Must initialize User/Tenant before calling this function.
//
function rawSetUserToken(user, tenant, token, expire, region, seed)
{
if(!apiutil.isSafeStrings(user, token, expire, region)){ // allow tenant/seed is null
r3logger.elog('some parameters are wrong : user=' + JSON.stringify(user) + ', tenant=' + JSON.stringify(tenant) + ', token=' + JSON.stringify(token) + ', expire=' + JSON.stringify(expire) + ', region=' + JSON.stringify(region));
return false;
}
var dkcobj = k2hr3.getK2hdkc(true, false); // use permanent object(need to clean)
var keys = r3keys(user, tenant);
var subkeylist;
if(!apiutil.isSafeEntity(dkcobj)){
return false;
}
//
// Check user key exists and create these.
//
var expire_limit = apiutil.calcExpire(expire); // UTC ISO 8601 to unixtime
var token_value_key = keys.TOKEN_USER_TOP_KEY + '/' + token; // "yrn:yahoo::::token:user/<token>"
var user_token_key = keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY + '/' + token; // "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>"
var user_token_seed_key = user_token_key + '/' + keys.SEED_KW; // "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>/seed"
// [NOTE]
// If tenant is null, following keys have not tenant keyword in that key string.
// [ not have tenant name ] vs [ have tenant name ]
// keys.USER_TENANT_AMBIGUOUS_KEY ---> "yrn:yahoo::::user:<user>:tenant/" or "yrn:yahoo::::user:<user>:tenant/<tenant>"
// keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY ---> "yrn:yahoo::::user:<user>:tenant//token" or "yrn:yahoo::::user:<user>:tenant/<tenant>/token"
//
// token top
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.USER_TENANT_AMBIGUOUS_KEY, true));
if(apiutil.tryAddStringToArray(subkeylist, keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY)){
if(!dkcobj.setSubkeys(keys.USER_TENANT_AMBIGUOUS_KEY, subkeylist)){ // add subkey yrn:yahoo::::user:<user>:tenant/{<tenant>}/token -> yrn:yahoo::::user:<user>:tenant/{<tenant>}
r3logger.elog('could not add ' + keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY + ' subkey under ' + keys.USER_TENANT_AMBIGUOUS_KEY + ' key');
dkcobj.clean();
return false;
}
}
// to token key
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY, true));
if(apiutil.tryAddStringToArray(subkeylist, user_token_key)){
if(!dkcobj.setSubkeys(keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY, subkeylist)){ // add subkey yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token> -> yrn:yahoo::::user:<user>:tenant/{<tenant>}/token
r3logger.elog('could not add ' + user_token_key + ' subkey under ' + keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY + ' key');
dkcobj.clean();
return false;
}
}
// get/set token value
var old_value = dkcobj.getValue(user_token_key, null, true, null);
if(old_value != region){
if(!dkcobj.setValue(user_token_key, region, null, null, expire_limit)){ // update new token key(value with region and expire) -> yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>
r3logger.elog('could not set ' + region + '(expire=' + expire + ') to ' + user_token_key + ' key');
dkcobj.clean();
return false;
}
}
// get/set seed value
if(apiutil.isSafeString(seed)){
old_value = dkcobj.getValue(user_token_seed_key, null, true, null);
if(old_value != seed){
if(!dkcobj.setValue(user_token_seed_key, seed, null, null, expire_limit)){ // update new token seed key(value with expire) -> yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>/seed
r3logger.elog('could not set ' + seed + '(expire=' + expire + ') to ' + user_token_seed_key + ' key');
dkcobj.clean();
return false;
}
}
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(user_token_key, true));
if(apiutil.tryAddStringToArray(subkeylist, user_token_seed_key)){
if(!dkcobj.setSubkeys(user_token_key, subkeylist)){ // add subkey yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>/seed -> yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>
r3logger.elog('could not add ' + user_token_seed_key + ' subkey under ' + user_token_key + ' key');
dkcobj.clean();
return false;
}
}
}
// create new token under token top key
//
// [NOTE]
// This key is not set expire limit. if you need to check expire,
// you look up key under user key.
//
if(!dkcobj.setValue(token_value_key, user_token_key)){ // create(over write) value(="yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>") without expire -> yrn:yahoo::::token/<token>
r3logger.elog('could not set ' + user_token_key + ' value without expire to ' + token_value_key + ' key');
dkcobj.clean();
return false;
}
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.TOKEN_USER_TOP_KEY, true));
if(apiutil.tryAddStringToArray(subkeylist, token_value_key)){
if(!dkcobj.setSubkeys(keys.TOKEN_USER_TOP_KEY, subkeylist)){ // add subkey yrn:yahoo::::token:user/<token> -> yrn:yahoo::::token:user
r3logger.elog('could not add ' + token_value_key + ' subkey under ' + keys.TOKEN_USER_TOP_KEY + ' key');
dkcobj.clean();
return false;
}
}
dkcobj.clean();
return true;
}
//---------------------------------------------------------
// get user unscoped token
//---------------------------------------------------------
//
// Get user token from keystone
//
// result null or object
// {
// user: user name(if existed, from parameter)
// userid: user id(if existed, from "yrn:yahoo::::user:<user name>:id")
// scoped: false(always false)
// token: token string(id)
// expire: expire string(if existed, null)
// region: region string
// }
//
// [NOTE]
// This function is wrapper for osapi.getUserUnscopedToken().
// This function checks existing unscoped token before call it.
//
function rawGetUserUnscopedTokenWrap(user, passwd, callback)
{
var _user = user;
var _passwd = apiutil.isSafeString(passwd) ? passwd : '';
var _callback = callback;
// get unscoped token
osapi.getUserUnscopedToken(_user, _passwd, function(err, jsonres)
{
var error;
if(null !== err){
error = new Error('could not get user access token by ' + err.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
// init user
var resobj = k2hr3.initUser(jsonres.user, jsonres.userid, jsonres.user, null);
if(!resobj.result){
error = new Error(resobj.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
// set unscoped token
var token_seed = apiutil.isSafeString(jsonres.token_seed) ? jsonres.token_seed : null;
if(!rawSetUserToken(jsonres.user, null, jsonres.token, jsonres.expire, jsonres.region, token_seed)){
error = new Error('failed to set unscoped/scoped user token');
r3logger.elog(error.message);
_callback(error, null);
return;
}
// succeed
_callback(null, jsonres);
return;
});
}
//---------------------------------------------------------
// get user unscoped token from token issued by another authentication system
//---------------------------------------------------------
//
// Get user token from token issued by another authentication system
//
// result null or object
// {
// user: user name(if existed, from parameter)
// userid: user id(if existed, from "yrn:yahoo::::user:<user name>:id")
// scoped: false(always false)
// token: token string(id)
// expire: expire string(if existed, null)
// region: region string
// }
//
// [NOTE]
// This function is wrapper for osapi.getUserUnscopedTokenByToken().
// This function checks existing unscoped token before call it.
//
function rawGetUserUnscopedTokenbyTokenWrap(token, callback)
{
var _orgtoken = token;
var _callback = callback;
// get unscoped token
osapi.getUserUnscopedTokenByToken(_orgtoken, function(err, jsonres)
{
var error;
if(null !== err){
error = new Error('could not get user access token by ' + err.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
// init user
var resobj = k2hr3.initUser(jsonres.user, jsonres.userid, jsonres.user, null);
if(!resobj.result){
error = new Error(resobj.message);
r3logger.elog(error.message);
_callback(error, null);
return;
}
// set unscoped token
var token_seed = apiutil.isSafeString(jsonres.token_seed) ? jsonres.token_seed : null;
if(!rawSetUserToken(jsonres.user, null, jsonres.token, jsonres.expire, jsonres.region, token_seed)){
error = new Error('failed to set unscoped/scoped user token');
r3logger.elog(error.message);
_callback(error, null);
return;
}
// succeed
_callback(null, jsonres);
return;
});
}
//---------------------------------------------------------
// remove scoped user token
//---------------------------------------------------------
//
// token scoped user token
//
// [NOTE] This removes(force expire) scoped user token for
// using ACR API.
// The token used by ACR must be removed after checking
// it, because this case allows using token one time.
//
function rawRemoveScopedUserToken(token)
{
if(!apiutil.isSafeString(token)){
r3logger.elog('parameter is wrong : token=' + JSON.stringify(token));
return false;
}
//
// Check token
//
if(0 === token.indexOf('R=')){
r3logger.elog('token(' + JSON.stringify(token) + ') is role token.');
return false;
}else if(0 === token.indexOf('U=')){
token = token.substr(2); // cut 'U='
}
var token_info = rawCheckUserToken(token);
if( null === token_info ||
!apiutil.isSafeString(token_info.user) ||
!apiutil.isSafeString(token_info.tenant) ||
!apiutil.isSafeEntity(token_info.scoped) ||
'boolean' !== typeof token_info.scoped ||
true !== token_info.scoped )
{
r3logger.elog('token(' + JSON.stringify(token) + ') is something wrong.');
return false;
}
//
// Remove token
//
var dkcobj = k2hr3.getK2hdkc(true, false); // use permanent object(need to clean)
var subkeylist;
var errmsg = '';
if(!apiutil.isSafeEntity(dkcobj)){
return false;
}
//
// Keys
//
var keys = r3keys(token_info.user, token_info.tenant);
var token_top_key = keys.TOKEN_USER_TOP_KEY; // "yrn:yahoo::::token:user"
var token_value_key = keys.TOKEN_USER_TOP_KEY + '/' + token; // "yrn:yahoo::::token:user/<token>"
var utoken_top_key = keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY; // "yrn:yahoo::::user:<user>:tenant/<tenant>/token"
var utoken_token_key= keys.USER_TENANT_AMBIGUOUS_TOKEN_KEY + '/' + token; // "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>"
var utoken_seed_key = utoken_token_key + '/' + keys.SEED_KW; // "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>/seed"
//
// check under token top
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(token_top_key, true));
if(apiutil.removeStringFromArray(subkeylist, token_value_key)){ // remove subkeys "yrn:yahoo::::token:user/<token>" -> "yrn:yahoo::::token:user"
if(!dkcobj.setSubkeys(token_top_key, subkeylist)){
errmsg += 'could not remove ' + token_value_key + ' subkey under ' + token_top_key + ' key, ';
}
}
if(!dkcobj.remove(token_value_key, false)){ // remove key "yrn:yahoo::::token:user/<token>"
errmsg += 'could not remove ' + token_value_key + 'key, probably it is not existed, ';
}
//
// check under user top
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(utoken_top_key, true));
if(apiutil.removeStringFromArray(subkeylist, utoken_token_key)){ // remove subkeys "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>" -> "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token"
if(!dkcobj.setSubkeys(utoken_top_key, subkeylist)){
errmsg += 'could not remove ' + utoken_token_key + ' subkey under ' + utoken_top_key + ' key, ';
}
}
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(utoken_token_key, true));
if(apiutil.removeStringFromArray(subkeylist, utoken_seed_key)){ // remove subkeys "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>/seed" -> "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>"
if(!dkcobj.setSubkeys(utoken_token_key, subkeylist)){
errmsg += 'could not remove ' + utoken_seed_key + ' subkey under ' + utoken_token_key + ' key, ';
}
}
if(!dkcobj.remove(utoken_seed_key, false)){ // remove key "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>/seed"
errmsg += 'could not remove ' + utoken_seed_key + 'key, probably it is not existed, ';
}
if(!dkcobj.remove(utoken_token_key, false)){ // remove key "yrn:yahoo::::user:<user>:tenant/{<tenant>}/token/<token>"
errmsg += 'could not remove ' + utoken_token_key + 'key, probably it is not existed, ';
}
if(apiutil.isSafeString(errmsg)){
r3logger.elog(errmsg);
}
dkcobj.clean();
return true; // Returns true even if there is an error in deletion processing
}
//---------------------------------------------------------
// Check User Token
//---------------------------------------------------------
//
// Check User Token
//
// result : null or token information
// {
// role: role name
// user: user name
// hostname: always null
// ip: always null
// port: always 0
// cuk: always null
// extra: always null
// tenant: tenant name
// display: display alias name for tenant
// id: tenant id string
// description: description for tenant
// scoped: role token is always scoped(true)
// region: when user token, the creator region name of the token
// }
//
function rawCheckUserToken(token)
{
if(!apiutil.isSafeString(token)){
r3logger.elog('token parameter is wrong');
return null;
}
// get user/tenant from token
var token_info = rawGetUserTenantByToken(token);
if(null === token_info || !apiutil.isSafeEntity(token_info.user)){
r3logger.elog('token is not any user/tenant(expired or wrong token)');
return null;
}
// add scoped flag
if(apiutil.isSafeEntity(token_info.tenant)){
token_info.scoped = true;
}else{
token_info.scoped = false;
}
token_info.role = null;
token_info.ip = null;
token_info.hostname = null;
token_info.port = 0;
token_info.cuk = null;
token_info.extra = null;
return token_info;
}
//---------------------------------------------------------
// [Role Token]
//---------------------------------------------------------
//
// Token: Token Id(################)
// X-Auth-Token: R=Token Id
// Token Id: The "Token Id" is a unique hex number string for 128bit.
// "Token Id" = "(<base id(64bit:8byte)> ^ <crypt id(64bit:8byte)>)" + "(<role id(64bit:8byte)> ^ <crypt id(64bit:8byte)>)"
// Role Token Key: "yrn:yahoo::::token:role/<Token Id>"
// Role Token Value: {
// role: "role full yrn"
// date: "UTC ISO 8601 time at create"
// expire: "UTC ISO 8601 time at expire"
// creator: "Host full yrn" or "User full yrn"
// base: "id from host" or "last 64bit string in UserToken"
// user: "user name", if creator is user, this value is user name.(if not, this is null)
// ip: "ip address", if creator is host, this value is ip address.(if not, this is null)
// hostname: "hostname", if creator is host, this value is hostname.(if not, this is null)
// port: "port number", if creator is host, this value is port number.(if not, this is 0)
// cuk: "cuk", if creator is host on iaas, this value is cuk.(allowed null)
// extra: "extra", if creator is host on iaas, this value is extra.(allowed null)
// tenant: "tenant name" for this role token(this mean token is scoped)
// verify: "random 64bit id for verify token"
// }
//
// [NOTE]
// "role id" which is in "Token Id" is included from role key(yrn:yahoo:<Tenant>:::role:<role name>/id).
// This value is secret, any API could not get this value directly.
//
//---------------------------------------------------------
// Get Role Token From user(token)
//---------------------------------------------------------
//
// user : this value is parsed from user token
// tenant : this value is parsed from user token
// role : target role name(full yrn or only role name)
// expire_limit : specify expire second(default 24H = 24 * 60 * 60 sec, 0 means no expire time.)
//
// result : {
// result: true/false
// message: null or error message string
// token: undefined(error) or role token string
// }
//
// [NOTE]
// set role token value is following
// {
// role: token's role yrn("yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}")
// date: create date(UTC ISO 8601)
// expire: expire date(UTC ISO 8601)
// creator: creator yrn("yrn:yahoo::::user:<user>" or "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/hosts/ip/<ip:port>")
// user: if creator is user, this value is user name.
// hostname: always null
// ip: always null
// port: if creator is host, this value is port number.(if not, this is 0)
// cuk: if creator is host on iaas, this value is cuk.(allowed null)
// extra: if creator is host on iaas, this value is extra.(allowed null)
// tenant: tenant name for this role token(this mean token is scoped)
// base: 32bytes hex string
// }
//
function rawGetRoleTokenByUser(user, tenant, role, expire_limit)
{
var resobj = {result: true, message: null};
if(!apiutil.isSafeStrings(user, tenant, role)){ // allow other argument is empty
resobj.result = false;
resobj.message = 'some parameters are wrong : user=' + JSON.stringify(user) + ', tenant=' + JSON.stringify(tenant) + ', role=' + JSON.stringify(role);
r3logger.elog(resobj.message);
return resobj;
}
if(!apiutil.isSafeEntity(expire_limit) || isNaN(expire_limit)){ // expire_limit must be number or null(undefined)
expire_limit = expire_rtoken; // default 24H
}else{
if(0 == expire_limit){
// [NOTE]
// If 0, set the maximum value to 10 years.
// Disable expire by setting a period of time within which this
// application is guaranteed not to survive, as permitted by ISO8601.
//
expire_limit = expire_reg_rtoken;
}
}
// check role name is only name or full yrn path
var keys = r3keys(user, tenant);
role = role.toLowerCase();
var roleptn = new RegExp('^' + keys.MATCH_ANY_TENANT_ROLE); // regex = /^yrn:yahoo:(.*)::(.*):role:(.*)/
var rolematchs = role.match(roleptn);
if(apiutil.isEmptyArray(rolematchs) || rolematchs.length < 4){
// role is not matched role(maybe not full yrn), then we need check it is another yrn path
roleptn = new RegExp('^' + keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
if(role.match(roleptn)){
resobj.result = false;
resobj.message = 'role(' + role + ') is not role yrn path)';
r3logger.elog(resobj.message);
return resobj;
}
// role is only role name, then we do not modify it.
}else{
// check tenant name
if(tenant !== rolematchs[2]){
resobj.result = false;
resobj.message = 'role(' + role + ') yrn has tenant(' + rolematchs[2] + '), but it is not specified tenant(' + tenant + ')';
r3logger.elog(resobj.message);
return resobj;
}
// role is set only role name
role = rolematchs[3];
}
var dkcobj = k2hr3.getK2hdkc(true, false); // use permanent object(need to clean)
var subkeylist;
if(!apiutil.isSafeEntity(dkcobj)){
resobj.result = false;
resobj.message = 'Not initialize yet.';
r3logger.elog(resobj.message);
return resobj;
}
//
// keys
//
var role_key = keys.ROLE_TOP_KEY + ':' + role; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}"
var role_id_key = role_key + '/' + keys.ID_KW; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/id"
var role_tokens_key = role_key + '/' + keys.ROLE_TOKEN_KW; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/tokens"
// user id
var user_id = dkcobj.getValue(keys.USER_ID_KEY, null, true, null); // get user id from "yrn:yahoo::::user:<user name>:id"
if(!apiutil.isSafeString(user_id)){
resobj.result = false;
resobj.message = 'could not get user id(' + keys.USER_ID_KEY + ') value, or it is wrong value(' + JSON.stringify(user_id) + ').';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
// role id
var role_id = dkcobj.getValue(role_id_key, null, true, null);
if(!apiutil.isSafeStrUuid4(role_id)){
var isError = false;
var old_role_id = apiutil.parseJSON(role_id);
if(!apiutil.isEmptyArray(old_role_id) && 4 == old_role_id.length){
// old version id, so reset new valus(UUID4) here.
role_id = apiutil.getStrUuid4();
if(!dkcobj.setValue(role_id_key, role_id)){ // set value -> yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/id
isError = true;
resobj.message = 'could not get role id(' + role_id_key + ') value, because failed to reset new role id instead of old id.';
}
}else{
isError = true;
resobj.message = 'could not get role id(' + role_id_key + ') value, or it is wrong value(' + JSON.stringify(role_id) + ').';
}
if(isError){
resobj.result = false;
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
// make token value
var now_unixtime = apiutil.getUnixtime();
var token_value = {};
token_value.role = role_key; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}"
token_value.date = (new Date(now_unixtime * 1000)).toISOString(); // now date(UTC ISO 8601)
token_value.expire = (new Date((now_unixtime + expire_limit) * 1000)).toISOString(); // expire date(UTC ISO 8601)
token_value.creator = keys.USER_KEY; // "yrn:yahoo::::user:<user>"
token_value.user = user; // user(creator)
token_value.hostname= null; // hostname(creator)
token_value.ip = null; // ip(creator)
token_value.port = 0; // port(creator)
token_value.cuk = null; // cuk(creator)
token_value.extra = null; // extra(creator)
token_value.tenant = tenant; // tenant(scope)
// role token and yrn key
var role_token = '';
var token_role_key = null;
// create key
for(var is_loop = true; is_loop; ){ // for eslint
// make role token
var token_elements = apiutil.makeStringToken256(user_id, role_id);
if(!apiutil.isSafeEntity(token_elements)){
resobj.result = false;
resobj.message = 'could not make token from ' + JSON.stringify(user_id) + ' and ' + JSON.stringify(role_id);
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
role_token = token_elements.str_token;
token_value.base = token_elements.str_base; // token base
// role token key
token_role_key = keys.TOKEN_ROLE_TOP_KEY + '/' + role_token; // "yrn:yahoo::::token:role/<role token>"
// get role token for existing check
var value = dkcobj.getValue(token_role_key, null, true, null);
if(!apiutil.isSafeEntity(value)){
// set value to role token
if(!dkcobj.setValue(token_role_key, JSON.stringify(token_value), null, null, expire_limit)){ // set token value -> yrn:yahoo::::token:role/<role token>
resobj.result = false;
resobj.message = 'could not set ' + JSON.stringify(token_value) + ' value to ' + token_role_key + ' key';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
break;
}else{
r3logger.dlog('conflict role token(' + role_token + ') which already is used, so remake token for uniq.');
}
}
// Add token to role token top key's subkey list
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.TOKEN_ROLE_TOP_KEY, true));
if(apiutil.tryAddStringToArray(subkeylist, token_role_key)){
if(!dkcobj.setSubkeys(keys.TOKEN_ROLE_TOP_KEY, subkeylist)){ // add subkey yrn:yahoo::::token:role/<role token> -> yrn:yahoo::::token:role
resobj.result = false;
resobj.message = 'could not add ' + token_role_key + ' subkey under ' + keys.TOKEN_ROLE_TOP_KEY + ' key';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
// Add token to role tokens key's subkey list
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(role_tokens_key, true));
if(apiutil.tryAddStringToArray(subkeylist, token_role_key)){
if(!dkcobj.setSubkeys(role_tokens_key, subkeylist)){ // add subkey yrn:yahoo::::token:role/<role token> -> yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/tokens
resobj.result = false;
resobj.message = 'could not add ' + token_role_key + ' subkey under ' + role_tokens_key + ' key';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
// Add role token into result object.
resobj.token = role_token;
dkcobj.clean();
return resobj;
}
//---------------------------------------------------------
// Get Role Token From ip address
//---------------------------------------------------------
// ip : ip address
// port : port number(0, undefined, null means any port)
// cuk : container unique key(undefined, null means any)
// tenant : tenant name
// role : target role name(full yrn or only role name)
// expire_limit : specify expire second(default 24H = 24 * 60 * 60 sec)
//
// result : {
// result: true/false
// message: null or error message string
// token: undefined(error) or role token string
// }
//
// [NOTE]
// set role token value is following
// {
// role: token's role yrn("yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}")
// date: create date(UTC ISO 8601)
// expire: expire date(UTC ISO 8601)
// creator: creator yrn("yrn:yahoo::::user:<user>" or "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/hosts/ip/<ip:port>")
// user: always null
// hostname: always null
// ip: if creator is host, this value is ip address.
// port: if creator is host, this value is port number.(if not, this is 0)
// cuk: if creator is host on iaas, this value is cuk.(allowed null)
// extra: if creator is host on iaas, this value is extra.(allowed null)
// tenant: tenant name for this role token(this mean token is scoped)
// base: 32bytes hex string
// }
//
// The role token which is built by host is made by only IP address.
// Hostname can not build a role token, because it is not secure.(= Hostname can easily be disguised.)
// Then only IP address can build a role token without UserToken.
//
function rawGetRoleTokenByIP(ip, port, cuk, tenant, role, expire_limit)
{
var resobj = {result: true, message: null};
if(!apiutil.isSafeStrings(tenant, role, ip)){ // allow other argument is empty
resobj.result = false;
resobj.message = 'some parameters are wrong : tenant=' + JSON.stringify(tenant) + ', role=' + JSON.stringify(role) + ', ip' + JSON.stringify(ip);
r3logger.elog(resobj.message);
return resobj;
}
if(!apiutil.isSafeString(ip)){
resobj.result = false;
resobj.message = 'ip parameter is empty.';
r3logger.elog(resobj.message);
return resobj;
}
if(!apiutil.isSafeEntity(port) || isNaN(port)){ // port must be number or null(undefined)
port = 0; // force set port 0(any).
}
if(!apiutil.isSafeString(cuk)){ // cuk is string if spacified
cuk = null; // force set null.
}
if(!apiutil.isSafeEntity(expire_limit) || isNaN(expire_limit)){ // expire_limit must be number or null(undefined)
expire_limit = expire_rtoken; // default 24H
}
// check role name is only name or full yrn path
var keys = r3keys(null, tenant);
role = role.toLowerCase();
var roleptn = new RegExp('^' + keys.MATCH_ANY_TENANT_ROLE); // regex = /^yrn:yahoo:(.*)::(.*):role:(.*)/
var rolematchs = role.match(roleptn);
if(apiutil.isEmptyArray(rolematchs) || rolematchs.length < 4){
// role is not matched role(maybe not full yrn), then we need check it is another yrn path
roleptn = new RegExp('^' + keys.NO_TENANT_KEY); // regex = /^yrn:yahoo:/
if(role.match(roleptn)){
resobj.result = false;
resobj.message = 'role(' + role + ') is not role yrn path)';
r3logger.elog(resobj.message);
return resobj;
}
// role is only role name, then we do not modify it.
}else{
// check tenant name
if(tenant !== rolematchs[2]){
resobj.result = false;
resobj.message = 'role(' + role + ') yrn has tenant(' + rolematchs[2] + '), but it is not specified tenant(' + tenant + ')';
r3logger.elog(resobj.message);
return resobj;
}
// role is set only role name
role = rolematchs[3];
}
var dkcobj = k2hr3.getK2hdkc(true, false); // use permanent object(need to clean)
var subkeylist;
if(!apiutil.isSafeEntity(dkcobj)){
resobj.result = false;
resobj.message = 'Not initialize yet.';
r3logger.elog(resobj.message);
return resobj;
}
//
// keys
//
var role_key = keys.ROLE_TOP_KEY + ':' + role; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}"
var role_id_key = role_key + '/' + keys.ID_KW; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/id"
var role_tokens_key = role_key + '/' + keys.ROLE_TOKEN_KW; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/tokens"
// find host key and get host id for base id
var host_info = k2hr3.findRoleHost(dkcobj, role_key, null, ip, port, cuk);
if(apiutil.isEmptyArray(host_info)){
resobj.result = false;
resobj.message = 'Not found ip(' + ip + ') with port(' + String(port) + ') and cuk(' + JSON.stringify(cuk) + ') in tenant(' + tenant + ') + role(' + role + ')';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
var host_value = null;
for(var pos = 0; pos < host_info.length; ++pos){
if(!apiutil.isSafeEntity(host_info[pos]) || !apiutil.isSafeString(host_info[pos].key)){
r3logger.dlog('Found ip(' + ip + ') with port(' + String(port) + ') in tenant(' + tenant + ') + role(' + role + '), but this host info(' + JSON.stringify(host_info[pos]) + ') is something wrong, skip it');
continue;
}
host_value = dkcobj.getValue(host_info[pos].key, null, true, null);
host_value = apiutil.parseJSON(host_value);
if( !apiutil.isSafeEntity(host_value) ||
(!apiutil.isSafeString(host_value.hostname) && !apiutil.isSafeString(host_value.ip)) || // hostname or ip is existed
!apiutil.isSafeEntity(host_value.port) ||
!apiutil.isSafeString(host_value[keys.ID_KW]) )
{
r3logger.dlog('Found ip(' + ip + ') with port(' + String(port) + ') in tenant(' + tenant + ') + role(' + role + '), but this host value(' + JSON.stringify(host_value) + ') is something wrong, skip it');
}else{
// found safe host info, we use this.
host_value.key = host_info[pos].key;
host_value.cuk = host_info[pos].cuk;
host_value.extra= host_info[pos].extra;
break;
}
host_value = null;
}
if(null === host_value){
resobj.result = false;
resobj.message = 'Found ip(' + ip + ') with port(' + String(port) + ') in tenant(' + tenant + ') + role(' + role + '), but there is not safe any host info';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
// role id
var role_id = dkcobj.getValue(role_id_key, null, true, null);
if(!apiutil.isSafeStrUuid4(role_id)){
var isError = false;
var old_role_id = apiutil.parseJSON(role_id);
if(!apiutil.isEmptyArray(old_role_id) && 4 == old_role_id.length){
// old version id, so reset new valus(UUID4) here.
role_id = apiutil.getStrUuid4();
if(!dkcobj.setValue(role_id_key, role_id)){ // set value -> yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/id
isError = true;
resobj.message = 'could not get role id(' + role_id_key + ') value, because failed to reset new role id instead of old id.';
}
}else{
isError = true;
resobj.message = 'could not get role id(' + role_id_key + ') value, or it is wrong value(' + JSON.stringify(role_id) + ').';
}
if(isError){
resobj.result = false;
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
// make token value
var now_unixtime = apiutil.getUnixtime();
var token_value = {};
token_value.role = role_key; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}"
token_value.date = (new Date(now_unixtime * 1000)).toISOString(); // now date(UTC ISO 8601)
token_value.expire = (new Date((now_unixtime + expire_limit) * 1000)).toISOString(); // expire date(UTC ISO 8601)
token_value.creator = host_value.key; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/hosts/ip/<ip:port>"
token_value.user = null; // user(creator)
token_value.hostname= null; // hostname(null)
token_value.ip = host_value.ip; // ip(creator)
token_value.port = host_value.port; // port(creator)
token_value.cuk = host_value.cuk; // cuk(creator)
token_value.extra = host_value.extra; // extra(creator)
token_value.tenant = tenant; // tenant(scope)
// role token and yrn key
var role_token = '';
var token_role_key = null;
// create key
for(var is_loop = true; is_loop; ){ // for eslint
// make role token
var token_elements = apiutil.makeStringToken256(host_value[keys.ID_KW], role_id);
if(!apiutil.isSafeEntity(token_elements)){
resobj.result = false;
resobj.message = 'could not make token from ' + JSON.stringify(host_value[keys.ID_KW]) + ' and ' + JSON.stringify(role_id);
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
role_token = token_elements.str_token;
token_value.base = token_elements.str_base; // token base
// role token key
token_role_key = keys.TOKEN_ROLE_TOP_KEY + '/' + role_token; // "yrn:yahoo::::token:role/<role token>"
// get role token for existing check
var value = dkcobj.getValue(token_role_key, null, true, null);
if(!apiutil.isSafeEntity(value)){
// set value to role token
if(!dkcobj.setValue(token_role_key, JSON.stringify(token_value), null, null, expire_limit)){ // set token value -> yrn:yahoo::::token:role/<role token>
resobj.result = false;
resobj.message = 'could not set ' + JSON.stringify(token_value) + ' value to ' + token_role_key + ' key';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
break;
}else{
r3logger.dlog('conflict role token(' + role_token + ') which already is used, so remake token for uniq.');
}
}
// Add token to role token top key's subkey list
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.TOKEN_ROLE_TOP_KEY, true));
if(apiutil.tryAddStringToArray(subkeylist, token_role_key)){
if(!dkcobj.setSubkeys(keys.TOKEN_ROLE_TOP_KEY, subkeylist)){ // add subkey yrn:yahoo::::token:role/<role token> -> yrn:yahoo::::token:role
r3logger.elog('could not add ' + token_role_key + ' subkey under ' + keys.TOKEN_ROLE_TOP_KEY + ' key');
dkcobj.clean();
return resobj;
}
}
// Add token to role tokens key's subkey list
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(role_tokens_key, true));
if(apiutil.tryAddStringToArray(subkeylist, token_role_key)){
if(!dkcobj.setSubkeys(role_tokens_key, subkeylist)){ // add subkey yrn:yahoo::::token:role/<role token> -> yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/tokens
resobj.result = false;
resobj.message = 'could not add ' + token_role_key + ' subkey under ' + role_tokens_key + ' key';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
// Add role token into result object.
resobj.token = role_token;
dkcobj.clean();
return resobj;
}
//---------------------------------------------------------
// Remove Role Token by User/IP
//---------------------------------------------------------
// token : role token
// user : this value is parsed from user token(or null)
// tenant : this value is parsed from user token(or null)
// ip : client ip address(or null)
// port : port number when ip address parameter exists
// cuk : cuk value when ip address parameter exists
//
// result : {
// result: true/false
// message: null or error message string
// }
//
function rawRemoveRoleToken(token, user, tenant, ip, port, cuk)
{
var resobj = {result: true, message: null};
if(!apiutil.isSafeString(token)){ // allow other argument is empty
resobj.result = false;
resobj.message = 'token parameter is empty';
r3logger.elog(resobj.message);
return resobj;
}
if( (apiutil.isSafeString(ip) && (apiutil.isSafeString(user) || apiutil.isSafeString(tenant))) ||
(!apiutil.isSafeString(ip) && (!apiutil.isSafeString(user) || !apiutil.isSafeString(tenant))) )
{
resobj.result = false;
resobj.message = 'tenant(' + JSON.stringify(tenant) + '), user(' + JSON.stringify(user) + '), ip(' + JSON.stringify(ip) + ') parameters are wrong pattern.';
r3logger.elog(resobj.message);
return resobj;
}
var dkcobj = k2hr3.getK2hdkc(true, false); // use permanent object(need to clean)
var subkeylist;
var value;
if(!apiutil.isSafeEntity(dkcobj)){
resobj.result = false;
resobj.message = 'Not initialize yet.';
r3logger.elog(resobj.message);
return resobj;
}
//
// keys
//
var keys = (apiutil.isSafeString(ip) ? r3keys() : r3keys(user, tenant));
var role_token_key = keys.TOKEN_ROLE_TOP_KEY + '/' + token; // "yrn:yahoo::::token:role/<role token>"
// get role token value
value = dkcobj.getValue(role_token_key, null, true, null);
value = apiutil.parseJSON(value);
if(!apiutil.isSafeEntity(value)){
// already role token is removed or expired.
r3logger.dlog('could not get role token(' + role_token_key + ') value, or it is wrong value(' + JSON.stringify(value) + '). We check all role token for expire here.');
dkcobj.clean();
//
// check and remove old role token under token top key("yrn:yahoo::::token:role") if old token is expired
//
// [NOTE]
// This processing is taking time, so it runs asynchronously.
// And for notes on this processing, refer to NOTE of rawCleanupRoleToken function.
//
rawCleanupRoleToken(function(result)
{
if(!result){
r3logger.wlog('Failed to cleanup expired role tokens under ' + keys.TOKEN_ROLE_TOP_KEY + ' key, but continue...');
}
});
// return success
return resobj;
}
// check token value
if( !apiutil.isSafeString(value.role) ||
!apiutil.isSafeString(value.date) ||
!apiutil.isSafeString(value.expire) ||
!apiutil.isSafeString(value.creator) ||
(!apiutil.isSafeString(value.user) && !apiutil.isSafeString(value.hostname) && !apiutil.isSafeString(value.ip)) ||
isNaN(value.port) ||
!apiutil.isSafeString(value.tenant) ||
!apiutil.isSafeString(value.base) )
{
//
// Not check expired token and ip address is empty here.
//
resobj.result = false;
resobj.message = 'could not get role token(' + role_token_key + ') value, or it is wrong value(' + JSON.stringify(value) + ').';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
// check expire
if(apiutil.isExpired(value.expire)){
resobj.result = false;
resobj.message = 'role token(' + role_token_key + ') is expired by expire date(' + value.expire + ').';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
// keep role tokens key for removing key in its subkey list.
var role_tokens_key = value.role + '/' + keys.ROLE_TOKEN_KW; // "yrn:yahoo:<service>::<tenant>:role:<role>{/<role>{...}}/tokens"
// check requester
if(apiutil.isSafeString(ip)){
// check ip address bases
//
// port
if(!isNaN(port)){
port = parseInt(port);
}else{
port = 0;
}
// cuk
if(apiutil.isSafeString(cuk) && apiutil.isSafeString(cuk.trim())){
cuk = cuk.trim();
}else{
cuk = null;
}
// check
if( value.port != port ||
apiutil.isSafeString(value.cuk) != apiutil.isSafeString(cuk) ||
(apiutil.isSafeString(value.cuk) && value.cuk != cuk) )
{
resobj.result = false;
resobj.message = 'could not remove role token(' + token + '), because port(' + JSON.stringify(port) + ' vs ' + JSON.stringify(value.port) + ')/cuk(' + JSON.stringify(cuk) + ' vs