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