diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-15 00:07:45 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-15 00:07:45 +0300 |
commit | 0b12a5312c9701fbfed25fbb334d47900ced736b (patch) | |
tree | a29a27e297134f573fd8e5c298d241f3156c207a /lib/banzai | |
parent | 92f95ccac81911d1fcc32e999a7f1ce04624a56c (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/banzai')
-rw-r--r-- | lib/banzai/filter/base_relative_link_filter.rb | 45 | ||||
-rw-r--r-- | lib/banzai/filter/repository_link_filter.rb (renamed from lib/banzai/filter/relative_link_filter.rb) | 83 | ||||
-rw-r--r-- | lib/banzai/filter/upload_link_filter.rb | 61 | ||||
-rw-r--r-- | lib/banzai/pipeline/post_process_pipeline.rb | 5 | ||||
-rw-r--r-- | lib/banzai/pipeline/relative_link_pipeline.rb | 13 |
5 files changed, 117 insertions, 90 deletions
diff --git a/lib/banzai/filter/base_relative_link_filter.rb b/lib/banzai/filter/base_relative_link_filter.rb new file mode 100644 index 00000000000..eca105ce9d9 --- /dev/null +++ b/lib/banzai/filter/base_relative_link_filter.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'uri' + +module Banzai + module Filter + class BaseRelativeLinkFilter < HTML::Pipeline::Filter + include Gitlab::Utils::StrongMemoize + + protected + + def linkable_attributes + strong_memoize(:linkable_attributes) do + attrs = [] + + attrs += doc.search('a:not(.gfm)').map do |el| + el.attribute('href') + end + + attrs += doc.search('img:not(.gfm), video:not(.gfm), audio:not(.gfm)').flat_map do |el| + [el.attribute('src'), el.attribute('data-src')] + end + + attrs.reject do |attr| + attr.blank? || attr.value.start_with?('//') + end + end + end + + def relative_url_root + Gitlab.config.gitlab.relative_url_root.presence || '/' + end + + def project + context[:project] + end + + private + + def unescape_and_scrub_uri(uri) + Addressable::URI.unescape(uri).scrub + end + end + end +end diff --git a/lib/banzai/filter/relative_link_filter.rb b/lib/banzai/filter/repository_link_filter.rb index 4f257189f8e..14cd607cc50 100644 --- a/lib/banzai/filter/relative_link_filter.rb +++ b/lib/banzai/filter/repository_link_filter.rb @@ -4,19 +4,17 @@ require 'uri' module Banzai module Filter - # HTML filter that "fixes" relative links to uploads or files in a repository. + # HTML filter that "fixes" relative links to files in a repository. # # Context options: # :commit - # :group # :current_user # :project # :project_wiki # :ref # :requested_path - class RelativeLinkFilter < HTML::Pipeline::Filter - include Gitlab::Utils::StrongMemoize - + # :system_note + class RepositoryLinkFilter < BaseRelativeLinkFilter def call return doc if context[:system_note] @@ -26,7 +24,9 @@ module Banzai load_uri_types linkable_attributes.each do |attr| - process_link_attr(attr) + if linkable_files? && repo_visible_to_user? + process_link_to_repository_attr(attr) + end end doc @@ -35,8 +35,8 @@ module Banzai protected def load_uri_types - return unless linkable_files? return unless linkable_attributes.present? + return unless linkable_files? return {} unless repository @uri_types = request_path.present? ? get_uri_types([request_path]) : {} @@ -57,24 +57,6 @@ module Banzai end end - def linkable_attributes - strong_memoize(:linkable_attributes) do - attrs = [] - - attrs += doc.search('a:not(.gfm)').map do |el| - el.attribute('href') - end - - attrs += doc.search('img, video, audio').flat_map do |el| - [el.attribute('src'), el.attribute('data-src')] - end - - attrs.reject do |attr| - attr.blank? || attr.value.start_with?('//') - end - end - end - def get_uri_types(paths) return {} if paths.empty? @@ -107,39 +89,6 @@ module Banzai rescue URI::Error, Addressable::URI::InvalidURIError end - def process_link_attr(html_attr) - if html_attr.value.start_with?('/uploads/') - process_link_to_upload_attr(html_attr) - elsif linkable_files? && repo_visible_to_user? - process_link_to_repository_attr(html_attr) - end - end - - def process_link_to_upload_attr(html_attr) - path_parts = [unescape_and_scrub_uri(html_attr.value)] - - if project - path_parts.unshift(relative_url_root, project.full_path) - elsif group - path_parts.unshift(relative_url_root, 'groups', group.full_path, '-') - else - path_parts.unshift(relative_url_root) - end - - begin - path = Addressable::URI.escape(File.join(*path_parts)) - rescue Addressable::URI::InvalidURIError - return - end - - html_attr.value = - if context[:only_path] - path - else - Addressable::URI.join(Gitlab.config.gitlab.base_url, path).to_s - end - end - def process_link_to_repository_attr(html_attr) uri = URI(html_attr.value) @@ -239,10 +188,6 @@ module Banzai @current_commit ||= context[:commit] || repository.commit(ref) end - def relative_url_root - Gitlab.config.gitlab.relative_url_root.presence || '/' - end - def repo_visible_to_user? project && Ability.allowed?(current_user, :download_code, project) end @@ -251,14 +196,6 @@ module Banzai context[:ref] || project.default_branch end - def group - context[:group] - end - - def project - context[:project] - end - def current_user context[:current_user] end @@ -266,12 +203,6 @@ module Banzai def repository @repository ||= project&.repository end - - private - - def unescape_and_scrub_uri(uri) - Addressable::URI.unescape(uri).scrub - end end end end diff --git a/lib/banzai/filter/upload_link_filter.rb b/lib/banzai/filter/upload_link_filter.rb new file mode 100644 index 00000000000..023c1288367 --- /dev/null +++ b/lib/banzai/filter/upload_link_filter.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'uri' + +module Banzai + module Filter + # HTML filter that "fixes" links to uploads. + # + # Context options: + # :group + # :only_path + # :project + # :system_note + class UploadLinkFilter < BaseRelativeLinkFilter + def call + return doc if context[:system_note] + + linkable_attributes.each do |attr| + process_link_to_upload_attr(attr) + end + + doc + end + + protected + + def process_link_to_upload_attr(html_attr) + return unless html_attr.value.start_with?('/uploads/') + + path_parts = [unescape_and_scrub_uri(html_attr.value)] + + if project + path_parts.unshift(relative_url_root, project.full_path) + elsif group + path_parts.unshift(relative_url_root, 'groups', group.full_path, '-') + else + path_parts.unshift(relative_url_root) + end + + begin + path = Addressable::URI.escape(File.join(*path_parts)) + rescue Addressable::URI::InvalidURIError + return + end + + html_attr.value = + if context[:only_path] + path + else + Addressable::URI.join(Gitlab.config.gitlab.base_url, path).to_s + end + + html_attr.parent.add_class('gfm') + end + + def group + context[:group] + end + end + end +end diff --git a/lib/banzai/pipeline/post_process_pipeline.rb b/lib/banzai/pipeline/post_process_pipeline.rb index fe629a23ff1..5e02d972614 100644 --- a/lib/banzai/pipeline/post_process_pipeline.rb +++ b/lib/banzai/pipeline/post_process_pipeline.rb @@ -16,7 +16,10 @@ module Banzai [ Filter::ReferenceRedactorFilter, Filter::InlineMetricsRedactorFilter, - Filter::RelativeLinkFilter, + # UploadLinkFilter must come before RepositoryLinkFilter to + # prevent unnecessary Gitaly calls from being made. + Filter::UploadLinkFilter, + Filter::RepositoryLinkFilter, Filter::IssuableStateFilter, Filter::SuggestionFilter ] diff --git a/lib/banzai/pipeline/relative_link_pipeline.rb b/lib/banzai/pipeline/relative_link_pipeline.rb deleted file mode 100644 index 88651892acc..00000000000 --- a/lib/banzai/pipeline/relative_link_pipeline.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Banzai - module Pipeline - class RelativeLinkPipeline < BasePipeline - def self.filters - FilterArray[ - Filter::RelativeLinkFilter - ] - end - end - end -end |