/* * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * * Contributors: * Arnaud Kervern */ package org.nuxeo.ecm.platform.web.common.requestcontroller.service; import java.io.Serializable; import java.util.Dictionary; import java.util.Enumeration; import java.util.Hashtable; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.nuxeo.common.xmap.annotation.XNode; import org.nuxeo.common.xmap.annotation.XObject; import org.nuxeo.runtime.api.Framework; import static org.apache.commons.lang.StringUtils.isEmpty; /** * @author <a href="mailto:ak@nuxeo.com">Arnaud Kervern</a> * @since 5.7.2 */ @XObject(value = "corsConfig") public class NuxeoCorsFilterDescriptor implements Serializable, Cloneable { private static final String PROPERTIES_PREFIX = "cors."; @XNode("@name") protected String name; @XNode("@enabled") protected Boolean enabled = true; @XNode("@allowGenericHttpRequests") protected Boolean allowGenericHttpRequests = true; @XNode("@allowOrigin") protected String allowOrigin; @XNode("@allowSubdomains") protected boolean allowSubdomains = false; @XNode("@supportedMethods") protected String supportedMethods; @XNode("@supportedHeaders") protected String supportedHeaders; @XNode("@exposedHeaders") protected String exposedHeaders; @XNode("@supportsCredentials") protected Boolean supportsCredentials = true; @XNode("@maxAge") protected int maxAge = -1; protected String pattern = ""; @XNode("pattern") public void setPattern(String pattern) { this.pattern = Framework.expandVars(pattern); } public FilterConfig buildFilterConfig() { final Dictionary<String, String> parameters = buildDictionary(); return new FilterConfig() { @Override public String getFilterName() { return "NuxeoCorsFilterDescriptor"; } @Override public ServletContext getServletContext() { // Not used with @see CORSFilter return null; } @Override public String getInitParameter(String name) { return parameters.get(name); } @Override public Enumeration getInitParameterNames() { return parameters.keys(); } }; } public boolean isMatching(HttpServletRequest request) { return !StringUtils.isEmpty(pattern) && request.getRequestURI().matches(pattern); } public NuxeoCorsFilterDescriptor clone() throws CloneNotSupportedException { NuxeoCorsFilterDescriptor n = new NuxeoCorsFilterDescriptor(); n.name = name; n.allowGenericHttpRequests = allowGenericHttpRequests; n.allowOrigin = allowOrigin; n.allowSubdomains = allowSubdomains; n.supportedMethods = supportedMethods; n.supportedHeaders = supportedHeaders; n.exposedHeaders = exposedHeaders; n.supportsCredentials = supportsCredentials; n.maxAge = maxAge; n.pattern = pattern; return n; } public void merge(NuxeoCorsFilterDescriptor o) { allowGenericHttpRequests = o.allowGenericHttpRequests; supportsCredentials = o.supportsCredentials; allowSubdomains = o.allowSubdomains; if (!StringUtils.isEmpty(o.allowOrigin)) { allowOrigin = o.allowOrigin; } if (!StringUtils.isEmpty(o.supportedMethods)) { supportedMethods = o.supportedMethods; } if (!StringUtils.isEmpty(o.supportedHeaders)) { supportedHeaders = o.supportedHeaders; } if (!StringUtils.isEmpty(o.exposedHeaders)) { exposedHeaders = o.exposedHeaders; } if (maxAge == -1) { maxAge = o.maxAge; } if (!StringUtils.isEmpty(o.pattern)) { pattern = o.pattern; } } protected Dictionary<String, String> buildDictionary() { Dictionary<String, String> params = new Hashtable<>(); params.put(PROPERTIES_PREFIX + "allowGenericHttpRequests", Boolean.toString(allowGenericHttpRequests)); if (!isEmpty(allowOrigin)) { params.put(PROPERTIES_PREFIX + "allowOrigin", allowOrigin); } params.put(PROPERTIES_PREFIX + "allowSubdomains", Boolean.toString(allowSubdomains)); if (!isEmpty(supportedMethods)) { params.put(PROPERTIES_PREFIX + "supportedMethods", supportedMethods); } if (!isEmpty(supportedHeaders)) { params.put(PROPERTIES_PREFIX + "supportedHeaders", supportedHeaders); } if (!isEmpty(exposedHeaders)) { params.put(PROPERTIES_PREFIX + "exposedHeaders", exposedHeaders); } params.put(PROPERTIES_PREFIX + "supportsCredentials", Boolean.toString(supportsCredentials)); params.put(PROPERTIES_PREFIX + "maxAge", Integer.toString(maxAge)); return params; } }