25 changed files with 0 additions and 2588 deletions
@ -1,36 +0,0 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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)); |
||||
} |
||||
} |
||||
@ -1,23 +0,0 @@
@@ -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 @@
@@ -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 @@
@@ -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