blob: ed21da36abd671825660459ab28e1ed830596e30 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.ofbiz.product.category;
import static org.ofbiz.base.util.UtilGenerics.checkMap;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.GeneralException;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilHttp;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilObject;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.DelegatorFactory;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.product.category.ftl.UrlRegexpTransform;
import org.ofbiz.security.Security;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.webapp.control.ConfigXMLReader;
import org.ofbiz.webapp.control.ConfigXMLReader.ControllerConfig;
import org.ofbiz.webapp.control.ContextFilter;
import org.ofbiz.webapp.control.WebAppConfigurationException;
/**
* UrlRegexpContextFilter - Restricts access to raw files and configures servlet objects.
*/
public class UrlRegexpContextFilter extends ContextFilter {
public static final String module = UrlRegexpContextFilter.class.getName();
/**
* @throws GeneralException
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String uri = httpRequest.getRequestURI();
boolean forwarded = UrlRegexpTransform.forwardUri(httpResponse, uri);
if (forwarded) {
return;
}
URL controllerConfigURL = ConfigXMLReader.getControllerConfigURL(config.getServletContext());
ControllerConfig controllerConfig = null;
Map<String, ConfigXMLReader.RequestMap> requestMaps = null;
try {
controllerConfig = ConfigXMLReader.getControllerConfig(controllerConfigURL);
requestMaps = controllerConfig.getRequestMapMap();
} catch (WebAppConfigurationException e) {
Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module);
throw new ServletException(e);
}
Set<String> uris = requestMaps.keySet();
// NOTE: the following part is copied from org.ofbiz.webapp.control.ContextFilter.doFilter method, please update this if framework is updated.
// Debug.logInfo("Running ContextFilter.doFilter", module);
// ----- Servlet Object Setup -----
// set the cached class loader for more speedy running in this thread
// set the ServletContext in the request for future use
httpRequest.setAttribute("servletContext", config.getServletContext());
// set the webSiteId in the session
if (UtilValidate.isEmpty(httpRequest.getSession().getAttribute("webSiteId"))) {
httpRequest.getSession().setAttribute("webSiteId", config.getServletContext().getAttribute("webSiteId"));
}
// set the filesystem path of context root.
httpRequest.setAttribute("_CONTEXT_ROOT_", config.getServletContext().getRealPath("/"));
// set the server root url
String serverRootUrl = UtilHttp.getServerRootUrl(httpRequest);
httpRequest.setAttribute("_SERVER_ROOT_URL_", serverRootUrl);
// request attributes from redirect call
String reqAttrMapHex = (String) httpRequest.getSession().getAttribute("_REQ_ATTR_MAP_");
if (UtilValidate.isNotEmpty(reqAttrMapHex)) {
byte[] reqAttrMapBytes = StringUtil.fromHexString(reqAttrMapHex);
Map<String, Object> reqAttrMap = checkMap(UtilObject.getObject(reqAttrMapBytes), String.class, Object.class);
if (reqAttrMap != null) {
for (Map.Entry<String, Object> entry : reqAttrMap.entrySet()) {
httpRequest.setAttribute(entry.getKey(), entry.getValue());
}
}
httpRequest.getSession().removeAttribute("_REQ_ATTR_MAP_");
}
// ----- Context Security -----
// check if we are disabled
String disableSecurity = config.getInitParameter("disableContextSecurity");
if (disableSecurity != null && "Y".equalsIgnoreCase(disableSecurity)) {
chain.doFilter(httpRequest, httpResponse);
return;
}
// check if we are told to redirect everthing
String redirectAllTo = config.getInitParameter("forceRedirectAll");
if (UtilValidate.isNotEmpty(redirectAllTo)) {
// little trick here so we don't loop on ourself
if (httpRequest.getSession().getAttribute("_FORCE_REDIRECT_") == null) {
httpRequest.getSession().setAttribute("_FORCE_REDIRECT_", "true");
Debug.logWarning("Redirecting user to: " + redirectAllTo, module);
if (!redirectAllTo.toLowerCase().startsWith("http")) {
redirectAllTo = httpRequest.getContextPath() + redirectAllTo;
}
httpResponse.sendRedirect(redirectAllTo);
return;
} else {
httpRequest.getSession().removeAttribute("_FORCE_REDIRECT_");
chain.doFilter(httpRequest, httpResponse);
return;
}
}
// test to see if we have come through the control servlet already, if not do the processing
String requestPath = null;
String contextUri = null;
if (httpRequest.getAttribute(ContextFilter.FORWARDED_FROM_SERVLET) == null) {
if (debug) Debug.log("[Domain]: " + httpRequest.getServerName() + " [Request]: " + httpRequest.getRequestURI(), module);
requestPath = httpRequest.getServletPath();
if (requestPath == null) requestPath = "";
if (requestPath.lastIndexOf("/") > 0) {
if (requestPath.indexOf("/") == 0) {
requestPath = "/" + requestPath.substring(1, requestPath.indexOf("/", 1));
} else {
requestPath = requestPath.substring(1, requestPath.indexOf("/"));
}
}
String requestInfo = httpRequest.getServletPath();
if (requestInfo == null) requestInfo = "";
if (requestInfo.lastIndexOf("/") >= 0) {
requestInfo = requestInfo.substring(0, requestInfo.lastIndexOf("/")) + "/*";
}
StringBuilder contextUriBuffer = new StringBuilder();
if (httpRequest.getContextPath() != null) {
contextUriBuffer.append(httpRequest.getContextPath());
}
if (httpRequest.getServletPath() != null) {
contextUriBuffer.append(httpRequest.getServletPath());
}
if (httpRequest.getPathInfo() != null) {
contextUriBuffer.append(httpRequest.getPathInfo());
}
contextUri = contextUriBuffer.toString();
List<String> pathItemList = StringUtil.split(httpRequest.getPathInfo(), "/");
String viewName = "";
if (pathItemList != null) {
viewName = pathItemList.get(0);
}
// Debug.logInfo("In ContextFilter.doFilter, FORWARDED_FROM_SERVLET is NOT set", module);
String allowedPath = config.getInitParameter("allowedPaths");
String redirectPath = config.getInitParameter("redirectPath");
String errorCode = config.getInitParameter("errorCode");
List<String> allowList = StringUtil.split(allowedPath, ":");
allowList.add("/"); // No path is allowed.
if (UtilValidate.isNotEmpty(httpRequest.getServletPath())) {
allowList.add(""); // No path is allowed if servlet path is not empty.
}
// Verbose Debugging
if (Debug.verboseOn()) {
for (String allow : allowList) {
Debug.logVerbose("[Allow]: " + allow, module);
}
Debug.logVerbose("[Request path]: " + requestPath, module);
Debug.logVerbose("[Request info]: " + requestInfo, module);
Debug.logVerbose("[Servlet path]: " + httpRequest.getServletPath(), module);
Debug.logVerbose("[View name]: " + viewName, module);
Debug.logVerbose("[Not In AllowList]: " + (!allowList.contains(requestPath) && !allowList.contains(requestInfo) && !allowList.contains(httpRequest.getServletPath())), module);
Debug.logVerbose("[Not In controller]: " + (UtilValidate.isEmpty(requestPath) && UtilValidate.isEmpty(httpRequest.getServletPath()) && !uris.contains(viewName)), module);
}
// check to make sure the requested url is allowed
if (!allowList.contains(requestPath) && !allowList.contains(requestInfo) && !allowList.contains(httpRequest.getServletPath())
&& (UtilValidate.isEmpty(requestPath) && UtilValidate.isEmpty(httpRequest.getServletPath()) && !uris.contains(viewName))) {
String filterMessage = "[Filtered request]: " + contextUri;
if (redirectPath == null) {
int error = 404;
if (UtilValidate.isNotEmpty(errorCode)) {
try {
error = Integer.parseInt(errorCode);
} catch (NumberFormatException nfe) {
Debug.logWarning(nfe, "Error code specified would not parse to Integer : " + errorCode, module);
}
}
filterMessage = filterMessage + " (" + error + ")";
httpResponse.sendError(error, contextUri);
} else {
filterMessage = filterMessage + " (" + redirectPath + ")";
if (!redirectPath.toLowerCase().startsWith("http")) {
redirectPath = httpRequest.getContextPath() + redirectPath;
}
// httpResponse.sendRedirect(redirectPath);
if (uri.equals("") || uri.equals("/")) {
// redirect without any url change in browser
RequestDispatcher rd = request.getRequestDispatcher(redirectPath);
rd.forward(request, response);
} else {
// redirect with url change in browser
httpResponse.setStatus(SeoConfigUtil.DEFAULT_RESPONSECODE);
httpResponse.setHeader("Location", redirectPath);
}
}
Debug.logWarning(filterMessage, module);
return;
}
}
// check if multi tenant is enabled
String useMultitenant = UtilProperties.getPropertyValue("general.properties", "multitenant");
if ("Y".equals(useMultitenant)) {
// get tenant delegator by domain name
String serverName = httpRequest.getServerName();
try {
// if tenant was specified, replace delegator with the new per-tenant delegator and set tenantId to session attribute
Delegator delegator = getDelegator(config.getServletContext());
List<GenericValue> tenants = delegator.findList("Tenant", EntityCondition.makeCondition("domainName", serverName), null, UtilMisc.toList("-createdStamp"), null, false);
if (UtilValidate.isNotEmpty(tenants)) {
GenericValue tenant = EntityUtil.getFirst(tenants);
String tenantId = tenant.getString("tenantId");
// if the request path is a root mount then redirect to the initial path
if (UtilValidate.isNotEmpty(requestPath) && requestPath.equals(contextUri)) {
String initialPath = tenant.getString("initialPath");
if (UtilValidate.isNotEmpty(initialPath) && !"/".equals(initialPath)) {
((HttpServletResponse) response).sendRedirect(initialPath);
return;
}
}
// make that tenant active, setup a new delegator and a new dispatcher
String tenantDelegatorName = delegator.getDelegatorBaseName() + "#" + tenantId;
httpRequest.getSession().setAttribute("delegatorName", tenantDelegatorName);
// after this line the delegator is replaced with the new per-tenant delegator
delegator = DelegatorFactory.getDelegator(tenantDelegatorName);
config.getServletContext().setAttribute("delegator", delegator);
// clear web context objects
// config.getServletContext().setAttribute("authorization", null);
config.getServletContext().setAttribute("security", null);
config.getServletContext().setAttribute("dispatcher", null);
// initialize authorizer
// getAuthz();
// initialize security
Security security = getSecurity();
// initialize the services dispatcher
LocalDispatcher dispatcher = getDispatcher(config.getServletContext());
// set web context objects
httpRequest.getSession().setAttribute("dispatcher", dispatcher);
httpRequest.getSession().setAttribute("security", security);
httpRequest.setAttribute("tenantId", tenantId);
}
// NOTE DEJ20101130: do NOT always put the delegator name in the user's session because the user may
// have logged in and specified a tenant, and even if no Tenant record with a matching domainName field
// is found this will change the user's delegator back to the base one instead of the one for the
// tenant specified on login
// httpRequest.getSession().setAttribute("delegatorName", delegator.getDelegatorName());
} catch (GenericEntityException e) {
Debug.logWarning(e, "Unable to get Tenant", module);
}
}
// we're done checking; continue on
chain.doFilter(httpRequest, httpResponse);
// reset thread local security
// AbstractAuthorization.clearThreadLocal();
}
}