/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.impl.wsdl.endpoint; import com.eviware.soapui.SoapUI; import com.eviware.soapui.config.CredentialsConfig.AuthType; import com.eviware.soapui.config.CredentialsConfig.AuthType.Enum; import com.eviware.soapui.config.DefaultEndpointStrategyConfig; import com.eviware.soapui.config.EndpointConfig; import com.eviware.soapui.config.ProjectConfig; import com.eviware.soapui.impl.rest.RestRequestInterface; import com.eviware.soapui.impl.support.AbstractHttpRequestInterface; import com.eviware.soapui.impl.support.AbstractInterface; import com.eviware.soapui.impl.wsdl.WsdlProject; import com.eviware.soapui.impl.wsdl.WsdlRequest; import com.eviware.soapui.impl.wsdl.submit.filters.HttpAuthenticationRequestFilter; import com.eviware.soapui.impl.wsdl.submit.filters.WssAuthenticationRequestFilter; import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport; import com.eviware.soapui.model.iface.Interface; import com.eviware.soapui.model.iface.Request; import com.eviware.soapui.model.iface.Response; import com.eviware.soapui.model.iface.SubmitContext; import com.eviware.soapui.model.project.EndpointStrategy; import com.eviware.soapui.model.project.Project; import com.eviware.soapui.model.project.ProjectListener; import com.eviware.soapui.model.propertyexpansion.PropertyExpander; import com.eviware.soapui.model.propertyexpansion.PropertyExpansion; import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer; import com.eviware.soapui.model.propertyexpansion.PropertyExpansionsResult; import com.eviware.soapui.model.support.ProjectListenerAdapter; import com.eviware.soapui.support.StringUtils; import com.eviware.soapui.support.types.StringList; import org.apache.commons.httpclient.URI; import org.apache.http.client.methods.HttpRequestBase; import javax.swing.JComponent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.net.URISyntaxException; import java.net.URL; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class DefaultEndpointStrategy implements EndpointStrategy, PropertyExpansionContainer { private WsdlProject project; private DefaultEndpointStrategyConfig config; private Map<String, EndpointDefaults> defaults = new HashMap<String, EndpointDefaults>(); private PropertyChangeListener propertyChangeListener = new InternalPropertyChangeListener(); private ProjectListener projectListener = new InternalProjectListener(); private DefaultEndpointStrategyConfigurationPanel configurationPanel; public void init(Project project) { this.project = (WsdlProject) project; initConfig(); project.addProjectListener(projectListener); for (Interface iface : project.getInterfaceList()) { for (String endpoint : iface.getEndpoints()) { // ensure we have defaults getEndpointDefaults(endpoint); } iface.addPropertyChangeListener(AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener); } removeUnusedEndpoints(); } private void initConfig() { ProjectConfig projectConfig = this.project.getConfig(); if (!projectConfig.isSetEndpointStrategy()) { projectConfig.addNewEndpointStrategy(); } config = (DefaultEndpointStrategyConfig) projectConfig.getEndpointStrategy().changeType( DefaultEndpointStrategyConfig.type); for (EndpointConfig endpointConfig : config.getEndpointList()) { if (!endpointConfig.isSetMode()) { endpointConfig.setMode(EndpointConfig.Mode.COMPLEMENT); } defaults.put(endpointConfig.getStringValue(), new EndpointDefaults(endpointConfig)); } } private void removeUnusedEndpoints() { if (config == null) { return; } Set<String> endpoints = new HashSet<String>(); for (Interface iface : project.getInterfaceList()) { endpoints.addAll(Arrays.asList(iface.getEndpoints())); } StringList keys = new StringList(); synchronized (defaults) { for (String key : defaults.keySet()) { if (!endpoints.contains(key)) { keys.add(key); } } for (String key : keys) { EndpointDefaults def = defaults.remove(key); config.getEndpointList().remove(def); } } } public void filterRequest(SubmitContext context, Request wsdlRequest) { HttpRequestBase httpMethod = (HttpRequestBase) context.getProperty(BaseHttpRequestTransport.HTTP_METHOD); URI tempUri = (URI) context.getProperty(BaseHttpRequestTransport.REQUEST_URI); java.net.URI uri = null; try { uri = new java.net.URI(tempUri.toString()); } catch (URISyntaxException e) { SoapUI.logError(e); } if (uri == null) { uri = httpMethod.getURI(); } if (uri == null) { return; } EndpointDefaults def = defaults.get(uri.toString()); if (def == null) { synchronized (defaults) { for (String ep : defaults.keySet()) { try { URL tempUrl = new URL(PropertyExpander.expandProperties(context, ep)); if (tempUrl.toString().equalsIgnoreCase(uri.toString())) { def = defaults.get(ep); break; } } catch (Exception e) { // we can hide this exception for now, it could happen for // invalid property-expansions, etc // if the endpoint really is wrong there will be other // exception later on } } if (wsdlRequest instanceof RestRequestInterface) { for (String ep : defaults.keySet()) { try { URL tempUrl = new URL(PropertyExpander.expandProperties(context, ep)); if (tempUrl.getHost().toString().equalsIgnoreCase(uri.getHost().toString())) { def = defaults.get(ep); break; } } catch (Exception e) { // we can hide this exception for now, it could happen for // invalid property-expansions, etc // if the endpoint really is wrong there will be other // exception later on } } } } if (def == null) { return; } } applyDefaultsToWsdlRequest(context, (AbstractHttpRequestInterface<?>) wsdlRequest, def); } protected void applyDefaultsToWsdlRequest(SubmitContext context, AbstractHttpRequestInterface<?> wsdlRequest, EndpointDefaults def) { String requestUsername = PropertyExpander.expandProperties(context, wsdlRequest.getUsername()); String requestPassword = PropertyExpander.expandProperties(context, wsdlRequest.getPassword()); String requestDomain = PropertyExpander.expandProperties(context, wsdlRequest.getDomain()); String defUsername = PropertyExpander.expandProperties(context, def.getUsername()); String defPassword = PropertyExpander.expandProperties(context, def.getPassword()); String defDomain = PropertyExpander.expandProperties(context, def.getDomain()); Enum authType = AuthType.Enum.forString(wsdlRequest.getAuthType()); if (def.getMode() == EndpointConfig.Mode.OVERRIDE) { overrideRequest(context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername, defPassword, defDomain, authType); } else if (def.getMode() == EndpointConfig.Mode.COPY) { copyToRequest(context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername, defPassword, defDomain, authType); } else if (def.getMode() == EndpointConfig.Mode.COMPLEMENT) { complementRequest(context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername, defPassword, defDomain, authType); } } private void overrideRequest(SubmitContext context, AbstractHttpRequestInterface<?> wsdlRequest, EndpointDefaults def, String requestUsername, String requestPassword, String requestDomain, String defUsername, String defPassword, String defDomain, com.eviware.soapui.config.CredentialsConfig.AuthType.Enum authType) { String username = StringUtils.hasContent(defUsername) ? defUsername : requestUsername; String password = StringUtils.hasContent(defPassword) ? defPassword : requestPassword; if (StringUtils.hasContent(username) || StringUtils.hasContent(password)) { // only set if not set in request String wssType = def.getWssType(); String wssTimeToLive = def.getWssTimeToLive(); if (wssType == null) { String domain = StringUtils.hasContent(defDomain) ? defDomain : requestDomain; HttpAuthenticationRequestFilter.initRequestCredentials(context, username, project.getSettings(), password, domain, authType); } if (StringUtils.hasContent(wssType) || StringUtils.hasContent(wssTimeToLive)) { try { // set to null so existing don't get removed if (wssTimeToLive != null && wssTimeToLive.length() == 0) { wssTimeToLive = null; } WssAuthenticationRequestFilter.setWssHeaders(context, username, password, wssType, wssTimeToLive); } catch (Exception e) { SoapUI.logError(e); } } } } private void copyToRequest(SubmitContext context, AbstractHttpRequestInterface<?> wsdlRequest, EndpointDefaults def, String requestUsername, String requestPassword, String requestDomain, String defUsername, String defPassword, String defDomain, com.eviware.soapui.config.CredentialsConfig.AuthType.Enum authType) { // only set if not set in request String wssType = def.getWssType(); if (wssType != null) { HttpAuthenticationRequestFilter .initRequestCredentials(context, null, project.getSettings(), null, null, null); } else { HttpAuthenticationRequestFilter.initRequestCredentials(context, defUsername, project.getSettings(), defPassword, defDomain, authType); } String wssTimeToLive = def.getWssTimeToLive(); if (wssTimeToLive == null) { wssTimeToLive = ""; } try { WssAuthenticationRequestFilter.setWssHeaders(context, defUsername, defPassword, wssType, wssTimeToLive); } catch (Exception e) { SoapUI.logError(e); } } private void complementRequest(SubmitContext context, AbstractHttpRequestInterface<?> httpRequest, EndpointDefaults def, String requestUsername, String requestPassword, String requestDomain, String defUsername, String defPassword, String defDomain, com.eviware.soapui.config.CredentialsConfig.AuthType.Enum authType) { String username = StringUtils.hasContent(requestUsername) ? requestUsername : defUsername; String password = StringUtils.hasContent(requestPassword) ? requestPassword : defPassword; if (httpRequest instanceof WsdlRequest) { WsdlRequest wsdlRequest = (WsdlRequest) httpRequest; // only set if not set in request String wssType = StringUtils.isNullOrEmpty(wsdlRequest.getWssPasswordType()) ? def.getWssType() : (StringUtils.hasContent(username) && StringUtils.hasContent(password)) ? null : wsdlRequest .getWssPasswordType(); String wssTimeToLive = StringUtils.isNullOrEmpty(wsdlRequest.getWssTimeToLive()) ? def.getWssTimeToLive() : null; if (!StringUtils.hasContent(wssType) && (StringUtils.hasContent(username) || StringUtils.hasContent(password))) { String domain = StringUtils.hasContent(requestDomain) ? requestDomain : defDomain; HttpAuthenticationRequestFilter.initRequestCredentials(context, username, project.getSettings(), password, domain, authType); } else if (StringUtils.hasContent(wssType) || StringUtils.hasContent(wssTimeToLive)) { try { // set to null so existing don't get removed if (wssTimeToLive != null && wssTimeToLive.length() == 0) { wssTimeToLive = null; } if (StringUtils.hasContent(username) || StringUtils.hasContent(password)) { WssAuthenticationRequestFilter.setWssHeaders(context, username, password, wssType, wssTimeToLive); } } catch (Exception e) { SoapUI.logError(e); } } } else { if ((StringUtils.hasContent(username) || StringUtils.hasContent(password))) { String domain = StringUtils.hasContent(requestDomain) ? requestDomain : defDomain; HttpAuthenticationRequestFilter.initRequestCredentials(context, username, project.getSettings(), password, domain, authType); } } } public void release() { project.removeProjectListener(projectListener); for (Interface iface : project.getInterfaceList()) { iface.removePropertyChangeListener(AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener); } if (configurationPanel != null) { configurationPanel.release(); } } private class InternalProjectListener extends ProjectListenerAdapter { @Override public void interfaceAdded(Interface iface) { for (String endpoint : iface.getEndpoints()) { // ensure we have defaults getEndpointDefaults(endpoint); } iface.addPropertyChangeListener(AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener); } @Override public void interfaceRemoved(Interface iface) { iface.removePropertyChangeListener(AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener); removeUnusedEndpoints(); } } private class InternalPropertyChangeListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { // new endpoint? String newValue = evt.getNewValue() == null ? null : evt.getNewValue().toString(); if (evt.getOldValue() == null) { getEndpointDefaults(newValue); } // changed endpoint? else if (newValue != null) { String oldValue = evt.getOldValue().toString(); EndpointDefaults def = defaults.containsKey(newValue) ? defaults.get(newValue) : getEndpointDefaults(oldValue); def.endpointConfig.setStringValue(newValue); synchronized (defaults) { defaults.remove(oldValue); defaults.put(newValue, def); } } else { removeUnusedEndpoints(); } } } public class EndpointDefaults implements PropertyExpansionContainer { private final EndpointConfig endpointConfig; public EndpointConfig getEndpointConfig() { return endpointConfig; } public EndpointDefaults(EndpointConfig endpointConfig) { this.endpointConfig = endpointConfig; if (!endpointConfig.isSetMode()) { endpointConfig.setMode(EndpointConfig.Mode.COMPLEMENT); } } public String getDomain() { return endpointConfig.getDomain(); } public String getPassword() { return endpointConfig.getPassword(); } public String getUsername() { return endpointConfig.getUsername(); } public String getWssTimeToLive() { return endpointConfig.getWssTimeToLive(); } public String getWssType() { String wssPasswordType = endpointConfig.getWssType(); return StringUtils.isNullOrEmpty(wssPasswordType) || WsdlRequest.PW_TYPE_NONE.equals(wssPasswordType) ? null : wssPasswordType; } public void setDomain(String arg0) { endpointConfig.setDomain(arg0); } public void setPassword(String arg0) { endpointConfig.setPassword(arg0); } public void setUsername(String arg0) { endpointConfig.setUsername(arg0); } public void setWssTimeToLive(String arg0) { endpointConfig.setWssTimeToLive(arg0); } public String getIncomingWss() { return endpointConfig.getIncomingWss(); } public String getOutgoingWss() { return endpointConfig.getOutgoingWss(); } public void setIncomingWss(String arg0) { endpointConfig.setIncomingWss(arg0); } public void setOutgoingWss(String arg0) { endpointConfig.setOutgoingWss(arg0); } public void setWssType(String wssPasswordType) { if (wssPasswordType == null || wssPasswordType.equals(WsdlRequest.PW_TYPE_NONE)) { if (endpointConfig.isSetWssType()) { endpointConfig.unsetWssType(); } } else { endpointConfig.setWssType(wssPasswordType); } } public EndpointConfig.Mode.Enum getMode() { return endpointConfig.getMode(); } public void setMode(EndpointConfig.Mode.Enum mode) { endpointConfig.setMode(mode); } protected EndpointConfig getConfig() { return endpointConfig; } public PropertyExpansion[] getPropertyExpansions() { PropertyExpansionsResult result = new PropertyExpansionsResult(project, this); result.extractAndAddAll("username"); result.extractAndAddAll("password"); result.extractAndAddAll("domain"); return result.toArray(); } } public EndpointDefaults getEndpointDefaults(String endpoint) { if (config == null) { initConfig(); } if (!defaults.containsKey(endpoint)) { synchronized (defaults) { EndpointConfig newEndpoint = config.addNewEndpoint(); newEndpoint.setStringValue(endpoint); defaults.put(endpoint, new EndpointDefaults(newEndpoint)); } } return defaults.get(endpoint); } public void onSave() { if (config == null) { return; } removeUnusedEndpoints(); // remove unused for (int c = 0; c < config.sizeOfEndpointArray(); c++) { EndpointConfig ec = config.getEndpointArray(c); if (StringUtils.isNullOrEmpty(ec.getDomain()) && StringUtils.isNullOrEmpty(ec.getUsername()) && StringUtils.isNullOrEmpty(ec.getPassword()) && StringUtils.isNullOrEmpty(ec.getWssType()) && StringUtils.isNullOrEmpty(ec.getWssTimeToLive()) && StringUtils.isNullOrEmpty(ec.getIncomingWss()) && StringUtils.isNullOrEmpty(ec.getOutgoingWss()) && ec.getMode() == EndpointConfig.Mode.COMPLEMENT) { synchronized (defaults) { defaults.remove(ec.getStringValue()); config.removeEndpoint(c); c--; } } } if (config.sizeOfEndpointArray() == 0) { project.getConfig().unsetEndpointStrategy(); config = null; } } public void importEndpoints(Interface iface) { EndpointStrategy ep = iface.getProject().getEndpointStrategy(); if (ep instanceof DefaultEndpointStrategy) { DefaultEndpointStrategy dep = (DefaultEndpointStrategy) ep; String[] endpoints = iface.getEndpoints(); for (String endpoint : endpoints) { getEndpointDefaults(endpoint).getConfig().set(dep.getEndpointDefaults(endpoint).getConfig()); } } } public JComponent getConfigurationPanel(Interface iface) { configurationPanel = new DefaultEndpointStrategyConfigurationPanel(iface, this); return configurationPanel; } public void afterRequest(SubmitContext context, Response response) { } public PropertyExpansion[] getPropertyExpansions() { PropertyExpansionsResult result = new PropertyExpansionsResult(project, this); for (EndpointDefaults ed : defaults.values()) { result.addAll(ed.getPropertyExpansions()); } return result.toArray(); } public void changeEndpoint(String oldEndpoint, String newEndpoint) { synchronized (defaults) { EndpointDefaults endpointDefaults = defaults.remove(oldEndpoint); if (endpointDefaults != null) { endpointDefaults.getConfig().setStringValue(newEndpoint); defaults.put(newEndpoint, endpointDefaults); } } } public void afterRequest(SubmitContext context, Request request) { } }