001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io.auth;
003
004import java.net.Authenticator;
005import java.net.PasswordAuthentication;
006import java.util.HashMap;
007import java.util.Map;
008
009import org.openstreetmap.josm.io.OsmApi;
010
011/**
012 * This is the default authenticator used in JOSM. It delegates lookup of credentials
013 * for the OSM API and an optional proxy server to the currently configured {@link CredentialsManager}.
014 * @since 2641
015 */
016public final class DefaultAuthenticator extends Authenticator {
017    private static DefaultAuthenticator instance;
018
019    /**
020     * Returns the unique instance
021     * @return The unique instance
022     */
023    public static DefaultAuthenticator getInstance() {
024        return instance;
025    }
026
027    /**
028     * Creates the unique instance
029     */
030    public static void createInstance() {
031        instance = new DefaultAuthenticator();
032    }
033
034    private final Map<RequestorType, Boolean> credentialsTried = new HashMap<RequestorType, Boolean>();
035    private boolean enabled = true;
036
037    private DefaultAuthenticator() {
038    }
039
040    /**
041     * Called by the Java HTTP stack when either the OSM API server or a proxy requires authentication.
042     */
043    @Override
044    protected PasswordAuthentication getPasswordAuthentication() {
045        if (!enabled)
046            return null;
047        try {
048            if (getRequestorType().equals(Authenticator.RequestorType.SERVER) && OsmApi.isUsingOAuth()) {
049                // if we are working with OAuth we don't prompt for a password
050                return null;
051            }
052            boolean tried = credentialsTried.get(getRequestorType()) != null;
053            CredentialsAgentResponse response = CredentialsManager.getInstance().getCredentials(getRequestorType(), getRequestingHost(), tried);
054            if (response == null || response.isCanceled())
055                return null;
056            credentialsTried.put(getRequestorType(), true);
057            return new PasswordAuthentication(response.getUsername(), response.getPassword());
058        } catch(CredentialsAgentException e) {
059            e.printStackTrace();
060            return null;
061        }
062    }
063
064    public boolean isEnabled() {
065        return enabled;
066    }
067
068    public void setEnabled(boolean enabled) {
069        this.enabled = enabled;
070    }
071}