Secure model mass assignment for administration panels
For the most applications I’m developing I want the users to be able to edit their user data or profile using model mass assignment in Rails. Moreover I want additionally an easy administration panel for super users who can access all the attributes of the users (and nested attributes) via mass assignment.
Now what’s an easy and rails-like way to allow users and super users to edit exclusively the attributes they have access for? I’ve searched the web and found dirty solutions like accessing the current_user from your model or modifying before_*-handlers. So here is my way.
In the user-model I declare the attributes the user has access to, using attr_accessible:
class User < ActiveRecord::Base attr_accessible :login, :email, :birthday, :country, :city, :age_is_public end
For the administration panel I create a new model which extends the User model. This AdminUser model extends the accessible attributes of the User model for the super user.
class AdminUser < User attr_accessible :role, :comment, :level end
Now I access the User model from the controller for standard users and the AdminUser model from the admin controller. The verification for a valid and logged in super user is done there.
class UsersController < ApplicationController
before_filter :login_required
[..]
def update
@user = User.find(current_user.id)
@user.update_attributes(params[:user])
[..]
end
class AdminUsersController < ApplicationController
before_filter :login_required, :admin_required
[..]
def update
@user = AdminUser.find(params[:id])
@user.update_attributes(params[:user])
[..]
end
That's it. Nice and clean model mass assignment depending on the security level of the user. This also works nice with nested attributes. Don't forget to add _attributes to your symbol name in attr_accessible in this case (like :profile_attributes for a has_one relationship with the profile model).
Keywords: admin panel, control panel, rails, nested_attributes_for, mass assignment, attr_accessible, attr_protected
Filed under: Development, English, Ruby On Rails on Juni 18th, 2009 | 1 Comment »