Module: Users::EmailOtpEnrollment
- Extended by:
- ActiveSupport::Concern
- Included in:
- User
- Defined in:
- app/models/concerns/users/email_otp_enrollment.rb
Instance Method Summary collapse
- #can_modify_email_otp_enrollment? ⇒ Boolean
- #email_otp_enrollment_restriction ⇒ Object
-
#email_otp_required_as_boolean ⇒ Object
These two methods allow us to treat email OTP enrollment as a boolean, while still preserving the enrollment date itself.
- #email_otp_required_as_boolean=(value) ⇒ Object
- #must_require_email_otp? ⇒ Boolean
-
#set_email_otp_required_after_based_on_restrictions(save: false) ⇒ Object
Ensures email_otp_required_after is in a valid state based on the restrictions applied to the user (instance settings, group policies, etc).
Instance Method Details
#can_modify_email_otp_enrollment? ⇒ Boolean
21 22 23 |
# File 'app/models/concerns/users/email_otp_enrollment.rb', line 21 def can_modify_email_otp_enrollment? email_otp_enrollment_restriction.nil? end |
#email_otp_enrollment_restriction ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'app/models/concerns/users/email_otp_enrollment.rb', line 25 def email_otp_enrollment_restriction return :feature_disabled unless Feature.enabled?(:email_based_mfa, self) return :uses_external_authenticator if password_automatically_set? # TwoFactorAuthVerifier provides Group, Global, and Admin 2FA # restriction logic reason = Gitlab::Auth::TwoFactorAuthVerifier.new(self).two_factor_authentication_reason return :"#{reason}_enforcement" if reason return :future_enforcement if email_otp_required_after&.future? return :email_otp_required if must_require_email_otp? nil end |
#email_otp_required_as_boolean ⇒ Object
These two methods allow us to treat email OTP enrollment as a boolean, while still preserving the enrollment date itself.
9 10 11 |
# File 'app/models/concerns/users/email_otp_enrollment.rb', line 9 def email_otp_required_as_boolean email_otp_required_after.present? end |
#email_otp_required_as_boolean=(value) ⇒ Object
13 14 15 16 17 18 19 |
# File 'app/models/concerns/users/email_otp_enrollment.rb', line 13 def email_otp_required_as_boolean=(value) if ActiveModel::Type::Boolean.new.cast(value) self.email_otp_required_after ||= Time.current else self.email_otp_required_after = nil end end |
#must_require_email_otp? ⇒ Boolean
40 41 42 43 44 |
# File 'app/models/concerns/users/email_otp_enrollment.rb', line 40 def must_require_email_otp? !password_automatically_set? && Gitlab::CurrentSettings.require_minimum_email_based_otp_for_users_with_passwords? && !two_factor_enabled? end |
#set_email_otp_required_after_based_on_restrictions(save: false) ⇒ Object
Ensures email_otp_required_after is in a valid state based on the restrictions applied to the user (instance settings, group policies, etc).
Sets the value directly on user_detail because delegated attributes don’t propagate dirty state to the parent User model, which would prevent changes from being saved.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'app/models/concerns/users/email_otp_enrollment.rb', line 56 def set_email_otp_required_after_based_on_restrictions(save: false) return unless Feature.enabled?(:email_based_mfa, self) if email_otp_required_after.nil? && must_require_email_otp? # Revert if being changed to nil, or set to Time.current if # it was always nil but shouldn't be user_detail.email_otp_required_after = user_detail.email_otp_required_after_was || Time.current elsif Gitlab::Auth::TwoFactorAuthVerifier.new(self).two_factor_authentication_required? && two_factor_enabled? # Email OTP has less security assurance than 2FA. Therefore, # don't allow email OTP when 2FA is required & configured. user_detail.email_otp_required_after = nil end # If neither condition is true, email_otp_required_after does not # need to be modified. return unless user_detail.email_otp_required_after_changed? Gitlab::AppLogger.info( message: "set_email_otp_required_after_based_on_restrictions is modifying email_otp_required_after", change: { before: user_detail.email_otp_required_after_was, after: user_detail.email_otp_required_after }, user_id: id ) # Conditionally save the record, with error logging instead of # raising. return unless save && !user_detail.save Gitlab::AppLogger.warn( message: 'set_email_otp_required_after_based_on_restrictions failed to save', change: { before: user_detail.email_otp_required_after_was, after: user_detail.email_otp_required_after }, errors: user_detail.errors. ) end |