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

Cant integrate casl/vue with rails cancancan #214

Closed
gusMoreno opened this issue Aug 9, 2019 · 8 comments
Closed

Cant integrate casl/vue with rails cancancan #214

gusMoreno opened this issue Aug 9, 2019 · 8 comments
Labels

Comments

@gusMoreno
Copy link

gusMoreno commented Aug 9, 2019

Hi,

I am having issues when my rule has a condition. The $can method always returns true.

The only rules I am trying to add are:

# ability.rb
def initialize(user)
    can :create, Task
    can :edit, Task, user_id: user.company.users.pluck(:id)
    can :manage, Task, user_id: user.id
end

I am using cancancan + @casl/vue. So what I am doing is fetching the cancancan abilities and updating the $ability with the response, as per below:

# ability.rb
  def to_list
    rules.map do |rule|
      object = { actions: rule.actions, subject: rule.subjects.map{ |s| s.is_a?(Symbol) ? s : s.name } }
      object[:conditions] = rule.conditions unless rule.conditions.blank?
      object[:inverted] = true unless rule.base_behavior
      object
    end
  end
Requests.setAbilities()
.then(response => {
    this.$ability.update(response.data.rules)
})

I console logged the $ability afterwards and it seems to be receiving the rules correctly.

I tested with 2 tasks, the first one has user_id: 1 and the second one has user_id: 6.

But when I am logged in as user_id: 1 the following code, always return true, for any tasks.

// Task.vue
methods: {
    ownTask() {
      return (this.$can("manage", 'Task'))
      // I also tried variations like:
      // return (this.$can("manage", this.task))
    }
}

I have read all the docs more than once, but I can't seem to make it work. I am using all the latest versions of @casl/vue and @casl/ability.

Could you please let me know what I am doing wrong?

Thanks in advance!

@stalniy
Copy link
Owner

stalniy commented Aug 10, 2019

You do everything correctly :) and casl works as expected.

When you do $can(“manage”, “Task”), you are actually asking: can I manage at least one task? And casl says, yes you can (because you can manage all tasks with userId = logged-in user id)

When you check instances ($can(“manage”, task)), you need to ensure that CASL can correctly detect instance type. So, in order to say why this doesn’t work I need to know how you create this.task variable, whether it’s a plain object or an instance of a class. By default, CASL try to detect instance type based on object constructor.name. In order to teach him how to correctly detect subject name, you need to pass subjectName option when crating Ability instance

@gusMoreno
Copy link
Author

gusMoreno commented Aug 10, 2019

I appreciate your fast response!

Right now, this.task is a plain object, I declare it in the data section of my vue component like this:

data() {
    return {
        task: {}
    }
}

And I have an endpoint on mounted section to fill in this object.

So in order for this to work, I have to:

  1. write a class Task and declare the object as task: Task.new
  2. Pass the subjectName to the Ability instance. How do I do it?

Is that correct?

@stalniy
Copy link
Owner

stalniy commented Aug 11, 2019

Not exactly. Please find info about subjectName in docs

Also you can check this repo for a reference

@stalniy
Copy link
Owner

stalniy commented Aug 13, 2019

Close as there is nothing to do from CASL side.

Thanks for the interest in CASL!

@stalniy stalniy closed this as completed Aug 13, 2019
@gusMoreno
Copy link
Author

Thanks @stalniy! I created a class for Task following the docs you sent, and it seems to be working great!

@twnaing
Copy link

twnaing commented Apr 24, 2020

I think the sample should be updated with the followings for casl 4.x

  1. action instead of actions (not breaking, but action is now recommended)
  2. subjectName insetad of subject in (breaking change)
    a. blog post
    b. example

@stalniy
Copy link
Owner

stalniy commented Apr 24, 2020

Right, the sample needs to be updated. All examples, I slowly move into monorepo https://github.com/stalniy/casl-examples . The next one is for vue-api.

There is no need to change subject to subjectName. @twnaing why did you decide this is required?

@twnaing
Copy link

twnaing commented Apr 24, 2020

@stalniy , the link redirected me to intro of the new documentation site. So I assumed (blindly) I need to change (and I had the working component for the wrong reason) and I posted it here (and the other link).

I think the one you want to redirect is conditions https://stalniy.github.io/casl/v4/en/guide/subject-type-detection

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

3 participants