Skip to content

Commit

Permalink
Ability to use attr_protected attributes as sign-in keys without tr…
Browse files Browse the repository at this point in the history
…iggering `ActiveModel::MassAssignmentSecurity::Error` when `ActiveRecord::Base.mass_assignment_sanitizer` is set to `:strict`. Fixes #1729.
  • Loading branch information
David FRANCOIS committed Mar 21, 2012
1 parent e92ae37 commit 885d883
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
2 changes: 1 addition & 1 deletion app/controllers/devise/sessions_controller.rb
Expand Up @@ -4,7 +4,7 @@ class Devise::SessionsController < DeviseController

# GET /resource/sign_in
def new
resource = build_resource
resource = build_resource(nil, :unsafe => true)
clean_up_passwords(resource)
respond_with(resource, serialize_options(resource))
end
Expand Down
17 changes: 14 additions & 3 deletions app/controllers/devise_controller.rb
Expand Up @@ -67,10 +67,21 @@ def resource=(new_resource)
instance_variable_set(:"@#{resource_name}", new_resource)
end

# Build a devise resource.
def build_resource(hash=nil)
# Build a devise resource.
# Assignment bypasses attribute protection when :unsafe option is passed
def build_resource(hash = nil, options = {})
hash ||= params[resource_name] || {}
self.resource = resource_class.new(hash)

if options[:unsafe]
self.resource = resource_class.new.tap do |resource|
hash.each do |key, value|
setter = :"#{key}="
resource.send(setter, value) if resource.respond_to?(setter)
end
end
else
self.resource = resource_class.new(hash)
end
end

# Helper for use in before_filters where no authentication is required.
Expand Down
16 changes: 16 additions & 0 deletions test/controllers/sessions_controller_test.rb
Expand Up @@ -13,4 +13,20 @@ class SessionsControllerTest < ActionController::TestCase
assert_equal 200, @response.status
assert_template "devise/sessions/new"
end

test "#new doesn't raise mass-assignment exception even if sign-in key is attr_protected" do
request.env["devise.mapping"] = Devise.mappings[:user]

ActiveRecord::Base.mass_assignment_sanitizer = :strict
User.class_eval { attr_protected :email }

begin
assert_nothing_raised ActiveModel::MassAssignmentSecurity::Error do
get :new, :user => { :email => "allez viens!" }
end
ensure
ActiveRecord::Base.mass_assignment_sanitizer = :logger
User.class_eval { attr_accessible :email }
end
end
end

0 comments on commit 885d883

Please sign in to comment.