diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2020-06-09 10:23:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-09 10:23:06 +0200 |
commit | 72a7cfaa395bbddabd0f0a712165fd7babf5d58c (patch) | |
tree | b983e24cda49dfaae2a08ef7193af1424e6b8f9b /app/controllers/concerns/two_factor_authentication_concern.rb | |
parent | 8b6d97fb7cc80321834f95bdee56e31676e1cff6 (diff) |
Add e-mail-based sign in challenge for users with disabled 2FA (#14013)
Diffstat (limited to 'app/controllers/concerns/two_factor_authentication_concern.rb')
-rw-r--r-- | app/controllers/concerns/two_factor_authentication_concern.rb | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/app/controllers/concerns/two_factor_authentication_concern.rb b/app/controllers/concerns/two_factor_authentication_concern.rb new file mode 100644 index 000000000..cdd8d14af --- /dev/null +++ b/app/controllers/concerns/two_factor_authentication_concern.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module TwoFactorAuthenticationConcern + extend ActiveSupport::Concern + + included do + prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create] + end + + def two_factor_enabled? + find_user&.otp_required_for_login? + end + + def valid_otp_attempt?(user) + user.validate_and_consume_otp!(user_params[:otp_attempt]) || + user.invalidate_otp_backup_code!(user_params[:otp_attempt]) + rescue OpenSSL::Cipher::CipherError + false + end + + def authenticate_with_two_factor + user = self.resource = find_user + + if user_params[:otp_attempt].present? && session[:attempt_user_id] + authenticate_with_two_factor_attempt(user) + elsif user.present? && user.external_or_valid_password?(user_params[:password]) + prompt_for_two_factor(user) + end + end + + def authenticate_with_two_factor_attempt(user) + if valid_otp_attempt?(user) + session.delete(:attempt_user_id) + remember_me(user) + sign_in(user) + else + flash.now[:alert] = I18n.t('users.invalid_otp_token') + prompt_for_two_factor(user) + end + end + + def prompt_for_two_factor(user) + session[:attempt_user_id] = user.id + @body_classes = 'lighter' + render :two_factor + end +end |