2022-05-07 20:08:51 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module SearchRateLimitable
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def check_search_rate_limit!
|
|
|
|
if current_user
|
2023-07-09 08:55:56 +05:30
|
|
|
# Because every search in the UI typically runs concurrent searches with different
|
|
|
|
# scopes to get counts, we apply rate limits on the search scope if it is present.
|
|
|
|
#
|
|
|
|
# If abusive search is detected, we have stricter limits and ignore the search scope.
|
|
|
|
check_rate_limit!(:search_rate_limit, scope: [current_user, safe_search_scope].compact)
|
2022-05-07 20:08:51 +05:30
|
|
|
else
|
|
|
|
check_rate_limit!(:search_rate_limit_unauthenticated, scope: [request.ip])
|
|
|
|
end
|
|
|
|
end
|
2023-07-09 08:55:56 +05:30
|
|
|
|
|
|
|
def safe_search_scope
|
|
|
|
# Sometimes search scope can have abusive length or invalid keyword. We don't want
|
|
|
|
# to send those to redis for rate limit checks, so we guard against that here.
|
|
|
|
return if Feature.disabled?(:search_rate_limited_scopes) || abuse_detected?
|
|
|
|
|
|
|
|
params[:scope]
|
|
|
|
end
|
|
|
|
|
|
|
|
def abuse_detected?
|
|
|
|
Gitlab::Search::Params.new(params, detect_abuse: true).abusive?
|
|
|
|
end
|
2022-05-07 20:08:51 +05:30
|
|
|
end
|