Rails Security Made Easy

April 25th 2010

I’ve just released an early-alpha version of secure_rails (http://github.com/alexbartlow/secure_rails), a way of collecting the cross-cutting concern of security into a single cohesive set of policy files.

It looks a lot like this:


#rails g security:model User
# lib/security/models/user.rb
 Secure(User) do |u|
   u.policy(:default) do
     attr_accessible # complete lockdown
   end
   
   u.policy(:self) do
     attr_accessible :name, :email # The user himself can edit name and email
   end
   
   u.policy(:admin, :include => :self) do
     attr_accessible :status # moderators can edit status
   
     validates_exclusion_of :status, :in => [:banned_forever], 
       :unless => :skip_status_validation
       
     def skip_status_validation ; false ; end
     # but the moderator cannot set the status to banned forever
   end
   
   u.policy(:manager) do
    # this doesn't do anything, but is here to show that you can use include to
    # pull in multiple roles
   end
   
   u.policy(:super_admin, :include => [:admin, :manager]) do
     def skip_status_validation ; true ; end 
       # superadmins skip the status validation check
   end
   
   # policies always take precidence over the policies they include.
   # That's why the super-admin policy works.
 end

That’s for models. It also lets you specify controller-grained access control:

# lib/security/controllers/users_controller.rb
SecureController(UsersController) do |u|
  u.policy(:default) do
    # Don't allow unprivileged users to change anything
    if [:create, :update].include?(params[:action])
      raise SecurityTransgression.new
    end
  end
end

Pretty awesome, dry, an unlikely to have you forget a before_filter :require_admin in an internal page. Default everything to closed, and you can open up all of your controllers and models in one place.

Check it out over on github (http://github.com/alexbartlow/secure_rails) – play around with it in your rails 3 apps, and let me know if you have any problems!

blog comments powered by Disqus