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 'lib/banzai/filter/inline_metrics_redactor_filter.rb')
-rw-r--r--lib/banzai/filter/inline_metrics_redactor_filter.rb89
1 files changed, 58 insertions, 31 deletions
diff --git a/lib/banzai/filter/inline_metrics_redactor_filter.rb b/lib/banzai/filter/inline_metrics_redactor_filter.rb
index 4d8a5028898..e84ba83e03e 100644
--- a/lib/banzai/filter/inline_metrics_redactor_filter.rb
+++ b/lib/banzai/filter/inline_metrics_redactor_filter.rb
@@ -8,14 +8,17 @@ module Banzai
include Gitlab::Utils::StrongMemoize
METRICS_CSS_CLASS = '.js-render-metrics'
+ URL = Gitlab::Metrics::Dashboard::Url
+
+ Embed = Struct.new(:project_path, :permission)
# Finds all embeds based on the css class the FE
# uses to identify the embedded content, removing
# only unnecessary nodes.
def call
nodes.each do |node|
- path = paths_by_node[node]
- user_has_access = user_access_by_path[path]
+ embed = embeds_by_node[node]
+ user_has_access = user_access_by_embed[embed]
node.remove unless user_has_access
end
@@ -30,40 +33,69 @@ module Banzai
end
# Returns all nodes which the FE will identify as
- # a metrics dashboard placeholder element
+ # a metrics embed placeholder element
#
# @return [Nokogiri::XML::NodeSet]
def nodes
@nodes ||= doc.css(METRICS_CSS_CLASS)
end
- # Maps a node to the full path of a project.
+ # Maps a node to key properties of an embed.
# Memoized so we only need to run the regex to get
# the project full path from the url once per node.
#
- # @return [Hash<Nokogiri::XML::Node, String>]
- def paths_by_node
- strong_memoize(:paths_by_node) do
- nodes.each_with_object({}) do |node, paths|
- paths[node] = path_for_node(node)
+ # @return [Hash<Nokogiri::XML::Node, Embed>]
+ def embeds_by_node
+ strong_memoize(:embeds_by_node) do
+ nodes.each_with_object({}) do |node, embeds|
+ embed = Embed.new
+ url = node.attribute('data-dashboard-url').to_s
+
+ set_path_and_permission(embed, url, URL.regex, :read_environment)
+ set_path_and_permission(embed, url, URL.grafana_regex, :read_project) unless embed.permission
+
+ embeds[node] = embed if embed.permission
end
end
end
- # Gets a project's full_path from the dashboard url
- # in the placeholder node. The FE will use the attr
- # `data-dashboard-url`, so we want to check against that
- # attribute directly in case a user has manually
- # created a metrics element (rather than supporting
- # an alternate attr in InlineMetricsFilter).
+ # Attempts to determine the path and permission attributes
+ # of a url based on expected dashboard url formats and
+ # sets the attributes on an Embed object
#
- # @return [String]
- def path_for_node(node)
- url = node.attribute('data-dashboard-url').to_s
-
- Gitlab::Metrics::Dashboard::Url.regex.match(url) do |m|
+ # @param embed [Embed]
+ # @param url [String]
+ # @param regex [RegExp]
+ # @param permission [Symbol]
+ def set_path_and_permission(embed, url, regex, permission)
+ return unless path = regex.match(url) do |m|
"#{$~[:namespace]}/#{$~[:project]}"
end
+
+ embed.project_path = path
+ embed.permission = permission
+ end
+
+ # Returns a mapping representing whether the current user
+ # has permission to view the embed for the project.
+ # Determined in a batch
+ #
+ # @return [Hash<Embed, Boolean>]
+ def user_access_by_embed
+ strong_memoize(:user_access_by_embed) do
+ unique_embeds.each_with_object({}) do |embed, access|
+ project = projects_by_path[embed.project_path]
+
+ access[embed] = Ability.allowed?(user, embed.permission, project)
+ end
+ end
+ end
+
+ # Returns a unique list of embeds
+ #
+ # @return [Array<Embed>]
+ def unique_embeds
+ embeds_by_node.values.uniq
end
# Maps a project's full path to a Project object.
@@ -74,22 +106,17 @@ module Banzai
def projects_by_path
strong_memoize(:projects_by_path) do
Project.eager_load(:route, namespace: [:route])
- .where_full_path_in(paths_by_node.values.uniq)
+ .where_full_path_in(unique_project_paths)
.index_by(&:full_path)
end
end
- # Returns a mapping representing whether the current user
- # has permission to view the metrics for the project.
- # Determined in a batch
+ # Returns a list of the full_paths of every project which
+ # has an embed in the doc
#
- # @return [Hash<Project, Boolean>]
- def user_access_by_path
- strong_memoize(:user_access_by_path) do
- projects_by_path.each_with_object({}) do |(path, project), access|
- access[path] = Ability.allowed?(user, :read_environment, project)
- end
- end
+ # @return [Array<String>]
+ def unique_project_paths
+ embeds_by_node.values.map(&:project_path).uniq
end
end
end