source: josm/trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java@ 18650

Last change on this file since 18650 was 18650, checked in by taylor.smock, 16 months ago

Fix #20768: Add OAuth 2.0 support

This also fixes #21607: authentication buttons are unavailable when credentials
are set.

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io.auth;
3
4import java.awt.Component;
5import java.net.Authenticator.RequestorType;
6import java.net.PasswordAuthentication;
7import java.util.Objects;
8
9import org.openstreetmap.josm.data.UserIdentityManager;
10import org.openstreetmap.josm.data.oauth.IOAuthToken;
11import org.openstreetmap.josm.data.oauth.OAuthToken;
12import org.openstreetmap.josm.io.OsmApi;
13import org.openstreetmap.josm.tools.CheckParameterUtil;
14import org.openstreetmap.josm.tools.Logging;
15import org.openstreetmap.josm.tools.Utils;
16
17/**
18 * CredentialManager is a factory for the single credential agent used.
19 *
20 * Currently, it defaults to replying an instance of {@link JosmPreferencesCredentialAgent}.
21 * @since 2641
22 */
23public class CredentialsManager implements CredentialsAgent {
24
25 private static volatile CredentialsManager instance;
26
27 /**
28 * Replies the single credential agent used in JOSM
29 *
30 * @return the single credential agent used in JOSM
31 */
32 public static CredentialsManager getInstance() {
33 if (instance == null) {
34 CredentialsAgent delegate;
35 if (agentFactory == null) {
36 delegate = new JosmPreferencesCredentialAgent();
37 } else {
38 delegate = agentFactory.getCredentialsAgent();
39 }
40 instance = new CredentialsManager(delegate);
41 }
42 return instance;
43 }
44
45 private static CredentialsAgentFactory agentFactory;
46
47 /**
48 * Credentials agent factory.
49 */
50 @FunctionalInterface
51 public interface CredentialsAgentFactory {
52 /**
53 * Returns the credentials agent instance.
54 * @return the credentials agent instance
55 */
56 CredentialsAgent getCredentialsAgent();
57 }
58
59 /**
60 * Plugins can register a CredentialsAgentFactory, thereby overriding
61 * JOSM's default credentials agent.
62 * @param agentFactory The Factory that provides the custom CredentialsAgent.
63 * Can be null to clear the factory and switch back to default behavior.
64 */
65 public static void registerCredentialsAgentFactory(CredentialsAgentFactory agentFactory) {
66 CredentialsManager.agentFactory = agentFactory;
67 CredentialsManager.instance = null;
68 }
69
70 /* non-static fields and methods */
71
72 /**
73 * The credentials agent doing the real stuff
74 */
75 private final CredentialsAgent delegate;
76
77 /**
78 * Constructs a new {@code CredentialsManager}.
79 * @param delegate The credentials agent backing this credential manager. Must not be {@code null}
80 */
81 public CredentialsManager(CredentialsAgent delegate) {
82 CheckParameterUtil.ensureParameterNotNull(delegate, "delegate");
83 this.delegate = delegate;
84 }
85
86 /**
87 * Returns type of credentials agent backing this credentials manager.
88 * @return The type of credentials agent
89 */
90 public final Class<? extends CredentialsAgent> getCredentialsAgentClass() {
91 return delegate.getClass();
92 }
93
94 /**
95 * Returns the username for OSM API
96 * @return the username for OSM API
97 */
98 public String getUsername() {
99 return getUsername(OsmApi.getOsmApi().getHost());
100 }
101
102 /**
103 * Returns the username for a given host
104 * @param host The host for which username is wanted
105 * @return The username for {@code host}
106 */
107 public String getUsername(String host) {
108 String username = null;
109 try {
110 PasswordAuthentication auth = lookup(RequestorType.SERVER, host);
111 if (auth != null) {
112 username = auth.getUserName();
113 }
114 } catch (CredentialsAgentException ex) {
115 Logging.debug(ex);
116 return null;
117 }
118 if (username == null) return null;
119 username = username.trim();
120 return username.isEmpty() ? null : username;
121 }
122
123 @Override
124 public PasswordAuthentication lookup(RequestorType requestorType, String host) throws CredentialsAgentException {
125 return delegate.lookup(requestorType, host);
126 }
127
128 @Override
129 public void store(RequestorType requestorType, String host, PasswordAuthentication credentials) throws CredentialsAgentException {
130 if (requestorType == RequestorType.SERVER && Objects.equals(OsmApi.getOsmApi().getHost(), host)) {
131 String username = credentials.getUserName();
132 if (!Utils.isBlank(username)) {
133 UserIdentityManager.getInstance().setPartiallyIdentified(username);
134 }
135 }
136 // see #11914: clear cache before we store new value
137 purgeCredentialsCache(requestorType);
138 delegate.store(requestorType, host, credentials);
139 }
140
141 @Override
142 public CredentialsAgentResponse getCredentials(RequestorType requestorType, String host, boolean noSuccessWithLastResponse)
143 throws CredentialsAgentException {
144 CredentialsAgentResponse credentials = delegate.getCredentials(requestorType, host, noSuccessWithLastResponse);
145 if (requestorType == RequestorType.SERVER) {
146 // see #11914 : Keep UserIdentityManager up to date
147 String userName = credentials.getUsername();
148 userName = userName == null ? "" : userName.trim();
149 if (!Objects.equals(UserIdentityManager.getInstance().getUserName(), userName)) {
150 if (userName.isEmpty())
151 UserIdentityManager.getInstance().setAnonymous();
152 else
153 UserIdentityManager.getInstance().setPartiallyIdentified(userName);
154 }
155 }
156 return credentials;
157 }
158
159 @Override
160 public OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException {
161 return delegate.lookupOAuthAccessToken();
162 }
163
164 @Override
165 public IOAuthToken lookupOAuthAccessToken(String host) throws CredentialsAgentException {
166 return delegate.lookupOAuthAccessToken(host);
167 }
168
169 @Override
170 public void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException {
171 delegate.storeOAuthAccessToken(accessToken);
172 }
173
174 @Override
175 public void storeOAuthAccessToken(String host, IOAuthToken accessToken) throws CredentialsAgentException {
176 delegate.storeOAuthAccessToken(host, accessToken);
177 }
178
179 @Override
180 public Component getPreferencesDecorationPanel() {
181 return delegate.getPreferencesDecorationPanel();
182 }
183
184 @Override
185 public void purgeCredentialsCache(RequestorType requestorType) {
186 delegate.purgeCredentialsCache(requestorType);
187 }
188}
Note: See TracBrowser for help on using the repository browser.