A REST API is written in ExpressJs 4.x.x / NodeJS.
Let's assume an interface :
app.delete('/api/v1/users/:uid', function (req, res, next) {
...
}
So with that interface users can be deleted.
Let's assume there are 2 Customers in the system, and each Customer has Users. A User can have the privilege of deleting other Users with a role named CustomersAdmin. But this User should only be able to delete Users which are Users from his Company(Customer).
So, let's get ACL into the scene. Assuming in our ACL we can define roles, resources and permissions. (Code is adopted from http://github.com/OptimalBits/node_acl#middlware.)
app.delete('/api/v1/users/:uid', acl.protect(), function (req, res, next)
{
// ? Delete User with uid = uid or check
// ? first if current user is in same company as user uid
}
There are two things to consider. One is protecting the route from persons without permission to HTTP/DELETE on that route ( /api/v1/users/:uid ) and the other is that a Person with Role CustomersAdmin shall not be allowed to delete Users from another Customer.
Is ACL supposed to do both? Or is it supposed to protect the route /api/v1/users?
So, would I use it like
acl.allow([
{
roles:'CustomersAdmin',
allows:[
{resources:['/api/v1/users', '/api/v1/users'] permissions:'delete'}
}
app.delete('/api/v1/users/:uid',acl.middleware(3), function(req,res,next)
{
Make sure uid is a User from same Customer as request is from(req.session.userid)
}
This would allow every User with Role CustomersAdmin to delete whatever user he wants. Or is it preferable to define each possible Users route as a Resource and define multiple Roles which can interact with them?
acl.allow([
{
roles:'CustomersAdminOne',
allows:[
{resources:['/api/v1/users/1', '/api/v1/users/2'], permissions:'delete'}]
},
{
roles:'CustomersTwoAdmin',
allows:[
{resources:['/api/v1/users/3','/api/v1/users/4'], permissions:'delete'}
]
}
app.delete('/api/v1/users/:uid',acl.middleware(), function(req,res,next)
{
no logic needed to be sure that request is from a user within the same customer
}
The way I solved this was to create a role per user. I use a mongoose post save hook:
acl.addUserRole(user._id, ['user', user._id]);
Then in a post save hook for a resource I do this:
acl.allow(['admin', doc.user._id], '/album/' + doc._id, ['*']);
acl.allow(['guest', 'user'], '/album/' + doc._id, ['get']);
You can then use the isAllowed
method to check if req.user
has the right permissions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With