Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 14:18:08 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 14:18:08 +0300
commit5afcbe03ead9ada87621888a31a62652b10a7e4f (patch)
tree9918b67a0d0f0bafa6542e839a8be37adf73102d /lib/gitlab/auth/devise/strategies/combined_two_factor_authenticatable.rb
parentc97c0201564848c1f53226fe19d71fdcc472f7d0 (diff)
Add latest changes from gitlab-org/gitlab@16-4-stable-eev16.4.0-rc42
Diffstat (limited to 'lib/gitlab/auth/devise/strategies/combined_two_factor_authenticatable.rb')
-rw-r--r--lib/gitlab/auth/devise/strategies/combined_two_factor_authenticatable.rb52
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/gitlab/auth/devise/strategies/combined_two_factor_authenticatable.rb b/lib/gitlab/auth/devise/strategies/combined_two_factor_authenticatable.rb
new file mode 100644
index 00000000000..ef326fd2a99
--- /dev/null
+++ b/lib/gitlab/auth/devise/strategies/combined_two_factor_authenticatable.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Auth
+ module Devise
+ module Strategies
+ # This strategy combines the following strategies from
+ # devise_two_factor gem:
+ # - TwoFactorAuthenticatable: https://github.com/devise-two-factor/devise-two-factor/blob/v4.0.2/lib/devise_two_factor/strategies/two_factor_authenticatable.rb
+ # - TwoFactorBackupable: https://github.com/devise-two-factor/devise-two-factor/blob/v4.0.2/lib/devise_two_factor/strategies/two_factor_backupable.rb
+ # to avoid double incrementing failed login attempts counter by each
+ # strategy in case an incorrect password is provided.
+ class CombinedTwoFactorAuthenticatable < ::Devise::Strategies::DatabaseAuthenticatable
+ def authenticate!
+ resource = mapping.to.find_for_database_authentication(authentication_hash)
+
+ # We check the OTP / backup code, then defer to DatabaseAuthenticatable
+ is_valid = validate(resource) do
+ validate_otp(resource) || resource.invalidate_otp_backup_code!(params[scope]['otp_attempt'])
+ end
+
+ if is_valid
+ # Devise fails to authenticate invalidated resources, but if we've
+ # gotten here, the object changed (Since we deleted a recovery code)
+ resource.save!
+
+ super
+ end
+
+ fail(::Devise.paranoid ? :invalid : :not_found_in_database) unless resource # rubocop: disable Style/SignalException
+
+ # We want to cascade to the next strategy if this one fails,
+ # but database authenticatable automatically halts on a bad password
+ @halted = false if @result == :failure
+ end
+
+ def validate_otp(resource)
+ return true unless resource.otp_required_for_login
+
+ return if params[scope]['otp_attempt'].nil?
+
+ resource.validate_and_consume_otp!(params[scope]['otp_attempt'])
+ end
+ end
+ end
+ end
+ end
+end
+
+Warden::Strategies.add(
+ :combined_two_factor_authenticatable,
+ Gitlab::Auth::Devise::Strategies::CombinedTwoFactorAuthenticatable)