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