diff --git a/core/src/main/java/org/springframework/security/intercept/web/FilterInvocationDefinitionSourceEditor.java b/core/src/main/java/org/springframework/security/intercept/web/FilterInvocationDefinitionSourceEditor.java deleted file mode 100644 index 5c19c7f837..0000000000 --- a/core/src/main/java/org/springframework/security/intercept/web/FilterInvocationDefinitionSourceEditor.java +++ /dev/null @@ -1,197 +0,0 @@ -/* 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.intercept.web; - -import java.beans.PropertyEditorSupport; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.LinkedHashMap; - -import org.springframework.security.util.StringSplitUtils; -import org.springframework.security.util.RegexUrlPathMatcher; -import org.springframework.security.util.UrlMatcher; -import org.springframework.security.util.AntUrlPathMatcher; -import org.springframework.security.SecurityConfig; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.util.StringUtils; - - -/** - * Property editor to assist with the setup of a {@link FilterInvocationDefinitionSource}. - *

- * Note that from version 2.0, the use of property-editor based configuration is deprecated in favour of namespace - * configuration options. - *

- * The class creates and populates a - * {@link org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource} - * using either an Ant or Regular Expression URL matching strategy depending on the type of patterns presented. - *

- * By default the class treats presented patterns as regular expressions. If the keyword - * PATTERN_TYPE_APACHE_ANT is present (case sensitive), patterns will be treated as Apache Ant paths - * rather than regular expressions. - * - * @author Ben Alex - * @deprecated Use namespace configuration instead. May be removed in future versions. - * @version $Id$ - */ -public class FilterInvocationDefinitionSourceEditor extends PropertyEditorSupport { - //~ Static fields/initializers ===================================================================================== - - private static final Log logger = LogFactory.getLog(FilterInvocationDefinitionSourceEditor.class); - public static final String DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON = - "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON"; - public static final String DIRECTIVE_PATTERN_TYPE_APACHE_ANT = "PATTERN_TYPE_APACHE_ANT"; - - //~ Methods ======================================================================================================== - - public void setAsText(String s) throws IllegalArgumentException { - if ((s == null) || "".equals(s)) { - // Leave target object empty - setValue(new DefaultFilterInvocationDefinitionSource(new RegexUrlPathMatcher())); - - return; - } - - boolean useAnt = s.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1; - boolean converUrlToLowerCase = s.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1; - - if (logger.isDebugEnabled()) { - if (useAnt) { - logger.debug(("Detected " + DIRECTIVE_PATTERN_TYPE_APACHE_ANT - + " directive; using Apache Ant style path expressions")); - } - - if (converUrlToLowerCase) { - if (logger.isDebugEnabled()) { - logger.debug("Detected " + DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON - + " directive; Instructing mapper to convert URLs to lowercase before comparison"); - } - } - } - - BufferedReader br = new BufferedReader(new StringReader(s)); - int counter = 0; - String line; - - LinkedHashMap urlMap = new LinkedHashMap(); - - while (true) { - counter++; - - try { - line = br.readLine(); - } catch (IOException ioe) { - throw new IllegalArgumentException(ioe.getMessage()); - } - - if (line == null) { - break; - } - - line = line.trim(); - - if (logger.isDebugEnabled()) { - logger.debug("Line " + counter + ": " + line); - } - - if (line.startsWith("//")) { - continue; - } - - // Attempt to detect malformed lines (as per SEC-204) - if (line.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) { - // Directive found; check for second directive or name=value - if ((line.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) || (line.lastIndexOf("=") != -1)) { - throw new IllegalArgumentException("Line appears to be malformed: " + line); - } - } - - // Attempt to detect malformed lines (as per SEC-204) - if (line.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) { - // Directive found; check for second directive or name=value - if ((line.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) - || (line.lastIndexOf("=") != -1)) { - throw new IllegalArgumentException("Line appears to be malformed: " + line); - } - } - - // Skip lines that are not directives - if (line.lastIndexOf('=') == -1) { - continue; - } - - if (line.lastIndexOf("==") != -1) { - throw new IllegalArgumentException("Only single equals should be used in line " + line); - } - - // Tokenize the line into its name/value tokens - // As per SEC-219, use the LAST equals as the delimiter between LHS and RHS - String name = StringSplitUtils.substringBeforeLast(line, "="); - String value = StringSplitUtils.substringAfterLast(line, "="); - - if (!StringUtils.hasText(name) || !StringUtils.hasText(value)) { - throw new IllegalArgumentException("Failed to parse a valid name/value pair from " + line); - } - - // Attempt to detect malformed lines (as per SEC-204) - if (converUrlToLowerCase && useAnt) { - // Should all be lowercase; check each character - // We only do this for Ant (regexp have control chars) - for (int i = 0; i < name.length(); i++) { - String character = name.substring(i, i + 1); - - if (!character.toLowerCase().equals(character)) { - throw new IllegalArgumentException("You are using the " - + DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON - + " with Ant Paths, yet you have specified an uppercase character in line: " + line - + " (character '" + character + "')"); - } - } - } - - String[] tokens = StringUtils.commaDelimitedListToStringArray(value); - - urlMap.put(new RequestKey(name), SecurityConfig.createList(tokens)); - } - - DefaultFilterInvocationDefinitionSource fids = - new DefaultFilterInvocationDefinitionSource(createMatcher(useAnt, converUrlToLowerCase), urlMap); - - if (useAnt) { - fids.setStripQueryStringFromUrls(true); - } - - setValue(fids); - } - - private UrlMatcher createMatcher(boolean useAnt, boolean converUrlToLowerCase) { - UrlMatcher matcher; - - if (useAnt) { - matcher = new AntUrlPathMatcher(); - ((AntUrlPathMatcher)matcher).setRequiresLowerCaseUrl(converUrlToLowerCase); - - } else { - matcher = new RegexUrlPathMatcher(); - ((RegexUrlPathMatcher)matcher).setRequiresLowerCaseUrl(converUrlToLowerCase); - } - - return matcher; - } -} diff --git a/core/src/test/java/org/springframework/security/intercept/web/FilterInvocationDefinitionSourceEditorTests.java b/core/src/test/java/org/springframework/security/intercept/web/FilterInvocationDefinitionSourceEditorTests.java deleted file mode 100644 index 13951a2dcf..0000000000 --- a/core/src/test/java/org/springframework/security/intercept/web/FilterInvocationDefinitionSourceEditorTests.java +++ /dev/null @@ -1,298 +0,0 @@ -/* 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.intercept.web; - -import junit.framework.TestCase; - -import org.springframework.security.ConfigAttribute; -import org.springframework.security.MockFilterChain; -import org.springframework.security.SecurityConfig; -import org.springframework.security.util.RegexUrlPathMatcher; -import org.springframework.security.util.AntUrlPathMatcher; - -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import java.util.Iterator; -import java.util.List; -import java.util.regex.PatternSyntaxException; - - -/** - * Tests {@link FilterInvocationDefinitionSourceEditor} and its associated default - * {@link DefaultFilterInvocationDefinitionSource}. - * - * @author Ben Alex - * @version $Id$ - */ -public class FilterInvocationDefinitionSourceEditorTests extends TestCase { - //~ Constructors =================================================================================================== - - public FilterInvocationDefinitionSourceEditorTests() { - } - - public FilterInvocationDefinitionSourceEditorTests(String arg0) { - super(arg0); - } - - //~ Methods ======================================================================================================== - - public void testConvertUrlToLowercaseDefaultSettingUnchangedByEditor() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - assertFalse(map.isConvertUrlToLowercaseBeforeComparison()); - } - - public void testConvertUrlToLowercaseDetectsUppercaseEntries() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - - try { - editor.setAsText( - "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON\r\nPATTERN_TYPE_APACHE_ANT\r\n\\/secUre/super/**=ROLE_WE_DONT_HAVE"); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(expected.getMessage().lastIndexOf("you have specified an uppercase character in line") != -1); - } - } - - public void testConvertUrlToLowercaseSettingApplied() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON\r\n\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - assertTrue(map.isConvertUrlToLowercaseBeforeComparison()); - } - - public void testDefaultIsRegularExpression() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - assertTrue(map.getUrlMatcher() instanceof RegexUrlPathMatcher); - } - - public void testDetectsDuplicateDirectivesOnSameLineSituation1() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - - try { - editor.setAsText( - "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT\r\n\\/secure/super/**=ROLE_WE_DONT_HAVE"); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(expected.getMessage().lastIndexOf("Line appears to be malformed") != -1); - } - } - - public void testDetectsDuplicateDirectivesOnSameLineSituation2() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - - try { - editor.setAsText( - "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON\r\nPATTERN_TYPE_APACHE_ANT /secure/super/**=ROLE_WE_DONT_HAVE"); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(expected.getMessage().lastIndexOf("Line appears to be malformed") != -1); - } - } - - public void testDetectsDuplicateDirectivesOnSameLineSituation3() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - - try { - editor.setAsText( - "PATTERN_TYPE_APACHE_ANT\r\nCONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON /secure/super/**=ROLE_WE_DONT_HAVE"); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(expected.getMessage().lastIndexOf("Line appears to be malformed") != -1); - } - } - - public void testEmptyStringReturnsEmptyMap() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText(""); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - assertEquals(0, map.getMapSize()); - } - - public void testInvalidRegularExpressionsDetected() throws Exception { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - - try { - editor.setAsText("*=SOME_ROLE"); - fail("Expected PatternSyntaxException"); - } catch (PatternSyntaxException expected) { - } - } - - public void testIterator() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - Iterator iter = map.getAllConfigAttributes().iterator(); - int counter = 0; - - while (iter.hasNext()) { - iter.next(); - counter++; - } - - assertEquals(2, counter); - } - - public void testMapReturnsNullWhenNoMatchFound() throws Exception { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); - httpRequest.setServletPath("/totally/different/path/index.html"); - - List returned = map.getAttributes(new FilterInvocation(httpRequest, - new MockHttpServletResponse(), new MockFilterChain())); - - assertEquals(null, returned); - } - - public void testMultiUrlParsing() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - assertEquals(2, map.getMapSize()); - } - - public void testNullReturnsEmptyMap() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText(null); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - assertEquals(0, map.getMapSize()); - } - - public void testOrderOfEntriesIsPreservedOrderA() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - - // Test ensures we match the first entry, not the second - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); - httpRequest.setServletPath("/secure/super/very_secret.html"); - - List returned = map.getAttributes(new FilterInvocation(httpRequest, - new MockHttpServletResponse(), new MockFilterChain())); - - assertEquals(SecurityConfig.createList("ROLE_WE_DONT_HAVE", "ANOTHER_ROLE"), returned); - } - - public void testOrderOfEntriesIsPreservedOrderB() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER\r\n\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); - httpRequest.setServletPath("/secure/super/very_secret.html"); - - List returned = map.getAttributes(new FilterInvocation(httpRequest, - new MockHttpServletResponse(), new MockFilterChain())); - - assertEquals(SecurityConfig.createList("ROLE_SUPERVISOR", "ROLE_TELLER"), returned); - } - - public void testSingleUrlParsingWithRegularExpressions() throws Exception { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); - httpRequest.setServletPath("/secure/super/very_secret.html"); - - List returned = map.getAttributes(new FilterInvocation(httpRequest, - new MockHttpServletResponse(), new MockFilterChain())); - List expected = SecurityConfig.createList("ROLE_WE_DONT_HAVE", "ANOTHER_ROLE"); - - assertEquals(expected, returned); - } - - public void testSingleUrlParsingWithAntPaths() throws Exception { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText("PATTERN_TYPE_APACHE_ANT\r\n/secure/super/**=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); - httpRequest.setServletPath("/secure/super/very_secret.html"); - - List returned = map.getAttributes(new FilterInvocation(httpRequest, - new MockHttpServletResponse(), new MockFilterChain())); - - assertEquals(SecurityConfig.createList("ROLE_WE_DONT_HAVE", "ANOTHER_ROLE"), returned); - } - - public void testWhitespaceAndCommentsAndLinesWithoutEqualsSignsAreIgnored() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - " \\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE \r\n \r\n \r\n // comment line \r\n \\A/testing.*\\Z=ROLE_TEST \r\n"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - assertEquals(2, map.getMapSize()); - } - - public void testAntPathDirectiveIsDetected() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - assertTrue(map.getUrlMatcher() instanceof AntUrlPathMatcher); - } - - public void testInvalidNameValueFailsToParse() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - - try { - // Use a "==" instead of an "=" - editor.setAsText(" PATTERN_TYPE_APACHE_ANT\r\n /secure/*==ROLE_SUPERVISOR,ROLE_TELLER \r\n"); - fail("Shouldn't be able to use '==' for config attribute."); - } catch (IllegalArgumentException expected) {} - } - - public void testSingleUrlParsing() throws Exception { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText("PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - - DefaultFilterInvocationDefinitionSource map = (DefaultFilterInvocationDefinitionSource) editor.getValue(); - - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); - httpRequest.setServletPath("/secure/super/very_secret.html"); - - List returned = map.getAttributes(new FilterInvocation(httpRequest, - new MockHttpServletResponse(), new MockFilterChain())); - List expected = SecurityConfig.createList("ROLE_WE_DONT_HAVE", "ANOTHER_ROLE"); - - assertEquals(expected, returned); - } -}