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.concurrent;
17  
18  import junit.framework.TestCase;
19  
20  import org.springframework.mock.web.MockFilterConfig;
21  import org.springframework.mock.web.MockHttpServletRequest;
22  import org.springframework.mock.web.MockHttpServletResponse;
23  import org.springframework.mock.web.MockHttpSession;
24  
25  import java.io.IOException;
26  
27  import java.util.Date;
28  
29  import javax.servlet.Filter;
30  import javax.servlet.FilterChain;
31  import javax.servlet.FilterConfig;
32  import javax.servlet.ServletException;
33  import javax.servlet.ServletRequest;
34  import javax.servlet.ServletResponse;
35  
36  
37  /***
38   * Tests {@link ConcurrentSessionFilter}.
39   *
40   * @author Ben Alex
41   * @version $Id: ConcurrentSessionFilterTests.java,v 1.2 2005/11/17 00:55:48 benalex Exp $
42   */
43  public class ConcurrentSessionFilterTests extends TestCase {
44      //~ Constructors ===========================================================
45  
46      public ConcurrentSessionFilterTests() {
47          super();
48      }
49  
50      public ConcurrentSessionFilterTests(String arg0) {
51          super(arg0);
52      }
53  
54      //~ Methods ================================================================
55  
56      public static void main(String[] args) {
57          junit.textui.TestRunner.run(ConcurrentSessionFilterTests.class);
58      }
59  
60      public void testDetectsExpiredSessions() throws Exception {
61          // Setup our HTTP request
62          MockHttpServletRequest request = new MockHttpServletRequest();
63          MockHttpSession session = new MockHttpSession();
64          request.setSession(session);
65  
66          MockHttpServletResponse response = new MockHttpServletResponse();
67          MockFilterConfig config = new MockFilterConfig(null);
68  
69          // Setup our expectation that the filter chain will not be invoked, as we redirect to expiredUrl
70          MockFilterChain chain = new MockFilterChain(false);
71  
72          // Setup our test fixture and registry to want this session to be expired
73          ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
74          SessionRegistry registry = new SessionRegistryImpl();
75          registry.registerNewSession(session.getId(), "principal");
76          registry.getSessionInformation(session.getId()).expireNow();
77          filter.setSessionRegistry(registry);
78          filter.setExpiredUrl("/expired.jsp");
79  
80          // Test
81          executeFilterInContainerSimulator(config, filter, request, response,
82              chain);
83  
84          assertEquals("/expired.jsp", response.getRedirectedUrl());
85      }
86  
87      public void testDetectsMissingExpiredUrl() throws Exception {
88          ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
89          filter.setSessionRegistry(new SessionRegistryImpl());
90  
91          try {
92              filter.afterPropertiesSet();
93              fail("Should have thrown IAE");
94          } catch (IllegalArgumentException expected) {
95              assertTrue(true);
96          }
97      }
98  
99      public void testDetectsMissingSessionRegistry() throws Exception {
100         ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
101         filter.setExpiredUrl("xcx");
102 
103         try {
104             filter.afterPropertiesSet();
105             fail("Should have thrown IAE");
106         } catch (IllegalArgumentException expected) {
107             assertTrue(true);
108         }
109     }
110 
111     public void testUpdatesLastRequestTime() throws Exception {
112         // Setup our HTTP request
113         MockHttpServletRequest request = new MockHttpServletRequest();
114         MockHttpSession session = new MockHttpSession();
115         request.setSession(session);
116 
117         MockHttpServletResponse response = new MockHttpServletResponse();
118         MockFilterConfig config = new MockFilterConfig(null);
119 
120         // Setup our expectation that the filter chain will be invoked, as our session hasn't expired
121         MockFilterChain chain = new MockFilterChain(true);
122 
123         // Setup our test fixture
124         ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
125         SessionRegistry registry = new SessionRegistryImpl();
126         registry.registerNewSession(session.getId(), "principal");
127 
128         Date lastRequest = registry.getSessionInformation(session.getId())
129                                    .getLastRequest();
130         filter.setSessionRegistry(registry);
131         filter.setExpiredUrl("/expired.jsp");
132 
133         Thread.sleep(1000);
134 
135         // Test
136         executeFilterInContainerSimulator(config, filter, request, response,
137             chain);
138 
139         assertTrue(registry.getSessionInformation(session.getId())
140                            .getLastRequest().after(lastRequest));
141     }
142 
143     private void executeFilterInContainerSimulator(FilterConfig filterConfig,
144         Filter filter, ServletRequest request, ServletResponse response,
145         FilterChain filterChain) throws ServletException, IOException {
146         filter.init(filterConfig);
147         filter.doFilter(request, response, filterChain);
148         filter.destroy();
149     }
150 
151     //~ Inner Classes ==========================================================
152 
153     private class MockFilterChain implements FilterChain {
154         private boolean expectToProceed;
155 
156         public MockFilterChain(boolean expectToProceed) {
157             this.expectToProceed = expectToProceed;
158         }
159 
160         private MockFilterChain() {
161             super();
162         }
163 
164         public void doFilter(ServletRequest request, ServletResponse response)
165             throws IOException, ServletException {
166             if (expectToProceed) {
167                 assertTrue(true);
168             } else {
169                 fail("Did not expect filter chain to proceed");
170             }
171         }
172     }
173 }