[java-shib-shared] branch main updated: OSJ-427: Simple signature verification fails to detect parameter ...

Brent Putman putmanb at georgetown.edu
Wed Mar 19 20:52:27 UTC 2025


This is an automated email from the git hooks/post-receive script.

putmanb pushed a commit to branch main
in repository java-shib-shared.

View the commit online:
http://git.shibboleth.net/view/?p=java-shib-shared.git;a=commit;h=643aa235e9261015c4191e812bfced80a344eeb3

The following commit(s) were added to refs/heads/main by this push:
     new 643aa235 OSJ-427: Simple signature verification fails to detect parameter ...
643aa235 is described below

commit 643aa235e9261015c4191e812bfced80a344eeb3
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Wed Mar 19 16:41:51 2025 -0400

    OSJ-427: Simple signature verification fails to detect parameter ...
    
    Move request validation code down to shib-networking.
---
 .../servlet/HttpServletRequestValidator.java       |  36 ++++
 ...BasicHttpServletRequestParametersValidator.java | 174 +++++++++++++++++
 .../impl/ChainingHttpServletRequestValidator.java  |  86 ++++++++
 ...cHttpServletRequestParametersValidatorTest.java | 216 +++++++++++++++++++++
 .../ChainingHttpServletRequestValidatorTest.java   |  86 ++++++++
 5 files changed, 598 insertions(+)

diff --git a/shib-networking/src/main/java/net/shibboleth/shared/servlet/HttpServletRequestValidator.java b/shib-networking/src/main/java/net/shibboleth/shared/servlet/HttpServletRequestValidator.java
new file mode 100644
index 00000000..6b2866d7
--- /dev/null
+++ b/shib-networking/src/main/java/net/shibboleth/shared/servlet/HttpServletRequestValidator.java
@@ -0,0 +1,36 @@
+/*
+ * 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 net.shibboleth.shared.servlet;
+
+import javax.annotation.Nonnull;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+
+/**
+ * Interface for a component that validates an {@link HttpServletRequest}.
+ */
+public interface HttpServletRequestValidator {
+    
+    /**
+     * Validate the request.
+     * 
+     * @param request the request to validate
+     * 
+     * @throws ServletException if the request is determined to be invalid
+     */
+    public void validate(@Nonnull final HttpServletRequest request) throws ServletException; 
+
+}
diff --git a/shib-networking/src/main/java/net/shibboleth/shared/servlet/impl/BasicHttpServletRequestParametersValidator.java b/shib-networking/src/main/java/net/shibboleth/shared/servlet/impl/BasicHttpServletRequestParametersValidator.java
new file mode 100644
index 00000000..80b0faa0
--- /dev/null
+++ b/shib-networking/src/main/java/net/shibboleth/shared/servlet/impl/BasicHttpServletRequestParametersValidator.java
@@ -0,0 +1,174 @@
+/*
+ * 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 net.shibboleth.shared.servlet.impl;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.AbstractInitializableComponent;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.servlet.HttpServletRequestValidator;
+
+/**
+ * Component that validates HTTP request parameters for required presence, uniqueness and mutual exclusivity.
+ */
+public class BasicHttpServletRequestParametersValidator extends AbstractInitializableComponent
+        implements HttpServletRequestValidator {
+    
+    /** Logger. */
+    @Nonnull private Logger log = LoggerFactory.getLogger(BasicHttpServletRequestParametersValidator.class);
+    
+    /** Required parameters. */
+    @Nonnull private Set<String> requiredParameters = CollectionSupport.emptySet();
+    
+    /** Unique parameters. */
+    @Nonnull private Set<String> uniqueParameters = CollectionSupport.emptySet();
+    
+    /** Mutually exclusive parameters. */
+    @Nonnull private Set<Set<String>> mutuallyExclusiveParameters = CollectionSupport.emptySet();
+
+    /**
+     * Get the required parameters. 
+     * 
+     * <p>A required parameter must be present in the request.</p>
+     * 
+     * @return the required parameters
+     */
+    @Nonnull @Unmodifiable @NotLive public Set<String> getRequiredParameters() {
+        return requiredParameters;
+    }
+
+    /**
+     * Set the required parameters. 
+     * 
+     * <p>A required parameter must be present in the request.</p>
+     * 
+     * @param params the required parameters
+     */
+    public void setRequiredParameters(@Nullable final Set<String> params) {
+        checkSetterPreconditions();
+        requiredParameters = CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(params));
+    }
+
+    /**
+     * Get the unique parameters. 
+     * 
+     * <p>A unique parameter must have at most 1 value.</p>
+     * 
+     * @return the unique parameters
+     */
+    @Nonnull @Unmodifiable @NotLive public Set<String> getUniqueParameters() {
+        return uniqueParameters;
+    }
+
+    /**
+     * Set the unique parameters. 
+     * 
+     * <p>A unique parameter must have at most 1 value.</p>
+     * 
+     * @param params the unique parameters
+     */
+    public void setUniqueParameters(@Nullable final Set<String> params) {
+        checkSetterPreconditions();
+        uniqueParameters = CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(params));
+    }
+
+    /**
+     * Get the mutually exclusive parameters.
+     * 
+     * <p>A request may not contain more then 1 parameter from an exclusivity set (the "inner" set(s) configured).
+     * Multiple exclusivity sets may be specified.</p>
+     * 
+     * @return the mutually exclusive parameters
+     */
+    @Nonnull @Unmodifiable @NotLive public Set<Set<String>> getMutuallyExclusiveParameters() {
+        return mutuallyExclusiveParameters;
+    }
+
+    /**
+     * Set the mutually exclusive parameters.
+     * 
+     * <p>A request may not contain more then 1 parameter from an exclusivity set (the "inner" set(s) configured).
+     * Multiple exclusivity sets may be specified.</p>
+     * 
+     * @param params the mutually exclusive parameters 
+     */
+    public void setMutuallyExclusiveParameters(@Nullable final Set<Set<String>> params) {
+        checkSetterPreconditions();
+        if (params == null) {
+            mutuallyExclusiveParameters = CollectionSupport.emptySet();
+        } else {
+            mutuallyExclusiveParameters = params.stream()
+                    .map(StringSupport::normalizeStringCollection)
+                    .map(CollectionSupport::copyToSet)
+                    .collect(CollectionSupport.nonnullCollector(Collectors.toUnmodifiableSet())).get();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void validate(@Nonnull final HttpServletRequest request) throws ServletException {
+        Constraint.isNotNull(request, "HttpServletRequest was null");
+        final Set<String> requestParams = request.getParameterMap().keySet();
+
+        log.debug("Evaluating request for required parameters: {}", getRequiredParameters());
+        for (final String param : getRequiredParameters()) {
+            if (!requestParams.contains(param)) {
+                log.warn("HTTP request did not contain required parameter: {}", param);
+                throw new ServletException("HTTP request did not contain required parameter: " + param);
+            }
+        }
+        
+        log.debug("Evaluating request for unique parameters: {}", getUniqueParameters());
+        for (final String param : getUniqueParameters()) {
+            final String[] values = request.getParameterValues(param);
+            if (values != null && values.length > 1) {
+                log.warn("HTTP request contained {} values for parameter: {}", values.length, param);
+                throw new ServletException("HTTP request contained multiple values for parameter: " + param);
+            }
+        }
+        
+        log.debug("Evaluating request for mutually exclusive parameters: {}", getMutuallyExclusiveParameters());
+        for (final Set<String> group : getMutuallyExclusiveParameters())  {
+            if (group.size() < 2) {
+                log.debug("Exclusivity group had < 2 members, skipping evaluation: ", group);
+                continue;
+            }
+            
+            final Set<String> groupIntersection = requestParams.stream()
+                    .filter(p -> group.contains(p))
+                    .collect(Collectors.toSet());
+
+           if (groupIntersection.size() > 1) {
+               log.warn("HTTP request contained mutuallly exclusive parameters: {}", groupIntersection);
+               throw new ServletException("HTTP request contained mutually exclusive parameters: "
+                       + groupIntersection);
+           }
+       }
+        
+    }
+
+}
diff --git a/shib-networking/src/main/java/net/shibboleth/shared/servlet/impl/ChainingHttpServletRequestValidator.java b/shib-networking/src/main/java/net/shibboleth/shared/servlet/impl/ChainingHttpServletRequestValidator.java
new file mode 100644
index 00000000..32372e69
--- /dev/null
+++ b/shib-networking/src/main/java/net/shibboleth/shared/servlet/impl/ChainingHttpServletRequestValidator.java
@@ -0,0 +1,86 @@
+/*
+ * 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 net.shibboleth.shared.servlet.impl;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.AbstractInitializableComponent;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.servlet.HttpServletRequestValidator;
+
+/**
+ * Implementation for a chain of {@link HttpServletRequestValidator}.
+ */
+public class ChainingHttpServletRequestValidator extends AbstractInitializableComponent implements HttpServletRequestValidator {
+   
+    /** Logger. */
+    private Logger log = LoggerFactory.getLogger(ChainingHttpServletRequestValidator.class);
+    
+    /** Chain validators. */
+    @Nonnull private List<HttpServletRequestValidator> validators = CollectionSupport.emptyList();
+    
+    /**
+     * Get the list of registered validators.
+     * 
+     * @return the list of validators
+     */
+    @Nonnull @Unmodifiable @NotLive public List<HttpServletRequestValidator> getValidators() {
+        return validators;
+    }
+
+    /**
+     * Set the list of registered validators.
+     * 
+     * @param newValidators the validators to use
+     */
+    public void setValidators(@Nullable final List<HttpServletRequestValidator> newValidators) {
+        checkSetterPreconditions();
+        
+        if (newValidators == null) {
+            validators = CollectionSupport.emptyList();
+        } else {
+            validators = newValidators.stream()
+                    .filter(Objects::nonNull)
+                    .collect(CollectionSupport.nonnullCollector(Collectors.toUnmodifiableList())).get();
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void validate(@Nonnull final HttpServletRequest request) throws ServletException {
+        for (final HttpServletRequestValidator validator : getValidators()) {
+            try {
+                validator.validate(request);
+            } catch (ServletException e) {
+                log.debug("Request failed validation for validator: {}", validator.getClass().getName());
+                throw e;
+            }
+        }
+    }
+
+}
diff --git a/shib-networking/src/test/java/net/shibboleth/shared/servlet/impl/BasicHttpServletRequestParametersValidatorTest.java b/shib-networking/src/test/java/net/shibboleth/shared/servlet/impl/BasicHttpServletRequestParametersValidatorTest.java
new file mode 100644
index 00000000..3ce4b909
--- /dev/null
+++ b/shib-networking/src/test/java/net/shibboleth/shared/servlet/impl/BasicHttpServletRequestParametersValidatorTest.java
@@ -0,0 +1,216 @@
+/*
+ * 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 net.shibboleth.shared.servlet.impl;
+
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jakarta.servlet.ServletException;
+import net.shibboleth.shared.collection.Pair;
+
+/**
+ * Unit test for {@link BasicHttpServletRequestParametersValidator}
+ */
+public class BasicHttpServletRequestParametersValidatorTest {
+    
+    @DataProvider
+    Object[][] requiredParamsSetterData() {
+        return new Object[][] {
+            new Object[] { Set.of(),
+                    Set.of()},
+            new Object[] { Set.of("  Foo  ", "  Bar  ", "   "),
+                    Set.of("Foo", "Bar")},
+        };
+    }
+    
+    @Test(dataProvider="requiredParamsSetterData")
+    public void requiredSetter(Set<String> params, Set<String> expected) throws Exception {
+        BasicHttpServletRequestParametersValidator validator = new BasicHttpServletRequestParametersValidator();
+        validator.setRequiredParameters(params);
+        validator.initialize();
+        
+        Assert.assertEquals(validator.getRequiredParameters(), expected);
+    }
+    
+    @DataProvider
+    Object[][] uniqueParamsSetterData() {
+        return new Object[][] {
+            new Object[] { Set.of(),
+                    Set.of()},
+            new Object[] { Set.of("  Foo  ", "  Bar  ", "   "),
+                    Set.of("Foo", "Bar")},
+        };
+    }
+    
+    @Test(dataProvider="uniqueParamsSetterData")
+    public void uniqueSetter(Set<String> params, Set<String> expected) throws Exception {
+        BasicHttpServletRequestParametersValidator validator = new BasicHttpServletRequestParametersValidator();
+        validator.setUniqueParameters(params);
+        validator.initialize();
+        
+        Assert.assertEquals(validator.getUniqueParameters(), expected);
+    }
+    
+    @DataProvider
+    Object[][] exclusiveParamsSetterData() {
+        return new Object[][] {
+            new Object[] { Set.of(Set.of()),
+                    Set.of(Set.of())},
+            new Object[] { Set.of(Set.of("  Foo  ", "  Bar  ", "   ")),
+                    Set.of(Set.of("Foo", "Bar"))},
+            new Object[] { Set.of(Set.of("  Foo  ", "  Bar  ", "   "), Set.of("  Baz   ", "   ", "   ABC  ")),
+                    Set.of(Set.of("Foo", "Bar"), Set.of("Baz", "ABC"))},
+        };
+    }
+    
+    @Test(dataProvider="exclusiveParamsSetterData")
+    public void exclusiveSetter(Set<Set<String>> params, Set<Set<String>> expected) throws Exception {
+        BasicHttpServletRequestParametersValidator validator = new BasicHttpServletRequestParametersValidator();
+        validator.setMutuallyExclusiveParameters(params);
+        validator.initialize();
+        
+        Assert.assertEquals(validator.getMutuallyExclusiveParameters(), expected);
+    }
+    
+    @DataProvider
+    Object[][] requiredParamsEvalData() {
+        return new Object[][] {
+            new Object[] { List.of(),
+                    Set.of(),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc"})),
+                    Set.of(),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc"})),
+                    Set.of("Foo"),
+                    true},
+            new Object[] { List.of(new Pair<>("Bar", new String[]{"def"})),
+                    Set.of("Foo"),
+                    false},
+            new Object[] { List.of(),
+                    Set.of("Foo"),
+                    false},
+        };
+    }
+    
+    @Test(dataProvider="requiredParamsEvalData")
+    public void requiredEval(List<Pair<String, String[]>> requestParams, Set<String> requiredParams, boolean valid) throws Exception {
+        BasicHttpServletRequestParametersValidator validator = new BasicHttpServletRequestParametersValidator();
+        validator.setRequiredParameters(requiredParams);
+        evaluateRequest(validator, "required", requestParams, valid);
+    }
+    
+    @DataProvider
+    Object[][] uniqueParamsEvalData() {
+        return new Object[][] {
+            new Object[] { List.of(),
+                    Set.of(),
+                    true},
+            new Object[] { List.of(),
+                    Set.of("Foo"),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc"})),
+                    Set.of("Foo"),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc"})),
+                    Set.of(),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc", "def"})),
+                    Set.of(),
+                    true},
+            new Object[] { List.of(new Pair<>("Bar", new String[]{"abc", "def"})),
+                    Set.of("Foo"),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc", "def"})),
+                    Set.of("Foo"),
+                    false},
+        };
+    }
+    
+    @Test(dataProvider="uniqueParamsEvalData")
+    public void uniqueEval(List<Pair<String, String[]>> requestParams, Set<String> uniqueParams, boolean valid) throws Exception {
+        BasicHttpServletRequestParametersValidator validator = new BasicHttpServletRequestParametersValidator();
+        validator.setUniqueParameters(uniqueParams);
+        evaluateRequest(validator, "unique", requestParams, valid);
+    }
+    
+    @DataProvider
+    Object[][] mutuallyExclusiveParamsEvalData() {
+        return new Object[][] {
+            new Object[] { List.of(),
+                    Set.of(),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc"})),
+                    Set.of(),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc",}), new Pair<>("Bar", new String[] {"def"})),
+                    Set.of(),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc",}), new Pair<>("Bar", new String[] {"def"})),
+                    Set.of(Set.of("Foo")),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc"})),
+                    Set.of(Set.of("Foo", "Bar")),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc",}), new Pair<>("Baz", new String[] {"def"})),
+                    Set.of(Set.of("Foo", "Bar")),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc",}), new Pair<>("Baz", new String[] {"def"})),
+                    Set.of(Set.of("Foo", "Bar"), Set.of("Bar", "Baz")),
+                    true},
+            new Object[] { List.of(new Pair<>("Foo", new String[]{"abc",}), new Pair<>("Bar", new String[] {"def"})),
+                    Set.of(Set.of("Foo", "Bar")),
+                    false},
+        };
+    }
+    
+    @Test(dataProvider="mutuallyExclusiveParamsEvalData")
+    public void mutuallyExclusiveEval(List<Pair<String, String[]>> requestParams, Set<Set<String>> exclusiveParams, boolean valid) throws Exception {
+        BasicHttpServletRequestParametersValidator validator = new BasicHttpServletRequestParametersValidator();
+        validator.setMutuallyExclusiveParameters(exclusiveParams);
+        evaluateRequest(validator, "exclusive", requestParams, valid);
+    }
+    
+    private void evaluateRequest(BasicHttpServletRequestParametersValidator validator, String desc,
+            List<Pair<String, String[]>> requestParams, boolean valid) throws Exception{
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        for (final Pair<String,String[]> requestParam : requestParams) {
+            final String first = requestParam.getFirst();
+            final String[] second = requestParam.getSecond();
+            assert first != null && second != null;
+            request.addParameter(first, second); 
+        }
+
+        validator.initialize();
+
+        try {
+            validator.validate(request);
+            if (!valid) {
+                Assert.fail(String.format("Request evaled to valid on invalid %s params", desc));
+            }
+        } catch (ServletException e) {
+            if (valid) {
+                Assert.fail(String.format("Request evaled to invaid on valid %s params", desc));
+            }
+        }
+    }
+
+}
diff --git a/shib-networking/src/test/java/net/shibboleth/shared/servlet/impl/ChainingHttpServletRequestValidatorTest.java b/shib-networking/src/test/java/net/shibboleth/shared/servlet/impl/ChainingHttpServletRequestValidatorTest.java
new file mode 100644
index 00000000..c4ea9f95
--- /dev/null
+++ b/shib-networking/src/test/java/net/shibboleth/shared/servlet/impl/ChainingHttpServletRequestValidatorTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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 net.shibboleth.shared.servlet.impl;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import net.shibboleth.shared.servlet.HttpServletRequestValidator;
+
+/**
+ * Unit test for {@link ChainingHttpServletRequestValidator}
+ */
+public class ChainingHttpServletRequestValidatorTest {
+    
+    @DataProvider
+    Object[][] testData() {
+        return new Object[][] {
+            new Object[] {null, true},
+            new Object[] {List.of(), true},
+            new Object[] {List.of(new MockValidator(true)), true},
+            new Object[] {List.of(new MockValidator(true), new MockValidator(true), new MockValidator(true)), true},
+            new Object[] {List.of(new MockValidator(false), new MockValidator(true), new MockValidator(true)), false},
+            new Object[] {List.of(new MockValidator(true), new MockValidator(true), new MockValidator(false)), false},
+        };
+    }
+    
+    @Test(dataProvider="testData")
+    public void validateRequest(List<HttpServletRequestValidator> validators, boolean valid) throws Exception {
+        ChainingHttpServletRequestValidator validator = new ChainingHttpServletRequestValidator();
+        validator.setValidators(validators);
+        validator.initialize();
+        
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        
+        try {
+            validator.validate(request);
+            if (!valid) {
+                Assert.fail("Invalid request evaled to valid");
+            }
+        } catch (ServletException e) {
+            if (valid) {
+                Assert.fail("Valid request evaled to invalid");
+            }
+        }
+    }
+    
+    public class MockValidator implements HttpServletRequestValidator {
+        
+        private boolean valid;
+
+        public MockValidator(boolean result) {
+            valid = result ;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void validate(@Nonnull HttpServletRequest request) throws ServletException {
+            if (!valid) {
+                throw new ServletException("Request was invalid");
+            }
+            
+        }
+        
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list