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,7 +158,10 @@ public class CaptchaChannelProcessor implements ChannelProcessor,
private String requiresHumanAfterMaxMillisKeyword = "REQUIRES_HUMAN_AFTER_MAX_MILLIS"; private String requiresHumanAfterMaxMillisKeyword = "REQUIRES_HUMAN_AFTER_MAX_MILLIS";
private ChannelEntryPoint entryPoint; private String keywordPrefix = "";
private ChannelEntryPoint entryPoint;
private int maxRequestsBeforeReTest = -1; private int maxRequestsBeforeReTest = -1;
@ -166,7 +169,15 @@ public class CaptchaChannelProcessor implements ChannelProcessor,
private long maxMillisBeforeReTest = -1; 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; return requiresHumanAfterMaxMillisKeyword;
} }
@ -227,28 +238,21 @@ 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;
.getContext(); context = (CaptchaSecurityContext) SecurityContextHolder
.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) {
logger logger
@ -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,274 +14,365 @@
*/ */
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$
*/ */
public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean { public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
// ~ Static fields/initializers // ~ Static fields/initializers
// ============================================= // =============================================
private static final Log logger = LogFactory private static final Log logger = LogFactory
.getLog(CaptchaEntryPoint.class); .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 = ";;";
// ================================================================
/** private String originalRequestMethodParameterName = "original_request_method";
* 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
* <code>https</code>, then
*
* @param forceHttps
*/
public void setForceHttps(boolean forceHttps) {
this.forceHttps = forceHttps;
}
public boolean getForceHttps() { private String urlEncodingCharset = "UTF-8";
return forceHttps;
}
/** private boolean isOutsideWebApp = false;
* The URL where the <code>CaptchaProcessingFilter</code> login page can
* be found. Should be relative to the web-app context path, and include a
* leading <code>/</code>
*
* @param captchaFormUrl
*/
public void setCaptchaFormUrl(String loginFormUrl) {
this.captchaFormUrl = loginFormUrl;
}
/** private boolean includeOriginalRequest = true;
* @return the captcha test page to redirect to.
*/
public String getCaptchaFormUrl() {
return captchaFormUrl;
}
public void setPortMapper(PortMapper portMapper) { private boolean includeOriginalParameters = false;
this.portMapper = portMapper;
}
public PortMapper getPortMapper() { // ~ Methods
return portMapper; // ================================================================
}
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 <code>https</code>,
* then
*/
public void setForceHttps(boolean forceHttps) {
this.forceHttps = forceHttps;
}
public PortResolver getPortResolver() { public boolean getForceHttps() {
return portResolver; return forceHttps;
} }
public boolean isOutsideWebApp() { /**
return isOutsideWebApp; * The URL where the <code>CaptchaProcessingFilter</code> login page can be found. Should be relative to the web-app
} * context path, and include a leading <code>/</code>
*/
public void setCaptchaFormUrl(String captchaFormUrl) {
this.captchaFormUrl = captchaFormUrl;
}
/** /**
* if set to true, the {@link #commence(ServletRequest, ServletResponse)} * @return the captcha test page to redirect to.
* method uses the {@link #getCaptchaFormUrl()} as a complete URL, else it */
* as a 'inside WebApp' path. public String getCaptchaFormUrl() {
* return captchaFormUrl;
* @param isOutsideWebApp }
*/
public void setOutsideWebApp(boolean isOutsideWebApp) {
this.isOutsideWebApp = isOutsideWebApp;
}
public String getOriginalRequestParameterName() { public void setPortMapper(PortMapper portMapper) {
return originalRequestParameterName; this.portMapper = portMapper;
} }
/** public PortMapper getPortMapper() {
* sets the parameter under which the original request url will be appended return portMapper;
* to the redirect url (only if {@link #isIncludeOriginalRequest()}==true). }
*
* @param originalRequestParameterName
*/
public void setOriginalRequestParameterName(
String originalRequestParameterName) {
this.originalRequestParameterName = originalRequestParameterName;
}
public boolean isIncludeOriginalRequest() { public void setPortResolver(PortResolver portResolver) {
return includeOriginalRequest; this.portResolver = portResolver;
} }
/** public PortResolver getPortResolver() {
* If set to true, the original request url will be appended to the redirect return portResolver;
* url using the {@link #getOriginalRequestParameterName()}. }
*
* @param includeOriginalRequest
*/
public void setIncludeOriginalRequest(boolean includeOriginalRequest) {
this.includeOriginalRequest = includeOriginalRequest;
}
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) public boolean isOutsideWebApp() {
throws IOException, ServletException { return isOutsideWebApp;
StringBuffer redirectUrl = new StringBuffer(); }
HttpServletRequest req = (HttpServletRequest) request;
if (isOutsideWebApp) {
redirectUrl = redirectUrl.append(captchaFormUrl);
} else {
buildInternalRedirect(redirectUrl, req);
}
if (includeOriginalRequest) { public String getOriginalRequestUrlParameterName() {
includeOriginalRequest(redirectUrl, req); return originalRequestUrlParameterName;
} }
// add post parameter? TODO?
if (logger.isDebugEnabled()) {
logger.debug("Redirecting to: " + redirectUrl);
}
((HttpServletResponse) response) public void setOriginalRequestUrlParameterName(String originalRequestUrlParameterName) {
.sendRedirect(((HttpServletResponse) response) this.originalRequestUrlParameterName = originalRequestUrlParameterName;
.encodeRedirectURL(redirectUrl.toString())); }
}
private void includeOriginalRequest(StringBuffer redirectUrl, public String getOriginalRequestParametersParameterName() {
HttpServletRequest req) { return originalRequestParametersParameterName;
// 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 void setOriginalRequestParametersParameterName(String originalRequestParametersParameterName) {
this.originalRequestParametersParameterName = originalRequestParametersParameterName;
}
private void buildInternalRedirect(StringBuffer redirectUrl, public String getOriginalRequestParametersNameValueSeparator() {
HttpServletRequest req) { return originalRequestParametersNameValueSeparator;
// construct it }
StringBuffer simpleRedirect = new StringBuffer();
String scheme = req.getScheme(); public void setOriginalRequestParametersNameValueSeparator(String originalRequestParametersNameValueSeparator) {
String serverName = req.getServerName(); this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator;
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); public String getOriginalRequestParametersSeparator() {
simpleRedirect.append("://"); return originalRequestParametersSeparator;
simpleRedirect.append(serverName); }
if (includePort) {
simpleRedirect.append(":");
simpleRedirect.append(serverPort);
}
simpleRedirect.append(contextPath);
simpleRedirect.append(captchaFormUrl);
if (forceHttps && req.getScheme().equals("http")) { public void setOriginalRequestParametersSeparator(String originalRequestParametersSeparator) {
Integer httpPort = new Integer(portResolver.getServerPort(req)); this.originalRequestParametersSeparator = originalRequestParametersSeparator;
Integer httpsPort = (Integer) portMapper.lookupHttpsPort(httpPort); }
if (httpsPort != null) { public String getOriginalRequestMethodParameterName() {
if (httpsPort.intValue() == 443) { return originalRequestMethodParameterName;
includePort = false; }
} else {
includePort = true;
}
redirectUrl.append("https://"); public void setOriginalRequestMethodParameterName(String originalRequestMethodParameterName) {
redirectUrl.append(serverName); this.originalRequestMethodParameterName = originalRequestMethodParameterName;
if (includePort) { }
redirectUrl.append(":");
redirectUrl.append(httpsPort); public String getUrlEncodingCharset() {
} return urlEncodingCharset;
redirectUrl.append(contextPath); }
redirectUrl.append(captchaFormUrl);
} else { public void setUrlEncodingCharset(String urlEncodingCharset) {
redirectUrl.append(simpleRedirect); this.urlEncodingCharset = urlEncodingCharset;
} }
} else {
redirectUrl.append(simpleRedirect); /**
} * 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);
}
}
} }

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,112 +15,128 @@
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$
*/ */
public class CaptchaValidationProcessingFilter implements InitializingBean, 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
.getLog(CaptchaValidationProcessingFilter.class);
protected static final Log logger = LogFactory // ~ Instance fields
.getLog(HttpSessionContextIntegrationFilter.class); // ========================================================
// ~ Instance fields private CaptchaServiceProxy captchaService;
// ======================================================== private String captchaValidationParameter = "_captcha_parameter";
private CaptchaServiceProxy captchaService;
// ~ Methods // ~ Methods
// ================================================================ // ================================================================
public CaptchaServiceProxy getCaptchaService() { public CaptchaServiceProxy getCaptchaService() {
return captchaService; return captchaService;
} }
public void setCaptchaService(CaptchaServiceProxy captchaService) { public void setCaptchaService(CaptchaServiceProxy captchaService) {
this.captchaService = captchaService; this.captchaService = captchaService;
} }
public void afterPropertiesSet() throws Exception {
if (this.captchaService == null) {
throw new IllegalArgumentException(
"CaptchaServiceProxy must be defined ");
}
}
/** public String getCaptchaValidationParameter() {
* Does nothing. We use IoC container lifecycle services instead. return captchaValidationParameter;
*/ }
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, public void setCaptchaValidationParameter(String captchaValidationParameter) {
FilterChain chain) throws IOException, ServletException { this.captchaValidationParameter = captchaValidationParameter;
}
if ((request != null) public void afterPropertiesSet() throws Exception {
&& (request if (this.captchaService == null) {
.getParameter(CAPTCHA_VALIDATION_SECURITY_PARAMETER_KEY) != null)) { throw new IllegalArgumentException(
logger.debug("captcha validation parameter not found, do nothing"); "CaptchaServiceProxy must be defined ");
// validate the request against CaptchaServiceProxy }
boolean valid = false; 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); * Does nothing. We use IoC container lifecycle services instead.
logger.debug("captchaServiceProxy says : request is valid =" */
+ valid); public void destroy() {
if (valid) { }
logger.debug("update the context");
((CaptchaSecurityContext) SecurityContextHolder.getContext())
.setHuman();
} 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 found");
logger.debug("captcha validation parameter not found, do nothing"); // validate the request against CaptchaServiceProxy
} boolean valid = false;
logger.debug("chain...");
chain.doFilter(request, response);
}
/** logger.debug("try to validate");
* Does nothing. We use IoC container lifecycle services instead.
* //get session
* @param filterConfig HttpSession session = ((HttpServletRequest) request).getSession();
* ignored if (session != null) {
*
* @throws ServletException String id = session.getId();
* ignored valid = this.captchaService.validateReponseForId(id,
*/ captcha_reponse);
public void init(FilterConfig filterConfig) throws ServletException { 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 {
}
} }

View File

@ -119,7 +119,7 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
} }
ApplicationContext getContext() { 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; return context;
} }
} }

