/* * Copyright 2002-2015 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.integration.security.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import org.junit.Before; import org.junit.Test; import org.springframework.aop.Advisor; import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; import org.springframework.beans.DirectFieldAccessor; import org.springframework.integration.channel.AbstractPollableChannel; import org.springframework.integration.core.MessageSelector; import org.springframework.integration.security.channel.ChannelAccessPolicy; import org.springframework.integration.security.channel.ChannelSecurityInterceptor; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.support.ChannelInterceptor; import org.springframework.security.access.ConfigAttribute; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; /** * @author Jonas Partner * @author Mark Fisher * @author Oleg Zhurakousky */ @ContextConfiguration public class SecuredChannelsParserTests extends AbstractJUnit4SpringContextTests { TestMessageChannel messageChannel; @Before public void setUp() { messageChannel = new TestMessageChannel(); } @Test public void testAdminRequiredForSend() { String beanName = "adminRequiredForSend"; messageChannel.setBeanName(beanName); MessageChannel proxy = (MessageChannel) applicationContext.getAutowireCapableBeanFactory() .applyBeanPostProcessorsAfterInitialization(messageChannel, beanName); assertTrue("Channel was not proxied", AopUtils.isAopProxy(proxy)); Advisor[] advisors = ((Advised) proxy).getAdvisors(); assertEquals("Wrong number of interceptors", 1, advisors.length); ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice(); ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor); assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy); Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend(); Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive(); assertTrue("ROLE_ADMIN not found as send attribute", this.getRolesFromDefintion(sendDefinition).contains("ROLE_ADMIN")); assertTrue("Policy applies to receive", receiveDefinition.size() == 0); } @Test public void testAdminOrUserRequiredForSend() { String beanName = "adminOrUserRequiredForSend"; messageChannel.setBeanName(beanName); MessageChannel proxy = (MessageChannel) applicationContext.getAutowireCapableBeanFactory() .applyBeanPostProcessorsAfterInitialization(messageChannel, beanName); assertTrue("Channel was not proxied", AopUtils.isAopProxy(proxy)); Advisor[] advisors = ((Advised) proxy).getAdvisors(); assertEquals("Wrong number of interceptors", 1, advisors.length); ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice(); ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor); assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy); Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend(); Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive(); Collection<String> sendRoles = this.getRolesFromDefintion(sendDefinition); assertTrue("ROLE_ADMIN not found as send attribute", sendRoles.contains("ROLE_ADMIN")); assertTrue("ROLE_USER not found as send attribute", sendRoles.contains("ROLE_USER")); assertTrue("Policy applies to receive", receiveDefinition.size() == 0); } @Test public void testAdminRequiredForReceive() { String beanName = "adminRequiredForReceive"; messageChannel.setBeanName(beanName); MessageChannel proxy = (MessageChannel) applicationContext.getAutowireCapableBeanFactory() .applyBeanPostProcessorsAfterInitialization(messageChannel, beanName); assertTrue("Channel was not proxied", AopUtils.isAopProxy(proxy)); Advisor[] advisors = ((Advised) proxy).getAdvisors(); assertEquals("Wrong number of interceptors", 1, advisors.length); ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice(); ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor); assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy); Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend(); Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive(); Collection<String> receiveRoles = this.getRolesFromDefintion(receiveDefinition); assertTrue("ROLE_ADMIN not found as receive attribute", receiveRoles.contains("ROLE_ADMIN")); assertTrue("Policy applies to receive", sendDefinition.size() == 0); } @Test public void testAdminOrUserRequiredForReceive() { String beanName = "adminOrUserRequiredForReceive"; messageChannel.setBeanName(beanName); MessageChannel proxy = (MessageChannel) applicationContext.getAutowireCapableBeanFactory() .applyBeanPostProcessorsAfterInitialization(messageChannel, beanName); assertTrue("Channel was not proxied", AopUtils.isAopProxy(proxy)); Advisor[] advisors = ((Advised) proxy).getAdvisors(); assertEquals("Wrong number of interceptors", 1, advisors.length); ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice(); ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor); assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy); Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend(); Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive(); Collection<String> receiveRoles = this.getRolesFromDefintion(receiveDefinition); assertTrue("ROLE_ADMIN not found as receive attribute", receiveRoles.contains("ROLE_ADMIN")); assertTrue("ROLE_USER not found as receive attribute", receiveRoles.contains("ROLE_USER")); assertTrue("Policy applies to receive", sendDefinition.size() == 0); } @Test public void testAdminRequiredForSendAndReceive() { String beanName = "adminRequiredForSendAndReceive"; messageChannel.setBeanName(beanName); MessageChannel proxy = (MessageChannel) applicationContext.getAutowireCapableBeanFactory() .applyBeanPostProcessorsAfterInitialization(messageChannel, beanName); assertTrue("Channel was not proxied", AopUtils.isAopProxy(proxy)); Advisor[] advisors = ((Advised) proxy).getAdvisors(); assertEquals("Wrong number of interceptors", 1, advisors.length); ChannelSecurityInterceptor interceptor = (ChannelSecurityInterceptor) advisors[0].getAdvice(); ChannelAccessPolicy policy = this.retrievePolicyForPatternString(beanName, interceptor); assertNotNull("Pattern '" + beanName + "' is not included in mappings", policy); Collection<ConfigAttribute> sendDefinition = policy.getConfigAttributesForSend(); Collection<ConfigAttribute> receiveDefinition = policy.getConfigAttributesForReceive(); assertNotNull("Pattern does not apply to 'send'", sendDefinition); assertNotNull("Pattern does not apply to 'receive'", receiveDefinition); Collection<String> sendRoles = this.getRolesFromDefintion(sendDefinition); Collection<String> receiveRoles = this.getRolesFromDefintion(receiveDefinition); assertTrue("ROLE_ADMIN not found in send attributes", sendRoles.contains("ROLE_ADMIN")); assertTrue("ROLE_ADMIN not found in receive attributes", receiveRoles.contains("ROLE_ADMIN")); } @SuppressWarnings("unchecked") private ChannelAccessPolicy retrievePolicyForPatternString(String patternString, ChannelSecurityInterceptor interceptor) { DirectFieldAccessor accessor = new DirectFieldAccessor(interceptor.obtainSecurityMetadataSource()); Map<Pattern, ChannelAccessPolicy> policies = (Map<Pattern, ChannelAccessPolicy>) accessor.getPropertyValue("patternMappings"); for (Map.Entry<Pattern, ChannelAccessPolicy> entry : policies.entrySet()) { if (entry.getKey().pattern().equals(patternString)) { return entry.getValue(); } } return null; } private Collection<String> getRolesFromDefintion(Collection<ConfigAttribute> definition) { Set<String> roles = new HashSet<String>(); //Collection configAttributes = SecurityConfig.createListFromCommaDelimitedString(definition); for (ConfigAttribute nextConfigAttribute : definition) { ConfigAttribute attribute = nextConfigAttribute; roles.add(attribute.getAttribute()); } return roles; } static class TestMessageChannel extends AbstractPollableChannel { List<ChannelInterceptor> interceptors = new ArrayList<ChannelInterceptor>(); @Override protected Message<?> doReceive(long timeout) { return null; } @Override protected boolean doSend(Message<?> message, long timeout) { return false; } public List<Message<?>> clear() { return null; } public List<Message<?>> purge(MessageSelector selector) { return null; } @Override public void addInterceptor(ChannelInterceptor interceptor) { interceptors.add(interceptor); } } }