Rails 3.2; Ruby 2.1; Cancan 1.6.10; User
is a devise
model.
I've followed the instructions for restricting controller actions based on attributes and have setup the following ability.rb
file:
class Ability
include CanCan::Ability
def initialize(user, params)
if user
if user.admin?
can :manage, :all
elsif user.employee?
cannot :manage, User
# Works
# can :manage, User if params[:id].to_f == user.id.to_f
# Doesn't work
can :manage, User, id: user.id
else
cannot :manage, :all
end
end
end
end
I can not get the line: can :manage, User, id: user.id
to work. It still allows me to edit any User
with a path like /users/4/edit
even though that is not the id
of the user
. However, if I use the line above with the if
statement, it works properly.
I've also tried passing in a block like:
can :manage, User, do |usr|
Rails.logger.debug("usr.id: #{usr.id}")
usr.id == user.id
end
Which doesn't even print to the log. Been at this for hours and am not really sure what the problem is.
UPDATE
I went though CanCan debugging and am getting conflicting results. Using the line can :manage, User, id: user.id
; I get the following results in console:
admin = User.find(1)#role of "admin"
user = User.find(4) #role of "employee"
ability = Ability.new(user)
ability.can?(:edit, user)
# true
ability.can?(:edit, admin)
# false
ability = Ability.new(admin)
ability.can?(:edit, user)
# true
ability.can?(:edit, admin)
# true
However, I'm still able to navigate to and edit (with changes being saved) other users while I'm logged in as user 4
Additionally, it works properly if I add the following to the controller:
def edit
@user = User.find(params[:id])
unless can? :edit, @user
redirect_to dashboard_path, alert: 'You do not have sufficient privileges to edit other users.'
end
end
I was under the impression that this shouldn't be necessary given what I have in ability.rb
So the problem ended up being that in the controller I was using authorize_resource
instead of load_and_authorize_resource
. Once I switched it to the later I was able to define abilities in ability.rb
.