Skip to content

Commit

Permalink
Merge pull request #77 from fkovinAtRocket/feature/RBAC
Browse files Browse the repository at this point in the history
Feature/rbac
  • Loading branch information
1000TurquoisePogs authored Mar 28, 2019
2 parents ddf3462 + 3d5ad3e commit 5ea953c
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 73 deletions.
80 changes: 9 additions & 71 deletions lib/auth-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,14 @@ function AuthManager(options) {
handlers: {},
defaultType: options.config.defaultAuthentication,
authTypes: {},
pendingPlugins: []
pendingPlugins: [],
rbacEnabled: !!options.config.rbac
});
if (!this.rbacEnabled) {
bootstrapLogger.warn('RBAC is disabled in the configuration. All authenticated'
+ ' users will have access to all servces. Enable RBAC in the configuration'
+ " to control users' access to individual services");
}
}
AuthManager.prototype = {
constructor: AuthManager,
Expand Down Expand Up @@ -173,76 +179,8 @@ AuthManager.prototype = {
return this.getBestAuthenticationHandler(authType);
},

// /*
// * a system could specifically allow a resource, or could allow a group of
// * resources in glob format.
// */
// checkAuthorization: Promise.coroutine(function*(username, resourceName,
// serviceConfig) {
// const authHandler = getAuthHandlerForService(serviceConfig);
// if (!authHandler) {
// return { authorized: false, status:
// 'Authentication failed because type=' + authType + ' is missing'
// };
// }
// for (const resourceNameCheck of possibleResourceNameMasks(resourceName)) {
// authLog.debug('authorize is looping with resourceNameCheck='
// + resourceNameCheck);
// const authResult = yield authHandler.authorized(serviceConfig, username,
// resourceNameCheck);
// if (authResult.authorized) {
// authLog.log(authLog.FINEST, 'Authorization success for resource='
// + resourceNameCheck + ', username=' + username);
// return { authorized: true };
// }
// }
// return { authorized: false, status:
// 'Authorization failure for resource=' + resourceName + ', username='
// + username
// };
// })
};

/*
* The next two functions are RACF-specific
*
* TODO consider moving them to a RACF auth plugin
*/
AuthManager.getResourceName = function getResourceName(url, method) {
const [_l, productCode, _p, pluginID, _s, serviceName, ...subUrl]
= url.split('/');
let resourceName = `${productCode}.${pluginID}_service.${serviceName}.`
+ `${method}.${subUrl.join('.')}`;
if (resourceName.endsWith('.')) {
resourceName = resourceName.substring(0, resourceName.length-1);
}
//console.log("url, method, resource name:", url, method, resourceName);
return resourceName;
};

/**
* iterator usage example:
*
* for (const resourceNameMask of AuthManager.possibleResourceNameMasks(
* resourceName)) {
* ...
* check(resourceNameMask)
* ...
* }
*/
AuthManager.possibleResourceNameMasks = function *possibleResourceNameMasks(
resourceName) {
const resourceNameParts = resourceName.split('.');
let resourceNameCheck = resourceName;
yield resourceNameCheck;
for (let resourceNamePart of resourceNameParts) {
if (resourceNameCheck == resourceName) {
resourceNameCheck = resourceNamePart + '.*';
} else {
resourceNameCheck = resourceNameCheck.substring(0,
resourceNameCheck.length - 1) + resourceNamePart + '.*';
}
yield resourceNameCheck;
isRbacEnabled() {
return this.rbacEnabled;
}
};

Expand Down
3 changes: 3 additions & 0 deletions lib/webapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ const commonMiddleware = {
}
appData.webApp.callRootService = function callRootService(name, url,
options) {
if (!this.rootServices[name]) {
throw new Error(`root service ${name} not found`);
}
return this.rootServices[name].call(url, options, req);
}
if (!appData.plugin) {
Expand Down
8 changes: 6 additions & 2 deletions lib/webauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ module.exports = function(authManager) {

middleware: Promise.coroutine(function*(req, res, next) {
try {
if (req.url.endsWith(".websocket") && (res._header == null)) {
const isWebsocket = req.url.endsWith(".websocket");
if (isWebsocket && (res._header == null)) {
//workaround for https://github.com/HenningM/express-ws/issues/64
//copied from https://github.com/HenningM/express-ws/pull/92
//TODO remove this once that bug is fixed
Expand All @@ -248,7 +249,10 @@ module.exports = function(authManager) {
}
const authPluginID = handler.pluginID;
const authPluginSession = getAuthPluginSession(req, authPluginID, {});
const result = yield handler.authorized(req, authPluginSession);
const result = yield handler.authorized(req, authPluginSession, {
syncOnly: isWebsocket,
bypassAuthorizatonCheck: !authManager.isRbacEnabled()
});
//we only care if its authorized
if (!result.authorized) {
const errorResponse = {
Expand Down
6 changes: 6 additions & 0 deletions plugins/terminal-proxy/lib/terminalProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,20 @@ function TerminalWebsocketProxy(messageConfig, clientIP, context, websocket, han

websocket.on('message',(msg)=>{t.handleWebsocketMessage(msg);});
websocket.on('close',(code,reason)=>{t.handleWebsocketClosed(code,reason);});
websocket.on('error', (error) => {
/* TODO handle the error, close the host connection, etc */
t.logger.warn("websocket error", error)
});

t.configured = true;
}
else {
/* TODO any cleanup needed? close the client websocket? */
this.logger.warn('Terminal websocket proxy was not supplied with valid message config description');
}
}
else {
/* TODO any cleanup needed? close the client websocket? */
this.logger.warn('Terminal websocket proxy was not supplied with valid message config description');
}
}
Expand Down

0 comments on commit 5ea953c

Please sign in to comment.