/******************************************************************************* * Copyright (c) 2010 Steffen Pingel and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Steffen Pingel - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.internal.trac.core.client; import java.util.regex.Pattern; import org.apache.xmlrpc.XmlRpcException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.mylyn.commons.net.AuthenticationCredentials; import org.eclipse.mylyn.commons.net.AuthenticationType; import org.eclipse.mylyn.internal.commons.xmlrpc.CommonXmlRpcClient; import org.eclipse.mylyn.internal.commons.xmlrpc.XmlRpcOperation; import org.eclipse.mylyn.internal.commons.xmlrpc.XmlRpcPermissionDeniedException; /** * @author Steffen Pingel */ abstract class TracXmlRpcOperation<T> extends XmlRpcOperation<T> { private static final Pattern RPC_METHOD_NOT_FOUND_PATTERN = Pattern.compile("RPC method \".*\" not found"); //$NON-NLS-1$ private boolean accountMangerAuthenticationFailed; public TracXmlRpcOperation(CommonXmlRpcClient client) { super(client); } @Override protected Object executeCall(IProgressMonitor monitor, String method, Object... parameters) throws XmlRpcException { try { // first attempt preCall(); return super.executeCall(monitor, method, parameters); } catch (XmlRpcPermissionDeniedException e) { if (accountMangerAuthenticationFailed) { // do not try again if this has failed in the past since it // is more likely that XML_RPC permissions have not been set throw e; } AuthenticationCredentials credentials = getClient().getLocation().getCredentials( AuthenticationType.REPOSITORY); if (!credentialsValid(credentials)) { throw e; } // try form-based authentication via AccountManagerPlugin as a // fall-back // HostConfiguration hostConfiguration = WebUtil.createHostConfiguration(getClient().getHttpClient(), // getClient().getLocation(), monitor); // try { // authenticateAccountManager(getClient().httpClient, hostConfiguration, credentials, monitor); // } catch (XmlRpcLoginException loginException) { // // caused by wrong user name or password // throw loginException; // } catch (IOException ignore) { // accountMangerAuthenticationFailed = true; // throw e; // } // // try { // validateAuthenticationState(getClient().httpClient); // } catch (XmlRpcLoginException ignore) { // // most likely form based authentication is not supported by // // repository // accountMangerAuthenticationFailed = true; // throw e; // } // the authentication information is available through the shared state in httpClient } // second attempt preCall(); return super.executeCall(monitor, method, parameters); } private void preCall() { // if (isTracd && digestScheme != null) { // probeAuthenticationScheme(monitor); // } } // void probeAuthenticationScheme(IProgressMonitor monitor) throws XmlRpcException { // AuthenticationCredentials credentials = client.getLocation().getCredentials(AuthenticationType.REPOSITORY); // if (!credentialsValid(credentials)) { // return; // } // // if (CommonXmlRpcClient.DEBUG_AUTH) { // System.err.println(client.getLocation().getUrl() + ": Probing authentication"); //$NON-NLS-1$ // } // HostConfiguration hostConfiguration = WebUtil.createHostConfiguration(httpClient, location, monitor); // HeadMethod method = new HeadMethod(getXmlRpcUrl(credentials).toString()); // try { // // execute without any credentials set // int result = WebUtil.execute(httpClient, hostConfiguration, method, new HttpState(), monitor); // if (CommonXmlRpcClient.DEBUG_AUTH) { // System.err.println(client.getLocation().getUrl() // + ": Received authentication response (" + result + ")"); //$NON-NLS-1$ //$NON-NLS-2$ // } // if (result == HttpStatus.SC_UNAUTHORIZED || result == HttpStatus.SC_FORBIDDEN) { // AuthScheme authScheme = method.getHostAuthState().getAuthScheme(); // if (authScheme instanceof DigestScheme) { // client.digestScheme = (DigestScheme) authScheme; // if (CommonXmlRpcClient.DEBUG_AUTH) { // System.err.println(client.getLocation().getUrl() + ": Received digest scheme"); //$NON-NLS-1$ // } // } else if (authScheme instanceof BasicScheme) { // httpClient.getParams().setAuthenticationPreemptive(true); // if (CommonXmlRpcClient.DEBUG_AUTH) { // System.err.println(client.getLocation().getUrl() + ": Received basic scheme"); //$NON-NLS-1$ // } // } else if (authScheme != null) { // if (CommonXmlRpcClient.DEBUG_AUTH) { // System.err.println(client.getLocation().getUrl() // + ": Received scheme (" + authScheme.getClass() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ // } // } else { // if (CommonXmlRpcClient.DEBUG_AUTH) { // System.err.println(client.getLocation().getUrl() + ": No authentication scheme received"); //$NON-NLS-1$ // } // } // // Header header = method.getResponseHeader("Server"); //$NON-NLS-1$ // isTracd = (header != null && header.getValue().startsWith("tracd")); //$NON-NLS-1$ // if (CommonXmlRpcClient.DEBUG_AUTH && isTracd) { // System.err.println(client.getLocation().getUrl() + ": Tracd detected"); //$NON-NLS-1$ // } // } // } catch (IOException e) { // // ignore // } finally { // method.releaseConnection(); // } //} @Override protected boolean isNoSuchMethodException(XmlRpcException e) { // the fault code is used for various errors, therefore detection is based on the message // message format by XML-RPC Plugin version: // 1.0.1: XML-RPC method "ticket.ge1t" not found // 1.0.6: RPC method "ticket.ge1t" not found // 1.10: RPC method "ticket.ge1t" not found' while executing 'ticket.ge1t() if (e.code == XML_FAULT_GENERAL_ERROR && e.getMessage() != null && RPC_METHOD_NOT_FOUND_PATTERN.matcher(e.getMessage()).find()) { return true; } return false; } }