You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2020/08/31 15:58:21 UTC

[wicket] 02/02: WICKET-6821 align CSPSettings with other settings

This is an automated email from the ASF dual-hosted git repository.

svenmeier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit f97afc3f1df51c410b8523c2c0d1924d08ca1466
Author: Sven Meier <sv...@apache.org>
AuthorDate: Sat Aug 29 22:39:56 2020 +0200

    WICKET-6821 align CSPSettings with other settings
    
    setter instead of factory method, add nonceCreator so subclassing is no longer needed
---
 .../wicket/csp/ContentSecurityPolicySettings.java  | 36 +++++++++++++++++++---
 .../wicket/protocol/http/WebApplication.java       | 16 ++++++++--
 .../csp/CSPSettingRequestCycleListenerTest.java    |  6 ++--
 .../head/filter/FilteringHeaderResponseTest.java   | 16 +++++-----
 4 files changed, 55 insertions(+), 19 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/csp/ContentSecurityPolicySettings.java b/wicket-core/src/main/java/org/apache/wicket/csp/ContentSecurityPolicySettings.java
index 7bd1bdd..de79be8 100644
--- a/wicket-core/src/main/java/org/apache/wicket/csp/ContentSecurityPolicySettings.java
+++ b/wicket-core/src/main/java/org/apache/wicket/csp/ContentSecurityPolicySettings.java
@@ -20,6 +20,7 @@ import java.util.Collections;
 import java.util.EnumMap;
 import java.util.Map;
 import java.util.function.Predicate;
+import java.util.function.Supplier;
 
 import org.apache.wicket.Application;
 import org.apache.wicket.MetaDataKey;
@@ -65,16 +66,20 @@ public class ContentSecurityPolicySettings
 		private static final long serialVersionUID = 1L;
 	};
 
-	private final Application application;
-
 	private final Map<CSPHeaderMode, CSPHeaderConfiguration> configs = new EnumMap<>(
 		CSPHeaderMode.class);
 
 	private Predicate<IRequestHandler> protectedFilter = RenderPageRequestHandler.class::isInstance;
 
+	private Supplier<String> nonceCreator;
+	
 	public ContentSecurityPolicySettings(Application application)
 	{
-		this.application = Args.notNull(application, "application");
+		Args.notNull(application, "application");
+		
+		nonceCreator = () -> {
+				return application.getSecuritySettings().getRandomSupplier().getRandomBase64(NONCE_LENGTH);
+			};
 	}
 
 	public CSPHeaderConfiguration blocking()
@@ -89,6 +94,20 @@ public class ContentSecurityPolicySettings
 	}
 
 	/**
+	 * Sets the creator of nonces.
+	 * 
+	 * @param nonceCreator
+	 *            The new creator, must not be null.
+	 * @return {@code this} for chaining.
+	 */
+	public ContentSecurityPolicySettings setNonceCreator(Supplier<String> nonceCreator)
+	{
+		Args.notNull(nonceCreator, "nonceCreator");
+		this.nonceCreator = nonceCreator;
+		return this;
+	}
+	
+	/**
 	 * Sets the predicate that determines which requests must be protected by the CSP. When the
 	 * predicate evaluates to false, the request will not be protected.
 	 * 
@@ -108,7 +127,7 @@ public class ContentSecurityPolicySettings
 	 * Should any request be protected by CSP.
 	 *
 	 * @param handler
-	 * @return <code>true</code> by default
+	 * @return <code>true</code> by default for all {@link RenderPageRequestHandler}s
 	 * 
 	 * @see #setProtectedFilter(Predicate)
 	 */
@@ -155,9 +174,16 @@ public class ContentSecurityPolicySettings
 		return nonce;
 	}
 
