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.captcha;
17  
18  import junit.framework.TestCase;
19  
20  import org.acegisecurity.MockPortResolver;
21  
22  import org.acegisecurity.util.PortMapperImpl;
23  
24  import org.springframework.mock.web.MockHttpServletRequest;
25  import org.springframework.mock.web.MockHttpServletResponse;
26  
27  import java.net.URLEncoder;
28  
29  import java.util.HashMap;
30  import java.util.Map;
31  
32  
33  /**
34   * Tests {@link CaptchaEntryPoint}.
35   *
36   * @author marc antoine Garrigue
37   * @version $Id: CaptchaEntryPointTests.java 1496 2006-05-23 13:38:33Z benalex $
38   */
39  public class CaptchaEntryPointTests extends TestCase {
40      //~ Methods ========================================================================================================
41  
42      public static void main(String[] args) {
43          junit.textui.TestRunner.run(CaptchaEntryPointTests.class);
44      }
45  
46      // ~ Methods
47      // ================================================================
48      public final void setUp() throws Exception {
49          super.setUp();
50      }
51  
52      public void testDetectsMissingCaptchaFormUrl() throws Exception {
53          CaptchaEntryPoint ep = new CaptchaEntryPoint();
54          ep.setPortMapper(new PortMapperImpl());
55          ep.setPortResolver(new MockPortResolver(80, 443));
56  
57          try {
58              ep.afterPropertiesSet();
59              fail("Should have thrown IllegalArgumentException");
60          } catch (IllegalArgumentException expected) {
61              assertEquals("captchaFormUrl must be specified", expected.getMessage());
62          }
63      }
64  
65      public void testDetectsMissingPortMapper() throws Exception {
66          CaptchaEntryPoint ep = new CaptchaEntryPoint();
67          ep.setCaptchaFormUrl("xxx");
68          ep.setPortMapper(null);
69  
70          try {
71              ep.afterPropertiesSet();
72              fail("Should have thrown IllegalArgumentException");
73          } catch (IllegalArgumentException expected) {
74              assertEquals("portMapper must be specified", expected.getMessage());
75          }
76      }
77  
78      public void testDetectsMissingPortResolver() throws Exception {
79          CaptchaEntryPoint ep = new CaptchaEntryPoint();
80          ep.setCaptchaFormUrl("xxx");
81          ep.setPortResolver(null);
82  
83          try {
84              ep.afterPropertiesSet();
85              fail("Should have thrown IllegalArgumentException");
86          } catch (IllegalArgumentException expected) {
87              assertEquals("portResolver must be specified", expected.getMessage());
88          }
89      }
90  
91      public void testGettersSetters() {
92          CaptchaEntryPoint ep = new CaptchaEntryPoint();
93          ep.setCaptchaFormUrl("/hello");
94          ep.setPortMapper(new PortMapperImpl());
95          ep.setPortResolver(new MockPortResolver(8080, 8443));
96          assertEquals("/hello", ep.getCaptchaFormUrl());
97          assertTrue(ep.getPortMapper() != null);
98          assertTrue(ep.getPortResolver() != null);
99  
100         assertEquals("original_requestUrl", ep.getOriginalRequestUrlParameterName());
101         ep.setOriginalRequestUrlParameterName("Z");
102         assertEquals("Z", ep.getOriginalRequestUrlParameterName());
103 
104         assertEquals(true, ep.isIncludeOriginalRequest());
105         ep.setIncludeOriginalRequest(false);
106         assertEquals(false, ep.isIncludeOriginalRequest());
107 
108         assertEquals(false, ep.isOutsideWebApp());
109         ep.setOutsideWebApp(true);
110         assertEquals(true, ep.isOutsideWebApp());
111 
112         ep.setForceHttps(false);
113         assertFalse(ep.getForceHttps());
114         ep.setForceHttps(true);
115         assertTrue(ep.getForceHttps());
116     }
117 
118     public void testHttpsOperationFromOriginalHttpUrl()
119         throws Exception {
120         MockHttpServletRequest request = new MockHttpServletRequest();
121 
122         request.setRequestURI("/some_path");
123         request.setScheme("http");
124         request.setServerName("www.example.com");
125         request.setContextPath("/bigWebApp");
126         request.setServerPort(80);
127 
128         MockHttpServletResponse response = new MockHttpServletResponse();
129 
130         CaptchaEntryPoint ep = new CaptchaEntryPoint();
131         ep.setIncludeOriginalRequest(false);
132         ep.setCaptchaFormUrl("/hello");
133         ep.setPortMapper(new PortMapperImpl());
134         ep.setForceHttps(true);
135         ep.setPortMapper(new PortMapperImpl());
136         ep.setPortResolver(new MockPortResolver(80, 443));
137         ep.afterPropertiesSet();
138 
139         ep.commence(request, response);
140         assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
141 
142         request.setServerPort(8080);
143         response = new MockHttpServletResponse();
144         ep.setPortResolver(new MockPortResolver(8080, 8443));
145         ep.commence(request, response);
146         assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
147 
148         // Now test an unusual custom HTTP:HTTPS is handled properly
149         request.setServerPort(8888);
150         response = new MockHttpServletResponse();
151         ep.commence(request, response);
152         assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
153 
154         PortMapperImpl portMapper = new PortMapperImpl();
155         Map map = new HashMap();
156         map.put("8888", "9999");
157         portMapper.setPortMappings(map);
158         response = new MockHttpServletResponse();
159 
160         ep = new CaptchaEntryPoint();
161         ep.setCaptchaFormUrl("/hello");
162         ep.setPortMapper(new PortMapperImpl());
163         ep.setForceHttps(true);
164         ep.setPortMapper(portMapper);
165         ep.setPortResolver(new MockPortResolver(8888, 9999));
166         ep.setIncludeOriginalRequest(false);
167 
168         ep.afterPropertiesSet();
169 
170         ep.commence(request, response);
171         assertEquals("https://www.example.com:9999/bigWebApp/hello", response.getRedirectedUrl());
172     }
173 
174     public void testHttpsOperationFromOriginalHttpsUrl()
175         throws Exception {
176         MockHttpServletRequest request = new MockHttpServletRequest();
177 
178         request.setRequestURI("/some_path");
179         request.setScheme("https");
180         request.setServerName("www.example.com");
181         request.setContextPath("/bigWebApp");
182         request.setServerPort(443);
183 
184         MockHttpServletResponse response = new MockHttpServletResponse();
185 
186         CaptchaEntryPoint ep = new CaptchaEntryPoint();
187         ep.setIncludeOriginalRequest(false);
188         ep.setCaptchaFormUrl("/hello");
189         ep.setPortMapper(new PortMapperImpl());
190         ep.setForceHttps(true);
191         ep.setPortMapper(new PortMapperImpl());
192         ep.setPortResolver(new MockPortResolver(80, 443));
193         ep.afterPropertiesSet();
194 
195         ep.commence(request, response);
196         assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
197 
198         request.setServerPort(8443);
199         response = new MockHttpServletResponse();
200         ep.setPortResolver(new MockPortResolver(8080, 8443));
201         ep.commence(request, response);
202         assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
203     }
204 
205     public void testNormalOperation() throws Exception {
206         CaptchaEntryPoint ep = new CaptchaEntryPoint();
207         ep.setCaptchaFormUrl("/hello");
208         ep.setPortMapper(new PortMapperImpl());
209         ep.setPortResolver(new MockPortResolver(80, 443));
210         ep.afterPropertiesSet();
211         ep.setIncludeOriginalRequest(false);
212 
213         MockHttpServletRequest request = new MockHttpServletRequest();
214         request.setRequestURI("/some_path");
215         request.setContextPath("/bigWebApp");
216         request.setScheme("http");
217         request.setServerName("www.example.com");
218         request.setContextPath("/bigWebApp");
219         request.setServerPort(80);
220 
221         MockHttpServletResponse response = new MockHttpServletResponse();
222 
223         ep.afterPropertiesSet();
224         ep.commence(request, response);
225         assertEquals("http://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
226     }
227 
228     public void testOperationWhenHttpsRequestsButHttpsPortUnknown()
229         throws Exception {
230         CaptchaEntryPoint ep = new CaptchaEntryPoint();
231         ep.setCaptchaFormUrl("/hello");
232         ep.setPortMapper(new PortMapperImpl());
233         ep.setPortResolver(new MockPortResolver(8888, 1234));
234         ep.setForceHttps(true);
235         ep.setIncludeOriginalRequest(false);
236 
237         ep.afterPropertiesSet();
238 
239         MockHttpServletRequest request = new MockHttpServletRequest();
240         request.setRequestURI("/some_path");
241         request.setContextPath("/bigWebApp");
242         request.setScheme("http");
243         request.setServerName("www.example.com");
244         request.setContextPath("/bigWebApp");
245         request.setServerPort(8888); // NB: Port we can't resolve
246 
247         MockHttpServletResponse response = new MockHttpServletResponse();
248 
249         ep.afterPropertiesSet();
250         ep.commence(request, response);
251 
252         // Response doesn't switch to HTTPS, as we didn't know HTTP port 8888 to
253         // HTTP port mapping
254         assertEquals("http://www.example.com:8888/bigWebApp/hello", response.getRedirectedUrl());
255     }
256 
257     public void testOperationWithOriginalRequestIncludes()
258         throws Exception {
259         CaptchaEntryPoint ep = new CaptchaEntryPoint();
260         ep.setCaptchaFormUrl("/hello");
261 
262         PortMapperImpl mapper = new PortMapperImpl();
263         mapper.getTranslatedPortMappings().put(new Integer(8888), new Integer(1234));
264         ep.setPortMapper(mapper);
265 
266         ep.setPortResolver(new MockPortResolver(8888, 1234));
267         ep.setIncludeOriginalRequest(true);
268         ep.afterPropertiesSet();
269 
270         MockHttpServletRequest request = new MockHttpServletRequest();
271         request.setMethod("post");
272         request.setRequestURI("/some_path");
273         request.setScheme("http");
274         request.setServerName("www.example.com");
275 
276         // request.setContextPath("/bigWebApp");
277         // TODO correct this when the getRequestUrl from mock works...
278         request.setServerPort(8888); // NB: Port we can't resolve
279 
280         MockHttpServletResponse response = new MockHttpServletResponse();
281 
282         ep.afterPropertiesSet();
283         ep.commence(request, response);
284         assertEquals("http://www.example.com:8888/hello?original_requestUrl="
285             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post",
286             response.getRedirectedUrl());
287 
288         // test the query params
289         request.addParameter("name", "value");
290         response = new MockHttpServletResponse();
291         ep.commence(request, response);
292         assertEquals("http://www.example.com:8888/hello?original_requestUrl="
293             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post",
294             response.getRedirectedUrl());
295 
296         // test the multiple query params
297         ep.setIncludeOriginalParameters(true);
298 
299         request.addParameter("name", "value");
300         request.addParameter("name1", "value2");
301         response = new MockHttpServletResponse();
302         ep.commence(request, response);
303         assertEquals("http://www.example.com:8888/hello?original_requestUrl="
304             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post"
305             + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"),
306             response.getRedirectedUrl());
307 
308         // test add parameter to captcha form url??
309         ep.setCaptchaFormUrl("/hello?toto=titi");
310         response = new MockHttpServletResponse();
311         ep.commence(request, response);
312         assertEquals("http://www.example.com:8888/hello?toto=titi&original_requestUrl="
313             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post"
314             + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"),
315             response.getRedirectedUrl());
316 
317         // with forcing!!!
318         ep.setForceHttps(true);
319         response = new MockHttpServletResponse();
320         ep.commence(request, response);
321         assertEquals("https://www.example.com:1234/hello?toto=titi&original_requestUrl="
322             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post"
323             + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"),
324             response.getRedirectedUrl());
325     }
326 
327     public void testOperationWithOutsideWebApp() throws Exception {
328         CaptchaEntryPoint ep = new CaptchaEntryPoint();
329         ep.setCaptchaFormUrl("https://www.jcaptcha.net/dotest/");
330 
331         PortMapperImpl mapper = new PortMapperImpl();
332         mapper.getTranslatedPortMappings().put(new Integer(8888), new Integer(1234));
333         ep.setPortMapper(mapper);
334 
335         ep.setPortResolver(new MockPortResolver(8888, 1234));
336         ep.setIncludeOriginalRequest(true);
337         ep.setOutsideWebApp(true);
338 
339         ep.afterPropertiesSet();
340 
341         MockHttpServletRequest request = new MockHttpServletRequest();
342         request.setRequestURI("/some_path");
343         request.setScheme("http");
344         request.setServerName("www.example.com");
345         request.setMethod("post");
346 
347         // request.setContextPath("/bigWebApp");
348         // TODO correct this when the getRequestUrl from mock works...
349         request.setServerPort(8888); // NB: Port we can't resolve
350 
351         MockHttpServletResponse response = new MockHttpServletResponse();
352 
353         ep.afterPropertiesSet();
354         ep.commence(request, response);
355         assertEquals("https://www.jcaptcha.net/dotest/?original_requestUrl="
356             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post",
357             response.getRedirectedUrl());
358 
359         // test the query params
360         request.addParameter("name", "value");
361         response = new MockHttpServletResponse();
362         ep.commence(request, response);
363         assertEquals("https://www.jcaptcha.net/dotest/?original_requestUrl="
364             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post",
365             response.getRedirectedUrl());
366 
367         // test the multiple query params
368         ep.setIncludeOriginalParameters(true);
369         request.addParameter("name", "value");
370         request.addParameter("name1", "value2");
371         response = new MockHttpServletResponse();
372         ep.commence(request, response);
373         assertEquals("https://www.jcaptcha.net/dotest/?original_requestUrl="
374             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post"
375             + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"),
376             response.getRedirectedUrl());
377 
378         // test add parameter to captcha form url??
379         ep.setCaptchaFormUrl("https://www.jcaptcha.net/dotest/?toto=titi");
380         response = new MockHttpServletResponse();
381         ep.commence(request, response);
382         assertEquals("https://www.jcaptcha.net/dotest/?toto=titi&original_requestUrl="
383             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post"
384             + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"),
385             response.getRedirectedUrl());
386 
387         // with forcing!!!
388         ep.setForceHttps(true);
389         response = new MockHttpServletResponse();
390         ep.commence(request, response);
391         assertEquals("https://www.jcaptcha.net/dotest/?toto=titi&original_requestUrl="
392             + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post"
393             + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"),
394             response.getRedirectedUrl());
395     }
396 }