views:

224

answers:

3

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?

+1  A: 

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.

Koraktor
+4  A: 

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.

jakob.skjerning
+1  A: 

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.

Dmitry Polushkin