/**
* Copyright 2005-2010 hdiv.org
*
* 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.hdiv.config;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hdiv.validator.IValidation;
/**
* Class containing HDIV configuration initialized from Spring Factory.
*
* @author Roberto Velasco
* @author Gorka Vicente
* @author Gotzon Illarramendi
*/
public class HDIVConfig {
private boolean disableHDIV = false;
/**
* Map with the pages that will not be Treated by the HDIV filter. The init pages
* are initialized by the Spring factory.
*/
protected Hashtable startPages;
/**
* Map with the parameters that will not be validated by the HDIV filter. The
* init parameters are initialized by the Spring factory.
*/
private Hashtable startParameters;
/**
* Map of the validated actions that are init pages. It is necessary to create
* this map to improve the efficiency at checking init-pages.
*
* @since HDIV 1.1.1
*/
private Hashtable matchedPages;
/**
* Map of the validated parameters that are init parameters. It is necessary to
* create this map to improve the efficiency at checking init-parameters.
*
* @since HDIV 1.1.1
*/
private Hashtable matchedParameters;
/**
* Error page to which HDIV will redirect the request if it doesn't pass the HDIV
* validation.
*/
private String errorPage;
/**
* Confidentiality indicator to know if information is accessible only for those
* who are authorized.
*/
private Boolean confidentiality;
/**
* Parameters which HDIV validation will not be appied to.
*/
private Map paramsWithoutValidation;
/**
* Validations for editable fields (text/textarea) defined by the user in the
* hdiv-validations.xml configuration file of Spring.
*/
private HDIVValidations validations;
/**
* If <code>cookiesIntegrity</code> is true, cookie integrity will not be
* applied.
*/
private boolean cookiesIntegrity;
/**
* If <code>cookiesConfidentiality</code> is true, cookie confidentiality will
* not be applied.
*/
private boolean cookiesConfidentiality;
/**
* if <code>avoidValidationInUrlsWithoutParams</code> is true, HDIV validation will
* not be applied in urls without parameters.
*
* @since HDIV 2.1.0
*/
private boolean avoidValidationInUrlsWithoutParams;
/**
* Extensions that we have to protect with HDIV's state.
* @since HDIV 2.0
*/
private Hashtable protectedURLPatterns;
/**
* Extensions that we have not to protect with HDIV's state.
* @since HDIV 2.1.0
*/
private List excludedURLExtensions;
public boolean isDisableHDIV() {
return disableHDIV;
}
public void setDisableHDIV(boolean disableHDIV) {
this.disableHDIV = disableHDIV;
}
/**
* Checks if <code>parameter</code> is an init parameter, in which case it will
* not be treated by HDIV.
*
* @param parameter Parameter name
* @return True if <code>parameter</code> is an init parameter. False
* otherwise.
*/
public boolean isStartParameter(String parameter) {
if (this.matchedParameters.containsKey(parameter)) {
return true;
}
String value = this.checkValue(parameter, this.startParameters);
if (value == null) {
return false;
}
this.matchedParameters.put(parameter, value);
return true;
}
/**
* Checks if <code>target</code> is an init action, in which case it will not
* be treated by HDIV.
*
* @param target target name
* @return True if <code>target</code> is an init action. False otherwise.
*/
public boolean isStartPage(String target) {
if (this.matchedPages.containsKey(target)) {
return true;
}
String value = this.checkValue(target, this.startPages);
if (value == null) {
return false;
}
this.matchedPages.put(target, value);
return true;
}
public boolean hasExtensionToExclude(String path){
if(this.excludedURLExtensions == null){
return false;
}
if (path.indexOf("?") > 0) {
path = path.substring(0, path.indexOf("?"));
}
if (path.charAt(path.length() - 1) == '/') {
return false;
}
int pound = path.indexOf("#");
if (pound >= 0) {
path = path.substring(0, pound);
}
for (Iterator iter = this.excludedURLExtensions.iterator(); iter.hasNext();) {
String extension = (String) iter.next();
if (path.endsWith(extension)) {
return true;
}
}
return false;
}
/**
* Checks if the parameter <code>parameter</code> is defined by the user as a
* no required validation parameter for the action <code>action</code>.
*
* @param action action name
* @param parameter parameter name
* @return True if it is parameter that needs no validation. False otherwise.
*/
public boolean isParameterWithoutValidation(String action, String parameter) {
if(this.paramsWithoutValidation == null){
return false;
}
Pattern p = null;
Matcher m = null;
String key = null;
for (Iterator iter = this.paramsWithoutValidation.keySet().iterator(); iter.hasNext();) {
key = (String) iter.next();
p = Pattern.compile(key);
m = p.matcher(action);
if (m.matches()) {
List parametersWithoutValidation = (List) this.paramsWithoutValidation.get(key);
String definedParameter = null;
for (int i = 0; i < parametersWithoutValidation.size(); i++) {
definedParameter = (String) parametersWithoutValidation.get(i);
p = Pattern.compile(definedParameter);
m = p.matcher(parameter);
if (m.matches()) {
return true;
}
}
}
}
return false;
}
/**
* Checks if <code>value</code> is an init action or parameter, in which case
* it will not be treated by HDIV.
*
* @param value target or parameter name
* @param startValues Map with start values
* @return True if <code>value</code> is an init action or parameter. False
* otherwise.
* @since HDIV 1.1.1
*/
public String checkValue(String value, Map startValues) {
String key = null;
Pattern p = null;
Matcher m = null;
for (Iterator iter = startValues.keySet().iterator(); iter.hasNext();) {
key = (String) iter.next();
p = (Pattern) startValues.get(key);
m = p.matcher(value);
if (m.matches()) {
return key;
}
}
return null;
}
/**
* Checks if the HDIV validation must be applied to the parameter
* <code>parameter</code>
*
* @param parameter Parameter name
* @param hdivParameter Name of the parameter that HDIV will include in the
* requests or/and forms which contains the state identifier parameter
* @return True if <code>parameter</code> doesn't need HDIV validation.
*/
public boolean needValidation(String parameter, String hdivParameter) {
if (this.isStartParameter(parameter) || (parameter.equals(hdivParameter))) {
return false;
}
return true;
}
public String getErrorPage() {
return errorPage;
}
public void setErrorPage(String errorPage) {
if (!errorPage.startsWith("/")) {
errorPage = "/" + errorPage;
}
this.errorPage = errorPage;
this.startPages.put(errorPage, Pattern.compile(errorPage));
}
public Boolean getConfidentiality() {
return confidentiality;
}
public void setConfidentiality(Boolean confidentiality) {
this.confidentiality = confidentiality;
}
public Map getParamsWithoutValidation() {
return paramsWithoutValidation;
}
public void setParamsWithoutValidation(Map paramsWithoutValidation) {
this.paramsWithoutValidation = paramsWithoutValidation;
}
/**
* It creates a map from the list of start pages defined by the user.
*
* @param userStartPages list of start pages defined by the user
*/
public void setUserStartPages(List userStartPages) {
this.matchedPages = new Hashtable();
this.startPages = new Hashtable();
String currentPattern;
for (int i = 0; i < userStartPages.size(); i++) {
currentPattern = (String) userStartPages.get(i);
this.startPages.put(currentPattern, Pattern.compile(currentPattern));
}
}
/**
* It creates a map from the list of init parameters defined by the user.
*
* @param userStartPages list of init parameters defined by the user
*/
public void setUserStartParameters(List userStartParameters) {
this.matchedParameters = new Hashtable();
this.startParameters = new Hashtable();
String currentPattern;
for (int i = 0; i < userStartParameters.size(); i++) {
currentPattern = (String) userStartParameters.get(i);
this.startParameters.put(currentPattern, Pattern.compile(currentPattern));
}
}
/**
* @param validations The validations to set.
* @since HDIV 1.1
*/
public void setValidations(HDIVValidations validations) {
this.validations = validations;
}
/**
* Checks if there are validations defined for editable fields
*
* @return True if validations for editable fields have been defined. False
* otherwise.
* @since HDIV 1.1
*/
public boolean existValidations() {
return ((this.validations != null) && (this.validations.getUrls() != null) && (this.validations
.getUrls().size() > 0));
}
/**
* <p>
* Checks if the values <code>values</code> are valid for the editable
* parameter <code>parameter</code>, using the validations defined in the
* hdiv-validations.xml configuration file of Spring.
* </p>
* <p>
* There are two types of validations:
* <li>accepted: the value is valid only if it passes the validation</li>
* <li>rejected: the value is rejected if doesn't pass the validation</li>
* </p>
*
* @param target target name
* @param parameter parameter name
* @param values parameter's values
* @param dataType editable data type
* @return True if the values <code>values</code> are valid for the parameter
* <code>parameter</code>.
* @since HDIV 1.1
*/
public boolean areEditableParameterValuesValid(String url, String parameter, String[] values,
String dataType) {
Pattern p = null;
Matcher m = null;
Iterator userDefinedURLs = this.validations.getUrls().keySet().iterator();
while (userDefinedURLs.hasNext()) {
String regExp = (String) userDefinedURLs.next();
p = Pattern.compile(regExp);
m = p.matcher(url);
if (m.matches()) {
List userDefinedValidations = (List) this.validations.getUrls().get(regExp);
for (int i = 0; i < userDefinedValidations.size(); i++) {
IValidation currentValidation = (IValidation) userDefinedValidations.get(i);
if (!currentValidation.validate(parameter, values, dataType)) {
return false;
}
}
}
}
return true;
}
/**
* @return Returns true if cookies' confidentiality is activated.
*/
public boolean isCookiesConfidentialityActivated() {
return (cookiesConfidentiality == false);
}
/**
* @param cookiesConfidentiality The cookiesConfidentiality to set.
*/
public void setCookiesConfidentiality(Boolean cookiesConfidentiality) {
this.cookiesConfidentiality = cookiesConfidentiality.booleanValue();
}
/**
* @return Returns true if cookies' integrity is activated.
*/
public boolean isCookiesIntegrityActivated() {
return (cookiesIntegrity == false);
}
/**
* @param cookiesIntegrity The cookiesIntegrity to set.
*/
public void setCookiesIntegrity(Boolean cookiesIntegrity) {
this.cookiesIntegrity = cookiesIntegrity.booleanValue();
}
/**
* @return Returns true if validation in urls without parameters
* is activated.
*/
public boolean isValidationInUrlsWithoutParamsActivated() {
return (avoidValidationInUrlsWithoutParams == false);
}
/**
* @param avoidValidationInUrlsWithoutParams The avoidValidationInUrlsWithoutParams to set.
*/
public void setAvoidValidationInUrlsWithoutParams(Boolean avoidValidationInUrlsWithoutParams) {
this.avoidValidationInUrlsWithoutParams = avoidValidationInUrlsWithoutParams.booleanValue();
}
/**
* @param protectedExtensions The protected extensions to set.
* @since HDIV 2.0
*/
public void setProtectedExtensions(List protectedExtensions) {
this.protectedURLPatterns = new Hashtable();
String currentProtectedExtension;
for (int i = 0; i < protectedExtensions.size(); i++) {
currentProtectedExtension = (String) protectedExtensions.get(i);
this.protectedURLPatterns.put(currentProtectedExtension, Pattern.compile(currentProtectedExtension));
}
}
public void setExcludedExtensions(List excludedExtensions)
{
this.excludedURLExtensions = new ArrayList();
String currentExtension;
for (int i = 0; i < excludedExtensions.size(); i++) {
currentExtension = (String) excludedExtensions.get(i);
this.excludedURLExtensions.add(currentExtension);
}
}
/**
* @return Returns the protected extensions.
* @since HDIV 2.0
*/
public Hashtable getProtectedURLPatterns() {
return protectedURLPatterns;
}
/**
* @return Returns the excluded extensions.
* @since HDIV 2.1.0
*/
public List getExcludedURLExtensions() {
return excludedURLExtensions;
}
}