diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java index 75295dad11..bdf15bf2fc 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java +++ b/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 requestMatchers; - - private OrRequestMatcher(List requestMatchers) { - this.requestMatchers = requestMatchers; - } - - public boolean matches(HttpServletRequest request) { - for(RequestMatcher matcher : requestMatchers) { - if(matcher.matches(request)) { - return true; - } - } - return false; - } - } } \ No newline at end of file diff --git a/web/src/main/java/org/springframework/security/web/util/AndRequestMatcher.java b/web/src/main/java/org/springframework/security/web/util/AndRequestMatcher.java new file mode 100644 index 0000000000..d82a7f99b8 --- /dev/null +++ b/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 requestMatchers; + + /** + * Creates a new instance + * + * @param requestMatchers the {@link RequestMatcher} instances to try + */ + public AndRequestMatcher(List 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; + } +} \ No newline at end of file diff --git a/web/src/main/java/org/springframework/security/web/util/NegatedRequestMatcher.java b/web/src/main/java/org/springframework/security/web/util/NegatedRequestMatcher.java new file mode 100644 index 0000000000..14f432d59d --- /dev/null +++ b/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); + } +} \ No newline at end of file diff --git a/web/src/main/java/org/springframework/security/web/util/OrRequestMatcher.java b/web/src/main/java/org/springframework/security/web/util/OrRequestMatcher.java new file mode 100644 index 0000000000..a34d61eb59 --- /dev/null +++ b/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 requestMatchers; + + /** + * Creates a new instance + * + * @param requestMatchers the {@link RequestMatcher} instances to try + */ + public OrRequestMatcher(List 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; + } +} \ No newline at end of file diff --git a/web/src/test/java/org/springframework/security/web/util/AndRequestMatcherTests.java b/web/src/test/java/org/springframework/security/web/util/AndRequestMatcherTests.java new file mode 100644 index 0000000000..6c60a2f72c --- /dev/null +++ b/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) null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorListContainsNull() { + new AndRequestMatcher(Arrays.asList((RequestMatcher)null)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorEmptyList() { + new AndRequestMatcher(Collections.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(); + } +} \ No newline at end of file diff --git a/web/src/test/java/org/springframework/security/web/util/NegatedRequestMatcherTests.java b/web/src/test/java/org/springframework/security/web/util/NegatedRequestMatcherTests.java new file mode 100644 index 0000000000..825e2c4506 --- /dev/null +++ b/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(); + } +} \ No newline at end of file diff --git a/web/src/test/java/org/springframework/security/web/util/OrRequestMatcherTests.java b/web/src/test/java/org/springframework/security/web/util/OrRequestMatcherTests.java new file mode 100644 index 0000000000..8e1d5d2f2e --- /dev/null +++ b/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) null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorListContainsNull() { + new OrRequestMatcher(Arrays.asList((RequestMatcher)null)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorEmptyList() { + new OrRequestMatcher(Collections.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(); + } +} \ No newline at end of file