blob: f5cf3e179718728ffc4a8bbd4fd98127db8bee1c [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.apache.ofbiz.webapp.control;
import static org.apache.ofbiz.base.util.UtilGenerics.checkMap;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilObject;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.DelegatorFactory;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.entity.util.EntityUtil;
import org.apache.ofbiz.security.Security;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.webapp.WebAppUtil;
import org.apache.ofbiz.webapp.website.WebSiteWorker;
/**
* ContextFilter - Configures objects for OFBiz applications
*/
public class ContextFilter implements Filter {
private static final String module = ContextFilter.class.getName();
protected FilterConfig config = null;
// default charset used to decode requests body data if no encoding is specified in the request
private String defaultCharacterEncoding;
private boolean isMultitenant;
/**
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
public void init(FilterConfig config) throws ServletException {
this.config = config;
// puts all init-parameters in ServletContext attributes for easier parametrization without code changes
this.putAllInitParametersInAttributes();
defaultCharacterEncoding = config.getServletContext().getInitParameter("charset");
if (UtilValidate.isEmpty(defaultCharacterEncoding)) {
defaultCharacterEncoding = "UTF-8";
}
// check the serverId
getServerId();
// initialize the delegator
WebAppUtil.getDelegator(config.getServletContext());
// initialize security
WebAppUtil.getSecurity(config.getServletContext());
// initialize the services dispatcher
WebAppUtil.getDispatcher(config.getServletContext());
// check if multi tenant is enabled
isMultitenant = EntityUtil.isMultiTenantEnabled();
// this will speed up the initial sessionId generation
new java.security.SecureRandom().nextLong();
}
/**
* @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;
// ----- Servlet Object Setup -----
// 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", WebSiteWorker.getWebSiteId(httpRequest));
}
// set the filesystem path of context root.
httpRequest.setAttribute("_CONTEXT_ROOT_", config.getServletContext().getRealPath("/"));
// set the server root url
httpRequest.setAttribute("_SERVER_ROOT_URL_", UtilHttp.getServerRootUrl(httpRequest));
if (request.getCharacterEncoding() == null) {
request.setCharacterEncoding(defaultCharacterEncoding);
}
WebAppUtil.setAttributesFromRequestBody(request);
request.setAttribute("delegator", config.getServletContext().getAttribute("delegator"));
request.setAttribute("dispatcher", config.getServletContext().getAttribute("dispatcher"));
request.setAttribute("security", config.getServletContext().getAttribute("security"));
if (isMultitenant) {
// 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 = WebAppUtil.getDelegator(config.getServletContext());
//Use base delegator for fetching data from entity of entityGroup org.apache.ofbiz.tenant
Delegator baseDelegator = DelegatorFactory.getDelegator(delegator.getDelegatorBaseName());
GenericValue tenantDomainName = EntityQuery.use(baseDelegator).from("TenantDomainName").where("domainName", serverName).queryOne();
String tenantId = null;
if(UtilValidate.isNotEmpty(tenantDomainName)) {
tenantId = tenantDomainName.getString("tenantId");
}
if(UtilValidate.isEmpty(tenantId)) {
tenantId = (String) httpRequest.getAttribute("userTenantId");
}
if(UtilValidate.isEmpty(tenantId)) {
tenantId = httpRequest.getParameter("userTenantId");
}
if (UtilValidate.isNotEmpty(tenantId)) {
// if the request path is a root mount then redirect to the initial path
if ("".equals(httpRequest.getContextPath()) && "".equals(httpRequest.getServletPath())) {
GenericValue tenant = EntityQuery.use(baseDelegator).from("Tenant").where("tenantId", tenantId).queryOne();
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("security", null);
config.getServletContext().setAttribute("dispatcher", null);
// initialize security
Security security = WebAppUtil.getSecurity(config.getServletContext());
// initialize the services dispatcher
LocalDispatcher dispatcher = WebAppUtil.getDispatcher(config.getServletContext());
// set web context objects
request.setAttribute("delegator", delegator);
request.setAttribute("dispatcher", dispatcher);
request.setAttribute("security", security);
request.setAttribute("userTenantId", 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(request, httpResponse);
}
/**
* @see javax.servlet.Filter#destroy()
*/
public void destroy() {
WebAppUtil.getDispatcher(config.getServletContext()).deregister();
config = null;
}
private void putAllInitParametersInAttributes() {
Enumeration<String> initParamEnum = UtilGenerics.cast(config.getServletContext().getInitParameterNames());
while (initParamEnum.hasMoreElements()) {
String initParamName = initParamEnum.nextElement();
String initParamValue = config.getServletContext().getInitParameter(initParamName);
if (Debug.verboseOn()) Debug.logVerbose("Adding web.xml context-param to application attribute with name [" + initParamName + "] and value [" + initParamValue + "]", module);
config.getServletContext().setAttribute(initParamName, initParamValue);
}
}
private String getServerId() {
String serverId = (String) config.getServletContext().getAttribute("_serverId");
if (serverId == null) {
serverId = config.getServletContext().getInitParameter("ofbizServerName");
config.getServletContext().setAttribute("_serverId", serverId);
}
return serverId;
}
}