Question on attr_protected and attr_accessible

Currently I have an admin page that I configured that is only accessible via the following:

On each controller that I do not want people to access, I place..

before_filter :login_required, :authorize

.. which will force them to login and then it will call an authorize function to check if they are an admin role..

private

def authorize   unless logged_in? && User.find(current_user).admin?     redirect_to root_url   end end

This works great for protecting my pages and allowing me to perform many administrative functions live on the site. However, one potential issue that I see is as far as user administration.

I've made it so that I can edit/update users through my administrative pages and protected those pages so only admins can access them. However, in order to set whether or not a user is an admin and be able to update that user, I need to have:

attr_accessible :admin

If I set this to attr_protected :admin

.. I'm unable to access that attribute and won't be able to update my admins..

Not quite true. it means that you can't do some_user.update_attributes (:admin => true).

You can however do some_user.admin = true

The attr_accessible/attr_protected mechanism is a bit of a blunt tool. There has been some discussion about revisiting this for rails 3

Fred

Frederick Cheung wrote:

This won't protect you from someone forgering a request. You should check this in the controller, maybe put something like this in the update method: """ user_to_update.admin = params[:admin] unless !logged_in_user.admin? """ (and PLEASE do check this code before relying on it, that's off the top of my head). Doing it this way will make sure that no non-admin can change the admin status of a user.

Regards,

Felix

Frederick Cheung wrote:

Thanks for the clarification Fred. So, how would I implement this in my edit view template? Or, are you stating it can't be done there but somewhere else?

It's nothing to do with the view template. You need to assign the relevant attribute by hand in your controller (presumably after checking that it is allowed).

Fred

One correction and one addition:

the before filters should look like this:

before_filter :login_required, :except => [:new, :create] before_filter :authorize, :except => [:user_edit, :update, :new, :create]

Otherwise, your new users wouldn't be able to register..

And, to protect your "new user" from being able to hack their form and add admin=true, you change the following in create method from:

@user = User.new(params[:user])

TO..

@user = User.new(params[:user].merge({ :admin => "false" }))

Do you prefer attr_protected or attr_accessible?

I used to only use attr_accessible, but usually my model only has one field to be protected, so it becomes a pain to write:

object.attr1 = ... object.attr2 = ... etc

I am considering the use of attr_protected with tests to make sure that the protected attributes are indeed protected.

Did anyone do the jump? Will it fire back at me?