Using :attr_accessible with role-based authorization
-
16-09-2019 - |
Question
In my online store, users are allowed to change certain properties of their orders (e.g., their billing address), but not others (e.g., the origination ip address). Administrators, on the other hand, are allowed to modify all order properties.
Given, this, how can I use :attr_accessible
to properly secure my Order model? Or will I have to use it to mark accessible all attributes that administrators can modify and refrain from using Order.update_attributes(params[:order])
in those controller actions that ordinary users can access?
Solution
Generally speaking, attr_accessible is not the tool you're looking for and Rails doesn't come with anything built in that does what you want.
If you want fine-grained control over who can update specific attributes in a model, you could do something like:
class Order < ActiveRecord::Base
def update_attributes_as_user(values, user)
values.each do |attribute, value|
# Update the attribute if the user is allowed to
@order.send("#{attribute}=", value) if user.can_modify?(attribute)
end
save
end
end
Then you can change your Order.update_attributes(params[:order])
to Order.update_attributes_as_user(params[:order], current_user)
and assuming you implement the User#can_modify?
method to return true in the correct cases, it should work.
OTHER TIPS
I had the same problem and now I'm using this gem http://github.com/dmitry/attr_accessible_block
It's easy and used in some production website.
Yes, you'll have to modify the actions, so permissions are checked inside the actions. Calling Order#update_attributes
will not work for the general user.
I can't rember a role-based authorization plugin that would allow something you are looking for. This is because these plugins mixin to the controllers and not the models. They would also need to mixin into ActiveRecord::Base
to check for attr_accesible
etc.