From ecefb213eebf272c58af454a3edbf1ba1b527f3f Mon Sep 17 00:00:00 2001 From: Biswajit Mandal Date: Fri, 12 Feb 2016 04:38:52 +0530 Subject: [PATCH] Related-Bug: #1544947 Currently Contrail WebUI checks for admin only role for all projects assigned to a user at login time. Instead of checking all projects at login time, only check the assigned project for admin only role and disallow login if user doesn't have admin only role in the assigned project. RBAC is not supported by Contrail WebUI, member only projects cannot be used with Contrail UI. At time of login, catalog response may contain high number of endpoints. Discard this data. Change-Id: I33c7370c4918f4bf1238bdb8c81ac3ddf8d4790b --- .../plugins/openstack/keystone.api.js | 16 ++- .../orchestration/plugins/plugins.api.js | 32 +++--- .../web/api/configServer.main.api.js | 100 ++++++++++++++---- src/tools/cutils.js | 3 - webroot/js/contrail-common.js | 4 - 5 files changed, 111 insertions(+), 44 deletions(-) diff --git a/src/serverroot/orchestration/plugins/openstack/keystone.api.js b/src/serverroot/orchestration/plugins/openstack/keystone.api.js index 5048f2fe9..8a35332fd 100644 --- a/src/serverroot/orchestration/plugins/openstack/keystone.api.js +++ b/src/serverroot/orchestration/plugins/openstack/keystone.api.js @@ -897,7 +897,7 @@ function getUIUserRoleByTenant (userObj, callback) return; } roles = getUIRolesByExtRoles(data['roles']); - callback(null, roles); + callback(null, roles, data); }); } @@ -1054,6 +1054,20 @@ function authenticate (req, res, appData, callback) }); return; } + var multiTenancyEnabled = commonUtils.isMultiTenancyEnabled(); + if ((true == multiTenancyEnabled) && + (false == isAdminRoleInProjects(req.session.userRoles))) { + /* Logged in user is not admin in multi_tenancy mode, + so redirect to login page + */ + errStr = "User with admin only role is allowed"; + commonUtils.changeFileContentAndSend(res, loginErrFile, + global.CONTRAIL_LOGIN_ERROR, + errStr, function() { + }); + return; + } + plugins.setAllCookies(req, res, appData, {'username': username}, function() { if(urlPath != '') res.redirect(urlPath + urlHash); diff --git a/src/serverroot/orchestration/plugins/plugins.api.js b/src/serverroot/orchestration/plugins/plugins.api.js index f5e23ab7c..949323fb5 100644 --- a/src/serverroot/orchestration/plugins/plugins.api.js +++ b/src/serverroot/orchestration/plugins/plugins.api.js @@ -198,16 +198,29 @@ function setAllCookies (req, res, appData, cookieObj, callback) { var loginErrFile = 'webroot/html/login-error.html'; var multiTenancyEnabled = commonUtils.isMultiTenancyEnabled(); + var adminProjectList = getAdminProjectList(req); if (null == appData['authObj']['defTokenObj']) { /* We have not got defTokenObj filled yet while sending to Auth * Module, so fill it up here */ - var adminProjectList = getAdminProjectList(req); /* adminProjectList must not empty array */ if (adminProjectList.length) { appData['authObj']['defTokenObj'] = req.session.tokenObjs[adminProjectList[0]]['token']; } else { + /* Check if multi_tenancy enabled */ + if (true == multiTenancyEnabled) { + /* We should not come here, multi_tenancy enabled, why we came + * here still + */ + logutils.logger.error("User with admin only role is allowed!!!"); + errStr = "User with admin only role is allowed"; + commonUtils.changeFileContentAndSend(res, loginErrFile, + global.CONTRAIL_LOGIN_ERROR, + errStr, function() { + }); + return; + } var tokenObjs = req.session.tokenObjs; for (key in tokenObjs) { appData['authObj']['defTokenObj'] = @@ -230,20 +243,13 @@ function setAllCookies (req, res, appData, cookieObj, callback) res.setHeader('Set-Cookie', 'domain=' + cookieObjs['domain'] + '; expires=' + cookieExpStr + secureCookieStr); } - /* Do not set cookie if project has member role */ var cookieProject = cookieObjs['project']; - try { - if (null != req.session.userRoles[cookieProject]) { - if ((-1 == req.session.userRoles[cookieProject].indexOf('admin')) && - (null != req.cookies.project)) { - cookieProject = null; - } - } - } catch(e) { - logutils.logger.error('setAllCookies parse error' + e); + if ((null == cookieProject) || + (-1 == adminProjectList.indexOf(cookieProject))) { + cookieProject = adminProjectList[0]; } if (null != cookieProject) { - res.setHeader('Set-Cookie', 'project=' + cookieObjs['project'] + + res.setHeader('Set-Cookie', 'project=' + cookieProject + '; expires=' + cookieExpStr + secureCookieStr); } res.setHeader('Set-Cookie', '_csrf=' + req.session._csrf + @@ -258,4 +264,4 @@ exports.setAllCookies = setAllCookies; exports.doDomainExist = doDomainExist; exports.formatDomainList = formatDomainList; exports.getDomainFqnByDomainUUID = getDomainFqnByDomainUUID; - +exports.getAdminProjectList = getAdminProjectList; diff --git a/src/serverroot/web/api/configServer.main.api.js b/src/serverroot/web/api/configServer.main.api.js index 8cb08127e..bf5df749b 100644 --- a/src/serverroot/web/api/configServer.main.api.js +++ b/src/serverroot/web/api/configServer.main.api.js @@ -41,45 +41,95 @@ function getDefProjectByAppData (appData) return defProject; } -function getAuthTokenByProject (req, defTokenObj, project) +function getAuthTokenByProject (req, defTokenObj, project, callback) { if ((null != req.session.tokenObjs[project]) && (null != req.session.tokenObjs[project]['token']) && (null != req.session.tokenObjs[project]['token']['id'])) { - return {'project': project, - 'token': req.session.tokenObjs[project]['token']['id']}; + callback(null, {'project': project, + 'token': req.session.tokenObjs[project]['token']['id']}); + return; } var defProject = commonUtils.getValueByJsonPath(defTokenObj, 'tenant;name', null); - return {'project': defProject, 'token': defTokenObj['id']}; + var defTokenId = + commonUtils.getValueByJsonPath(defTokenObj, 'id', null); + var plugins = require('./../../orchestration/plugins/plugins.api'); + var adminProjList = plugins.getAdminProjectList(req); + if ((null == adminProjList) ||(!adminProjList.length)) { + callback(null, {'project': defProject, 'token': defTokenId}); + return; + } + var tokenObjs = req.session.tokenObjs; + var tokenId = null; + for (key in tokenObjs) { + if (-1 != adminProjList.indexOf(key)) { + tokenId = + commonUtils.getValueByJsonPath(tokenObjs[key], + 'token;id', null); + break; + } + } + if (null == tokenId) { + tokenId = + commonUtils.getValueByJsonPath(tokenObjs[key], + 'token;id', null); + if (null == tokenId) { + callback(null, {'project': defProject, 'token': defTokenId}); + return; + } + } + + var userObj = {'tokenid': tokenId, 'tenant': project, 'req': req}; + authApi.getUIUserRoleByTenant(userObj, function(err, roles, data) { + if (null == data) { + callback(null, {'project': defProject, 'token': defTokenId}); + return; + } + var tokenObj = data['tokenObj']; + if ((null != err) || (null == tokenObj) || + (null == tokenObj['token']) || (null == tokenObj['token']['id']) || + (null == tokenObj['token']['tenant'])) { + callback(null, {'project': defProject, 'token': defTokenId}); + return; + } + callback(null, {'project': tokenObj['token']['tenant']['name'], + 'token': tokenObj['token']['id']}); + }); } -function configAppHeaders (headers, appData) +function configAppHeaders (headers, appData, callback) { var defProject = getDefProjectByAppData(appData); var multiTenancyEnabled = commonUtils.isMultiTenancyEnabled(); var xAuthTokenObj = null; - try { - var xAuthTokenObj = - getAuthTokenByProject(appData['authObj'].req, - appData['authObj']['defTokenObj'], - defProject); + if ((null == appData) || (null == appData['authObj'].req) || + (null == appData['authObj']['defTokenObj'])) { + headers['X-Auth-Token'] = null; + headers['X_API_ROLE'] = null; + callback(headers); + return; + } + getAuthTokenByProject(appData['authObj'].req, + appData['authObj']['defTokenObj'], + defProject, function(err, xAuthTokenObj) { headers['X-Auth-Token'] = xAuthTokenObj['token']; if (true == multiTenancyEnabled) { - if (null != xAuthTokenObj['project']) { - headers['X_API_ROLE'] = - appData['authObj'].req.session.userRoles[xAuthTokenObj['project']].join(','); - } else { + try { + if (null != xAuthTokenObj['project']) { + headers['X_API_ROLE'] = + appData['authObj'].req.session.userRoles[xAuthTokenObj['project']].join(','); + } else { + headers['X_API_ROLE'] = null; + } + } catch(e) { headers['X_API_ROLE'] = null; } } - } catch(e) { - headers['X-Auth-Token'] = null; - headers['X_API_ROLE'] = null; - } - return headers; + callback(headers); + }); } function apiGet (reqUrl, appData, callback, appHeaders, stopRetry) @@ -89,7 +139,7 @@ function apiGet (reqUrl, appData, callback, appHeaders, stopRetry) var multiTenancyEnabled = commonUtils.isMultiTenancyEnabled(); var defProject = getDefProjectByAppData(appData); - headers = configAppHeaders(headers, appData); + configAppHeaders(headers, appData, function(headers) { headers = getHeaders(headers, appHeaders); configServer.api.get(reqUrl, function(err, data) { if (err) { @@ -105,6 +155,7 @@ function apiGet (reqUrl, appData, callback, appHeaders, stopRetry) callback(null, data); } }, headers); + }); } function apiPut (reqUrl, reqData, appData, callback, appHeaders, stopRetry) @@ -114,7 +165,7 @@ function apiPut (reqUrl, reqData, appData, callback, appHeaders, stopRetry) var multiTenancyEnabled = commonUtils.isMultiTenancyEnabled(); var defProject = getDefProjectByAppData(appData); - headers = configAppHeaders(headers, appData); + configAppHeaders(headers, appData, function(headers) { headers = getHeaders(headers, appHeaders); configServer.api.put(reqUrl, reqData, function(err, data) { @@ -131,6 +182,7 @@ function apiPut (reqUrl, reqData, appData, callback, appHeaders, stopRetry) callback(null, data); } }, headers); + }); } function apiPost (reqUrl, reqData, appData, callback, appHeaders, stopRetry) @@ -140,7 +192,7 @@ function apiPost (reqUrl, reqData, appData, callback, appHeaders, stopRetry) var multiTenancyEnabled = commonUtils.isMultiTenancyEnabled(); var defProject = getDefProjectByAppData(appData); - headers = configAppHeaders(headers, appData); + configAppHeaders(headers, appData, function(headers) { headers = getHeaders(headers, appHeaders); configServer.api.post(reqUrl, reqData, function(err, data) { @@ -157,6 +209,7 @@ function apiPost (reqUrl, reqData, appData, callback, appHeaders, stopRetry) callback(null, data); } }, headers); + }); } function apiDelete (reqUrl, appData, callback, appHeaders, stopRetry) @@ -166,7 +219,7 @@ function apiDelete (reqUrl, appData, callback, appHeaders, stopRetry) var multiTenancyEnabled = commonUtils.isMultiTenancyEnabled(); var defProject = getDefProjectByAppData(appData); - headers = configAppHeaders(headers, appData); + configAppHeaders(headers, appData, function(headers) { headers = getHeaders(headers, appHeaders); configServer.api.delete(reqUrl, function(err, data) { @@ -183,6 +236,7 @@ function apiDelete (reqUrl, appData, callback, appHeaders, stopRetry) callback(null, data); } }, headers); + }); } exports.apiGet = apiGet; diff --git a/src/tools/cutils.js b/src/tools/cutils.js index e87146428..f49dc7e1e 100644 --- a/src/tools/cutils.js +++ b/src/tools/cutils.js @@ -24,9 +24,6 @@ function setCookie(name, value) { var oldCookie = getCookie(name); document.cookie = name + "=" + escape(value) + "; expires=Sun, 17 Jan 2038 00:00:00 UTC; path=/"; - if (('project' == name) && (oldCookie != value)) { - menuHandler.loadMenu(); - } } var class_A = 1; diff --git a/webroot/js/contrail-common.js b/webroot/js/contrail-common.js index d4bdc3fa3..14f52ddff 100644 --- a/webroot/js/contrail-common.js +++ b/webroot/js/contrail-common.js @@ -178,7 +178,6 @@ function Contrail() { }; this.setCookie = function(name, value) { - var oldCookie = contrail.getCookie(name); var secureCookieStr = ""; var insecureAccess = getValueByJsonPath(globalObj, 'webServerInfo;insecureAccess', @@ -189,9 +188,6 @@ function Contrail() { document.cookie = name + "=" + escape(value) + "; expires=Sun, 17 Jan 2038 00:00:00 UTC; path=/" + secureCookieStr; - if (('project' == name) && (oldCookie != value)) { - menuHandler.loadMenu(); - } }; this.formatJSON2HTML = function(json, formatDepth){