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  
16  package org.acegisecurity.ui.rememberme;
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  import org.acegisecurity.context.SecurityContextHolder;
25  import org.acegisecurity.context.SecurityContextImpl;
26  import org.acegisecurity.providers.TestingAuthenticationToken;
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  import javax.servlet.http.HttpServletRequest;
40  import javax.servlet.http.HttpServletResponse;
41  
42  
43  /***
44   * Tests {@link RememberMeProcessingFilter}.
45   *
46   * @author Ben Alex
47   * @version $Id: RememberMeProcessingFilterTests.java,v 1.7 2005/11/17 00:56:09 benalex Exp $
48   */
49  public class RememberMeProcessingFilterTests extends TestCase {
50      //~ Constructors ===========================================================
51  
52      public RememberMeProcessingFilterTests() {
53          super();
54      }
55  
56      public RememberMeProcessingFilterTests(String arg0) {
57          super(arg0);
58      }
59  
60      //~ Methods ================================================================
61  
62      public static void main(String[] args) {
63          junit.textui.TestRunner.run(RememberMeProcessingFilterTests.class);
64      }
65  
66      public void testDetectsRememberMeServicesProperty()
67          throws Exception {
68          RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
69  
70          // check default is NullRememberMeServices
71          assertEquals(NullRememberMeServices.class,
72              filter.getRememberMeServices().getClass());
73  
74          // check getter/setter
75          filter.setRememberMeServices(new TokenBasedRememberMeServices());
76          assertEquals(TokenBasedRememberMeServices.class,
77              filter.getRememberMeServices().getClass());
78  
79          // check detects if made null
80          filter.setRememberMeServices(null);
81  
82          try {
83              filter.afterPropertiesSet();
84              fail("Should have thrown IllegalArgumentException");
85          } catch (IllegalArgumentException expected) {
86              assertTrue(true);
87          }
88      }
89  
90      public void testDoFilterWithNonHttpServletRequestDetected()
91          throws Exception {
92          RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
93  
94          try {
95              filter.doFilter(null, new MockHttpServletResponse(),
96                  new MockFilterChain());
97              fail("Should have thrown ServletException");
98          } catch (ServletException expected) {
99              assertEquals("Can only process HttpServletRequest",
100                 expected.getMessage());
101         }
102     }
103 
104     public void testDoFilterWithNonHttpServletResponseDetected()
105         throws Exception {
106         RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
107 
108         try {
109             MockHttpServletRequest request = new MockHttpServletRequest();
110             request.setRequestURI("dc");
111             filter.doFilter(request, null, new MockFilterChain());
112             fail("Should have thrown ServletException");
113         } catch (ServletException expected) {
114             assertEquals("Can only process HttpServletResponse",
115                 expected.getMessage());
116         }
117     }
118 
119     public void testOperationWhenAuthenticationExistsInContextHolder()
120         throws Exception {
121         // Put an Authentication object into the SecurityContextHolder
122         Authentication originalAuth = new TestingAuthenticationToken("user",
123                 "password",
124                 new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")});
125         SecurityContextHolder.getContext().setAuthentication(originalAuth);
126 
127         // Setup our filter correctly
128         Authentication remembered = new TestingAuthenticationToken("remembered",
129                 "password",
130                 new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_REMEMBERED")});
131         RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
132         filter.setRememberMeServices(new MockRememberMeServices(remembered));
133         filter.afterPropertiesSet();
134 
135         // Test
136         MockHttpServletRequest request = new MockHttpServletRequest();
137         request.setRequestURI("x");
138         executeFilterInContainerSimulator(new MockFilterConfig(), filter,
139             request, new MockHttpServletResponse(), new MockFilterChain(true));
140 
141         // Ensure filter didn't change our original object
142         assertEquals(originalAuth,
143             SecurityContextHolder.getContext().getAuthentication());
144     }
145 
146     public void testOperationWhenNoAuthenticationInContextHolder()
147         throws Exception {
148         Authentication remembered = new TestingAuthenticationToken("remembered",
149                 "password",
150                 new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_REMEMBERED")});
151         RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
152         filter.setRememberMeServices(new MockRememberMeServices(remembered));
153         filter.afterPropertiesSet();
154 
155         MockHttpServletRequest request = new MockHttpServletRequest();
156         request.setRequestURI("x");
157         executeFilterInContainerSimulator(new MockFilterConfig(), filter,
158             request, new MockHttpServletResponse(), new MockFilterChain(true));
159 
160         // Ensure filter setup with our remembered authentication object
161         assertEquals(remembered,
162             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     //~ Inner Classes ==========================================================
184 
185     private class MockFilterChain implements FilterChain {
186         private boolean expectToProceed;
187 
188         public MockFilterChain(boolean expectToProceed) {
189             this.expectToProceed = expectToProceed;
190         }
191 
192         private MockFilterChain() {
193             super();
194         }
195 
196         public void doFilter(ServletRequest request, ServletResponse response)
197             throws IOException, ServletException {
198             if (expectToProceed) {
199                 assertTrue(true);
200             } else {
201                 fail("Did not expect filter chain to proceed");
202             }
203         }
204     }
205 
206     private class MockRememberMeServices implements RememberMeServices {
207         private Authentication authToReturn;
208 
209         public MockRememberMeServices(Authentication authToReturn) {
210             this.authToReturn = authToReturn;
211         }
212 
213         public Authentication autoLogin(HttpServletRequest request,
214             HttpServletResponse response) {
215             return authToReturn;
216         }
217 
218         public void loginFail(HttpServletRequest request,
219             HttpServletResponse response) {}
220 
221         public void loginSuccess(HttpServletRequest request,
222             HttpServletResponse response,
223             Authentication successfulAuthentication) {}
224     }
225 }