Specify do not change password Change in registrations / change

I have some custom fields for my Devise registration controller and set it to Application_controller:

def configure_permitted_parameters
  devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_password, :remember_me) }
end

      

Here is my registration form:

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
  <%= f.error_notification %>
<div class="form-inputs">
    <%= f.input :email, required: true, autofocus: true, placeholder: "Email" %>
<br>
<%= f.input :password, autocomplete: "off", hint: "Leave blank if you are not changing your password", required: false, placeholder: "Password" %>
<br>
<%= f.input :password_confirmation, required: false, placeholder: "Password Confirmation" %>

      



  <div class="form-actions">
     <%= link_to "Back to Home Page", user_landings_path, :class => 'btn btn-success' %>
    <%= f.submit 'Update', :class => 'btn btn-primary' %>
  </div>
<% end %>

      

The email message was saved, but not the password.

Any advice?

Edit:

I also bypassed the requirement that users enter their current password to update their account, if that matters:

class RegistrationsController <Style :: RegistrationsController

protected

  def update_resource(resource, params)
    resource.update_without_password(params)
  end

      

end

+3


source to share


2 answers


I've solved this in the past by manually assigning a password to the resource. Overwrite the method update_resource

in yours RegistrationsController

(or wherever you may need it). This will ensure that the password is updated if passed in parameters and then any other attributes are processed.

  def update_resource(resource, params)
    if params[:password]
      resource.password = params[:password]
      resource.password_confirmation = params[:password_confirmation]
    end

    resource.update_without_password(params)
  end

      



This is a bit of a monkey patch, but gets the job done.

+2


source


This behavior is exactly what the authors of Divises want. They don't want the user to change the password without presenting the current one because this is a possible security issue. Say you left your car unlocked when you went to get coffee and your roommate changed your password on the website you signed in to. Not cool, right? So as I decided for myself, it is best to separate the editing of the profile and change the password actions so that you can change the profile without presenting the current_password, but you must provide it to change the password.

The exact reason why the password is not updated in Devises update_without_password (params.delete note and authors comment):

# Updates record attributes without asking for the current password.
# Never allows a change to the current password. If you are using this
# method, you should probably override this method to protect other
# attributes you would not like to be updated without a password.

def update_without_password(params, *options)
  params.delete(:password)
  params.delete(:password_confirmation)

  result = update_attributes(params, *options)
  clean_up_passwords
  result
end

      



Now notice how they make the password optional in the update_with_password method (note id params [: password] .blank? Block):

def update_with_password(params, *options)
  current_password = params.delete(:current_password)

  if params[:password].blank?
    params.delete(:password)
    params.delete(:password_confirmation) if params[:password_confirmation].blank?
  end

  result = if valid_password?(current_password)
    update_attributes(params, *options)
  else
    self.assign_attributes(params, *options)
    self.valid?
    self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
    false
  end

  clean_up_passwords
  result
end

      

So, the exact solution to your question is to override the update_without_params method to remove the password from the parameters conditionally, as in the update_with_password method. But I personally don't advise doing this due to the potential security issue. In my opinion, the best solution is to separate the view of editing a profile and changing a password.

0


source







All Articles