Search code examples
ruby-on-railssecuritysecurity-roles

Using :attr_accessible with role-based authorization


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.