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
path: root/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-11-24 15:10:21 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-24 15:10:21 +0300
commit77b8390171a55d4593e3730551751d8348992f80 (patch)
tree61adcb066a34458a98dfbf90f0a8ce3420533a1a /lib
parent49cea0b04a1138a00cc7068c4c1a997867aeae88 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r--lib/banzai/filter/issuable_reference_expansion_filter.rb92
-rw-r--r--lib/banzai/filter/issuable_state_filter.rb66
-rw-r--r--lib/banzai/filter/references/abstract_reference_filter.rb2
-rw-r--r--lib/banzai/pipeline/post_process_pipeline.rb2
-rw-r--r--lib/gitlab/content_security_policy/config_loader.rb6
-rw-r--r--lib/gitlab/database.rb9
-rw-r--r--lib/gitlab/database/gitlab_loose_foreign_keys.yml8
-rw-r--r--lib/gitlab/database/loose_foreign_keys.rb38
-rw-r--r--lib/gitlab/regex.rb2
-rw-r--r--lib/gitlab/tracking.rb8
-rw-r--r--lib/gitlab/tracking/destinations/snowplow_micro.rb4
11 files changed, 163 insertions, 74 deletions
diff --git a/lib/banzai/filter/issuable_reference_expansion_filter.rb b/lib/banzai/filter/issuable_reference_expansion_filter.rb
new file mode 100644
index 00000000000..6822e36c9be
--- /dev/null
+++ b/lib/banzai/filter/issuable_reference_expansion_filter.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+module Banzai
+ module Filter
+ # HTML filter that appends extra information to issuable links.
+ # Runs as a post-process filter as issuable might change while
+ # Markdown is in the cache.
+ #
+ # This filter supports cross-project references.
+ class IssuableReferenceExpansionFilter < HTML::Pipeline::Filter
+ include Gitlab::Utils::StrongMemoize
+
+ VISIBLE_STATES = %w(closed merged).freeze
+
+ def call
+ return doc unless context[:issuable_reference_expansion_enabled]
+
+ context = RenderContext.new(project, current_user)
+ extractor = Banzai::IssuableExtractor.new(context)
+ issuables = extractor.extract([doc])
+
+ issuables.each do |node, issuable|
+ next if !can_read_cross_project? && cross_referenced?(issuable)
+ next unless should_expand?(node, issuable)
+
+ case node.attr('data-reference-format')
+ when '+'
+ expand_reference_with_title_and_state(node, issuable)
+ else
+ expand_reference_with_state(node, issuable)
+ end
+ end
+
+ doc
+ end
+
+ private
+
+ # Example: Issue Title (#123 - closed)
+ def expand_reference_with_title_and_state(node, issuable)
+ node.content = "#{issuable.title.truncate(50)} (#{node.content}"
+ node.content += " - #{issuable_state_text(issuable)}" if VISIBLE_STATES.include?(issuable.state)
+ node.content += ')'
+ end
+
+ # Example: #123 (closed)
+ def expand_reference_with_state(node, issuable)
+ node.content += " (#{issuable_state_text(issuable)})"
+ end
+
+ def issuable_state_text(issuable)
+ moved_issue?(issuable) ? s_("IssuableStatus|moved") : issuable.state
+ end
+
+ def moved_issue?(issuable)
+ issuable.instance_of?(Issue) && issuable.moved?
+ end
+
+ def should_expand?(node, issuable)
+ # We add this extra check to avoid unescaping HTML and generating reference link text for every reference
+ return unless node.attr('data-reference-format').present? || VISIBLE_STATES.include?(issuable.state)
+
+ CGI.unescapeHTML(node.inner_html) == issuable.reference_link_text(project || group)
+ end
+
+ def cross_referenced?(issuable)
+ return true if issuable.project != project
+ return true if issuable.respond_to?(:group) && issuable.group != group
+
+ false
+ end
+
+ def can_read_cross_project?
+ strong_memoize(:can_read_cross_project) do
+ Ability.allowed?(current_user, :read_cross_project)
+ end
+ end
+
+ def current_user
+ context[:current_user]
+ end
+
+ def project
+ context[:project]
+ end
+
+ def group
+ context[:group]
+ end
+ end
+ end
+end
diff --git a/lib/banzai/filter/issuable_state_filter.rb b/lib/banzai/filter/issuable_state_filter.rb
deleted file mode 100644
index a88629ac105..00000000000
--- a/lib/banzai/filter/issuable_state_filter.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-module Banzai
- module Filter
- # HTML filter that appends state information to issuable links.
- # Runs as a post-process filter as issuable state might change while
- # Markdown is in the cache.
- #
- # This filter supports cross-project references.
- class IssuableStateFilter < HTML::Pipeline::Filter
- VISIBLE_STATES = %w(closed merged).freeze
-
- def call
- return doc unless context[:issuable_state_filter_enabled]
-
- context = RenderContext.new(project, current_user)
- extractor = Banzai::IssuableExtractor.new(context)
- issuables = extractor.extract([doc])
-
- issuables.each do |node, issuable|
- next if !can_read_cross_project? && cross_referenced?(issuable)
-
- if VISIBLE_STATES.include?(issuable.state) && issuable_reference?(node.inner_html, issuable)
- state = moved_issue?(issuable) ? s_("IssuableStatus|moved") : issuable.state
- node.content += " (#{state})"
- end
- end
-
- doc
- end
-
- private
-
- def moved_issue?(issuable)
- issuable.instance_of?(Issue) && issuable.moved?
- end
-
- def issuable_reference?(text, issuable)
- CGI.unescapeHTML(text) == issuable.reference_link_text(project || group)
- end
-
- def cross_referenced?(issuable)
- return true if issuable.project != project
- return true if issuable.respond_to?(:group) && issuable.group != group
-
- false
- end
-
- def can_read_cross_project?
- Ability.allowed?(current_user, :read_cross_project)
- end
-
- def current_user
- context[:current_user]
- end
-
- def project
- context[:project]
- end
-
- def group
- context[:group]
- end
- end
- end
-end
diff --git a/lib/banzai/filter/references/abstract_reference_filter.rb b/lib/banzai/filter/references/abstract_reference_filter.rb
index cae0a8b424a..7a23326bafa 100644
--- a/lib/banzai/filter/references/abstract_reference_filter.rb
+++ b/lib/banzai/filter/references/abstract_reference_filter.rb
@@ -205,6 +205,8 @@ module Banzai
data_attributes = data_attributes_for(link_content || match, parent, object,
link_content: !!link_content,
link_reference: link_reference)
+ data_attributes[:reference_format] = matches[:format] if matches.names.include?("format")
+
data = data_attribute(data_attributes)
url =
diff --git a/lib/banzai/pipeline/post_process_pipeline.rb b/lib/banzai/pipeline/post_process_pipeline.rb
index 889574cf6bf..da2262cdf83 100644
--- a/lib/banzai/pipeline/post_process_pipeline.rb
+++ b/lib/banzai/pipeline/post_process_pipeline.rb
@@ -19,7 +19,7 @@ module Banzai
# prevent unnecessary Gitaly calls from being made.
Filter::UploadLinkFilter,
Filter::RepositoryLinkFilter,
- Filter::IssuableStateFilter,
+ Filter::IssuableReferenceExpansionFilter,
Filter::SuggestionFilter
]
end
diff --git a/lib/gitlab/content_security_policy/config_loader.rb b/lib/gitlab/content_security_policy/config_loader.rb
index bdae59e7e3c..50490d1b5a3 100644
--- a/lib/gitlab/content_security_policy/config_loader.rb
+++ b/lib/gitlab/content_security_policy/config_loader.rb
@@ -36,6 +36,7 @@ module Gitlab
if Rails.env.development?
allow_webpack_dev_server(directives)
allow_letter_opener(directives)
+ allow_snowplow_micro(directives) if Gitlab::Tracking.snowplow_micro_enabled?
allow_customersdot(directives) if ENV['CUSTOMER_PORTAL_URL'].present?
end
@@ -138,6 +139,11 @@ module Gitlab
append_to_directive(directives, 'frame_src', Gitlab::Utils.append_path(Gitlab.config.gitlab.url, '/rails/letter_opener/'))
end
+ def self.allow_snowplow_micro(directives)
+ url = URI.join(Gitlab::Tracking::Destinations::SnowplowMicro.new.uri, '/').to_s
+ append_to_directive(directives, 'connect_src', url)
+ end
+
# Using 'self' in the CSP introduces several CSP bypass opportunities
# for this reason we list the URLs where GitLab frames itself instead
def self.allow_framed_gitlab_paths(directives)
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index 9c74e5d2ca8..1a464555278 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -63,6 +63,15 @@ module Gitlab
}.compact.with_indifferent_access.freeze
end
+ # This returns a list of base models with connection associated for a given gitlab_schema
+ def self.schemas_to_base_models
+ @schemas_to_base_models ||= {
+ gitlab_main: [self.database_base_models.fetch(:main)],
+ gitlab_ci: [self.database_base_models[:ci] || self.database_base_models.fetch(:main)], # use CI or fallback to main
+ gitlab_shared: self.database_base_models.values # all models
+ }.with_indifferent_access.freeze
+ end
+
# We configure the database connection pool size automatically based on the
# configured concurrency. We also add some headroom, to make sure we don't
# run out of connections when more threads besides the 'user-facing' ones
diff --git a/lib/gitlab/database/gitlab_loose_foreign_keys.yml b/lib/gitlab/database/gitlab_loose_foreign_keys.yml
new file mode 100644
index 00000000000..27b8f3bbe0f
--- /dev/null
+++ b/lib/gitlab/database/gitlab_loose_foreign_keys.yml
@@ -0,0 +1,8 @@
+chat_names:
+ - to_table: ci_pipeline_chat_data
+ column: chat_name_id
+ on_delete: async_delete
+ci_runners:
+ - to_table: clusters_applications_runners
+ column: runner_id
+ on_delete: async_nullify
diff --git a/lib/gitlab/database/loose_foreign_keys.rb b/lib/gitlab/database/loose_foreign_keys.rb
new file mode 100644
index 00000000000..1d885b3fbc8
--- /dev/null
+++ b/lib/gitlab/database/loose_foreign_keys.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module LooseForeignKeys
+ def self.definitions_by_table
+ @definitions_by_table ||= definitions.group_by(&:from_table).with_indifferent_access.freeze
+ end
+
+ def self.definitions
+ @definitions ||= loose_foreign_keys_yaml.flat_map do |parent_table_name, configs|
+ configs.map { |config| build_definition(parent_table_name, config) }
+ end.freeze
+ end
+
+ def self.build_definition(parent_table_name, config)
+ to_table = config.fetch('to_table')
+
+ ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(
+ parent_table_name,
+ to_table,
+ {
+ column: config.fetch('column'),
+ on_delete: config.fetch('on_delete').to_sym,
+ gitlab_schema: GitlabSchema.table_schema(to_table)
+ }
+ )
+ end
+
+ def self.loose_foreign_keys_yaml
+ @loose_foreign_keys_yaml ||= YAML.load_file(Rails.root.join('lib/gitlab/database/gitlab_loose_foreign_keys.yml'))
+ end
+
+ private_class_method :build_definition
+ private_class_method :loose_foreign_keys_yaml
+ end
+ end
+end
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index 8b2f786a91a..e247515bdde 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -413,7 +413,7 @@ module Gitlab
end
def issue
- @issue ||= /(?<issue>\d+\b)/
+ @issue ||= /(?<issue>\d+)(?<format>\+)?(?=\W|\z)/
end
def base64_regex
diff --git a/lib/gitlab/tracking.rb b/lib/gitlab/tracking.rb
index ec032cf2d3c..216b1d04bf6 100644
--- a/lib/gitlab/tracking.rb
+++ b/lib/gitlab/tracking.rb
@@ -25,6 +25,10 @@ module Gitlab
snowplow.hostname
end
+ def snowplow_micro_enabled?
+ Rails.env.development? && Gitlab::Utils.to_boolean(ENV['SNOWPLOW_MICRO_ENABLE'])
+ end
+
private
def snowplow
@@ -34,10 +38,6 @@ module Gitlab
Gitlab::Tracking::Destinations::Snowplow.new
end
end
-
- def snowplow_micro_enabled?
- Rails.env.development? && Gitlab::Utils.to_boolean(ENV['SNOWPLOW_MICRO_ENABLE'])
- end
end
end
end
diff --git a/lib/gitlab/tracking/destinations/snowplow_micro.rb b/lib/gitlab/tracking/destinations/snowplow_micro.rb
index cbdc7430e78..8beab910818 100644
--- a/lib/gitlab/tracking/destinations/snowplow_micro.rb
+++ b/lib/gitlab/tracking/destinations/snowplow_micro.rb
@@ -23,8 +23,6 @@ module Gitlab
"#{uri.host}:#{uri.port}"
end
- private
-
def uri
strong_memoize(:snowplow_uri) do
uri = URI(ENV['SNOWPLOW_MICRO_URI'] || DEFAULT_URI)
@@ -33,6 +31,8 @@ module Gitlab
end
end
+ private
+
override :cookie_domain
def cookie_domain
'.gitlab.com'