Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/concerns')
-rw-r--r--app/models/concerns/analytics/cycle_analytics/stage_event_model.rb78
-rw-r--r--app/models/concerns/awardable.rb18
-rw-r--r--app/models/concerns/bulk_users_by_email_load.rb2
-rw-r--r--app/models/concerns/chronic_duration_attribute.rb2
-rw-r--r--app/models/concerns/ci/deployable.rb39
-rw-r--r--app/models/concerns/enums/issuable_link.rb12
-rw-r--r--app/models/concerns/import_state/sidekiq_job_tracker.rb2
-rw-r--r--app/models/concerns/integrations/enable_ssl_verification.rb21
-rw-r--r--app/models/concerns/issuable_link.rb28
-rw-r--r--app/models/concerns/noteable.rb4
-rw-r--r--app/models/concerns/protected_ref_access.rb2
-rw-r--r--app/models/concerns/repository_storage_movable.rb1
-rw-r--r--app/models/concerns/reset_on_column_errors.rb50
-rw-r--r--app/models/concerns/reset_on_union_error.rb37
-rw-r--r--app/models/concerns/routable.rb74
-rw-r--r--app/models/concerns/storage/legacy_namespace.rb112
-rw-r--r--app/models/concerns/vulnerability_finding_helpers.rb1
17 files changed, 200 insertions, 283 deletions
diff --git a/app/models/concerns/analytics/cycle_analytics/stage_event_model.rb b/app/models/concerns/analytics/cycle_analytics/stage_event_model.rb
index d268c32c088..1d9cf5729cd 100644
--- a/app/models/concerns/analytics/cycle_analytics/stage_event_model.rb
+++ b/app/models/concerns/analytics/cycle_analytics/stage_event_model.rb
@@ -16,6 +16,7 @@ module Analytics
scope :start_event_timestamp_before, -> (date) { where(arel_table[:start_event_timestamp].lteq(date)) }
scope :authored, ->(user) { where(author_id: user) }
scope :with_milestone_id, ->(milestone_id) { where(milestone_id: milestone_id) }
+ scope :without_milestone_id, -> (milestone_id) { where('milestone_id <> ? or milestone_id IS NULL', milestone_id) }
scope :end_event_is_not_happened_yet, -> { where(end_event_timestamp: nil) }
scope :order_by_end_event, -> (direction) do
# ORDER BY end_event_timestamp, merge_request_id/issue_id, start_event_timestamp
@@ -57,45 +58,19 @@ module Analytics
class_methods do
def upsert_data(data)
- upsert_values = data.map do |row|
- row.values_at(
- :stage_event_hash_id,
- :issuable_id,
- :group_id,
- :project_id,
- :milestone_id,
- :author_id,
- :state_id,
- :start_event_timestamp,
- :end_event_timestamp
- )
- end
+ upsert_values = data.map { |row| row.values_at(*column_list) }
value_list = Arel::Nodes::ValuesList.new(upsert_values).to_sql
query = <<~SQL
INSERT INTO #{quoted_table_name}
(
- stage_event_hash_id,
- #{connection.quote_column_name(issuable_id_column)},
- group_id,
- project_id,
- milestone_id,
- author_id,
- state_id,
- start_event_timestamp,
- end_event_timestamp
+ #{insert_column_list.join(",\n")}
)
#{value_list}
ON CONFLICT(stage_event_hash_id, #{issuable_id_column})
DO UPDATE SET
- group_id = excluded.group_id,
- project_id = excluded.project_id,
- milestone_id = excluded.milestone_id,
- author_id = excluded.author_id,
- state_id = excluded.state_id,
- start_event_timestamp = excluded.start_event_timestamp,
- end_event_timestamp = excluded.end_event_timestamp
+ #{column_updates.join(",\n")}
SQL
result = connection.execute(query)
@@ -113,6 +88,51 @@ module Analytics
def arel_order(arel_node, direction)
direction.to_sym == :desc ? arel_node.desc : arel_node.asc
end
+
+ def select_columns
+ [
+ issuable_model.arel_table[:id],
+ issuable_model.arel_table[project_column].as('project_id'),
+ issuable_model.arel_table[:milestone_id],
+ issuable_model.arel_table[:author_id],
+ issuable_model.arel_table[:state_id],
+ Project.arel_table[:parent_id].as('group_id')
+ ]
+ end
+
+ def column_list
+ [
+ :stage_event_hash_id,
+ :issuable_id,
+ :group_id,
+ :project_id,
+ :milestone_id,
+ :author_id,
+ :state_id,
+ :start_event_timestamp,
+ :end_event_timestamp
+ ]
+ end
+
+ def insert_column_list
+ [
+ :stage_event_hash_id,
+ connection.quote_column_name(issuable_id_column),
+ :group_id,
+ :project_id,
+ :milestone_id,
+ :author_id,
+ :state_id,
+ :start_event_timestamp,
+ :end_event_timestamp
+ ]
+ end
+
+ def column_updates
+ insert_column_list.map do |column|
+ "#{column} = excluded.#{column}"
+ end
+ end
end
end
end
diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb
index e830594af11..22e71c4fa13 100644
--- a/app/models/concerns/awardable.rb
+++ b/app/models/concerns/awardable.rb
@@ -13,26 +13,26 @@ module Awardable
end
class_methods do
- def awarded(user, name = nil)
+ def awarded(user, name = nil, base_class_name = base_class.name, awardable_id_column = :id)
award_emoji_table = Arel::Table.new('award_emoji')
inner_query = award_emoji_table
.project('true')
.where(award_emoji_table[:user_id].eq(user.id))
- .where(award_emoji_table[:awardable_type].eq(base_class.name))
- .where(award_emoji_table[:awardable_id].eq(self.arel_table[:id]))
+ .where(award_emoji_table[:awardable_type].eq(base_class_name))
+ .where(award_emoji_table[:awardable_id].eq(self.arel_table[awardable_id_column]))
inner_query = inner_query.where(award_emoji_table[:name].eq(name)) if name.present?
where(inner_query.exists)
end
- def not_awarded(user, name = nil)
+ def not_awarded(user, name = nil, base_class_name = base_class.name, awardable_id_column = :id)
award_emoji_table = Arel::Table.new('award_emoji')
inner_query = award_emoji_table
.project('true')
.where(award_emoji_table[:user_id].eq(user.id))
- .where(award_emoji_table[:awardable_type].eq(base_class.name))
- .where(award_emoji_table[:awardable_id].eq(self.arel_table[:id]))
+ .where(award_emoji_table[:awardable_type].eq(base_class_name))
+ .where(award_emoji_table[:awardable_id].eq(self.arel_table[awardable_id_column]))
inner_query = inner_query.where(award_emoji_table[:name].eq(name)) if name.present?
@@ -52,14 +52,14 @@ module Awardable
end
# Order votes by emoji, optional sort order param `descending` defaults to true
- def order_votes(emoji_name, direction)
+ def order_votes(emoji_name, direction, base_class_name = base_class.name, awardable_id_column = :id)
awardable_table = self.arel_table
awards_table = AwardEmoji.arel_table
join_clause = awardable_table
.join(awards_table, Arel::Nodes::OuterJoin)
- .on(awards_table[:awardable_id].eq(awardable_table[:id])
- .and(awards_table[:awardable_type].eq(base_class.name).and(awards_table[:name].eq(emoji_name))))
+ .on(awards_table[:awardable_id].eq(awardable_table[awardable_id_column])
+ .and(awards_table[:awardable_type].eq(base_class_name).and(awards_table[:name].eq(emoji_name))))
.join_sources
joins(join_clause).group(awardable_table[:id]).reorder(
diff --git a/app/models/concerns/bulk_users_by_email_load.rb b/app/models/concerns/bulk_users_by_email_load.rb
index edbd3e21458..55143ead30a 100644
--- a/app/models/concerns/bulk_users_by_email_load.rb
+++ b/app/models/concerns/bulk_users_by_email_load.rb
@@ -7,7 +7,7 @@ module BulkUsersByEmailLoad
def users_by_emails(emails)
Gitlab::SafeRequestLoader.execute(resource_key: user_by_email_resource_key, resource_ids: emails) do |emails|
# have to consider all emails - even secondary, so use all_emails here
- grouped_users_by_email = User.by_any_email(emails).preload(:emails).group_by(&:all_emails)
+ grouped_users_by_email = User.by_any_email(emails, confirmed: true).preload(:emails).group_by(&:all_emails)
grouped_users_by_email.each_with_object({}) do |(found_emails, users), h|
found_emails.each { |e| h[e] = users.first if emails.include?(e) } # don't include all emails for an account, only the ones we want
diff --git a/app/models/concerns/chronic_duration_attribute.rb b/app/models/concerns/chronic_duration_attribute.rb
index 7b7b61fdf06..44b34cf9b2f 100644
--- a/app/models/concerns/chronic_duration_attribute.rb
+++ b/app/models/concerns/chronic_duration_attribute.rb
@@ -18,7 +18,7 @@ module ChronicDurationAttribute
begin
new_value = if value.present?
- ChronicDuration.parse(value, use_complete_matcher: true).to_i
+ ChronicDuration.parse(value).to_i
else
parameters[:default].presence
end
diff --git a/app/models/concerns/ci/deployable.rb b/app/models/concerns/ci/deployable.rb
index d25151f9a34..844c8a1fa7d 100644
--- a/app/models/concerns/ci/deployable.rb
+++ b/app/models/concerns/ci/deployable.rb
@@ -4,6 +4,7 @@
module Ci
module Deployable
extend ActiveSupport::Concern
+ include Gitlab::Utils::StrongMemoize
included do
prepend_mod_with('Ci::Deployable') # rubocop: disable Cop/InjectEnterpriseEditionModule
@@ -17,8 +18,16 @@ module Ci
end
end
+ after_transition any => [:failed] do |job|
+ next unless job.stops_environment?
+
+ job.run_after_commit do
+ Environments::StopJobFailedWorker.perform_async(id)
+ end
+ end
+
# Synchronize Deployment Status
- # Please note that the data integirty is not assured because we can't use
+ # Please note that the data integrity is not assured because we can't use
# a database transaction due to DB decomposition.
after_transition do |job, transition|
next if transition.loopback?
@@ -32,13 +41,12 @@ module Ci
end
def outdated_deployment?
- strong_memoize(:outdated_deployment) do
- deployment_job? &&
- project.ci_forward_deployment_enabled? &&
- (!project.ci_forward_deployment_rollback_allowed? || incomplete?) &&
- deployment&.older_than_last_successful_deployment?
- end
+ deployment_job? &&
+ project.ci_forward_deployment_enabled? &&
+ (!project.ci_forward_deployment_rollback_allowed? || incomplete?) &&
+ deployment&.older_than_last_successful_deployment?
end
+ strong_memoize_attr :outdated_deployment?
# Virtual deployment status depending on the environment status.
def deployment_status
@@ -106,10 +114,10 @@ module Ci
namespace = options.dig(:environment, :kubernetes, :namespace)
- if namespace.present? # rubocop:disable Style/GuardClause
- strong_memoize(:expanded_kubernetes_namespace) do
- ExpandVariables.expand(namespace, -> { simple_variables })
- end
+ return unless namespace.present?
+
+ strong_memoize(:expanded_kubernetes_namespace) do
+ ExpandVariables.expand(namespace, -> { simple_variables })
end
end
@@ -146,12 +154,11 @@ module Ci
end
def environment_status
- strong_memoize(:environment_status) do
- if has_environment_keyword? && merge_request
- EnvironmentStatus.new(project, persisted_environment, merge_request, pipeline.sha)
- end
- end
+ return unless has_environment_keyword? && merge_request
+
+ EnvironmentStatus.new(project, persisted_environment, merge_request, pipeline.sha)
end
+ strong_memoize_attr :environment_status
def on_stop
options&.dig(:environment, :on_stop)
diff --git a/app/models/concerns/enums/issuable_link.rb b/app/models/concerns/enums/issuable_link.rb
new file mode 100644
index 00000000000..ca5728c2600
--- /dev/null
+++ b/app/models/concerns/enums/issuable_link.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Enums
+ module IssuableLink
+ TYPE_RELATES_TO = 'relates_to'
+ TYPE_BLOCKS = 'blocks'
+
+ def self.link_types
+ { TYPE_RELATES_TO => 0, TYPE_BLOCKS => 1 }
+ end
+ end
+end
diff --git a/app/models/concerns/import_state/sidekiq_job_tracker.rb b/app/models/concerns/import_state/sidekiq_job_tracker.rb
index b7d0ed0f51b..9c892acb158 100644
--- a/app/models/concerns/import_state/sidekiq_job_tracker.rb
+++ b/app/models/concerns/import_state/sidekiq_job_tracker.rb
@@ -19,7 +19,7 @@ module ImportState
end
def self.jid_by(project_id:, status:)
- select(:jid).where(status: status).find_by(project_id: project_id)
+ select(:id, :jid).where(status: status).find_by(project_id: project_id)
end
end
end
diff --git a/app/models/concerns/integrations/enable_ssl_verification.rb b/app/models/concerns/integrations/enable_ssl_verification.rb
index 9735a9bf5f6..cb20955488a 100644
--- a/app/models/concerns/integrations/enable_ssl_verification.rb
+++ b/app/models/concerns/integrations/enable_ssl_verification.rb
@@ -5,7 +5,11 @@ module Integrations
extend ActiveSupport::Concern
prepended do
- boolean_accessor :enable_ssl_verification
+ field :enable_ssl_verification,
+ type: :checkbox,
+ title: -> { s_('Integrations|SSL verification') },
+ checkbox_label: -> { s_('Integrations|Enable SSL verification') },
+ help: -> { s_('Integrations|Clear if using a self-signed certificate.') }
end
def initialize_properties
@@ -17,18 +21,11 @@ module Integrations
def fields
super.tap do |fields|
url_index = fields.index { |field| field[:name].ends_with?('_url') }
- insert_index = url_index ? url_index + 1 : -1
+ insert_index = url_index || -1
- fields.insert(insert_index,
- Field.new(
- name: 'enable_ssl_verification',
- integration_class: self,
- type: :checkbox,
- title: s_('Integrations|SSL verification'),
- checkbox_label: s_('Integrations|Enable SSL verification'),
- help: s_('Integrations|Clear if using a self-signed certificate.')
- )
- )
+ enable_ssl_verification_index = fields.index { |field| field[:name] == 'enable_ssl_verification' }
+
+ fields.insert(insert_index, fields.delete_at(enable_ssl_verification_index))
end
end
end
diff --git a/app/models/concerns/issuable_link.rb b/app/models/concerns/issuable_link.rb
index e884e5acecf..dcd2705185f 100644
--- a/app/models/concerns/issuable_link.rb
+++ b/app/models/concerns/issuable_link.rb
@@ -9,8 +9,8 @@
module IssuableLink
extend ActiveSupport::Concern
- TYPE_RELATES_TO = 'relates_to'
- TYPE_BLOCKS = 'blocks' ## EE-only. Kept here to be used on link_type enum.
+ MAX_LINKS_COUNT = 100
+ TYPE_RELATES_TO = Enums::IssuableLink::TYPE_RELATES_TO
class_methods do
def inverse_link_type(type)
@@ -38,10 +38,11 @@ module IssuableLink
validates :source, uniqueness: { scope: :target_id, message: 'is already related' }
validate :check_self_relation
validate :check_opposite_relation
+ validate :validate_max_number_of_links, on: :create
scope :for_source_or_target, ->(issuable) { where(source: issuable).or(where(target: issuable)) }
- enum link_type: { TYPE_RELATES_TO => 0, TYPE_BLOCKS => 1 }
+ enum link_type: Enums::IssuableLink.link_types
private
@@ -60,6 +61,27 @@ module IssuableLink
errors.add(:source, "is already related to this #{self.class.issuable_name}")
end
end
+
+ def validate_max_number_of_links
+ return unless source && target
+
+ validate_max_number_of_links_for(source, :source)
+ validate_max_number_of_links_for(target, :target)
+ end
+
+ def validate_max_number_of_links_for(item, attribute_name)
+ return unless item.linked_items_count >= MAX_LINKS_COUNT
+
+ errors.add(
+ attribute_name,
+ format(
+ s_('This %{issuable} would exceed the maximum number of linked %{issuables} (%{limit}).'),
+ issuable: self.class.issuable_name,
+ issuables: self.class.issuable_name.pluralize,
+ limit: MAX_LINKS_COUNT
+ )
+ )
+ end
end
end
diff --git a/app/models/concerns/noteable.rb b/app/models/concerns/noteable.rb
index 06cee46645b..971089edc45 100644
--- a/app/models/concerns/noteable.rb
+++ b/app/models/concerns/noteable.rb
@@ -12,12 +12,12 @@ module Noteable
class_methods do
# `Noteable` class names that support replying to individual notes.
def replyable_types
- %w[Issue MergeRequest]
+ %w[Issue MergeRequest AbuseReport]
end
# `Noteable` class names that support resolvable notes.
def resolvable_types
- %w[Issue MergeRequest DesignManagement::Design]
+ %w[Issue MergeRequest DesignManagement::Design AbuseReport]
end
# `Noteable` class names that support creating/forwarding individual notes.
diff --git a/app/models/concerns/protected_ref_access.rb b/app/models/concerns/protected_ref_access.rb
index f0bb1cc359b..a5994b538ce 100644
--- a/app/models/concerns/protected_ref_access.rb
+++ b/app/models/concerns/protected_ref_access.rb
@@ -71,6 +71,8 @@ module ProtectedRefAccess
return false if current_user.nil? || no_access?
return current_user.admin? if admin_access?
+ return false if Feature.enabled?(:check_membership_in_protected_ref_access) && !project.member?(current_user)
+
yield if block_given?
user_can_access?(current_user)
diff --git a/app/models/concerns/repository_storage_movable.rb b/app/models/concerns/repository_storage_movable.rb
index 87ff413f2c1..77edabb9706 100644
--- a/app/models/concerns/repository_storage_movable.rb
+++ b/app/models/concerns/repository_storage_movable.rb
@@ -49,6 +49,7 @@ module RepositoryStorageMovable
begin
storage_move.container.set_repository_read_only!(skip_git_transfer_check: true)
rescue StandardError => e
+ storage_move.do_fail!
storage_move.add_error(e.message)
next false
end
diff --git a/app/models/concerns/reset_on_column_errors.rb b/app/models/concerns/reset_on_column_errors.rb
new file mode 100644
index 00000000000..8ace52ebff5
--- /dev/null
+++ b/app/models/concerns/reset_on_column_errors.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module ResetOnColumnErrors
+ extend ActiveSupport::Concern
+
+ MAX_RESET_PERIOD = 10.minutes
+
+ included do |base|
+ base.rescue_from ActiveRecord::StatementInvalid, with: :reset_on_union_error
+ base.rescue_from ActiveModel::UnknownAttributeError, with: :reset_on_unknown_attribute_error
+
+ base.class_attribute :previous_reset_columns_from_error
+ end
+
+ class_methods do
+ def do_reset(exception)
+ class_to_be_reset = base_class
+
+ class_to_be_reset.reset_column_information
+ Gitlab::ErrorTracking.log_exception(exception, { reset_model_name: class_to_be_reset.name })
+
+ class_to_be_reset.previous_reset_columns_from_error = Time.current
+ end
+
+ def reset_on_union_error(exception)
+ if exception.message.include?("each UNION query must have the same number of columns") && should_reset?
+ do_reset(exception)
+ end
+
+ raise
+ end
+
+ def should_reset?
+ return false if base_class.previous_reset_columns_from_error? &&
+ base_class.previous_reset_columns_from_error > MAX_RESET_PERIOD.ago
+
+ Feature.enabled?(:reset_column_information_on_statement_invalid, type: :ops)
+ end
+ end
+
+ def reset_on_union_error(exception)
+ self.class.reset_on_union_error(exception)
+ end
+
+ def reset_on_unknown_attribute_error(exception)
+ self.class.do_reset(exception) if self.class.should_reset?
+
+ raise
+ end
+end
diff --git a/app/models/concerns/reset_on_union_error.rb b/app/models/concerns/reset_on_union_error.rb
deleted file mode 100644
index 42e350b0bed..00000000000
--- a/app/models/concerns/reset_on_union_error.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-module ResetOnUnionError
- extend ActiveSupport::Concern
-
- MAX_RESET_PERIOD = 10.minutes
-
- included do |base|
- base.rescue_from ActiveRecord::StatementInvalid, with: :reset_on_union_error
-
- base.class_attribute :previous_reset_columns_from_error
- end
-
- class_methods do
- def reset_on_union_error(exception)
- if reset_on_statement_invalid?(exception)
- class_to_be_reset = base_class
-
- class_to_be_reset.reset_column_information
- Gitlab::ErrorTracking.log_exception(exception, { reset_model_name: class_to_be_reset.name })
-
- class_to_be_reset.previous_reset_columns_from_error = Time.current
- end
-
- raise
- end
-
- def reset_on_statement_invalid?(exception)
- return false unless exception.message.include?("each UNION query must have the same number of columns")
-
- return false if base_class.previous_reset_columns_from_error? &&
- base_class.previous_reset_columns_from_error > MAX_RESET_PERIOD.ago
-
- Feature.enabled?(:reset_column_information_on_statement_invalid, type: :ops)
- end
- end
-end
diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb
index ef14ff5fbe2..4c16ba18823 100644
--- a/app/models/concerns/routable.rb
+++ b/app/models/concerns/routable.rb
@@ -15,16 +15,7 @@ module Routable
#
# Returns a single object, or nil.
- # rubocop:disable Metrics/CyclomaticComplexity
- # rubocop:disable Metrics/PerceivedComplexity
- def self.find_by_full_path(
- path,
- follow_redirects: false,
- route_scope: Route,
- redirect_route_scope: RedirectRoute,
- optimize_routable: Routable.optimize_routable_enabled?
- )
-
+ def self.find_by_full_path(path, follow_redirects: false, route_scope: nil)
return unless path.present?
# Convert path to string to prevent DB error: function lower(integer) does not exist
@@ -35,49 +26,22 @@ module Routable
#
# We need to qualify the columns with the table name, to support both direct lookups on
# Route/RedirectRoute, and scoped lookups through the Routable classes.
- if optimize_routable
- path_condition = { path: path }
-
- source_type_condition = if route_scope == Route
- {}
- else
- { source_type: route_scope.klass.base_class }
- end
+ path_condition = { path: path }
- route =
- Route.where(source_type_condition).find_by(path_condition) ||
- Route.where(source_type_condition).iwhere(path_condition).take
+ source_type_condition = route_scope ? { source_type: route_scope.klass.base_class } : {}
- if follow_redirects
- route ||= RedirectRoute.where(source_type_condition).iwhere(path_condition).take
- end
+ route =
+ Route.where(source_type_condition).find_by(path_condition) ||
+ Route.where(source_type_condition).iwhere(path_condition).take
- return unless route
- return route.source if route_scope == Route
-
- route_scope.find_by(id: route.source_id)
- else
- Gitlab::Database.allow_cross_joins_across_databases(url:
- "https://gitlab.com/gitlab-org/gitlab/-/issues/420046") do
- route =
- route_scope.find_by(routes: { path: path }) ||
- route_scope.iwhere(Route.arel_table[:path] => path).take
-
- if follow_redirects
- route ||= redirect_route_scope.iwhere(RedirectRoute.arel_table[:path] => path).take
- end
-
- next unless route
-
- route.is_a?(Routable) ? route : route.source
- end
+ if follow_redirects
+ route ||= RedirectRoute.where(source_type_condition).iwhere(path_condition).take
end
- end
- # rubocop:enable Metrics/PerceivedComplexity
- # rubocop:enable Metrics/CyclomaticComplexity
- def self.optimize_routable_enabled?
- Feature.enabled?(:optimize_routable)
+ return unless route
+ return route.source unless route_scope
+
+ route_scope.find_by(id: route.source_id)
end
included do
@@ -107,22 +71,12 @@ module Routable
#
# Returns a single object, or nil.
def find_by_full_path(path, follow_redirects: false)
- optimize_routable = Routable.optimize_routable_enabled?
-
- if optimize_routable
- route_scope = all
- redirect_route_scope = RedirectRoute
- else
- route_scope = includes(:route).references(:routes)
- redirect_route_scope = joins(:redirect_routes)
- end
+ route_scope = all
Routable.find_by_full_path(
path,
follow_redirects: follow_redirects,
- route_scope: route_scope,
- redirect_route_scope: redirect_route_scope,
- optimize_routable: optimize_routable
+ route_scope: route_scope
)
end
diff --git a/app/models/concerns/storage/legacy_namespace.rb b/app/models/concerns/storage/legacy_namespace.rb
deleted file mode 100644
index 5455a2159cd..00000000000
--- a/app/models/concerns/storage/legacy_namespace.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-# frozen_string_literal: true
-
-module Storage
- module LegacyNamespace
- extend ActiveSupport::Concern
-
- include Gitlab::ShellAdapter
-
- def move_dir
- proj_with_tags = first_project_with_container_registry_tags
-
- if proj_with_tags
- raise Gitlab::UpdatePathError, "Namespace #{name} (#{id}) cannot be moved because at least one project (e.g. #{proj_with_tags.name} (#{proj_with_tags.id})) has tags in container registry"
- end
-
- parent_was = if saved_change_to_parent? && parent_id_before_last_save.present?
- Namespace.find(parent_id_before_last_save) # raise NotFound early if needed
- end
-
- if saved_change_to_parent?
- former_parent_full_path = parent_was&.full_path
- parent_full_path = parent&.full_path
- Gitlab::UploadsTransfer.new.move_namespace(path, former_parent_full_path, parent_full_path)
- else
- Gitlab::UploadsTransfer.new.rename_namespace(full_path_before_last_save, full_path)
- end
-
- # If repositories moved successfully we need to
- # send update instructions to users.
- # However we cannot allow rollback since we moved namespace dir
- # So we basically we mute exceptions in next actions
- begin
- send_update_instructions
- write_projects_repository_config
- rescue StandardError => e
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e,
- full_path_before_last_save: full_path_before_last_save,
- full_path: full_path,
- action: 'move_dir')
- end
-
- true # false would cancel later callbacks but not rollback
- end
-
- # Hooks
-
- # Save the storages before the projects are destroyed to use them on after destroy
- def prepare_for_destroy
- old_repository_storages
- end
-
- private
-
- def move_repositories
- # Move the namespace directory in all storages used by member projects
- repository_storages(legacy_only: true).each do |repository_storage|
- # Ensure old directory exists before moving it
- Gitlab::GitalyClient::NamespaceService.allow do
- gitlab_shell.add_namespace(repository_storage, full_path_before_last_save)
-
- # Ensure new directory exists before moving it (if there's a parent)
- gitlab_shell.add_namespace(repository_storage, parent.full_path) if parent
-
- unless gitlab_shell.mv_namespace(repository_storage, full_path_before_last_save, full_path)
-
- Gitlab::AppLogger.error("Exception moving path #{repository_storage} from #{full_path_before_last_save} to #{full_path}")
-
- # if we cannot move namespace directory we should rollback
- # db changes in order to prevent out of sync between db and fs
- raise Gitlab::UpdatePathError, 'namespace directory cannot be moved'
- end
- end
- end
- end
-
- def old_repository_storages
- @old_repository_storage_paths ||= repository_storages(legacy_only: true)
- end
-
- def repository_storages(legacy_only: false)
- # We need to get the storage paths for all the projects, even the ones that are
- # pending delete. Unscoping also get rids of the default order, which causes
- # problems with SELECT DISTINCT.
- Project.unscoped do
- namespace_projects = all_projects
- namespace_projects = namespace_projects.without_storage_feature(:repository) if legacy_only
- namespace_projects.pluck(Arel.sql('distinct(repository_storage)'))
- end
- end
-
- def rm_dir
- # Remove the namespace directory in all storages paths used by member projects
- old_repository_storages.each do |repository_storage|
- # Move namespace directory into trash.
- # We will remove it later async
- new_path = "#{full_path}+#{id}+deleted"
-
- Gitlab::GitalyClient::NamespaceService.allow do
- if gitlab_shell.mv_namespace(repository_storage, full_path, new_path)
- Gitlab::AppLogger.info %(Namespace directory "#{full_path}" moved to "#{new_path}")
-
- # Remove namespace directory async with delay so
- # GitLab has time to remove all projects first
- run_after_commit do
- GitlabShellWorker.perform_in(5.minutes, :rm_namespace, repository_storage, new_path)
- end
- end
- end
- end
- end
- end
-end
diff --git a/app/models/concerns/vulnerability_finding_helpers.rb b/app/models/concerns/vulnerability_finding_helpers.rb
index e8a50497b20..94d091e8459 100644
--- a/app/models/concerns/vulnerability_finding_helpers.rb
+++ b/app/models/concerns/vulnerability_finding_helpers.rb
@@ -50,6 +50,7 @@ module VulnerabilityFindingHelpers
finding_data = report_finding.to_hash.except(
:compare_key, :identifiers, :location, :scanner, :links, :signatures, :flags, :evidence
)
+
identifiers = report_finding.identifiers.uniq(&:fingerprint).map do |identifier|
Vulnerabilities::Identifier.new(identifier.to_hash.merge({ project: project }))
end