From 560a1cb16f695ce6381b1a2ef063b91b2eb915c4 Mon Sep 17 00:00:00 2001 From: Vasiliy Ermolovich Date: Fri, 29 Nov 2024 13:56:24 +0100 Subject: [PATCH] Use proc to set password length validation so it's possible to override it dynamically. Co-authored-by: Manoj M J --- CHANGELOG.md | 12 ++++++++++++ lib/devise/models/validatable.rb | 4 +++- test/models_test.rb | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 104b9057ec..28c1240b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,19 @@ * Removed deprecations warning output for `Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION` (@soartec-lab) * Add Rails 8 support. - Routes are lazy-loaded by default in test and development environments now so Devise loads them before `Devise.mappings` call. + * Password length validator is changed from + ``` + validates_length_of :password, within: password_length, allow_blank: true` + ``` + + to + + ``` + validates_length_of :password, minimum: proc { password_length.min }, maximum: proc { password_length.max }, allow_blank: true + ``` + + so it's possible to override `password_length` at runtime. (@manojmj92) * bug fixes * Make `Devise` work without `ActionMailer` when `Zeitwerk` autoloader is used. diff --git a/lib/devise/models/validatable.rb b/lib/devise/models/validatable.rb index 1c22fb5fec..62486cfbe0 100644 --- a/lib/devise/models/validatable.rb +++ b/lib/devise/models/validatable.rb @@ -14,6 +14,8 @@ module Models # * +email_regexp+: the regular expression used to validate e-mails; # * +password_length+: a range expressing password length. Defaults to 6..128. # + # Since +password_length+ is applied in a proc within `validates_length_of` it can be overridden + # at runtime. module Validatable # All validations used by this module. VALIDATIONS = [:validates_presence_of, :validates_uniqueness_of, :validates_format_of, @@ -34,7 +36,7 @@ def self.included(base) validates_presence_of :password, if: :password_required? validates_confirmation_of :password, if: :password_required? - validates_length_of :password, within: password_length, allow_blank: true + validates_length_of :password, minimum: proc { password_length.min }, maximum: proc { password_length.max }, allow_blank: true end end diff --git a/test/models_test.rb b/test/models_test.rb index c213d20470..16acb92c98 100644 --- a/test/models_test.rb +++ b/test/models_test.rb @@ -26,8 +26,8 @@ def assert_include_modules(klass, *modules) test 'validations options are not applied too late' do validators = WithValidation.validators_on :password length = validators.find { |v| v.kind == :length } - assert_equal 2, length.options[:minimum] - assert_equal 6, length.options[:maximum] + assert_equal 2, length.options[:minimum].call + assert_equal 6, length.options[:maximum].call end test 'validations are applied just once' do