0

I have User model on which I use device and cancancan. Here is my ability:

if user.role? :patient
         can :access_profile, User, :id => user.id
end

where access_profile alias is:

alias_action :show, :edit, :update, :destroy, :to => :access_profile

In my users_controller I use load_and_authorize_resource. For example when I try "users/4" and current_user.id = 3 I am able to get there.

In logs i see this:

User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 4]]
User Load (0.6ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 3]]
  Rendered users/show.html.erb within layouts/application (0.4ms)

Here first query comes from set_user method. I guess the second query loads my resource to authorize. And here since current_user.id = 3 and in 2nd query i see 3 too, i guess that is why I am authorized. But id in 2nd query must be 4, i guess.

What to do in order to load_and_authorize method work properly.

yerassyl
  • 2,958
  • 6
  • 42
  • 68

1 Answers1

0

Are you sure that automatic loading of instance works ? Cancancan will use Class as the object to check ability if instance can not be loaded and access to Class will always return true if defined (regardless parameters like :id)

Change load_and_authorize_resource to load_resource and check if authorize! :access_profile, @user used in access_profile action will also protect the access.

You can also define ability on instance directly: can :access_profile, user instead of defining on User class.

Dawid Gosławski
  • 2,028
  • 1
  • 18
  • 25