UNPKG

@webgap/authorization-utils

Version:

WebGAP authorization module for express routes using Role-based Access Control - RBAC.

118 lines (110 loc) 3.64 kB
/** * (C) Copyright 2014 WebGAP (http://www.webgap.eu/). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Created by: ManuelMartins * Created on: 07-08-2014 * */ "use strict"; var Roles = require('./lib/Roles'); var notifier = require('@webgap/notifier'); /** * Express.js Middleware * Handles authorization on express routes using Role-based Access Control - RBAC * * Built to use with Passport. 'req._passport.session.user' is expected * * A user must contain a list of roles. A set of Roles is available Notifier.Role: USER, PROVIDER, ADMIN * * Usage: * router.get('/admin', isAuthorized(['admin']), function (req, res) { * res.render('backend/admin/admin.html', template.generate(req)); * }); * * @param {Object} options * @param {Object} options.notifier * @param {string} options.unauthorizedURL defaults to '/unauthorized' * @param {string} options.loginURL defaults to '/auth/login' * @param {string} options.unauthenticatedMessageKey defaults to 'messages.warning.authentication-required' * @param {string} options.unauthorizedMessageKey defaults to 'messages.error.authorization-required' * @constructor */ function Authorizator(options) { options = options || {}; this.notifier = options.notifier || notifier; this.unauthorizedURL = options.unauthorizedURL || '/unauthorized'; this.loginURL = options.loginURL || '/auth/login'; this.unauthenticatedMessageKey = options.unauthenticatedMessageKey || 'messages.warning.authentication-required'; this.unauthorizedMessageKey = options.unauthorizedMessageKey || 'messages.error.authorization-required'; } /** * Checks whether a user with a specific role is authorized or not to access a route suitable for Expressjs * * @param roles */ Authorizator.prototype.isAuthorized = function isAuthorized(roles) { var self = this; return function authorizationMiddleware(req, res, next) { if (!req._passport.session || !req._passport.session.user) { return handleRedirect(req, res, notifier, self.unauthenticatedMessageKey, self.loginURL); } else if (!self.hasAccess(req.user, roles)) { return handleRedirect(req, res, notifier, self.unauthorizedMessageKey, self.unauthorizedURL); } else { return next(); } }; }; /** * Hanldles redirect on error * * @param {object} req * @param {object} res * @param {object} notifier * @param {string} messageKey * @param {string} url * */ function handleRedirect(req, res, notifier, messageKey, url) { notifier.notify({ notification: { request: req, message: messageKey } }, function afterNotify(err) { if (err) { console.warn('Notifier module error. \n%s', err); } res.redirect(url); }); } /** * Returns true if an User has a specific role or roles * * @param user * @param roles * @returns {boolean} */ Authorizator.prototype.hasAccess = function hasAccess(user, roles) { if (!roles || !user || !user.roles) { return false; } return roles.some(function(element) { return user.roles.indexOf(element) >= 0; }); }; module.exports = Authorizator; module.exports.Role = Roles;