Finalizing the validation, entry point and channel processor concerning captchas. Replacing the Thread.sleep() in captchaChannelProcessorTest to avoid the build break issue.

This commit is contained in:
Marc-Antoine Garrigue 2005-09-20 12:24:47 +00:00
parent 6f3e92e2e4
commit 60d3b6505b
11 changed files with 1447 additions and 1209 deletions

View File

@ -79,7 +79,7 @@ import org.springframework.util.Assert;
* *
* *
* *
* <li>{@link #getRequiresHumanUntilMaxRequestsKeyword()} <br> * <li>{@link #getRequiresHumanAfterMaxRequestsKeyword()} <br>
* default value = <code>REQUIRES_HUMAN_AFTER_MAX_MILLIS</code> <br> * default value = <code>REQUIRES_HUMAN_AFTER_MAX_MILLIS</code> <br>
* if detected, checks if : * if detected, checks if :
* *
@ -138,7 +138,7 @@ import org.springframework.util.Assert;
* and the REQUIRES_HUMAN_AFTER_MAX_REQUESTS keywords <br> * and the REQUIRES_HUMAN_AFTER_MAX_REQUESTS keywords <br>
* with a maxRequestsBeforeReTest=20 <br> * with a maxRequestsBeforeReTest=20 <br>
* and a maxMillisBeforeReTest=3600000 <br> * and a maxMillisBeforeReTest=3600000 <br>
* and amaxRequestsBeforeFirstTest=1000</li> * and a maxRequestsBeforeFirstTest=1000</li>
* *
* </ul> * </ul>
* *
@ -158,6 +158,9 @@ public class CaptchaChannelProcessor implements ChannelProcessor,
private String requiresHumanAfterMaxMillisKeyword = "REQUIRES_HUMAN_AFTER_MAX_MILLIS"; private String requiresHumanAfterMaxMillisKeyword = "REQUIRES_HUMAN_AFTER_MAX_MILLIS";
private String keywordPrefix = "";
private ChannelEntryPoint entryPoint; private ChannelEntryPoint entryPoint;
private int maxRequestsBeforeReTest = -1; private int maxRequestsBeforeReTest = -1;
@ -166,6 +169,14 @@ public class CaptchaChannelProcessor implements ChannelProcessor,
private long maxMillisBeforeReTest = -1; private long maxMillisBeforeReTest = -1;
public String getKeywordPrefix() {
return keywordPrefix;
}
public void setKeywordPrefix(String keywordPrefix) {
this.keywordPrefix = keywordPrefix;
}
public String getRequiresHumanAfterMaxMillisKeyword() { public String getRequiresHumanAfterMaxMillisKeyword() {
return requiresHumanAfterMaxMillisKeyword; return requiresHumanAfterMaxMillisKeyword;
} }
@ -227,27 +238,20 @@ public class CaptchaChannelProcessor implements ChannelProcessor,
if ((invocation == null) || (config == null)) { if ((invocation == null) || (config == null)) {
throw new IllegalArgumentException("Nulls cannot be provided"); throw new IllegalArgumentException("Nulls cannot be provided");
} }
CaptchaSecurityContext context = (CaptchaSecurityContext) SecurityContextHolder CaptchaSecurityContext context = null;
context = (CaptchaSecurityContext) SecurityContextHolder
.getContext(); .getContext();
Iterator iter = config.getConfigAttributes(); Iterator iter = config.getConfigAttributes();
boolean shouldRedirect = true; boolean shouldRedirect = false;
while (iter.hasNext()) { while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next(); ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (supports(attribute)) { if (supports(attribute)) {
logger.debug("supports this attribute : " + attribute); logger.debug("supports this attribute : " + attribute);
if (isContextValidForAttribute(context, attribute)) { if (!isContextValidForAttribute(context, attribute)) {
shouldRedirect = false;
} else {
// reset if already passed a constraint
shouldRedirect = true; shouldRedirect = true;
// break at first unsatisfy contraint
break;
} }
} }
} }
if (shouldRedirect) { if (shouldRedirect) {
@ -270,8 +274,7 @@ public class CaptchaChannelProcessor implements ChannelProcessor,
if ((attribute != null) || (attribute.getAttribute() != null)) { if ((attribute != null) || (attribute.getAttribute() != null)) {
// test the REQUIRES_HUMAN_AFTER_MAX_REQUESTS keyword // test the REQUIRES_HUMAN_AFTER_MAX_REQUESTS keyword
if (attribute.getAttribute().equals( if (isKeywordMaxRequest(attribute)) {
getRequiresHumanAfterMaxRequestsKeyword())) {
if (isContextValidConcerningHumanOrFirstTest(context) if (isContextValidConcerningHumanOrFirstTest(context)
&& isContextValidConcerningReTest(context)) { && isContextValidConcerningReTest(context)) {
valid = true; valid = true;
@ -279,8 +282,7 @@ public class CaptchaChannelProcessor implements ChannelProcessor,
} }
// test the REQUIRES_HUMAN_AFTER_MAX_MILLIS keyword // test the REQUIRES_HUMAN_AFTER_MAX_MILLIS keyword
if (attribute.getAttribute().equals( if (isKeywordMillis(attribute)) {
getRequiresHumanAfterMaxMillisKeyword())) {
if (isContextValidConcerningHumanOrFirstTest(context) if (isContextValidConcerningHumanOrFirstTest(context)
&& isContextValidConcerningMaxMillis(context)) { && isContextValidConcerningMaxMillis(context)) {
valid = true; valid = true;
@ -346,10 +348,7 @@ public class CaptchaChannelProcessor implements ChannelProcessor,
public boolean supports(ConfigAttribute attribute) { public boolean supports(ConfigAttribute attribute) {
if ((attribute != null) if ((attribute != null)
&& (attribute.getAttribute() != null) && (attribute.getAttribute() != null)
&& (attribute.getAttribute().equals( && (isKeywordMaxRequest(attribute) || isKeywordMillis(attribute)
getRequiresHumanAfterMaxRequestsKeyword()) || attribute
.getAttribute().equals(
getRequiresHumanAfterMaxMillisKeyword())
)) { )) {
return true; 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());
}
} }

View File

@ -14,38 +14,54 @@
*/ */
package net.sf.acegisecurity.captcha; package net.sf.acegisecurity.captcha;
import java.io.IOException; import net.sf.acegisecurity.securechannel.ChannelEntryPoint;
import java.util.Enumeration; 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.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import net.sf.acegisecurity.securechannel.ChannelEntryPoint; import java.io.UnsupportedEncodingException;
import net.sf.acegisecurity.util.PortMapper; import java.net.URLEncoder;
import net.sf.acegisecurity.util.PortMapperImpl; import java.util.Enumeration;
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;
/** /**
* The captcha entry point : redirect to the captcha test page. <br/> * The captcha entry point : redirect to the captcha test page. <br/>
* * <p/>
* This entry point can force the use of SSL : see {@link #getForceHttps()}<br/> * This entry point can force the use of SSL : see {@link #getForceHttps()}<br/>
* * <p/>
* This entry point allows internal OR external redirect : see * This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}<br/>/ Original request
* {@link #setOutsideWebApp(boolean)}<br/>/ Original request can be added to * can be added to the redirect path using a custom translation : see {@link #setIncludeOriginalRequest(boolean)} <br/>
* the redirect path using a special parameter : see * Original request is translated using URLEncoding and the following translation mapping in the redirect url : <ul>
* {@link #getOriginalRequestParameterName()} and * <li>original url => {@link #getOriginalRequestUrlParameterName()}</li> <li> If {@link
* {@link #setIncludeOriginalRequest()} <br/> <br/> Default values :<br/> * #isIncludeOriginalParameters()}</li> <li>original method => {@link #getOriginalRequestMethodParameterName()} </li>
* forceHttps = false<br/> includesOriginalRequest = false<br/> * <li>original parameters => {@link #getOriginalRequestParametersParameterName()} </li> <li>The orinial parameters
* originalRequestParameterName= "originalRequest"<br/> isOutsideWebApp=false<br/> * string is contructed using :</li> <ul> <li>a parameter separator {@link #getOriginalRequestParametersSeparator()}
* </li> <li>a parameter name value pair separator for each parameter {@link #getOriginalRequestParametersNameValueSeparator()}
* </li> </ul> </ul>
* <p/>
* <p/>
* <p/>
* <br/> Default values :<br/> forceHttps = false<br/> includesOriginalRequest = true<br/> includesOriginalParameters =
* false<br/> isOutsideWebApp=false<br/> originalRequestUrlParameterName ="original_requestUrl" <br/>
* originalRequestParametersParameterName = "original_request_parameters";<br/>
* <p/>
* originalRequestParametersNameValueSeparator = "@@"; <br/>
* <p/>
* originalRequestParametersSeparator = ";;"; <br/>
* <p/>
* originalRequestMethodParameterName = "original_request_method"; <br/>
* <p/>
* urlEncodingCharset = "UTF-8"; <br/>
* *
* @author marc antoine Garrigue * @author marc antoine Garrigue
* @version $Id$ * @version $Id$
@ -68,22 +84,31 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
private boolean forceHttps = false; private boolean forceHttps = false;
private String originalRequestParameterName = "originalRequest"; private String originalRequestUrlParameterName = "original_requestUrl";
private String originalRequestParametersParameterName = "original_request_parameters";
private String originalRequestParametersNameValueSeparator = "@@";
private String originalRequestParametersSeparator = ";;";
private String originalRequestMethodParameterName = "original_request_method";
private String urlEncodingCharset = "UTF-8";
private boolean isOutsideWebApp = false; private boolean isOutsideWebApp = false;
private boolean includeOriginalRequest = false; private boolean includeOriginalRequest = true;
private boolean includeOriginalParameters = false;
// ~ Methods // ~ Methods
// ================================================================ // ================================================================
/** /**
* Set to true to force captcha form access to be via https. If this value * Set to true to force captcha form access to be via https. If this value is ture (the default is false), and the
* is ture (the default is false), and the incoming request for the * incoming request for the protected resource which triggered the interceptor was not already <code>https</code>,
* protected resource which triggered the interceptor was not already * then
* <code>https</code>, then
*
* @param forceHttps
*/ */
public void setForceHttps(boolean forceHttps) { public void setForceHttps(boolean forceHttps) {
this.forceHttps = forceHttps; this.forceHttps = forceHttps;
@ -94,14 +119,11 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
} }
/** /**
* The URL where the <code>CaptchaProcessingFilter</code> login page can * The URL where the <code>CaptchaProcessingFilter</code> login page can be found. Should be relative to the web-app
* be found. Should be relative to the web-app context path, and include a * context path, and include a leading <code>/</code>
* leading <code>/</code>
*
* @param captchaFormUrl
*/ */
public void setCaptchaFormUrl(String loginFormUrl) { public void setCaptchaFormUrl(String captchaFormUrl) {
this.captchaFormUrl = loginFormUrl; this.captchaFormUrl = captchaFormUrl;
} }
/** /**
@ -127,54 +149,100 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
return portResolver; return portResolver;
} }
public boolean isOutsideWebApp() { public boolean isOutsideWebApp() {
return isOutsideWebApp; return isOutsideWebApp;
} }
public String getOriginalRequestUrlParameterName() {
return originalRequestUrlParameterName;
}
public void setOriginalRequestUrlParameterName(String originalRequestUrlParameterName) {
this.originalRequestUrlParameterName = originalRequestUrlParameterName;
}
public String getOriginalRequestParametersParameterName() {
return originalRequestParametersParameterName;
}
public void setOriginalRequestParametersParameterName(String originalRequestParametersParameterName) {
this.originalRequestParametersParameterName = originalRequestParametersParameterName;
}
public String getOriginalRequestParametersNameValueSeparator() {
return originalRequestParametersNameValueSeparator;
}
public void setOriginalRequestParametersNameValueSeparator(String originalRequestParametersNameValueSeparator) {
this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator;
}
public String getOriginalRequestParametersSeparator() {
return originalRequestParametersSeparator;
}
public void setOriginalRequestParametersSeparator(String originalRequestParametersSeparator) {
this.originalRequestParametersSeparator = originalRequestParametersSeparator;
}
public String getOriginalRequestMethodParameterName() {
return originalRequestMethodParameterName;
}
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)} * if set to true, the {@link #commence(ServletRequest, ServletResponse)} method uses the {@link
* method uses the {@link #getCaptchaFormUrl()} as a complete URL, else it * #getCaptchaFormUrl()} as a complete URL, else it as a 'inside WebApp' path.
* as a 'inside WebApp' path.
*
* @param isOutsideWebApp
*/ */
public void setOutsideWebApp(boolean isOutsideWebApp) { public void setOutsideWebApp(boolean isOutsideWebApp) {
this.isOutsideWebApp = isOutsideWebApp; this.isOutsideWebApp = isOutsideWebApp;
} }
public String getOriginalRequestParameterName() {
return originalRequestParameterName;
}
/**
* 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 boolean isIncludeOriginalRequest() { public boolean isIncludeOriginalRequest() {
return includeOriginalRequest; return includeOriginalRequest;
} }
/** /**
* If set to true, the original request url will be appended to the redirect * If set to true, the original request url will be appended to the redirect url using the {@link
* url using the {@link #getOriginalRequestParameterName()}. * #getOriginalRequestParameterName()}.
*
* @param includeOriginalRequest
*/ */
public void setIncludeOriginalRequest(boolean includeOriginalRequest) { public void setIncludeOriginalRequest(boolean includeOriginalRequest) {
this.includeOriginalRequest = includeOriginalRequest; this.includeOriginalRequest = includeOriginalRequest;
} }
public boolean isIncludeOriginalParameters() {
return includeOriginalParameters;
}
public void setIncludeOriginalParameters(boolean includeOriginalParameters) {
this.includeOriginalParameters = includeOriginalParameters;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.hasLength(captchaFormUrl, "captchaFormUrl must be specified"); 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(portMapper, "portMapper must be specified");
Assert.notNull(portResolver, "portResolver must be specified"); Assert.notNull(portResolver, "portResolver must be specified");
URLEncoder.encode(" fzaef é& à ", urlEncodingCharset);
} }
public void commence(ServletRequest request, ServletResponse response) public void commence(ServletRequest request, ServletResponse response)
@ -191,14 +259,13 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
if (includeOriginalRequest) { if (includeOriginalRequest) {
includeOriginalRequest(redirectUrl, req); includeOriginalRequest(redirectUrl, req);
} }
// add post parameter? TODO? // add post parameter? DONE!
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Redirecting to: " + redirectUrl); logger.debug("Redirecting to: " + redirectUrl);
} }
((HttpServletResponse) response) ((HttpServletResponse) response)
.sendRedirect(((HttpServletResponse) response) .sendRedirect(redirectUrl.toString());
.encodeRedirectURL(redirectUrl.toString()));
} }
private void includeOriginalRequest(StringBuffer redirectUrl, private void includeOriginalRequest(StringBuffer redirectUrl,
@ -209,24 +276,48 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
} else { } else {
redirectUrl.append("?"); redirectUrl.append("?");
} }
redirectUrl.append(originalRequestParameterName);
redirectUrl.append(originalRequestUrlParameterName);
redirectUrl.append("="); redirectUrl.append("=");
redirectUrl.append(req.getRequestURL().toString()); 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 // append query params
redirectUrl.append("&");
redirectUrl.append(originalRequestParametersParameterName);
redirectUrl.append("=");
StringBuffer qp = new StringBuffer();
Enumeration parameters = req.getParameterNames(); Enumeration parameters = req.getParameterNames();
if (parameters != null && parameters.hasMoreElements()) { if (parameters != null && parameters.hasMoreElements()) {
redirectUrl.append("?"); //qp.append("?");
while (parameters.hasMoreElements()) { while (parameters.hasMoreElements()) {
String name = parameters.nextElement().toString(); String name = parameters.nextElement().toString();
String value = req.getParameter(name); String value = req.getParameter(name);
redirectUrl.append(name); qp.append(name);
redirectUrl.append("="); qp.append(originalRequestParametersNameValueSeparator);
redirectUrl.append(value); qp.append(value);
if (parameters.hasMoreElements()) { if (parameters.hasMoreElements()) {
redirectUrl.append("&"); qp.append(originalRequestParametersSeparator);
} }
} }
} }
try {
redirectUrl.append(URLEncoder.encode(qp.toString(), urlEncodingCharset));
} catch (Exception e) {
logger.warn(e);
}
}
} }

View File

@ -30,8 +30,6 @@ public interface CaptchaSecurityContext extends SecurityContext {
/** /**
* set human attribute, should called after captcha validation. * set human attribute, should called after captcha validation.
*
* @param human
*/ */
void setHuman(); void setHuman();

View File

@ -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; package net.sf.acegisecurity.captcha;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
@ -11,7 +26,9 @@ import javax.servlet.ServletRequest;
public interface CaptchaServiceProxy { 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);
} }

View File

@ -15,33 +15,24 @@
package net.sf.acegisecurity.captcha; 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.HttpSessionContextIntegrationFilter;
import net.sf.acegisecurity.context.SecurityContextHolder; import net.sf.acegisecurity.context.SecurityContextHolder;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; 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}. <br/> It * Filter for web integration of the {@link CaptchaServiceProxy}. <br/> It basically intercept calls containing the
* basically intercept calls containing the specific validation parameter, use * specific validation parameter, use the {@link CaptchaServiceProxy} to validate the request, and update the {@link
* the {@link CaptchaServiceProxy} to validate the request, and update the * CaptchaSecurityContext} if the request passed the validation. <br/> <br/> This Filter should be placed after the
* {@link CaptchaSecurityContext} if the request passed the validation. <br/> * ContextIntegration filter and before the {@link CaptchaChannelProcessor} filter in the filter stack in order to
* <br/> This Filter should be placed after the ContextIntegration filter and * update the {@link CaptchaSecurityContext} before the humanity verification routine occurs. <br/> <br/> This filter
* before the {@link CaptchaChannelProcessor} filter in the filter stack in * should only be used in conjunction with the {@link CaptchaSecurityContext} <br/> <br/>
* order to update the {@link CaptchaSecurityContext} before the humanity
* verification routine occurs. <br/> <br/> This filter should only be used in
* conjunction with the {@link CaptchaSecurityContext} <br/> <br/>
*
* *
* @author marc antoine Garrigue * @author marc antoine Garrigue
* @version $Id$ * @version $Id$
@ -50,15 +41,15 @@ public class CaptchaValidationProcessingFilter implements InitializingBean,
Filter { Filter {
// ~ Static fields/initializers // ~ Static fields/initializers
// ============================================= // =============================================
public static String CAPTCHA_VALIDATION_SECURITY_PARAMETER_KEY = "_captcha_parameter";
protected static final Log logger = LogFactory protected static final Log logger = LogFactory
.getLog(HttpSessionContextIntegrationFilter.class); .getLog(CaptchaValidationProcessingFilter.class);
// ~ Instance fields // ~ Instance fields
// ======================================================== // ========================================================
private CaptchaServiceProxy captchaService; private CaptchaServiceProxy captchaService;
private String captchaValidationParameter = "_captcha_parameter";
// ~ Methods // ~ Methods
// ================================================================ // ================================================================
@ -71,11 +62,24 @@ public class CaptchaValidationProcessingFilter implements InitializingBean,
this.captchaService = captchaService; this.captchaService = captchaService;
} }
public String getCaptchaValidationParameter() {
return captchaValidationParameter;
}
public void setCaptchaValidationParameter(String captchaValidationParameter) {
this.captchaValidationParameter = captchaValidationParameter;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (this.captchaService == null) { if (this.captchaService == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"CaptchaServiceProxy must be defined "); "CaptchaServiceProxy must be defined ");
} }
if (this.captchaValidationParameter == null||"".equals(captchaValidationParameter)) {
throw new IllegalArgumentException(
"captchaValidationParameter must not be empty or null");
}
} }
/** /**
@ -86,40 +90,52 @@ public class CaptchaValidationProcessingFilter implements InitializingBean,
public void doFilter(ServletRequest request, ServletResponse response, public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException { FilterChain chain) throws IOException, ServletException {
String captcha_reponse = request
.getParameter(captchaValidationParameter);
if ((request != null) && request instanceof HttpServletRequest
&& ( captcha_reponse!= null)) {
if ((request != null) logger.debug("captcha validation parameter found");
&& (request
.getParameter(CAPTCHA_VALIDATION_SECURITY_PARAMETER_KEY) != null)) {
logger.debug("captcha validation parameter not found, do nothing");
// validate the request against CaptchaServiceProxy // validate the request against CaptchaServiceProxy
boolean valid = false; boolean valid = false;
logger.debug("try to validate"); logger.debug("try to validate");
valid = this.captchaService.validateRequest(request);
logger.debug("captchaServiceProxy says : request is valid =" //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); + valid);
if (valid) { if (valid) {
logger.debug("update the context"); logger.debug("update the context");
((CaptchaSecurityContext) SecurityContextHolder.getContext()) ((CaptchaSecurityContext) SecurityContextHolder.getContext())
.setHuman(); .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 { } else {
logger.debug("captcha validation parameter not found, do nothing"); logger.debug("captcha validation parameter not found, do nothing");
} }
logger.debug("chain..."); logger.debug("chain ...");
chain.doFilter(request, response); chain.doFilter(request, response);
} }
/** /**
* Does nothing. We use IoC container lifecycle services instead. * Does nothing. We use IoC container lifecycle services instead.
* *
* @param filterConfig * @param filterConfig ignored
* ignored
* *
* @throws ServletException * @throws ServletException ignored
* ignored
*/ */
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig filterConfig) throws ServletException {
} }