View File

@ -15,532 +15,538 @@
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$
*/ */
public class CaptchaChannelProcessorTests extends TestCase { public class CaptchaChannelProcessorTests extends TestCase {
public void testDecideRequestsFirstTestRequests() throws Exception { public void testDecideRequestsFirstTestRequests() throws Exception {
ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE"));
cad.addConfigAttribute(new SecurityConfig( cad.addConfigAttribute(new SecurityConfig(
"REQUIRES_HUMAN_AFTER_MAX_REQUESTS")); "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);
response = decideWithNewResponse(cad, processor, request); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
assertEquals(null, response.getRedirectedUrl()); SecurityContextHolder.setContext(context);
response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response
.getRedirectedUrl());
}
public void testDecideRequestsFirstTestMillis() throws Exception { CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); CaptchaEntryPoint epoint = new CaptchaEntryPoint();
cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); epoint.setCaptchaFormUrl("/jcaptcha.do");
cad.addConfigAttribute(new SecurityConfig( epoint.setIncludeOriginalRequest(false);
"REQUIRES_HUMAN_AFTER_MAX_MILLIS"));
CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); processor.setEntryPoint(epoint);
SecurityContextHolder.setContext(context);
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); MockHttpServletRequest request = new MockHttpServletRequest();
CaptchaEntryPoint epoint = new CaptchaEntryPoint(); request.setQueryString("info=true");
epoint.setCaptchaFormUrl("/jcaptcha.do"); request.setServerName("localhost");
processor.setEntryPoint(epoint); request.setContextPath("/demo");
request.setServletPath("/restricted");
request.setScheme("http");
request.setServerPort(8000);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse();
request.setQueryString("info=true"); MockFilterChain chain = new MockFilterChain();
request.setServerName("localhost"); FilterInvocation fi = new FilterInvocation(request, response, chain);
request.setContextPath("/demo");
request.setServletPath("/restricted"); processor.decide(fi, cad);
request.setScheme("http"); assertEquals(response.getRedirectedUrl(),
request.setServerPort(8000); "http://localhost:8000/demo/jcaptcha.do");
processor.setMaxRequestsBeforeFirstTest(1);
MockHttpServletResponse response = new MockHttpServletResponse(); response = decideWithNewResponse(cad, processor, request);
MockFilterChain chain = new MockFilterChain(); assertEquals(response.getRedirectedUrl(), null);
FilterInvocation fi = new FilterInvocation(request, response, chain);
processor.decide(fi, cad); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals(response.getRedirectedUrl(),
.getRedirectedUrl()); "http://localhost:8000/demo/jcaptcha.do");
processor.setMaxRequestsBeforeFirstTest(1); processor.setMaxRequestsBeforeFirstTest(2);
processor.setMaxMillisBeforeReTest(0);
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl()); assertEquals(null, response.getRedirectedUrl());
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
.getRedirectedUrl()); .getRedirectedUrl());
}
processor.setMaxRequestsBeforeFirstTest(2); public void testDecideRequestsFirstTestMillis() throws Exception {
processor.setMaxRequestsBeforeReTest(0); 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); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
assertEquals(null, response.getRedirectedUrl()); SecurityContextHolder.setContext(context);
response = decideWithNewResponse(cad, processor, request); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
assertEquals("http://localhost:8000/demo/jcaptcha.do", response CaptchaEntryPoint epoint = new CaptchaEntryPoint();
.getRedirectedUrl()); epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
}
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); processor.setEntryPoint(epoint);
assertEquals(null, response.getRedirectedUrl());
response = decideWithNewResponse(cad, processor, request); MockHttpServletRequest request = new MockHttpServletRequest();
assertEquals(null, response.getRedirectedUrl()); request.setQueryString("info=true");
request.setServerName("localhost");
request.setContextPath("/demo");
request.setServletPath("/restricted");
request.setScheme("http");
request.setServerPort(8000);
response = decideWithNewResponse(cad, processor, request); MockHttpServletResponse response = new MockHttpServletResponse();
assertEquals("http://localhost:8000/demo/jcaptcha.do", response MockFilterChain chain = new MockFilterChain();
.getRedirectedUrl()); FilterInvocation fi = new FilterInvocation(request, response, chain);
}
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 { processor.decide(fi, cad);
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
processor.setEntryPoint(new CaptchaEntryPoint()); .getRedirectedUrl());
processor.afterPropertiesSet();
try { processor.setMaxRequestsBeforeFirstTest(1);
processor.decide(null, null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
/*
// TODO: Re-enable these tests. response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl());
Commented out by Ben Alex on 19 Sep 05 as the Thread.sleep(100) approach to simulating response = decideWithNewResponse(cad, processor, request);
request age caused intermittent problems. An alternative approach should be used assertEquals("http://localhost:8000/demo/jcaptcha.do", response
instead, such as (a) modifying the CaptchaSecurityContextImpl (why not make a package .getRedirectedUrl());
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 { processor.setMaxRequestsBeforeFirstTest(2);
ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); processor.setMaxRequestsBeforeReTest(0);
cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE"));
cad.addConfigAttribute(new SecurityConfig(
"REQUIRES_HUMAN_AFTER_MAX_MILLIS"));
CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); response = decideWithNewResponse(cad, processor, request);
SecurityContextHolder.setContext(context); assertEquals(null, response.getRedirectedUrl());
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); response = decideWithNewResponse(cad, processor, request);
CaptchaEntryPoint epoint = new CaptchaEntryPoint(); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
epoint.setCaptchaFormUrl("/jcaptcha.do"); .getRedirectedUrl());
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); 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); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
assertEquals("http://localhost:8000/demo/jcaptcha.do", response SecurityContextHolder.setContext(context);
.getRedirectedUrl());
context.setHuman(); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
SecurityContextHolder.setContext(context); CaptchaEntryPoint epoint = new CaptchaEntryPoint();
epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
processor.setEntryPoint(epoint);
response = decideWithNewResponse(cad, processor, request); MockHttpServletRequest request = new MockHttpServletRequest();
assertEquals(null, response.getRedirectedUrl()); request.setQueryString("info=true");
request.setServerName("localhost");
request.setContextPath("/demo");
request.setServletPath("/restricted");
request.setScheme("http");
request.setServerPort(8000);
response = decideWithNewResponse(cad, processor, request); MockHttpServletResponse response = new MockHttpServletResponse();
assertEquals(null, response.getRedirectedUrl()); MockFilterChain chain = new MockFilterChain();
FilterInvocation fi = new FilterInvocation(request, response, chain);
processor.decide(fi, cad);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response
.getRedirectedUrl());
Thread.sleep(100); 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); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals(null, response.getRedirectedUrl());
.getRedirectedUrl());
}
public void testDecideBoth() throws Exception { response = decideWithNewResponse(cad, processor, request);
ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); .getRedirectedUrl());
cad.addConfigAttribute(new SecurityConfig(
"REQUIRES_HUMAN_AFTER_MAX_MILLIS"));
cad.addConfigAttribute(new SecurityConfig(
"REQUIRES_HUMAN_AFTER_MAX_REQUESTS"));
CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); processor.setMaxMillisBeforeReTest(0);
SecurityContextHolder.setContext(context); context.setHuman();
SecurityContextHolder.setContext(context);
response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl());
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); response = decideWithNewResponse(cad, processor, request);
CaptchaEntryPoint epoint = new CaptchaEntryPoint(); assertEquals(null, response.getRedirectedUrl());
epoint.setCaptchaFormUrl("/jcaptcha.do");
processor.setEntryPoint(epoint);
MockHttpServletRequest request = new MockHttpServletRequest(); response = decideWithNewResponse(cad, processor, request);
request.setQueryString("info=true"); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
request.setServerName("localhost"); .getRedirectedUrl());
request.setContextPath("/demo");
request.setServletPath("/restricted");
request.setScheme("http");
request.setServerPort(8000);
MockHttpServletResponse response = new MockHttpServletResponse(); context.setHuman();
MockFilterChain chain = new MockFilterChain(); SecurityContextHolder.setContext(context);
FilterInvocation fi = new FilterInvocation(request, response, chain);
processor.decide(fi, cad); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals(null, response.getRedirectedUrl());
.getRedirectedUrl());
processor.setMaxRequestsBeforeFirstTest(1); response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl());
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals(response.getRedirectedUrl(), null); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
.getRedirectedUrl());
}
response = decideWithNewResponse(cad, processor, request); private MockHttpServletResponse decideWithNewResponse(
assertEquals("http://localhost:8000/demo/jcaptcha.do", response ConfigAttributeDefinition cad, CaptchaChannelProcessor processor,
.getRedirectedUrl()); 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;
}
processor.setMaxMillisBeforeReTest(100); public void testDecideRejectsNulls() throws Exception {
processor.setMaxRequestsBeforeReTest(2); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
processor.setEntryPoint(new CaptchaEntryPoint());
processor.afterPropertiesSet();
response = decideWithNewResponse(cad, processor, request); try {
assertEquals("http://localhost:8000/demo/jcaptcha.do", response processor.decide(null, null);
.getRedirectedUrl()); fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
context.setHuman(); public void testDecideMillis() throws Exception {
SecurityContextHolder.setContext(context); 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); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
assertEquals(null, response.getRedirectedUrl()); SecurityContextHolder.setContext(context);
Thread.sleep(100); CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
CaptchaEntryPoint epoint = new CaptchaEntryPoint();
epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
response = decideWithNewResponse(cad, processor, request); processor.setEntryPoint(epoint);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response
.getRedirectedUrl());
response = decideWithNewResponse(cad, processor, request); MockHttpServletRequest request = new MockHttpServletRequest();
assertEquals("http://localhost:8000/demo/jcaptcha.do", response request.setQueryString("info=true");
.getRedirectedUrl()); request.setServerName("localhost");
request.setContextPath("/demo");
request.setServletPath("/restricted");
request.setScheme("http");
request.setServerPort(8000);
context.setHuman(); MockHttpServletResponse response = new MockHttpServletResponse();
SecurityContextHolder.setContext(context); MockFilterChain chain = new MockFilterChain();
FilterInvocation fi = new FilterInvocation(request, response, chain);
response = decideWithNewResponse(cad, processor, request); processor.decide(fi, cad);
assertEquals(null, response.getRedirectedUrl()); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
.getRedirectedUrl());
response = decideWithNewResponse(cad, processor, request); processor.setMaxRequestsBeforeFirstTest(1);
assertEquals(null, response.getRedirectedUrl());
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals(response.getRedirectedUrl(), null);
.getRedirectedUrl());
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
.getRedirectedUrl()); .getRedirectedUrl());
context.setHuman(); processor.setMaxMillisBeforeReTest(100);
SecurityContextHolder.setContext(context);
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals(null, response.getRedirectedUrl()); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
.getRedirectedUrl());
Thread.sleep(100); context.setHuman();
SecurityContextHolder.setContext(context);
response = decideWithNewResponse(cad, processor, request); response = decideWithNewResponse(cad, processor, request);
assertEquals("http://localhost:8000/demo/jcaptcha.do", response assertEquals(null, response.getRedirectedUrl());
.getRedirectedUrl());
response = decideWithNewResponse(cad, processor, request); waitFor(100);
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 response = decideWithNewResponse(cad, processor, request);
.getRequiresHumanAfterMaxRequestsKeyword()); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
processor.setRequiresHumanAfterMaxRequestsKeyword("Y"); .getRedirectedUrl());
assertEquals("Y", processor.getRequiresHumanAfterMaxRequestsKeyword());
assertEquals(0, processor.getMaxRequestsBeforeFirstTest()); processor.setMaxRequestsBeforeReTest(0);
processor.setMaxRequestsBeforeFirstTest(1); context.setHuman();
assertEquals(1, processor.getMaxRequestsBeforeFirstTest()); SecurityContextHolder.setContext(context);
assertEquals(-1, processor.getMaxRequestsBeforeReTest()); response = decideWithNewResponse(cad, processor, request);
processor.setMaxRequestsBeforeReTest(11); assertEquals(null, response.getRedirectedUrl());
assertEquals(11, processor.getMaxRequestsBeforeReTest());
assertEquals(-1, processor.getMaxMillisBeforeReTest()); response = decideWithNewResponse(cad, processor, request);
processor.setMaxMillisBeforeReTest(111); assertEquals(null, response.getRedirectedUrl());
assertEquals(111, processor.getMaxMillisBeforeReTest());
assertTrue(processor.getEntryPoint() == null); waitFor(100);
processor.setEntryPoint(new CaptchaEntryPoint());
assertTrue(processor.getEntryPoint() != null);
}
public void testMissingEntryPoint() throws Exception { response = decideWithNewResponse(cad, processor, request);
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
processor.setEntryPoint(null); .getRedirectedUrl());
try { context.setHuman();
processor.afterPropertiesSet(); SecurityContextHolder.setContext(context);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("entryPoint required", expected.getMessage());
}
}
public void testMissingKeyword() throws Exception { response = decideWithNewResponse(cad, processor, request);
CaptchaChannelProcessor processor = new CaptchaChannelProcessor(); assertEquals(null, response.getRedirectedUrl());
processor.setRequiresHumanAfterMaxMillisKeyword(null);
try { response = decideWithNewResponse(cad, processor, request);
processor.afterPropertiesSet(); assertEquals(null, response.getRedirectedUrl());
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
} waitFor(100);
processor.setRequiresHumanAfterMaxMillisKeyword("");
try { response = decideWithNewResponse(cad, processor, request);
processor.afterPropertiesSet(); assertEquals("http://localhost:8000/demo/jcaptcha.do", response
fail("Should have thrown IllegalArgumentException"); .getRedirectedUrl());
} catch (IllegalArgumentException expected) { }
} public void testDecideBoth() throws Exception {
processor.setRequiresHumanAfterMaxRequestsKeyword(""); 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"));
try { CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
processor.afterPropertiesSet(); SecurityContextHolder.setContext(context);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
} CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
CaptchaEntryPoint epoint = new CaptchaEntryPoint();
processor.setRequiresHumanAfterMaxRequestsKeyword(null); epoint.setCaptchaFormUrl("/jcaptcha.do");
epoint.setIncludeOriginalRequest(false);
try {
processor.afterPropertiesSet(); processor.setEntryPoint(epoint);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("info=true");
} request.setServerName("localhost");
request.setContextPath("/demo");
} request.setServletPath("/restricted");
request.setScheme("http");
public void testSupports() { request.setServerPort(8000);
CaptchaChannelProcessor processor = new CaptchaChannelProcessor();
assertTrue(processor.supports(new SecurityConfig(processor MockHttpServletResponse response = new MockHttpServletResponse();
.getRequiresHumanAfterMaxMillisKeyword()))); MockFilterChain chain = new MockFilterChain();
assertTrue(processor.supports(new SecurityConfig(processor FilterInvocation fi = new FilterInvocation(request, response, chain);
.getRequiresHumanAfterMaxRequestsKeyword())));
processor.decide(fi, cad);
assertTrue(processor.supports(new SecurityConfig( assertEquals("http://localhost:8000/demo/jcaptcha.do", response
"REQUIRES_HUMAN_AFTER_MAX_REQUESTS"))); .getRedirectedUrl());
assertTrue(processor.supports(new SecurityConfig(
"REQUIRES_HUMAN_AFTER_MAX_MILLIS"))); processor.setMaxRequestsBeforeFirstTest(1);
assertFalse(processor.supports(null)); response = decideWithNewResponse(cad, processor, request);
assertEquals(response.getRedirectedUrl(), null);
assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED")));
} 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()<start+time){
}
return;
}
} }

View File

@ -15,371 +15,416 @@
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
// ================================================================ // ================================================================
public final void setUp() throws Exception { public final void setUp() throws Exception {
super.setUp(); super.setUp();
} }
public static void main(String[] args) { public static void main(String[] args) {
junit.textui.TestRunner.run(CaptchaEntryPointTests.class); junit.textui.TestRunner.run(CaptchaEntryPointTests.class);
} }
public void testDetectsMissingCaptchaFormUrl() throws Exception { public void testDetectsMissingCaptchaFormUrl() throws Exception {
CaptchaEntryPoint ep = new CaptchaEntryPoint(); CaptchaEntryPoint ep = new CaptchaEntryPoint();
ep.setPortMapper(new PortMapperImpl()); ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443)); ep.setPortResolver(new MockPortResolver(80, 443));
try { try {
ep.afterPropertiesSet(); ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException"); fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertEquals("captchaFormUrl must be specified", expected assertEquals("captchaFormUrl must be specified", expected
.getMessage()); .getMessage());
} }
} }
public void testDetectsMissingPortMapper() throws Exception { public void testDetectsMissingPortMapper() throws Exception {
CaptchaEntryPoint ep = new CaptchaEntryPoint(); CaptchaEntryPoint ep = new CaptchaEntryPoint();
ep.setCaptchaFormUrl("xxx"); ep.setCaptchaFormUrl("xxx");
ep.setPortMapper(null); ep.setPortMapper(null);
try { try {
ep.afterPropertiesSet(); ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException"); fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertEquals("portMapper must be specified", expected.getMessage()); assertEquals("portMapper must be specified", expected.getMessage());
} }
} }
public void testDetectsMissingPortResolver() throws Exception { public void testDetectsMissingPortResolver() throws Exception {
CaptchaEntryPoint ep = new CaptchaEntryPoint(); CaptchaEntryPoint ep = new CaptchaEntryPoint();
ep.setCaptchaFormUrl("xxx"); ep.setCaptchaFormUrl("xxx");
ep.setPortResolver(null); ep.setPortResolver(null);
try { try {
ep.afterPropertiesSet(); ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException"); fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertEquals("portResolver must be specified", expected assertEquals("portResolver must be specified", expected
.getMessage()); .getMessage());
} }
} }
public void testGettersSetters() { public void testGettersSetters() {
CaptchaEntryPoint ep = new CaptchaEntryPoint(); CaptchaEntryPoint ep = new CaptchaEntryPoint();
ep.setCaptchaFormUrl("/hello"); ep.setCaptchaFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl()); ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8080, 8443)); ep.setPortResolver(new MockPortResolver(8080, 8443));
assertEquals("/hello", ep.getCaptchaFormUrl()); assertEquals("/hello", ep.getCaptchaFormUrl());
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()); assertEquals(true, ep.isIncludeOriginalRequest());
ep.setIncludeOriginalRequest(true); ep.setIncludeOriginalRequest(false);
assertEquals(true, ep.isIncludeOriginalRequest()); assertEquals(false, ep.isIncludeOriginalRequest());
assertEquals(false, ep.isOutsideWebApp()); assertEquals(false, ep.isOutsideWebApp());
ep.setOutsideWebApp(true); ep.setOutsideWebApp(true);
assertEquals(true, ep.isOutsideWebApp()); assertEquals(true, ep.isOutsideWebApp());
ep.setForceHttps(false); ep.setForceHttps(false);
assertFalse(ep.getForceHttps()); assertFalse(ep.getForceHttps());
ep.setForceHttps(true); ep.setForceHttps(true);
assertTrue(ep.getForceHttps()); assertTrue(ep.getForceHttps());
} }
public void testHttpsOperationFromOriginalHttpUrl() throws Exception { public void testHttpsOperationFromOriginalHttpUrl() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse(); request.setRequestURI("/some_path");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(80);
CaptchaEntryPoint ep = new CaptchaEntryPoint(); MockHttpServletResponse response = new MockHttpServletResponse();
ep.setCaptchaFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet();
ep.commence(request, response); CaptchaEntryPoint ep = new CaptchaEntryPoint();
assertEquals("https://www.example.com/bigWebApp/hello", response ep.setIncludeOriginalRequest(false);
.getRedirectedUrl()); ep.setCaptchaFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet();
request.setServerPort(8080); ep.commence(request, response);
response = new MockHttpServletResponse(); assertEquals("https://www.example.com/bigWebApp/hello", response
ep.setPortResolver(new MockPortResolver(8080, 8443)); .getRedirectedUrl());
ep.commence(request, response);
assertEquals("https://www.example.com:8443/bigWebApp/hello", response
.getRedirectedUrl());
// Now test an unusual custom HTTP:HTTPS is handled properly request.setServerPort(8080);
request.setServerPort(8888); response = new MockHttpServletResponse();
response = new MockHttpServletResponse(); ep.setPortResolver(new MockPortResolver(8080, 8443));
ep.commence(request, response); ep.commence(request, response);
assertEquals("https://www.example.com:8443/bigWebApp/hello", response assertEquals("https://www.example.com:8443/bigWebApp/hello", response
.getRedirectedUrl()); .getRedirectedUrl());
PortMapperImpl portMapper = new PortMapperImpl(); // Now test an unusual custom HTTP:HTTPS is handled properly
Map map = new HashMap(); request.setServerPort(8888);
map.put("8888", "9999"); response = new MockHttpServletResponse();
portMapper.setPortMappings(map); ep.commence(request, response);
response = new MockHttpServletResponse(); assertEquals("https://www.example.com:8443/bigWebApp/hello", response
.getRedirectedUrl());
ep = new CaptchaEntryPoint(); PortMapperImpl portMapper = new PortMapperImpl();
ep.setCaptchaFormUrl("/hello"); Map map = new HashMap();
ep.setPortMapper(new PortMapperImpl()); map.put("8888", "9999");
ep.setForceHttps(true); portMapper.setPortMappings(map);
ep.setPortMapper(portMapper); response = new MockHttpServletResponse();
ep.setPortResolver(new MockPortResolver(8888, 9999));
ep.afterPropertiesSet();
ep.commence(request, response); ep = new CaptchaEntryPoint();
assertEquals("https://www.example.com:9999/bigWebApp/hello", response ep.setCaptchaFormUrl("/hello");
.getRedirectedUrl()); ep.setPortMapper(new PortMapperImpl());
} ep.setForceHttps(true);
ep.setPortMapper(portMapper);
ep.setPortResolver(new MockPortResolver(8888, 9999));
ep.setIncludeOriginalRequest(false);
public void testHttpsOperationFromOriginalHttpsUrl() throws Exception { ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
request.setScheme("https");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(443);
MockHttpServletResponse response = new MockHttpServletResponse(); ep.commence(request, response);
assertEquals("https://www.example.com:9999/bigWebApp/hello", response
.getRedirectedUrl());
}
CaptchaEntryPoint ep = new CaptchaEntryPoint(); public void testHttpsOperationFromOriginalHttpsUrl() throws Exception {
ep.setCaptchaFormUrl("/hello"); MockHttpServletRequest request = new MockHttpServletRequest();
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet();
ep.commence(request, response); request.setRequestURI("/some_path");
assertEquals("https://www.example.com/bigWebApp/hello", response request.setScheme("https");
.getRedirectedUrl()); request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(443);
request.setServerPort(8443); MockHttpServletResponse response = new MockHttpServletResponse();
response = new MockHttpServletResponse();
ep.setPortResolver(new MockPortResolver(8080, 8443));
ep.commence(request, response);
assertEquals("https://www.example.com:8443/bigWebApp/hello", response
.getRedirectedUrl());
}
public void testNormalOperation() throws Exception { 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.setPortResolver(new MockPortResolver(80, 443)); ep.setForceHttps(true);
ep.afterPropertiesSet(); ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest(); ep.commence(request, response);
request.setRequestURI("/some_path"); assertEquals("https://www.example.com/bigWebApp/hello", response
request.setContextPath("/bigWebApp"); .getRedirectedUrl());
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse(); request.setServerPort(8443);
response = new MockHttpServletResponse();
ep.setPortResolver(new MockPortResolver(8080, 8443));
ep.commence(request, response);
assertEquals("https://www.example.com:8443/bigWebApp/hello", response
.getRedirectedUrl());
}
ep.afterPropertiesSet(); public void testNormalOperation() throws Exception {
ep.commence(request, response); CaptchaEntryPoint ep = new CaptchaEntryPoint();
assertEquals("http://www.example.com/bigWebApp/hello", response ep.setCaptchaFormUrl("/hello");
.getRedirectedUrl()); ep.setPortMapper(new PortMapperImpl());
} ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet();
ep.setIncludeOriginalRequest(false);
public void testOperationWhenHttpsRequestsButHttpsPortUnknown()
throws Exception {
CaptchaEntryPoint ep = new CaptchaEntryPoint();
ep.setCaptchaFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8888, 1234));
ep.setForceHttps(true);
ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path"); request.setRequestURI("/some_path");
request.setContextPath("/bigWebApp"); request.setContextPath("/bigWebApp");
request.setScheme("http"); request.setScheme("http");
request.setServerName("www.example.com"); request.setServerName("www.example.com");
request.setContextPath("/bigWebApp"); request.setContextPath("/bigWebApp");
request.setServerPort(8888); // NB: Port we can't resolve request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
ep.afterPropertiesSet(); ep.afterPropertiesSet();
ep.commence(request, response); ep.commence(request, response);
assertEquals("http://www.example.com/bigWebApp/hello", response
.getRedirectedUrl());
}
// Response doesn't switch to HTTPS, as we didn't know HTTP port 8888 to public void testOperationWhenHttpsRequestsButHttpsPortUnknown()
// HTTP port mapping throws Exception {
assertEquals("http://www.example.com:8888/bigWebApp/hello", response CaptchaEntryPoint ep = new CaptchaEntryPoint();
.getRedirectedUrl()); ep.setCaptchaFormUrl("/hello");
} ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8888, 1234));
ep.setForceHttps(true);
ep.setIncludeOriginalRequest(false);
public void testOperationWithOriginalRequestIncludes() throws Exception { ep.afterPropertiesSet();
CaptchaEntryPoint ep = new CaptchaEntryPoint();
ep.setCaptchaFormUrl("/hello");
PortMapperImpl mapper = new PortMapperImpl();
mapper.getTranslatedPortMappings().put(new Integer(8888),
new Integer(1234));
ep.setPortMapper(mapper);
ep.setPortResolver(new MockPortResolver(8888, 1234)); MockHttpServletRequest request = new MockHttpServletRequest();
ep.setIncludeOriginalRequest(true); request.setRequestURI("/some_path");
ep.afterPropertiesSet(); request.setContextPath("/bigWebApp");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(8888); // NB: Port we can't resolve
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse();
request.setRequestURI("/some_path");
request.setScheme("http");
request.setServerName("www.example.com");
// request.setContextPath("/bigWebApp");
// TODO correct this when the getRequestUrl from mock works...
request.setServerPort(8888); // NB: Port we can't resolve ep.afterPropertiesSet();
ep.commence(request, response);
MockHttpServletResponse response = new MockHttpServletResponse(); // Response doesn't switch to HTTPS, as we didn't know HTTP port 8888 to
// HTTP port mapping
assertEquals("http://www.example.com:8888/bigWebApp/hello", response
.getRedirectedUrl());
}
ep.afterPropertiesSet(); public void testOperationWithOriginalRequestIncludes() throws Exception {
ep.commence(request, response); CaptchaEntryPoint ep = new CaptchaEntryPoint();
assertEquals( ep.setCaptchaFormUrl("/hello");
"http://www.example.com:8888/hello?originalRequest=http://www.example.com:8888/some_path", PortMapperImpl mapper = new PortMapperImpl();
response.getRedirectedUrl()); mapper.getTranslatedPortMappings().put(new Integer(8888),
new Integer(1234));
ep.setPortMapper(mapper);
// test the query params ep.setPortResolver(new MockPortResolver(8888, 1234));
request.addParameter("name", "value"); ep.setIncludeOriginalRequest(true);
response = new MockHttpServletResponse(); ep.afterPropertiesSet();
ep.commence(request, response);
assertEquals(
"http://www.example.com:8888/hello?originalRequest=http://www.example.com:8888/some_path?name=value",
response.getRedirectedUrl());
// test the multiple query params MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("name", "value"); request.setMethod("post");
request.addParameter("name1", "value2"); request.setRequestURI("/some_path");
response = new MockHttpServletResponse(); request.setScheme("http");
ep.commence(request, response); request.setServerName("www.example.com");
assertEquals( // request.setContextPath("/bigWebApp");
"http://www.example.com:8888/hello?originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2", // TODO correct this when the getRequestUrl from mock works...
response.getRedirectedUrl());
// test add parameter to captcha form url?? request.setServerPort(8888); // NB: Port we can't resolve
ep.setCaptchaFormUrl("/hello?toto=titi"); MockHttpServletResponse response = new MockHttpServletResponse();
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"http://www.example.com:8888/hello?toto=titi&originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2",
response.getRedirectedUrl());
// with forcing!!! ep.afterPropertiesSet();
ep.setForceHttps(true); ep.commence(request, response);
response = new MockHttpServletResponse(); assertEquals(
ep.commence(request, response); "http://www.example.com:8888/hello?original_requestUrl="
assertEquals( + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8")
"https://www.example.com:1234/hello?toto=titi&originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2", + "&original_request_method=post",
response.getRedirectedUrl()); response.getRedirectedUrl());
} // test the query params
request.addParameter("name", "value");
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"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());
public void testOperationWithOutsideWebApp() throws Exception { // test the multiple query params
CaptchaEntryPoint ep = new CaptchaEntryPoint(); ep.setIncludeOriginalParameters(true);
ep.setCaptchaFormUrl("https://www.jcaptcha.net/dotest/");
PortMapperImpl mapper = new PortMapperImpl();
mapper.getTranslatedPortMappings().put(new Integer(8888),
new Integer(1234));
ep.setPortMapper(mapper);
ep.setPortResolver(new MockPortResolver(8888, 1234)); request.addParameter("name", "value");
ep.setIncludeOriginalRequest(true); request.addParameter("name1", "value2");
ep.setOutsideWebApp(true); response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"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());
ep.afterPropertiesSet(); // test add parameter to captcha form url??
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
request.setScheme("http");
request.setServerName("www.example.com");
// request.setContextPath("/bigWebApp");
// TODO correct this when the getRequestUrl from mock works...
request.setServerPort(8888); // NB: Port we can't resolve ep.setCaptchaFormUrl("/hello?toto=titi");
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"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());
MockHttpServletResponse response = new MockHttpServletResponse(); // with forcing!!!
ep.setForceHttps(true);
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"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());
ep.afterPropertiesSet(); }
ep.commence(request, response);
assertEquals(
"https://www.jcaptcha.net/dotest/?originalRequest=http://www.example.com:8888/some_path",
response.getRedirectedUrl());
// test the query params public void testOperationWithOutsideWebApp() throws Exception {
request.addParameter("name", "value"); CaptchaEntryPoint ep = new CaptchaEntryPoint();
response = new MockHttpServletResponse(); ep.setCaptchaFormUrl("https://www.jcaptcha.net/dotest/");
ep.commence(request, response); PortMapperImpl mapper = new PortMapperImpl();
assertEquals( mapper.getTranslatedPortMappings().put(new Integer(8888),
"https://www.jcaptcha.net/dotest/?originalRequest=http://www.example.com:8888/some_path?name=value", new Integer(1234));
response.getRedirectedUrl()); ep.setPortMapper(mapper);
// test the multiple query params ep.setPortResolver(new MockPortResolver(8888, 1234));
request.addParameter("name", "value"); ep.setIncludeOriginalRequest(true);
request.addParameter("name1", "value2"); ep.setOutsideWebApp(true);
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"https://www.jcaptcha.net/dotest/?originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2",
response.getRedirectedUrl());
// test add parameter to captcha form url?? ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
request.setScheme("http");
request.setServerName("www.example.com");
request.setMethod("post");
// request.setContextPath("/bigWebApp");
// TODO correct this when the getRequestUrl from mock works...
ep.setCaptchaFormUrl("https://www.jcaptcha.net/dotest/?toto=titi"); request.setServerPort(8888); // NB: Port we can't resolve
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"https://www.jcaptcha.net/dotest/?toto=titi&originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2",
response.getRedirectedUrl());
// with forcing!!! MockHttpServletResponse response = new MockHttpServletResponse();
ep.setForceHttps(true);
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"https://www.jcaptcha.net/dotest/?toto=titi&originalRequest=http://www.example.com:8888/some_path?name=value&name1=value2",
response.getRedirectedUrl());
} ep.afterPropertiesSet();
ep.commence(request, response);
assertEquals(
"https://www.jcaptcha.net/dotest/?original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8")
+ "&original_request_method=post"
,
response.getRedirectedUrl());
// test the query params
request.addParameter("name", "value");
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"https://www.jcaptcha.net/dotest/?original_requestUrl="
+ URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") +
"&original_request_method=post",
response.getRedirectedUrl());
// test the multiple query params
ep.setIncludeOriginalParameters(true);
request.addParameter("name", "value");
request.addParameter("name1", "value2");
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"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());
// test add parameter to captcha form url??
ep.setCaptchaFormUrl("https://www.jcaptcha.net/dotest/?toto=titi");
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"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());
// with forcing!!!
ep.setForceHttps(true);
response = new MockHttpServletResponse();
ep.commence(request, response);
assertEquals(
"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());
}
} }

View File

@ -1,64 +1,85 @@
/* 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() {
CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
assertEquals("should not be human", false, context.isHuman()); assertEquals("should not be human", false, context.isHuman());
assertEquals("should be 0", 0, context assertEquals("should be 0", 0, context
.getLastPassedCaptchaDateInMillis()); .getLastPassedCaptchaDateInMillis());
assertEquals("should be 0", 0, context assertEquals("should be 0", 0, context
.getHumanRestrictedResourcesRequestsCount()); .getHumanRestrictedResourcesRequestsCount());
} }
public void testSetHuman() { public void testSetHuman() {
CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
context.setHuman(); context.setHuman();
assertEquals("should be human", true, context.isHuman()); assertEquals("should be human", true, context.isHuman());
assertTrue("should be more than 0", context assertTrue("should be more than 0", context
.getLastPassedCaptchaDateInMillis() .getLastPassedCaptchaDateInMillis()
- now >= 0); - now >= 0);
assertTrue("should be less than 0,1 seconde", context assertTrue("should be less than 0,1 seconde", context
.getLastPassedCaptchaDateInMillis() .getLastPassedCaptchaDateInMillis()
- now < 100); - now < 100);
assertEquals("should be 0", 0, context assertEquals("should be 0", 0, context
.getHumanRestrictedResourcesRequestsCount()); .getHumanRestrictedResourcesRequestsCount());
} }
public void testIncrementRequests() { public void testIncrementRequests() {
CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
context.setHuman(); context.setHuman();
assertEquals("should be human", true, context.isHuman()); assertEquals("should be human", true, context.isHuman());
assertEquals("should be 0", 0, context assertEquals("should be 0", 0, context
.getHumanRestrictedResourcesRequestsCount()); .getHumanRestrictedResourcesRequestsCount());
context.incrementHumanRestrictedRessoucesRequestsCount(); context.incrementHumanRestrictedRessoucesRequestsCount();
assertEquals("should be 1", 1, context assertEquals("should be 1", 1, context
.getHumanRestrictedResourcesRequestsCount()); .getHumanRestrictedResourcesRequestsCount());
} }
public void testResetHuman() { public void testResetHuman() {
CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
context.setHuman(); context.setHuman();
assertEquals("should be human", true, context.isHuman()); assertEquals("should be human", true, context.isHuman());
assertEquals("should be 0", 0, context assertEquals("should be 0", 0, context
.getHumanRestrictedResourcesRequestsCount()); .getHumanRestrictedResourcesRequestsCount());
context.incrementHumanRestrictedRessoucesRequestsCount(); context.incrementHumanRestrictedRessoucesRequestsCount();
assertEquals("should be 1", 1, context assertEquals("should be 1", 1, context
.getHumanRestrictedResourcesRequestsCount()); .getHumanRestrictedResourcesRequestsCount());
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
context.setHuman(); context.setHuman();
assertEquals("should be 0", 0, context assertEquals("should be 0", 0, context
.getHumanRestrictedResourcesRequestsCount()); .getHumanRestrictedResourcesRequestsCount());
assertTrue("should be more than 0", context assertTrue("should be more than 0", context
.getLastPassedCaptchaDateInMillis() .getLastPassedCaptchaDateInMillis()
- now >= 0); - now >= 0);
assertTrue("should be less than 0,1 seconde", context assertTrue("should be less than 0,1 seconde", context
.getLastPassedCaptchaDateInMillis() .getLastPassedCaptchaDateInMillis()
- now < 100); - now < 100);
} }
} }

View File

@ -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; 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 {
/* /*
*/ */
public void testAfterPropertiesSet() throws Exception { public void testAfterPropertiesSet() throws Exception {
CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter(); CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter();
try { try {
filter.afterPropertiesSet(); filter.afterPropertiesSet();
fail("should have thrown an invalid argument exception"); fail("should have thrown an invalid argument exception");
} catch (Exception e) { } catch (Exception e) {
assertTrue("should be an InvalidArgumentException", assertTrue("should be an InvalidArgumentException",
IllegalArgumentException.class.isAssignableFrom(e IllegalArgumentException.class.isAssignableFrom(e
.getClass())); .getClass()));
} }
filter.setCaptchaService(new MockCaptchaServiceProxy());
filter.afterPropertiesSet();
} 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 * Test method for
* 'net.sf.acegisecurity.captcha.CaptchaValidationProcessingFilter.doFilter(ServletRequest, * 'net.sf.acegisecurity.captcha.CaptchaValidationProcessingFilter.doFilter(ServletRequest,
* ServletResponse, FilterChain)' * ServletResponse, FilterChain)'
*/ */
public void testDoFilterWithRequestParameter() throws Exception { public void testDoFilterWithoutRequestParameter() throws Exception {
CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
SecurityContextHolder.setContext(context); 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(); * Test method for
MockFilterChain chain = new MockFilterChain(true); * 'net.sf.acegisecurity.captcha.CaptchaValidationProcessingFilter.doFilter(ServletRequest,
filter.setCaptchaService(service); * ServletResponse, FilterChain)'
filter.doFilter(request, null, chain); */
assertTrue("should have been called", service.hasBeenCalled); public void testDoFilterWithRequestParameter() throws Exception {
assertFalse("context should not have been updated", context.isHuman()); CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
// test with valid SecurityContextHolder.setContext(context);
service.valid = true;
filter.doFilter(request, null, chain);
assertTrue("should have been called", service.hasBeenCalled);
assertTrue("context should have been updated", context.isHuman());
} 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());
}
} }

View File

@ -15,18 +15,20 @@
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;
} }
} }