Skip to content

Commit

Permalink
Related-Bug: #1544947
Browse files Browse the repository at this point in the history
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
  • Loading branch information
biswajit-mandal committed Feb 12, 2016
1 parent 25751c3 commit ecefb21
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 44 deletions.
16 changes: 15 additions & 1 deletion src/serverroot/orchestration/plugins/openstack/keystone.api.js
Expand Up @@ -897,7 +897,7 @@ function getUIUserRoleByTenant (userObj, callback)
return;
}
roles = getUIRolesByExtRoles(data['roles']);
callback(null, roles);
callback(null, roles, data);
});
}

Expand Down Expand Up @@ -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);
Expand Down
32 changes: 19 additions & 13 deletions src/serverroot/orchestration/plugins/plugins.api.js
Expand Up @@ -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'] =
Expand All @@ -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 +
Expand All @@ -258,4 +264,4 @@ exports.setAllCookies = setAllCookies;
exports.doDomainExist = doDomainExist;
exports.formatDomainList = formatDomainList;
exports.getDomainFqnByDomainUUID = getDomainFqnByDomainUUID;

exports.getAdminProjectList = getAdminProjectList;
100 changes: 77 additions & 23 deletions src/serverroot/web/api/configServer.main.api.js
Expand Up @@ -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)
Expand All @@ -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) {
Expand All @@ -105,6 +155,7 @@ function apiGet (reqUrl, appData, callback, appHeaders, stopRetry)
callback(null, data);
}
}, headers);
});
}

function apiPut (reqUrl, reqData, appData, callback, appHeaders, stopRetry)
Expand All @@ -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) {
Expand All @@ -131,6 +182,7 @@ function apiPut (reqUrl, reqData, appData, callback, appHeaders, stopRetry)
callback(null, data);
}
}, headers);
});
}

function apiPost (reqUrl, reqData, appData, callback, appHeaders, stopRetry)
Expand All @@ -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) {
Expand All @@ -157,6 +209,7 @@ function apiPost (reqUrl, reqData, appData, callback, appHeaders, stopRetry)
callback(null, data);
}
}, headers);
});
}

function apiDelete (reqUrl, appData, callback, appHeaders, stopRetry)
Expand All @@ -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) {
Expand All @@ -183,6 +236,7 @@ function apiDelete (reqUrl, appData, callback, appHeaders, stopRetry)
callback(null, data);
}
}, headers);
});
}

exports.apiGet = apiGet;
Expand Down
3 changes: 0 additions & 3 deletions src/tools/cutils.js
Expand Up @@ -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;
Expand Down
4 changes: 0 additions & 4 deletions webroot/js/contrail-common.js
Expand Up @@ -178,7 +178,6 @@ function Contrail() {
};

this.setCookie = function(name, value) {
var oldCookie = contrail.getCookie(name);
var secureCookieStr = "";
var insecureAccess =
getValueByJsonPath(globalObj, 'webServerInfo;insecureAccess',
Expand All @@ -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){
Expand Down

0 comments on commit ecefb21

Please sign in to comment.