View File

@ -15,22 +15,21 @@
package net.sf.acegisecurity.captcha; package net.sf.acegisecurity.captcha;
import java.io.IOException;
import javax.servlet.ServletException;
import junit.framework.TestCase; import junit.framework.TestCase;
import net.sf.acegisecurity.ConfigAttributeDefinition; import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.MockFilterChain; import net.sf.acegisecurity.MockFilterChain;
import net.sf.acegisecurity.SecurityConfig; import net.sf.acegisecurity.SecurityConfig;
import net.sf.acegisecurity.context.SecurityContextHolder; import net.sf.acegisecurity.context.SecurityContextHolder;
import net.sf.acegisecurity.intercept.web.FilterInvocation; import net.sf.acegisecurity.intercept.web.FilterInvocation;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
/** /**
* Tests {@link CaptchaChannelProcessor} * Tests {@link CaptchaChannelProcessor}
*
* @author marc antoine Garrigue * @author marc antoine Garrigue
* @version $Id$ * @version $Id$
*/ */
@ -48,6 +47,8 @@ public class CaptchaChannelProcessorTests extends TestCase {
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
CaptchaEntryPoint epoint = new CaptchaEntryPoint(); CaptchaEntryPoint epoint = new CaptchaEntryPoint();
epoint.setCaptchaFormUrl("/jcaptcha.do"); epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
processor.setEntryPoint(epoint); processor.setEntryPoint(epoint);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
@ -98,6 +99,8 @@ public class CaptchaChannelProcessorTests extends TestCase {
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
CaptchaEntryPoint epoint = new CaptchaEntryPoint(); CaptchaEntryPoint epoint = new CaptchaEntryPoint();
epoint.setCaptchaFormUrl("/jcaptcha.do"); epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
processor.setEntryPoint(epoint); processor.setEntryPoint(epoint);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
@ -149,6 +152,8 @@ public class CaptchaChannelProcessorTests extends TestCase {
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
CaptchaEntryPoint epoint = new CaptchaEntryPoint(); CaptchaEntryPoint epoint = new CaptchaEntryPoint();
epoint.setCaptchaFormUrl("/jcaptcha.do"); epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
processor.setEntryPoint(epoint); processor.setEntryPoint(epoint);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
@ -249,16 +254,6 @@ public class CaptchaChannelProcessorTests extends TestCase {
assertTrue(true); 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 { public void testDecideMillis() throws Exception {
ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
@ -272,6 +267,8 @@ public class CaptchaChannelProcessorTests extends TestCase {
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
CaptchaEntryPoint epoint = new CaptchaEntryPoint(); CaptchaEntryPoint epoint = new CaptchaEntryPoint();
epoint.setCaptchaFormUrl("/jcaptcha.do"); epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
processor.setEntryPoint(epoint); processor.setEntryPoint(epoint);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
@ -311,7 +308,7 @@ public class CaptchaChannelProcessorTests extends TestCase {
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl()); assertEquals(null, response.getRedirectedUrl());
Thread.sleep(100); waitFor(100);
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals("http://localhost:8000/demo/jcaptcha.do", response
@ -327,7 +324,7 @@ public class CaptchaChannelProcessorTests extends TestCase {
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl()); assertEquals(null, response.getRedirectedUrl());
Thread.sleep(100); waitFor(100);
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals("http://localhost:8000/demo/jcaptcha.do", response
@ -342,7 +339,7 @@ public class CaptchaChannelProcessorTests extends TestCase {
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl()); assertEquals(null, response.getRedirectedUrl());
Thread.sleep(100); waitFor(100);
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals("http://localhost:8000/demo/jcaptcha.do", response
@ -363,6 +360,8 @@ public class CaptchaChannelProcessorTests extends TestCase {
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
CaptchaEntryPoint epoint = new CaptchaEntryPoint(); CaptchaEntryPoint epoint = new CaptchaEntryPoint();
epoint.setCaptchaFormUrl("/jcaptcha.do"); epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
processor.setEntryPoint(epoint); processor.setEntryPoint(epoint);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
@ -403,7 +402,7 @@ public class CaptchaChannelProcessorTests extends TestCase {
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl()); assertEquals(null, response.getRedirectedUrl());
Thread.sleep(100); waitFor(100);
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals("http://localhost:8000/demo/jcaptcha.do", response
@ -436,7 +435,7 @@ public class CaptchaChannelProcessorTests extends TestCase {
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl()); assertEquals(null, response.getRedirectedUrl());
Thread.sleep(100); waitFor(100);
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals("http://localhost:8000/demo/jcaptcha.do", response
@ -446,7 +445,7 @@ public class CaptchaChannelProcessorTests extends TestCase {
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals("http://localhost:8000/demo/jcaptcha.do", response
.getRedirectedUrl()); .getRedirectedUrl());
} }
*/
public void testGettersSetters() { public void testGettersSetters() {
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
assertEquals("REQUIRES_HUMAN_AFTER_MAX_MILLIS", processor assertEquals("REQUIRES_HUMAN_AFTER_MAX_MILLIS", processor
@ -543,4 +542,11 @@ public class CaptchaChannelProcessorTests extends TestCase {
assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED"))); assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED")));
} }
private void waitFor(int time){
long start=System.currentTimeMillis();
while(System.currentTimeMillis()<start+time){
}
return;
}
} }

View File

@ -15,23 +15,21 @@
package net.sf.acegisecurity.captcha; package net.sf.acegisecurity.captcha;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase; import junit.framework.TestCase;
import net.sf.acegisecurity.MockPortResolver; import net.sf.acegisecurity.MockPortResolver;
import net.sf.acegisecurity.securechannel.RetryWithHttpEntryPoint;
import net.sf.acegisecurity.util.PortMapperImpl; import net.sf.acegisecurity.util.PortMapperImpl;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/** /**
* Tests {@link RetryWithHttpEntryPoint}. * Tests {@link CaptchaEntryPoint}.
* *
* @author Ben Alex * @author marc antoine Garrigue
* @version $Id: RetryWithHttpEntryPointTests.java,v 1.4 2005/04/11 01:07:02 * @version $Id$
* luke_t Exp $
*/ */
public class CaptchaEntryPointTests extends TestCase { public class CaptchaEntryPointTests extends TestCase {
// ~ Methods // ~ Methods
@ -96,13 +94,13 @@ public class CaptchaEntryPointTests extends TestCase {
assertTrue(ep.getPortMapper() != null); assertTrue(ep.getPortMapper() != null);
assertTrue(ep.getPortResolver() != null); assertTrue(ep.getPortResolver() != null);
assertEquals("originalRequest", ep.getOriginalRequestParameterName()); assertEquals("original_requestUrl", ep.getOriginalRequestUrlParameterName());
ep.setOriginalRequestParameterName("Z"); ep.setOriginalRequestUrlParameterName("Z");
assertEquals("Z", ep.getOriginalRequestParameterName()); assertEquals("Z", ep.getOriginalRequestUrlParameterName());
assertEquals(false, ep.isIncludeOriginalRequest());
ep.setIncludeOriginalRequest(true);
assertEquals(true, ep.isIncludeOriginalRequest()); assertEquals(true, ep.isIncludeOriginalRequest());
ep.setIncludeOriginalRequest(false);
assertEquals(false, ep.isIncludeOriginalRequest());
assertEquals(false, ep.isOutsideWebApp()); assertEquals(false, ep.isOutsideWebApp());
ep.setOutsideWebApp(true); ep.setOutsideWebApp(true);
@ -117,6 +115,7 @@ public class CaptchaEntryPointTests extends TestCase {
public void testHttpsOperationFromOriginalHttpUrl() throws Exception { public void testHttpsOperationFromOriginalHttpUrl() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path"); request.setRequestURI("/some_path");
request.setScheme("http"); request.setScheme("http");
request.setServerName("www.example.com"); request.setServerName("www.example.com");
@ -126,6 +125,7 @@ public class CaptchaEntryPointTests extends TestCase {
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
CaptchaEntryPoint ep = new CaptchaEntryPoint(); CaptchaEntryPoint ep = new CaptchaEntryPoint();
ep.setIncludeOriginalRequest(false);
ep.setCaptchaFormUrl("/hello"); ep.setCaptchaFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl()); ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true); ep.setForceHttps(true);
@ -163,6 +163,8 @@ public class CaptchaEntryPointTests extends TestCase {
ep.setForceHttps(true); ep.setForceHttps(true);
ep.setPortMapper(portMapper); ep.setPortMapper(portMapper);
ep.setPortResolver(new MockPortResolver(8888, 9999)); ep.setPortResolver(new MockPortResolver(8888, 9999));
ep.setIncludeOriginalRequest(false);
ep.afterPropertiesSet(); ep.afterPropertiesSet();
ep.commence(request, response); ep.commence(request, response);
@ -172,6 +174,7 @@ public class CaptchaEntryPointTests extends TestCase {
public void testHttpsOperationFromOriginalHttpsUrl() throws Exception { public void testHttpsOperationFromOriginalHttpsUrl() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path"); request.setRequestURI("/some_path");
request.setScheme("https"); request.setScheme("https");
request.setServerName("www.example.com"); request.setServerName("www.example.com");
@ -181,6 +184,7 @@ public class CaptchaEntryPointTests extends TestCase {
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
CaptchaEntryPoint ep = new CaptchaEntryPoint(); CaptchaEntryPoint ep = new CaptchaEntryPoint();
ep.setIncludeOriginalRequest(false);
ep.setCaptchaFormUrl("/hello"); ep.setCaptchaFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl()); ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true); ep.setForceHttps(true);
@ -206,6 +210,8 @@ public class CaptchaEntryPointTests extends TestCase {
ep.setPortMapper(new PortMapperImpl()); ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443)); ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet(); ep.afterPropertiesSet();
ep.setIncludeOriginalRequest(false);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path"); request.setRequestURI("/some_path");
@ -230,6 +236,8 @@ public class CaptchaEntryPointTests extends TestCase {
ep.setPortMapper(new PortMapperImpl()); ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8888, 1234)); ep.setPortResolver(new MockPortResolver(8888, 1234));
ep.setForceHttps(true); ep.setForceHttps(true);
ep.setIncludeOriginalRequest(false);
ep.afterPropertiesSet(); ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
@ -264,6 +272,7 @@ public class CaptchaEntryPointTests extends TestCase {
ep.afterPropertiesSet(); ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("post");
request.setRequestURI("/some_path"); request.setRequestURI("/some_path");
request.setScheme("http"); request.setScheme("http");
request.setServerName("www.example.com"); request.setServerName("www.example.com");
@ -277,7 +286,9 @@ public class CaptchaEntryPointTests extends TestCase {
ep.afterPropertiesSet(); ep.afterPropertiesSet();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"http://www.example.com:8888/hello?originalRequest=http://www.example.com:8888/some_path", "http://www.example.com:8888/hello?original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8")
+ "&original_request_method=post",
response.getRedirectedUrl()); response.getRedirectedUrl());
// test the query params // test the query params
@ -285,16 +296,24 @@ public class CaptchaEntryPointTests extends TestCase {
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"http://www.example.com:8888/hello?originalRequest=http://www.example.com:8888/some_path?name=value", "http://www.example.com:8888/hello?original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8")
+ "&original_request_method=post",
response.getRedirectedUrl()); response.getRedirectedUrl());
// test the multiple query params // test the multiple query params
ep.setIncludeOriginalParameters(true);
request.addParameter("name", "value"); request.addParameter("name", "value");
request.addParameter("name1", "value2"); request.addParameter("name1", "value2");
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"http://www.example.com:8888/hello?originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2", "http://www.example.com:8888/hello?original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8")
+ "&original_request_method=post"
+ "&original_request_parameters="
+ URLEncoder.encode("name@@value;;name1@@value2", "UTF-8"),
response.getRedirectedUrl()); response.getRedirectedUrl());
// test add parameter to captcha form url?? // test add parameter to captcha form url??
@ -303,7 +322,10 @@ public class CaptchaEntryPointTests extends TestCase {
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"http://www.example.com:8888/hello?toto=titi&originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2", "http://www.example.com:8888/hello?toto=titi&original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8")
+ "&original_request_method=post" + "&original_request_parameters="
+ URLEncoder.encode("name@@value;;name1@@value2", "UTF-8"),
response.getRedirectedUrl()); response.getRedirectedUrl());
// with forcing!!! // with forcing!!!
@ -311,7 +333,11 @@ public class CaptchaEntryPointTests extends TestCase {
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"https://www.example.com:1234/hello?toto=titi&originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2", "https://www.example.com:1234/hello?toto=titi&original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") +
"&original_request_method=post"
+ "&original_request_parameters="
+ URLEncoder.encode("name@@value;;name1@@value2", "UTF-8"),
response.getRedirectedUrl()); response.getRedirectedUrl());
} }
@ -333,6 +359,7 @@ public class CaptchaEntryPointTests extends TestCase {
request.setRequestURI("/some_path"); request.setRequestURI("/some_path");
request.setScheme("http"); request.setScheme("http");
request.setServerName("www.example.com"); request.setServerName("www.example.com");
request.setMethod("post");
// request.setContextPath("/bigWebApp"); // request.setContextPath("/bigWebApp");
// TODO correct this when the getRequestUrl from mock works... // TODO correct this when the getRequestUrl from mock works...
@ -343,7 +370,10 @@ public class CaptchaEntryPointTests extends TestCase {
ep.afterPropertiesSet(); ep.afterPropertiesSet();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"https://www.jcaptcha.net/dotest/?originalRequest=http://www.example.com:8888/some_path", "https://www.jcaptcha.net/dotest/?original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8")
+ "&original_request_method=post"
,
response.getRedirectedUrl()); response.getRedirectedUrl());
// test the query params // test the query params
@ -351,16 +381,23 @@ public class CaptchaEntryPointTests extends TestCase {
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"https://www.jcaptcha.net/dotest/?originalRequest=http://www.example.com:8888/some_path?name=value", "https://www.jcaptcha.net/dotest/?original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") +
"&original_request_method=post",
response.getRedirectedUrl()); response.getRedirectedUrl());
// test the multiple query params // test the multiple query params
ep.setIncludeOriginalParameters(true);
request.addParameter("name", "value"); request.addParameter("name", "value");
request.addParameter("name1", "value2"); request.addParameter("name1", "value2");
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"https://www.jcaptcha.net/dotest/?originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2", "https://www.jcaptcha.net/dotest/?original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8")
+ "&original_request_method=post"
+ "&original_request_parameters="
+ URLEncoder.encode("name@@value;;name1@@value2", "UTF-8"),
response.getRedirectedUrl()); response.getRedirectedUrl());
// test add parameter to captcha form url?? // test add parameter to captcha form url??
@ -369,7 +406,11 @@ public class CaptchaEntryPointTests extends TestCase {
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"https://www.jcaptcha.net/dotest/?toto=titi&originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2", "https://www.jcaptcha.net/dotest/?toto=titi&original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") +
"&original_request_method=post"
+ "&original_request_parameters="
+ URLEncoder.encode("name@@value;;name1@@value2", "UTF-8"),
response.getRedirectedUrl()); response.getRedirectedUrl());
// with forcing!!! // with forcing!!!
@ -377,7 +418,11 @@ public class CaptchaEntryPointTests extends TestCase {
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
ep.commence(request, response); ep.commence(request, response);
assertEquals( assertEquals(
"https://www.jcaptcha.net/dotest/?toto=titi&originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2", "https://www.jcaptcha.net/dotest/?toto=titi&original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") +
"&original_request_method=post"
+ "&original_request_parameters="
+ URLEncoder.encode("name@@value;;name1@@value2", "UTF-8"),
response.getRedirectedUrl()); response.getRedirectedUrl());
} }

