lib/authlogic/session/password.rb in authlogic-3.8.0 vs lib/authlogic/session/password.rb in authlogic-4.0.0

- old
+ new

@@ -4,11 +4,11 @@ module Password def self.included(klass) klass.class_eval do extend Config include InstanceMethods - validate :validate_by_password, :if => :authenticating_with_password? + validate :validate_by_password, if: :authenticating_with_password? class << self attr_accessor :configured_password_methods end end @@ -125,46 +125,14 @@ rw_config(:verify_password_method, value, "valid_password?") end alias_method :verify_password_method=, :verify_password_method end - # Password-related instance methods + # Password related instance methods module InstanceMethods - E_AC_PARAMETERS = <<-STR.strip_heredoc.freeze - You have passed an ActionController::Parameters to Authlogic 3. That's - OK for now, but in Authlogic 4, it will raise an error. Please - replace: - - UserSession.new(user_session_params) - UserSession.create(user_session_params) - - with - - UserSession.new(user_session_params.to_h) - UserSession.create(user_session_params.to_h) - - And don't forget to `permit`! - - During the transition of rails to Strong Parameters, it has been - common for Authlogic users to forget to `permit` their params. They - would pass their params into Authlogic, we'd call `to_h`, and they'd - be surprised when authentication failed. - - In 2018, people are still making this mistake. We'd like to help them - and make authlogic a little simpler at the same time, so in Authlogic - 3.7.0, we deprecated the use of ActionController::Parameters. - - We discussed this issue thoroughly between late 2016 and early - 2018. Notable discussions include: - - - https://github.com/binarylogic/authlogic/issues/512 - - https://github.com/binarylogic/authlogic/pull/558 - - https://github.com/binarylogic/authlogic/pull/577 - STR - def initialize(*args) - if !self.class.configured_password_methods + unless self.class.configured_password_methods configure_password_methods self.class.configured_password_methods = true end super end @@ -182,48 +150,69 @@ end end # Accepts the login_field / password_field credentials combination in # hash form. + # + # You must pass an actual Hash, `ActionController::Parameters` is + # specifically not allowed. + # + # See `Authlogic::Session::Foundation#credentials=` for an overview of + # all method signatures. def credentials=(value) super - values = parse_param_val(value) # add strong parameters check - + values = Array.wrap(value) if values.first.is_a?(Hash) - values.first.with_indifferent_access.slice(login_field, password_field).each do |field, value| - next if value.blank? - send("#{field}=", value) + values.first.with_indifferent_access.slice(login_field, password_field).each do |field, val| + next if val.blank? + send("#{field}=", val) end end end def invalid_password? invalid_password == true end private + def add_invalid_password_error + if generalize_credentials_error_messages? + add_general_credentials_error + else + errors.add(password_field, I18n.t('error_messages.password_invalid', default: "is not valid")) + end + end + + def add_login_not_found_error + if generalize_credentials_error_messages? + add_general_credentials_error + else + errors.add(login_field, I18n.t('error_messages.login_not_found', default: "is not valid")) + end + end + def configure_password_methods if login_field - self.class.send(:attr_writer, login_field) if !respond_to?("#{login_field}=") - self.class.send(:attr_reader, login_field) if !respond_to?(login_field) + self.class.send(:attr_writer, login_field) unless respond_to?("#{login_field}=") + self.class.send(:attr_reader, login_field) unless respond_to?(login_field) end if password_field - self.class.send(:attr_writer, password_field) if !respond_to?("#{password_field}=") - self.class.send(:define_method, password_field) {} if !respond_to?(password_field) + self.class.send(:attr_writer, password_field) unless respond_to?("#{password_field}=") + self.class.send(:define_method, password_field) {} unless respond_to?(password_field) # The password should not be accessible publicly. This way forms # using form_for don't fill the password with the attempted # password. To prevent this we just create this method that is # private. - self.class.class_eval <<-"end_eval", __FILE__, __LINE__ + self.class.class_eval <<-EOS, __FILE__, __LINE__ private def protected_#{password_field} @#{password_field} end - end_eval + EOS end end def authenticating_with_password? login_field && (!send(login_field).nil? || !send("protected_#{password_field}").nil?) @@ -232,31 +221,27 @@ def validate_by_password self.invalid_password = false # check for blank fields if send(login_field).blank? - errors.add(login_field, I18n.t('error_messages.login_blank', :default => "cannot be blank")) + errors.add(login_field, I18n.t('error_messages.login_blank', default: "cannot be blank")) end if send("protected_#{password_field}").blank? - errors.add(password_field, I18n.t('error_messages.password_blank', :default => "cannot be blank")) + errors.add(password_field, I18n.t('error_messages.password_blank', default: "cannot be blank")) end return if errors.count > 0 self.attempted_record = search_for_record(find_by_login_method, send(login_field)) if attempted_record.blank? - generalize_credentials_error_messages? ? - add_general_credentials_error : - errors.add(login_field, I18n.t('error_messages.login_not_found', :default => "is not valid")) + add_login_not_found_error return end # check for invalid password - if !attempted_record.send(verify_password_method, send("protected_#{password_field}")) + unless attempted_record.send(verify_password_method, send("protected_#{password_field}")) self.invalid_password = true - generalize_credentials_error_messages? ? - add_general_credentials_error : - errors.add(password_field, I18n.t('error_messages.password_invalid', :default => "is not valid")) + add_invalid_password_error return end end attr_accessor :invalid_password @@ -269,16 +254,16 @@ self.class.login_field end def add_general_credentials_error error_message = - if self.class.generalize_credentials_error_messages.is_a? String - self.class.generalize_credentials_error_messages - else - "#{login_field.to_s.humanize}/Password combination is not valid" - end - errors.add(:base, I18n.t('error_messages.general_credentials_error', :default => error_message)) + if self.class.generalize_credentials_error_messages.is_a? String + self.class.generalize_credentials_error_messages + else + "#{login_field.to_s.humanize}/Password combination is not valid" + end + errors.add(:base, I18n.t('error_messages.general_credentials_error', default: error_message)) end def generalize_credentials_error_messages? self.class.generalize_credentials_error_messages end @@ -287,21 +272,9 @@ self.class.password_field end def verify_password_method self.class.verify_password_method - end - - # In Rails 5 the ActionController::Parameters no longer inherits from HashWithIndifferentAccess. - # See: http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#actioncontroller-parameters-no-longer-inherits-from-hashwithindifferentaccess - # This method converts the ActionController::Parameters to a Hash - def parse_param_val(value) - if value.first.class.name == "ActionController::Parameters" - ActiveSupport::Deprecation.warn(E_AC_PARAMETERS) - [value.first.to_h] - else - value.is_a?(Array) ? value : [value] - end end end end end end