UNPKG

access-manager

Version:

A one-stop solution for implementing authenticated and anonymous continuous sessions with user handling and whitelisted acl.

63 lines (56 loc) 1.8 kB
module.exports = class Acl{ constructor(settings){ this.AclModel = settings.model; return async (...args) => await this.acl(...args); } async acl(req, res, next){ let roles = ['*']; // everyone always has the "*" (all) role // pick roles from session uses if(req.user._id){ roles = [...roles, ...req.user.roles]; // concat in the user roles (using spread operator) }else{ // add the non-authenticated role roles.push('anonymous'); } // find ACL paths that maches roles let entries = await this.AclModel.find({ //path: req.path, 'roles.role':{$in: roles} }); // new section to handle wildcard paths endings // (would have prefered a good regex mongoose query) entries = entries.filter( e => { // check for match with wildcard if(e.path.indexOf('*') == e.path.length - 1){ // wildcard end return req.path.indexOf(e.path.split('*')[0]) > -1; }else{ // find exact match return e.path == req.path; } }); // now, do we have the proper method in any of our matched role(s) let remaining = []; for(let entry of entries){ let remRoles = entry.roles.filter(role => { if(role.methods.includes('*') || role.methods.includes('ALL')){ return true; } return role.methods.includes(req.method) }); // console.log('path', req.path, 'req.method', req.method); // console.log('remRoles', remRoles); // console.log('req.user.roles', req.user.roles); if(remRoles.length > 0){ remaining.push(entry); } } if(remaining.length > 0){ // pass! next(); } else{ // reject! (we are not allowed here) res.status(403); res.send('Forbidden'); } } }