diff --git a/pom.xml b/pom.xml
index eb610f6..113d857 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,6 +103,11 @@
assertj-core
3.15.0
+
+ org.mockito
+ mockito-core
+ 3.3.3
+
com.fasterxml.jackson
jackson-bom
@@ -152,6 +157,11 @@
junit-jupiter-engine
test
+
+ org.mockito
+ mockito-core
+ test
+
org.springframework
spring-test
diff --git a/src/main/java/com/innoq/spring/cookie/flash/CookieFlashMapManager.java b/src/main/java/com/innoq/spring/cookie/flash/CookieFlashMapManager.java
index 2c397d1..ffb227a 100644
--- a/src/main/java/com/innoq/spring/cookie/flash/CookieFlashMapManager.java
+++ b/src/main/java/com/innoq/spring/cookie/flash/CookieFlashMapManager.java
@@ -15,6 +15,8 @@
*/
package com.innoq.spring.cookie.flash;
+import com.innoq.spring.cookie.flash.codec.FlashMapListCodec;
+import com.innoq.spring.cookie.flash.verification.CookieVerificationFailureHandler;
import com.innoq.spring.cookie.security.CookieValueSigner;
import org.springframework.util.Assert;
import org.springframework.web.servlet.FlashMap;
@@ -36,6 +38,8 @@ public final class CookieFlashMapManager extends AbstractFlashMapManager {
private final FlashMapListCodec codec;
private final CookieValueSigner signer;
private final String cookieName;
+ private CookieVerificationFailureHandler verificationFailureHandler =
+ CookieVerificationFailureHandler.ignoreFailures();
public CookieFlashMapManager(FlashMapListCodec codec,
CookieValueSigner signer) {
@@ -52,6 +56,12 @@ public CookieFlashMapManager(FlashMapListCodec codec,
this.cookieName = cookieName;
}
+ public void setVerificationFailureHandler(
+ CookieVerificationFailureHandler verificationFailureHandler) {
+ Assert.notNull(verificationFailureHandler, "CookieVerificationFailureHandler must not be null");
+ this.verificationFailureHandler = verificationFailureHandler;
+ }
+
@Override
protected List retrieveFlashMaps(HttpServletRequest request) {
final Cookie cookie = getCookie(request, cookieName);
@@ -87,16 +97,14 @@ protected Object getFlashMapsMutex(HttpServletRequest request) {
private List decode(String value) {
final String[] signatureAndPayload = reverse(value).split("--", 2);
if (signatureAndPayload.length != 2) {
- // TODO logging
- return null;
+ return verificationFailureHandler.onInvalidValue(value);
}
final String signature = reverse(signatureAndPayload[0]);
final String payload = reverse(signatureAndPayload[1]);
if (!isVerified(payload, signature)) {
- // TODO logging
- return null;
+ return verificationFailureHandler.onInvalidSignature(payload, signature);
}
return codec.decode(payload);
diff --git a/src/main/java/com/innoq/spring/cookie/flash/FlashMapListCodec.java b/src/main/java/com/innoq/spring/cookie/flash/codec/FlashMapListCodec.java
similarity index 94%
rename from src/main/java/com/innoq/spring/cookie/flash/FlashMapListCodec.java
rename to src/main/java/com/innoq/spring/cookie/flash/codec/FlashMapListCodec.java
index 02a0524..88ecb4f 100644
--- a/src/main/java/com/innoq/spring/cookie/flash/FlashMapListCodec.java
+++ b/src/main/java/com/innoq/spring/cookie/flash/codec/FlashMapListCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.innoq.spring.cookie.flash;
+package com.innoq.spring.cookie.flash.codec;
import org.springframework.web.servlet.FlashMap;
diff --git a/src/main/java/com/innoq/spring/cookie/flash/codec/jackson/JacksonFlashMapListCodec.java b/src/main/java/com/innoq/spring/cookie/flash/codec/jackson/JacksonFlashMapListCodec.java
index b314749..69ae433 100644
--- a/src/main/java/com/innoq/spring/cookie/flash/codec/jackson/JacksonFlashMapListCodec.java
+++ b/src/main/java/com/innoq/spring/cookie/flash/codec/jackson/JacksonFlashMapListCodec.java
@@ -19,7 +19,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.innoq.spring.cookie.flash.FlashMapListCodec;
+import com.innoq.spring.cookie.flash.codec.FlashMapListCodec;
import org.springframework.util.Assert;
import org.springframework.web.servlet.FlashMap;
diff --git a/src/main/java/com/innoq/spring/cookie/flash/verification/CookieVerificationFailureHandler.java b/src/main/java/com/innoq/spring/cookie/flash/verification/CookieVerificationFailureHandler.java
new file mode 100644
index 0000000..18bb4fc
--- /dev/null
+++ b/src/main/java/com/innoq/spring/cookie/flash/verification/CookieVerificationFailureHandler.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright 2018 innoQ Deutschland GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.innoq.spring.cookie.flash.verification;
+
+import org.springframework.web.servlet.FlashMap;
+
+import java.util.List;
+
+public interface CookieVerificationFailureHandler {
+
+ List onInvalidValue(String value);
+
+ List onInvalidSignature(String payload, String signature);
+
+ static CookieVerificationFailureHandler ignoreFailures() {
+ return IgnoreCookieVerificationFailureHandler.INSTANCE;
+ }
+}
diff --git a/src/main/java/com/innoq/spring/cookie/flash/verification/IgnoreCookieVerificationFailureHandler.java b/src/main/java/com/innoq/spring/cookie/flash/verification/IgnoreCookieVerificationFailureHandler.java
new file mode 100644
index 0000000..0452c95
--- /dev/null
+++ b/src/main/java/com/innoq/spring/cookie/flash/verification/IgnoreCookieVerificationFailureHandler.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright 2018 innoQ Deutschland GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.innoq.spring.cookie.flash.verification;
+
+import org.springframework.web.servlet.FlashMap;
+
+import java.util.List;
+
+enum IgnoreCookieVerificationFailureHandler
+ implements CookieVerificationFailureHandler {
+ INSTANCE;
+
+ @Override
+ public List onInvalidValue(String value) {
+ return null;
+ }
+
+ @Override
+ public List onInvalidSignature(String payload, String signature) {
+ return null;
+ }
+}
diff --git a/src/test/java/com/innoq/spring/cookie/flash/CookieFlashMapManagerTest.java b/src/test/java/com/innoq/spring/cookie/flash/CookieFlashMapManagerTest.java
index be88e42..9dcf455 100644
--- a/src/test/java/com/innoq/spring/cookie/flash/CookieFlashMapManagerTest.java
+++ b/src/test/java/com/innoq/spring/cookie/flash/CookieFlashMapManagerTest.java
@@ -16,6 +16,7 @@
package com.innoq.spring.cookie.flash;
import com.innoq.spring.cookie.flash.codec.jackson.JacksonFlashMapListCodec;
+import com.innoq.spring.cookie.flash.verification.CookieVerificationFailureHandler;
import com.innoq.spring.cookie.security.CookieValueSigner;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -30,6 +31,9 @@
import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
class CookieFlashMapManagerTest {
@@ -65,6 +69,43 @@ void retrieveFlashMaps_withValidCookie_returnsFlashMaps() {
assertThat(flashMap.getTargetRequestPath()).isEqualTo("/foo");
}
+ @Test
+ void retrieveFlashMaps_withInvalidCookieValue_callsGivenVerificationFailureHandlerAndUsesItsReturnValue() {
+ MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
+ request.setCookies(new Cookie("flash", "ABCDEF"));
+
+ CookieVerificationFailureHandler verificationFailureHandler =
+ mock(CookieVerificationFailureHandler.class);
+ when(verificationFailureHandler.onInvalidValue("ABCDEF")).thenReturn(null);
+
+ sut.setVerificationFailureHandler(verificationFailureHandler);
+
+ List flashMaps = sut.retrieveFlashMaps(request);
+
+ assertThat(flashMaps).isNull();
+ verify(verificationFailureHandler).onInvalidValue("ABCDEF");
+ }
+
+ @Test
+ void retrieveFlashMaps_withInvalidCookieValueSignatur_callsGivenVerificationFailureHandlerAndUsesItsReturnValue() {
+ String cookieValue = "abcd--efgh";
+
+ MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
+ request.setCookies(new Cookie("flash", cookieValue));
+
+ CookieVerificationFailureHandler verificationFailureHandler =
+ mock(CookieVerificationFailureHandler.class);
+ when(verificationFailureHandler.onInvalidSignature("abcd", "efgh"))
+ .thenReturn(null);
+
+ sut.setVerificationFailureHandler(verificationFailureHandler);
+
+ List flashMaps = sut.retrieveFlashMaps(request);
+
+ assertThat(flashMaps).isNull();
+ verify(verificationFailureHandler).onInvalidSignature("abcd", "efgh");
+ }
+
@Test
void updateFlashMaps_withSingleFlashMap_writesCookie() {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");