    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.captcha;
    16
    17  import junit.framework.TestCase;
    18
    19  import org.acegisecurity.ConfigAttributeDefinition;
    20  import org.acegisecurity.MockFilterChain;
    21  import org.acegisecurity.SecurityConfig;
    22  import org.acegisecurity.context.SecurityContextHolder;
    23  import org.acegisecurity.intercept.web.FilterInvocation;
    24
    25  import org.springframework.mock.web.MockHttpServletRequest;
    26  import org.springframework.mock.web.MockHttpServletResponse;
    27
    28  import java.io.IOException;
    29
    30  import javax.servlet.ServletException;
    31
    32
    33  /***
    34   * Tests {@link org.acegisecurity.captcha.CaptchaChannelProcessorTemplate}
    35   *
    36   * @author marc antoine Garrigue
    37   * @version $Id: CaptchaChannelProcessorTemplateTests.java,v 1.2 2005/11/17 00:56:08 benalex Exp $
    38   */
    39  public class CaptchaChannelProcessorTemplateTests extends TestCase {
    40      //~ Methods ================================================================
    41
    42      public void testContextRedirect() throws Exception {
    43          CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
    44          processor.setKeyword("X");
    45
    46          ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
    47          cad.addConfigAttribute(new SecurityConfig("Y"));
    48
    49          CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
    50          SecurityContextHolder.setContext(context);
    51
    52          CaptchaEntryPoint epoint = new CaptchaEntryPoint();
    53          epoint.setCaptchaFormUrl("/jcaptcha.do");
    54          epoint.setIncludeOriginalRequest(false);
    55
    56          processor.setEntryPoint(epoint);
    57
    58          MockHttpServletRequest request = new MockHttpServletRequest();
    59          request.setQueryString("info=true");
    60          request.setServerName("localhost");
    61          request.setContextPath("/demo");
    62          request.setServletPath("/restricted");
    63          request.setScheme("http");
    64          request.setServerPort(8000);
    65
    66          MockHttpServletResponse response = new MockHttpServletResponse();
    67          MockFilterChain chain = new MockFilterChain();
    68          FilterInvocation fi = new FilterInvocation(request, response, chain);
    69
    70          processor.decide(fi, cad);
    71          assertEquals(null, response.getRedirectedUrl());
    72          processor.setKeyword("Y");
    73          response = decideWithNewResponse(cad, processor, request);
    74          assertEquals("http://localhost:8000/demo/jcaptcha.do",
    75              response.getRedirectedUrl());
    76          context.setHuman();
    77          response = decideWithNewResponse(cad, processor, request);
    78          assertEquals(null, response.getRedirectedUrl());
    79      }
    80
    81      public void testDecideRejectsNulls() throws Exception {
    82          CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
    83          processor.setEntryPoint(new CaptchaEntryPoint());
    84          processor.setKeyword("X");
    85          processor.afterPropertiesSet();
    86
    87          try {
    88              processor.decide(null, null);
    89              fail("Should have thrown IllegalArgumentException");
    90          } catch (IllegalArgumentException expected) {
    91              assertTrue(true);
    92          }
    93      }
    94
    95      public void testGettersSetters() {
    96          CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
    97          assertEquals(null, processor.getKeyword());
    98          processor.setKeyword("X");
    99          assertEquals("X", processor.getKeyword());
    100
    101         assertEquals(0, processor.getThresold());
    102         processor.setThresold(1);
    103         assertEquals(1, processor.getThresold());
    104
    105         assertTrue(processor.getEntryPoint() == null);
    106         processor.setEntryPoint(new CaptchaEntryPoint());
    107         assertTrue(processor.getEntryPoint() != null);
    108     }
    109
    110     public void testIncrementRequestCount() throws Exception {
    111         CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
    112         processor.setKeyword("X");
    113
    114         ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
    115         cad.addConfigAttribute(new SecurityConfig("X"));
    116
    117         CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
    118         SecurityContextHolder.setContext(context);
    119
    120         CaptchaEntryPoint epoint = new CaptchaEntryPoint();
    121         epoint.setCaptchaFormUrl("/jcaptcha.do");
    122         processor.setEntryPoint(epoint);
    123
    124         MockHttpServletRequest request = new MockHttpServletRequest();
    125         request.setQueryString("info=true");
    126         request.setServerName("localhost");
    127         request.setContextPath("/demo");
    128         request.setServletPath("/restricted");
    129         request.setScheme("http");
    130         request.setServerPort(8000);
    131
    132         MockHttpServletResponse response = new MockHttpServletResponse();
    133         MockFilterChain chain = new MockFilterChain();
    134         FilterInvocation fi = new FilterInvocation(request, response, chain);
    135
    136         processor.decide(fi, cad);
    137         assertEquals(0, context.getHumanRestrictedResourcesRequestsCount());
    138         context.setHuman();
    139         decideWithNewResponse(cad, processor, request);
    140         assertEquals(1, context.getHumanRestrictedResourcesRequestsCount());
    141         decideWithNewResponse(cad, processor, request);
    142         assertEquals(2, context.getHumanRestrictedResourcesRequestsCount());
    143         processor.setKeyword("Y");
    144         decideWithNewResponse(cad, processor, request);
    145         assertEquals(2, context.getHumanRestrictedResourcesRequestsCount());
    146         context = new CaptchaSecurityContextImpl();
    147         decideWithNewResponse(cad, processor, request);
    148         assertEquals(0, context.getHumanRestrictedResourcesRequestsCount());
    149     }
    150
    151     public void testMissingEntryPoint() throws Exception {
    152         CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
    153         processor.setEntryPoint(null);
    154
    155         try {
    156             processor.afterPropertiesSet();
    157             fail("Should have thrown IllegalArgumentException");
    158         } catch (IllegalArgumentException expected) {
    159             assertEquals("entryPoint required", expected.getMessage());
    160         }
    161     }
    162
    163     public void testMissingKeyword() throws Exception {
    164         CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
    165         processor.setKeyword(null);
    166
    167         try {
    168             processor.afterPropertiesSet();
    169             fail("Should have thrown IllegalArgumentException");
    170         } catch (IllegalArgumentException expected) {}
    171
    172         processor.setKeyword("");
    173
    174         try {
    175             processor.afterPropertiesSet();
    176             fail("Should have thrown IllegalArgumentException");
    177         } catch (IllegalArgumentException expected) {}
    178     }
    179
    180     public void testSupports() {
    181         CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
    182         processor.setKeyword("X");
    183         assertTrue(processor.supports(
    184                 new SecurityConfig(processor.getKeyword())));
    185
    186         assertTrue(processor.supports(new SecurityConfig("X")));
    187
    188         assertFalse(processor.supports(null));
    189
    190         assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED")));
    191     }
    192
    193     private MockHttpServletResponse decideWithNewResponse(
    194         ConfigAttributeDefinition cad,
    195         CaptchaChannelProcessorTemplate processor,
    196         MockHttpServletRequest request) throws IOException, ServletException {
    197         MockHttpServletResponse response;
    198         MockFilterChain chain;
    199         FilterInvocation fi;
    200         response = new MockHttpServletResponse();
    201         chain = new MockFilterChain();
    202         fi = new FilterInvocation(request, response, chain);
    203         processor.decide(fi, cad);
    204
    205         return response;
    206     }
    207
    208     //~ Inner Classes ==========================================================
    209
    210     private class TestHumanityCaptchaChannelProcessor
    211         extends CaptchaChannelProcessorTemplate {
    212         boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
    213             return context.isHuman();
    214         }
    215     }
    216 }