diff --git a/app/models/concerns/password_complexity_concern.rb b/app/models/concerns/password_complexity_concern.rb new file mode 100644 index 000000000..bbcef17fc --- /dev/null +++ b/app/models/concerns/password_complexity_concern.rb @@ -0,0 +1,23 @@ +module PasswordComplexityConcern + extend ActiveSupport::Concern + + # Allows adding a condition to the password complexity validation. + # Default is yes. Can be overridden in included classes. + def validate_password_complexity? + true + end + + included do + # Add a validator for password complexity. + # + # The validator triggers as soon as the password is long enough (to avoid presenting + # two errors when the password is too short, one about length and one about complexity). + validates :password, password_complexity: true, if: -> { password_has_minimum_length? && validate_password_complexity? } + end + + private + + def password_has_minimum_length? + self.class.password_length.include?(password.try(:size)) + end +end diff --git a/app/models/super_admin.rb b/app/models/super_admin.rb index eeb69a255..e849ce3e6 100644 --- a/app/models/super_admin.rb +++ b/app/models/super_admin.rb @@ -25,11 +25,11 @@ # updated_at :datetime # class SuperAdmin < ApplicationRecord + include PasswordComplexityConcern + devise :rememberable, :trackable, :validatable, :lockable, :async, :recoverable, :two_factor_authenticatable, :otp_secret_encryption_key => Rails.application.secrets.otp_secret_key - validates :password, password_complexity: true, if: -> (u) { Devise.password_length.include?(u.password.try(:size)) } - def enable_otp! self.otp_secret = SuperAdmin.generate_otp_secret self.otp_required_for_login = true diff --git a/app/models/user.rb b/app/models/user.rb index 9fde0c77d..32219d6b7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -31,6 +31,7 @@ # class User < ApplicationRecord include EmailSanitizableConcern + include PasswordComplexityConcern enum loged_in_with_france_connect: { particulier: 'particulier', @@ -57,7 +58,9 @@ class User < ApplicationRecord before_validation -> { sanitize_email(:email) } - validates :password, password_complexity: true, if: -> (u) { u.administrateur.present? && Devise.password_length.include?(u.password.try(:size)) } + def validate_password_complexity? + administrateur? + end # Override of Devise::Models::Confirmable#send_confirmation_instructions def send_confirmation_instructions