diff options
Diffstat (limited to 'lib/banzai/filter/inline_metrics_redactor_filter.rb')
-rw-r--r-- | lib/banzai/filter/inline_metrics_redactor_filter.rb | 154 |
1 files changed, 0 insertions, 154 deletions
diff --git a/lib/banzai/filter/inline_metrics_redactor_filter.rb b/lib/banzai/filter/inline_metrics_redactor_filter.rb deleted file mode 100644 index b256815ae84..00000000000 --- a/lib/banzai/filter/inline_metrics_redactor_filter.rb +++ /dev/null @@ -1,154 +0,0 @@ -# frozen_string_literal: true - -module Banzai - module Filter - # HTML filter that removes embeded elements that the current user does - # not have permission to view. - class InlineMetricsRedactorFilter < HTML::Pipeline::Filter - include Gitlab::Utils::StrongMemoize - - METRICS_CSS_CLASS = '.js-render-metrics' - XPATH = Gitlab::Utils::Nokogiri.css_to_xpath(METRICS_CSS_CLASS).freeze - EMBED_LIMIT = 100 - - Route = Struct.new(:regex, :permission) - 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| - embed = embeds_by_node[node] - user_has_access = user_access_by_embed[embed] - - node.remove unless user_has_access - end - - doc - end - - private - - def user - context[:current_user] - end - - # Returns all nodes which the FE will identify as - # a metrics embed placeholder element - # - # Removes any nodes beyond the first 100 - # - # @return [Nokogiri::XML::NodeSet] - def nodes - strong_memoize(:nodes) do - nodes = doc.xpath(XPATH) - nodes.drop(EMBED_LIMIT).each(&:remove) - - nodes - end - end - - # 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, 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 - - permissions_by_route.each do |route| - set_path_and_permission(embed, url, route.regex, route.permission) unless embed.permission - end - - embeds[node] = embed if embed.permission - end - end - end - - def permissions_by_route - [ - Route.new( - ::Gitlab::Metrics::Dashboard::Url.metrics_regex, - :read_environment - ), - Route.new( - ::Gitlab::Metrics::Dashboard::Url.grafana_regex, - :read_project - ), - Route.new( - ::Gitlab::Metrics::Dashboard::Url.clusters_regex, - :read_cluster - ), - Route.new( - ::Gitlab::Metrics::Dashboard::Url.alert_regex, - :read_prometheus_alerts - ) - ] - end - - # 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 - # - # @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. - # Contains all of the Projects referenced in the - # metrics placeholder elements of the current document - # - # @return [Hash<String, Project>] - def projects_by_path - strong_memoize(:projects_by_path) do - Project.eager_load(:route, namespace: [:route]) - .where_full_path_in(unique_project_paths) - .index_by(&:full_path) - end - end - - # Returns a list of the full_paths of every project which - # has an embed in the doc - # - # @return [Array<String>] - def unique_project_paths - embeds_by_node.values.map(&:project_path).uniq - end - end - end -end |