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

Ability to have condition as function #526

Closed
mmahalwy opened this issue Jul 21, 2021 · 4 comments
Closed

Ability to have condition as function #526

mmahalwy opened this issue Jul 21, 2021 · 4 comments

Comments

@mmahalwy
Copy link

Is your feature request related to a problem? Please describe.
There are cases where it'd be great to have the conditions of an ability be a function – this could be for fetching data related to the subject. An example is checking a subject that has a many-to-many relationship where the join table needs to be queried. In the traditional Twitter example, a user has many followers and many following.

Describe the solution you'd like
Add ability to conditions for an async function

can('read', Follower, async (followerSubject) => /* use subject to query a db and return true/false or an object */)

Describe alternatives you've considered (optional)
Eager loading the data for the subject, then using nested conditions. Not ideal though.

Additional context (optional)
Add any other context or screenshots about the feature request here.

@mmahalwy mmahalwy changed the title Ability to have condition as function? Ability to have condition as function Jul 21, 2021
@stalniy
Copy link
Owner

stalniy commented Jul 21, 2021

Please read comments in this issue #160

originally, I decided not to implement this because it changes all methods to be async.

There is no easy way to support both styles in single class, so you can try to implement it yourself (based on PureAbility class) and let me know how it goes

@stalniy
Copy link
Owner

stalniy commented Jul 21, 2021

Casl works best when you model BL according DDD and check permissions on Aggregate Roots.

It also works good in NoSQL world. For SQL there is a pending issue but eventually you could use something like this to check permissions on relations:

const isAllowed = Post.exists({
  where: acessibleBy(ability).Post
})

this already works in @casl/prisma - https://casl.js.org/v5/en/package/casl-prisma

@stalniy stalniy closed this as completed Jul 21, 2021
@stalniy
Copy link
Owner

stalniy commented Jul 21, 2021

Close, because in the foreseen future don’t plan to implement this

@mmahalwy
Copy link
Author

hey @stalniy thanks for the quick reply!

I am using Prisma and GraphQL. Problem is, I need to check if an object is related to another model. My current solution is to requery the object with the associated models and do a check that way

subject(
          'ApplicationFormConfig',
          await prisma.applicationFormConfig.findUnique({
            where: { id: parent.id },
            include: { organizations: true },
            rejectOnNotFound: true,
          })

Then in ability:

can(manage, 'ApplicationFormConfig', { organizations: { every: { id: organization.id } } });

This will get the job done, so I'm not too bothered, but I can would have much rather made that query in the can definition so that I don't have to repeat this query in other places.

Do you have an example where I can create my own with PureAbility? Is there a way to extend the can method for Ability right now? I'd like to maintain the casl/prisma features.

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

No branches or pull requests

2 participants