Removing out of date modules in sandbox
This commit is contained in:
parent
dca566ff1f
commit
ebb24b9004
|
@ -1,36 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-security-parent</artifactId>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<version>3.0.0.CI-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-captcha</artifactId>
|
||||
<name>Spring Security - Captcha module</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>org.springframework.test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -1,60 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Your Corporation. All Rights Reserved.
|
||||
*/
|
||||
package org.springframework.security.captcha;
|
||||
|
||||
/**
|
||||
* Return false if the number of requests for captcha protcted URLs for the user
|
||||
* exceeds the threshold value.
|
||||
*
|
||||
* <br/>
|
||||
* Default keyword : <tt>REQUIRES_CAPTCHA_ABOVE_THRESHOLD_REQUESTS</tt>
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
/** Keyword for this channelProcessor */
|
||||
public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_ABOVE_THRESHOLD_REQUESTS";
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AlwaysTestAfterMaxRequestsCaptchaChannelProcessor() {
|
||||
this.setKeyword(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
*
|
||||
* @return false if the number of requests for captcha protected URLs exceeds the threshold.
|
||||
*/
|
||||
boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
|
||||
if (context.getHumanRestrictedResourcesRequestsCount() < getThreshold()) {
|
||||
logger.debug("context is valid : request count < thresold");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
logger.debug("context is not valid : request count > thresold");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
/**
|
||||
* Return false if the time in millis since the last captcha test is less than the threshold;<br/>
|
||||
* Default keyword : <tt>REQUIRES_CAPTCHA_AFTER_THRESHOLD_IN_MILLIS</tt>.
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
/** Keyword for this channelProcessor */
|
||||
public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_AFTER_THRESHOLD_IN_MILLIS";
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AlwaysTestAfterTimeInMillisCaptchaChannelProcessor() {
|
||||
|
||||
this.setKeyword(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Returns false if the time (in milliseconds) since the last captcha validation is greater than the
|
||||
* threshold value.
|
||||
*
|
||||
* @param context the CaptchaSecurityContext
|
||||
*
|
||||
*/
|
||||
boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
|
||||
if ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < getThreshold()) {
|
||||
logger.debug("context is valid : current time - last passed captcha date < threshold");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
logger.debug("context is not valid : current time - last passed captcha date > threshold");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Return false if the average time in millis between any CaptchaChannelProcessorTemplate mapped
|
||||
* urls requests is greater than the threshold value or the context is not human;<br />
|
||||
* Default keyword : <tt>REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS</tt> <br>
|
||||
* Note : before first humanity check
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
/** Keyword for this channelProcessor */
|
||||
public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS";
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor() {
|
||||
this.setKeyword(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Verify that threshold is > 0
|
||||
*
|
||||
* @throws Exception if false
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
super.afterPropertiesSet();
|
||||
Assert.isTrue(getThreshold() > 0, "thresold must be > 0");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
|
||||
int req = context.getHumanRestrictedResourcesRequestsCount();
|
||||
float thresold = getThreshold();
|
||||
float duration = System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis();
|
||||
float average;
|
||||
|
||||
if (req == 0) {
|
||||
average = thresold + 1;
|
||||
} else {
|
||||
average = duration / req;
|
||||
}
|
||||
|
||||
if (context.isHuman() && (average > thresold)) {
|
||||
logger.debug("context is valid : average time between requests < threshold && is human");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
logger.debug("context is not valid : average time between requests > threshold or is not human");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import org.springframework.security.ConfigAttribute;
|
||||
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
|
||||
import org.springframework.security.intercept.web.FilterInvocation;
|
||||
|
||||
import org.springframework.security.securechannel.ChannelEntryPoint;
|
||||
import org.springframework.security.securechannel.ChannelProcessor;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
|
||||
/**
|
||||
* CaptchaChannel template : Ensures the user has enough human privileges by review of the {@link
|
||||
* CaptchaSecurityContext} and using an abstract routine {@link
|
||||
* #isContextValidConcerningHumanity(CaptchaSecurityContext)} (implemented by sub classes)
|
||||
* <p>The component uses 2 main parameters for its configuration :
|
||||
* <ul>
|
||||
* <li>a keyword to be mapped to urls in the {@link
|
||||
* org.springframework.security.securechannel.ChannelProcessingFilter} configuration<br>
|
||||
* default value provided by sub classes.</li>
|
||||
* <li>and a threshold : used by the routine {@link
|
||||
* #isContextValidConcerningHumanity(CaptchaSecurityContext)} to evaluate whether the {@link
|
||||
* CaptchaSecurityContext} is valid default value = 0</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class CaptchaChannelProcessorTemplate implements ChannelProcessor, InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private ChannelEntryPoint entryPoint;
|
||||
protected Log logger = LogFactory.getLog(this.getClass());
|
||||
private String keyword = null;
|
||||
private int thresold = 0;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Verify if entryPoint and keyword are ok
|
||||
*
|
||||
* @throws Exception if not
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(entryPoint, "entryPoint required");
|
||||
Assert.hasLength(keyword, "keyword required");
|
||||
}
|
||||
|
||||
public void decide(FilterInvocation invocation, java.util.List<ConfigAttribute> config) throws IOException, ServletException {
|
||||
if ((invocation == null) || (config == null)) {
|
||||
throw new IllegalArgumentException("Nulls cannot be provided");
|
||||
}
|
||||
|
||||
CaptchaSecurityContext context = null;
|
||||
context = (CaptchaSecurityContext) SecurityContextHolder.getContext();
|
||||
|
||||
Iterator iter = config.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
ConfigAttribute attribute = (ConfigAttribute) iter.next();
|
||||
|
||||
if (supports(attribute)) {
|
||||
logger.debug("supports this attribute : " + attribute);
|
||||
|
||||
if (!isContextValidConcerningHumanity(context)) {
|
||||
logger.debug("context is not allowed to access ressource, redirect to captcha entry point");
|
||||
redirectToEntryPoint(invocation);
|
||||
} else {
|
||||
logger.debug("has been successfully checked this keyword, increment request count");
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
}
|
||||
} else {
|
||||
logger.debug("do not support this attribute");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ChannelEntryPoint getEntryPoint() {
|
||||
return entryPoint;
|
||||
}
|
||||
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public int getThreshold() {
|
||||
return thresold;
|
||||
}
|
||||
|
||||
abstract boolean isContextValidConcerningHumanity(CaptchaSecurityContext context);
|
||||
|
||||
private void redirectToEntryPoint(FilterInvocation invocation)
|
||||
throws IOException, ServletException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("context is not valid : redirecting to entry point");
|
||||
}
|
||||
|
||||
entryPoint.commence(invocation.getRequest(), invocation.getResponse());
|
||||
}
|
||||
|
||||
public void setEntryPoint(ChannelEntryPoint entryPoint) {
|
||||
this.entryPoint = entryPoint;
|
||||
}
|
||||
|
||||
public void setKeyword(String keyword) {
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
public void setThreshold(int thresold) {
|
||||
this.thresold = thresold;
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
if ((attribute != null) && (keyword.equals(attribute.getAttribute()))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,393 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import org.springframework.security.securechannel.ChannelEntryPoint;
|
||||
|
||||
import org.springframework.security.util.PortMapper;
|
||||
import org.springframework.security.util.PortMapperImpl;
|
||||
import org.springframework.security.util.PortResolver;
|
||||
import org.springframework.security.util.PortResolverImpl;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* The captcha entry point : redirect to the captcha test page.
|
||||
* <p>
|
||||
* This entry point can force the use of SSL : see {@link #getForceHttps()}
|
||||
* <p>
|
||||
* This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}<br />
|
||||
* / Original request can be added to the redirect path using a custom translation : see
|
||||
* {@link #setIncludeOriginalRequest(boolean)}<br />
|
||||
* The original request is translated using URLEncoding and the following translation mapping in the redirect url :
|
||||
* <ul>
|
||||
* <li>original url => {@link #getOriginalRequestUrlParameterName()}</li>
|
||||
* <li>If {@link #isIncludeOriginalParameters()}</li>
|
||||
* <li>original method => {@link #getOriginalRequestMethodParameterName()}</li>
|
||||
* <li>original parameters => {@link #getOriginalRequestParametersParameterName()}</li>
|
||||
* <li>The original parameters string is contructed using :
|
||||
* <ul>
|
||||
* <li>a parameter separator {@link #getOriginalRequestParametersSeparator()}</li>
|
||||
* <li>a parameter name value pair separator for each parameter {@link
|
||||
* #getOriginalRequestParametersNameValueSeparator()}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* <br><br>
|
||||
* Default values :
|
||||
* <pre>
|
||||
* forceHttps = false
|
||||
* includesOriginalRequest = true
|
||||
* includesOriginalParameters = false
|
||||
* isOutsideWebApp = false
|
||||
* originalRequestUrlParameterName = original_requestUrl
|
||||
* originalRequestParametersParameterName = original_request_parameters
|
||||
* originalRequestParametersNameValueSeparator = __
|
||||
* originalRequestParametersSeparator = ;;
|
||||
* originalRequestMethodParameterName = original_request_method
|
||||
* urlEncodingCharset = UTF-8
|
||||
* </pre>
|
||||
* </p>
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CaptchaEntryPoint.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private PortMapper portMapper = new PortMapperImpl();
|
||||
private PortResolver portResolver = new PortResolverImpl();
|
||||
private String captchaFormUrl;
|
||||
private String originalRequestMethodParameterName = "original_request_method";
|
||||
private String originalRequestParametersNameValueSeparator = "__";
|
||||
private String originalRequestParametersParameterName = "original_request_parameters";
|
||||
private String originalRequestParametersSeparator = ";;";
|
||||
private String originalRequestUrlParameterName = "original_requestUrl";
|
||||
private String urlEncodingCharset = "UTF-8";
|
||||
private boolean forceHttps = false;
|
||||
private boolean includeOriginalParameters = false;
|
||||
private boolean includeOriginalRequest = true;
|
||||
private boolean isOutsideWebApp = false;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void commence(HttpServletRequest request, HttpServletResponse 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());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the captcha test page to redirect to.
|
||||
*/
|
||||
public String getCaptchaFormUrl() {
|
||||
return captchaFormUrl;
|
||||
}
|
||||
|
||||
public boolean getForceHttps() {
|
||||
return forceHttps;
|
||||
}
|
||||
|
||||
public String getOriginalRequestMethodParameterName() {
|
||||
return originalRequestMethodParameterName;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersNameValueSeparator() {
|
||||
return originalRequestParametersNameValueSeparator;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersParameterName() {
|
||||
return originalRequestParametersParameterName;
|
||||
}
|
||||
|
||||
public String getOriginalRequestParametersSeparator() {
|
||||
return originalRequestParametersSeparator;
|
||||
}
|
||||
|
||||
public String getOriginalRequestUrlParameterName() {
|
||||
return originalRequestUrlParameterName;
|
||||
}
|
||||
|
||||
public PortMapper getPortMapper() {
|
||||
return portMapper;
|
||||
}
|
||||
|
||||
public PortResolver getPortResolver() {
|
||||
return portResolver;
|
||||
}
|
||||
|
||||
public String getUrlEncodingCharset() {
|
||||
return urlEncodingCharset;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIncludeOriginalParameters() {
|
||||
return includeOriginalParameters;
|
||||
}
|
||||
|
||||
public boolean isIncludeOriginalRequest() {
|
||||
return includeOriginalRequest;
|
||||
}
|
||||
|
||||
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>
|
||||
*
|
||||
* @param captchaFormUrl
|
||||
*/
|
||||
public void setCaptchaFormUrl(String captchaFormUrl) {
|
||||
this.captchaFormUrl = captchaFormUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true to force captcha form access to be via https. If this value is true (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 void setIncludeOriginalParameters(boolean includeOriginalParameters) {
|
||||
this.includeOriginalParameters = includeOriginalParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to true, the original request url will be appended to the redirect url using the {@link
|
||||
* #getOriginalRequestUrlParameterName()}.
|
||||
*
|
||||
* @param includeOriginalRequest
|
||||
*/
|
||||
public void setIncludeOriginalRequest(boolean includeOriginalRequest) {
|
||||
this.includeOriginalRequest = includeOriginalRequest;
|
||||
}
|
||||
|
||||
public void setOriginalRequestMethodParameterName(String originalRequestMethodParameterName) {
|
||||
this.originalRequestMethodParameterName = originalRequestMethodParameterName;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersNameValueSeparator(String originalRequestParametersNameValueSeparator) {
|
||||
this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersParameterName(String originalRequestParametersParameterName) {
|
||||
this.originalRequestParametersParameterName = originalRequestParametersParameterName;
|
||||
}
|
||||
|
||||
public void setOriginalRequestParametersSeparator(String originalRequestParametersSeparator) {
|
||||
this.originalRequestParametersSeparator = originalRequestParametersSeparator;
|
||||
}
|
||||
|
||||
public void setOriginalRequestUrlParameterName(String originalRequestUrlParameterName) {
|
||||
this.originalRequestUrlParameterName = originalRequestUrlParameterName;
|
||||
}
|
||||
|
||||
/**
|
||||
* if set to true, the {@link #commence(ServletRequest, ServletResponse)} method uses the {@link
|
||||
* #getCaptchaFormUrl()} as a complete URL, else it as a 'inside WebApp' path.
|
||||
*
|
||||
* @param isOutsideWebApp
|
||||
*/
|
||||
public void setOutsideWebApp(boolean isOutsideWebApp) {
|
||||
this.isOutsideWebApp = isOutsideWebApp;
|
||||
}
|
||||
|
||||
public void setPortMapper(PortMapper portMapper) {
|
||||
this.portMapper = portMapper;
|
||||
}
|
||||
|
||||
public void setPortResolver(PortResolver portResolver) {
|
||||
this.portResolver = portResolver;
|
||||
}
|
||||
|
||||
public void setUrlEncodingCharset(String urlEncodingCharset) {
|
||||
this.urlEncodingCharset = urlEncodingCharset;
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import org.springframework.security.context.SecurityContext;
|
||||
|
||||
|
||||
/**
|
||||
* Interface that adds humanity concerns to the SecurityContext
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface CaptchaSecurityContext extends SecurityContext {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the number of human restricted resources requested since the last passed captcha.
|
||||
*/
|
||||
int getHumanRestrictedResourcesRequestsCount();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the date of the last passed Captcha in millis, 0 if the user never passed captcha.
|
||||
*/
|
||||
long getLastPassedCaptchaDateInMillis();
|
||||
|
||||
/**
|
||||
* Increments the human Restricted Resources Requests Count.
|
||||
*/
|
||||
void incrementHumanRestrictedResourcesRequestsCount();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if the current user has already passed a captcha.
|
||||
*/
|
||||
boolean isHuman();
|
||||
|
||||
/**
|
||||
* set human attribute, should be called after captcha validation.
|
||||
*/
|
||||
void setHuman();
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import org.springframework.security.context.SecurityContextImpl;
|
||||
|
||||
|
||||
/**
|
||||
* Default CaptchaSecurityContext implementation
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaSecurityContextImpl extends SecurityContextImpl implements CaptchaSecurityContext {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private boolean human;
|
||||
private int humanRestrictedResourcesRequestsCount;
|
||||
private long lastPassedCaptchaDate;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public CaptchaSecurityContextImpl() {
|
||||
human = false;
|
||||
lastPassedCaptchaDate = 0;
|
||||
humanRestrictedResourcesRequestsCount = 0;
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof CaptchaSecurityContextImpl) {
|
||||
CaptchaSecurityContextImpl rhs = (CaptchaSecurityContextImpl) obj;
|
||||
|
||||
if (this.isHuman() != rhs.isHuman()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.getHumanRestrictedResourcesRequestsCount() != rhs.getHumanRestrictedResourcesRequestsCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.getLastPassedCaptchaDateInMillis() != rhs.getLastPassedCaptchaDateInMillis()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getHumanRestrictedResourcesRequestsCount() {
|
||||
return humanRestrictedResourcesRequestsCount;
|
||||
}
|
||||
|
||||
public long getLastPassedCaptchaDateInMillis() {
|
||||
return lastPassedCaptchaDate;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int code = super.hashCode();
|
||||
code ^= this.humanRestrictedResourcesRequestsCount;
|
||||
code ^= this.lastPassedCaptchaDate;
|
||||
|
||||
if (this.isHuman()) {
|
||||
code ^= -37;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to increment the human Restricted Resources Requests Count;
|
||||
*/
|
||||
public void incrementHumanRestrictedResourcesRequestsCount() {
|
||||
humanRestrictedResourcesRequestsCount++;
|
||||
}
|
||||
|
||||
public boolean isHuman() {
|
||||
return human;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the lastPassedCaptchaDate and count.
|
||||
*/
|
||||
public void setHuman() {
|
||||
this.human = true;
|
||||
this.lastPassedCaptchaDate = System.currentTimeMillis();
|
||||
this.humanRestrictedResourcesRequestsCount = 0;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
/**
|
||||
* Provide a common interface for captcha validation.
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface CaptchaServiceProxy {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id the id token
|
||||
* @param captchaResponse the user response
|
||||
*
|
||||
* @return true if the response is validated by the back end captcha service.
|
||||
*/
|
||||
boolean validateReponseForId(String id, Object captchaResponse);
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
/**
|
||||
* Filter for web integration of the {@link CaptchaServiceProxy}.
|
||||
* <p>
|
||||
* It basically intercept calls containing the specific validation parameter, uses the {@link CaptchaServiceProxy} to
|
||||
* validate the request, and update the {@link CaptchaSecurityContext} if the request passed the validation.
|
||||
* <p>
|
||||
* This Filter should be placed after the ContextIntegration filter and before the {@link
|
||||
* CaptchaChannelProcessorTemplate} filter in the filter stack in order to update the {@link CaptchaSecurityContext}
|
||||
* before the humanity verification routine occurs.
|
||||
* <p>
|
||||
* This filter should only be used in conjunction with the {@link CaptchaSecurityContext}<br>
|
||||
*
|
||||
* @author marc antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaValidationProcessingFilter implements InitializingBean, Filter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(CaptchaValidationProcessingFilter.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private CaptchaServiceProxy captchaService;
|
||||
private String captchaValidationParameter = "_captcha_parameter";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.captchaService == null) {
|
||||
throw new IllegalArgumentException("CaptchaServiceProxy must be defined ");
|
||||
}
|
||||
|
||||
if ((this.captchaValidationParameter == null) || "".equals(captchaValidationParameter)) {
|
||||
throw new IllegalArgumentException("captchaValidationParameter must not be empty or null");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing. We use IoC container lifecycle services instead.
|
||||
*/
|
||||
public void destroy() {}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
String captchaResponse = request.getParameter(captchaValidationParameter);
|
||||
|
||||
if ((request != null) && request instanceof HttpServletRequest && (captchaResponse != null)) {
|
||||
logger.debug("captcha validation parameter found");
|
||||
|
||||
// validate the request against CaptchaServiceProxy
|
||||
boolean valid = false;
|
||||
|
||||
logger.debug("try to validate");
|
||||
|
||||
//get session
|
||||
HttpSession session = ((HttpServletRequest) request).getSession();
|
||||
|
||||
if (session != null) {
|
||||
String id = session.getId();
|
||||
valid = this.captchaService.validateReponseForId(id, captchaResponse);
|
||||
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");
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("chain ...");
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
public CaptchaServiceProxy getCaptchaService() {
|
||||
return captchaService;
|
||||
}
|
||||
|
||||
public String getCaptchaValidationParameter() {
|
||||
return captchaValidationParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing. We use IoC container lifecycle services instead.
|
||||
*
|
||||
* @param filterConfig ignored
|
||||
*
|
||||
* @throws ServletException ignored
|
||||
*/
|
||||
public void init(FilterConfig filterConfig) throws ServletException {}
|
||||
|
||||
public void setCaptchaService(CaptchaServiceProxy captchaService) {
|
||||
this.captchaService = captchaService;
|
||||
}
|
||||
|
||||
public void setCaptchaValidationParameter(String captchaValidationParameter) {
|
||||
this.captchaValidationParameter = captchaValidationParameter;
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
/**
|
||||
* Return false if any CaptchaChannelProcessorTemplate mapped urls have been requested more than threshold and
|
||||
* humanity is false; <br>
|
||||
* Default keyword : REQUIRES_CAPTCHA_ONCE_ABOVE_THRESHOLD_REQUESTS</p>
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class TestOnceAfterMaxRequestsCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_ONCE_ABOVE_THRESHOLD_REQUESTS";
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public TestOnceAfterMaxRequestsCaptchaChannelProcessor() {
|
||||
this.setKeyword(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
|
||||
if (context.isHuman() || (context.getHumanRestrictedResourcesRequestsCount() < getThreshold())) {
|
||||
logger.debug("context is valid concerning humanity or request count < threshold");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
logger.debug("context is not valid concerning humanity and request count > threshold");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
Captcha classes. Contains :<br/>
|
||||
<ul>
|
||||
<li>a CaptchaSecurityContext that overrides the default SecurityContext and holds some captcha related informations</li>
|
||||
<li>an abstract CaptchaChannelProcessorTemplate and its implementations that test this context according to the configuration</li>
|
||||
<li>a CaptchaServiceProxy and a CaptchaValidationProcessingFilter that alows to validate a captcha response and to update the CaptchaSecurity</li>
|
||||
<li>a CaptchaEntryPoint that redirects to a captcha page if the CaptchaChannelProcessor implementation decide so</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
/**
|
||||
* @author Marc-Antoine Garrigue
|
||||
*/
|
||||
public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessorTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
AlwaysTestAfterMaxRequestsCaptchaChannelProcessor alwaysTestAfterMaxRequestsCaptchaChannelProcessor;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
alwaysTestAfterMaxRequestsCaptchaChannelProcessor = new AlwaysTestAfterMaxRequestsCaptchaChannelProcessor();
|
||||
}
|
||||
|
||||
public void testIsContextValidConcerningHumanity()
|
||||
throws Exception {
|
||||
alwaysTestAfterMaxRequestsCaptchaChannelProcessor.setThreshold(1);
|
||||
|
||||
CaptchaSecurityContextImpl context = new CaptchaSecurityContextImpl();
|
||||
assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
|
||||
alwaysTestAfterMaxRequestsCaptchaChannelProcessor.setThreshold(-1);
|
||||
assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
|
||||
alwaysTestAfterMaxRequestsCaptchaChannelProcessor.setThreshold(3);
|
||||
assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
|
||||
public void testNewContext() {
|
||||
CaptchaSecurityContextImpl context = new CaptchaSecurityContextImpl();
|
||||
|
||||
assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
alwaysTestAfterMaxRequestsCaptchaChannelProcessor.setThreshold(1);
|
||||
assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import junit.framework.*;
|
||||
|
||||
import org.springframework.security.captcha.AlwaysTestAfterTimeInMillisCaptchaChannelProcessor;
|
||||
|
||||
|
||||
/**
|
||||
* WARNING! This test class make some assumptions concerning the compute speed! For example the two following
|
||||
* instructions should be computed in the same millis or the test is not valid.<pre><code>context.setHuman();
|
||||
* assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
* </code></pre>This should be the case for most environements unless
|
||||
* <ul>
|
||||
* <li>you run it on a good old TRS-80</li>
|
||||
* <li>you start M$office during this test ;)</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
AlwaysTestAfterTimeInMillisCaptchaChannelProcessor alwaysTestAfterTimeInMillisCaptchaChannelProcessor;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
alwaysTestAfterTimeInMillisCaptchaChannelProcessor = new AlwaysTestAfterTimeInMillisCaptchaChannelProcessor();
|
||||
}
|
||||
|
||||
public void testEqualsThresold() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
|
||||
//the two following instructions should be computed or the test is not valid (never fails). This should be the case
|
||||
// for most environements unless if you run it on a good old TRS-80 (thanks mom).
|
||||
context.setHuman();
|
||||
assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
/* Commented out as it makes assumptions about the speed of the build server and fails intermittently on
|
||||
build.springframework.org - L.T.
|
||||
|
||||
public void testIsContextValidConcerningHumanity()
|
||||
throws Exception {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
alwaysTestAfterTimeInMillisCaptchaChannelProcessor.setThreshold(100);
|
||||
context.setHuman();
|
||||
|
||||
while ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < alwaysTestAfterTimeInMillisCaptchaChannelProcessor
|
||||
.getThreshold()) {
|
||||
assertTrue(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
context.incrementHumanRestrictedRessoucesRequestsCount();
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
while ((System.currentTimeMillis() - now) < 1) {}
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
*/
|
||||
public void testNewContext() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
|
||||
//alwaysTestAfterTimeInMillisCaptchaChannelProcessor.setThreshold(10);
|
||||
assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @author $author$
|
||||
* @version $Revision: 2142 $
|
||||
*/
|
||||
public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor = new AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor();
|
||||
}
|
||||
|
||||
public void testEqualsThresold() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.setThreshold(100);
|
||||
|
||||
context.setHuman();
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
/*
|
||||
while ((System.currentTimeMillis() - now) <= 100) {
|
||||
assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
|
||||
context.incrementHumanRestrictedRessoucesRequestsCount();
|
||||
assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity(
|
||||
context));
|
||||
|
||||
context.setHuman();
|
||||
context.incrementHumanRestrictedRessoucesRequestsCount();
|
||||
assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity(
|
||||
context));
|
||||
|
||||
alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.setThreshold(0);
|
||||
context.setHuman();
|
||||
context.incrementHumanRestrictedRessoucesRequestsCount();
|
||||
assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity(
|
||||
context));
|
||||
alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.setThreshold(0);
|
||||
*/
|
||||
}
|
||||
/*
|
||||
public void testIsContextValidConcerningHumanity()
|
||||
throws Exception {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.setThreshold(10);
|
||||
context.setHuman();
|
||||
|
||||
while ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < (10 * alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
.getThreshold())) {
|
||||
assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
}
|
||||
|
||||
public void testNewContext() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity(
|
||||
context));
|
||||
|
||||
context.setHuman();
|
||||
assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity(
|
||||
context));
|
||||
}
|
||||
|
||||
public void testShouldPassAbove() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
|
||||
context.setHuman();
|
||||
|
||||
int i = 0;
|
||||
|
||||
while ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < (100 * alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
.getThreshold())) {
|
||||
System.out.println((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()));
|
||||
|
||||
context.incrementHumanRestrictedRessoucesRequestsCount();
|
||||
i++;
|
||||
|
||||
while ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < (alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
.getThreshold() * i)) {}
|
||||
|
||||
System.out.println((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()));
|
||||
|
||||
assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor
|
||||
.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -1,229 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.ConfigAttribute;
|
||||
import org.springframework.security.SecurityConfig;
|
||||
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
|
||||
import org.springframework.security.intercept.web.FilterInvocation;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link org.springframework.security.captcha.CaptchaChannelProcessorTemplate}
|
||||
*
|
||||
* @author marc antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaChannelProcessorTemplateTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
private MockHttpServletResponse decideWithNewResponse(List<ConfigAttribute> cad,
|
||||
CaptchaChannelProcessorTemplate 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 setUp() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
public void testContextRedirect() throws Exception {
|
||||
CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
|
||||
processor.setKeyword("X");
|
||||
|
||||
List<ConfigAttribute> cad = SecurityConfig.createList("Y");
|
||||
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
SecurityContextHolder.setContext(context);
|
||||
|
||||
CaptchaEntryPoint epoint = new CaptchaEntryPoint();
|
||||
epoint.setCaptchaFormUrl("/jcaptcha.do");
|
||||
epoint.setIncludeOriginalRequest(false);
|
||||
|
||||
processor.setEntryPoint(epoint);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setQueryString("info=true");
|
||||
request.setServerName("localhost");
|
||||
request.setContextPath("/demo");
|
||||
request.setServletPath("/restricted");
|
||||
request.setScheme("http");
|
||||
request.setServerPort(8000);
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
FilterInvocation fi = new FilterInvocation(request, response, chain);
|
||||
|
||||
processor.decide(fi, cad);
|
||||
assertEquals(null, response.getRedirectedUrl());
|
||||
processor.setKeyword("Y");
|
||||
response = decideWithNewResponse(cad, processor, request);
|
||||
assertEquals("http://localhost:8000/demo/jcaptcha.do", response.getRedirectedUrl());
|
||||
context.setHuman();
|
||||
response = decideWithNewResponse(cad, processor, request);
|
||||
assertEquals(null, response.getRedirectedUrl());
|
||||
}
|
||||
|
||||
public void testDecideRejectsNulls() throws Exception {
|
||||
CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
|
||||
processor.setEntryPoint(new CaptchaEntryPoint());
|
||||
processor.setKeyword("X");
|
||||
processor.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
processor.decide(null, null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
|
||||
assertEquals(null, processor.getKeyword());
|
||||
processor.setKeyword("X");
|
||||
assertEquals("X", processor.getKeyword());
|
||||
|
||||
assertEquals(0, processor.getThreshold());
|
||||
processor.setThreshold(1);
|
||||
assertEquals(1, processor.getThreshold());
|
||||
|
||||
assertTrue(processor.getEntryPoint() == null);
|
||||
processor.setEntryPoint(new CaptchaEntryPoint());
|
||||
assertTrue(processor.getEntryPoint() != null);
|
||||
}
|
||||
|
||||
public void testIncrementRequestCount() throws Exception {
|
||||
CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
|
||||
processor.setKeyword("X");
|
||||
|
||||
List<ConfigAttribute> cad = SecurityConfig.createList("X");
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
SecurityContextHolder.setContext(context);
|
||||
|
||||
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(0, context.getHumanRestrictedResourcesRequestsCount());
|
||||
context.setHuman();
|
||||
decideWithNewResponse(cad, processor, request);
|
||||
assertEquals(1, context.getHumanRestrictedResourcesRequestsCount());
|
||||
decideWithNewResponse(cad, processor, request);
|
||||
assertEquals(2, context.getHumanRestrictedResourcesRequestsCount());
|
||||
processor.setKeyword("Y");
|
||||
decideWithNewResponse(cad, processor, request);
|
||||
assertEquals(2, context.getHumanRestrictedResourcesRequestsCount());
|
||||
context = new CaptchaSecurityContextImpl();
|
||||
decideWithNewResponse(cad, processor, request);
|
||||
assertEquals(0, context.getHumanRestrictedResourcesRequestsCount());
|
||||
}
|
||||
|
||||
public void testMissingEntryPoint() throws Exception {
|
||||
CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
|
||||
processor.setEntryPoint(null);
|
||||
|
||||
try {
|
||||
processor.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("entryPoint required", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testMissingKeyword() throws Exception {
|
||||
CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
|
||||
processor.setKeyword(null);
|
||||
|
||||
try {
|
||||
processor.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {}
|
||||
|
||||
processor.setKeyword("");
|
||||
|
||||
try {
|
||||
processor.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {}
|
||||
}
|
||||
|
||||
public void testSupports() {
|
||||
CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor();
|
||||
processor.setKeyword("X");
|
||||
assertTrue(processor.supports(new SecurityConfig(processor.getKeyword())));
|
||||
|
||||
assertTrue(processor.supports(new SecurityConfig("X")));
|
||||
|
||||
assertFalse(processor.supports(null));
|
||||
|
||||
assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED")));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class TestHumanityCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate {
|
||||
boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) {
|
||||
return context.isHuman();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MockFilterChain implements FilterChain {
|
||||
public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,386 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.MockPortResolver;
|
||||
|
||||
import org.springframework.security.util.PortMapperImpl;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CaptchaEntryPoint}.
|
||||
*
|
||||
* @author marc antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaEntryPointTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testDetectsMissingCaptchaFormUrl() throws Exception {
|
||||
CaptchaEntryPoint ep = new CaptchaEntryPoint();
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setPortResolver(new MockPortResolver(80, 443));
|
||||
|
||||
try {
|
||||
ep.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("captchaFormUrl must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingPortMapper() throws Exception {
|
||||
CaptchaEntryPoint ep = new CaptchaEntryPoint();
|
||||
ep.setCaptchaFormUrl("xxx");
|
||||
ep.setPortMapper(null);
|
||||
|
||||
try {
|
||||
ep.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("portMapper must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingPortResolver() throws Exception {
|
||||
CaptchaEntryPoint ep = new CaptchaEntryPoint();
|
||||
ep.setCaptchaFormUrl("xxx");
|
||||
ep.setPortResolver(null);
|
||||
|
||||
try {
|
||||
ep.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("portResolver must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
CaptchaEntryPoint ep = new CaptchaEntryPoint();
|
||||
ep.setCaptchaFormUrl("/hello");
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setPortResolver(new MockPortResolver(8080, 8443));
|
||||
assertEquals("/hello", ep.getCaptchaFormUrl());
|
||||
assertTrue(ep.getPortMapper() != null);
|
||||
assertTrue(ep.getPortResolver() != null);
|
||||
|
||||
assertEquals("original_requestUrl", ep.getOriginalRequestUrlParameterName());
|
||||
ep.setOriginalRequestUrlParameterName("Z");
|
||||
assertEquals("Z", ep.getOriginalRequestUrlParameterName());
|
||||
|
||||
assertEquals(true, ep.isIncludeOriginalRequest());
|
||||
ep.setIncludeOriginalRequest(false);
|
||||
assertEquals(false, ep.isIncludeOriginalRequest());
|
||||
|
||||
assertEquals(false, ep.isOutsideWebApp());
|
||||
ep.setOutsideWebApp(true);
|
||||
assertEquals(true, ep.isOutsideWebApp());
|
||||
|
||||
ep.setForceHttps(false);
|
||||
assertFalse(ep.getForceHttps());
|
||||
ep.setForceHttps(true);
|
||||
assertTrue(ep.getForceHttps());
|
||||
}
|
||||
|
||||
public void testHttpsOperationFromOriginalHttpUrl()
|
||||
throws Exception {
|
||||
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();
|
||||
|
||||
CaptchaEntryPoint ep = new CaptchaEntryPoint();
|
||||
ep.setIncludeOriginalRequest(false);
|
||||
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);
|
||||
assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
|
||||
|
||||
request.setServerPort(8080);
|
||||
response = new MockHttpServletResponse();
|
||||
ep.setPortResolver(new MockPortResolver(8080, 8443));
|
||||
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(8888);
|
||||
response = new MockHttpServletResponse();
|
||||
ep.commence(request, response);
|
||||
assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
|
||||
|
||||
PortMapperImpl portMapper = new PortMapperImpl();
|
||||
Map map = new HashMap();
|
||||
map.put("8888", "9999");
|
||||
portMapper.setPortMappings(map);
|
||||
response = new MockHttpServletResponse();
|
||||
|
||||
ep = new CaptchaEntryPoint();
|
||||
ep.setCaptchaFormUrl("/hello");
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setForceHttps(true);
|
||||
ep.setPortMapper(portMapper);
|
||||
ep.setPortResolver(new MockPortResolver(8888, 9999));
|
||||
ep.setIncludeOriginalRequest(false);
|
||||
|
||||
ep.afterPropertiesSet();
|
||||
|
||||
ep.commence(request, response);
|
||||
assertEquals("https://www.example.com:9999/bigWebApp/hello", response.getRedirectedUrl());
|
||||
}
|
||||
|
||||
public void testHttpsOperationFromOriginalHttpsUrl()
|
||||
throws Exception {
|
||||
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();
|
||||
|
||||
CaptchaEntryPoint ep = new CaptchaEntryPoint();
|
||||
ep.setIncludeOriginalRequest(false);
|
||||
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);
|
||||
assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
public void testNormalOperation() throws Exception {
|
||||
CaptchaEntryPoint ep = new CaptchaEntryPoint();
|
||||
ep.setCaptchaFormUrl("/hello");
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setPortResolver(new MockPortResolver(80, 443));
|
||||
ep.afterPropertiesSet();
|
||||
ep.setIncludeOriginalRequest(false);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI("/some_path");
|
||||
request.setContextPath("/bigWebApp");
|
||||
request.setScheme("http");
|
||||
request.setServerName("www.example.com");
|
||||
request.setContextPath("/bigWebApp");
|
||||
request.setServerPort(80);
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
ep.afterPropertiesSet();
|
||||
ep.commence(request, response);
|
||||
assertEquals("http://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
|
||||
}
|
||||
|
||||
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.setIncludeOriginalRequest(false);
|
||||
|
||||
ep.afterPropertiesSet();
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI("/some_path");
|
||||
request.setContextPath("/bigWebApp");
|
||||
request.setScheme("http");
|
||||
request.setServerName("www.example.com");
|
||||
request.setContextPath("/bigWebApp");
|
||||
request.setServerPort(8888); // NB: Port we can't resolve
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
ep.afterPropertiesSet();
|
||||
ep.commence(request, response);
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
public void testOperationWithOriginalRequestIncludes()
|
||||
throws Exception {
|
||||
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));
|
||||
ep.setIncludeOriginalRequest(true);
|
||||
ep.afterPropertiesSet();
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setMethod("post");
|
||||
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
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
ep.afterPropertiesSet();
|
||||
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());
|
||||
|
||||
// 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());
|
||||
|
||||
// test the multiple query params
|
||||
ep.setIncludeOriginalParameters(true);
|
||||
|
||||
request.addParameter("name", "value");
|
||||
request.addParameter("name1", "value2");
|
||||
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());
|
||||
|
||||
// test add parameter to captcha form url??
|
||||
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());
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
public void testOperationWithOutsideWebApp() throws Exception {
|
||||
CaptchaEntryPoint ep = new CaptchaEntryPoint();
|
||||
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));
|
||||
ep.setIncludeOriginalRequest(true);
|
||||
ep.setOutsideWebApp(true);
|
||||
|
||||
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...
|
||||
request.setServerPort(8888); // NB: Port we can't resolve
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CaptchaSecurityContextImpl}.
|
||||
*
|
||||
* @author marc antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaSecurityContextImplTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testDefaultValues() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
assertEquals("should not be human", false, context.isHuman());
|
||||
assertEquals("should be 0", 0, context.getLastPassedCaptchaDateInMillis());
|
||||
assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount());
|
||||
}
|
||||
|
||||
public void testEquals() {
|
||||
CaptchaSecurityContext context1 = new CaptchaSecurityContextImpl();
|
||||
CaptchaSecurityContext context2 = new CaptchaSecurityContextImpl();
|
||||
|
||||
assertEquals(context1, context2);
|
||||
|
||||
assertFalse(context1.isHuman());
|
||||
context1.setHuman();
|
||||
assertNotSame(context1, context2);
|
||||
|
||||
// Get fresh copy
|
||||
context1 = new CaptchaSecurityContextImpl();
|
||||
assertEquals(context1, context2);
|
||||
|
||||
context1.incrementHumanRestrictedResourcesRequestsCount();
|
||||
assertNotSame(context1, context2);
|
||||
}
|
||||
|
||||
public void testHashcode() {
|
||||
CaptchaSecurityContext context1 = new CaptchaSecurityContextImpl();
|
||||
CaptchaSecurityContext context2 = new CaptchaSecurityContextImpl();
|
||||
|
||||
assertEquals(context1.hashCode(), context2.hashCode());
|
||||
|
||||
assertFalse(context1.isHuman());
|
||||
context1.setHuman();
|
||||
assertTrue(context1.hashCode() != context2.hashCode());
|
||||
|
||||
// Get fresh copy
|
||||
context1 = new CaptchaSecurityContextImpl();
|
||||
assertEquals(context1.hashCode(), context2.hashCode());
|
||||
|
||||
context1.incrementHumanRestrictedResourcesRequestsCount();
|
||||
assertTrue(context1 != context2);
|
||||
}
|
||||
|
||||
public void testIncrementRequests() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
context.setHuman();
|
||||
assertEquals("should be human", true, context.isHuman());
|
||||
assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount());
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
assertEquals("should be 1", 1, context.getHumanRestrictedResourcesRequestsCount());
|
||||
}
|
||||
|
||||
public void testResetHuman() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
context.setHuman();
|
||||
assertEquals("should be human", true, context.isHuman());
|
||||
assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount());
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
assertEquals("should be 1", 1, context.getHumanRestrictedResourcesRequestsCount());
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
context.setHuman();
|
||||
assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount());
|
||||
assertTrue("should be more than 0", (context.getLastPassedCaptchaDateInMillis() - now) >= 0);
|
||||
assertTrue("should be less than 0,1 seconde", (context.getLastPassedCaptchaDateInMillis() - now) < 100);
|
||||
}
|
||||
|
||||
public void testSetHuman() {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
long now = System.currentTimeMillis();
|
||||
context.setHuman();
|
||||
assertEquals("should be human", true, context.isHuman());
|
||||
assertTrue("should be more than 0", (context.getLastPassedCaptchaDateInMillis() - now) >= 0);
|
||||
assertTrue("should be less than 0,1 seconde", (context.getLastPassedCaptchaDateInMillis() - now) < 100);
|
||||
assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount());
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
|
||||
import org.springframework.security.util.MockFilter;
|
||||
import org.springframework.security.util.MockFilterChain;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CaptchaValidationProcessingFilter}.
|
||||
*
|
||||
* @author marc antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CaptchaValidationProcessingFilterTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/*
|
||||
*/
|
||||
public void testAfterPropertiesSet() throws Exception {
|
||||
CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter();
|
||||
|
||||
try {
|
||||
filter.afterPropertiesSet();
|
||||
fail("should have thrown an invalid argument exception");
|
||||
} catch (Exception e) {
|
||||
assertTrue("should be an InvalidArgumentException",
|
||||
IllegalArgumentException.class.isAssignableFrom(e.getClass()));
|
||||
}
|
||||
|
||||
filter.setCaptchaService(new MockCaptchaServiceProxy());
|
||||
filter.afterPropertiesSet();
|
||||
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
|
||||
* 'org.springframework.security.captcha.CaptchaValidationProcessingFilter.doFilter(ServletRequest,
|
||||
* ServletResponse, FilterChain)'
|
||||
*/
|
||||
public void testDoFilterWithRequestParameter() throws Exception {
|
||||
CaptchaSecurityContext context = new CaptchaSecurityContextImpl();
|
||||
SecurityContextHolder.setContext(context);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
CaptchaValidationProcessingFilter filter = new CaptchaValidationProcessingFilter();
|
||||
request.addParameter(filter.getCaptchaValidationParameter(), "");
|
||||
|
||||
MockCaptchaServiceProxy service = new MockCaptchaServiceProxy();
|
||||
MockFilterChain chain = new MockFilterChain(true);
|
||||
filter.setCaptchaService(service);
|
||||
filter.doFilter(request, null, chain);
|
||||
assertTrue("should have been called", service.hasBeenCalled);
|
||||
assertFalse("context should not have been updated", context.isHuman());
|
||||
|
||||
// test with valid
|
||||
service.valid = true;
|
||||
filter.doFilter(request, null, chain);
|
||||
assertTrue("should have been called", service.hasBeenCalled);
|
||||
assertTrue("context should have been updated", context.isHuman());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.security.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());
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
/**
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Id$
|
||||
*/
|
||||
public class MockCaptchaServiceProxy implements CaptchaServiceProxy {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
public boolean hasBeenCalled = false;
|
||||
public boolean valid = false;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public boolean validateReponseForId(String id, Object response) {
|
||||
hasBeenCalled = true;
|
||||
|
||||
return valid;
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.captcha;
|
||||
|
||||
import junit.framework.*;
|
||||
|
||||
import org.springframework.security.captcha.TestOnceAfterMaxRequestsCaptchaChannelProcessor;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Marc-Antoine Garrigue
|
||||
* @version $Revision: 2142 $
|
||||
*/
|
||||
public class TestOnceAfterMaxRequestsCaptchaChannelProcessorTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
TestOnceAfterMaxRequestsCaptchaChannelProcessor testOnceAfterMaxRequestsCaptchaChannelProcessor;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
testOnceAfterMaxRequestsCaptchaChannelProcessor = new TestOnceAfterMaxRequestsCaptchaChannelProcessor();
|
||||
}
|
||||
|
||||
public void testIsContextValidConcerningHumanity()
|
||||
throws Exception {
|
||||
testOnceAfterMaxRequestsCaptchaChannelProcessor.setThreshold(1);
|
||||
|
||||
CaptchaSecurityContextImpl context = new CaptchaSecurityContextImpl();
|
||||
assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
|
||||
testOnceAfterMaxRequestsCaptchaChannelProcessor.setThreshold(-1);
|
||||
assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
|
||||
testOnceAfterMaxRequestsCaptchaChannelProcessor.setThreshold(3);
|
||||
assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
context.incrementHumanRestrictedResourcesRequestsCount();
|
||||
assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
context.setHuman();
|
||||
|
||||
for (int i = 0; i < (2 * testOnceAfterMaxRequestsCaptchaChannelProcessor.getThreshold()); i++) {
|
||||
assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
}
|
||||
|
||||
public void testNewContext() {
|
||||
CaptchaSecurityContextImpl context = new CaptchaSecurityContextImpl();
|
||||
|
||||
assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
testOnceAfterMaxRequestsCaptchaChannelProcessor.setThreshold(1);
|
||||
assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
|
||||
}
|
||||
}
|
|
@ -11,9 +11,7 @@
|
|||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>webwork</module>
|
||||
<module>other</module>
|
||||
<module>captcha</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-sandbox</artifactId>
|
||||
<version>3.0.0.CI-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-security-webwork</artifactId>
|
||||
<name>Spring Security - Webwork support</name>
|
||||
<description>Spring Security - Support for WebWork 2</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>opensymphony</groupId>
|
||||
<artifactId>webwork</artifactId>
|
||||
<version>2.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -1,132 +0,0 @@
|
|||
/* Copyright 2006 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 org.springframework.security.webwork;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.ui.ExceptionTranslationFilter;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.opensymphony.webwork.ServletActionContext;
|
||||
import com.opensymphony.webwork.dispatcher.DispatcherUtils;
|
||||
import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
|
||||
import com.opensymphony.xwork.ActionContext;
|
||||
import com.opensymphony.xwork.ActionProxy;
|
||||
import com.opensymphony.xwork.ActionProxyFactory;
|
||||
import com.opensymphony.xwork.Result;
|
||||
import com.opensymphony.xwork.config.ConfigurationException;
|
||||
import com.opensymphony.xwork.util.OgnlValueStack;
|
||||
import com.opensymphony.xwork.util.XWorkContinuationConfig;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* WebWork {@link DispatcherUtils} that ignores Acegi exceptions so they can be processed by
|
||||
* {@link ExceptionTranslationFilter}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This is meant to be fixed inside WebWork, see <a href="http://jira.opensymphony.com/browse/WW-291">WW-291</a>. Known
|
||||
* broken versions are 2.2.3 and 2.2.4.
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AcegiDispatcherUtils extends DispatcherUtils {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(AcegiDispatcherUtils.class);
|
||||
|
||||
protected AcegiDispatcherUtils(ServletContext servletContext) {
|
||||
super(servletContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Loads the action and executes it. This method first creates the action context from the given parameters then
|
||||
* loads an <tt>ActionProxy</tt> from the given action name and namespace. After that, the action is executed and
|
||||
* output channels throught the response object. Actions not found are sent back to the user via the
|
||||
* {@link DispatcherUtils#sendError} method, using the 404 return code. All other errors are reported by throwing a
|
||||
* ServletException.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Difference between this and WebWork prvided class is that any unhandled exception will be thrown instead of
|
||||
* processed inside WebWork.
|
||||
* </p>
|
||||
*
|
||||
* @param request the HttpServletRequest object
|
||||
* @param response the HttpServletResponse object
|
||||
* @param mapping the action mapping object
|
||||
* @throws ServletException when an unknown error occurs (not a 404, but typically something that would end up as a
|
||||
* 5xx by the servlet container)
|
||||
*/
|
||||
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
|
||||
ActionMapping mapping) throws ServletException {
|
||||
Map extraContext = createContextMap(request, response, mapping, context);
|
||||
|
||||
// If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
|
||||
OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
|
||||
if (stack != null) {
|
||||
extraContext.put(ActionContext.VALUE_STACK, new OgnlValueStack(stack));
|
||||
}
|
||||
|
||||
try {
|
||||
String namespace = mapping.getNamespace();
|
||||
String name = mapping.getName();
|
||||
String method = mapping.getMethod();
|
||||
|
||||
String id = request.getParameter(XWorkContinuationConfig.CONTINUE_PARAM);
|
||||
if (id != null) {
|
||||
// remove the continue key from the params - we don't want to bother setting
|
||||
// on the value stack since we know it won't work. Besides, this breaks devMode!
|
||||
Map params = (Map) extraContext.get(ActionContext.PARAMETERS);
|
||||
params.remove(XWorkContinuationConfig.CONTINUE_PARAM);
|
||||
|
||||
// and now put the key in the context to be picked up later by XWork
|
||||
extraContext.put(XWorkContinuationConfig.CONTINUE_KEY, id);
|
||||
}
|
||||
|
||||
ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, name, extraContext, true,
|
||||
false);
|
||||
proxy.setMethod(method);
|
||||
request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
|
||||
|
||||
// if the ActionMapping says to go straight to a result, do it!
|
||||
if (mapping.getResult() != null) {
|
||||
Result result = mapping.getResult();
|
||||
result.execute(proxy.getInvocation());
|
||||
} else {
|
||||
proxy.execute();
|
||||
}
|
||||
|
||||
// If there was a previous value stack then set it back onto the request
|
||||
if (stack != null) {
|
||||
request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, stack);
|
||||
}
|
||||
} catch (ConfigurationException e) {
|
||||
LOG.error("Could not find action", e);
|
||||
sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
|
||||
} catch (Exception e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* Copyright 2006 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 org.springframework.security.webwork;
|
||||
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.springframework.security.ui.ExceptionTranslationFilter;
|
||||
|
||||
import com.opensymphony.webwork.dispatcher.DispatcherUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@link com.opensymphony.webwork.dispatcher.FilterDispatcher} that will setup WebWork to ignore Acegi exceptions so
|
||||
* they can be processed by {@link ExceptionTranslationFilter}
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Set it up in your web.xml instead of WebWork provided {@link com.opensymphony.webwork.dispatcher.FilterDispatcher}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This is meant to be fixed inside WebWork, see <a href="http://jira.opensymphony.com/browse/WW-291">WW-291</a>. Known
|
||||
* broken versions are 2.2.3 and 2.2.4.
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class FilterDispatcher extends com.opensymphony.webwork.dispatcher.FilterDispatcher {
|
||||
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
super.init(filterConfig);
|
||||
DispatcherUtils.setInstance(new AcegiDispatcherUtils(filterConfig.getServletContext()));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue