onury / accesscontrol

Role and Attribute based Access Control for Node.js
https://onury.io/accesscontrol
MIT License
2.21k stars 178 forks source link

Possession granularity #52

Closed acn-jamil-naja closed 6 years ago

acn-jamil-naja commented 6 years ago

Possession is exactly what I have been looking for with an ACL!

Is there away to have more granular possession model as part of the library? currently there is own, any. how do I implement something like "associated"?

scandinave commented 6 years ago

The concept of assiociation is heavely tied to your application logic. So it's up to you to implement it.

In my expressJS application i have user that have profil and access on their own resources. So i have created a grant like this .

ac.grant('user').readOwn('profil')
ac.grant('user').readOwn('resource')

After that i have a middleware that check for every access to a route.First, if a user have an "any" permission on this route, and then if a user have an "own" permission with a relation extracted from the database. So it's your DB model that conduct the choice.

To not make a request each time you check a permission you can :

acn-jamil-naja commented 6 years ago

Thanks @scandinave Do you have any suggestion for owning a "segment" of resources. Say a location admin, that has "own" access to a specific segment of users based on their location?

scandinave commented 6 years ago

You can use attributes for that. For example, my user should be able to update their profile but not their role. Only admin can do that. So i have defined this rule :

ac.grant('user').updateOwn('profil', ['*', '!roles']); This means that user can update all of it's profil, except the roles resource. For read or update on a resource you can use :

const permission = ac.can('user').readOwn('profil');
permission.granted;       // true
permission.attributes;    // ['*', '!roles']
permission.filter(data);  // filtered data (without roles)

For a findAll you can call filter on each resources or if you can, use the same middleware to inject parameters in the request to only select field that user can access .

acn-jamil-naja commented 6 years ago

thats useful thank you @scandinave

the scenario I am missing is: Say we have a an admin (say AdminA) for "london" based users is there a syntax for giving AdminA "own" relationship on an user with location===london ?

scandinave commented 6 years ago

This is what is missing in the library, a context. This will be implemented in V3 normally. But as i tell you, you can use this,

ac.grant('admin').readOwn('user'); ac.grant('admin').updateOwn('user'); ac.grant('admin').deleteOwn('user'); ac.grant('admin').createOwn('user');

And uses your middleware to handle the check to know if the user being access is from london. Using a middleware make you application code agnostic to security constraints and guaranteed that if your security constraints changes, your application code will not.

acn-jamil-naja commented 6 years ago

Understood Very useful thank you @scandinave