/* * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * 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.access.intercept; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; import java.util.Collection; import java.util.List; import java.util.Vector; import org.aopalliance.intercept.MethodInvocation; import org.junit.Test; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AfterInvocationProvider; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.core.Authentication; import org.springframework.security.util.SimpleMethodInvocation; /** * Tests {@link AfterInvocationProviderManager}. * * @author Ben Alex */ @SuppressWarnings("unchecked") public class AfterInvocationProviderManagerTests { // ~ Methods // ======================================================================================================== @Test public void testCorrectOperation() throws Exception { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); list.add(new MockAfterInvocationProvider("swap1", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); list.add(new MockAfterInvocationProvider("swap2", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); list.add(new MockAfterInvocationProvider("swap3", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); manager.setProviders(list); assertThat(manager.getProviders()).isEqualTo(list); manager.afterPropertiesSet(); List<ConfigAttribute> attr1 = SecurityConfig.createList( new String[] { "GIVE_ME_SWAP1" }); List<ConfigAttribute> attr2 = SecurityConfig.createList( new String[] { "GIVE_ME_SWAP2" }); List<ConfigAttribute> attr3 = SecurityConfig.createList( new String[] { "GIVE_ME_SWAP3" }); List<ConfigAttribute> attr2and3 = SecurityConfig.createList( new String[] { "GIVE_ME_SWAP2", "GIVE_ME_SWAP3" }); List<ConfigAttribute> attr4 = SecurityConfig.createList( new String[] { "NEVER_CAUSES_SWAP" }); assertThat(manager.decide(null, new SimpleMethodInvocation(), attr1, "content-before-swapping")).isEqualTo("swap1"); assertThat(manager.decide(null, new SimpleMethodInvocation(), attr2, "content-before-swapping")).isEqualTo("swap2"); assertThat(manager.decide(null, new SimpleMethodInvocation(), attr3, "content-before-swapping")).isEqualTo("swap3"); assertThat(manager.decide(null, new SimpleMethodInvocation(), attr4, "content-before-swapping")).isEqualTo("content-before-swapping"); assertThat(manager.decide(null, new SimpleMethodInvocation(), attr2and3, "content-before-swapping")).isEqualTo("swap3"); } @Test public void testRejectsEmptyProvidersList() { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); try { manager.setProviders(list); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertThat(true).isTrue(); } } @Test public void testRejectsNonAfterInvocationProviders() { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); list.add(new MockAfterInvocationProvider("swap1", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); list.add(Integer.valueOf(45)); list.add(new MockAfterInvocationProvider("swap3", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); try { manager.setProviders(list); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertThat(true).isTrue(); } } @Test public void testRejectsNullProvidersList() throws Exception { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); try { manager.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertThat(true).isTrue(); } } @Test public void testSupportsConfigAttributeIteration() throws Exception { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); list.add(new MockAfterInvocationProvider("swap1", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); list.add(new MockAfterInvocationProvider("swap2", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); list.add(new MockAfterInvocationProvider("swap3", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); manager.setProviders(list); manager.afterPropertiesSet(); assertThat(manager.supports(new SecurityConfig("UNKNOWN_ATTRIB"))).isFalse(); assertThat(manager.supports(new SecurityConfig("GIVE_ME_SWAP2"))).isTrue(); } @Test public void testSupportsSecureObjectIteration() throws Exception { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); list.add(new MockAfterInvocationProvider("swap1", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); list.add(new MockAfterInvocationProvider("swap2", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); list.add(new MockAfterInvocationProvider("swap3", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); manager.setProviders(list); manager.afterPropertiesSet(); // assertFalse(manager.supports(FilterInvocation.class)); assertThat(manager.supports(MethodInvocation.class)).isTrue(); } // ~ Inner Classes // ================================================================================================== /** * Always returns the constructor-defined <code>forceReturnObject</code>, provided the * same configuration attribute was provided. Also stores the secure object it * supports. */ private class MockAfterInvocationProvider implements AfterInvocationProvider { private Class secureObject; private ConfigAttribute configAttribute; private Object forceReturnObject; public MockAfterInvocationProvider(Object forceReturnObject, Class secureObject, ConfigAttribute configAttribute) { this.forceReturnObject = forceReturnObject; this.secureObject = secureObject; this.configAttribute = configAttribute; } public Object decide(Authentication authentication, Object object, Collection<ConfigAttribute> config, Object returnedObject) throws AccessDeniedException { if (config.contains(configAttribute)) { return forceReturnObject; } return returnedObject; } public boolean supports(Class<?> clazz) { return secureObject.isAssignableFrom(clazz); } public boolean supports(ConfigAttribute attribute) { return attribute.equals(configAttribute); } } }