0

In a Rails app which uses JSONAPI::Resources and CanCanCan, I have a Caption model (has_one :video) and a Video model (has_many :captions).

I want to allow guests to only access those captions which belong to a published video: can :read, Caption, video: { visible: true }

However, this is not working. Guests can access all captions by visiting the /captions route. If I remove the above line, guests can't access any caption and receive 401 Unauthorized instead.

We have a few abilities defined in a similar way, and I just can't figure out what's the problem in this case. This specific ability definition seems not to be ignored, but interpreted in a wrong way. This variation also let's guest access all captions:

can :read, Caption do | caption |
  false
end

How can I debug this?

Pida
  • 928
  • 9
  • 32
  • How do you distinguish between guests and authenticated users? Do you have a `can :manage, Caption` somewhere? – razvans Sep 21 '21 at 11:39
  • I have a rather complex `ability.rb` file with an `initialize` function at the top. This calls other functions such as `guest_actions` (which is what I'm working on right now), `user_actions`, etc. At the moment, I `return`from this funtion after calling `guest_actions`. There's no `can :manage` and no other `can :read, Caption` in this file. – Pida Sep 21 '21 at 12:31
  • I realized my problem is more general: Users should only be allowed to *add* captions to their own videos, but `can %i[create destroy], Caption, video: { creator: { id: person.id } }` causes a 403 unless I remove the condition on the video. This happens inside an `author_actions` method with a `person` argument. Using Byebug, I could verify that `person.id == video.creator.id`. – Pida Sep 22 '21 at 11:00

1 Answers1

0

To debug your problem, you can take a look at this page of the cancancan gem documentation : https://github.com/CanCanCommunity/cancancan/blob/develop/docs/debugging.md

You also have the gem byebug who is really helpful : https://www.rubydoc.info/gems/byebug/11.1.3

Emilien Baudet
  • 428
  • 4
  • 10
  • Thanks. We use Byebug, but placing *byebug* in the last code sample in my question did not have any effects when running the tests. I'll have a look at the documentation, I haven't seen the page you link to before. – Pida Sep 21 '21 at 12:20
  • The commands from the first two sections on that page output `true` for both `ability.can?(:read, Caption.first)` and `ability.can?(:index, Caption)`, and they output `false` when I comment out the line concerning `Caption`. The ability definition has an effect, but the condition on `Video` doesn't. – Pida Sep 21 '21 at 12:52