OptimalBits / node_acl

Access control lists for node applications
2.62k stars 369 forks source link

static path #197

Closed Wuntenn closed 8 years ago

Wuntenn commented 8 years ago

I have some express static routes (resources) that I would like to restrict access to. I'm trying to use the acl with no luck so far.

Are you guys able to advise me if this is possible or if not do you know of a robust solution similar to this one that would allow me to do this?

akaustel commented 8 years ago

I use node_acl without express, but you can check the code in lib/acl.js. Search for middleware, and you find the implementation which checks for permissions. You can write an own version of it if it does not solve your problem out of the box.

Wuntenn commented 8 years ago

Hey thanks @akaustel, I'm now reading through the code. I must be doing things wrong. I was getting warnings about expecting middleware whilst getting a function instead.

I'm gonna have another crack at it.

akaustel commented 8 years ago

Middleware in express are javascript functions, see: https://expressjs.com/en/guide/writing-middleware.html. You can always add some debug output to the middleware code to see what it does. Let me know how it turned out.

Wuntenn commented 8 years ago

Hey thanks @akaustel. I've been learning MEAN through use of MEANJS. I'm fine with middleware when using express's route method via app.route. Middleware seem easier to reason with when used that way because I can add new ones into the chain.

Its just that express's use method works slightly differently. I've read in the docs that it's just a mount point, however mount-point and routes to me don't seem to have many differences.

I need to protect some static routes that are currently created usingapp.use in conjunction with express.static. I'm not 100% sure if I can chain further middleware to the one returned by express.static (before applying it to the mount path) or if I will have to do multiple calls.

app.use doesn't chain so i'm a little out of my comfort-zone. I suspect that I introduced some human-error into the mix as well for enjoyment.

akaustel commented 8 years ago

Hi @Wuntenn! Did you get your problem solved?

Wuntenn commented 8 years ago

Hey thanks for checking @akaustel,

I opened a pandora! I hadn't been keeping up-to-date with upstream. My code has diverged quite a bit. When I updated... 😢 😭 😭 😪

I'm now hopefully close to the point where I can tackle the acl once again. If it would help with the queue, I can close this issue and re-open it if I still have problems.

akaustel commented 8 years ago

Oh, no! Hope you get back on track. Closing this one sounds good, if you think this is not actually a problem due to node_acl. Of course you should open a new issue with a fresh description on any new problem you encounter.

Wuntenn commented 8 years ago

Yay!!! All sorted!!

I managed to protect the static files. I was looking though a few of the issues and I saw some that mentioned the ability to specify a regex to match resources.

I'm currently listing the resources long-hand, however I can see this getting tedious. Although I understand (from an issue comment) that this may open vulnerabilities, I just wanted to know if this is possible?

Thanks for helping @manast - appreciated. I'll close the issue

akaustel commented 8 years ago

@Wuntenn if you have some time to spare, it would be nice to have some solution linked or posted here in case someone has a similar problem. Great that you got it working!

Wuntenn commented 8 years ago

I've stolen this code from meanjs as an example:

var acl = require('acl');

// Using the memory backend
acl = new acl(new acl.memoryBackend());

/**
 * Invoke Admin Permissions
 */
exports.invokeRolesPolicies = function () {
  acl.allow([{
    roles: ['admin'],
    allows: [{
      resources: '/api/users',
      permissions: '*'
    }, {
      resources: [
        '/list/the/resources/for/example.css',
        '/and/any/other/like/this.svg',
      ],
      permissions: 'get'
    }]
  }]);
};

/**
 * Check If Admin Policy Allows
 */
exports.isAccessible = function (req, res, next) {
... (pretty much same as below!)
});

/**
 * Check static files
 */
exports.isAccessible = function (req, res, next) {
  var roles = (req.user) ? req.user.roles : ['guest'];

  // Check for user roles
  acl.areAnyRolesAllowed(roles, req.originalUrl, req.method.toLowerCase(), function (err, isAllowed) {
    if (err) {
      // An authorization error occurred
      return res.status(500).send('Unexpected authorization error');
    } else {
      if (isAllowed) {
        // Access granted! Invoke next middleware
        return next();
      } else {
        return res.status(403).json({
          message: 'User is not authorized'
        });
      }
    }
  });
};

Use req.originalUrl instead of req.route.path which only exists for routes and won't exist for static assets.