summaryrefslogtreecommitdiff
path: root/app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb')
-rw-r--r--app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb50
1 files changed, 38 insertions, 12 deletions
diff --git a/app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb b/app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb
index 6014ed0dd13..03783cd75a3 100644
--- a/app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb
+++ b/app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb
@@ -11,7 +11,13 @@ module Authenticates2FAForAdminMode
return handle_locked_user(user) unless user.can?(:log_in)
session[:otp_user_id] = user.id
- setup_u2f_authentication(user)
+ push_frontend_feature_flag(:webauthn)
+
+ if user.two_factor_webauthn_enabled?
+ setup_webauthn_authentication(user)
+ else
+ setup_u2f_authentication(user)
+ end
render 'admin/sessions/two_factor', layout: 'application'
end
@@ -24,7 +30,11 @@ module Authenticates2FAForAdminMode
if user_params[:otp_attempt].present? && session[:otp_user_id]
admin_mode_authenticate_with_two_factor_via_otp(user)
elsif user_params[:device_response].present? && session[:otp_user_id]
- admin_mode_authenticate_with_two_factor_via_u2f(user)
+ if user.two_factor_webauthn_enabled?
+ admin_mode_authenticate_with_two_factor_via_webauthn(user)
+ else
+ admin_mode_authenticate_with_two_factor_via_u2f(user)
+ end
elsif user && user.valid_password?(user_params[:password])
admin_mode_prompt_for_two_factor(user)
else
@@ -52,18 +62,17 @@ module Authenticates2FAForAdminMode
def admin_mode_authenticate_with_two_factor_via_u2f(user)
if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenge])
- # Remove any lingering user data from login
- session.delete(:otp_user_id)
- session.delete(:challenge)
-
- # The admin user has successfully passed 2fa, enable admin mode ignoring password
- enable_admin_mode
+ admin_handle_two_factor_success
else
- user.increment_failed_attempts!
- Gitlab::AppLogger.info("Failed Admin Mode Login: user=#{user.username} ip=#{request.remote_ip} method=U2F")
- flash.now[:alert] = _('Authentication via U2F device failed.')
+ admin_handle_two_factor_failure(user, 'U2F')
+ end
+ end
- admin_mode_prompt_for_two_factor(user)
+ def admin_mode_authenticate_with_two_factor_via_webauthn(user)
+ if Webauthn::AuthenticateService.new(user, user_params[:device_response], session[:challenge]).execute
+ admin_handle_two_factor_success
+ else
+ admin_handle_two_factor_failure(user, 'WebAuthn')
end
end
@@ -81,4 +90,21 @@ module Authenticates2FAForAdminMode
flash.now[:alert] = _('Invalid login or password')
render :new
end
+
+ def admin_handle_two_factor_success
+ # Remove any lingering user data from login
+ session.delete(:otp_user_id)
+ session.delete(:challenge)
+
+ # The admin user has successfully passed 2fa, enable admin mode ignoring password
+ enable_admin_mode
+ end
+
+ def admin_handle_two_factor_failure(user, method)
+ user.increment_failed_attempts!
+ Gitlab::AppLogger.info("Failed Admin Mode Login: user=#{user.username} ip=#{request.remote_ip} method=#{method}")
+ flash.now[:alert] = _('Authentication via %{method} device failed.') % { method: method }
+
+ admin_mode_prompt_for_two_factor(user)
+ end
end