diff options
Diffstat (limited to 'app/controllers/admin/concerns')
-rw-r--r-- | app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb | 50 |
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 |