1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00

Add resource_params internal helper to param filtering

In light of recent discussions around mass assignment security and
the alternate solution of using the controller to filter params, not the model,
a hook/helper is needed to be able to override how the params are filtered
before they are used to build the resource.
This commit is contained in:
Adam Meehan 2012-05-15 18:07:02 +10:00
parent f95513e86b
commit 7ec4c1424d
6 changed files with 19 additions and 8 deletions

View file

@ -6,7 +6,7 @@ class Devise::ConfirmationsController < DeviseController
# POST /resource/confirmation # POST /resource/confirmation
def create def create
self.resource = resource_class.send_confirmation_instructions(params[resource_name]) self.resource = resource_class.send_confirmation_instructions(resource_params)
if successfully_sent?(resource) if successfully_sent?(resource)
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name)) respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))

View file

@ -8,7 +8,7 @@ class Devise::PasswordsController < DeviseController
# POST /resource/password # POST /resource/password
def create def create
self.resource = resource_class.send_reset_password_instructions(params[resource_name]) self.resource = resource_class.send_reset_password_instructions(resource_params)
if successfully_sent?(resource) if successfully_sent?(resource)
respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name)) respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name))
@ -25,7 +25,7 @@ class Devise::PasswordsController < DeviseController
# PUT /resource/password # PUT /resource/password
def update def update
self.resource = resource_class.reset_password_by_token(params[resource_name]) self.resource = resource_class.reset_password_by_token(resource_params)
if resource.errors.empty? if resource.errors.empty?
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active flash_message = resource.active_for_authentication? ? :updated : :updated_not_active

View file

@ -39,7 +39,7 @@ class Devise::RegistrationsController < DeviseController
def update def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key) self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
if resource.update_with_password(params[resource_name]) if resource.update_with_password(resource_params)
if is_navigational_format? if is_navigational_format?
if resource.respond_to?(:pending_reconfirmation?) && resource.pending_reconfirmation? if resource.respond_to?(:pending_reconfirmation?) && resource.pending_reconfirmation?
flash_key = :update_needs_confirmation flash_key = :update_needs_confirmation
@ -77,7 +77,7 @@ class Devise::RegistrationsController < DeviseController
# Build a devise resource passing in the session. Useful to move # Build a devise resource passing in the session. Useful to move
# temporary session data to the newly created user. # temporary session data to the newly created user.
def build_resource(hash=nil) def build_resource(hash=nil)
hash ||= params[resource_name] || {} hash ||= resource_params || {}
self.resource = resource_class.new_with_session(hash, session) self.resource = resource_class.new_with_session(hash, session)
end end

View file

@ -8,7 +8,7 @@ class Devise::UnlocksController < DeviseController
# POST /resource/unlock # POST /resource/unlock
def create def create
self.resource = resource_class.send_unlock_instructions(params[resource_name]) self.resource = resource_class.send_unlock_instructions(resource_params)
if successfully_sent?(resource) if successfully_sent?(resource)
respond_with({}, :location => after_sending_unlock_instructions_path_for(resource)) respond_with({}, :location => after_sending_unlock_instructions_path_for(resource))

View file

@ -5,7 +5,7 @@ class DeviseController < Devise.parent_controller.constantize
helper DeviseHelper helper DeviseHelper
helpers = %w(resource scope_name resource_name signed_in_resource helpers = %w(resource scope_name resource_name signed_in_resource
resource_class devise_mapping) resource_class resource_params devise_mapping)
hide_action *helpers hide_action *helpers
helper_method *helpers helper_method *helpers
@ -28,6 +28,10 @@ class DeviseController < Devise.parent_controller.constantize
devise_mapping.to devise_mapping.to
end end
def resource_params
params[resource_name]
end
# Returns a signed in resource from session (if one exists) # Returns a signed in resource from session (if one exists)
def signed_in_resource def signed_in_resource
warden.authenticate(:scope => resource_name) warden.authenticate(:scope => resource_name)
@ -81,7 +85,7 @@ MESSAGE
# Build a devise resource. # Build a devise resource.
# Assignment bypasses attribute protection when :unsafe option is passed # Assignment bypasses attribute protection when :unsafe option is passed
def build_resource(hash = nil, options = {}) def build_resource(hash = nil, options = {})
hash ||= params[resource_name] || {} hash ||= resource_params || {}
if options[:unsafe] if options[:unsafe]
self.resource = resource_class.new.tap do |resource| self.resource = resource_class.new.tap do |resource|

View file

@ -33,6 +33,13 @@ class HelpersTest < ActionController::TestCase
assert_equal user, @controller.instance_variable_get(:@user) assert_equal user, @controller.instance_variable_get(:@user)
end end
test 'get resource params from request params using resource name as key' do
user_params = {'name' => 'Shirley Templar'}
@controller.stubs(:params).returns(HashWithIndifferentAccess.new({'user' => user_params}))
assert_equal user_params, @controller.resource_params
end
test 'resources methods are not controller actions' do test 'resources methods are not controller actions' do
assert @controller.class.action_methods.empty? assert @controller.class.action_methods.empty?
end end