DEV: Allow plugins to extend frame-ancestors (#13316)

DEV: Allow plugins to extend frame-ancestors (#13316)

diff --git a/lib/content_security_policy/builder.rb b/lib/content_security_policy/builder.rb
index e59e8e2..fe2e830 100644
--- a/lib/content_security_policy/builder.rb
+++ b/lib/content_security_policy/builder.rb
@@ -5,6 +5,7 @@ class ContentSecurityPolicy
   class Builder
     EXTENDABLE_DIRECTIVES = %i[
       base_uri
+      frame_ancestors
       object_src
       script_src
       worker_src
@@ -16,7 +17,6 @@ class ContentSecurityPolicy
       default_src
       font_src
       form_action
-      frame_ancestors
       frame_src
       img_src
       manifest_src
diff --git a/spec/fixtures/plugins/csp_extension/plugin.rb b/spec/fixtures/plugins/csp_extension/plugin.rb
index cfab239..364dd10 100644
--- a/spec/fixtures/plugins/csp_extension/plugin.rb
+++ b/spec/fixtures/plugins/csp_extension/plugin.rb
@@ -7,5 +7,6 @@
 
 extend_content_security_policy(
   script_src: ['https://from-plugin.com'],
-  object_src: ['https://test-stripping.com']
+  object_src: ['https://test-stripping.com'],
+  frame_ancestors: ['https://frame-ancestors-plugin.ext']
 )
diff --git a/spec/lib/content_security_policy_spec.rb b/spec/lib/content_security_policy_spec.rb
index 5d4e0da..73192cd 100644
--- a/spec/lib/content_security_policy_spec.rb
+++ b/spec/lib/content_security_policy_spec.rb
@@ -188,26 +188,49 @@ describe ContentSecurityPolicy do
     end
   end
 
-  it 'can be extended by plugins' do
-    plugin = Class.new(Plugin::Instance) do
-      attr_accessor :enabled
-      def enabled?
-        @enabled
+  context 'with a plugin' do
+    let(:plugin_class) do
+      Class.new(Plugin::Instance) do
+        attr_accessor :enabled
+        def enabled?
+          @enabled
+        end
       end
-    end.new(nil, "#{Rails.root}/spec/fixtures/plugins/csp_extension/plugin.rb")
+    end
+
+    it 'can extend script-src and object-src' do
+      plugin = plugin_class.new(nil, "#{Rails.root}/spec/fixtures/plugins/csp_extension/plugin.rb")
+
+      plugin.activate!
+      Discourse.plugins << plugin
 
-    plugin.activate!
-    Discourse.plugins << plugin
+      plugin.enabled = true
+      expect(parse(policy)['script-src']).to include('https://from-plugin.com')
+      expect(parse(policy)['object-src']).to include('https://test-stripping.com')
+      expect(parse(policy)['object-src']).to_not include("'none'")
 
-    plugin.enabled = true
-    expect(parse(policy)['script-src']).to include('https://from-plugin.com')
-    expect(parse(policy)['object-src']).to include('https://test-stripping.com')
-    expect(parse(policy)['object-src']).to_not include("'none'")
+      plugin.enabled = false
+      expect(parse(policy)['script-src']).to_not include('https://from-plugin.com')
+
+      Discourse.plugins.delete plugin
+    end
 
-    plugin.enabled = false
-    expect(parse(policy)['script-src']).to_not include('https://from-plugin.com')
+    it 'can extend frame_ancestors' do
+      SiteSetting.content_security_policy_frame_ancestors = true
+      plugin = plugin_class.new(nil, "#{Rails.root}/spec/fixtures/plugins/csp_extension/plugin.rb")
 
-    Discourse.plugins.pop
+      plugin.activate!
+      Discourse.plugins << plugin
+
+      plugin.enabled = true
+      expect(parse(policy)['frame-ancestors']).to include("'self'")
+      expect(parse(policy)['frame-ancestors']).to include('https://frame-ancestors-plugin.ext')
+
+      plugin.enabled = false
+      expect(parse(policy)['frame-ancestors']).to_not include('https://frame-ancestors-plugin.ext')
+
+      Discourse.plugins.delete plugin
+    end
   end
 
   it 'only includes unsafe-inline for qunit paths' do

GitHub sha: f90c4bd6

This commit appears in #13316 which was approved by eviltrout. It was merged by pmusaraj.