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.providers.anonymous;
17  
18  import junit.framework.TestCase;
19  
20  import org.acegisecurity.Authentication;
21  import org.acegisecurity.GrantedAuthority;
22  import org.acegisecurity.GrantedAuthorityImpl;
23  import org.acegisecurity.MockFilterConfig;
24  
25  import org.acegisecurity.context.SecurityContextHolder;
26  
27  import org.acegisecurity.providers.TestingAuthenticationToken;
28  
29  import org.acegisecurity.userdetails.memory.UserAttribute;
30  
31  import org.springframework.mock.web.MockHttpServletRequest;
32  import org.springframework.mock.web.MockHttpServletResponse;
33  
34  import java.io.IOException;
35  
36  import javax.servlet.Filter;
37  import javax.servlet.FilterChain;
38  import javax.servlet.FilterConfig;
39  import javax.servlet.ServletException;
40  import javax.servlet.ServletRequest;
41  import javax.servlet.ServletResponse;
42  
43  
44  /**
45   * Tests {@link AnonymousProcessingFilter}.
46   *
47   * @author Ben Alex
48   * @version $Id: AnonymousProcessingFilterTests.java 1496 2006-05-23 13:38:33Z benalex $
49   */
50  public class AnonymousProcessingFilterTests extends TestCase {
51      //~ Constructors ===================================================================================================
52  
53      public AnonymousProcessingFilterTests() {
54          super();
55      }
56  
57      public AnonymousProcessingFilterTests(String arg0) {
58          super(arg0);
59      }
60  
61      //~ Methods ========================================================================================================
62  
63      private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request,
64          ServletResponse response, FilterChain filterChain)
65          throws ServletException, IOException {
66          filter.init(filterConfig);
67          filter.doFilter(request, response, filterChain);
68          filter.destroy();
69      }
70  
71      public static void main(String[] args) {
72          junit.textui.TestRunner.run(AnonymousProcessingFilterTests.class);
73      }
74  
75      protected void setUp() throws Exception {
76          super.setUp();
77          SecurityContextHolder.clearContext();
78      }
79  
80      protected void tearDown() throws Exception {
81          super.tearDown();
82          SecurityContextHolder.clearContext();
83      }
84  
85      public void testDetectsMissingKey() throws Exception {
86          UserAttribute user = new UserAttribute();
87          user.setPassword("anonymousUsername");
88          user.addAuthority(new GrantedAuthorityImpl("ROLE_ANONYMOUS"));
89  
90          AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
91          filter.setUserAttribute(user);
92  
93          try {
94              filter.afterPropertiesSet();
95              fail("Should have thrown IllegalArgumentException");
96          } catch (IllegalArgumentException expected) {
97              assertTrue(true);
98          }
99      }
100 
101     public void testDetectsUserAttribute() throws Exception {
102         AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
103         filter.setKey("qwerty");
104 
105         try {
106             filter.afterPropertiesSet();
107             fail("Should have thrown IllegalArgumentException");
108         } catch (IllegalArgumentException expected) {
109             assertTrue(true);
110         }
111     }
112 
113     public void testGettersSetters() throws Exception {
114         UserAttribute user = new UserAttribute();
115         user.setPassword("anonymousUsername");
116         user.addAuthority(new GrantedAuthorityImpl("ROLE_ANONYMOUS"));
117 
118         AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
119         filter.setKey("qwerty");
120         filter.setUserAttribute(user);
121         assertTrue(filter.isRemoveAfterRequest());
122         filter.afterPropertiesSet();
123 
124         assertEquals("qwerty", filter.getKey());
125         assertEquals(user, filter.getUserAttribute());
126         filter.setRemoveAfterRequest(false);
127         assertFalse(filter.isRemoveAfterRequest());
128     }
129 
130     public void testOperationWhenAuthenticationExistsInContextHolder()
131         throws Exception {
132         // Put an Authentication object into the SecurityContextHolder
133         Authentication originalAuth = new TestingAuthenticationToken("user", "password",
134                 new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")});
135         SecurityContextHolder.getContext().setAuthentication(originalAuth);
136 
137         // Setup our filter correctly
138         UserAttribute user = new UserAttribute();
139         user.setPassword("anonymousUsername");
140         user.addAuthority(new GrantedAuthorityImpl("ROLE_ANONYMOUS"));
141 
142         AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
143         filter.setKey("qwerty");
144         filter.setUserAttribute(user);
145         filter.afterPropertiesSet();
146 
147         // Test
148         MockHttpServletRequest request = new MockHttpServletRequest();
149         request.setRequestURI("x");
150         executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
151             new MockFilterChain(true));
152 
153         // Ensure filter didn't change our original object
154         assertEquals(originalAuth, SecurityContextHolder.getContext().getAuthentication());
155     }
156 
157     public void testOperationWhenNoAuthenticationInSecurityContextHolder()
158         throws Exception {
159         UserAttribute user = new UserAttribute();
160         user.setPassword("anonymousUsername");
161         user.addAuthority(new GrantedAuthorityImpl("ROLE_ANONYMOUS"));
162 
163         AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
164         filter.setKey("qwerty");
165         filter.setUserAttribute(user);
166         filter.setRemoveAfterRequest(false); // set to non-default value
167         filter.afterPropertiesSet();
168 
169         MockHttpServletRequest request = new MockHttpServletRequest();
170         request.setRequestURI("x");
171         executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
172             new MockFilterChain(true));
173 
174         Authentication auth = SecurityContextHolder.getContext().getAuthentication();
175         assertEquals("anonymousUsername", auth.getPrincipal());
176         assertEquals(new GrantedAuthorityImpl("ROLE_ANONYMOUS"), auth.getAuthorities()[0]);
177         SecurityContextHolder.getContext().setAuthentication(null); // so anonymous fires again
178 
179         // Now test operation if we have removeAfterRequest = true
180         filter.setRemoveAfterRequest(true); // set to default value
181         executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
182             new MockFilterChain(true));
183         assertNull(SecurityContextHolder.getContext().getAuthentication());
184     }
185 
186     //~ Inner Classes ==================================================================================================
187 
188     private class MockFilterChain implements FilterChain {
189         private boolean expectToProceed;
190 
191         public MockFilterChain(boolean expectToProceed) {
192             this.expectToProceed = expectToProceed;
193         }
194 
195         private MockFilterChain() {
196             super();
197         }
198 
199         public void doFilter(ServletRequest request, ServletResponse response)
200             throws IOException, ServletException {
201             if (expectToProceed) {
202                 assertTrue(true);
203             } else {
204                 fail("Did not expect filter chain to proceed");
205             }
206         }
207     }
208 }