Rails Security Made Easy
April 25th 2010I’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
# 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
# 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!