Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recommendation for user groups #199

Closed
Victordmdb opened this issue Jun 4, 2019 · 4 comments
Closed

Recommendation for user groups #199

Victordmdb opened this issue Jun 4, 2019 · 4 comments
Labels

Comments

@Victordmdb
Copy link

Victordmdb commented Jun 4, 2019

Hi, great package! I'm trying to see if it can be integrated with graphql-shield for full api permissions.

I was wondering how one would implement permissions based on user grouping.

e.g a user can update an item created by another user in the same group.

If i have a groupId field on the user, and a createdBy field on the item, is there any way to populate the createdBy field when defining rule conditions for the item so i can determine if the active user is in the same group?

@stalniy
Copy link
Owner

stalniy commented Jun 4, 2019

Hi,

CASL perfectly works with domain models which have enough knowledge about themselves. CASL by itslef does not propose any population/loading logic, instead it expects that model has already everything inside.

So, in your case you have 2 options:

  1. easy, add groupId to item
  2. a bit more complex, make sure that an item is always loaded with groupId (infer groupId from createdBy)

So, then you can define your permissions like this:

can('manage', 'Item', { groupId: user.groupId })

There is a proposal #160 which aims to add possibility to asynchronously resolve conditions but it has drawbacks and introduces complexity, so I don't know whether it will be implemented.

@Victordmdb
Copy link
Author

Thanks for the response.

For solution 1 that would only work for simpler use cases. If users are added/removed to/from groups frequently all items associated with those users would therefore also have to be updated every time.

For solution 2, I'm not sure how you mean by that without an extra query to load the info from the groupId.

Understandable adding promises isn't a clean solution, but it adds some flexibility which serves more complex use cases.

@stalniy
Copy link
Owner

stalniy commented Jun 5, 2019

create a method on repository level findItem (or static method inside your model in case of ActiveRecord impl) which returns Item with inferred groupId. For SQL, you can do join. For mongo, you can do aggregation query or send 2 queries. To ensure that you send no more than 2 queries in this case you can use dataloader lib.

Eventually you will get the same result as with async conditions. + serializability.

Another approach is to split abilities into several ones (you can group by models or by user roles). You can read this article for ruby for details https://medium.com/@coorasse/cancancan-that-scales-d4e526fced3d

@Victordmdb
Copy link
Author

Victordmdb commented Jun 6, 2019

I chose to precache the given users groupmates. In my current use case that's sufficient since the groups are small and don't overlap.

Thanks for the recommendations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants