From 9ac6b4ebb051cf10c624706a26f1ebd6457e0845 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 | 28 +++-- .../web/api/configServer.main.api.js | 100 ++++++++++++++---- src/tools/cutils.js | 3 - webroot/js/contrail-common.js | 4 - 5 files changed, 111 insertions(+), 40 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 39f1df12f..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,16 +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']; - if (null != req.session.userRoles[cookieProject]) { - if ((-1 == req.session.userRoles[cookieProject].indexOf('admin')) && - (null != req.cookies.project)) { - cookieProject = null; - } + 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 + @@ -254,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){