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

accessible_by permanently modifies a rule's conditions via normalize_conditions, causing can? to fail #876

Open
rockorequin opened this issue Jan 20, 2025 · 0 comments

Comments

@rockorequin
Copy link

rockorequin commented Jan 20, 2025

The ConditionNormalizer in accessible_by permanently modifies a rule's conditions when you call accessible_by, meaning that a call to the can? method that worked before calling accessible_by may not work afterwards.

For example, say I have the models Client, Project, and Activity, where an activity belongs to a project and a project belongs to a client. In Ability, I can create a rule to say that a user can read any project or activity belonging to client with id 10:

can :read, [ Project, Activity ], client: { id: 10 }

This creates a rule with conditions: { client: { id: 10 } }.

Then if I run this code in the controller:

    @project = Project.first
    can? :read, @project
    @activities = Activity.accessible_by current_ability
    can? :read, @project

then the first call to can? runs without error. The call to Activity.accessible_by current_ability permanently changes the rule's conditions to { project: { client: { id: 10 } } } via a call to normalize_conditions, and the second identical call to can? then raises a NoMethodError saying "undefined method `project' for an instance of Project" because the new conditions make cancancan call @project.project.client instead of @project.client.

Is the rule illegal, ie should you only ever create a rule with an array of models that all have through reflections to the condition OR all have belongs_to reflections to the condition? Or should accessible_by not permanently change the conditions for the rule?

I'm using cancancan 3.6.1 and Rails 8.0.1.

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

No branches or pull requests

1 participant