001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.io.auth;
003    
004    import java.awt.Component;
005    import java.net.Authenticator.RequestorType;
006    import java.net.PasswordAuthentication;
007    
008    import org.openstreetmap.josm.data.oauth.OAuthToken;
009    import org.openstreetmap.josm.gui.JosmUserIdentityManager;
010    import org.openstreetmap.josm.io.OsmApi;
011    import org.openstreetmap.josm.tools.Utils;
012    
013    /**
014     * CredentialManager is a factory for the single credential agent used.
015     *
016     * Currently, it defaults to replying an instance of {@link JosmPreferencesCredentialAgent}.
017     *
018     */
019    public class CredentialsManager implements CredentialsAgent {
020       
021        private static CredentialsManager instance;
022    
023        /**
024         * Replies the single credential agent used in JOSM
025         *
026         * @return the single credential agent used in JOSM
027         */
028        static public CredentialsManager getInstance() {
029            if (instance == null) {
030                CredentialsAgent delegate;
031                if (agentFactory == null) {
032                    delegate = new JosmPreferencesCredentialAgent();
033                } else {
034                    delegate = agentFactory.getCredentialsAgent();
035                }
036                instance = new CredentialsManager(delegate);
037            }
038            return instance;
039        }
040        
041        private static CredentialsAgentFactory agentFactory;
042    
043        public interface CredentialsAgentFactory {
044            CredentialsAgent getCredentialsAgent();
045        }
046        
047        /**
048         * Plugins can register a CredentialsAgentFactory, thereby overriding
049         * JOSM's default credentials agent.
050         * @param agentFactory The Factory that provides the custom CredentialsAgent.
051         * Can be null to clear the factory and switch back to default behavior.
052         */
053        public static void registerCredentialsAgentFactory(CredentialsAgentFactory agentFactory) {
054            CredentialsManager.agentFactory = agentFactory;
055            CredentialsManager.instance = null;
056        }
057    
058        /*****
059         * non-static fields and methods
060         */
061        
062        private CredentialsAgent delegate;
063    
064        public CredentialsManager(CredentialsAgent delegate) {
065            this.delegate = delegate;
066        }
067    
068        public String getUsername() {
069            return getUsername(OsmApi.getOsmApi().getHost());
070        }
071    
072        public String getUsername(String host) {
073            String username = null;
074            try {
075                PasswordAuthentication auth = lookup(RequestorType.SERVER, host);
076                if (auth != null) {
077                    username = auth.getUserName();
078                }
079            } catch (CredentialsAgentException ex) {
080                return null;
081            }
082            if (username == null) return null;
083            username = username.trim();
084            return Utils.equal(username, "") ? null : username;
085        }
086    
087        @Override
088        public PasswordAuthentication lookup(RequestorType requestorType, String host) throws CredentialsAgentException {
089            return delegate.lookup(requestorType, host);
090        }
091    
092        @Override
093        public void store(RequestorType requestorType, String host, PasswordAuthentication credentials) throws CredentialsAgentException {
094            if (requestorType == RequestorType.SERVER && Utils.equal(OsmApi.getOsmApi().getHost(), host)) {
095                String username = credentials.getUserName();
096                if(username != null && !username.trim().isEmpty()) {
097                    JosmUserIdentityManager.getInstance().setPartiallyIdentified(username);
098                }
099            }
100            delegate.store(requestorType, host, credentials);
101        }
102    
103        @Override
104        public CredentialsAgentResponse getCredentials(RequestorType requestorType, String host, boolean noSuccessWithLastResponse) throws CredentialsAgentException {
105            return delegate.getCredentials(requestorType, host, noSuccessWithLastResponse);
106        }
107    
108        @Override
109        public OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException {
110            return delegate.lookupOAuthAccessToken();
111        }
112    
113        @Override
114        public void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException {
115            delegate.storeOAuthAccessToken(accessToken);
116        }
117    
118        @Override
119        public Component getPreferencesDecorationPanel() {
120            return delegate.getPreferencesDecorationPanel();
121        }
122    }