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