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    }