quamen / bouncer

Keep the riff raff out. Mass Assignment protection at the controller level.

This URL has Read+Write access

Ben Schwarz (author)
Thu Jul 02 20:01:03 -0700 2009
quamen (committer)
Sun Jul 12 04:12:42 -0700 2009
commit  8e05b2059346fae683d83ca61668c82f8d77e786
tree    93cdfbd0649a96720a4fd91dd518612691dfc5cf
parent  f8e6420c494ec4190e4d421a8570aa8031b5d2ae
name age message
file MIT-LICENSE Mon Apr 27 16:44:36 -0700 2009 First time lucky [Gareth Townsend]
file README.markdown Loading commit data...
file Rakefile Mon Apr 27 16:44:36 -0700 2009 First time lucky [Gareth Townsend]
file init.rb Mon Apr 27 16:44:36 -0700 2009 First time lucky [Gareth Townsend]
file install.rb Mon Apr 27 16:44:36 -0700 2009 First time lucky [Gareth Townsend]
directory lib/
directory tasks/ Mon Apr 27 16:44:36 -0700 2009 First time lucky [Gareth Townsend]
directory test/ Mon Apr 27 16:44:36 -0700 2009 First time lucky [Gareth Townsend]
file uninstall.rb Mon Apr 27 16:44:36 -0700 2009 First time lucky [Gareth Townsend]
README.markdown

Bouncer

Your rails app is like a club. Everyone wants in. Most users are fine, but every now and again someone wants to cause trouble.

You need a bouncer to keep the riff raff out.

Bouncer allows you to filter the params passed into your controller so that you can safely manage mass assignment at the controller level.

Example

Take a user model with the following attributes: login, password, admin.

admin is a boolean that signifies whether the user has the ability to perform admin tasks.

You probably use the following code throughout your application in controllers.

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

This code is problematic. Should a user decide to fiddle with your parameters and pass in admin=true you could have a bit of a problem on your hands.

You need a bouncer with a door list.

class UsersController < ApplicationController
  allow_params :user => [ :login, :password ]
end

Now you can safely use User.new(params[:user]) in your controller to mass assign only the attributes you've said are safe.

You should use allow_params in every controller within your application. By default bouncer will strip everything from the params hash that isn't required by rails to operate.

Why Not Use attr_accessible?

attr_accessible is great. But it's handled at the model level.

You might want to allow assignment of the admin attribute from an admin specific user interface.

You end up with code like this:

class AdminUsersController < ApplicationController

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

end

The following is much nicer:

class UsersController < ApplicationController
  allow_params :user => [ :login, :password ]
end

class AdminUsersController < ApplicationController
  allow_params :user => [ :login, :password, :admin ]
end

You can also post single params like :id for things like activation tokens and pagination keys.

class ActivationsController < ApplicationController
  allow_params :token

  def create
    @user = User.find_by_activation_token(params[:token])
  end
end

Copyright (c) 2009 Gareth Townsend, released under the MIT license

Thanks to Josh Bassett for helping nut out self.request.env['rack.routing_args'].keys and other refactorings.