blob: 0b878e0bca969a73dc3ab27aebe3664653fc3cdc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.update.internal.ui.security;
import java.net.*;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.ui.*;
/**
* A transient database that remembers information, such as usernames and
* passwords. The information is stored in memory only and is discarted
* when the Plaform shuts down.
*/
public class UpdateManagerAuthenticator extends Authenticator {
// fields needed for caching the password
public static final String INFO_PASSWORD = "password"; //$NON-NLS-1$
public static final String INFO_USERNAME = "username"; //$NON-NLS-1$
public static final String UNKNOWN_HOST = "unknown"; //$NON-NLS-1$
public static final String AUTH_SCHEME = ""; //$NON-NLS-1$
private String requestingHostName;
private int requestingPort;
private String requestingProtocol;
private String requestingPrompt;
private String requestingScheme;
private Map savedPasswordAuthentication;
/**
* The Map containing the userid and password
* HashMap allows <code>null</code> as the value
*/
private Map result = new HashMap();
/**
*
*/
public void addAuthenticationInfo(URL serverUrl, String realm, String scheme, Map info) {
try {
Platform.addAuthorizationInfo(serverUrl, realm, scheme, info);
} catch (CoreException e) {
UpdateUI.logException(e);
}
}
/**
*
*/
public Map getAuthenticationInfo(URL serverUrl, String realm, String scheme) {
return Platform.getAuthorizationInfo(serverUrl, realm, scheme);
}
/**
*
*/
public Map requestAuthenticationInfo(URL resourceUrl, String realm, String scheme) {
// already called by retrieve
//if (!equalsPreviousRequest(resourceUrl, realm, scheme)) {
// save state
this.requestingPort = resourceUrl.getPort();
this.requestingPrompt = realm;
this.requestingProtocol = resourceUrl.getProtocol();
this.requestingScheme = scheme;
this.requestingHostName = resourceUrl.getHost();
// try to get the password info from the in-memory database first
Map map = Platform.getAuthorizationInfo(resourceUrl, requestingPrompt, requestingScheme);
if (map == null) {
map = retrievePasswordAuthentication(resourceUrl, requestingPrompt, requestingScheme);
}
savedPasswordAuthentication = map;
//}
// we must return a valid Map while we internally manage Cancel dialog (map==null -> dialog cancelled)
return savedPasswordAuthentication;
}
/**
* @see org.eclipse.update.internal.core.net.http.client.IAuthenticator#addProtectionSpace(URL, String)
*/
public void addProtectionSpace(URL resourceUrl, String realm) {
try {
Platform.addProtectionSpace(resourceUrl, realm);
} catch (CoreException e) {
UpdateUI.logException(e, false);
}
}
/**
* @see org.eclipse.update.internal.core.net.http.client.IAuthenticator#getProtectionSpace(URL)
*/
public String getProtectionSpace(URL resourceUrl) {
return Platform.getProtectionSpace(resourceUrl);
}
/*
* forces a refresh
*/
public void reset() {
requestingPort = 0;
requestingPrompt = null;
requestingProtocol = null;
requestingScheme = null;
requestingHostName = null;
}
/*
* returns a map that contains the userid and the password
* or <code>null</code> if the dialog has been cancelled
*/
private Map retrievePasswordAuthentication(final URL resourceUrl, final String realm, final String scheme) {
result = new HashMap();
if ("Basic".equalsIgnoreCase(scheme) || "NTLM".equalsIgnoreCase(scheme)) { //$NON-NLS-1$
Display disp = Display.getCurrent();
if (disp != null) {
result = promptForPassword(resourceUrl, realm);
} else {
Display.getDefault().syncExec(new Runnable() {
public void run() {
result = promptForPassword(resourceUrl, realm);
}
});
}
}
return result;
}
/*
* returns true if this request is the same as the saved one
* used to prevent double dialog if user cancelled or entered wrong userid/password
*/
private boolean equalsPreviousRequest(URL url, String realm, String scheme) {
if (requestingPort != url.getPort())
return false;
if (requestingPrompt != null && !requestingPrompt.equals(realm))
return false;
if (requestingPrompt == null && realm != null)
return false;
if (requestingProtocol != null && !requestingProtocol.equals(url.getProtocol()))
return false;
if (requestingProtocol == null && url.getProtocol() != null)
return false;
if (requestingScheme != null && !requestingScheme.equals(scheme))
return false;
if (requestingScheme == null && scheme != null)
return false;
if (requestingHostName != null && !requestingHostName.equals(url.getHost()))
return false;
if (requestingHostName == null && url.getHost() != null)
return false;
return true;
}
/*
* returns a map that contains the userid and the password
* or <code>null</code> if the dialog has been cancelled
*/
private Map promptForPassword(URL resourceUrl, String realm) {
Map result = null;
Shell shell = new Shell();
UserValidationDialog ui = new UserValidationDialog(shell, resourceUrl, realm, ""); //$NON-NLS-1$
ui.setUsernameMutable(true);
ui.setBlockOnOpen(true);
ui.open();
boolean isCancelled = ui.getReturnCode() == UserValidationDialog.CANCEL;
if (!isCancelled) {
result = new HashMap();
result.put(INFO_USERNAME, ui.getUserid());
result.put(INFO_PASSWORD, ui.getPassword());
}
shell.dispose();
return result;
}
/*
* @see Authenticator#getPasswordAuthentication()
*/
protected PasswordAuthentication getPasswordAuthentication() {
try {
String hostName = getRequestingHost() != null ? getRequestingHost() : UNKNOWN_HOST;
URL url = new URL(getRequestingProtocol(), hostName, getRequestingPort(), ""); //$NON-NLS-1$
Map map = retrievePasswordAuthentication(url);
String username = null;
String password = null;
if (map != null) {
username = (String) map.get(INFO_USERNAME);
password = (String) map.get(INFO_PASSWORD);
}
if (username != null && password != null) {
return new PasswordAuthentication(username, password.toCharArray());
} else {
return null;
}
} catch (MalformedURLException e) {
IStatus status = Utilities.newCoreException("", e).getStatus(); //$NON-NLS-1$
UpdateUI.log(status, false);
}
return new PasswordAuthentication("", new char[] { ' ' }); //$NON-NLS-1$
}
/*
*
*/
private Map retrievePasswordAuthentication(URL url) {
if (equalsPreviousRequest(url,getRequestingPrompt(),getRequestingScheme())) {
// same request, the userid/password was wrong
// or user cancelled. force a refresh
if (savedPasswordAuthentication != null)
// only prompt if the user didn't cancel
savedPasswordAuthentication = requestAuthenticationInfo(url, requestingPrompt, requestingScheme);
} else {
// save state
requestingPort = getRequestingPort();
requestingPrompt = getRequestingPrompt();
requestingProtocol = getRequestingProtocol();
requestingScheme = getRequestingScheme();
requestingHostName = getRequestingHost() != null ? getRequestingHost() : UNKNOWN_HOST;
savedPasswordAuthentication = Platform.getAuthorizationInfo(url, requestingPrompt, requestingScheme);
if (savedPasswordAuthentication == null) {
savedPasswordAuthentication = requestAuthenticationInfo(url, requestingPrompt, requestingScheme);
}
}
return savedPasswordAuthentication;
}
}