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