diff options
Diffstat (limited to 'lib/gitlab/auth/blocked_user_tracker.rb')
-rw-r--r-- | lib/gitlab/auth/blocked_user_tracker.rb | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/lib/gitlab/auth/blocked_user_tracker.rb b/lib/gitlab/auth/blocked_user_tracker.rb index 7609a7b04f6..b6d2adc834b 100644 --- a/lib/gitlab/auth/blocked_user_tracker.rb +++ b/lib/gitlab/auth/blocked_user_tracker.rb @@ -2,37 +2,58 @@ module Gitlab module Auth class BlockedUserTracker + include Gitlab::Utils::StrongMemoize + ACTIVE_RECORD_REQUEST_PARAMS = 'action_dispatch.request.request_parameters' - def self.log_if_user_blocked(env) - message = env.dig('warden.options', :message) + def initialize(env) + @env = env + end - # Devise calls User#active_for_authentication? on the User model and then - # throws an exception to Warden with User#inactive_message: - # https://github.com/plataformatec/devise/blob/v4.2.1/lib/devise/hooks/activatable.rb#L8 - # - # Since Warden doesn't pass the user record to the failure handler, we - # need to do a database lookup with the username. We can limit the - # lookups to happen when the user was blocked by checking the inactive - # message passed along by Warden. - return unless message == User::BLOCKED_MESSAGE + def user_blocked? + user&.blocked? + end - # Check for either LDAP or regular GitLab account logins - login = env.dig(ACTIVE_RECORD_REQUEST_PARAMS, 'username') || - env.dig(ACTIVE_RECORD_REQUEST_PARAMS, 'user', 'login') + def user + return unless has_user_blocked_message? - return unless login.present? + strong_memoize(:user) do + # Check for either LDAP or regular GitLab account logins + login = @env.dig(ACTIVE_RECORD_REQUEST_PARAMS, 'username') || + @env.dig(ACTIVE_RECORD_REQUEST_PARAMS, 'user', 'login') - user = User.by_login(login) + User.by_login(login) if login.present? + end + rescue TypeError + end - return unless user&.blocked? + def log_blocked_user_activity! + return unless user_blocked? - Gitlab::AppLogger.info("Failed login for blocked user: user=#{user.username} ip=#{env['REMOTE_ADDR']}") + Gitlab::AppLogger.info("Failed login for blocked user: user=#{user.username} ip=#{@env['REMOTE_ADDR']}") SystemHooksService.new.execute_hooks_for(user, :failed_login) - true rescue TypeError end + + private + + ## + # Devise calls User#active_for_authentication? on the User model and then + # throws an exception to Warden with User#inactive_message: + # https://github.com/plataformatec/devise/blob/v4.2.1/lib/devise/hooks/activatable.rb#L8 + # + # Since Warden doesn't pass the user record to the failure handler, we + # need to do a database lookup with the username. We can limit the + # lookups to happen when the user was blocked by checking the inactive + # message passed along by Warden. + # + def has_user_blocked_message? + strong_memoize(:user_blocked_message) do + message = @env.dig('warden.options', :message) + message == User::BLOCKED_MESSAGE + end + end end end end |