Commit 4f641864 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'ld-rename-query_limiting_whitelist-to-allowlist' into 'master'

Rename QueryLimiting.whitelist to .disable! [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!55717
parents c8f44dbc 32c45159
...@@ -11,7 +11,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -11,7 +11,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
# https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233 # https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233
before_action :set_application_setting, except: :integrations before_action :set_application_setting, except: :integrations
before_action :whitelist_query_limiting, only: [:usage_data] before_action :disable_query_limiting, only: [:usage_data]
before_action only: [:ci_cd] do before_action only: [:ci_cd] do
push_frontend_feature_flag(:ci_instance_variables_ui, default_enabled: true) push_frontend_feature_flag(:ci_instance_variables_ui, default_enabled: true)
...@@ -194,8 +194,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -194,8 +194,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
@plans = Plan.all @plans = Plan.all
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/63107') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/63107')
end end
def application_setting_params def application_setting_params
......
...@@ -4,7 +4,7 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -4,7 +4,7 @@ class Admin::ServicesController < Admin::ApplicationController
include ServiceParams include ServiceParams
before_action :service, only: [:edit, :update] before_action :service, only: [:edit, :update]
before_action :whitelist_query_limiting, only: [:index] before_action :disable_query_limiting, only: [:index]
feature_category :integrations feature_category :integrations
...@@ -39,7 +39,7 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -39,7 +39,7 @@ class Admin::ServicesController < Admin::ApplicationController
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/-/issues/220357') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/220357')
end end
end end
...@@ -13,7 +13,7 @@ module Boards ...@@ -13,7 +13,7 @@ module Boards
requires_cross_project_access if: -> { board&.group_board? } requires_cross_project_access if: -> { board&.group_board? }
before_action :whitelist_query_limiting, only: [:bulk_move] before_action :disable_query_limiting, only: [:bulk_move]
before_action :authorize_read_issue, only: [:index] before_action :authorize_read_issue, only: [:index]
before_action :authorize_create_issue, only: [:create] before_action :authorize_create_issue, only: [:create]
before_action :authorize_update_issue, only: [:update] before_action :authorize_update_issue, only: [:update]
...@@ -147,8 +147,8 @@ module Boards ...@@ -147,8 +147,8 @@ module Boards
serializer.represent(resource, opts) serializer.represent(resource, opts)
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/35174') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/35174')
end end
def validate_id_list def validate_id_list
......
...@@ -4,7 +4,8 @@ class GraphqlController < ApplicationController ...@@ -4,7 +4,8 @@ class GraphqlController < ApplicationController
# Unauthenticated users have access to the API for public data # Unauthenticated users have access to the API for public data
skip_before_action :authenticate_user! skip_before_action :authenticate_user!
WHITELIST_HEADER = 'HTTP_X_GITLAB_QUERY_WHITELIST_ISSUE' # Header can be passed by tests to disable SQL query limits.
DISABLE_SQL_QUERY_LIMIT_HEADER = 'HTTP_X_GITLAB_DISABLE_SQL_QUERY_LIMIT'
# If a user is using their session to access GraphQL, we need to have session # If a user is using their session to access GraphQL, we need to have session
# storage, since the admin-mode check is session wide. # storage, since the admin-mode check is session wide.
...@@ -23,7 +24,7 @@ class GraphqlController < ApplicationController ...@@ -23,7 +24,7 @@ class GraphqlController < ApplicationController
before_action(only: [:execute]) { authenticate_sessionless_user!(:api) } before_action(only: [:execute]) { authenticate_sessionless_user!(:api) }
before_action :set_user_last_activity before_action :set_user_last_activity
before_action :track_vs_code_usage before_action :track_vs_code_usage
before_action :whitelist_query! before_action :disable_query_limiting
# Since we deactivate authentication from the main ApplicationController and # Since we deactivate authentication from the main ApplicationController and
# defer it to :authorize_access_api!, we need to override the bypass session # defer it to :authorize_access_api!, we need to override the bypass session
...@@ -62,12 +63,14 @@ class GraphqlController < ApplicationController ...@@ -62,12 +63,14 @@ class GraphqlController < ApplicationController
private private
# Tests may mark some queries as exempt from query limits # Tests may mark some GraphQL queries as exempt from SQL query limits
def whitelist_query! def disable_query_limiting
whitelist_issue = request.headers[WHITELIST_HEADER] return unless Gitlab::QueryLimiting.enabled_for_env?
return unless whitelist_issue
Gitlab::QueryLimiting.whitelist(whitelist_issue) disable_issue = request.headers[DISABLE_SQL_QUERY_LIMIT_HEADER]
return unless disable_issue
Gitlab::QueryLimiting.disable!(disable_issue)
end end
def set_user_last_activity def set_user_last_activity
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
class Import::GitlabProjectsController < Import::BaseController class Import::GitlabProjectsController < Import::BaseController
include WorkhorseAuthorization include WorkhorseAuthorization
before_action :whitelist_query_limiting, only: [:create] before_action :disable_query_limiting, only: [:create]
before_action :verify_gitlab_project_import_enabled before_action :verify_gitlab_project_import_enabled
def new def new
...@@ -42,8 +42,8 @@ class Import::GitlabProjectsController < Import::BaseController ...@@ -42,8 +42,8 @@ class Import::GitlabProjectsController < Import::BaseController
) )
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42437') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42437')
end end
def uploader_class def uploader_class
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
class Import::ManifestController < Import::BaseController class Import::ManifestController < Import::BaseController
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
before_action :whitelist_query_limiting, only: [:create] before_action :disable_query_limiting, only: [:create]
before_action :verify_import_enabled before_action :verify_import_enabled
before_action :ensure_import_vars, only: [:create, :status] before_action :ensure_import_vars, only: [:create, :status]
...@@ -115,7 +115,7 @@ class Import::ManifestController < Import::BaseController ...@@ -115,7 +115,7 @@ class Import::ManifestController < Import::BaseController
render_404 unless manifest_import_enabled? render_404 unless manifest_import_enabled?
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/48939') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/48939')
end end
end end
...@@ -8,7 +8,7 @@ class Projects::CommitsController < Projects::ApplicationController ...@@ -8,7 +8,7 @@ class Projects::CommitsController < Projects::ApplicationController
prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:rss) } prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:rss) }
around_action :allow_gitaly_ref_name_caching around_action :allow_gitaly_ref_name_caching
before_action :whitelist_query_limiting, except: :commits_root before_action :disable_query_limiting, except: :commits_root
before_action :require_non_empty_project before_action :require_non_empty_project
before_action :assign_ref_vars, except: :commits_root before_action :assign_ref_vars, except: :commits_root
before_action :authorize_download_code! before_action :authorize_download_code!
...@@ -83,7 +83,7 @@ class Projects::CommitsController < Projects::ApplicationController ...@@ -83,7 +83,7 @@ class Projects::CommitsController < Projects::ApplicationController
@commits = set_commits_for_rendering(@commits) @commits = set_commits_for_rendering(@commits)
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42330') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42330')
end end
end end
...@@ -7,7 +7,7 @@ class Projects::ForksController < Projects::ApplicationController ...@@ -7,7 +7,7 @@ class Projects::ForksController < Projects::ApplicationController
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
# Authorize # Authorize
before_action :whitelist_query_limiting, only: [:create] before_action :disable_query_limiting, only: [:create]
before_action :require_non_empty_project before_action :require_non_empty_project
before_action :authorize_download_code! before_action :authorize_download_code!
before_action :authenticate_user!, only: [:new, :create] before_action :authenticate_user!, only: [:new, :create]
...@@ -110,8 +110,8 @@ class Projects::ForksController < Projects::ApplicationController ...@@ -110,8 +110,8 @@ class Projects::ForksController < Projects::ApplicationController
access_denied! unless fork_namespace && fork_service.valid_fork_target? access_denied! unless fork_namespace && fork_service.valid_fork_target?
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42335') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42335')
end end
def load_namespaces_with_associations def load_namespaces_with_associations
......
...@@ -18,7 +18,7 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -18,7 +18,7 @@ class Projects::IssuesController < Projects::ApplicationController
prepend_before_action :authenticate_user!, only: [:new, :export_csv] prepend_before_action :authenticate_user!, only: [:new, :export_csv]
prepend_before_action :store_uri, only: [:new, :show, :designs] prepend_before_action :store_uri, only: [:new, :show, :designs]
before_action :whitelist_query_limiting, only: [:create, :create_merge_request, :move, :bulk_update] before_action :disable_query_limiting, only: [:create, :create_merge_request, :move, :bulk_update]
before_action :check_issues_available! before_action :check_issues_available!
before_action :issue, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) } before_action :issue, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) }
after_action :log_issue_show, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) } after_action :log_issue_show, unless: ->(c) { ISSUES_EXCEPT_ACTIONS.include?(c.action_name.to_sym) }
...@@ -353,13 +353,13 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -353,13 +353,13 @@ class Projects::IssuesController < Projects::ApplicationController
IssuesFinder IssuesFinder
end end
def whitelist_query_limiting def disable_query_limiting
# Also see the following issues: # Also see the following issues:
# #
# 1. https://gitlab.com/gitlab-org/gitlab-foss/issues/42423 # 1. https://gitlab.com/gitlab-org/gitlab-foss/issues/42423
# 2. https://gitlab.com/gitlab-org/gitlab-foss/issues/42424 # 2. https://gitlab.com/gitlab-org/gitlab-foss/issues/42424
# 3. https://gitlab.com/gitlab-org/gitlab-foss/issues/42426 # 3. https://gitlab.com/gitlab-org/gitlab-foss/issues/42426
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42422') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42422')
end end
private private
......
...@@ -6,7 +6,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap ...@@ -6,7 +6,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
include RendersCommits include RendersCommits
skip_before_action :merge_request skip_before_action :merge_request
before_action :whitelist_query_limiting, only: [:create] before_action :disable_query_limiting, only: [:create]
before_action :authorize_create_merge_request_from! before_action :authorize_create_merge_request_from!
before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path] before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path]
before_action :build_merge_request, except: [:create] before_action :build_merge_request, except: [:create]
...@@ -133,8 +133,8 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap ...@@ -133,8 +133,8 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42384') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42384')
end end
def incr_count_webide_merge_request def incr_count_webide_merge_request
......
...@@ -14,7 +14,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -14,7 +14,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
skip_before_action :merge_request, only: [:index, :bulk_update, :export_csv] skip_before_action :merge_request, only: [:index, :bulk_update, :export_csv]
before_action :apply_diff_view_cookie!, only: [:show] before_action :apply_diff_view_cookie!, only: [:show]
before_action :whitelist_query_limiting, only: [:assign_related_issues, :update] before_action :disable_query_limiting, only: [:assign_related_issues, :update]
before_action :authorize_update_issuable!, only: [:close, :edit, :update, :remove_wip, :sort] before_action :authorize_update_issuable!, only: [:close, :edit, :update, :remove_wip, :sort]
before_action :authorize_read_actual_head_pipeline!, only: [ before_action :authorize_read_actual_head_pipeline!, only: [
:test_reports, :test_reports,
...@@ -468,9 +468,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -468,9 +468,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
access_denied! unless @merge_request.can_be_merged_by?(current_user) access_denied! unless @merge_request.can_be_merged_by?(current_user)
end end
def whitelist_query_limiting def disable_query_limiting
# Also see https://gitlab.com/gitlab-org/gitlab-foss/issues/42441 # Also see https://gitlab.com/gitlab-org/gitlab-foss/issues/42441
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42438') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42438')
end end
def reports_response(report_comparison, pipeline = nil) def reports_response(report_comparison, pipeline = nil)
......
...@@ -4,7 +4,7 @@ class Projects::NetworkController < Projects::ApplicationController ...@@ -4,7 +4,7 @@ class Projects::NetworkController < Projects::ApplicationController
include ExtractsPath include ExtractsPath
include ApplicationHelper include ApplicationHelper
before_action :whitelist_query_limiting before_action :disable_query_limiting
before_action :require_non_empty_project before_action :require_non_empty_project
before_action :assign_ref_vars before_action :assign_ref_vars
before_action :authorize_download_code! before_action :authorize_download_code!
...@@ -42,7 +42,7 @@ class Projects::NetworkController < Projects::ApplicationController ...@@ -42,7 +42,7 @@ class Projects::NetworkController < Projects::ApplicationController
@commit = @repo.commit(@options[:extended_sha1]) @commit = @repo.commit(@options[:extended_sha1])
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42333') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42333')
end end
end end
...@@ -6,7 +6,7 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -6,7 +6,7 @@ class Projects::NotesController < Projects::ApplicationController
include NotesHelper include NotesHelper
include ToggleAwardEmoji include ToggleAwardEmoji
before_action :whitelist_query_limiting, only: [:create, :update] before_action :disable_query_limiting, only: [:create, :update]
before_action :authorize_read_note! before_action :authorize_read_note!
before_action :authorize_create_note!, only: [:create] before_action :authorize_create_note!, only: [:create]
before_action :authorize_resolve_note!, only: [:resolve, :unresolve] before_action :authorize_resolve_note!, only: [:resolve, :unresolve]
...@@ -87,7 +87,7 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -87,7 +87,7 @@ class Projects::NotesController < Projects::ApplicationController
access_denied! unless can?(current_user, :create_note, noteable) access_denied! unless can?(current_user, :create_note, noteable)
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42383') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42383')
end end
end end
...@@ -4,7 +4,7 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -4,7 +4,7 @@ class Projects::PipelinesController < Projects::ApplicationController
include ::Gitlab::Utils::StrongMemoize include ::Gitlab::Utils::StrongMemoize
include Analytics::UniqueVisitsHelper include Analytics::UniqueVisitsHelper
before_action :whitelist_query_limiting, only: [:create, :retry] before_action :disable_query_limiting, only: [:create, :retry]
before_action :pipeline, except: [:index, :new, :create, :charts, :config_variables] before_action :pipeline, except: [:index, :new, :create, :charts, :config_variables]
before_action :set_pipeline_path, only: [:show] before_action :set_pipeline_path, only: [:show]
before_action :authorize_read_pipeline! before_action :authorize_read_pipeline!
...@@ -92,7 +92,7 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -92,7 +92,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end end
def show def show
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/-/issues/26657') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/26657')
respond_to do |format| respond_to do |format|
format.html format.html
...@@ -269,9 +269,9 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -269,9 +269,9 @@ class Projects::PipelinesController < Projects::ApplicationController
&.present(current_user: current_user) &.present(current_user: current_user)
end end
def whitelist_query_limiting def disable_query_limiting
# Also see https://gitlab.com/gitlab-org/gitlab-foss/issues/42343 # Also see https://gitlab.com/gitlab-org/gitlab-foss/issues/42343
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42339') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42339')
end end
def authorize_update_pipeline! def authorize_update_pipeline!
......
...@@ -14,7 +14,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -14,7 +14,7 @@ class ProjectsController < Projects::ApplicationController
around_action :allow_gitaly_ref_name_caching, only: [:index, :show] around_action :allow_gitaly_ref_name_caching, only: [:index, :show]
before_action :whitelist_query_limiting, only: [:show, :create] before_action :disable_query_limiting, only: [:show, :create]
before_action :authenticate_user!, except: [:index, :show, :activity, :refs, :resolve, :unfoldered_environment_names] before_action :authenticate_user!, except: [:index, :show, :activity, :refs, :resolve, :unfoldered_environment_names]
before_action :redirect_git_extension, only: [:show] before_action :redirect_git_extension, only: [:show]
before_action :project, except: [:index, :new, :create, :resolve] before_action :project, except: [:index, :new, :create, :resolve]
...@@ -510,8 +510,8 @@ class ProjectsController < Projects::ApplicationController ...@@ -510,8 +510,8 @@ class ProjectsController < Projects::ApplicationController
redirect_to(request.original_url.sub(%r{\.git/?\Z}, '')) redirect_to(request.original_url.sub(%r{\.git/?\Z}, ''))
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/-/issues/20826') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/20826')
end end
def present_project def present_project
......
...@@ -9,7 +9,7 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -9,7 +9,7 @@ class RegistrationsController < Devise::RegistrationsController
layout 'devise' layout 'devise'
prepend_before_action :check_captcha, only: :create prepend_before_action :check_captcha, only: :create
before_action :whitelist_query_limiting, :ensure_destroy_prerequisites_met, only: [:destroy] before_action :disable_query_limiting, :ensure_destroy_prerequisites_met, only: [:destroy]
before_action :load_recaptcha, only: :new before_action :load_recaptcha, only: :new
before_action :set_invite_params, only: :new before_action :set_invite_params, only: :new
...@@ -162,8 +162,8 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -162,8 +162,8 @@ class RegistrationsController < Devise::RegistrationsController
@devise_mapping ||= Devise.mappings[:user] @devise_mapping ||= Devise.mappings[:user]
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42380') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42380')
end end
def load_recaptcha def load_recaptcha
......
...@@ -53,7 +53,7 @@ module Mutations ...@@ -53,7 +53,7 @@ module Mutations
end end
def resolve(board:, **args) def resolve(board:, **args)
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/-/issues/247861') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/247861')
raise_resource_not_available_error! unless board raise_resource_not_available_error! unless board
authorize_board!(board) authorize_board!(board)
......
...@@ -19,7 +19,7 @@ module Mutations ...@@ -19,7 +19,7 @@ module Mutations
def resolve(project_path:, iid:, assignee_usernames:, operation_mode: Types::MutationOperationModeEnum.enum[:replace]) def resolve(project_path:, iid:, assignee_usernames:, operation_mode: Types::MutationOperationModeEnum.enum[:replace])
resource = authorized_find!(project_path: project_path, iid: iid) resource = authorized_find!(project_path: project_path, iid: iid)
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/36098') if resource.is_a?(MergeRequest) Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/36098') if resource.is_a?(MergeRequest)
update_service_class.new( update_service_class.new(
resource.project, resource.project,
......
...@@ -11,7 +11,7 @@ module Mutations ...@@ -11,7 +11,7 @@ module Mutations
description: 'The project to move the issue to.' description: 'The project to move the issue to.'
def resolve(project_path:, iid:, target_project_path:) def resolve(project_path:, iid:, target_project_path:)
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/-/issues/267762') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/267762')
issue = authorized_find!(project_path: project_path, iid: iid) issue = authorized_find!(project_path: project_path, iid: iid)
source_project = issue.project source_project = issue.project
......
...@@ -42,7 +42,8 @@ module Mutations ...@@ -42,7 +42,8 @@ module Mutations
description: 'Squash commits on the source branch before merge.' description: 'Squash commits on the source branch before merge.'
def resolve(project_path:, iid:, **args) def resolve(project_path:, iid:, **args)
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42317') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42317')
merge_request = authorized_find!(project_path: project_path, iid: iid) merge_request = authorized_find!(project_path: project_path, iid: iid)
project = merge_request.target_project project = merge_request.target_project
merge_params = args.compact.with_indifferent_access merge_params = args.compact.with_indifferent_access
......
...@@ -48,7 +48,7 @@ class PostReceiveService ...@@ -48,7 +48,7 @@ class PostReceiveService
end end
def process_mr_push_options(push_options, changes) def process_mr_push_options(push_options, changes)
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/61359') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/61359')
return unless repository return unless repository
unless repository.repo_type.project? unless repository.repo_type.project?
......
# frozen_string_literal: true # frozen_string_literal: true
if Gitlab::QueryLimiting.enable? if Gitlab::QueryLimiting.enabled_for_env?
require_dependency 'gitlab/query_limiting/active_support_subscriber' require_dependency 'gitlab/query_limiting/active_support_subscriber'
require_dependency 'gitlab/query_limiting/transaction' require_dependency 'gitlab/query_limiting/transaction'
require_dependency 'gitlab/query_limiting/middleware' require_dependency 'gitlab/query_limiting/middleware'
......
...@@ -15,30 +15,30 @@ When a test fails because it executes more than 100 SQL queries there are two ...@@ -15,30 +15,30 @@ When a test fails because it executes more than 100 SQL queries there are two
solutions to this problem: solutions to this problem:
- Reduce the number of SQL queries that are executed. - Reduce the number of SQL queries that are executed.
- Whitelist the controller or API endpoint. - Disable query limiting for the controller or API endpoint.
You should only resort to whitelisting when an existing controller or endpoint You should only resort to disabling query limits when an existing controller or endpoint
is to blame as in this case reducing the number of SQL queries can take a lot of is to blame as in this case reducing the number of SQL queries can take a lot of
effort. Newly added controllers and endpoints are not allowed to execute more effort. Newly added controllers and endpoints are not allowed to execute more
than 100 SQL queries and no exceptions are made for this rule. _If_ a large than 100 SQL queries and no exceptions are made for this rule. _If_ a large
number of SQL queries is necessary to perform certain work it's best to have number of SQL queries is necessary to perform certain work it's best to have
this work performed by Sidekiq instead of doing this directly in a web request. this work performed by Sidekiq instead of doing this directly in a web request.
## Whitelisting ## Disable query limiting
In the event that you _have_ to whitelist a controller you must first In the event that you _have_ to disable query limits for a controller, you must first
create an issue. This issue should (preferably in the title) mention the create an issue. This issue should (preferably in the title) mention the
controller or endpoint and include the appropriate labels (`database`, controller or endpoint and include the appropriate labels (`database`,
`performance`, and at least a team specific label such as `Discussion`). `performance`, and at least a team specific label such as `Discussion`).
After the issue has been created you can whitelist the code in question. For After the issue has been created, you can disable query limits on the code in question. For
Rails controllers it's best to create a `before_action` hook that runs as early Rails controllers it's best to create a `before_action` hook that runs as early
as possible. The called method in turn should call as possible. The called method in turn should call
`Gitlab::QueryLimiting.whitelist('issue URL here')`. For example: `Gitlab::QueryLimiting.disable!('issue URL here')`. For example:
```ruby ```ruby
class MyController < ApplicationController class MyController < ApplicationController
before_action :whitelist_query_limiting, only: [:show] before_action :disable_query_limiting, only: [:show]
def index def index
# ... # ...
...@@ -48,8 +48,8 @@ class MyController < ApplicationController ...@@ -48,8 +48,8 @@ class MyController < ApplicationController
# ... # ...
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/...') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/...')
end end
end end
``` ```
...@@ -63,7 +63,7 @@ call directly into the endpoint like so: ...@@ -63,7 +63,7 @@ call directly into the endpoint like so:
```ruby ```ruby
get '/projects/:id/foo' do get '/projects/:id/foo' do
Gitlab::QueryLimiting.whitelist('...') Gitlab::QueryLimiting.disable!('...')
# ... # ...
end end
......
...@@ -9,8 +9,7 @@ module EE ...@@ -9,8 +9,7 @@ module EE
prepended do prepended do
include DescriptionDiffActions include DescriptionDiffActions
before_action :whitelist_query_limiting_ee, only: [:update] before_action :disable_query_limiting_ee, only: [:update]
before_action only: [:new, :create] do before_action only: [:new, :create] do
populate_vulnerability_id populate_vulnerability_id
end end
...@@ -43,8 +42,8 @@ module EE ...@@ -43,8 +42,8 @@ module EE
options.reject { |key| key == 'weight' } options.reject { |key| key == 'weight' }
end end
def whitelist_query_limiting_ee def disable_query_limiting_ee
::Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/4794') ::Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/4794')
end end
def issue_params def issue_params
......
...@@ -16,7 +16,7 @@ module EE ...@@ -16,7 +16,7 @@ module EE
push_frontend_feature_flag(:usage_data_i_testing_load_performance_widget_total, @project, default_enabled: true) push_frontend_feature_flag(:usage_data_i_testing_load_performance_widget_total, @project, default_enabled: true)
end end
before_action :whitelist_query_limiting_ee_merge, only: [:merge] before_action :disable_query_limiting_ee_merge, only: [:merge]
before_action :authorize_read_pipeline!, only: [:container_scanning_reports, :dependency_scanning_reports, before_action :authorize_read_pipeline!, only: [:container_scanning_reports, :dependency_scanning_reports,
:sast_reports, :secret_detection_reports, :dast_reports, :sast_reports, :secret_detection_reports, :dast_reports,
:metrics_reports, :coverage_fuzzing_reports, :metrics_reports, :coverage_fuzzing_reports,
...@@ -64,8 +64,8 @@ module EE ...@@ -64,8 +64,8 @@ module EE
private private
def whitelist_query_limiting_ee_merge def disable_query_limiting_ee_merge
::Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/4792') ::Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/4792')
end end
end end
end end
......
...@@ -115,7 +115,7 @@ module API ...@@ -115,7 +115,7 @@ module API
at_least_one_of :title, :description, :start_date_fixed, :start_date_is_fixed, :due_date_fixed, :due_date_is_fixed, :labels, :add_labels, :remove_labels, :state_event, :confidential at_least_one_of :title, :description, :start_date_fixed, :start_date_is_fixed, :due_date_fixed, :due_date_is_fixed, :labels, :add_labels, :remove_labels, :state_event, :confidential
end end
put ':id/(-/)epics/:epic_iid' do put ':id/(-/)epics/:epic_iid' do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/194104') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/194104')
authorize_can_admin_epic! authorize_can_admin_epic!
......
...@@ -90,7 +90,7 @@ module EE ...@@ -90,7 +90,7 @@ module EE
desc: 'Array of Group IDs to set as approvers.' desc: 'Array of Group IDs to set as approvers.'
end end
put 'approvers' do put 'approvers' do
::Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/8883') ::Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/8883')
merge_request = find_merge_request_with_access(params[:merge_request_iid], :update_approvers) merge_request = find_merge_request_with_access(params[:merge_request_iid], :update_approvers)
......
...@@ -70,7 +70,7 @@ module API ...@@ -70,7 +70,7 @@ module API
optional :variables, Array, desc: 'Array of variables available in the pipeline' optional :variables, Array, desc: 'Array of variables available in the pipeline'
end end
post ':id/pipeline' do post ':id/pipeline' do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42124') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42124')
authorize! :create_pipeline, user_project authorize! :create_pipeline, user_project
......
...@@ -112,7 +112,7 @@ module API ...@@ -112,7 +112,7 @@ module API
end end
def delete_group(group) def delete_group(group)
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/46285') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/46285')
destroy_conditionally!(group) do |group| destroy_conditionally!(group) do |group|
::Groups::DestroyService.new(group, current_user).async_execute ::Groups::DestroyService.new(group, current_user).async_execute
end end
......
...@@ -116,7 +116,7 @@ module API ...@@ -116,7 +116,7 @@ module API
end end
def create_note(noteable, opts) def create_note(noteable, opts)
whitelist_query_limiting disable_query_limiting
authorize!(:create_note, noteable) authorize!(:create_note, noteable)
parent = noteable_parent(noteable) parent = noteable_parent(noteable)
...@@ -144,8 +144,8 @@ module API ...@@ -144,8 +144,8 @@ module API
present discussion, with: Entities::Discussion present discussion, with: Entities::Discussion
end end
def whitelist_query_limiting def disable_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/-/issues/211538') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/211538')
end end
end end
end end
......
...@@ -242,7 +242,7 @@ module API ...@@ -242,7 +242,7 @@ module API
use :issue_params use :issue_params
end end
post ':id/issues' do post ':id/issues' do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42320') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42320')
check_rate_limit! :issues_create, [current_user] check_rate_limit! :issues_create, [current_user]
...@@ -288,7 +288,7 @@ module API ...@@ -288,7 +288,7 @@ module API
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
put ':id/issues/:issue_iid' do put ':id/issues/:issue_iid' do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42322') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42322')
issue = user_project.issues.find_by!(iid: params.delete(:issue_iid)) issue = user_project.issues.find_by!(iid: params.delete(:issue_iid))
authorize! :update_issue, issue authorize! :update_issue, issue
...@@ -346,7 +346,7 @@ module API ...@@ -346,7 +346,7 @@ module API
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
post ':id/issues/:issue_iid/move' do post ':id/issues/:issue_iid/move' do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42323') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42323')
issue = user_project.issues.find_by(iid: params[:issue_iid]) issue = user_project.issues.find_by(iid: params[:issue_iid])
not_found!('Issue') unless issue not_found!('Issue') unless issue
......
...@@ -207,7 +207,7 @@ module API ...@@ -207,7 +207,7 @@ module API
use :optional_params use :optional_params
end end
post ":id/merge_requests" do post ":id/merge_requests" do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42316') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42316')
authorize! :create_merge_request_from, user_project authorize! :create_merge_request_from, user_project
...@@ -416,7 +416,7 @@ module API ...@@ -416,7 +416,7 @@ module API
at_least_one_of(*::API::MergeRequests.update_params_at_least_one_of) at_least_one_of(*::API::MergeRequests.update_params_at_least_one_of)
end end
put ':id/merge_requests/:merge_request_iid' do put ':id/merge_requests/:merge_request_iid' do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42318') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42318')
merge_request = find_merge_request_with_access(params.delete(:merge_request_iid), :update_merge_request) merge_request = find_merge_request_with_access(params.delete(:merge_request_iid), :update_merge_request)
...@@ -445,7 +445,7 @@ module API ...@@ -445,7 +445,7 @@ module API
optional :squash, type: Grape::API::Boolean, desc: 'When true, the commits will be squashed into a single commit on merge' optional :squash, type: Grape::API::Boolean, desc: 'When true, the commits will be squashed into a single commit on merge'
end end
put ':id/merge_requests/:merge_request_iid/merge' do put ':id/merge_requests/:merge_request_iid/merge' do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42317') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42317')
merge_request = find_project_merge_request(params[:merge_request_iid]) merge_request = find_project_merge_request(params[:merge_request_iid])
......
...@@ -67,7 +67,7 @@ module API ...@@ -67,7 +67,7 @@ module API
check_rate_limit! :project_import, [current_user, :project_import] check_rate_limit! :project_import, [current_user, :project_import]
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42437') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42437')
validate_file! validate_file!
......
...@@ -215,7 +215,7 @@ module API ...@@ -215,7 +215,7 @@ module API
use :create_params use :create_params
end end
post do post do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/21139') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/21139')
attrs = declared_params(include_missing: false) attrs = declared_params(include_missing: false)
attrs = translate_params_for_compatibility(attrs) attrs = translate_params_for_compatibility(attrs)
filter_attributes_using_license!(attrs) filter_attributes_using_license!(attrs)
...@@ -248,7 +248,7 @@ module API ...@@ -248,7 +248,7 @@ module API
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
post "user/:user_id", feature_category: :projects do post "user/:user_id", feature_category: :projects do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/21139') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/21139')
authenticated_as_admin! authenticated_as_admin!
user = User.find_by(id: params.delete(:user_id)) user = User.find_by(id: params.delete(:user_id))
not_found!('User') unless user not_found!('User') unless user
...@@ -310,7 +310,7 @@ module API ...@@ -310,7 +310,7 @@ module API
optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the fork' optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the fork'
end end
post ':id/fork', feature_category: :source_code_management do post ':id/fork', feature_category: :source_code_management do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42284') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42284')
not_found! unless can?(current_user, :fork_project, user_project) not_found! unless can?(current_user, :fork_project, user_project)
......
...@@ -21,7 +21,7 @@ module API ...@@ -21,7 +21,7 @@ module API
optional :variables, type: Hash, desc: 'The list of variables to be injected into build' optional :variables, type: Hash, desc: 'The list of variables to be injected into build'
end end
post ":id/(ref/:ref/)trigger/pipeline", requirements: { ref: /.+/ } do post ":id/(ref/:ref/)trigger/pipeline", requirements: { ref: /.+/ } do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42283') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab-foss/issues/42283')
forbidden! if gitlab_pipeline_hook_request? forbidden! if gitlab_pipeline_hook_request?
......
...@@ -571,7 +571,7 @@ module API ...@@ -571,7 +571,7 @@ module API
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
delete ":id", feature_category: :users do delete ":id", feature_category: :users do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/20757') Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/20757')
authenticated_as_admin! authenticated_as_admin!
......
...@@ -6,28 +6,36 @@ module Gitlab ...@@ -6,28 +6,36 @@ module Gitlab
# #
# This is only enabled in development and test to ensure we don't produce # This is only enabled in development and test to ensure we don't produce
# any errors that users of other environments can't do anything about themselves. # any errors that users of other environments can't do anything about themselves.
def self.enable? def self.enabled_for_env?
Rails.env.development? || Rails.env.test? Rails.env.development? || Rails.env.test?
end end
def self.enabled?
enabled_for_env? &&
!Gitlab::SafeRequestStore[:query_limiting_disabled]
end
# Allows the current request to execute any number of SQL queries. # Allows the current request to execute any number of SQL queries.
# #
# This method should _only_ be used when there's a corresponding issue to # This method should _only_ be used when there's a corresponding issue to
# reduce the number of queries. # reduce the number of queries.
# #
# The issue URL is only meant to push developers into creating an issue # The issue URL is only meant to push developers into creating an issue
# instead of blindly whitelisting offending blocks of code. # instead of blindly disabling for offending blocks of code.
def self.whitelist(issue_url) def self.disable!(issue_url)
return unless enable?
unless issue_url.start_with?('https://') unless issue_url.start_with?('https://')
raise( raise(
ArgumentError, ArgumentError,
'You must provide a valid issue URL in order to whitelist a block of code' 'You must provide a valid issue URL in order to allow a block of code'
) )
end end
Transaction&.current&.whitelisted = true Gitlab::SafeRequestStore[:query_limiting_disabled] = true
end
# Enables query limiting for the request.
def self.enable!
Gitlab::SafeRequestStore[:query_limiting_disabled] = nil
end end
end end
end end
...@@ -5,7 +5,7 @@ module Gitlab ...@@ -5,7 +5,7 @@ module Gitlab
class Transaction class Transaction
THREAD_KEY = :__gitlab_query_counts_transaction THREAD_KEY = :__gitlab_query_counts_transaction
attr_accessor :count, :whitelisted attr_accessor :count
# The name of the action (e.g. `UsersController#show`) that is being # The name of the action (e.g. `UsersController#show`) that is being
# executed. # executed.
...@@ -45,7 +45,6 @@ module Gitlab ...@@ -45,7 +45,6 @@ module Gitlab
def initialize def initialize
@action = nil @action = nil
@count = 0 @count = 0
@whitelisted = false
@sql_executed = [] @sql_executed = []
end end
...@@ -59,7 +58,7 @@ module Gitlab ...@@ -59,7 +58,7 @@ module Gitlab
end end
def increment def increment
@count += 1 unless whitelisted @count += 1 if enabled?
end end
def executed_sql(sql) def executed_sql(sql)
...@@ -83,6 +82,10 @@ module Gitlab ...@@ -83,6 +82,10 @@ module Gitlab
["#{header}: #{msg}", log, ellipsis].compact.join("\n") ["#{header}: #{msg}", log, ellipsis].compact.join("\n")
end end
def enabled?
::Gitlab::QueryLimiting.enabled?
end
end end
end end
end end
...@@ -68,11 +68,15 @@ RSpec.describe Gitlab::QueryLimiting::Transaction do ...@@ -68,11 +68,15 @@ RSpec.describe Gitlab::QueryLimiting::Transaction do
it 'increments the number of executed queries' do it 'increments the number of executed queries' do
transaction = described_class.new transaction = described_class.new
expect(transaction.count).to be_zero expect { transaction.increment }.to change { transaction.count }.by(1)
end
it 'does not increment the number of executed queries when query limiting is disabled' do
transaction = described_class.new
transaction.increment allow(transaction).to receive(:enabled?).and_return(false)
expect(transaction.count).to eq(1) expect { transaction.increment }.not_to change { transaction.count }
end end
end end
......
...@@ -2,81 +2,85 @@ ...@@ -2,81 +2,85 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::QueryLimiting do RSpec.describe Gitlab::QueryLimiting, :request_store do
describe '.enable?' do describe '.enabled_for_env?' do
it 'returns true in a test environment' do it 'returns true in a test environment' do
expect(described_class.enable?).to eq(true) expect(described_class.enabled_for_env?).to eq(true)
end end
it 'returns true in a development environment' do it 'returns true in a development environment' do
stub_rails_env('development') stub_rails_env('development')
stub_rails_env('development') stub_rails_env('development')
expect(described_class.enable?).to eq(true) expect(described_class.enabled_for_env?).to eq(true)
end end
it 'returns false on GitLab.com' do it 'returns false on GitLab.com' do
stub_rails_env('production') stub_rails_env('production')
allow(Gitlab).to receive(:com?).and_return(true) allow(Gitlab).to receive(:com?).and_return(true)
expect(described_class.enable?).to eq(false) expect(described_class.enabled_for_env?).to eq(false)
end end
it 'returns false in a non GitLab.com' do it 'returns false in a non GitLab.com' do
allow(Gitlab).to receive(:com?).and_return(false) allow(Gitlab).to receive(:com?).and_return(false)
stub_rails_env('production') stub_rails_env('production')
expect(described_class.enable?).to eq(false) expect(described_class.enabled_for_env?).to eq(false)
end end
end end
describe '.whitelist' do shared_context 'disable and enable' do |result|
it 'raises ArgumentError when an invalid issue URL is given' do let(:transaction) { Gitlab::QueryLimiting::Transaction.new }
expect { described_class.whitelist('foo') } let(:code) do
.to raise_error(ArgumentError) proc do
end 2.times { User.count }
context 'without a transaction' do
it 'does nothing' do
expect { described_class.whitelist('https://example.com') }
.not_to raise_error
end end
end end
context 'with a transaction' do
let(:transaction) { Gitlab::QueryLimiting::Transaction.new }
before do before do
allow(Gitlab::QueryLimiting::Transaction) allow(Gitlab::QueryLimiting::Transaction)
.to receive(:current) .to receive(:current)
.and_return(transaction) .and_return(transaction)
end end
end
it 'does not increment the number of SQL queries executed in the block' do describe '.disable!' do
before = transaction.count include_context 'disable and enable'
described_class.whitelist('https://example.com')
2.times do it 'raises an ArgumentError when an invalid issue URL is given' do
User.count expect { described_class.disable!('foo') }
.to raise_error(ArgumentError)
end end
expect(transaction.count).to eq(before) it 'stops the number of SQL queries from being incremented' do
described_class.disable!('https://example.com')
expect { code.call }.not_to change { transaction.count }
end
end end
it 'whitelists when enabled' do describe '.enable!' do
described_class.whitelist('https://example.com') include_context 'disable and enable'
expect(transaction.whitelisted).to eq(true) it 'allows the number of SQL queries to be incremented' do
end described_class.enable!
it 'does not whitelist when disabled' do expect { code.call }.to change { transaction.count }.by(2)
allow(described_class).to receive(:enable?).and_return(false) end
end
described_class.whitelist('https://example.com') describe '#enabled?' do
it 'returns true when enabled' do
Gitlab::SafeRequestStore[:query_limiting_disabled] = nil
expect(transaction.whitelisted).to eq(false) expect(described_class).to be_enabled
end end
it 'returns false when disabled' do
Gitlab::SafeRequestStore[:query_limiting_disabled] = true
expect(described_class).not_to be_enabled
end end
end end
end end
...@@ -47,10 +47,10 @@ RSpec.describe 'getting merge request listings nested in a project' do ...@@ -47,10 +47,10 @@ RSpec.describe 'getting merge request listings nested in a project' do
end end
before do before do
# We cannot call the whitelist here, since the transaction does not # We cannot disable SQL query limiting here, since the transaction does not
# begin until we enter the controller. # begin until we enter the controller.
headers = { headers = {
'X-GITLAB-QUERY-WHITELIST-ISSUE' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/322979' 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/322979'
} }
post_graphql(query, current_user: current_user, headers: headers) post_graphql(query, current_user: current_user, headers: headers)
......
...@@ -359,6 +359,9 @@ RSpec.configure do |config| ...@@ -359,6 +359,9 @@ RSpec.configure do |config|
# Reset all feature flag stubs to default for testing # Reset all feature flag stubs to default for testing
stub_all_feature_flags stub_all_feature_flags
# Re-enable query limiting in case it was disabled
Gitlab::QueryLimiting.enable!
end end
config.before(:example, :mailer) do config.before(:example, :mailer) do
......
...@@ -15,20 +15,14 @@ end ...@@ -15,20 +15,14 @@ end
# If Sidekiq::Testing.inline! is used, SQL transactions done inside # If Sidekiq::Testing.inline! is used, SQL transactions done inside
# Sidekiq worker are included in the SQL query limit (in a real # Sidekiq worker are included in the SQL query limit (in a real
# deployment sidekiq worker is executed separately). To avoid # deployment sidekiq worker is executed separately). To avoid increasing
# increasing SQL limit counter, the request is marked as whitelisted # SQL limit counter, query limiting is disabled during Sidekiq block
# during Sidekiq block
class DisableQueryLimit class DisableQueryLimit
def call(worker_instance, msg, queue) def call(worker_instance, msg, queue)
transaction = Gitlab::QueryLimiting::Transaction.current ::Gitlab::QueryLimiting.disable!('https://mock-issue')
if !transaction.respond_to?(:whitelisted) || transaction.whitelisted
yield
else
transaction.whitelisted = true
yield yield
transaction.whitelisted = false ensure
end ::Gitlab::QueryLimiting.enable!
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment