Clover coverage report - Acegi Security System for Spring - 1.0.0-RC1
Coverage timestamp: Mon Dec 5 2005 09:05:15 EST
file stats: LOC: 433   Methods: 30
NCLOC: 245   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CaptchaEntryPoint.java 93.3% 87.3% 63.3% 84.1%
coverage coverage
 1    /* Copyright 2004, 2005 Acegi Technology Pty Limited
 2    *
 3    * Licensed under the Apache License, Version 2.0 (the "License");
 4    * you may not use this file except in compliance with the License.
 5    * You may obtain a copy of the License at
 6    *
 7    * http://www.apache.org/licenses/LICENSE-2.0
 8    *
 9    * Unless required by applicable law or agreed to in writing, software
 10    * distributed under the License is distributed on an "AS IS" BASIS,
 11    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    * See the License for the specific language governing permissions and
 13    * limitations under the License.
 14    */
 15   
 16    package org.acegisecurity.captcha;
 17   
 18    import org.acegisecurity.securechannel.ChannelEntryPoint;
 19    import org.acegisecurity.util.PortMapper;
 20    import org.acegisecurity.util.PortMapperImpl;
 21    import org.acegisecurity.util.PortResolver;
 22    import org.acegisecurity.util.PortResolverImpl;
 23   
 24    import org.apache.commons.logging.Log;
 25    import org.apache.commons.logging.LogFactory;
 26   
 27    import org.springframework.beans.factory.InitializingBean;
 28   
 29    import org.springframework.util.Assert;
 30   
 31    import java.io.IOException;
 32    import java.io.UnsupportedEncodingException;
 33   
 34    import java.net.URLEncoder;
 35   
 36    import java.util.Enumeration;
 37   
 38    import javax.servlet.ServletException;
 39    import javax.servlet.ServletRequest;
 40    import javax.servlet.ServletResponse;
 41    import javax.servlet.http.HttpServletRequest;
 42    import javax.servlet.http.HttpServletResponse;
 43   
 44   
 45    /**
 46    * The captcha entry point : redirect to the captcha test page. <br>
 47    *
 48    * <p>
 49    * This entry point can force the use of SSL : see {@link #getForceHttps()}<br>
 50    * </p>
 51    * This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}<br>
 52    * / Original request can be added to the redirect path using a custom
 53    * translation : see {@link #setIncludeOriginalRequest(boolean)}<br>
 54    * Original request is translated using URLEncoding and the following
 55    * translation mapping in the redirect url :
 56    *
 57    * <ul>
 58    * <li>
 59    * original url => {@link #getOriginalRequestUrlParameterName()}
 60    * </li>
 61    * <li>
 62    * If {@link #isIncludeOriginalParameters()}
 63    * </li>
 64    * <li>
 65    * original method => {@link #getOriginalRequestMethodParameterName()}
 66    * </li>
 67    * <li>
 68    * original parameters => {@link #getOriginalRequestParametersParameterName()}
 69    * </li>
 70    * <li>
 71    * The original parameters string is contructed using :
 72    *
 73    * <ul>
 74    * <li>
 75    * a parameter separator {@link #getOriginalRequestParametersSeparator()}
 76    * </li>
 77    * <li>
 78    * a parameter name value pair separator for each parameter {@link
 79    * #getOriginalRequestParametersNameValueSeparator()}
 80    * </li>
 81    * </ul>
 82    *
 83    * </li>
 84    * </ul>
 85    *
 86    * <br><br>
 87    * Default values :<br>
 88    * forceHttps = false<br>
 89    * includesOriginalRequest = true<br>
 90    * includesOriginalParameters = false<br>
 91    * isOutsideWebApp=false<br>
 92    * originalRequestUrlParameterName =original_requestUrl <br>
 93    * originalRequestParametersParameterName = original_request_parameters<br>
 94    * originalRequestParametersNameValueSeparator = __ <br>
 95    * originalRequestParametersSeparator = ;; <br>
 96    * originalRequestMethodParameterName = original_request_method <br>
 97    * urlEncodingCharset = UTF-8<br>
 98    *
 99    * @author marc antoine Garrigue
 100    * @version $Id: CaptchaEntryPoint.java,v 1.4 2005/11/17 00:55:49 benalex Exp $
 101    */
 102    public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
 103    //~ Static fields/initializers =============================================
 104   
 105    // ~ Static fields/initializers
 106    // =============================================
 107    private static final Log logger = LogFactory.getLog(CaptchaEntryPoint.class);
 108   
 109    //~ Instance fields ========================================================
 110   
 111    // ~ Instance fields
 112    // ========================================================
 113    private PortMapper portMapper = new PortMapperImpl();
 114    private PortResolver portResolver = new PortResolverImpl();
 115    private String captchaFormUrl;
 116    private String originalRequestMethodParameterName = "original_request_method";
 117    private String originalRequestParametersNameValueSeparator = "__";
 118    private String originalRequestParametersParameterName = "original_request_parameters";
 119    private String originalRequestParametersSeparator = ";;";
 120    private String originalRequestUrlParameterName = "original_requestUrl";
 121    private String urlEncodingCharset = "UTF-8";
 122    private boolean forceHttps = false;
 123    private boolean includeOriginalParameters = false;
 124    private boolean includeOriginalRequest = true;
 125    private boolean isOutsideWebApp = false;
 126   
 127    //~ Methods ================================================================
 128   
 129    /**
 130    * The URL where the <code>CaptchaProcessingFilter</code> login page can be
 131    * found. Should be relative to the web-app context path, and include a
 132    * leading <code>/</code>
 133    *
 134    * @param captchaFormUrl
 135    */
 136  14 public void setCaptchaFormUrl(String captchaFormUrl) {
 137  14 this.captchaFormUrl = captchaFormUrl;
 138    }
 139   
 140    /**
 141    * DOCUMENT ME!
 142    *
 143    * @return the captcha test page to redirect to.
 144    */
 145  1 public String getCaptchaFormUrl() {
 146  1 return captchaFormUrl;
 147    }
 148   
 149    // ~ Methods
 150    // ================================================================
 151   
 152    /**
 153    * Set to true to force captcha form access to be via https. If this value
 154    * is ture (the default is false), and the incoming request for the
 155    * protected resource which triggered the interceptor was not already
 156    * <code>https</code>, then
 157    *
 158    * @param forceHttps
 159    */
 160  8 public void setForceHttps(boolean forceHttps) {
 161  8 this.forceHttps = forceHttps;
 162    }
 163   
 164  2 public boolean getForceHttps() {
 165  2 return forceHttps;
 166    }
 167   
 168  2 public void setIncludeOriginalParameters(boolean includeOriginalParameters) {
 169  2 this.includeOriginalParameters = includeOriginalParameters;
 170    }
 171   
 172  0 public boolean isIncludeOriginalParameters() {
 173  0 return includeOriginalParameters;
 174    }
 175   
 176    /**
 177    * If set to true, the original request url will be appended to the
 178    * redirect url using the {@link #getOriginalRequestUrlParameterName()}.
 179    *
 180    * @param includeOriginalRequest
 181    */
 182  9 public void setIncludeOriginalRequest(boolean includeOriginalRequest) {
 183  9 this.includeOriginalRequest = includeOriginalRequest;
 184    }
 185   
 186  2 public boolean isIncludeOriginalRequest() {
 187  2 return includeOriginalRequest;
 188    }
 189   
 190  0 public void setOriginalRequestMethodParameterName(
 191    String originalRequestMethodParameterName) {
 192  0 this.originalRequestMethodParameterName = originalRequestMethodParameterName;
 193    }
 194   
 195  0 public String getOriginalRequestMethodParameterName() {
 196  0 return originalRequestMethodParameterName;
 197    }
 198   
 199  0 public void setOriginalRequestParametersNameValueSeparator(
 200    String originalRequestParametersNameValueSeparator) {
 201  0 this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator;
 202    }
 203   
 204  0 public String getOriginalRequestParametersNameValueSeparator() {
 205  0 return originalRequestParametersNameValueSeparator;
 206    }
 207   
 208  0 public void setOriginalRequestParametersParameterName(
 209    String originalRequestParametersParameterName) {
 210  0 this.originalRequestParametersParameterName = originalRequestParametersParameterName;
 211    }
 212   
 213  0 public String getOriginalRequestParametersParameterName() {
 214  0 return originalRequestParametersParameterName;
 215    }
 216   
 217  0 public void setOriginalRequestParametersSeparator(
 218    String originalRequestParametersSeparator) {
 219  0 this.originalRequestParametersSeparator = originalRequestParametersSeparator;
 220    }
 221   
 222  0 public String getOriginalRequestParametersSeparator() {
 223  0 return originalRequestParametersSeparator;
 224    }
 225   
 226  1 public void setOriginalRequestUrlParameterName(
 227    String originalRequestUrlParameterName) {
 228  1 this.originalRequestUrlParameterName = originalRequestUrlParameterName;
 229    }
 230   
 231  2 public String getOriginalRequestUrlParameterName() {
 232  2 return originalRequestUrlParameterName;
 233    }
 234   
 235    /**
 236    * if set to true, the {@link #commence(ServletRequest, ServletResponse)}
 237    * method uses the {@link #getCaptchaFormUrl()} as a complete URL, else it
 238    * as a 'inside WebApp' path.
 239    *
 240    * @param isOutsideWebApp
 241    */
 242  2 public void setOutsideWebApp(boolean isOutsideWebApp) {
 243  2 this.isOutsideWebApp = isOutsideWebApp;
 244    }
 245   
 246  2 public boolean isOutsideWebApp() {
 247  2 return isOutsideWebApp;
 248    }
 249   
 250  13 public void setPortMapper(PortMapper portMapper) {
 251  13 this.portMapper = portMapper;
 252    }
 253   
 254  1 public PortMapper getPortMapper() {
 255  1 return portMapper;
 256    }
 257   
 258  12 public void setPortResolver(PortResolver portResolver) {
 259  12 this.portResolver = portResolver;
 260    }
 261   
 262  1 public PortResolver getPortResolver() {
 263  1 return portResolver;
 264    }
 265   
 266  0 public void setUrlEncodingCharset(String urlEncodingCharset) {
 267  0 this.urlEncodingCharset = urlEncodingCharset;
 268    }
 269   
 270  0 public String getUrlEncodingCharset() {
 271  0 return urlEncodingCharset;
 272    }
 273   
 274  14 public void afterPropertiesSet() throws Exception {
 275  14 Assert.hasLength(captchaFormUrl, "captchaFormUrl must be specified");
 276  13 Assert.hasLength(originalRequestMethodParameterName,
 277    "originalRequestMethodParameterName must be specified");
 278  13 Assert.hasLength(originalRequestParametersNameValueSeparator,
 279    "originalRequestParametersNameValueSeparator must be specified");
 280  13 Assert.hasLength(originalRequestParametersParameterName,
 281    "originalRequestParametersParameterName must be specified");
 282  13 Assert.hasLength(originalRequestParametersSeparator,
 283    "originalRequestParametersSeparator must be specified");
 284  13 Assert.hasLength(originalRequestUrlParameterName,
 285    "originalRequestUrlParameterName must be specified");
 286  13 Assert.hasLength(urlEncodingCharset,
 287    "urlEncodingCharset must be specified");
 288  13 Assert.notNull(portMapper, "portMapper must be specified");
 289  12 Assert.notNull(portResolver, "portResolver must be specified");
 290  11 URLEncoder.encode(" fzaef é& à ", urlEncodingCharset);
 291    }
 292   
 293  20 public void commence(ServletRequest request, ServletResponse response)
 294    throws IOException, ServletException {
 295  20 StringBuffer redirectUrl = new StringBuffer();
 296  20 HttpServletRequest req = (HttpServletRequest) request;
 297   
 298  20 if (isOutsideWebApp) {
 299  5 redirectUrl = redirectUrl.append(captchaFormUrl);
 300    } else {
 301  15 buildInternalRedirect(redirectUrl, req);
 302    }
 303   
 304  20 if (includeOriginalRequest) {
 305  11 includeOriginalRequest(redirectUrl, req);
 306    }
 307   
 308    // add post parameter? DONE!
 309  20 if (logger.isDebugEnabled()) {
 310  0 logger.debug("Redirecting to: " + redirectUrl);
 311    }
 312   
 313  20 ((HttpServletResponse) response).sendRedirect(redirectUrl.toString());
 314    }
 315   
 316  15 private void buildInternalRedirect(StringBuffer redirectUrl,
 317    HttpServletRequest req) {
 318    // construct it
 319  15 StringBuffer simpleRedirect = new StringBuffer();
 320   
 321  15 String scheme = req.getScheme();
 322  15 String serverName = req.getServerName();
 323  15 int serverPort = portResolver.getServerPort(req);
 324  15 String contextPath = req.getContextPath();
 325  15 boolean includePort = true;
 326   
 327  15 if ("http".equals(scheme.toLowerCase()) && (serverPort == 80)) {
 328  2 includePort = false;
 329    }
 330   
 331  15 if ("https".equals(scheme.toLowerCase()) && (serverPort == 443)) {
 332  1 includePort = false;
 333    }
 334   
 335  15 simpleRedirect.append(scheme);
 336  15 simpleRedirect.append("://");
 337  15 simpleRedirect.append(serverName);
 338   
 339  15 if (includePort) {
 340  12 simpleRedirect.append(":");
 341  12 simpleRedirect.append(serverPort);
 342    }
 343   
 344  15 simpleRedirect.append(contextPath);
 345  15 simpleRedirect.append(captchaFormUrl);
 346   
 347  15 if (forceHttps && req.getScheme().equals("http")) {
 348  6 Integer httpPort = new Integer(portResolver.getServerPort(req));
 349  6 Integer httpsPort = (Integer) portMapper.lookupHttpsPort(httpPort);
 350   
 351  6 if (httpsPort != null) {
 352  5 if (httpsPort.intValue() == 443) {
 353  1 includePort = false;
 354    } else {
 355  4 includePort = true;
 356    }
 357   
 358  5 redirectUrl.append("https://");
 359  5 redirectUrl.append(serverName);
 360   
 361  5 if (includePort) {
 362  4 redirectUrl.append(":");
 363  4 redirectUrl.append(httpsPort);
 364    }
 365   
 366  5 redirectUrl.append(contextPath);
 367  5 redirectUrl.append(captchaFormUrl);
 368    } else {
 369  1 redirectUrl.append(simpleRedirect);
 370    }
 371    } else {
 372  9 redirectUrl.append(simpleRedirect);
 373    }
 374    }
 375   
 376  11 private void includeOriginalRequest(StringBuffer redirectUrl,
 377    HttpServletRequest req) {
 378    // add original request to the url
 379  11 if (redirectUrl.indexOf("?") >= 0) {
 380  4 redirectUrl.append("&");
 381    } else {
 382  7 redirectUrl.append("?");
 383    }
 384   
 385  11 redirectUrl.append(originalRequestUrlParameterName);
 386  11 redirectUrl.append("=");
 387   
 388  11 try {
 389  11 redirectUrl.append(URLEncoder.encode(req.getRequestURL().toString(),
 390    urlEncodingCharset));
 391    } catch (UnsupportedEncodingException e) {
 392  0 logger.warn(e);
 393    }
 394   
 395    //append method
 396  11 redirectUrl.append("&");
 397  11 redirectUrl.append(originalRequestMethodParameterName);
 398  11 redirectUrl.append("=");
 399  11 redirectUrl.append(req.getMethod());
 400   
 401  11 if (includeOriginalParameters) {
 402    // append query params
 403  6 redirectUrl.append("&");
 404  6 redirectUrl.append(originalRequestParametersParameterName);
 405  6 redirectUrl.append("=");
 406   
 407  6 StringBuffer qp = new StringBuffer();
 408  6 Enumeration parameters = req.getParameterNames();
 409   
 410  6 if ((parameters != null) && parameters.hasMoreElements()) {
 411    //qp.append("?");
 412  6 while (parameters.hasMoreElements()) {
 413  12 String name = parameters.nextElement().toString();
 414  12 String value = req.getParameter(name);
 415  12 qp.append(name);
 416  12 qp.append(originalRequestParametersNameValueSeparator);
 417  12 qp.append(value);
 418   
 419  12 if (parameters.hasMoreElements()) {
 420  6 qp.append(originalRequestParametersSeparator);
 421    }
 422    }
 423    }
 424   
 425  6 try {
 426  6 redirectUrl.append(URLEncoder.encode(qp.toString(),
 427    urlEncodingCharset));
 428    } catch (Exception e) {
 429  0 logger.warn(e);
 430    }
 431    }
 432    }
 433    }