Sha256: b102b9736e6fb2f6de513da3c8554159d9137c04f3419b645b60a3d7aafa56ca

Contents?: true

Size: 1.54 KB

Versions: 2

Compression:

Stored size: 1.54 KB

Contents

# frozen_string_literal: true

module Decidim
  module DecidimAwesome
    module IframeComponent
      class IframeController < DecidimAwesome::BlankComponentController
        ALLOWED_ATTRIBUTES = %w(src width height frameborder title allow allowpaymentrequest name referrerpolicy sandbox srcdoc allowfullscreen).freeze
        helper_method :iframe, :viewport_width?
        before_action :add_additional_csp_directives, only: :show

        def show; end

        private

        def iframe
          @iframe ||= sanitize(current_component.settings.iframe).html_safe
        end

        def sanitize(html)
          sanitizer = Rails::Html::SafeListSanitizer.new
          partially_sanitized_html = sanitizer.sanitize(html, tags: %w(iframe), attributes: ALLOWED_ATTRIBUTES)

          document = Nokogiri::HTML::DocumentFragment.parse(partially_sanitized_html)
          document.css("iframe").each do |iframe|
            iframe["srcdoc"] = Loofah.fragment(iframe["srcdoc"]).scrub!(:prune).to_s if iframe["srcdoc"]
          end

          document.to_s
        end

        def viewport_width?
          current_component.settings.viewport_width
        end

        def add_additional_csp_directives
          iframe_urls = Nokogiri::HTML::DocumentFragment.parse(iframe).children.select { |x| x.name == "iframe" }.filter_map { |x| x.attribute("src")&.value }
          return if iframe_urls.blank?

          iframe_urls.each do |url|
            content_security_policy.append_csp_directive("frame-src", url)
          end
        end
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
decidim-decidim_awesome-0.11.2 app/controllers/decidim/decidim_awesome/iframe_component/iframe_controller.rb
decidim-decidim_awesome-0.11.1 app/controllers/decidim/decidim_awesome/iframe_component/iframe_controller.rb