-
-
Notifications
You must be signed in to change notification settings - Fork 271
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
Field-specific abilities act differently based on whether conditions are given as null or empty object. #684
Comments
Hmm... this is very nice edge case :) Good catch. So, currently it works the way it works because there are particular expectations, in other words if inverted rule has conditions and we check based on subject type then this rule cannot match because subjectType has no properties. For example: ability = defineAbility((can, cannot) => {
can('read', 'Post')
cannot('read', 'Post', { private: true })
})
expect(ability).to.allow('read', 'Post') If I change the logic then this test fails and user cannot read Post but technically there is likelihood there are posts between that are not private and can be read. In your cause, situation like this: ability = defineAbility((can, cannot) => {
can('read', 'Post')
cannot('read', 'Post', {})
}) I know there are conditions but I can't do any assumptions based on their evaluation (because it depends on conditionsMatcher) and I cannot evaluate check on subject type. Actually, in this case can but I don't know how this will behave in cases Let's make assumption that we have custom conditions matcher that executes function on object: ability = defineAbility((can, cannot) => {
can('read', 'Post')
cannot('read', 'Post', (post) => true)
}) How can we detect that conditions always return One possible way to solve this is to force conditions matcher to provide some additional information and tell casl whether conditions can be perceived as always returning You can comment out |
Hmmmm, my first assumption would have been that if a Another option would be to treat subject and instance checks differently, but that seems like a great source of confusion on its own, and a big breaking change to boot. Is there a case where empty conditions object is meaningfully different from a null? Unless there's another edge case somewhere else, In the project where I encountered this issue I solved that by replacing empty objects with nulls on the rule generation side, and so far the test suite seems to pass. But then again, that project does not use particularly advanced ability logic. Overall, it seems to me that even a "fix your parameters" warning on encountering an empty object would go most of the way for this particular issue. |
warnings makes sense. I think this can be implemented on conditions matcher level. It can provide warnings and casl can forward this to some function passed through options, so you can forward that to error handling system or just to console.log. For cases, when @ucas/core AST is used I could even check for some predefined ConditionNode to make this functionality work as you requested |
Describe the bug
Field-specific abilities act differently based on whether conditions are given as null or empty object. If
conditions
is an empty object, field-specific inverted rule can not override previously given general rule. Withconditions
as null, it can. When generating rules to use by frontend code from backend definitions (Ruby gem "cancancan" in my case), it can lead to unexpected behaviour.To Reproduce
Expected behavior
I expect both cases to work identically, because they represent identical rule definitions.
Interactive example (optional, but highly desirable)
https://codesandbox.io/s/jovial-rhodes-kyj9v7?file=/src/index.js
CASL Version
@casl/ability
- 6.2.0Environment:
Latest chrome
The text was updated successfully, but these errors were encountered: