Explorar o código

SEC-2339: Added Logical (Or, And, Negated) RequestMatchers

Rob Winch %!s(int64=12) %!d(string=hai) anos
pai
achega
ddc0ef7ab3

+ 1 - 25
config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java

@@ -65,6 +65,7 @@ import org.springframework.security.web.context.AbstractSecurityWebApplicationIn
 import org.springframework.security.web.session.HttpSessionEventPublisher;
 import org.springframework.security.web.util.AntPathRequestMatcher;
 import org.springframework.security.web.util.AnyRequestMatcher;
+import org.springframework.security.web.util.OrRequestMatcher;
 import org.springframework.security.web.util.RegexRequestMatcher;
 import org.springframework.security.web.util.RequestMatcher;
 import org.springframework.util.Assert;
@@ -1346,29 +1347,4 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
         }
         return apply(configurer);
     }
-
-    /**
-     * Internal {@link RequestMatcher} instance used by {@link RequestMatcher}
-     * that will match if any of the passed in {@link RequestMatcher} instances
-     * match.
-     *
-     * @author Rob Winch
-     * @since 3.2
-     */
-    private static final class OrRequestMatcher implements RequestMatcher {
-        private final List<RequestMatcher> requestMatchers;
-
-        private OrRequestMatcher(List<RequestMatcher> requestMatchers) {
-            this.requestMatchers = requestMatchers;
-        }
-
-        public boolean matches(HttpServletRequest request) {
-            for(RequestMatcher matcher : requestMatchers) {
-                if(matcher.matches(request)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
 }

+ 66 - 0
web/src/main/java/org/springframework/security/web/util/AndRequestMatcher.java

@@ -0,0 +1,66 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * 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 org.springframework.security.web.util;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.util.Assert;
+
+
+/**
+ * {@link RequestMatcher} that will return true if all of the passed in
+ * {@link RequestMatcher} instances match.
+ *
+ * @author Rob Winch
+ * @since 3.2
+ */
+public final class AndRequestMatcher implements RequestMatcher {
+    private final List<RequestMatcher> requestMatchers;
+
+    /**
+     * Creates a new instance
+     *
+     * @param requestMatchers the {@link RequestMatcher} instances to try
+     */
+    public AndRequestMatcher(List<RequestMatcher> requestMatchers) {
+        Assert.notEmpty(requestMatchers, "requestMatchers must contain a value");
+        if(requestMatchers.contains(null)) {
+            throw new IllegalArgumentException("requestMatchers cannot contain null values");
+        }
+        this.requestMatchers = requestMatchers;
+    }
+
+    /**
+     * Creates a new instance
+     *
+     * @param requestMatchers the {@link RequestMatcher} instances to try
+     */
+    public AndRequestMatcher(RequestMatcher... requestMatchers) {
+        this(Arrays.asList(requestMatchers));
+    }
+
+    public boolean matches(HttpServletRequest request) {
+        for(RequestMatcher matcher : requestMatchers) {
+            if(!matcher.matches(request)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

+ 46 - 0
web/src/main/java/org/springframework/security/web/util/NegatedRequestMatcher.java

@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * 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 org.springframework.security.web.util;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.util.Assert;
+
+/**
+ * A {@link RequestMatcher} that will negate the {@link RequestMatcher} passed
+ * in. For example, if the {@link RequestMatcher} passed in returns true,
+ * {@link NegatedRequestMatcher} will return false. If the {@link RequestMatcher}
+ * passed in returns false, {@link NegatedRequestMatcher} will return true.
+ *
+ * @author Rob Winch
+ * @since 3.2
+ */
+public class NegatedRequestMatcher implements RequestMatcher {
+    private final RequestMatcher requestMatcher;
+
+    /**
+     * Creates a new instance
+     * @param requestMatcher the {@link RequestMatcher} that will be negated.
+     */
+    public NegatedRequestMatcher(RequestMatcher requestMatcher) {
+        Assert.notNull(requestMatcher, "requestMatcher cannot be null");
+        this.requestMatcher = requestMatcher;
+    }
+
+    public boolean matches(HttpServletRequest request) {
+        return !requestMatcher.matches(request);
+    }
+}

+ 66 - 0
web/src/main/java/org/springframework/security/web/util/OrRequestMatcher.java

@@ -0,0 +1,66 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * 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 org.springframework.security.web.util;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.util.Assert;
+
+
+/**
+ * {@link RequestMatcher} that will return true if any of the passed in
+ * {@link RequestMatcher} instances match.
+ *
+ * @author Rob Winch
+ * @since 3.2
+ */
+public final class OrRequestMatcher implements RequestMatcher {
+    private final List<RequestMatcher> requestMatchers;
+
+    /**
+     * Creates a new instance
+     *
+     * @param requestMatchers the {@link RequestMatcher} instances to try
+     */
+    public OrRequestMatcher(List<RequestMatcher> requestMatchers) {
+        Assert.notEmpty(requestMatchers, "requestMatchers must contain a value");
+        if(requestMatchers.contains(null)) {
+            throw new IllegalArgumentException("requestMatchers cannot contain null values");
+        }
+        this.requestMatchers = requestMatchers;
+    }
+
+    /**
+     * Creates a new instance
+     *
+     * @param requestMatchers the {@link RequestMatcher} instances to try
+     */
+    public OrRequestMatcher(RequestMatcher... requestMatchers) {
+        this(Arrays.asList(requestMatchers));
+    }
+
+    public boolean matches(HttpServletRequest request) {
+        for(RequestMatcher matcher : requestMatchers) {
+            if(matcher.matches(request)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 123 - 0
web/src/test/java/org/springframework/security/web/util/AndRequestMatcherTests.java

@@ -0,0 +1,123 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * 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 org.springframework.security.web.util;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+/**
+ *
+ * @author Rob Winch
+ *
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class AndRequestMatcherTests {
+    @Mock
+    private RequestMatcher delegate;
+
+    @Mock
+    private RequestMatcher delegate2;
+
+    @Mock
+    private HttpServletRequest request;
+
+    private RequestMatcher matcher;
+
+    @Test(expected = NullPointerException.class)
+    public void constructorNullArray() {
+        new AndRequestMatcher((RequestMatcher[]) null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorArrayContainsNull() {
+        new AndRequestMatcher((RequestMatcher)null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorEmptyArray() {
+        new AndRequestMatcher(new RequestMatcher[0]);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorNullList() {
+        new AndRequestMatcher((List<RequestMatcher>) null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorListContainsNull() {
+        new AndRequestMatcher(Arrays.asList((RequestMatcher)null));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorEmptyList() {
+        new AndRequestMatcher(Collections.<RequestMatcher>emptyList());
+    }
+
+    @Test
+    public void matchesSingleTrue() {
+        when(delegate.matches(request)).thenReturn(true);
+        matcher = new AndRequestMatcher(delegate);
+
+        assertThat(matcher.matches(request)).isTrue();
+    }
+
+    @Test
+    public void matchesMultiTrue() {
+        when(delegate.matches(request)).thenReturn(true);
+        when(delegate2.matches(request)).thenReturn(true);
+        matcher = new AndRequestMatcher(delegate, delegate2);
+
+        assertThat(matcher.matches(request)).isTrue();
+    }
+
+
+    @Test
+    public void matchesSingleFalse() {
+        when(delegate.matches(request)).thenReturn(false);
+        matcher = new AndRequestMatcher(delegate);
+
+        assertThat(matcher.matches(request)).isFalse();
+    }
+
+    @Test
+    public void matchesMultiBothFalse() {
+        when(delegate.matches(request)).thenReturn(false);
+        when(delegate2.matches(request)).thenReturn(false);
+        matcher = new AndRequestMatcher(delegate, delegate2);
+
+        assertThat(matcher.matches(request)).isFalse();
+    }
+
+    @Test
+    public void matchesMultiSingleFalse() {
+        when(delegate.matches(request)).thenReturn(true);
+        when(delegate2.matches(request)).thenReturn(false);
+        matcher = new AndRequestMatcher(delegate, delegate2);
+
+        assertThat(matcher.matches(request)).isFalse();
+    }
+}

+ 63 - 0
web/src/test/java/org/springframework/security/web/util/NegatedRequestMatcherTests.java

@@ -0,0 +1,63 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * 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 org.springframework.security.web.util;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+/**
+ *
+ * @author Rob Winch
+ *
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class NegatedRequestMatcherTests {
+    @Mock
+    private RequestMatcher delegate;
+
+    @Mock
+    private HttpServletRequest request;
+
+    private RequestMatcher matcher;
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorNull() {
+        new NegatedRequestMatcher(null);
+    }
+
+    @Test
+    public void matchesDelegateFalse() {
+        when(delegate.matches(request)).thenReturn(false);
+        matcher = new NegatedRequestMatcher(delegate);
+
+        assertThat(matcher.matches(request)).isTrue();
+    }
+
+    @Test
+    public void matchesDelegateTrue() {
+        when(delegate.matches(request)).thenReturn(true);
+        matcher = new NegatedRequestMatcher(delegate);
+
+        assertThat(matcher.matches(request)).isFalse();
+    }
+}

+ 123 - 0
web/src/test/java/org/springframework/security/web/util/OrRequestMatcherTests.java

@@ -0,0 +1,123 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * 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 org.springframework.security.web.util;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+/**
+ *
+ * @author Rob Winch
+ *
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class OrRequestMatcherTests {
+    @Mock
+    private RequestMatcher delegate;
+
+    @Mock
+    private RequestMatcher delegate2;
+
+    @Mock
+    private HttpServletRequest request;
+
+    private RequestMatcher matcher;
+
+    @Test(expected = NullPointerException.class)
+    public void constructorNullArray() {
+        new OrRequestMatcher((RequestMatcher[]) null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorArrayContainsNull() {
+        new OrRequestMatcher((RequestMatcher)null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorEmptyArray() {
+        new OrRequestMatcher(new RequestMatcher[0]);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorNullList() {
+        new OrRequestMatcher((List<RequestMatcher>) null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorListContainsNull() {
+        new OrRequestMatcher(Arrays.asList((RequestMatcher)null));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void constructorEmptyList() {
+        new OrRequestMatcher(Collections.<RequestMatcher>emptyList());
+    }
+
+    @Test
+    public void matchesSingleTrue() {
+        when(delegate.matches(request)).thenReturn(true);
+        matcher = new OrRequestMatcher(delegate);
+
+        assertThat(matcher.matches(request)).isTrue();
+    }
+
+    @Test
+    public void matchesMultiTrue() {
+        when(delegate.matches(request)).thenReturn(true);
+        when(delegate2.matches(request)).thenReturn(true);
+        matcher = new OrRequestMatcher(delegate, delegate2);
+
+        assertThat(matcher.matches(request)).isTrue();
+    }
+
+
+    @Test
+    public void matchesSingleFalse() {
+        when(delegate.matches(request)).thenReturn(false);
+        matcher = new OrRequestMatcher(delegate);
+
+        assertThat(matcher.matches(request)).isFalse();
+    }
+
+    @Test
+    public void matchesMultiBothFalse() {
+        when(delegate.matches(request)).thenReturn(false);
+        when(delegate2.matches(request)).thenReturn(false);
+        matcher = new OrRequestMatcher(delegate, delegate2);
+
+        assertThat(matcher.matches(request)).isFalse();
+    }
+
+    @Test
+    public void matchesMultiSingleFalse() {
+        when(delegate.matches(request)).thenReturn(true);
+        when(delegate2.matches(request)).thenReturn(false);
+        matcher = new OrRequestMatcher(delegate, delegate2);
+
+        assertThat(matcher.matches(request)).isTrue();
+    }
+}