/** * Copyright 2005-2016 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.filter; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hdiv.context.RequestContextHolder; import org.hdiv.state.IState; import org.hdiv.util.HDIVErrorCodes; import org.hdiv.util.Method; import org.hdiv.util.UtilsJsf; /** * <p> * JSF's ValidatorHelper. * </p> * <p> * Differences with core's validation helper: * </p> * <ul> * <li>If it is a JSF request (with JSF state) doesn't do any validation. If it is a HDIV request (with HDIV state) delegates validation to * core's validation helper.</li> * <li>isTheSameAction() method is overwritten because action checking changes.</li> * <li>addParameterToRequest(..) method is overwritten because in the JSF version confidentiality is disabled and RequestWrapper is not * used. Consequently, no parameter is added to the request.</li> * </ul> * * @author Gotzon Illarramendi */ public class JsfValidatorHelper extends ValidatorHelperRequest { /** * Commons Logging instance. */ private static final Log log = LogFactory.getLog(JsfValidatorHelper.class); /** * Request attribute that has a true value only if the request has a view state. */ public static final String IS_VIEW_STATE_REQUEST = JsfValidatorHelper.class.getName() + "IS_VIEW_STATE_REQUEST"; /* * (non-Javadoc) * * @see org.hdiv.filter.ValidatorHelperRequest#preValidate(javax.servlet.http.HttpServletRequest, java.lang.String) */ @Override protected ValidatorHelperResult preValidate(final ValidationContext vc) { RequestContextHolder ctx = vc.getRequestContext(); if (log.isDebugEnabled()) { log.debug("URI: " + ctx.getRequestURI()); } Map<String, String[]> requestMap = ctx.getParameterMap(); boolean isViewState = UtilsJsf.hasFacesViewParamName(requestMap.keySet()); ctx.setAttribute(IS_VIEW_STATE_REQUEST, isViewState); if (isViewState) { // Contains parameter with JSF state, it is a JSF request. if (log.isDebugEnabled()) { log.debug("Request contains view state"); } if (hdivConfig.isStartPage(vc.getTarget(), Method.secureValueOf(ctx.getMethod()))) { // It is an init page if (log.isDebugEnabled()) { log.debug("Request is start page"); } return ValidatorHelperResult.VALIDATION_NOT_REQUIRED; } return ValidatorHelperResult.VALID; } // Delegate to ValidatorHelperRequest return null; } /* * (non-Javadoc) * * @see org.hdiv.filter.ValidatorHelperRequest#isTheSameAction(javax.servlet.http.HttpServletRequest, java.lang.String, * org.hdiv.state.IState) */ @Override public ValidatorHelperResult isTheSameAction(final RequestContextHolder request, final String target, final IState state) { // First check if target and action are the same // When outputlink is used target matches action if (state.getAction().equalsIgnoreCase(target)) { return ValidatorHelperResult.VALID; } if (target.endsWith("/")) { String actionSlash = state.getAction() + "/"; if (actionSlash.equalsIgnoreCase(target)) { return ValidatorHelperResult.VALID; } } // In the case of <h:link> component, action may not have context-path and servlet mapping. // e.g. action=/view/viewAccount, target=/hdiv-jsf/view/viewAccount.faces and // targetWithoutContextPath = /view/viewAccount.faces String targetWithoutServletAndContextPath = target.substring(0, target.indexOf('.')); boolean isActionState = state.getAction().equalsIgnoreCase(targetWithoutServletAndContextPath); if (isActionState) { return ValidatorHelperResult.VALID; } // In other case, <h:link> component may have context path but not servlet mapping String targetWithoutServlet = target.substring(0, target.indexOf('.')); isActionState = state.getAction().equalsIgnoreCase(targetWithoutServlet); if (isActionState) { return ValidatorHelperResult.VALID; } if (log.isDebugEnabled()) { log.debug("isTheSameAction=false"); log.debug(" target:" + target); log.debug(" state action:" + state.getAction()); } ValidatorError error = new ValidatorError(HDIVErrorCodes.INVALID_ACTION, target); return new ValidatorHelperResult(error); } /* * (non-Javadoc) * * @see org.hdiv.filter.ValidatorHelperRequest#addParameterToRequest(javax.servlet.http.HttpServletRequest, java.lang.String, * java.lang.Object) */ protected void addParameterToRequest(final HttpServletRequest request, final String name, final Object value) { throw new IllegalStateException("Confidentiality is not implemented in JSF."); } }