View File

@ -1,7 +1,28 @@
/* 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; package net.sf.acegisecurity.captcha;
import net.sf.acegisecurity.context.SecurityContextImplTests; import net.sf.acegisecurity.context.SecurityContextImplTests;
/**
* Tests {@link CaptchaSecurityContextImpl}.
*
* @author marc antoine Garrigue
* @version $Id$
*/
public class CaptchaSecurityContextImplTests extends SecurityContextImplTests { public class CaptchaSecurityContextImplTests extends SecurityContextImplTests {
public void testDefaultValues() { public void testDefaultValues() {

View File

@ -1,11 +1,31 @@
/* 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; package net.sf.acegisecurity.captcha;
import junit.framework.TestCase; import junit.framework.TestCase;
import net.sf.acegisecurity.context.SecurityContextHolder; import net.sf.acegisecurity.context.SecurityContextHolder;
import net.sf.acegisecurity.util.MockFilterChain; import net.sf.acegisecurity.util.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
/**
* Tests {@link CaptchaValidationProcessingFilter}.
*
* @author marc antoine Garrigue
* @version $Id$
*/
public class CaptchaValidationProcessingFilterTests extends TestCase { public class CaptchaValidationProcessingFilterTests extends TestCase {
/* /*
@ -21,8 +41,19 @@ public class CaptchaValidationProcessingFilterTests extends TestCase {
IllegalArgumentException.class.isAssignableFrom(e IllegalArgumentException.class.isAssignableFrom(e
.getClass())); .getClass()));
} }
filter.setCaptchaService(new MockCaptchaServiceProxy()); filter.setCaptchaService(new MockCaptchaServiceProxy());
filter.afterPropertiesSet(); 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()));
}
} }
@ -60,12 +91,13 @@ public class CaptchaValidationProcessingFilterTests extends TestCase {
SecurityContextHolder.setContext(context); SecurityContextHolder.setContext(context);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request
.addParameter(
CaptchaValidationProcessingFilter.CAPTCHA_VALIDATION_SECURITY_PARAMETER_KEY,
"");
CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter(); CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter();
request
.addParameter(
filter.getCaptchaValidationParameter(),
"");
MockCaptchaServiceProxy service = new MockCaptchaServiceProxy(); MockCaptchaServiceProxy service = new MockCaptchaServiceProxy();
MockFilterChain chain = new MockFilterChain(true); MockFilterChain chain = new MockFilterChain(true);
filter.setCaptchaService(service); filter.setCaptchaService(service);

View File

@ -15,15 +15,17 @@
package net.sf.acegisecurity.captcha; package net.sf.acegisecurity.captcha;
import javax.servlet.ServletRequest; /**
* @author marc antoine Garrigue
* @version $Id$
*/
public class MockCaptchaServiceProxy implements CaptchaServiceProxy { 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) { public boolean validateReponseForId(String id, Object response) {
hasBeenCalled = true; hasBeenCalled = true;
return valid; return valid;