diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/AbstractConfiguredSecurityBuilderTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/AbstractConfiguredSecurityBuilderTests.groovy deleted file mode 100644 index ab0c813856..0000000000 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/AbstractConfiguredSecurityBuilderTests.groovy +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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.config.annotation.web - -import org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder -import org.springframework.security.config.annotation.BaseSpringSpec -import org.springframework.security.config.annotation.ObjectPostProcessor; -import org.springframework.security.config.annotation.SecurityConfigurer -import org.springframework.security.config.annotation.SecurityConfigurerAdapter -import org.springframework.test.util.ReflectionTestUtils - -import spock.lang.Specification - -/** - * @author Rob Winch - * - */ -class AbstractConfiguredSecurityBuilderTests extends BaseSpringSpec { - - ConcreteAbstractConfiguredBuilder builder - - def setup() { - builder = new ConcreteAbstractConfiguredBuilder(objectPostProcessor) - } - - def "Null ObjectPostProcessor rejected"() { - when: - new ConcreteAbstractConfiguredBuilder(null) - then: - thrown(IllegalArgumentException) - when: - builder.objectPostProcessor(null); - then: - thrown(IllegalArgumentException) - } - - def "apply null is rejected"() { - when: - builder.apply(null) - then: - thrown(IllegalArgumentException) - } - - def "Duplicate configurer is removed"() { - when: - builder.apply(new ConcreteConfigurer()) - builder.apply(new ConcreteConfigurer()) - then: - ReflectionTestUtils.getField(builder,"configurers").size() == 1 - } - - def "build twice fails"() { - setup: - builder.build() - when: - builder.build() - then: - thrown(IllegalStateException) - } - - def "getObject before build fails"() { - when: - builder.getObject() - then: - thrown(IllegalStateException) - } - - def "Configurer.init can apply another configurer"() { - setup: - DelegateConfigurer.CONF = Mock(SecurityConfigurerAdapter) - when: - builder.apply(new DelegateConfigurer()) - builder.build() - then: - 1 * DelegateConfigurer.CONF.init(builder) - 1 * DelegateConfigurer.CONF.configure(builder) - } - - def "getConfigurer with multi fails"() { - setup: - ConcreteAbstractConfiguredBuilder builder = new ConcreteAbstractConfiguredBuilder(objectPostProcessor, true) - builder.apply(new DelegateConfigurer()) - builder.apply(new DelegateConfigurer()) - when: - builder.getConfigurer(DelegateConfigurer) - then: "Fail due to trying to obtain a single DelegateConfigurer and multiple are provided" - thrown(IllegalStateException) - } - - def "removeConfigurer with multi fails"() { - setup: - ConcreteAbstractConfiguredBuilder builder = new ConcreteAbstractConfiguredBuilder(objectPostProcessor, true) - builder.apply(new DelegateConfigurer()) - builder.apply(new DelegateConfigurer()) - when: - builder.removeConfigurer(DelegateConfigurer) - then: "Fail due to trying to remove and obtain a single DelegateConfigurer and multiple are provided" - thrown(IllegalStateException) - } - - def "removeConfigurers with multi"() { - setup: - DelegateConfigurer c1 = new DelegateConfigurer() - DelegateConfigurer c2 = new DelegateConfigurer() - ConcreteAbstractConfiguredBuilder builder = new ConcreteAbstractConfiguredBuilder(objectPostProcessor, true) - builder.apply(c1) - builder.apply(c2) - when: - def result = builder.removeConfigurers(DelegateConfigurer) - then: - result.size() == 2 - result.contains(c1) - result.contains(c2) - builder.getConfigurers(DelegateConfigurer).empty - } - - def "getConfigurers with multi"() { - setup: - DelegateConfigurer c1 = new DelegateConfigurer() - DelegateConfigurer c2 = new DelegateConfigurer() - ConcreteAbstractConfiguredBuilder builder = new ConcreteAbstractConfiguredBuilder(objectPostProcessor, true) - builder.apply(c1) - builder.apply(c2) - when: - def result = builder.getConfigurers(DelegateConfigurer) - then: - result.size() == 2 - result.contains(c1) - result.contains(c2) - builder.getConfigurers(DelegateConfigurer).size() == 2 - } - - private static class DelegateConfigurer extends SecurityConfigurerAdapter { - private static SecurityConfigurer CONF; - - @Override - public void init(ConcreteAbstractConfiguredBuilder builder) - throws Exception { - builder.apply(CONF); - } - } - - private static class ConcreteConfigurer extends SecurityConfigurerAdapter { } - - private class ConcreteAbstractConfiguredBuilder extends AbstractConfiguredSecurityBuilder { - - public ConcreteAbstractConfiguredBuilder(ObjectPostProcessor objectPostProcessor) { - super(objectPostProcessor); - } - - public ConcreteAbstractConfiguredBuilder(ObjectPostProcessor objectPostProcessor, boolean allowMulti) { - super(objectPostProcessor,allowMulti); - } - - public Object performBuild() throws Exception { - return "success"; - } - } - -} diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/RequestMatchersTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/RequestMatchersTests.groovy deleted file mode 100644 index 873f2ed396..0000000000 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/RequestMatchersTests.groovy +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.config.annotation.web; - -import static org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.RequestMatchers.* - -import org.springframework.http.HttpMethod; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.RegexRequestMatcher; - -import spock.lang.Specification; - -/** - * @author Rob Winch - * - */ -class RequestMatchersTests extends Specification { - - def "regexMatchers(GET,'/a.*') uses RegexRequestMatcher"() { - when: - def matchers = regexMatchers(HttpMethod.GET, "/a.*") - then: 'matcher is a RegexRequestMatcher' - matchers.collect {it.class } == [RegexRequestMatcher] - } - - def "regexMatchers('/a.*') uses RegexRequestMatcher"() { - when: - def matchers = regexMatchers("/a.*") - then: 'matcher is a RegexRequestMatcher' - matchers.collect {it.class } == [RegexRequestMatcher] - } - - def "antMatchers(GET,'/a.*') uses AntPathRequestMatcher"() { - when: - def matchers = antMatchers(HttpMethod.GET, "/a.*") - then: 'matcher is a RegexRequestMatcher' - matchers.collect {it.class } == [AntPathRequestMatcher] - } - - def "antMatchers('/a.*') uses AntPathRequestMatcher"() { - when: - def matchers = antMatchers("/a.*") - then: 'matcher is a AntPathRequestMatcher' - matchers.collect {it.class } == [AntPathRequestMatcher] - } -} diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/AbstractConfiguredSecurityBuilderTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/AbstractConfiguredSecurityBuilderTests.java new file mode 100644 index 0000000000..dadf5fb8d5 --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/annotation/web/AbstractConfiguredSecurityBuilderTests.java @@ -0,0 +1,150 @@ +/* + * Copyright 2002-2018 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.config.annotation.web; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder; +import org.springframework.security.config.annotation.ObjectPostProcessor; +import org.springframework.security.config.annotation.SecurityConfigurer; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link AbstractConfiguredSecurityBuilder}. + * + * @author Joe Grandja + */ +public class AbstractConfiguredSecurityBuilderTests { + private TestConfiguredSecurityBuilder builder; + + @Before + public void setUp() { + this.builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenObjectPostProcessorIsNullThenThrowIllegalArgumentException() { + new TestConfiguredSecurityBuilder(null); + } + + @Test(expected = IllegalArgumentException.class) + public void objectPostProcessorWhenNullThenThrowIllegalArgumentException() { + this.builder.objectPostProcessor(null); + } + + @Test + public void applyWhenDuplicateConfigurerAddedThenDuplicateConfigurerRemoved() throws Exception { + this.builder.apply(new TestSecurityConfigurer()); + this.builder.apply(new TestSecurityConfigurer()); + assertThat((Map) ReflectionTestUtils.getField(this.builder, "configurers")).hasSize(1); + } + + @Test(expected = IllegalStateException.class) + public void buildWhenBuildTwiceThenThrowIllegalStateException() throws Exception { + this.builder.build(); + this.builder.build(); + } + + @Test(expected = IllegalStateException.class) + public void getObjectWhenNotBuiltThenThrowIllegalStateException() throws Exception { + this.builder.getObject(); + } + + @Test + public void buildWhenConfigurerAppliesAnotherConfigurerThenObjectStillBuilds() throws Exception { + DelegateSecurityConfigurer.CONFIGURER = mock(SecurityConfigurer.class); + this.builder.apply(new DelegateSecurityConfigurer()); + this.builder.build(); + verify(DelegateSecurityConfigurer.CONFIGURER).init(this.builder); + verify(DelegateSecurityConfigurer.CONFIGURER).configure(this.builder); + } + + @Test(expected = IllegalStateException.class) + public void getConfigurerWhenMultipleConfigurersThenThrowIllegalStateException() throws Exception { + TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class), true); + builder.apply(new DelegateSecurityConfigurer()); + builder.apply(new DelegateSecurityConfigurer()); + builder.getConfigurer(DelegateSecurityConfigurer.class); + } + + @Test(expected = IllegalStateException.class) + public void removeConfigurerWhenMultipleConfigurersThenThrowIllegalStateException() throws Exception { + TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class), true); + builder.apply(new DelegateSecurityConfigurer()); + builder.apply(new DelegateSecurityConfigurer()); + builder.removeConfigurer(DelegateSecurityConfigurer.class); + } + + @Test + public void removeConfigurersWhenMultipleConfigurersThenConfigurersRemoved() throws Exception { + DelegateSecurityConfigurer configurer1 = new DelegateSecurityConfigurer(); + DelegateSecurityConfigurer configurer2 = new DelegateSecurityConfigurer(); + TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class), true); + builder.apply(configurer1); + builder.apply(configurer2); + List removedConfigurers = builder.removeConfigurers(DelegateSecurityConfigurer.class); + assertThat(removedConfigurers).hasSize(2); + assertThat(removedConfigurers).containsExactly(configurer1, configurer2); + assertThat(builder.getConfigurers(DelegateSecurityConfigurer.class)).isEmpty(); + } + + @Test + public void getConfigurersWhenMultipleConfigurersThenConfigurersReturned() throws Exception { + DelegateSecurityConfigurer configurer1 = new DelegateSecurityConfigurer(); + DelegateSecurityConfigurer configurer2 = new DelegateSecurityConfigurer(); + TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class), true); + builder.apply(configurer1); + builder.apply(configurer2); + List configurers = builder.getConfigurers(DelegateSecurityConfigurer.class); + assertThat(configurers).hasSize(2); + assertThat(configurers).containsExactly(configurer1, configurer2); + assertThat(builder.getConfigurers(DelegateSecurityConfigurer.class)).hasSize(2); + } + + private static class DelegateSecurityConfigurer extends SecurityConfigurerAdapter { + private static SecurityConfigurer CONFIGURER; + + @Override + public void init(TestConfiguredSecurityBuilder builder) throws Exception { + builder.apply(CONFIGURER); + } + } + + private static class TestSecurityConfigurer extends SecurityConfigurerAdapter { } + + private static class TestConfiguredSecurityBuilder extends AbstractConfiguredSecurityBuilder { + + private TestConfiguredSecurityBuilder(ObjectPostProcessor objectPostProcessor) { + super(objectPostProcessor); + } + + private TestConfiguredSecurityBuilder(ObjectPostProcessor objectPostProcessor, boolean allowConfigurersOfSameType) { + super(objectPostProcessor, allowConfigurersOfSameType); + } + + public Object performBuild() throws Exception { + return "success"; + } + } +} diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryTests.java new file mode 100644 index 0000000000..5722cb7ab2 --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryTests.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2018 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.config.annotation.web; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.HttpMethod; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.RegexRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link AbstractRequestMatcherRegistry}. + * + * @author Joe Grandja + */ +public class AbstractRequestMatcherRegistryTests { + private TestRequestMatcherRegistry matcherRegistry; + + @Before + public void setUp() { + this.matcherRegistry = new TestRequestMatcherRegistry(); + } + + @Test + public void regexMatchersWhenHttpMethodAndPatternParamsThenReturnRegexRequestMatcherType() { + List requestMatchers = this.matcherRegistry.regexMatchers(HttpMethod.GET, "/a.*"); + assertThat(requestMatchers).isNotEmpty(); + assertThat(requestMatchers.size()).isEqualTo(1); + assertThat(requestMatchers.get(0)).isExactlyInstanceOf(RegexRequestMatcher.class); + } + + @Test + public void regexMatchersWhenPatternParamThenReturnRegexRequestMatcherType() { + List requestMatchers = this.matcherRegistry.regexMatchers("/a.*"); + assertThat(requestMatchers).isNotEmpty(); + assertThat(requestMatchers.size()).isEqualTo(1); + assertThat(requestMatchers.get(0)).isExactlyInstanceOf(RegexRequestMatcher.class); + } + + @Test + public void antMatchersWhenHttpMethodAndPatternParamsThenReturnAntPathRequestMatcherType() { + List requestMatchers = this.matcherRegistry.antMatchers(HttpMethod.GET, "/a.*"); + assertThat(requestMatchers).isNotEmpty(); + assertThat(requestMatchers.size()).isEqualTo(1); + assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class); + } + + @Test + public void antMatchersWhenPatternParamThenReturnAntPathRequestMatcherType() { + List requestMatchers = this.matcherRegistry.antMatchers("/a.*"); + assertThat(requestMatchers).isNotEmpty(); + assertThat(requestMatchers.size()).isEqualTo(1); + assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class); + } + + private static class TestRequestMatcherRegistry extends AbstractRequestMatcherRegistry> { + + @Override + public List mvcMatchers(String... mvcPatterns) { + return null; + } + + @Override + public List mvcMatchers(HttpMethod method, String... mvcPatterns) { + return null; + } + + @Override + protected List chainRequestMatchers(List requestMatchers) { + return requestMatchers; + } + } +}