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 }