001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.io.auth;
003
004 import java.net.Authenticator.RequestorType;
005 import java.net.PasswordAuthentication;
006 import java.util.HashMap;
007 import java.util.Map;
008
009 import org.openstreetmap.josm.gui.io.CredentialDialog;
010
011 abstract public class AbstractCredentialsAgent implements CredentialsAgent {
012
013 protected Map<RequestorType, PasswordAuthentication> memoryCredentialsCache = new HashMap<RequestorType, PasswordAuthentication>();
014
015 /**
016 * @see CredentialsAgent#getCredentials(RequestorType, boolean)
017 */
018 @Override
019 public CredentialsAgentResponse getCredentials(RequestorType requestorType, String host, boolean noSuccessWithLastResponse) throws CredentialsAgentException{
020 if (requestorType == null)
021 return null;
022 PasswordAuthentication credentials = lookup(requestorType, host);
023 String username = (credentials == null || credentials.getUserName() == null) ? "" : credentials.getUserName();
024 String password = (credentials == null || credentials.getPassword() == null) ? "" : String.valueOf(credentials.getPassword());
025
026 CredentialsAgentResponse response = new CredentialsAgentResponse();
027
028 /*
029 * Last request was successful and there was no credentials stored
030 * in file (or only the username is stored).
031 * -> Try to recall credentials that have been entered
032 * manually in this session.
033 */
034 if (!noSuccessWithLastResponse && memoryCredentialsCache.containsKey(requestorType) &&
035 (credentials == null || credentials.getPassword() == null || credentials.getPassword().length == 0)) {
036 PasswordAuthentication pa = memoryCredentialsCache.get(requestorType);
037 response.setUsername(pa.getUserName());
038 response.setPassword(pa.getPassword());
039 response.setCanceled(false);
040 /*
041 * Prompt the user for credentials. This happens the first time each
042 * josm start if the user does not save the credentials to preference
043 * file (username=="") and each time after authentication failed
044 * (noSuccessWithLastResponse == true).
045 */
046 } else if (noSuccessWithLastResponse || username.equals("") || password.equals("")) {
047 CredentialDialog dialog = null;
048 switch(requestorType) {
049 case SERVER: dialog = CredentialDialog.getOsmApiCredentialDialog(username, password, host, getSaveUsernameAndPasswordCheckboxText()); break;
050 case PROXY: dialog = CredentialDialog.getHttpProxyCredentialDialog(username, password, host, getSaveUsernameAndPasswordCheckboxText()); break;
051 }
052 dialog.setVisible(true);
053 response.setCanceled(dialog.isCanceled());
054 if (dialog.isCanceled())
055 return response;
056 response.setUsername(dialog.getUsername());
057 response.setPassword(dialog.getPassword());
058 if (dialog.isSaveCredentials()) {
059 store(requestorType, host, new PasswordAuthentication(
060 response.getUsername(),
061 response.getPassword()
062 ));
063 /*
064 * User decides not to save credentials to file. Keep it
065 * in memory so we don't have to ask over and over again.
066 */
067 } else {
068 PasswordAuthentication pa = new PasswordAuthentication(dialog.getUsername(), dialog.getPassword());
069 memoryCredentialsCache.put(requestorType, pa);
070 }
071 /*
072 * We got it from file.
073 */
074 } else {
075 response.setUsername(username);
076 response.setPassword(password.toCharArray());
077 response.setCanceled(false);
078 }
079 return response;
080 }
081
082 /**
083 * Provide the text for a checkbox that offers to save the
084 * username and password that has been entered by the user.
085 */
086 public abstract String getSaveUsernameAndPasswordCheckboxText();
087 }