+	/**
+	 * Create a new nonce.
+	 *
+	 * @return nonce
+	 * 
+	 * @see #setNonceCreator(Supplier)
+	 */
 	protected String createNonce()
 	{
-		return application.getSecuritySettings().getRandomSupplier().getRandomBase64(NONCE_LENGTH);
+		return nonceCreator.get();
 	}
 
 	/**
diff --git a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
index d38cadf..a3c4ffc 100644
--- a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
+++ b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
@@ -1111,10 +1111,9 @@ public abstract class WebApplication extends Application
 	}
 	
 	/**
-	 * Builds the {@link ContentSecurityPolicySettings} to be used for this application. Override
-	 * this method to provider your own implementation.
+	 * TODO remove in Wicket 10
 	 * 
-	 * @return The newly created CSP settings.
+	 * @deprecated use {@link #setCspSettings(ContentSecurityPolicySettings)} instead
 	 */
 	protected ContentSecurityPolicySettings newCspSettings()
 	{
@@ -1129,6 +1128,8 @@ public abstract class WebApplication extends Application
 	 * @return The {@link ContentSecurityPolicySettings} for this application.
 	 * @see ContentSecurityPolicySettings
 	 * @see CSPHeaderConfiguration
+	 * 
+	 * TODO make final in Wicket 10
 	 */
 	public ContentSecurityPolicySettings getCspSettings()
 	{
@@ -1140,4 +1141,13 @@ public abstract class WebApplication extends Application
 		}
 		return cspSettings;
 	}
+
+	/**
+	 * Set CSP settings.
+	 * 
+	 */
+	public void setCspSettings(ContentSecurityPolicySettings cspSettings)
+	{
+		this.cspSettings = cspSettings;
+	}
 }
\ No newline at end of file
diff --git a/wicket-core/src/test/java/org/apache/wicket/csp/CSPSettingRequestCycleListenerTest.java b/wicket-core/src/test/java/org/apache/wicket/csp/CSPSettingRequestCycleListenerTest.java
index 08a4d36..0100f58 100644
--- a/wicket-core/src/test/java/org/apache/wicket/csp/CSPSettingRequestCycleListenerTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/csp/CSPSettingRequestCycleListenerTest.java
@@ -53,16 +53,16 @@ public class CSPSettingRequestCycleListenerTest extends WicketTestCase
 		return new MockApplication()
 		{
 			@Override
-			protected ContentSecurityPolicySettings newCspSettings()
+			protected void init()
 			{
-				return new ContentSecurityPolicySettings(this)
+				setCspSettings(new ContentSecurityPolicySettings(this)
 				{
 					@Override
 					public boolean isEnabled()
 					{
 						return true;
 					}
-				};
+				});
 			}
 		};
 	}
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
index 34c6d8a..610abbc 100644
--- a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
@@ -44,22 +44,24 @@ class FilteringHeaderResponseTest extends WicketTestCase
 		return new MockApplication()
 		{
 			@Override
-			protected ContentSecurityPolicySettings newCspSettings()
+			protected void init()
 			{
-				return new ContentSecurityPolicySettings(this)
+				super.init();
+
+				setCspSettings(new ContentSecurityPolicySettings(this)
 				{
 					@Override
 					public String getNonce(RequestCycle cycle)
 					{
 						return "NONCE";
 					}
-					
+
 					@Override
 					public boolean isEnabled()
 					{
 						return true;
 					}
-				};
+				});
 			}
 		};
 	}
@@ -69,8 +71,7 @@ class FilteringHeaderResponseTest extends WicketTestCase
 	{
 		// use this header resource decorator to load all JavaScript resources in the page
 		// footer (after </body>)
-		tester.getApplication()
-			.getHeaderResponseDecorators()
+		tester.getApplication().getHeaderResponseDecorators()
 			.add(response -> new JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS"));
 		executeTest(FilteredHeaderPage.class, "FilteredHeaderPageExpected.html");
 	}
@@ -110,8 +111,7 @@ class FilteringHeaderResponseTest extends WicketTestCase
 	@Test
 	void deferred() throws Exception
 	{
-		tester.getApplication()
-			.getHeaderResponseDecorators()
+		tester.getApplication().getHeaderResponseDecorators()
 			.add(response -> new JavaScriptDeferHeaderResponse(response));
 		executeTest(DeferredPage.class, "DeferredPageExpected.html");
 	}