1   /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.intercept.web;
17  
18  import junit.framework.TestCase;
19  
20  import org.acegisecurity.ConfigAttributeDefinition;
21  import org.acegisecurity.MockFilterChain;
22  import org.acegisecurity.SecurityConfig;
23  
24  import org.springframework.mock.web.MockHttpServletRequest;
25  import org.springframework.mock.web.MockHttpServletResponse;
26  
27  import java.util.Iterator;
28  
29  
30  /**
31   * Tests {@link FilterInvocationDefinitionSourceEditor} and its associated {@link
32   * PathBasedFilterInvocationDefinitionMap}.
33   *
34   * @author Ben Alex
35   * @version $Id: FilterInvocationDefinitionSourceEditorWithPathsTests.java 1496 2006-05-23 13:38:33Z benalex $
36   */
37  public class FilterInvocationDefinitionSourceEditorWithPathsTests extends TestCase {
38      //~ Constructors ===================================================================================================
39  
40      public FilterInvocationDefinitionSourceEditorWithPathsTests() {
41          super();
42      }
43  
44      public FilterInvocationDefinitionSourceEditorWithPathsTests(String arg0) {
45          super(arg0);
46      }
47  
48      //~ Methods ========================================================================================================
49  
50      public static void main(String[] args) {
51          junit.textui.TestRunner.run(FilterInvocationDefinitionSourceEditorWithPathsTests.class);
52      }
53  
54      public final void setUp() throws Exception {
55          super.setUp();
56      }
57  
58      public void testAntPathDirectiveIsDetected() {
59          FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
60          editor.setAsText(
61              "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER");
62  
63          FilterInvocationDefinitionMap map = (FilterInvocationDefinitionMap) editor.getValue();
64          assertTrue(map instanceof PathBasedFilterInvocationDefinitionMap);
65      }
66  
67      public void testConvertUrlToLowercaseDefaultSettingUnchangedByEditor() {
68          FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
69          editor.setAsText(
70              "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER");
71  
72          PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
73          assertFalse(map.isConvertUrlToLowercaseBeforeComparison());
74      }
75  
76      public void testConvertUrlToLowercaseSettingApplied() {
77          FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
78          editor.setAsText(
79              "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON\r\nPATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER");
80  
81          PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
82          assertTrue(map.isConvertUrlToLowercaseBeforeComparison());
83      }
84  
85      public void testInvalidNameValueFailsToParse() {
86          FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
87  
88          try {
89              // Use a "==" instead of an "="
90              editor.setAsText("         PATTERN_TYPE_APACHE_ANT\r\n    /secure/*==ROLE_SUPERVISOR,ROLE_TELLER      \r\n");
91              fail("Shouldn't be able to use '==' for config attribute.");
92          } catch (IllegalArgumentException expected) {}
93      }
94  
95      public void testIterator() {
96          FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
97          editor.setAsText(
98              "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER");
99  
100         PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
101         Iterator iter = map.getConfigAttributeDefinitions();
102         int counter = 0;
103 
104         while (iter.hasNext()) {
105             iter.next();
106             counter++;
107         }
108 
109         assertEquals(2, counter);
110     }
111 
112     public void testMapReturnsNullWhenNoMatchFound() throws Exception {
113         FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
114         editor.setAsText("PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE");
115 
116         PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
117 
118         MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null);
119         httpRequest.setServletPath("/totally/different/path/index.html");
120 
121         ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest,
122                     new MockHttpServletResponse(), new MockFilterChain()));
123 
124         assertEquals(null, returned);
125     }
126 
127     public void testMultiUrlParsing() {
128         FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
129         editor.setAsText(
130             "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER");
131 
132         PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
133         assertEquals(2, map.getMapSize());
134     }
135 
136     public void testNoArgConstructorDoesntExist() {
137         Class clazz = PathBasedFilterInvocationDefinitionMap.EntryHolder.class;
138 
139         try {
140             clazz.getDeclaredConstructor((Class[]) null);
141             fail("Should have thrown NoSuchMethodException");
142         } catch (NoSuchMethodException expected) {
143             assertTrue(true);
144         }
145     }
146 
147     public void testOrderOfEntriesIsPreservedOrderA() {
148         FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
149         editor.setAsText(
150             "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/**=ROLE_WE_DONT_HAVE,ANOTHER_ROLE\r\n/secure/**=ROLE_SUPERVISOR,ROLE_TELLER");
151 
152         PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
153 
154         // Test ensures we match the first entry, not the second
155         MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null);
156         httpRequest.setServletPath("/secure/super/very_secret.html");
157 
158         ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest,
159                     new MockHttpServletResponse(), new MockFilterChain()));
160 
161         ConfigAttributeDefinition expected = new ConfigAttributeDefinition();
162         expected.addConfigAttribute(new SecurityConfig("ROLE_WE_DONT_HAVE"));
163         expected.addConfigAttribute(new SecurityConfig("ANOTHER_ROLE"));
164 
165         assertEquals(expected, returned);
166     }
167 
168     public void testOrderOfEntriesIsPreservedOrderB() {
169         FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
170         editor.setAsText(
171             "PATTERN_TYPE_APACHE_ANT\r\n/secure/**=ROLE_SUPERVISOR,ROLE_TELLER\r\n/secure/super/**=ROLE_WE_DONT_HAVE");
172 
173         PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
174 
175         MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null);
176         httpRequest.setServletPath("/secure/super/very_secret.html");
177 
178         ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest,
179                     new MockHttpServletResponse(), new MockFilterChain()));
180 
181         ConfigAttributeDefinition expected = new ConfigAttributeDefinition();
182         expected.addConfigAttribute(new SecurityConfig("ROLE_SUPERVISOR"));
183         expected.addConfigAttribute(new SecurityConfig("ROLE_TELLER"));
184 
185         assertEquals(expected, returned);
186     }
187 
188     public void testSingleUrlParsing() throws Exception {
189         FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
190         editor.setAsText("PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE,ANOTHER_ROLE");
191 
192         PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
193 
194         MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null);
195         httpRequest.setServletPath("/secure/super/very_secret.html");
196 
197         ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest,
198                     new MockHttpServletResponse(), new MockFilterChain()));
199 
200         ConfigAttributeDefinition expected = new ConfigAttributeDefinition();
201         expected.addConfigAttribute(new SecurityConfig("ROLE_WE_DONT_HAVE"));
202         expected.addConfigAttribute(new SecurityConfig("ANOTHER_ROLE"));
203 
204         assertEquals(expected, returned);
205     }
206 
207     public void testWhitespaceAndCommentsAndLinesWithoutEqualsSignsAreIgnored() {
208         FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor();
209         editor.setAsText(
210             "         PATTERN_TYPE_APACHE_ANT\r\n    /secure/super/*=ROLE_WE_DONT_HAVE\r\n    /secure/*=ROLE_SUPERVISOR,ROLE_TELLER      \r\n   \r\n     \r\n   // comment line  \r\n    \r\n");
211 
212         PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue();
213         assertEquals(2, map.getMapSize());
214     }
215 }