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