From 60d3b6505ba583f8e6c9398555318e4eeb52cfb5 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Garrigue Date: Tue, 20 Sep 2005 12:24:47 +0000 Subject: [PATCH] Finalizing the validation, entry point and channel processor concerning captchas. Replacing the Thread.sleep() in captchaChannelProcessorTest to avoid the build break issue. --- .../captcha/CaptchaChannelProcessor.java | 64 +- .../captcha/CaptchaEntryPoint.java | 527 +++++----- .../captcha/CaptchaSecurityContext.java | 4 +- .../captcha/CaptchaServiceProxy.java | 21 +- .../CaptchaValidationProcessingFilter.java | 182 ++-- .../ui/session/HttpSessionEventPublisher.java | 2 +- .../captcha/CaptchaChannelProcessorTests.java | 918 +++++++++--------- .../captcha/CaptchaEntryPointTests.java | 635 ++++++------ .../CaptchaSecurityContextImplTests.java | 125 ++- ...aptchaValidationProcessingFilterTests.java | 160 +-- .../captcha/MockCaptchaServiceProxy.java | 18 +- 11 files changed, 1447 insertions(+), 1209 deletions(-) diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaChannelProcessor.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaChannelProcessor.java index feb0f3d806..87cebfce13 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaChannelProcessor.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaChannelProcessor.java @@ -79,7 +79,7 @@ import org.springframework.util.Assert; * * * - *
  • {@link #getRequiresHumanUntilMaxRequestsKeyword()}
    + *
  • {@link #getRequiresHumanAfterMaxRequestsKeyword()}
    * default value = REQUIRES_HUMAN_AFTER_MAX_MILLIS
    * if detected, checks if : * @@ -138,7 +138,7 @@ import org.springframework.util.Assert; * and the REQUIRES_HUMAN_AFTER_MAX_REQUESTS keywords
    * with a maxRequestsBeforeReTest=20
    * and a maxMillisBeforeReTest=3600000
    - * and amaxRequestsBeforeFirstTest=1000
  • + * and a maxRequestsBeforeFirstTest=1000 * * * @@ -158,7 +158,10 @@ public class CaptchaChannelProcessor implements ChannelProcessor, private String requiresHumanAfterMaxMillisKeyword = "REQUIRES_HUMAN_AFTER_MAX_MILLIS"; - private ChannelEntryPoint entryPoint; + private String keywordPrefix = ""; + + + private ChannelEntryPoint entryPoint; private int maxRequestsBeforeReTest = -1; @@ -166,7 +169,15 @@ public class CaptchaChannelProcessor implements ChannelProcessor, private long maxMillisBeforeReTest = -1; - public String getRequiresHumanAfterMaxMillisKeyword() { + public String getKeywordPrefix() { + return keywordPrefix; + } + + public void setKeywordPrefix(String keywordPrefix) { + this.keywordPrefix = keywordPrefix; + } + + public String getRequiresHumanAfterMaxMillisKeyword() { return requiresHumanAfterMaxMillisKeyword; } @@ -227,28 +238,21 @@ public class CaptchaChannelProcessor implements ChannelProcessor, if ((invocation == null) || (config == null)) { throw new IllegalArgumentException("Nulls cannot be provided"); } - CaptchaSecurityContext context = (CaptchaSecurityContext) SecurityContextHolder - .getContext(); + CaptchaSecurityContext context = null; + context = (CaptchaSecurityContext) SecurityContextHolder + .getContext(); - Iterator iter = config.getConfigAttributes(); - boolean shouldRedirect = true; + Iterator iter = config.getConfigAttributes(); + boolean shouldRedirect = false; while (iter.hasNext()) { ConfigAttribute attribute = (ConfigAttribute) iter.next(); - if (supports(attribute)) { logger.debug("supports this attribute : " + attribute); - if (isContextValidForAttribute(context, attribute)) { - shouldRedirect = false; - } else { - // reset if already passed a constraint - + if (!isContextValidForAttribute(context, attribute)) { shouldRedirect = true; - // break at first unsatisfy contraint - break; - } - - } + } + } } if (shouldRedirect) { logger @@ -270,8 +274,7 @@ public class CaptchaChannelProcessor implements ChannelProcessor, if ((attribute != null) || (attribute.getAttribute() != null)) { // test the REQUIRES_HUMAN_AFTER_MAX_REQUESTS keyword - if (attribute.getAttribute().equals( - getRequiresHumanAfterMaxRequestsKeyword())) { + if (isKeywordMaxRequest(attribute)) { if (isContextValidConcerningHumanOrFirstTest(context) && isContextValidConcerningReTest(context)) { valid = true; @@ -279,8 +282,7 @@ public class CaptchaChannelProcessor implements ChannelProcessor, } // test the REQUIRES_HUMAN_AFTER_MAX_MILLIS keyword - if (attribute.getAttribute().equals( - getRequiresHumanAfterMaxMillisKeyword())) { + if (isKeywordMillis(attribute)) { if (isContextValidConcerningHumanOrFirstTest(context) && isContextValidConcerningMaxMillis(context)) { valid = true; @@ -346,10 +348,7 @@ public class CaptchaChannelProcessor implements ChannelProcessor, public boolean supports(ConfigAttribute attribute) { if ((attribute != null) && (attribute.getAttribute() != null) - && (attribute.getAttribute().equals( - getRequiresHumanAfterMaxRequestsKeyword()) || attribute - .getAttribute().equals( - getRequiresHumanAfterMaxMillisKeyword()) + && (isKeywordMaxRequest(attribute) || isKeywordMillis(attribute) )) { return true; @@ -358,4 +357,15 @@ public class CaptchaChannelProcessor implements ChannelProcessor, } } + private boolean isKeywordMillis(ConfigAttribute attribute) { + return attribute + .getAttribute().equals( + getKeywordPrefix()+getRequiresHumanAfterMaxMillisKeyword()); + } + + private boolean isKeywordMaxRequest(ConfigAttribute attribute) { + return attribute.getAttribute().equals( + getKeywordPrefix()+getRequiresHumanAfterMaxRequestsKeyword()); + } + } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaEntryPoint.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaEntryPoint.java index 2e39d76b29..4f58d40f59 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaEntryPoint.java @@ -14,274 +14,365 @@ */ package net.sf.acegisecurity.captcha; -import java.io.IOException; -import java.util.Enumeration; +import net.sf.acegisecurity.securechannel.ChannelEntryPoint; +import net.sf.acegisecurity.util.PortMapper; +import net.sf.acegisecurity.util.PortMapperImpl; +import net.sf.acegisecurity.util.PortResolver; +import net.sf.acegisecurity.util.PortResolverImpl; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - -import net.sf.acegisecurity.securechannel.ChannelEntryPoint; -import net.sf.acegisecurity.util.PortMapper; -import net.sf.acegisecurity.util.PortMapperImpl; -import net.sf.acegisecurity.util.PortResolver; -import net.sf.acegisecurity.util.PortResolverImpl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Enumeration; /** * The captcha entry point : redirect to the captcha test page.
    - * + *

    * This entry point can force the use of SSL : see {@link #getForceHttps()}
    - * - * This entry point allows internal OR external redirect : see - * {@link #setOutsideWebApp(boolean)}
    / Original request can be added to - * the redirect path using a special parameter : see - * {@link #getOriginalRequestParameterName()} and - * {@link #setIncludeOriginalRequest()}

    Default values :
    - * forceHttps = false
    includesOriginalRequest = false
    - * originalRequestParameterName= "originalRequest"
    isOutsideWebApp=false
    - * + *

    + * This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}
    / Original request + * can be added to the redirect path using a custom translation : see {@link #setIncludeOriginalRequest(boolean)}
    + * Original request is translated using URLEncoding and the following translation mapping in the redirect url :

    + *

    + *

    + *

    + *
    Default values :
    forceHttps = false
    includesOriginalRequest = true
    includesOriginalParameters = + * false
    isOutsideWebApp=false
    originalRequestUrlParameterName ="original_requestUrl"
    + * originalRequestParametersParameterName = "original_request_parameters";
    + *

    + * originalRequestParametersNameValueSeparator = "@@";
    + *

    + * originalRequestParametersSeparator = ";;";
    + *

    + * originalRequestMethodParameterName = "original_request_method";
    + *

    + * urlEncodingCharset = "UTF-8";
    + * * @author marc antoine Garrigue * @version $Id$ */ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean { - // ~ Static fields/initializers - // ============================================= + // ~ Static fields/initializers + // ============================================= - private static final Log logger = LogFactory - .getLog(CaptchaEntryPoint.class); + private static final Log logger = LogFactory + .getLog(CaptchaEntryPoint.class); - // ~ Instance fields - // ======================================================== + // ~ Instance fields + // ======================================================== - private PortMapper portMapper = new PortMapperImpl(); + private PortMapper portMapper = new PortMapperImpl(); - private PortResolver portResolver = new PortResolverImpl(); + private PortResolver portResolver = new PortResolverImpl(); - private String captchaFormUrl; + private String captchaFormUrl; - private boolean forceHttps = false; + private boolean forceHttps = false; - private String originalRequestParameterName = "originalRequest"; + private String originalRequestUrlParameterName = "original_requestUrl"; - private boolean isOutsideWebApp = false; + private String originalRequestParametersParameterName = "original_request_parameters"; - private boolean includeOriginalRequest = false; + private String originalRequestParametersNameValueSeparator = "@@"; - // ~ Methods - // ================================================================ + private String originalRequestParametersSeparator = ";;"; - /** - * Set to true to force captcha form access to be via https. If this value - * is ture (the default is false), and the incoming request for the - * protected resource which triggered the interceptor was not already - * https, then - * - * @param forceHttps - */ - public void setForceHttps(boolean forceHttps) { - this.forceHttps = forceHttps; - } + private String originalRequestMethodParameterName = "original_request_method"; - public boolean getForceHttps() { - return forceHttps; - } + private String urlEncodingCharset = "UTF-8"; - /** - * The URL where the CaptchaProcessingFilter login page can - * be found. Should be relative to the web-app context path, and include a - * leading / - * - * @param captchaFormUrl - */ - public void setCaptchaFormUrl(String loginFormUrl) { - this.captchaFormUrl = loginFormUrl; - } + private boolean isOutsideWebApp = false; - /** - * @return the captcha test page to redirect to. - */ - public String getCaptchaFormUrl() { - return captchaFormUrl; - } + private boolean includeOriginalRequest = true; - public void setPortMapper(PortMapper portMapper) { - this.portMapper = portMapper; - } + private boolean includeOriginalParameters = false; - public PortMapper getPortMapper() { - return portMapper; - } + // ~ Methods + // ================================================================ - public void setPortResolver(PortResolver portResolver) { - this.portResolver = portResolver; - } + /** + * Set to true to force captcha form access to be via https. If this value is ture (the default is false), and the + * incoming request for the protected resource which triggered the interceptor was not already https, + * then + */ + public void setForceHttps(boolean forceHttps) { + this.forceHttps = forceHttps; + } - public PortResolver getPortResolver() { - return portResolver; - } + public boolean getForceHttps() { + return forceHttps; + } - public boolean isOutsideWebApp() { - return isOutsideWebApp; - } + /** + * The URL where the CaptchaProcessingFilter login page can be found. Should be relative to the web-app + * context path, and include a leading / + */ + public void setCaptchaFormUrl(String captchaFormUrl) { + this.captchaFormUrl = captchaFormUrl; + } - /** - * if set to true, the {@link #commence(ServletRequest, ServletResponse)} - * method uses the {@link #getCaptchaFormUrl()} as a complete URL, else it - * as a 'inside WebApp' path. - * - * @param isOutsideWebApp - */ - public void setOutsideWebApp(boolean isOutsideWebApp) { - this.isOutsideWebApp = isOutsideWebApp; - } + /** + * @return the captcha test page to redirect to. + */ + public String getCaptchaFormUrl() { + return captchaFormUrl; + } - public String getOriginalRequestParameterName() { - return originalRequestParameterName; - } + public void setPortMapper(PortMapper portMapper) { + this.portMapper = portMapper; + } - /** - * sets the parameter under which the original request url will be appended - * to the redirect url (only if {@link #isIncludeOriginalRequest()}==true). - * - * @param originalRequestParameterName - */ - public void setOriginalRequestParameterName( - String originalRequestParameterName) { - this.originalRequestParameterName = originalRequestParameterName; - } + public PortMapper getPortMapper() { + return portMapper; + } - public boolean isIncludeOriginalRequest() { - return includeOriginalRequest; - } + public void setPortResolver(PortResolver portResolver) { + this.portResolver = portResolver; + } - /** - * If set to true, the original request url will be appended to the redirect - * url using the {@link #getOriginalRequestParameterName()}. - * - * @param includeOriginalRequest - */ - public void setIncludeOriginalRequest(boolean includeOriginalRequest) { - this.includeOriginalRequest = includeOriginalRequest; - } + public PortResolver getPortResolver() { + return portResolver; + } - public void afterPropertiesSet() throws Exception { - Assert.hasLength(captchaFormUrl, "captchaFormUrl must be specified"); - Assert.notNull(portMapper, "portMapper must be specified"); - Assert.notNull(portResolver, "portResolver must be specified"); - } - public void commence(ServletRequest request, ServletResponse response) - throws IOException, ServletException { - StringBuffer redirectUrl = new StringBuffer(); - HttpServletRequest req = (HttpServletRequest) request; + public boolean isOutsideWebApp() { + return isOutsideWebApp; + } - if (isOutsideWebApp) { - redirectUrl = redirectUrl.append(captchaFormUrl); - } else { - buildInternalRedirect(redirectUrl, req); - } - if (includeOriginalRequest) { - includeOriginalRequest(redirectUrl, req); - } - // add post parameter? TODO? - if (logger.isDebugEnabled()) { - logger.debug("Redirecting to: " + redirectUrl); - } + public String getOriginalRequestUrlParameterName() { + return originalRequestUrlParameterName; + } - ((HttpServletResponse) response) - .sendRedirect(((HttpServletResponse) response) - .encodeRedirectURL(redirectUrl.toString())); - } + public void setOriginalRequestUrlParameterName(String originalRequestUrlParameterName) { + this.originalRequestUrlParameterName = originalRequestUrlParameterName; + } - private void includeOriginalRequest(StringBuffer redirectUrl, - HttpServletRequest req) { - // add original request to the url - if (redirectUrl.indexOf("?") >= 0) { - redirectUrl.append("&"); - } else { - redirectUrl.append("?"); - } - redirectUrl.append(originalRequestParameterName); - redirectUrl.append("="); - redirectUrl.append(req.getRequestURL().toString()); - // append query params - Enumeration parameters = req.getParameterNames(); - if (parameters != null && parameters.hasMoreElements()) { - redirectUrl.append("?"); - while (parameters.hasMoreElements()) { - String name = parameters.nextElement().toString(); - String value = req.getParameter(name); - redirectUrl.append(name); - redirectUrl.append("="); - redirectUrl.append(value); - if (parameters.hasMoreElements()) { - redirectUrl.append("&"); - } - } - } + public String getOriginalRequestParametersParameterName() { + return originalRequestParametersParameterName; + } - } + public void setOriginalRequestParametersParameterName(String originalRequestParametersParameterName) { + this.originalRequestParametersParameterName = originalRequestParametersParameterName; + } - private void buildInternalRedirect(StringBuffer redirectUrl, - HttpServletRequest req) { - // construct it - StringBuffer simpleRedirect = new StringBuffer(); + public String getOriginalRequestParametersNameValueSeparator() { + return originalRequestParametersNameValueSeparator; + } - String scheme = req.getScheme(); - String serverName = req.getServerName(); - int serverPort = portResolver.getServerPort(req); - String contextPath = req.getContextPath(); - boolean includePort = true; - if ("http".equals(scheme.toLowerCase()) && (serverPort == 80)) { - includePort = false; - } - if ("https".equals(scheme.toLowerCase()) && (serverPort == 443)) { - includePort = false; - } + public void setOriginalRequestParametersNameValueSeparator(String originalRequestParametersNameValueSeparator) { + this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator; + } - simpleRedirect.append(scheme); - simpleRedirect.append("://"); - simpleRedirect.append(serverName); - if (includePort) { - simpleRedirect.append(":"); - simpleRedirect.append(serverPort); - } - simpleRedirect.append(contextPath); - simpleRedirect.append(captchaFormUrl); + public String getOriginalRequestParametersSeparator() { + return originalRequestParametersSeparator; + } - if (forceHttps && req.getScheme().equals("http")) { - Integer httpPort = new Integer(portResolver.getServerPort(req)); - Integer httpsPort = (Integer) portMapper.lookupHttpsPort(httpPort); + public void setOriginalRequestParametersSeparator(String originalRequestParametersSeparator) { + this.originalRequestParametersSeparator = originalRequestParametersSeparator; + } - if (httpsPort != null) { - if (httpsPort.intValue() == 443) { - includePort = false; - } else { - includePort = true; - } + public String getOriginalRequestMethodParameterName() { + return originalRequestMethodParameterName; + } - redirectUrl.append("https://"); - redirectUrl.append(serverName); - if (includePort) { - redirectUrl.append(":"); - redirectUrl.append(httpsPort); - } - redirectUrl.append(contextPath); - redirectUrl.append(captchaFormUrl); - } else { - redirectUrl.append(simpleRedirect); - } - } else { - redirectUrl.append(simpleRedirect); - } - } + public void setOriginalRequestMethodParameterName(String originalRequestMethodParameterName) { + this.originalRequestMethodParameterName = originalRequestMethodParameterName; + } + + public String getUrlEncodingCharset() { + return urlEncodingCharset; + } + + public void setUrlEncodingCharset(String urlEncodingCharset) { + this.urlEncodingCharset = urlEncodingCharset; + } + + /** + * if set to true, the {@link #commence(ServletRequest, ServletResponse)} method uses the {@link + * #getCaptchaFormUrl()} as a complete URL, else it as a 'inside WebApp' path. + */ + public void setOutsideWebApp(boolean isOutsideWebApp) { + this.isOutsideWebApp = isOutsideWebApp; + } + + + public boolean isIncludeOriginalRequest() { + return includeOriginalRequest; + } + + /** + * If set to true, the original request url will be appended to the redirect url using the {@link + * #getOriginalRequestParameterName()}. + */ + public void setIncludeOriginalRequest(boolean includeOriginalRequest) { + this.includeOriginalRequest = includeOriginalRequest; + } + + public boolean isIncludeOriginalParameters() { + return includeOriginalParameters; + } + + public void setIncludeOriginalParameters(boolean includeOriginalParameters) { + this.includeOriginalParameters = includeOriginalParameters; + } + + public void afterPropertiesSet() throws Exception { + Assert.hasLength(captchaFormUrl, "captchaFormUrl must be specified"); + Assert.hasLength(originalRequestMethodParameterName, "originalRequestMethodParameterName must be specified"); + Assert.hasLength(originalRequestParametersNameValueSeparator, "originalRequestParametersNameValueSeparator must be specified"); + Assert.hasLength(originalRequestParametersParameterName, "originalRequestParametersParameterName must be specified"); + Assert.hasLength(originalRequestParametersSeparator, "originalRequestParametersSeparator must be specified"); + Assert.hasLength(originalRequestUrlParameterName, "originalRequestUrlParameterName must be specified"); + Assert.hasLength(urlEncodingCharset, "urlEncodingCharset must be specified"); + Assert.notNull(portMapper, "portMapper must be specified"); + Assert.notNull(portResolver, "portResolver must be specified"); + URLEncoder.encode(" fzaef é& à ", urlEncodingCharset); + } + + public void commence(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + StringBuffer redirectUrl = new StringBuffer(); + HttpServletRequest req = (HttpServletRequest) request; + + if (isOutsideWebApp) { + redirectUrl = redirectUrl.append(captchaFormUrl); + } else { + buildInternalRedirect(redirectUrl, req); + } + + if (includeOriginalRequest) { + includeOriginalRequest(redirectUrl, req); + } + // add post parameter? DONE! + if (logger.isDebugEnabled()) { + logger.debug("Redirecting to: " + redirectUrl); + } + + ((HttpServletResponse) response) + .sendRedirect(redirectUrl.toString()); + } + + private void includeOriginalRequest(StringBuffer redirectUrl, + HttpServletRequest req) { + // add original request to the url + if (redirectUrl.indexOf("?") >= 0) { + redirectUrl.append("&"); + } else { + redirectUrl.append("?"); + } + + redirectUrl.append(originalRequestUrlParameterName); + redirectUrl.append("="); + try { + redirectUrl.append(URLEncoder.encode(req.getRequestURL().toString(), urlEncodingCharset)); + } catch (UnsupportedEncodingException e) { + logger.warn(e); + } + + //append method + redirectUrl.append("&"); + redirectUrl.append(originalRequestMethodParameterName); + redirectUrl.append("="); + redirectUrl.append(req.getMethod()); + if (includeOriginalParameters) { + + // append query params + + redirectUrl.append("&"); + redirectUrl.append(originalRequestParametersParameterName); + redirectUrl.append("="); + StringBuffer qp = new StringBuffer(); + Enumeration parameters = req.getParameterNames(); + if (parameters != null && parameters.hasMoreElements()) { + //qp.append("?"); + while (parameters.hasMoreElements()) { + String name = parameters.nextElement().toString(); + String value = req.getParameter(name); + qp.append(name); + qp.append(originalRequestParametersNameValueSeparator); + qp.append(value); + if (parameters.hasMoreElements()) { + qp.append(originalRequestParametersSeparator); + } + } + } + try { + redirectUrl.append(URLEncoder.encode(qp.toString(), urlEncodingCharset)); + } catch (Exception e) { + logger.warn(e); + } + } + + } + + private void buildInternalRedirect(StringBuffer redirectUrl, + HttpServletRequest req) { + // construct it + StringBuffer simpleRedirect = new StringBuffer(); + + String scheme = req.getScheme(); + String serverName = req.getServerName(); + int serverPort = portResolver.getServerPort(req); + String contextPath = req.getContextPath(); + boolean includePort = true; + if ("http".equals(scheme.toLowerCase()) && (serverPort == 80)) { + includePort = false; + } + if ("https".equals(scheme.toLowerCase()) && (serverPort == 443)) { + includePort = false; + } + + simpleRedirect.append(scheme); + simpleRedirect.append("://"); + simpleRedirect.append(serverName); + if (includePort) { + simpleRedirect.append(":"); + simpleRedirect.append(serverPort); + } + simpleRedirect.append(contextPath); + simpleRedirect.append(captchaFormUrl); + + if (forceHttps && req.getScheme().equals("http")) { + Integer httpPort = new Integer(portResolver.getServerPort(req)); + Integer httpsPort = (Integer) portMapper.lookupHttpsPort(httpPort); + + if (httpsPort != null) { + if (httpsPort.intValue() == 443) { + includePort = false; + } else { + includePort = true; + } + + redirectUrl.append("https://"); + redirectUrl.append(serverName); + if (includePort) { + redirectUrl.append(":"); + redirectUrl.append(httpsPort); + } + redirectUrl.append(contextPath); + redirectUrl.append(captchaFormUrl); + } else { + redirectUrl.append(simpleRedirect); + } + } else { + redirectUrl.append(simpleRedirect); + } + } } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContext.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContext.java index df0a2ac008..03d3bb423a 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContext.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContext.java @@ -30,13 +30,11 @@ public interface CaptchaSecurityContext extends SecurityContext { /** * set human attribute, should called after captcha validation. - * - * @param human */ void setHuman(); /** - * + * * @return number of human restricted resources requests since the last * passed captcha. */ diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaServiceProxy.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaServiceProxy.java index 01d45b36ca..2c1057e3c2 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaServiceProxy.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaServiceProxy.java @@ -1,3 +1,18 @@ +/* Copyright 2004 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.sf.acegisecurity.captcha; import javax.servlet.ServletRequest; @@ -11,7 +26,9 @@ import javax.servlet.ServletRequest; public interface CaptchaServiceProxy { /** - * @return true if the request is validated by the back end captcha service. + * @param id the id token + * @param captchaResponse the user response + * @return true if the response is validated by the back end captcha service. */ - boolean validateRequest(ServletRequest request); + boolean validateReponseForId(String id , Object captchaResponse); } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilter.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilter.java index d9d59e3b7f..a72fd46969 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilter.java @@ -15,112 +15,128 @@ package net.sf.acegisecurity.captcha; -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - import net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter; import net.sf.acegisecurity.context.SecurityContextHolder; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.io.IOException; + /** - * Filter for web integration of the {@link CaptchaServiceProxy}.
    It - * basically intercept calls containing the specific validation parameter, use - * the {@link CaptchaServiceProxy} to validate the request, and update the - * {@link CaptchaSecurityContext} if the request passed the validation.
    - *
    This Filter should be placed after the ContextIntegration filter and - * before the {@link CaptchaChannelProcessor} filter in the filter stack in - * order to update the {@link CaptchaSecurityContext} before the humanity - * verification routine occurs.

    This filter should only be used in - * conjunction with the {@link CaptchaSecurityContext}

    - * - * + * Filter for web integration of the {@link CaptchaServiceProxy}.
    It basically intercept calls containing the + * specific validation parameter, use the {@link CaptchaServiceProxy} to validate the request, and update the {@link + * CaptchaSecurityContext} if the request passed the validation.

    This Filter should be placed after the + * ContextIntegration filter and before the {@link CaptchaChannelProcessor} filter in the filter stack in order to + * update the {@link CaptchaSecurityContext} before the humanity verification routine occurs.

    This filter + * should only be used in conjunction with the {@link CaptchaSecurityContext}

    + * * @author marc antoine Garrigue * @version $Id$ */ public class CaptchaValidationProcessingFilter implements InitializingBean, - Filter { - // ~ Static fields/initializers - // ============================================= - public static String CAPTCHA_VALIDATION_SECURITY_PARAMETER_KEY = "_captcha_parameter"; + Filter { + // ~ Static fields/initializers + // ============================================= + protected static final Log logger = LogFactory + .getLog(CaptchaValidationProcessingFilter.class); - protected static final Log logger = LogFactory - .getLog(HttpSessionContextIntegrationFilter.class); + // ~ Instance fields + // ======================================================== - // ~ Instance fields - // ======================================================== + private CaptchaServiceProxy captchaService; + private String captchaValidationParameter = "_captcha_parameter"; - private CaptchaServiceProxy captchaService; - // ~ Methods - // ================================================================ + // ~ Methods + // ================================================================ - public CaptchaServiceProxy getCaptchaService() { - return captchaService; - } + public CaptchaServiceProxy getCaptchaService() { + return captchaService; + } - public void setCaptchaService(CaptchaServiceProxy captchaService) { - this.captchaService = captchaService; - } + public void setCaptchaService(CaptchaServiceProxy captchaService) { + this.captchaService = captchaService; + } - public void afterPropertiesSet() throws Exception { - if (this.captchaService == null) { - throw new IllegalArgumentException( - "CaptchaServiceProxy must be defined "); - } - } - /** - * Does nothing. We use IoC container lifecycle services instead. - */ - public void destroy() { - } + public String getCaptchaValidationParameter() { + return captchaValidationParameter; + } - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void setCaptchaValidationParameter(String captchaValidationParameter) { + this.captchaValidationParameter = captchaValidationParameter; + } - if ((request != null) - && (request - .getParameter(CAPTCHA_VALIDATION_SECURITY_PARAMETER_KEY) != null)) { - logger.debug("captcha validation parameter not found, do nothing"); - // validate the request against CaptchaServiceProxy - boolean valid = false; + public void afterPropertiesSet() throws Exception { + if (this.captchaService == null) { + throw new IllegalArgumentException( + "CaptchaServiceProxy must be defined "); + } + if (this.captchaValidationParameter == null||"".equals(captchaValidationParameter)) { + throw new IllegalArgumentException( + "captchaValidationParameter must not be empty or null"); + } + } - logger.debug("try to validate"); - valid = this.captchaService.validateRequest(request); - logger.debug("captchaServiceProxy says : request is valid =" - + valid); - if (valid) { - logger.debug("update the context"); - ((CaptchaSecurityContext) SecurityContextHolder.getContext()) - .setHuman(); + /** + * Does nothing. We use IoC container lifecycle services instead. + */ + public void destroy() { + } - } + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + String captcha_reponse = request + .getParameter(captchaValidationParameter); + if ((request != null) && request instanceof HttpServletRequest + && ( captcha_reponse!= null)) { - } else { - logger.debug("captcha validation parameter not found, do nothing"); - } - logger.debug("chain..."); - chain.doFilter(request, response); - } + logger.debug("captcha validation parameter found"); + // validate the request against CaptchaServiceProxy + boolean valid = false; - /** - * Does nothing. We use IoC container lifecycle services instead. - * - * @param filterConfig - * ignored - * - * @throws ServletException - * ignored - */ - public void init(FilterConfig filterConfig) throws ServletException { - } + logger.debug("try to validate"); + + //get session + HttpSession session = ((HttpServletRequest) request).getSession(); + if (session != null) { + + String id = session.getId(); + valid = this.captchaService.validateReponseForId(id, + captcha_reponse); + logger.debug("captchaServiceProxy says : request is valid = " + + valid); + if (valid) { + logger.debug("update the context"); + ((CaptchaSecurityContext) SecurityContextHolder.getContext()) + .setHuman(); + //logger.debug("retrieve original request from ") + + }else{ + logger.debug("captcha test failed"); + } + + }else{ + logger.debug("no session found, user don't even ask a captcha challenge"); + } + } else { + logger.debug("captcha validation parameter not found, do nothing"); + } + logger.debug("chain ..."); + chain.doFilter(request, response); + } + + /** + * Does nothing. We use IoC container lifecycle services instead. + * + * @param filterConfig ignored + * + * @throws ServletException ignored + */ + public void init(FilterConfig filterConfig) throws ServletException { + } } diff --git a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionEventPublisher.java b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionEventPublisher.java index a08ee383d7..f1da2d8e30 100644 --- a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionEventPublisher.java +++ b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionEventPublisher.java @@ -119,7 +119,7 @@ public class HttpSessionEventPublisher implements HttpSessionListener, } ApplicationContext getContext() { - Assert.notNull(context, "setContext(...) never called, ApplicationContext must not be null"); + Assert.notNull(context, "setContext(...) never called, ApplicationContext must not be null"); return context; } } diff --git a/core/src/test/java/org/acegisecurity/captcha/CaptchaChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/captcha/CaptchaChannelProcessorTests.java index bad74a5756..65f3aa3b01 100644 --- a/core/src/test/java/org/acegisecurity/captcha/CaptchaChannelProcessorTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/CaptchaChannelProcessorTests.java @@ -15,532 +15,538 @@ package net.sf.acegisecurity.captcha; -import java.io.IOException; - -import javax.servlet.ServletException; - import junit.framework.TestCase; import net.sf.acegisecurity.ConfigAttributeDefinition; import net.sf.acegisecurity.MockFilterChain; import net.sf.acegisecurity.SecurityConfig; import net.sf.acegisecurity.context.SecurityContextHolder; import net.sf.acegisecurity.intercept.web.FilterInvocation; - import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -/** - * Tests {@link CaptchaChannelProcessor} +import javax.servlet.ServletException; +import java.io.IOException; + +/** + * Tests {@link CaptchaChannelProcessor} + * * @author marc antoine Garrigue * @version $Id$ */ public class CaptchaChannelProcessorTests extends TestCase { - public void testDecideRequestsFirstTestRequests() throws Exception { - ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); - cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); - cad.addConfigAttribute(new SecurityConfig( - "REQUIRES_HUMAN_AFTER_MAX_REQUESTS")); - - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - SecurityContextHolder.setContext(context); - - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - CaptchaEntryPoint epoint = new CaptchaEntryPoint(); - epoint.setCaptchaFormUrl("/jcaptcha.do"); - processor.setEntryPoint(epoint); - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString("info=true"); - request.setServerName("localhost"); - request.setContextPath("/demo"); - request.setServletPath("/restricted"); - request.setScheme("http"); - request.setServerPort(8000); - - MockHttpServletResponse response = new MockHttpServletResponse(); - MockFilterChain chain = new MockFilterChain(); - FilterInvocation fi = new FilterInvocation(request, response, chain); - - processor.decide(fi, cad); - assertEquals(response.getRedirectedUrl(), - "http://localhost:8000/demo/jcaptcha.do"); - - processor.setMaxRequestsBeforeFirstTest(1); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(response.getRedirectedUrl(), null); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(response.getRedirectedUrl(), - "http://localhost:8000/demo/jcaptcha.do"); - - processor.setMaxRequestsBeforeFirstTest(2); - processor.setMaxMillisBeforeReTest(0); + public void testDecideRequestsFirstTestRequests() throws Exception { + ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); + cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); + cad.addConfigAttribute(new SecurityConfig( + "REQUIRES_HUMAN_AFTER_MAX_REQUESTS")); - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - } + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + SecurityContextHolder.setContext(context); - public void testDecideRequestsFirstTestMillis() throws Exception { - ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); - cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); - cad.addConfigAttribute(new SecurityConfig( - "REQUIRES_HUMAN_AFTER_MAX_MILLIS")); + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + CaptchaEntryPoint epoint = new CaptchaEntryPoint(); + epoint.setCaptchaFormUrl("/jcaptcha.do"); + epoint.setIncludeOriginalRequest(false); - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - SecurityContextHolder.setContext(context); + processor.setEntryPoint(epoint); - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - CaptchaEntryPoint epoint = new CaptchaEntryPoint(); - epoint.setCaptchaFormUrl("/jcaptcha.do"); - processor.setEntryPoint(epoint); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setQueryString("info=true"); + request.setServerName("localhost"); + request.setContextPath("/demo"); + request.setServletPath("/restricted"); + request.setScheme("http"); + request.setServerPort(8000); - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString("info=true"); - request.setServerName("localhost"); - request.setContextPath("/demo"); - request.setServletPath("/restricted"); - request.setScheme("http"); - request.setServerPort(8000); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain chain = new MockFilterChain(); + FilterInvocation fi = new FilterInvocation(request, response, chain); + + processor.decide(fi, cad); + assertEquals(response.getRedirectedUrl(), + "http://localhost:8000/demo/jcaptcha.do"); + + processor.setMaxRequestsBeforeFirstTest(1); - MockHttpServletResponse response = new MockHttpServletResponse(); - MockFilterChain chain = new MockFilterChain(); - FilterInvocation fi = new FilterInvocation(request, response, chain); + response = decideWithNewResponse(cad, processor, request); + assertEquals(response.getRedirectedUrl(), null); - processor.decide(fi, cad); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + response = decideWithNewResponse(cad, processor, request); + assertEquals(response.getRedirectedUrl(), + "http://localhost:8000/demo/jcaptcha.do"); - processor.setMaxRequestsBeforeFirstTest(1); + processor.setMaxRequestsBeforeFirstTest(2); + processor.setMaxMillisBeforeReTest(0); - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + } - processor.setMaxRequestsBeforeFirstTest(2); - processor.setMaxRequestsBeforeReTest(0); + public void testDecideRequestsFirstTestMillis() throws Exception { + ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); + cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); + cad.addConfigAttribute(new SecurityConfig( + "REQUIRES_HUMAN_AFTER_MAX_MILLIS")); - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + SecurityContextHolder.setContext(context); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - } - - public void testDecideRequestsReTest() throws Exception { - ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); - cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); - cad.addConfigAttribute(new SecurityConfig( - "REQUIRES_HUMAN_AFTER_MAX_REQUESTS")); - - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - SecurityContextHolder.setContext(context); - - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - CaptchaEntryPoint epoint = new CaptchaEntryPoint(); - epoint.setCaptchaFormUrl("/jcaptcha.do"); - processor.setEntryPoint(epoint); - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString("info=true"); - request.setServerName("localhost"); - request.setContextPath("/demo"); - request.setServletPath("/restricted"); - request.setScheme("http"); - request.setServerPort(8000); - - MockHttpServletResponse response = new MockHttpServletResponse(); - MockFilterChain chain = new MockFilterChain(); - FilterInvocation fi = new FilterInvocation(request, response, chain); - - processor.decide(fi, cad); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - processor.setMaxRequestsBeforeFirstTest(1); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(response.getRedirectedUrl(), null); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - processor.setMaxRequestsBeforeReTest(2); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - context.setHuman(); - SecurityContextHolder.setContext(context); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - processor.setMaxMillisBeforeReTest(0); - context.setHuman(); - SecurityContextHolder.setContext(context); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - context.setHuman(); - SecurityContextHolder.setContext(context); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - } - - private MockHttpServletResponse decideWithNewResponse( - ConfigAttributeDefinition cad, CaptchaChannelProcessor processor, - MockHttpServletRequest request) throws IOException, - ServletException { - MockHttpServletResponse response; - MockFilterChain chain; - FilterInvocation fi; - response = new MockHttpServletResponse(); - chain = new MockFilterChain(); - fi = new FilterInvocation(request, response, chain); - processor.decide(fi, cad); - return response; - } - - public void testDecideRejectsNulls() throws Exception { - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - processor.setEntryPoint(new CaptchaEntryPoint()); - processor.afterPropertiesSet(); - - try { - processor.decide(null, null); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - } -/* - - // TODO: Re-enable these tests. - - Commented out by Ben Alex on 19 Sep 05 as the Thread.sleep(100) approach to simulating - request age caused intermittent problems. An alternative approach should be used - instead, such as (a) modifying the CaptchaSecurityContextImpl (why not make a package - protected setLastPassedCaptchaDateInMillis) or (b) providing a package protected method - so that the unit test can modify the time being used by CaptchaChannelProcesor instead - of using System.currentTimeMillis(). - - public void testDecideMillis() throws Exception { - ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); - cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); - cad.addConfigAttribute(new SecurityConfig( - "REQUIRES_HUMAN_AFTER_MAX_MILLIS")); - - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - SecurityContextHolder.setContext(context); - - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - CaptchaEntryPoint epoint = new CaptchaEntryPoint(); - epoint.setCaptchaFormUrl("/jcaptcha.do"); - processor.setEntryPoint(epoint); - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString("info=true"); - request.setServerName("localhost"); - request.setContextPath("/demo"); - request.setServletPath("/restricted"); - request.setScheme("http"); - request.setServerPort(8000); - - MockHttpServletResponse response = new MockHttpServletResponse(); - MockFilterChain chain = new MockFilterChain(); - FilterInvocation fi = new FilterInvocation(request, response, chain); - - processor.decide(fi, cad); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - processor.setMaxRequestsBeforeFirstTest(1); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(response.getRedirectedUrl(), null); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - processor.setMaxMillisBeforeReTest(100); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - context.setHuman(); - SecurityContextHolder.setContext(context); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - Thread.sleep(100); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - processor.setMaxRequestsBeforeReTest(0); - context.setHuman(); - SecurityContextHolder.setContext(context); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); - - Thread.sleep(100); - - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - - context.setHuman(); - SecurityContextHolder.setContext(context); + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + CaptchaEntryPoint epoint = new CaptchaEntryPoint(); + epoint.setCaptchaFormUrl("/jcaptcha.do"); + epoint.setIncludeOriginalRequest(false); - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); + processor.setEntryPoint(epoint); - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setQueryString("info=true"); + request.setServerName("localhost"); + request.setContextPath("/demo"); + request.setServletPath("/restricted"); + request.setScheme("http"); + request.setServerPort(8000); - Thread.sleep(100); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain chain = new MockFilterChain(); + FilterInvocation fi = new FilterInvocation(request, response, chain); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - } + processor.decide(fi, cad); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - public void testDecideBoth() throws Exception { - ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); - cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); - cad.addConfigAttribute(new SecurityConfig( - "REQUIRES_HUMAN_AFTER_MAX_MILLIS")); - cad.addConfigAttribute(new SecurityConfig( - "REQUIRES_HUMAN_AFTER_MAX_REQUESTS")); + processor.setMaxRequestsBeforeFirstTest(1); - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - SecurityContextHolder.setContext(context); + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - CaptchaEntryPoint epoint = new CaptchaEntryPoint(); - epoint.setCaptchaFormUrl("/jcaptcha.do"); - processor.setEntryPoint(epoint); + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString("info=true"); - request.setServerName("localhost"); - request.setContextPath("/demo"); - request.setServletPath("/restricted"); - request.setScheme("http"); - request.setServerPort(8000); + processor.setMaxRequestsBeforeFirstTest(2); + processor.setMaxRequestsBeforeReTest(0); - MockHttpServletResponse response = new MockHttpServletResponse(); - MockFilterChain chain = new MockFilterChain(); - FilterInvocation fi = new FilterInvocation(request, response, chain); + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - processor.decide(fi, cad); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - processor.setMaxRequestsBeforeFirstTest(1); + } - response = decideWithNewResponse(cad, processor, request); - assertEquals(response.getRedirectedUrl(), null); + public void testDecideRequestsReTest() throws Exception { + ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); + cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); + cad.addConfigAttribute(new SecurityConfig( + "REQUIRES_HUMAN_AFTER_MAX_REQUESTS")); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + SecurityContextHolder.setContext(context); - processor.setMaxMillisBeforeReTest(100); - processor.setMaxRequestsBeforeReTest(2); + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + CaptchaEntryPoint epoint = new CaptchaEntryPoint(); + epoint.setCaptchaFormUrl("/jcaptcha.do"); + epoint.setIncludeOriginalRequest(false); + + processor.setEntryPoint(epoint); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setQueryString("info=true"); + request.setServerName("localhost"); + request.setContextPath("/demo"); + request.setServletPath("/restricted"); + request.setScheme("http"); + request.setServerPort(8000); - context.setHuman(); - SecurityContextHolder.setContext(context); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain chain = new MockFilterChain(); + FilterInvocation fi = new FilterInvocation(request, response, chain); + + processor.decide(fi, cad); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); + processor.setMaxRequestsBeforeFirstTest(1); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(response.getRedirectedUrl(), null); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + processor.setMaxRequestsBeforeReTest(2); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + context.setHuman(); + SecurityContextHolder.setContext(context); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - Thread.sleep(100); + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + processor.setMaxMillisBeforeReTest(0); + context.setHuman(); + SecurityContextHolder.setContext(context); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - context.setHuman(); - SecurityContextHolder.setContext(context); + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); + context.setHuman(); + SecurityContextHolder.setContext(context); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - context.setHuman(); - SecurityContextHolder.setContext(context); + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + } - response = decideWithNewResponse(cad, processor, request); - assertEquals(null, response.getRedirectedUrl()); + private MockHttpServletResponse decideWithNewResponse( + ConfigAttributeDefinition cad, CaptchaChannelProcessor processor, + MockHttpServletRequest request) throws IOException, + ServletException { + MockHttpServletResponse response; + MockFilterChain chain; + FilterInvocation fi; + response = new MockHttpServletResponse(); + chain = new MockFilterChain(); + fi = new FilterInvocation(request, response, chain); + processor.decide(fi, cad); + return response; + } - Thread.sleep(100); + public void testDecideRejectsNulls() throws Exception { + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + processor.setEntryPoint(new CaptchaEntryPoint()); + processor.afterPropertiesSet(); - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); + try { + processor.decide(null, null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } - response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", response - .getRedirectedUrl()); - } -*/ - public void testGettersSetters() { - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - assertEquals("REQUIRES_HUMAN_AFTER_MAX_MILLIS", processor - .getRequiresHumanAfterMaxMillisKeyword()); - processor.setRequiresHumanAfterMaxMillisKeyword("X"); - assertEquals("X", processor.getRequiresHumanAfterMaxMillisKeyword()); + public void testDecideMillis() throws Exception { + ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); + cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); + cad.addConfigAttribute(new SecurityConfig( + "REQUIRES_HUMAN_AFTER_MAX_MILLIS")); - assertEquals("REQUIRES_HUMAN_AFTER_MAX_REQUESTS", processor - .getRequiresHumanAfterMaxRequestsKeyword()); - processor.setRequiresHumanAfterMaxRequestsKeyword("Y"); - assertEquals("Y", processor.getRequiresHumanAfterMaxRequestsKeyword()); + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + SecurityContextHolder.setContext(context); - assertEquals(0, processor.getMaxRequestsBeforeFirstTest()); - processor.setMaxRequestsBeforeFirstTest(1); - assertEquals(1, processor.getMaxRequestsBeforeFirstTest()); + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + CaptchaEntryPoint epoint = new CaptchaEntryPoint(); + epoint.setCaptchaFormUrl("/jcaptcha.do"); + epoint.setIncludeOriginalRequest(false); - assertEquals(-1, processor.getMaxRequestsBeforeReTest()); - processor.setMaxRequestsBeforeReTest(11); - assertEquals(11, processor.getMaxRequestsBeforeReTest()); + processor.setEntryPoint(epoint); - assertEquals(-1, processor.getMaxMillisBeforeReTest()); - processor.setMaxMillisBeforeReTest(111); - assertEquals(111, processor.getMaxMillisBeforeReTest()); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setQueryString("info=true"); + request.setServerName("localhost"); + request.setContextPath("/demo"); + request.setServletPath("/restricted"); + request.setScheme("http"); + request.setServerPort(8000); - assertTrue(processor.getEntryPoint() == null); - processor.setEntryPoint(new CaptchaEntryPoint()); - assertTrue(processor.getEntryPoint() != null); - } + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain chain = new MockFilterChain(); + FilterInvocation fi = new FilterInvocation(request, response, chain); - public void testMissingEntryPoint() throws Exception { - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - processor.setEntryPoint(null); + processor.decide(fi, cad); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - try { - processor.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertEquals("entryPoint required", expected.getMessage()); - } - } + processor.setMaxRequestsBeforeFirstTest(1); - public void testMissingKeyword() throws Exception { - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - processor.setRequiresHumanAfterMaxMillisKeyword(null); + response = decideWithNewResponse(cad, processor, request); + assertEquals(response.getRedirectedUrl(), null); - try { - processor.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - } - processor.setRequiresHumanAfterMaxMillisKeyword(""); + processor.setMaxMillisBeforeReTest(100); - try { - processor.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); - } - processor.setRequiresHumanAfterMaxRequestsKeyword(""); + context.setHuman(); + SecurityContextHolder.setContext(context); - try { - processor.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); - } - - processor.setRequiresHumanAfterMaxRequestsKeyword(null); - - try { - processor.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - - } - - } - - public void testSupports() { - CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); - assertTrue(processor.supports(new SecurityConfig(processor - .getRequiresHumanAfterMaxMillisKeyword()))); - assertTrue(processor.supports(new SecurityConfig(processor - .getRequiresHumanAfterMaxRequestsKeyword()))); - - assertTrue(processor.supports(new SecurityConfig( - "REQUIRES_HUMAN_AFTER_MAX_REQUESTS"))); - assertTrue(processor.supports(new SecurityConfig( - "REQUIRES_HUMAN_AFTER_MAX_MILLIS"))); - - assertFalse(processor.supports(null)); - - assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED"))); - } + waitFor(100); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + processor.setMaxRequestsBeforeReTest(0); + context.setHuman(); + SecurityContextHolder.setContext(context); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); + + waitFor(100); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + context.setHuman(); + SecurityContextHolder.setContext(context); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); + + waitFor(100); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + } + + public void testDecideBoth() throws Exception { + ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); + cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); + cad.addConfigAttribute(new SecurityConfig( + "REQUIRES_HUMAN_AFTER_MAX_MILLIS")); + cad.addConfigAttribute(new SecurityConfig( + "REQUIRES_HUMAN_AFTER_MAX_REQUESTS")); + + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + SecurityContextHolder.setContext(context); + + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + CaptchaEntryPoint epoint = new CaptchaEntryPoint(); + epoint.setCaptchaFormUrl("/jcaptcha.do"); + epoint.setIncludeOriginalRequest(false); + + processor.setEntryPoint(epoint); + + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setQueryString("info=true"); + request.setServerName("localhost"); + request.setContextPath("/demo"); + request.setServletPath("/restricted"); + request.setScheme("http"); + request.setServerPort(8000); + + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain chain = new MockFilterChain(); + FilterInvocation fi = new FilterInvocation(request, response, chain); + + processor.decide(fi, cad); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + processor.setMaxRequestsBeforeFirstTest(1); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(response.getRedirectedUrl(), null); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + processor.setMaxMillisBeforeReTest(100); + processor.setMaxRequestsBeforeReTest(2); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + context.setHuman(); + SecurityContextHolder.setContext(context); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); + + waitFor(100); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + context.setHuman(); + SecurityContextHolder.setContext(context); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + context.setHuman(); + SecurityContextHolder.setContext(context); + + response = decideWithNewResponse(cad, processor, request); + assertEquals(null, response.getRedirectedUrl()); + + waitFor(100); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + + response = decideWithNewResponse(cad, processor, request); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response + .getRedirectedUrl()); + } + + public void testGettersSetters() { + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + assertEquals("REQUIRES_HUMAN_AFTER_MAX_MILLIS", processor + .getRequiresHumanAfterMaxMillisKeyword()); + processor.setRequiresHumanAfterMaxMillisKeyword("X"); + assertEquals("X", processor.getRequiresHumanAfterMaxMillisKeyword()); + + assertEquals("REQUIRES_HUMAN_AFTER_MAX_REQUESTS", processor + .getRequiresHumanAfterMaxRequestsKeyword()); + processor.setRequiresHumanAfterMaxRequestsKeyword("Y"); + assertEquals("Y", processor.getRequiresHumanAfterMaxRequestsKeyword()); + + assertEquals(0, processor.getMaxRequestsBeforeFirstTest()); + processor.setMaxRequestsBeforeFirstTest(1); + assertEquals(1, processor.getMaxRequestsBeforeFirstTest()); + + assertEquals(-1, processor.getMaxRequestsBeforeReTest()); + processor.setMaxRequestsBeforeReTest(11); + assertEquals(11, processor.getMaxRequestsBeforeReTest()); + + assertEquals(-1, processor.getMaxMillisBeforeReTest()); + processor.setMaxMillisBeforeReTest(111); + assertEquals(111, processor.getMaxMillisBeforeReTest()); + + assertTrue(processor.getEntryPoint() == null); + processor.setEntryPoint(new CaptchaEntryPoint()); + assertTrue(processor.getEntryPoint() != null); + } + + public void testMissingEntryPoint() throws Exception { + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + processor.setEntryPoint(null); + + try { + processor.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("entryPoint required", expected.getMessage()); + } + } + + public void testMissingKeyword() throws Exception { + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + processor.setRequiresHumanAfterMaxMillisKeyword(null); + + try { + processor.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + + } + processor.setRequiresHumanAfterMaxMillisKeyword(""); + + try { + processor.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + + } + processor.setRequiresHumanAfterMaxRequestsKeyword(""); + + try { + processor.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + + } + + processor.setRequiresHumanAfterMaxRequestsKeyword(null); + + try { + processor.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + + } + + } + + public void testSupports() { + CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); + assertTrue(processor.supports(new SecurityConfig(processor + .getRequiresHumanAfterMaxMillisKeyword()))); + assertTrue(processor.supports(new SecurityConfig(processor + .getRequiresHumanAfterMaxRequestsKeyword()))); + + assertTrue(processor.supports(new SecurityConfig( + "REQUIRES_HUMAN_AFTER_MAX_REQUESTS"))); + assertTrue(processor.supports(new SecurityConfig( + "REQUIRES_HUMAN_AFTER_MAX_MILLIS"))); + + assertFalse(processor.supports(null)); + + assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED"))); + } + + private void waitFor(int time){ + long start=System.currentTimeMillis(); + while(System.currentTimeMillis()= 0); - assertTrue("should be less than 0,1 seconde", context - .getLastPassedCaptchaDateInMillis() - - now < 100); - assertEquals("should be 0", 0, context - .getHumanRestrictedResourcesRequestsCount()); - } + public void testSetHuman() { + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + long now = System.currentTimeMillis(); + context.setHuman(); + assertEquals("should be human", true, context.isHuman()); + assertTrue("should be more than 0", context + .getLastPassedCaptchaDateInMillis() + - now >= 0); + assertTrue("should be less than 0,1 seconde", context + .getLastPassedCaptchaDateInMillis() + - now < 100); + assertEquals("should be 0", 0, context + .getHumanRestrictedResourcesRequestsCount()); + } - public void testIncrementRequests() { - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - context.setHuman(); - assertEquals("should be human", true, context.isHuman()); - assertEquals("should be 0", 0, context - .getHumanRestrictedResourcesRequestsCount()); - context.incrementHumanRestrictedRessoucesRequestsCount(); - assertEquals("should be 1", 1, context - .getHumanRestrictedResourcesRequestsCount()); - } + public void testIncrementRequests() { + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + context.setHuman(); + assertEquals("should be human", true, context.isHuman()); + assertEquals("should be 0", 0, context + .getHumanRestrictedResourcesRequestsCount()); + context.incrementHumanRestrictedRessoucesRequestsCount(); + assertEquals("should be 1", 1, context + .getHumanRestrictedResourcesRequestsCount()); + } - public void testResetHuman() { - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - context.setHuman(); - assertEquals("should be human", true, context.isHuman()); - assertEquals("should be 0", 0, context - .getHumanRestrictedResourcesRequestsCount()); - context.incrementHumanRestrictedRessoucesRequestsCount(); - assertEquals("should be 1", 1, context - .getHumanRestrictedResourcesRequestsCount()); - long now = System.currentTimeMillis(); - context.setHuman(); - assertEquals("should be 0", 0, context - .getHumanRestrictedResourcesRequestsCount()); - assertTrue("should be more than 0", context - .getLastPassedCaptchaDateInMillis() - - now >= 0); - assertTrue("should be less than 0,1 seconde", context - .getLastPassedCaptchaDateInMillis() - - now < 100); + public void testResetHuman() { + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + context.setHuman(); + assertEquals("should be human", true, context.isHuman()); + assertEquals("should be 0", 0, context + .getHumanRestrictedResourcesRequestsCount()); + context.incrementHumanRestrictedRessoucesRequestsCount(); + assertEquals("should be 1", 1, context + .getHumanRestrictedResourcesRequestsCount()); + long now = System.currentTimeMillis(); + context.setHuman(); + assertEquals("should be 0", 0, context + .getHumanRestrictedResourcesRequestsCount()); + assertTrue("should be more than 0", context + .getLastPassedCaptchaDateInMillis() + - now >= 0); + assertTrue("should be less than 0,1 seconde", context + .getLastPassedCaptchaDateInMillis() + - now < 100); - } + } } diff --git a/core/src/test/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilterTests.java index 676afc153a..688ab47926 100644 --- a/core/src/test/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilterTests.java @@ -1,83 +1,115 @@ +/* Copyright 2004 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.sf.acegisecurity.captcha; import junit.framework.TestCase; import net.sf.acegisecurity.context.SecurityContextHolder; import net.sf.acegisecurity.util.MockFilterChain; - import org.springframework.mock.web.MockHttpServletRequest; +/** + * Tests {@link CaptchaValidationProcessingFilter}. + * + * @author marc antoine Garrigue + * @version $Id$ + */ public class CaptchaValidationProcessingFilterTests extends TestCase { - /* - */ - public void testAfterPropertiesSet() throws Exception { - CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter(); + /* + */ + public void testAfterPropertiesSet() throws Exception { + CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter(); - try { - filter.afterPropertiesSet(); - fail("should have thrown an invalid argument exception"); - } catch (Exception e) { - assertTrue("should be an InvalidArgumentException", - IllegalArgumentException.class.isAssignableFrom(e - .getClass())); - } - filter.setCaptchaService(new MockCaptchaServiceProxy()); - filter.afterPropertiesSet(); + try { + filter.afterPropertiesSet(); + fail("should have thrown an invalid argument exception"); + } catch (Exception e) { + assertTrue("should be an InvalidArgumentException", + IllegalArgumentException.class.isAssignableFrom(e + .getClass())); + } - } + filter.setCaptchaService(new MockCaptchaServiceProxy()); + filter.afterPropertiesSet(); + filter.setCaptchaValidationParameter(null); + try { + filter.afterPropertiesSet(); + fail("should have thrown an invalid argument exception"); + } catch (Exception e) { + assertTrue("should be an InvalidArgumentException", + IllegalArgumentException.class.isAssignableFrom(e + .getClass())); + } - /* - * Test method for - * 'net.sf.acegisecurity.captcha.CaptchaValidationProcessingFilter.doFilter(ServletRequest, - * ServletResponse, FilterChain)' - */ - public void testDoFilterWithoutRequestParameter() throws Exception { - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - SecurityContextHolder.setContext(context); - MockHttpServletRequest request = new MockHttpServletRequest(); - CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter(); - MockCaptchaServiceProxy service = new MockCaptchaServiceProxy(); - MockFilterChain chain = new MockFilterChain(true); - filter.setCaptchaService(service); - filter.doFilter(request, null, chain); - assertFalse("proxy should not have been called", service.hasBeenCalled); - assertFalse("context should not have been updated", context.isHuman()); - // test with valid - service.valid = true; - filter.doFilter(request, null, chain); - assertFalse("proxy should not have been called", service.hasBeenCalled); - assertFalse("context should not have been updated", context.isHuman()); - } + } - /* - * Test method for - * 'net.sf.acegisecurity.captcha.CaptchaValidationProcessingFilter.doFilter(ServletRequest, - * ServletResponse, FilterChain)' - */ - public void testDoFilterWithRequestParameter() throws Exception { - CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - SecurityContextHolder.setContext(context); + /* + * Test method for + * 'net.sf.acegisecurity.captcha.CaptchaValidationProcessingFilter.doFilter(ServletRequest, + * ServletResponse, FilterChain)' + */ + public void testDoFilterWithoutRequestParameter() throws Exception { + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + SecurityContextHolder.setContext(context); + MockHttpServletRequest request = new MockHttpServletRequest(); + CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter(); + MockCaptchaServiceProxy service = new MockCaptchaServiceProxy(); + MockFilterChain chain = new MockFilterChain(true); + filter.setCaptchaService(service); + filter.doFilter(request, null, chain); + assertFalse("proxy should not have been called", service.hasBeenCalled); + assertFalse("context should not have been updated", context.isHuman()); + // test with valid + service.valid = true; + filter.doFilter(request, null, chain); + assertFalse("proxy should not have been called", service.hasBeenCalled); + assertFalse("context should not have been updated", context.isHuman()); - MockHttpServletRequest request = new MockHttpServletRequest(); - request - .addParameter( - CaptchaValidationProcessingFilter.CAPTCHA_VALIDATION_SECURITY_PARAMETER_KEY, - ""); + } - CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter(); - MockCaptchaServiceProxy service = new MockCaptchaServiceProxy(); - MockFilterChain chain = new MockFilterChain(true); - filter.setCaptchaService(service); - filter.doFilter(request, null, chain); - assertTrue("should have been called", service.hasBeenCalled); - assertFalse("context should not have been updated", context.isHuman()); - // test with valid - service.valid = true; - filter.doFilter(request, null, chain); - assertTrue("should have been called", service.hasBeenCalled); - assertTrue("context should have been updated", context.isHuman()); + /* + * Test method for + * 'net.sf.acegisecurity.captcha.CaptchaValidationProcessingFilter.doFilter(ServletRequest, + * ServletResponse, FilterChain)' + */ + public void testDoFilterWithRequestParameter() throws Exception { + CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); + SecurityContextHolder.setContext(context); - } + MockHttpServletRequest request = new MockHttpServletRequest(); + + CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter(); + request + .addParameter( + filter.getCaptchaValidationParameter(), + ""); + + MockCaptchaServiceProxy service = new MockCaptchaServiceProxy(); + MockFilterChain chain = new MockFilterChain(true); + filter.setCaptchaService(service); + filter.doFilter(request, null, chain); + assertTrue("should have been called", service.hasBeenCalled); + assertFalse("context should not have been updated", context.isHuman()); + // test with valid + service.valid = true; + filter.doFilter(request, null, chain); + assertTrue("should have been called", service.hasBeenCalled); + assertTrue("context should have been updated", context.isHuman()); + + } } diff --git a/core/src/test/java/org/acegisecurity/captcha/MockCaptchaServiceProxy.java b/core/src/test/java/org/acegisecurity/captcha/MockCaptchaServiceProxy.java index 22df451797..6b3197e9ee 100644 --- a/core/src/test/java/org/acegisecurity/captcha/MockCaptchaServiceProxy.java +++ b/core/src/test/java/org/acegisecurity/captcha/MockCaptchaServiceProxy.java @@ -15,18 +15,20 @@ package net.sf.acegisecurity.captcha; -import javax.servlet.ServletRequest; - +/** + * @author marc antoine Garrigue + * @version $Id$ + */ public class MockCaptchaServiceProxy implements CaptchaServiceProxy { - public boolean valid = false; + public boolean valid = false; - public boolean hasBeenCalled = false; + public boolean hasBeenCalled = false; - public boolean validateRequest(ServletRequest request) { - hasBeenCalled = true; - return valid; + public boolean validateReponseForId(String id, Object response) { + hasBeenCalled = true; + return valid; - } + } }