diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-14 09:07:47 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-14 09:07:47 +0300 |
commit | 1943b0a274de377e0d3e212d3d4d1bfcf58d3690 (patch) | |
tree | edfa2b58bed59364ec0466636b6c0d32636035f7 /app | |
parent | e67cd0407febc97c0676bea1f1e6f7739912d94f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/autocomplete_controller.rb | 10 | ||||
-rw-r--r-- | app/controllers/concerns/search_rate_limitable.rb | 15 | ||||
-rw-r--r-- | app/controllers/search_controller.rb | 9 | ||||
-rw-r--r-- | app/helpers/application_settings_helper.rb | 3 | ||||
-rw-r--r-- | app/models/application_setting.rb | 6 | ||||
-rw-r--r-- | app/models/application_setting_implementation.rb | 3 | ||||
-rw-r--r-- | app/models/concerns/timebox.rb | 1 | ||||
-rw-r--r-- | app/models/instance_configuration.rb | 3 | ||||
-rw-r--r-- | app/models/milestone.rb | 1 | ||||
-rw-r--r-- | app/views/admin/application_settings/_search_limits.html.haml | 16 | ||||
-rw-r--r-- | app/views/admin/application_settings/network.html.haml | 11 | ||||
-rw-r--r-- | app/views/admin/runners/edit.html.haml | 15 |
12 files changed, 65 insertions, 28 deletions
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index ee5caf63703..4bcd1be9f53 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class AutocompleteController < ApplicationController + include SearchRateLimitable + skip_before_action :authenticate_user!, only: [:users, :award_emojis, :merge_request_target_branches] - before_action :check_email_search_rate_limit!, only: [:users] + before_action :check_search_rate_limit!, only: [:users, :projects] feature_category :users, [:users, :user] feature_category :projects, [:projects] @@ -72,12 +74,6 @@ class AutocompleteController < ApplicationController def target_branch_params params.permit(:group_id, :project_id).select { |_, v| v.present? } end - - def check_email_search_rate_limit! - search_params = Gitlab::Search::Params.new(params) - - check_rate_limit!(:user_email_lookup, scope: [current_user]) if search_params.email_lookup? - end end AutocompleteController.prepend_mod_with('AutocompleteController') diff --git a/app/controllers/concerns/search_rate_limitable.rb b/app/controllers/concerns/search_rate_limitable.rb new file mode 100644 index 00000000000..a77ebd276b6 --- /dev/null +++ b/app/controllers/concerns/search_rate_limitable.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module SearchRateLimitable + extend ActiveSupport::Concern + + private + + def check_search_rate_limit! + if current_user + check_rate_limit!(:search_rate_limit, scope: [current_user]) + else + check_rate_limit!(:search_rate_limit_unauthenticated, scope: [request.ip]) + end + end +end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 0c3d400875d..817da658f14 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -4,6 +4,7 @@ class SearchController < ApplicationController include ControllerWithCrossProjectAccessCheck include SearchHelper include RedisTracking + include SearchRateLimitable RESCUE_FROM_TIMEOUT_ACTIONS = [:count, :show, :autocomplete].freeze @@ -17,7 +18,7 @@ class SearchController < ApplicationController search_term_present = params[:search].present? || params[:term].present? search_term_present && !params[:project_id].present? end - before_action :check_email_search_rate_limit!, only: [:show, :count, :autocomplete] + before_action :check_search_rate_limit!, only: [:show, :count, :autocomplete] rescue_from ActiveRecord::QueryCanceled, with: :render_timeout @@ -202,12 +203,6 @@ class SearchController < ApplicationController render status: :request_timeout end end - - def check_email_search_rate_limit! - return unless search_service.params.email_lookup? - - check_rate_limit!(:user_email_lookup, scope: [current_user]) - end end SearchController.prepend_mod_with('SearchController') diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 1c148029e47..d9a1731e820 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -424,7 +424,8 @@ module ApplicationSettingsHelper :sidekiq_job_limiter_compression_threshold_bytes, :sidekiq_job_limiter_limit_bytes, :suggest_pipeline_enabled, - :user_email_lookup_limit, + :search_rate_limit, + :search_rate_limit_unauthenticated, :users_get_by_id_limit, :users_get_by_id_limit_allowlist_raw, :runner_token_expiration_interval, diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 9941f76a51f..3453518fea8 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -11,6 +11,7 @@ class ApplicationSetting < ApplicationRecord ignore_columns %i[elasticsearch_shards elasticsearch_replicas], remove_with: '14.4', remove_after: '2021-09-22' ignore_columns %i[static_objects_external_storage_auth_token], remove_with: '14.9', remove_after: '2022-03-22' ignore_column %i[max_package_files_for_package_destruction], remove_with: '14.9', remove_after: '2022-03-22' + ignore_column :user_email_lookup_limit, remove_with: '15.0', remove_after: '2022-04-18' INSTANCE_REVIEW_MIN_USERS = 50 GRAFANA_URL_ERROR_MESSAGE = 'Please check your Grafana URL setting in ' \ @@ -519,9 +520,12 @@ class ApplicationSetting < ApplicationRecord validates :notes_create_limit, numericality: { only_integer: true, greater_than_or_equal_to: 0 } - validates :user_email_lookup_limit, + validates :search_rate_limit, numericality: { only_integer: true, greater_than_or_equal_to: 0 } + validates :search_rate_limit_unauthenticated, + numericality: { only_integer: true, greater_than_or_equal_to: 0 } + validates :notes_create_limit_allowlist, length: { maximum: 100, message: N_('is too long (maximum is 100 entries)') }, allow_nil: false diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index 73448461826..42049713883 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -233,7 +233,8 @@ module ApplicationSettingImplementation rate_limiting_response_text: nil, whats_new_variant: 0, user_deactivation_emails_enabled: true, - user_email_lookup_limit: 60, + search_rate_limit: 30, + search_rate_limit_unauthenticated: 10, users_get_by_id_limit: 300, users_get_by_id_limit_allowlist: [] } diff --git a/app/models/concerns/timebox.rb b/app/models/concerns/timebox.rb index 943ef3fa59f..d53594eb5af 100644 --- a/app/models/concerns/timebox.rb +++ b/app/models/concerns/timebox.rb @@ -44,7 +44,6 @@ module Timebox validates :group, presence: true, unless: :project validates :project, presence: true, unless: :group - validates :title, presence: true validate :timebox_type_check validate :start_date_should_be_less_than_due_date, if: proc { |m| m.start_date.present? && m.due_date.present? } diff --git a/app/models/instance_configuration.rb b/app/models/instance_configuration.rb index 2016024b2f4..00e55d0fd89 100644 --- a/app/models/instance_configuration.rb +++ b/app/models/instance_configuration.rb @@ -118,7 +118,8 @@ class InstanceConfiguration group_export_download: application_setting_limit_per_minute(:group_download_export_limit), group_import: application_setting_limit_per_minute(:group_import_limit), raw_blob: application_setting_limit_per_minute(:raw_blob_request_limit), - user_email_lookup: application_setting_limit_per_minute(:user_email_lookup_limit), + search_rate_limit: application_setting_limit_per_minute(:search_rate_limit), + search_rate_limit_unauthenticated: application_setting_limit_per_minute(:search_rate_limit_unauthenticated), users_get_by_id: { enabled: application_settings[:users_get_by_id_limit] > 0, requests_per_period: application_settings[:users_get_by_id_limit], diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 2c95cc2672c..86da29dd27a 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -35,6 +35,7 @@ class Milestone < ApplicationRecord scope :with_api_entity_associations, -> { preload(project: [:project_feature, :route, namespace: :route]) } scope :order_by_dates_and_title, -> { order(due_date: :asc, start_date: :asc, title: :asc) } + validates :title, presence: true validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") } validate :uniqueness_of_title, if: :title_changed? diff --git a/app/views/admin/application_settings/_search_limits.html.haml b/app/views/admin/application_settings/_search_limits.html.haml new file mode 100644 index 00000000000..24403fe8fd3 --- /dev/null +++ b/app/views/admin/application_settings/_search_limits.html.haml @@ -0,0 +1,16 @@ += form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-search-limits-settings'), html: { class: 'fieldset-form' } do |f| + = form_errors(@application_setting) + + %fieldset + .form-group + = f.label :search_rate_limit, _('Maximum authenticated requests by a user per minute'), class: 'label-bold' + .form-text.gl-text-gray-600 + = _("Set this number to 0 to disable the limit.") + + = f.label :search_rate_limit, _('Maximum number of requests per minute for an authenticated user'), class: 'label-bold' + .form-group + = f.label :search_rate_limit_unauthenticated, _('Maximum number of requests per minute for an unauthenticated IP address'), class: 'label-bold' + = f.number_field :search_rate_limit_unauthenticated, class: 'form-control gl-form-input' + + + = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml index 90183b028f0..b0e3f8182f6 100644 --- a/app/views/admin/application_settings/network.html.haml +++ b/app/views/admin/application_settings/network.html.haml @@ -48,6 +48,17 @@ .settings-content = render partial: 'network_rate_limits', locals: { anchor: 'js-files-limits-settings', setting_fragment: 'files_api' } +%section.settings.as-note-limits.no-animate#js-search-limits-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Search rate limits') + %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Set rate limits for searches performed by web or API requests.') + .settings-content + = render 'search_limits' + %section.settings.as-deprecated-limits.no-animate#js-deprecated-limits-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 diff --git a/app/views/admin/runners/edit.html.haml b/app/views/admin/runners/edit.html.haml index b65fead49ab..55fd09ac203 100644 --- a/app/views/admin/runners/edit.html.haml +++ b/app/views/admin/runners/edit.html.haml @@ -25,15 +25,12 @@ - if project %tr %td - .gl-alert.gl-alert-danger - .gl-alert-container - = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-content - .gl-alert-body - %strong - = project.full_name - .gl-alert-actions - = link_to _('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button' + = render 'shared/global_alert', + variant: :danger, + dismissible: false, + title: project.full_name do + .gl-alert-actions + = link_to _('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button' %table.table{ data: { testid: 'unassigned-projects' } } %thead |