Ticket #22810: 22810.2.patch
File 22810.2.patch, 251.3 KB (added by , 2 years ago) |
---|
-
core/src/org/openstreetmap/josm/data/oauth/OAuth20Parameters.java
Subject: [PATCH] See #22810: Drop deprecated authentication methods --- IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/data/oauth/OAuth20Parameters.java b/core/src/org/openstreetmap/josm/data/oauth/OAuth20Parameters.java
a b 147 147 if (this.tokenUrl != null) builder.add(TOKEN_URL, this.tokenUrl); 148 148 return builder.build().toString(); 149 149 } 150 151 @Override 152 public int hashCode() { 153 return Objects.hash(this.apiUrl, this.authorizeUrl, this.tokenUrl, this.clientId, this.clientSecret, this.redirectUri); 154 } 155 156 @Override 157 public boolean equals(Object obj) { 158 if (obj != null && this.getClass() == obj.getClass()) { 159 OAuth20Parameters other = (OAuth20Parameters) obj; 160 return Objects.equals(this.clientSecret, other.clientSecret) && 161 Objects.equals(this.clientId, other.clientId) && 162 Objects.equals(this.redirectUri, other.redirectUri) && 163 Objects.equals(this.tokenUrl, other.tokenUrl) && 164 Objects.equals(this.authorizeUrl, other.authorizeUrl) && 165 Objects.equals(this.apiUrl, other.apiUrl); 166 } 167 return false; 168 } 150 169 } -
core/src/org/openstreetmap/josm/data/oauth/OAuthAccessTokenHolder.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/data/oauth/OAuthAccessTokenHolder.java b/core/src/org/openstreetmap/josm/data/oauth/OAuthAccessTokenHolder.java
a b 36 36 } 37 37 38 38 private boolean saveToPreferences; 39 private String accessTokenKey;40 private String accessTokenSecret;41 39 42 40 private final Map<String, Map<OAuthVersion, IOAuthToken>> tokenMap = new HashMap<>(); 43 41 … … 52 50 53 51 /** 54 52 * Sets whether the current access token should be saved to the preferences file. 55 * 53 * <p> 56 54 * If true, the access token is saved in clear text to the preferences file. The same 57 55 * access token can therefore be used in multiple JOSM sessions. 58 * 56 * <p> 59 57 * If false, the access token isn't saved to the preferences file. If JOSM is closed, 60 58 * the access token is lost and new token has to be generated by the OSM server the 61 59 * next time JOSM is used. … … 66 64 this.saveToPreferences = saveToPreferences; 67 65 } 68 66 69 /**70 * Replies the access token key. null, if no access token key is currently set.71 *72 * @return the access token key73 */74 public String getAccessTokenKey() {75 return accessTokenKey;76 }77 78 /**79 * Sets the access token key. Pass in null to remove the current access token key.80 *81 * @param accessTokenKey the access token key82 */83 public void setAccessTokenKey(String accessTokenKey) {84 this.accessTokenKey = accessTokenKey;85 }86 87 /**88 * Replies the access token secret. null, if no access token secret is currently set.89 *90 * @return the access token secret91 */92 public String getAccessTokenSecret() {93 return accessTokenSecret;94 }95 96 /**97 * Sets the access token secret. Pass in null to remove the current access token secret.98 *99 * @param accessTokenSecret access token secret, or null100 */101 public void setAccessTokenSecret(String accessTokenSecret) {102 this.accessTokenSecret = accessTokenSecret;103 }104 105 /**106 * Replies the access token.107 * @return the access token, can be {@code null}108 */109 public OAuthToken getAccessToken() {110 if (!containsAccessToken())111 return null;112 return new OAuthToken(accessTokenKey, accessTokenSecret);113 }114 115 67 /** 116 68 * Replies the access token. 117 69 * @param api The api the token is for … … 139 91 return null; 140 92 } 141 93 142 /**143 * Sets the access token hold by this holder.144 *145 * @param accessTokenKey the access token key146 * @param accessTokenSecret the access token secret147 */148 public void setAccessToken(String accessTokenKey, String accessTokenSecret) {149 this.accessTokenKey = accessTokenKey;150 this.accessTokenSecret = accessTokenSecret;151 }152 153 /**154 * Sets the access token hold by this holder.155 *156 * @param token the access token. Can be null to clear the content in this holder.157 */158 public void setAccessToken(OAuthToken token) {159 if (token == null) {160 this.accessTokenKey = null;161 this.accessTokenSecret = null;162 } else {163 this.accessTokenKey = token.getKey();164 this.accessTokenSecret = token.getSecret();165 }166 }167 168 94 /** 169 95 * Sets the access token hold by this holder. 170 96 * … … 185 111 } 186 112 } 187 113 188 /**189 * Replies true if this holder contains an complete access token, consisting of an190 * Access Token Key and an Access Token Secret.191 *192 * @return true if this holder contains an complete access token193 */194 public boolean containsAccessToken() {195 return accessTokenKey != null && accessTokenSecret != null;196 }197 198 114 /** 199 115 * Initializes the content of this holder from the Access Token managed by the 200 116 * credential manager. … … 204 120 */ 205 121 public void init(CredentialsAgent cm) { 206 122 CheckParameterUtil.ensureParameterNotNull(cm, "cm"); 207 OAuthToken token = null;208 try {209 token = cm.lookupOAuthAccessToken();210 } catch (CredentialsAgentException e) {211 Logging.error(e);212 Logging.warn(tr("Failed to retrieve OAuth Access Token from credential manager"));213 Logging.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));214 }215 123 saveToPreferences = Config.getPref().getBoolean("oauth.access-token.save-to-preferences", true); 216 if (token != null) {217 accessTokenKey = token.getKey();218 accessTokenSecret = token.getSecret();219 }220 124 } 221 125 222 126 /** … … 231 135 Config.getPref().putBoolean("oauth.access-token.save-to-preferences", saveToPreferences); 232 136 try { 233 137 if (!saveToPreferences) { 234 cm.storeOAuthAccessToken(null);235 138 for (String host : this.tokenMap.keySet()) { 236 139 cm.storeOAuthAccessToken(host, null); 237 140 } 238 141 } else { 239 if (this.accessTokenKey != null && this.accessTokenSecret != null) {240 cm.storeOAuthAccessToken(new OAuthToken(accessTokenKey, accessTokenSecret));241 } else {242 cm.storeOAuthAccessToken(null);243 }244 142 for (Map.Entry<String, Map<OAuthVersion, IOAuthToken>> entry : this.tokenMap.entrySet()) { 245 143 if (entry.getValue().isEmpty()) { 246 144 cm.storeOAuthAccessToken(entry.getKey(), null); … … 264 162 * Clears the content of this holder 265 163 */ 266 164 public void clear() { 267 accessTokenKey = null; 268 accessTokenSecret = null; 165 this.tokenMap.clear(); 269 166 } 270 167 } -
core/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java b/core/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java
a b 3 3 4 4 import java.io.BufferedReader; 5 5 import java.io.IOException; 6 import java.net.URL; 7 import java.util.Objects; 6 import java.net.URI; 7 import java.net.URISyntaxException; 8 import java.util.Arrays; 8 9 9 10 import jakarta.json.Json; 10 11 import jakarta.json.JsonObject; … … 17 18 import org.openstreetmap.josm.io.auth.CredentialsManager; 18 19 import org.openstreetmap.josm.spi.preferences.Config; 19 20 import org.openstreetmap.josm.spi.preferences.IUrls; 20 import org.openstreetmap.josm.tools.CheckParameterUtil;21 21 import org.openstreetmap.josm.tools.HttpClient; 22 22 import org.openstreetmap.josm.tools.Logging; 23 23 import org.openstreetmap.josm.tools.Utils; 24 24 25 import oauth.signpost.OAuthConsumer;26 import oauth.signpost.OAuthProvider;27 28 25 /** 29 26 * This class manages an immutable set of OAuth parameters. 30 * @since 2747 27 * @since 2747 (static factory class since xxx) 31 28 */ 32 public class OAuthParameters implements IOAuthParameters { 29 public final class OAuthParameters { 30 private static final String OSM_API_DEFAULT = "https://api.openstreetmap.org/api"; 31 private static final String OSM_API_DEV = "https://api06.dev.openstreetmap.org/api"; 32 private static final String OSM_API_MASTER = "https://master.apis.dev.openstreetmap.org/api"; 33 33 34 /** 35 * The default JOSM OAuth consumer key (created by user josmeditor). 36 */ 37 public static final String DEFAULT_JOSM_CONSUMER_KEY = "F7zPYlVCqE2BUH9Hr4SsWZSOnrKjpug1EgqkbsSb"; 38 /** 39 * The default JOSM OAuth consumer secret (created by user josmeditor). 40 */ 41 public static final String DEFAULT_JOSM_CONSUMER_SECRET = "rIkjpPcBNkMQxrqzcOvOC4RRuYupYr7k8mfP13H5"; 34 private OAuthParameters() { 35 // Hide constructor 36 } 42 37 43 38 /** 44 39 * Replies a set of default parameters for a consumer accessing the standard OSM server … … 46 41 * 47 42 * @return a set of default parameters 48 43 */ 49 public static OAuthParameters createDefault() { 50 return createDefault(null); 51 } 52 53 /** 54 * Replies a set of default parameters for a consumer accessing an OSM server 55 * at the given API url. URL parameters are only set if the URL equals {@link IUrls#getDefaultOsmApiUrl} 56 * or references the domain "dev.openstreetmap.org", otherwise they may be <code>null</code>. 57 * 58 * @param apiUrl The API URL for which the OAuth default parameters are created. If null or empty, the default OSM API url is used. 59 * @return a set of default parameters for the given {@code apiUrl} 60 * @since 5422 61 */ 62 public static OAuthParameters createDefault(String apiUrl) { 63 return (OAuthParameters) createDefault(apiUrl, OAuthVersion.OAuth10a); 44 public static IOAuthParameters createDefault() { 45 return createDefault(Config.getUrls().getDefaultOsmApiUrl(), OAuthVersion.OAuth20); 64 46 } 65 47 66 48 /** … … 79 61 } 80 62 81 63 switch (oAuthVersion) { 82 case OAuth10a:83 return getDefaultOAuth10Parameters(apiUrl);84 64 case OAuth20: 85 65 case OAuth21: // For now, OAuth 2.1 (draft) is just OAuth 2.0 with mandatory extensions, which we implement. 86 66 return getDefaultOAuth20Parameters(apiUrl); … … 97 77 private static OAuth20Parameters getDefaultOAuth20Parameters(String apiUrl) { 98 78 final String clientId; 99 79 final String clientSecret; 100 final String redirectUri ;80 final String redirectUri = "http://127.0.0.1:8111/oauth_authorization"; 101 81 final String baseUrl; 102 if (apiUrl != null && !Config.getUrls().getDefaultOsmApiUrl().equals(apiUrl) && !"http://invalid".equals(apiUrl)) { 82 apiUrl = apiUrl == null ? OsmApi.getOsmApi().getServerUrl() : apiUrl; 83 if (!OsmApi.getOsmApi().getServerUrl().equals(apiUrl) 84 && !Arrays.asList(OSM_API_DEFAULT, OSM_API_DEV, OSM_API_MASTER).contains(apiUrl) 85 && !"http://invalid".equals(apiUrl)) { 103 86 clientId = ""; 104 87 clientSecret = ""; 105 88 baseUrl = apiUrl; 106 89 HttpClient client = null; 107 redirectUri = "";108 90 // Check if the server is RFC 8414 compliant 109 91 try { 110 client = HttpClient.create(new URL(apiUrl + (apiUrl.endsWith("/") ? "" : "/") + ".well-known/oauth-authorization-server")); 92 client = HttpClient.create(new URI(apiUrl + (apiUrl.endsWith("/") ? "" : "/") 93 + ".well-known/oauth-authorization-server").toURL()); 111 94 HttpClient.Response response = client.connect(); 112 95 if (response.getResponseCode() == 200) { 113 96 try (BufferedReader reader = response.getContentReader(); … … 119 102 } 120 103 } 121 104 } 122 } catch ( IOException | OAuthException e) {105 } catch (URISyntaxException | IOException | OAuthException e) { 123 106 Logging.trace(e); 124 107 } finally { 125 108 if (client != null) client.disconnect(); 126 109 } 127 110 } else { 128 clientId = "edPII614Lm0_0zEpc_QzEltA9BUll93-Y-ugRQUoHMI"; 129 // We don't actually use the client secret in our authorization flow. 130 clientSecret = null; 131 baseUrl = "https://www.openstreetmap.org/oauth2"; 132 redirectUri = "http://127.0.0.1:8111/oauth_authorization"; 111 switch (apiUrl) { 112 case OSM_API_DEV: 113 case OSM_API_MASTER: 114 // This clientId/clientSecret are provided by taylor.smock. Feel free to change if needed, but 115 // do let one of the maintainers with server access know so that they can update the test OAuth 116 // token. 117 clientId = "-QZt6n1btDfqrfJNGUIMZjzcyqTgIV6sy79_W4kmQLM"; 118 // Keep secret for dev apis, just in case we want to test something that needs it. 119 clientSecret = "SWnmRD4AdLO-2-ttHE5TR3eLF2McNf7dh0_Z2WNzJdI"; 120 break; 121 case OSM_API_DEFAULT: 122 clientId = "edPII614Lm0_0zEpc_QzEltA9BUll93-Y-ugRQUoHMI"; 123 // We don't actually use the client secret in our authorization flow. 124 clientSecret = null; 125 break; 126 default: 127 clientId = ""; 128 clientSecret = null; 129 } 130 baseUrl = "https://" + OsmApi.getOsmApi().getHost() + "/oauth2"; 133 131 apiUrl = OsmApi.getOsmApi().getBaseUrl(); 134 132 } 135 133 return new OAuth20Parameters(clientId, clientSecret, baseUrl, apiUrl, redirectUri); … … 153 151 return new OAuth20Parameters(clientId, clientSecret, tokenEndpoint, authorizationEndpoint, apiUrl, redirectUri); 154 152 } 155 153 156 /**157 * Get the default OAuth 1.0a parameters158 * @param apiUrl The api url159 * @return The default parameters160 */161 private static OAuthParameters getDefaultOAuth10Parameters(String apiUrl) {162 final String consumerKey;163 final String consumerSecret;164 final String serverUrl;165 166 if (apiUrl != null && !Config.getUrls().getDefaultOsmApiUrl().equals(apiUrl)) {167 consumerKey = ""; // a custom consumer key is required168 consumerSecret = ""; // a custom consumer secret is requireds169 serverUrl = apiUrl.replaceAll("/api$", "");170 } else {171 consumerKey = DEFAULT_JOSM_CONSUMER_KEY;172 consumerSecret = DEFAULT_JOSM_CONSUMER_SECRET;173 serverUrl = Config.getUrls().getOSMWebsite();174 }175 176 return new OAuthParameters(177 consumerKey,178 consumerSecret,179 serverUrl + "/oauth/request_token",180 serverUrl + "/oauth/access_token",181 serverUrl + "/oauth/authorize",182 serverUrl + "/login",183 serverUrl + "/logout");184 }185 186 /**187 * Replies a set of parameters as defined in the preferences.188 *189 * @param apiUrl the API URL. Must not be null.190 * @return the parameters191 */192 public static OAuthParameters createFromApiUrl(String apiUrl) {193 return (OAuthParameters) createFromApiUrl(apiUrl, OAuthVersion.OAuth10a);194 }195 196 154 /** 197 155 * Replies a set of parameters as defined in the preferences. 198 156 * … … 204 162 public static IOAuthParameters createFromApiUrl(String apiUrl, OAuthVersion oAuthVersion) { 205 163 IOAuthParameters parameters = createDefault(apiUrl, oAuthVersion); 206 164 switch (oAuthVersion) { 207 case OAuth10a:208 OAuthParameters oauth10aParameters = (OAuthParameters) parameters;209 return new OAuthParameters(210 Config.getPref().get("oauth.settings.consumer-key", oauth10aParameters.getConsumerKey()),211 Config.getPref().get("oauth.settings.consumer-secret", oauth10aParameters.getConsumerSecret()),212 Config.getPref().get("oauth.settings.request-token-url", oauth10aParameters.getRequestTokenUrl()),213 Config.getPref().get("oauth.settings.access-token-url", oauth10aParameters.getAccessTokenUrl()),214 Config.getPref().get("oauth.settings.authorise-url", oauth10aParameters.getAuthoriseUrl()),215 Config.getPref().get("oauth.settings.osm-login-url", oauth10aParameters.getOsmLoginUrl()),216 Config.getPref().get("oauth.settings.osm-logout-url", oauth10aParameters.getOsmLogoutUrl()));217 165 case OAuth20: 218 166 case OAuth21: // Right now, OAuth 2.1 will work with our OAuth 2.0 implementation 219 167 OAuth20Parameters oAuth20Parameters = (OAuth20Parameters) parameters; … … 228 176 throw new IllegalArgumentException("Unknown OAuth version: " + oAuthVersion); 229 177 } 230 178 } 231 232 /**233 * Remembers the current values in the preferences.234 */235 @Override236 public void rememberPreferences() {237 Config.getPref().put("oauth.settings.consumer-key", getConsumerKey());238 Config.getPref().put("oauth.settings.consumer-secret", getConsumerSecret());239 Config.getPref().put("oauth.settings.request-token-url", getRequestTokenUrl());240 Config.getPref().put("oauth.settings.access-token-url", getAccessTokenUrl());241 Config.getPref().put("oauth.settings.authorise-url", getAuthoriseUrl());242 Config.getPref().put("oauth.settings.osm-login-url", getOsmLoginUrl());243 Config.getPref().put("oauth.settings.osm-logout-url", getOsmLogoutUrl());244 }245 246 private final String consumerKey;247 private final String consumerSecret;248 private final String requestTokenUrl;249 private final String accessTokenUrl;250 private final String authoriseUrl;251 private final String osmLoginUrl;252 private final String osmLogoutUrl;253 254 /**255 * Constructs a new {@code OAuthParameters}.256 * @param consumerKey consumer key257 * @param consumerSecret consumer secret258 * @param requestTokenUrl request token URL259 * @param accessTokenUrl access token URL260 * @param authoriseUrl authorise URL261 * @param osmLoginUrl the OSM login URL (for automatic mode)262 * @param osmLogoutUrl the OSM logout URL (for automatic mode)263 * @see #createDefault264 * @see #createFromApiUrl265 * @since 9220266 */267 public OAuthParameters(String consumerKey, String consumerSecret,268 String requestTokenUrl, String accessTokenUrl, String authoriseUrl, String osmLoginUrl, String osmLogoutUrl) {269 this.consumerKey = consumerKey;270 this.consumerSecret = consumerSecret;271 this.requestTokenUrl = requestTokenUrl;272 this.accessTokenUrl = accessTokenUrl;273 this.authoriseUrl = authoriseUrl;274 this.osmLoginUrl = osmLoginUrl;275 this.osmLogoutUrl = osmLogoutUrl;276 }277 278 /**279 * Creates a clone of the parameters in <code>other</code>.280 *281 * @param other the other parameters. Must not be null.282 * @throws IllegalArgumentException if other is null283 */284 public OAuthParameters(OAuthParameters other) {285 CheckParameterUtil.ensureParameterNotNull(other, "other");286 this.consumerKey = other.consumerKey;287 this.consumerSecret = other.consumerSecret;288 this.accessTokenUrl = other.accessTokenUrl;289 this.requestTokenUrl = other.requestTokenUrl;290 this.authoriseUrl = other.authoriseUrl;291 this.osmLoginUrl = other.osmLoginUrl;292 this.osmLogoutUrl = other.osmLogoutUrl;293 }294 295 /**296 * Gets the consumer key.297 * @return The consumer key298 */299 public String getConsumerKey() {300 return consumerKey;301 }302 303 /**304 * Gets the consumer secret.305 * @return The consumer secret306 */307 public String getConsumerSecret() {308 return consumerSecret;309 }310 311 /**312 * Gets the request token URL.313 * @return The request token URL314 */315 public String getRequestTokenUrl() {316 return requestTokenUrl;317 }318 319 /**320 * Gets the access token URL.321 * @return The access token URL322 */323 @Override324 public String getAccessTokenUrl() {325 return accessTokenUrl;326 }327 328 @Override329 public String getAuthorizationUrl() {330 return this.authoriseUrl;331 }332 333 @Override334 public OAuthVersion getOAuthVersion() {335 return OAuthVersion.OAuth10a;336 }337 338 @Override339 public String getClientId() {340 return this.consumerKey;341 }342 343 @Override344 public String getClientSecret() {345 return this.consumerSecret;346 }347 348 /**349 * Gets the authorise URL.350 * @return The authorise URL351 */352 public String getAuthoriseUrl() {353 return this.getAuthorizationUrl();354 }355 356 /**357 * Gets the URL used to login users on the website (for automatic mode).358 * @return The URL used to login users359 */360 public String getOsmLoginUrl() {361 return osmLoginUrl;362 }363 364 /**365 * Gets the URL used to logout users on the website (for automatic mode).366 * @return The URL used to logout users367 */368 public String getOsmLogoutUrl() {369 return osmLogoutUrl;370 }371 372 /**373 * Builds an {@link OAuthConsumer} based on these parameters.374 *375 * @return the consumer376 */377 public OAuthConsumer buildConsumer() {378 return new SignpostAdapters.OAuthConsumer(consumerKey, consumerSecret);379 }380 381 /**382 * Builds an {@link OAuthProvider} based on these parameters and a OAuth consumer <code>consumer</code>.383 *384 * @param consumer the consumer. Must not be null.385 * @return the provider386 * @throws IllegalArgumentException if consumer is null387 */388 public OAuthProvider buildProvider(OAuthConsumer consumer) {389 CheckParameterUtil.ensureParameterNotNull(consumer, "consumer");390 return new SignpostAdapters.OAuthProvider(391 requestTokenUrl,392 accessTokenUrl,393 authoriseUrl394 );395 }396 397 @Override398 public boolean equals(Object o) {399 if (this == o) return true;400 if (o == null || getClass() != o.getClass()) return false;401 OAuthParameters that = (OAuthParameters) o;402 return Objects.equals(consumerKey, that.consumerKey) &&403 Objects.equals(consumerSecret, that.consumerSecret) &&404 Objects.equals(requestTokenUrl, that.requestTokenUrl) &&405 Objects.equals(accessTokenUrl, that.accessTokenUrl) &&406 Objects.equals(authoriseUrl, that.authoriseUrl) &&407 Objects.equals(osmLoginUrl, that.osmLoginUrl) &&408 Objects.equals(osmLogoutUrl, that.osmLogoutUrl);409 }410 411 @Override412 public int hashCode() {413 return Objects.hash(consumerKey, consumerSecret, requestTokenUrl, accessTokenUrl, authoriseUrl, osmLoginUrl, osmLogoutUrl);414 }415 179 } -
deleted file core/src/org/openstreetmap/josm/data/oauth/OAuthToken.java
diff --git a/core/src/org/openstreetmap/josm/data/oauth/OAuthToken.java b/core/src/org/openstreetmap/josm/data/oauth/OAuthToken.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.data.oauth;3 4 import java.util.Objects;5 6 import org.openstreetmap.josm.tools.CheckParameterUtil;7 8 import oauth.signpost.OAuthConsumer;9 10 /**11 * An oauth token that has been obtained by JOSM and can be used to authenticate the user on the server.12 */13 public class OAuthToken {14 15 /**16 * Creates an OAuthToken from the token currently managed by the {@link OAuthConsumer}.17 *18 * @param consumer the consumer19 * @return the token20 */21 public static OAuthToken createToken(OAuthConsumer consumer) {22 return new OAuthToken(consumer.getToken(), consumer.getTokenSecret());23 }24 25 private final String key;26 private final String secret;27 28 /**29 * Creates a new token30 *31 * @param key the token key32 * @param secret the token secret33 */34 public OAuthToken(String key, String secret) {35 this.key = key;36 this.secret = secret;37 }38 39 /**40 * Creates a clone of another token41 *42 * @param other the other token. Must not be null.43 * @throws IllegalArgumentException if other is null44 */45 public OAuthToken(OAuthToken other) {46 CheckParameterUtil.ensureParameterNotNull(other, "other");47 this.key = other.key;48 this.secret = other.secret;49 }50 51 /**52 * Replies the token key53 *54 * @return the token key55 */56 public String getKey() {57 return key;58 }59 60 /**61 * Replies the token secret62 *63 * @return the token secret64 */65 public String getSecret() {66 return secret;67 }68 69 @Override70 public int hashCode() {71 return Objects.hash(key, secret);72 }73 74 @Override75 public boolean equals(Object obj) {76 if (this == obj) return true;77 if (obj == null || getClass() != obj.getClass()) return false;78 OAuthToken that = (OAuthToken) obj;79 return Objects.equals(key, that.key) &&80 Objects.equals(secret, that.secret);81 }82 } -
core/src/org/openstreetmap/josm/data/oauth/OAuthVersion.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/data/oauth/OAuthVersion.java b/core/src/org/openstreetmap/josm/data/oauth/OAuthVersion.java
a b 8 8 */ 9 9 public enum OAuthVersion { 10 10 /** <a href="https://oauth.net/core/1.0a/">OAuth 1.0a</a> */ 11 @Deprecated 11 12 OAuth10a, 12 13 /** <a href="https://datatracker.ietf.org/doc/html/rfc6749">OAuth 2.0</a> */ 13 14 OAuth20, -
deleted file core/src/org/openstreetmap/josm/data/oauth/SignpostAdapters.java
diff --git a/core/src/org/openstreetmap/josm/data/oauth/SignpostAdapters.java b/core/src/org/openstreetmap/josm/data/oauth/SignpostAdapters.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.data.oauth;3 4 import java.io.IOException;5 import java.io.InputStream;6 import java.net.URL;7 import java.util.Map;8 9 import org.openstreetmap.josm.tools.HttpClient;10 11 import oauth.signpost.AbstractOAuthConsumer;12 import oauth.signpost.AbstractOAuthProvider;13 14 /**15 * Adapters to make {@code oauth.signpost} work with {@link HttpClient}.16 */17 public final class SignpostAdapters {18 19 private SignpostAdapters() {20 // Hide constructor for utility classes21 }22 23 /**24 * OAuth provider.25 */26 public static class OAuthProvider extends AbstractOAuthProvider {27 28 private static final long serialVersionUID = 1L;29 30 /**31 * Constructs a new {@code OAuthProvider}.32 * @param requestTokenEndpointUrl request token endpoint URL33 * @param accessTokenEndpointUrl access token endpoint URL34 * @param authorizationWebsiteUrl authorization website URL35 */36 public OAuthProvider(String requestTokenEndpointUrl, String accessTokenEndpointUrl, String authorizationWebsiteUrl) {37 super(requestTokenEndpointUrl, accessTokenEndpointUrl, authorizationWebsiteUrl);38 }39 40 @Override41 protected HttpRequest createRequest(String endpointUrl) throws Exception {42 return new HttpRequest(HttpClient.create(new URL(endpointUrl)));43 }44 45 @Override46 protected HttpResponse sendRequest(oauth.signpost.http.HttpRequest request) throws Exception {47 return new HttpResponse(((HttpRequest) request).request.connect());48 }49 50 @Override51 protected void closeConnection(oauth.signpost.http.HttpRequest request, oauth.signpost.http.HttpResponse response) throws Exception {52 if (response != null) {53 ((HttpResponse) response).response.disconnect();54 } else if (request != null) {55 ((HttpRequest) request).request.disconnect();56 }57 }58 }59 60 /**61 * OAuth consumer.62 */63 public static class OAuthConsumer extends AbstractOAuthConsumer {64 65 private static final long serialVersionUID = 1L;66 67 /**68 * Constructs a new {@code OAuthConsumer}.69 * @param consumerKey consumer key70 * @param consumerSecret consumer secret71 */72 public OAuthConsumer(String consumerKey, String consumerSecret) {73 super(consumerKey, consumerSecret);74 }75 76 @Override77 protected HttpRequest wrap(Object request) {78 return new HttpRequest((HttpClient) request);79 }80 }81 82 static final class HttpRequest implements oauth.signpost.http.HttpRequest {83 final HttpClient request;84 85 HttpRequest(HttpClient request) {86 this.request = request;87 }88 89 @Override90 public void setHeader(String name, String value) {91 request.setHeader(name, value);92 }93 94 @Override95 public String getMethod() {96 return request.getRequestMethod();97 }98 99 @Override100 public String getRequestUrl() {101 return request.getURL().toExternalForm();102 }103 104 @Override105 public String getContentType() {106 return request.getRequestHeader("Content-Type");107 }108 109 @Override110 public String getHeader(String name) {111 return request.getRequestHeader(name);112 }113 114 @Override115 public InputStream getMessagePayload() {116 return null;117 }118 119 @Override120 public void setRequestUrl(String url) {121 throw new IllegalStateException();122 }123 124 @Override125 public Map<String, String> getAllHeaders() {126 throw new IllegalStateException();127 }128 129 @Override130 public Object unwrap() {131 throw new IllegalStateException();132 }133 }134 135 static final class HttpResponse implements oauth.signpost.http.HttpResponse {136 final HttpClient.Response response;137 138 HttpResponse(HttpClient.Response response) {139 this.response = response;140 }141 142 @Override143 public int getStatusCode() {144 return response.getResponseCode();145 }146 147 @Override148 public String getReasonPhrase() {149 return response.getResponseMessage();150 }151 152 @Override153 public InputStream getContent() throws IOException {154 return response.getContent();155 }156 157 @Override158 public Object unwrap() {159 throw new IllegalStateException();160 }161 }162 } -
core/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java b/core/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java
a b 4 4 import java.util.Objects; 5 5 6 6 import org.openstreetmap.josm.data.oauth.IOAuthParameters; 7 import org.openstreetmap.josm.data.oauth.IOAuthToken; 7 8 import org.openstreetmap.josm.data.oauth.OAuthParameters; 8 import org.openstreetmap.josm.data.oauth.OAuthToken;9 9 import org.openstreetmap.josm.data.oauth.OAuthVersion; 10 10 import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel; 11 11 import org.openstreetmap.josm.tools.CheckParameterUtil; … … 22 22 public static final String ACCESS_TOKEN_PROP = AbstractAuthorizationUI.class.getName() + ".accessToken"; 23 23 24 24 private String apiUrl; 25 private final AdvancedOAuthPropertiesPanel pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel(OAuthVersion.OAuth10a); 26 private transient OAuthToken accessToken; 27 28 /** 29 * Constructs a new {@code AbstractAuthorizationUI} without API URL. 30 * @since 10189 31 */ 32 protected AbstractAuthorizationUI() { 33 } 25 private final AdvancedOAuthPropertiesPanel pnlAdvancedProperties; 26 private transient IOAuthToken accessToken; 34 27 35 28 /** 36 29 * Constructs a new {@code AbstractAuthorizationUI} for the given API URL. 37 * @param apiUrl The OSM API URL 38 * @since 5422 30 * @param apiUrl The OSM API URL (may be null) 31 * @param oAuthVersion The oauth version to use 32 * @since xxx 39 33 */ 40 protected AbstractAuthorizationUI(String apiUrl) { 41 setApiUrl(apiUrl); 34 protected AbstractAuthorizationUI(String apiUrl, OAuthVersion oAuthVersion) { 35 this.pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel(oAuthVersion); 36 if (apiUrl != null) { 37 setApiUrl(apiUrl); 38 } 42 39 } 43 40 44 protected void fireAccessTokenChanged( OAuthToken oldValue,OAuthToken newValue) {41 protected void fireAccessTokenChanged(IOAuthToken oldValue, IOAuthToken newValue) { 45 42 firePropertyChange(ACCESS_TOKEN_PROP, oldValue, newValue); 46 43 } 47 44 … … 90 87 * 91 88 * @return the retrieved Access Token 92 89 */ 93 public OAuthToken getAccessToken() {90 public IOAuthToken getAccessToken() { 94 91 return accessToken; 95 92 } 96 93 … … 100 97 * 101 98 * @param accessToken the new access token. null, to clear the current access token 102 99 */ 103 protected void setAccessToken( OAuthToken accessToken) {104 OAuthToken oldValue = this.accessToken;100 protected void setAccessToken(IOAuthToken accessToken) { 101 IOAuthToken oldValue = this.accessToken; 105 102 this.accessToken = accessToken; 106 103 if (oldValue == null ^ this.accessToken == null) { 107 104 fireAccessTokenChanged(oldValue, this.accessToken); … … 112 109 } 113 110 } 114 111 112 /** 113 * Get the OAuth version for this AuthorizationUI 114 * @return The OAuth version 115 * @since xxx 116 */ 117 public OAuthVersion getOAuthVersion() { 118 return this.pnlAdvancedProperties.getAdvancedParameters().getOAuthVersion(); 119 } 120 115 121 /** 116 122 * Replies true if this UI currently has an Access Token 117 123 * -
core/src/org/openstreetmap/josm/gui/oauth/AccessTokenInfoPanel.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/oauth/AccessTokenInfoPanel.java b/core/src/org/openstreetmap/josm/gui/oauth/AccessTokenInfoPanel.java
a b 11 11 import javax.swing.JLabel; 12 12 import javax.swing.JPanel; 13 13 14 import org.openstreetmap.josm.data.oauth.IOAuthToken; 15 import org.openstreetmap.josm.data.oauth.OAuth20Token; 14 16 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder; 15 import org.openstreetmap.josm.data.oauth.OAuthToken;16 17 import org.openstreetmap.josm.gui.widgets.JosmTextField; 18 import org.openstreetmap.josm.tools.JosmRuntimeException; 17 19 18 20 /** 19 * Displays the key and the secretof an OAuth Access Token.20 * @since 2746 21 * Displays the key of an OAuth Access Token. 22 * @since 2746 (modified for OAuth 2 in xxx) 21 23 */ 22 24 public class AccessTokenInfoPanel extends JPanel { 23 25 24 26 private final JosmTextField tfAccessTokenKey = new JosmTextField(null, null, 0, false); 25 private final JosmTextField tfAccessTokenSecret = new JosmTextField(null, null, 0, false);26 27 private final JCheckBox cbSaveAccessTokenInPreferences = new JCheckBox(tr("Save Access Token in preferences")); 27 28 28 29 /** … … 55 56 gc.insets = new Insets(0, 0, 3, 3); 56 57 add(new JLabel(tr("Access Token Secret:")), gc); 57 58 58 gc.gridx = 1;59 59 gc.weightx = 1.0; 60 add(tfAccessTokenSecret, gc);61 tfAccessTokenSecret.setEditable(false);62 63 60 // the checkbox 64 61 gc.gridx = 0; 65 62 gc.gridy = 2; … … 86 83 * 87 84 * @param token the access token. If null, the content in the info panel is cleared 88 85 */ 89 public void setAccessToken( OAuthToken token) {86 public void setAccessToken(IOAuthToken token) { 90 87 if (token == null) { 91 88 tfAccessTokenKey.setText(""); 92 tfAccessTokenSecret.setText("");93 89 return; 94 90 } 95 tfAccessTokenKey.setText(token.getKey()); 96 tfAccessTokenSecret.setText(token.getSecret()); 91 if (token instanceof OAuth20Token) { 92 tfAccessTokenKey.setText(((OAuth20Token) token).getBearerToken()); 93 } else { 94 throw new JosmRuntimeException("Unknown token type: " + token.getClass()); 95 } 97 96 } 98 97 99 98 public void setSaveToPreferences(boolean saveToPreferences) { -
core/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java b/core/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java
a b 52 52 private final JosmTextField tfRequestTokenURL = new JosmTextField(); 53 53 private final JosmTextField tfAccessTokenURL = new JosmTextField(); 54 54 private final JosmTextField tfAuthoriseURL = new JosmTextField(); 55 private final JosmTextField tfOsmLoginURL = new JosmTextField();56 private final JosmTextField tfOsmLogoutURL = new JosmTextField();57 55 private final OAuthVersion oauthVersion; 58 56 private transient UseDefaultItemListener ilUseDefault; 59 57 private String apiUrl; … … 83 81 gc.gridy = 1; 84 82 gc.weightx = 0.0; 85 83 gc.gridwidth = 1; 86 if (this.oauthVersion == OAuthVersion.OAuth10a) { 87 add(new JLabel(tr("Consumer Key:")), gc); 88 } else { 89 add(new JLabel(tr("Client ID:")), gc); 90 } 84 add(new JLabel(tr("Client ID:")), gc); 91 85 92 86 gc.gridx = 1; 93 87 gc.weightx = 1.0; … … 98 92 gc.gridy++; 99 93 gc.gridx = 0; 100 94 gc.weightx = 0.0; 101 if (this.oauthVersion == OAuthVersion.OAuth10a) { 102 add(new JLabel(tr("Consumer Secret:")), gc); 103 } else { 104 add(new JLabel(tr("Client Secret:")), gc); 105 } 95 add(new JLabel(tr("Client Secret:")), gc); 106 96 107 97 gc.gridx = 1; 108 98 gc.weightx = 1.0; … … 113 103 gc.gridy++; 114 104 gc.gridx = 0; 115 105 gc.weightx = 0.0; 116 if (this.oauthVersion == OAuthVersion.OAuth10a) { 117 add(new JLabel(tr("Request Token URL:")), gc); 118 } else { 119 add(new JLabel(tr("Redirect URL:")), gc); 120 } 106 add(new JLabel(tr("Redirect URL:")), gc); 121 107 122 108 gc.gridx = 1; 123 109 gc.weightx = 1.0; … … 146 132 add(tfAuthoriseURL, gc); 147 133 SelectAllOnFocusGainedDecorator.decorate(tfAuthoriseURL); 148 134 149 if (this.oauthVersion == OAuthVersion.OAuth10a) {150 // -- OSM login URL151 gc.gridy++;152 gc.gridx = 0;153 gc.weightx = 0.0;154 add(new JLabel(tr("OSM login URL:")), gc);155 156 gc.gridx = 1;157 gc.weightx = 1.0;158 add(tfOsmLoginURL, gc);159 SelectAllOnFocusGainedDecorator.decorate(tfOsmLoginURL);160 161 // -- OSM logout URL162 gc.gridy++;163 gc.gridx = 0;164 gc.weightx = 0.0;165 add(new JLabel(tr("OSM logout URL:")), gc);166 167 gc.gridx = 1;168 gc.weightx = 1.0;169 add(tfOsmLogoutURL, gc);170 SelectAllOnFocusGainedDecorator.decorate(tfOsmLogoutURL);171 }172 173 135 ilUseDefault = new UseDefaultItemListener(); 174 136 cbUseDefaults.addItemListener(ilUseDefault); 175 137 } 176 138 177 139 protected boolean hasCustomSettings() { 178 OAuthParameters params = OAuthParameters.createDefault(apiUrl);140 IOAuthParameters params = OAuthParameters.createDefault(apiUrl, OAuthVersion.OAuth20); 179 141 return !params.equals(getAdvancedParameters()); 180 142 } 181 143 … … 213 175 cbUseDefaults.setSelected(true); 214 176 IOAuthParameters iParams = OAuthParameters.createDefault(apiUrl, this.oauthVersion); 215 177 switch (this.oauthVersion) { 216 case OAuth10a:217 OAuthParameters params = (OAuthParameters) iParams;218 tfConsumerKey.setText(params.getConsumerKey());219 tfConsumerSecret.setText(params.getConsumerSecret());220 tfRequestTokenURL.setText(params.getRequestTokenUrl());221 tfAccessTokenURL.setText(params.getAccessTokenUrl());222 tfAuthoriseURL.setText(params.getAuthoriseUrl());223 tfOsmLoginURL.setText(params.getOsmLoginUrl());224 tfOsmLogoutURL.setText(params.getOsmLogoutUrl());225 break;226 178 case OAuth20: 227 179 case OAuth21: 228 180 OAuth20Parameters params20 = (OAuth20Parameters) iParams; … … 231 183 tfAccessTokenURL.setText(params20.getAccessTokenUrl()); 232 184 tfAuthoriseURL.setText(params20.getAuthorizationUrl()); 233 185 tfRequestTokenURL.setText(params20.getRedirectUri()); 186 break; 187 default: 188 throw new UnsupportedOperationException("Unsupported OAuth version: " + this.oauthVersion); 234 189 } 235 190 236 191 setChildComponentsEnabled(false); … … 252 207 public IOAuthParameters getAdvancedParameters() { 253 208 if (cbUseDefaults.isSelected()) 254 209 return OAuthParameters.createDefault(apiUrl, this.oauthVersion); 255 if (this.oauthVersion == OAuthVersion.OAuth10a) {256 return new OAuthParameters(257 tfConsumerKey.getText(),258 tfConsumerSecret.getText(),259 tfRequestTokenURL.getText(),260 tfAccessTokenURL.getText(),261 tfAuthoriseURL.getText(),262 tfOsmLoginURL.getText(),263 tfOsmLogoutURL.getText());264 }265 210 return new OAuth20Parameters( 266 211 tfConsumerKey.getText(), 267 212 tfConsumerSecret.getText(), … … 285 230 } else { 286 231 cbUseDefaults.setSelected(false); 287 232 setChildComponentsEnabled(true); 288 if (parameters instanceof OAuthParameters) { 289 OAuthParameters parameters10 = (OAuthParameters) parameters; 290 tfConsumerKey.setText(parameters10.getConsumerKey() == null ? "" : parameters10.getConsumerKey()); 291 tfConsumerSecret.setText(parameters10.getConsumerSecret() == null ? "" : parameters10.getConsumerSecret()); 292 tfRequestTokenURL.setText(parameters10.getRequestTokenUrl() == null ? "" : parameters10.getRequestTokenUrl()); 293 tfAccessTokenURL.setText(parameters10.getAccessTokenUrl() == null ? "" : parameters10.getAccessTokenUrl()); 294 tfAuthoriseURL.setText(parameters10.getAuthoriseUrl() == null ? "" : parameters10.getAuthoriseUrl()); 295 tfOsmLoginURL.setText(parameters10.getOsmLoginUrl() == null ? "" : parameters10.getOsmLoginUrl()); 296 tfOsmLogoutURL.setText(parameters10.getOsmLogoutUrl() == null ? "" : parameters10.getOsmLogoutUrl()); 297 } else if (parameters instanceof OAuth20Parameters) { 233 if (parameters instanceof OAuth20Parameters) { 298 234 OAuth20Parameters parameters20 = (OAuth20Parameters) parameters; 299 235 tfConsumerKey.setText(parameters20.getClientId()); 300 236 tfConsumerSecret.setText(parameters20.getClientSecret()); … … 319 255 if (useDefault) { 320 256 resetToDefaultSettings(); 321 257 } else { 322 setAdvancedParameters(OAuthParameters.createFromApiUrl(paramApiUrl ));258 setAdvancedParameters(OAuthParameters.createFromApiUrl(paramApiUrl, OAuthVersion.OAuth20)); 323 259 } 324 260 ilUseDefault.setEnabled(true); 325 261 } … … 330 266 public void rememberPreferences() { 331 267 Config.getPref().putBoolean("oauth.settings.use-default", cbUseDefaults.isSelected()); 332 268 if (cbUseDefaults.isSelected()) { 333 new OAuthParameters(null, null, null, null, null, null, null).rememberPreferences();269 OAuthParameters.createDefault().rememberPreferences(); 334 270 } else { 335 271 getAdvancedParameters().rememberPreferences(); 336 272 } -
core/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java b/core/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java
a b 12 12 import java.awt.Insets; 13 13 import java.awt.event.ActionEvent; 14 14 import java.io.IOException; 15 import java.net.Authenticator.RequestorType;16 import java.net.PasswordAuthentication;17 15 import java.util.concurrent.Executor; 18 16 19 17 import javax.swing.AbstractAction; … … 23 21 import javax.swing.JOptionPane; 24 22 import javax.swing.JPanel; 25 23 import javax.swing.JTabbedPane; 26 import javax.swing.event.DocumentEvent;27 import javax.swing.event.DocumentListener;28 import javax.swing.text.JTextComponent;29 24 import javax.swing.text.html.HTMLEditorKit; 30 25 26 import org.openstreetmap.josm.data.oauth.IOAuthToken; 31 27 import org.openstreetmap.josm.data.oauth.OAuthParameters; 32 import org.openstreetmap.josm.data.oauth.OAuth Token;28 import org.openstreetmap.josm.data.oauth.OAuthVersion; 33 29 import org.openstreetmap.josm.gui.HelpAwareOptionPane; 34 30 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 35 31 import org.openstreetmap.josm.gui.help.HelpUtil; 36 import org.openstreetmap.josm.gui.preferences.server.UserNameValidator;37 32 import org.openstreetmap.josm.gui.util.GuiHelper; 38 import org.openstreetmap.josm.gui.widgets.DefaultTextComponentValidator;39 33 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 40 34 import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 41 import org.openstreetmap.josm.gui.widgets.JosmPasswordField;42 import org.openstreetmap.josm.gui.widgets.JosmTextField;43 import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;44 35 import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel; 45 import org.openstreetmap.josm.io.OsmApi;46 36 import org.openstreetmap.josm.io.OsmTransferException; 47 import org.openstreetmap.josm.io.auth.CredentialsAgent;48 import org.openstreetmap.josm.io.auth.CredentialsAgentException;49 import org.openstreetmap.josm.io.auth.CredentialsManager;50 37 import org.openstreetmap.josm.tools.ImageProvider; 51 38 import org.openstreetmap.josm.tools.Logging; 52 import org.openstreetmap.josm.tools.Utils;53 39 import org.xml.sax.SAXException; 54 40 55 41 /** 56 * This is a nUI which supports a JOSM user to get an OAuth Access Token in a fully42 * This is a UI which supports a JOSM user to get an OAuth Access Token in a fully 57 43 * automatic process. 58 44 * 59 45 * @since 2746 60 46 */ 61 47 public class FullyAutomaticAuthorizationUI extends AbstractAuthorizationUI { 62 63 private final JosmTextField tfUserName = new JosmTextField();64 private final JosmPasswordField tfPassword = new JosmPasswordField();65 private transient UserNameValidator valUserName;66 private transient PasswordValidator valPassword;67 48 private final AccessTokenInfoPanel pnlAccessTokenInfo = new AccessTokenInfoPanel(); 68 49 private OsmPrivilegesPanel pnlOsmPrivileges; 69 50 private JPanel pnlPropertiesPanel; … … 104 85 pnlMessage.setText("<html><body><p class=\"warning-body\">" 105 86 + tr("Please enter your OSM user name and password. The password will <strong>not</strong> be saved " 106 87 + "in clear text in the JOSM preferences and it will be submitted to the OSM server <strong>only once</strong>. " 107 + "Subsequent data upload requests don''t use your password any more.").replace All("\\. ", ".<br>")88 + "Subsequent data upload requests don''t use your password any more.").replace(". ", ".<br>") 108 89 + "</p>" 109 90 + "</body></html>"); 110 91 pnl.add(pnlMessage, gc); … … 120 101 121 102 gc.gridx = 1; 122 103 gc.weightx = 1.0; 123 pnl.add(tfUserName, gc);124 SelectAllOnFocusGainedDecorator.decorate(tfUserName);125 valUserName = new UserNameValidator(tfUserName);126 valUserName.validate();127 104 128 105 // the password input field 129 106 gc.anchor = GridBagConstraints.NORTHWEST; … … 135 112 136 113 gc.gridx = 1; 137 114 gc.weightx = 1.0; 138 pnl.add(tfPassword, gc);139 SelectAllOnFocusGainedDecorator.decorate(tfPassword);140 valPassword = new PasswordValidator(tfPassword);141 valPassword.validate();142 115 143 116 // filler - grab remaining space 144 117 gc.gridy = 4; … … 166 139 return pnl; 167 140 } 168 141 169 /**170 * Initializes the panel with values from the preferences171 * @param paramApiUrl the API URL172 */173 @Override174 public void initialize(String paramApiUrl) {175 super.initialize(paramApiUrl);176 CredentialsAgent cm = CredentialsManager.getInstance();177 try {178 PasswordAuthentication pa = cm.lookup(RequestorType.SERVER, OsmApi.getOsmApi().getHost());179 if (pa == null) {180 tfUserName.setText("");181 tfPassword.setText("");182 } else {183 tfUserName.setText(pa.getUserName() == null ? "" : pa.getUserName());184 tfPassword.setText(pa.getPassword() == null ? "" : String.valueOf(pa.getPassword()));185 }186 } catch (CredentialsAgentException e) {187 Logging.error(e);188 tfUserName.setText("");189 tfPassword.setText("");190 }191 }192 193 142 /** 194 143 * Builds the panel with the action button for starting the authorisation 195 144 * … … 199 148 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT)); 200 149 201 150 RunAuthorisationAction runAuthorisationAction = new RunAuthorisationAction(); 202 tfPassword.getDocument().addDocumentListener(runAuthorisationAction);203 tfUserName.getDocument().addDocumentListener(runAuthorisationAction);204 151 pnl.add(new JButton(runAuthorisationAction)); 205 152 return pnl; 206 153 } … … 288 235 repaint(); 289 236 } 290 237 291 protected String getOsmUserName() {292 return tfUserName.getText();293 }294 295 protected String getOsmPassword() {296 return String.valueOf(tfPassword.getPassword());297 }298 299 238 /** 300 239 * Constructs a new {@code FullyAutomaticAuthorizationUI} for the given API URL. 301 240 * @param apiUrl The OSM API URL 302 241 * @param executor the executor used for running the HTTP requests for the authorization 303 242 * @since 5422 243 * @deprecated since xxx 304 244 */ 245 @Deprecated 305 246 public FullyAutomaticAuthorizationUI(String apiUrl, Executor executor) { 306 super(apiUrl); 247 this(apiUrl, executor, OAuthVersion.OAuth10a); 248 } 249 250 /** 251 * Constructs a new {@code FullyAutomaticAuthorizationUI} for the given API URL. 252 * @param apiUrl The OSM API URL 253 * @param executor the executor used for running the HTTP requests for the authorization 254 * @param oAuthVersion The OAuth version to use for this UI 255 * @since xxx 256 */ 257 public FullyAutomaticAuthorizationUI(String apiUrl, Executor executor, OAuthVersion oAuthVersion) { 258 super(apiUrl, oAuthVersion); 307 259 this.executor = executor; 308 260 build(); 309 261 } … … 314 266 } 315 267 316 268 @Override 317 protected void setAccessToken( OAuthToken accessToken) {269 protected void setAccessToken(IOAuthToken accessToken) { 318 270 super.setAccessToken(accessToken); 319 271 pnlAccessTokenInfo.setAccessToken(accessToken); 320 272 } … … 322 274 /** 323 275 * Starts the authorisation process 324 276 */ 325 class RunAuthorisationAction extends AbstractAction implements DocumentListener{277 class RunAuthorisationAction extends AbstractAction { 326 278 RunAuthorisationAction() { 327 279 putValue(NAME, tr("Authorize now")); 328 280 new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this); 329 281 putValue(SHORT_DESCRIPTION, tr("Click to redirect you to the authorization form on the JOSM web site")); 330 updateEnabledState();331 282 } 332 283 333 284 @Override 334 285 public void actionPerformed(ActionEvent evt) { 335 286 executor.execute(new FullyAutomaticAuthorisationTask(FullyAutomaticAuthorizationUI.this)); 336 287 } 337 338 protected final void updateEnabledState() {339 setEnabled(valPassword.isValid() && valUserName.isValid());340 }341 342 @Override343 public void changedUpdate(DocumentEvent e) {344 updateEnabledState();345 }346 347 @Override348 public void insertUpdate(DocumentEvent e) {349 updateEnabledState();350 }351 352 @Override353 public void removeUpdate(DocumentEvent e) {354 updateEnabledState();355 }356 288 } 357 289 358 290 /** … … 385 317 executor.execute(new TestAccessTokenTask( 386 318 FullyAutomaticAuthorizationUI.this, 387 319 getApiUrl(), 388 (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters(),389 320 getAccessToken() 390 321 )); 391 322 } 392 323 } 393 324 394 static class PasswordValidator extends DefaultTextComponentValidator {395 PasswordValidator(JTextComponent tc) {396 super(tc, tr("Please enter your OSM password"), tr("The password cannot be empty. Please enter your OSM password"));397 }398 }399 400 325 class FullyAutomaticAuthorisationTask extends PleaseWaitRunnable { 401 326 private boolean canceled; 402 327 … … 438 363 + "a valid login URL from the OAuth Authorize Endpoint URL ''{0}''.<br><br>" 439 364 + "Please check your advanced setting and try again." 440 365 + "</html>", 441 ((OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()).getAuthoriseUrl()), 442 tr("OAuth authorization failed"), 443 JOptionPane.ERROR_MESSAGE, 444 HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed") 445 ); 446 } 447 448 protected void alertLoginFailed() { 449 final String loginUrl = ((OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()).getOsmLoginUrl(); 450 HelpAwareOptionPane.showOptionDialog( 451 FullyAutomaticAuthorizationUI.this, 452 tr("<html>" 453 + "The automatic process for retrieving an OAuth Access Token<br>" 454 + "from the OSM server failed. JOSM failed to log into {0}<br>" 455 + "for user {1}.<br><br>" 456 + "Please check username and password and try again." 457 +"</html>", 458 loginUrl, 459 Utils.escapeReservedCharactersHTML(getOsmUserName())), 366 getAdvancedPropertiesPanel().getAdvancedParameters().getAuthorizationUrl()), 460 367 tr("OAuth authorization failed"), 461 368 JOptionPane.ERROR_MESSAGE, 462 369 HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed") … … 464 371 } 465 372 466 373 protected void handleException(final OsmOAuthAuthorizationException e) { 467 Runnable r = () -> {468 if (e instanceof OsmLoginFailedException) {469 alertLoginFailed();470 } else {471 alertAuthorisationFailed();472 }473 };474 374 Logging.error(e); 475 GuiHelper.runInEDT( r);375 GuiHelper.runInEDT(this::alertAuthorisationFailed); 476 376 } 477 377 478 378 @Override 479 379 protected void realRun() throws SAXException, IOException, OsmTransferException { 480 try { 481 getProgressMonitor().setTicksCount(3); 482 OsmOAuthAuthorizationClient authClient = new OsmOAuthAuthorizationClient( 483 (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters() 484 ); 485 OAuthToken requestToken = authClient.getRequestToken( 486 getProgressMonitor().createSubTaskMonitor(1, false) 487 ); 488 getProgressMonitor().worked(1); 489 if (canceled) return; 490 authClient.authorise( 491 requestToken, 492 getOsmUserName(), 493 getOsmPassword(), 494 pnlOsmPrivileges.getPrivileges(), 495 getProgressMonitor().createSubTaskMonitor(1, false) 496 ); 497 getProgressMonitor().worked(1); 498 if (canceled) return; 499 final OAuthToken accessToken = authClient.getAccessToken( 500 getProgressMonitor().createSubTaskMonitor(1, false) 501 ); 502 getProgressMonitor().worked(1); 503 if (canceled) return; 504 GuiHelper.runInEDT(() -> { 505 prepareUIForResultDisplay(); 506 setAccessToken(accessToken); 507 }); 508 } catch (final OsmOAuthAuthorizationException e) { 509 handleException(e); 510 } 380 getProgressMonitor().setTicksCount(2); 381 OAuthAuthorizationWizard.authorize(true, token -> { 382 if (!canceled) { 383 getProgressMonitor().worked(1); 384 GuiHelper.runInEDT(() -> { 385 prepareUIForResultDisplay(); 386 setAccessToken(token.orElse(null)); 387 }); 388 } 389 }, getOAuthVersion()); 390 getProgressMonitor().worked(1); 511 391 } 512 392 } 513 393 } -
core/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java b/core/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java
a b 24 24 import javax.swing.event.DocumentListener; 25 25 import javax.swing.text.JTextComponent; 26 26 27 import org.openstreetmap.josm.data.oauth.OAuth20Exception; 28 import org.openstreetmap.josm.data.oauth.OAuth20Token; 27 29 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder; 28 30 import org.openstreetmap.josm.data.oauth.OAuthParameters; 29 import org.openstreetmap.josm.data.oauth.OAuth Token;31 import org.openstreetmap.josm.data.oauth.OAuthVersion; 30 32 import org.openstreetmap.josm.gui.widgets.DefaultTextComponentValidator; 31 33 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 32 34 import org.openstreetmap.josm.gui.widgets.JosmTextField; 33 35 import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator; 34 36 import org.openstreetmap.josm.tools.ImageProvider; 37 import org.openstreetmap.josm.tools.JosmRuntimeException; 35 38 36 39 /** 37 40 * This is an UI which supports a JOSM user to get an OAuth Access Token in a fully manual process. … … 43 46 private final JosmTextField tfAccessTokenKey = new JosmTextField(); 44 47 private transient AccessTokenKeyValidator valAccessTokenKey; 45 48 private final JosmTextField tfAccessTokenSecret = new JosmTextField(); 46 private transient AccessTokenSecretValidator valAccessTokenSecret;47 49 private final JCheckBox cbSaveToPreferences = new JCheckBox(tr("Save Access Token in preferences")); 48 50 private final HtmlPanel pnlMessage = new HtmlPanel(); 49 51 private final transient Executor executor; … … 53 55 * @param apiUrl The OSM API URL 54 56 * @param executor the executor used for running the HTTP requests for the authorization 55 57 * @since 5422 58 * @deprecated since xxx, use {@link ManualAuthorizationUI#ManualAuthorizationUI(String, Executor, OAuthVersion)} 59 * instead. 56 60 */ 61 @Deprecated 57 62 public ManualAuthorizationUI(String apiUrl, Executor executor) { 58 super(/* dont pass apiURL because setApiUrl is overridden and references a local field */); 63 this(apiUrl, executor, OAuthVersion.OAuth10a); 64 } 65 66 /** 67 * Constructs a new {@code ManualAuthorizationUI} for the given API URL. 68 * @param apiUrl The OSM API URL 69 * @param executor the executor used for running the HTTP requests for the authorization 70 * @param oAuthVersion The OAuthVersion to use for this UI 71 * @since xxx 72 */ 73 public ManualAuthorizationUI(String apiUrl, Executor executor, OAuthVersion oAuthVersion) { 74 super(null /* don't pass apiURL because setApiUrl is overridden and references a local field */, 75 oAuthVersion); 59 76 setApiUrl(apiUrl); 60 77 this.executor = executor; 61 78 build(); … … 94 111 valAccessTokenKey.validate(); 95 112 tfAccessTokenKey.getDocument().addDocumentListener(accessTokenBuilder); 96 113 97 // the access token key input field98 gc.gridy = 2;99 gc.gridx = 0;100 gc.weightx = 0.0;101 pnl.add(new JLabel(tr("Access Token Secret:")), gc);102 103 gc.gridx = 1;104 gc.weightx = 1.0;105 pnl.add(tfAccessTokenSecret, gc);106 SelectAllOnFocusGainedDecorator.decorate(tfAccessTokenSecret);107 valAccessTokenSecret = new AccessTokenSecretValidator(tfAccessTokenSecret);108 valAccessTokenSecret.validate();109 tfAccessTokenSecret.getDocument().addDocumentListener(accessTokenBuilder);110 111 114 // the checkbox for saving to preferences 112 115 gc.gridy = 3; 113 116 gc.gridx = 0; … … 184 187 } 185 188 } 186 189 187 private static class AccessTokenSecretValidator extends DefaultTextComponentValidator {188 AccessTokenSecretValidator(JTextComponent tc) {189 super(tc, tr("Please enter an Access Token Secret"),190 tr("The Access Token Secret must not be empty. Please enter an Access Token Secret"));191 }192 }193 194 190 class AccessTokenBuilder implements DocumentListener { 195 191 196 192 public void build() { 197 if (!valAccessTokenKey.isValid() || !valAccessTokenSecret.isValid()) {193 if (!valAccessTokenKey.isValid()) { 198 194 setAccessToken(null); 199 195 } else { 200 setAccessToken(new OAuthToken(tfAccessTokenKey.getText().trim(), tfAccessTokenSecret.getText().trim())); 196 try { 197 setAccessToken(new OAuth20Token(getOAuthParameters(), "{\"token_type\":\"bearer\", \"access_token\"" 198 + tfAccessTokenKey.getText().trim() + "\"}")); 199 } catch (OAuth20Exception e) { 200 throw new JosmRuntimeException(e); 201 } 201 202 } 202 203 } 203 204 … … 233 234 TestAccessTokenTask task = new TestAccessTokenTask( 234 235 ManualAuthorizationUI.this, 235 236 getApiUrl(), 236 (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters(),237 237 getAccessToken() 238 238 ); 239 239 executor.execute(task); -
core/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java b/core/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java
a b 17 17 import java.beans.PropertyChangeEvent; 18 18 import java.beans.PropertyChangeListener; 19 19 import java.lang.reflect.InvocationTargetException; 20 import java.net.UR L;20 import java.net.URI; 21 21 import java.util.Objects; 22 import java.util.Optional; 22 23 import java.util.concurrent.Executor; 23 24 import java.util.concurrent.FutureTask; 25 import java.util.function.Consumer; 24 26 25 27 import javax.swing.AbstractAction; 26 28 import javax.swing.BorderFactory; 27 29 import javax.swing.JButton; 28 30 import javax.swing.JDialog; 31 import javax.swing.JOptionPane; 29 32 import javax.swing.JPanel; 30 33 import javax.swing.JScrollPane; 31 34 import javax.swing.SwingUtilities; 32 35 import javax.swing.UIManager; 33 36 import javax.swing.text.html.HTMLEditorKit; 34 37 38 import org.openstreetmap.josm.data.oauth.IOAuthParameters; 39 import org.openstreetmap.josm.data.oauth.IOAuthToken; 40 import org.openstreetmap.josm.data.oauth.OAuth20Authorization; 35 41 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder; 36 42 import org.openstreetmap.josm.data.oauth.OAuthParameters; 37 import org.openstreetmap.josm.data.oauth.OAuthToken; 43 import org.openstreetmap.josm.data.oauth.OAuthVersion; 44 import org.openstreetmap.josm.data.oauth.osm.OsmScopes; 38 45 import org.openstreetmap.josm.gui.MainApplication; 39 46 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction; 40 47 import org.openstreetmap.josm.gui.help.HelpUtil; … … 42 49 import org.openstreetmap.josm.gui.util.WindowGeometry; 43 50 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 44 51 import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 52 import org.openstreetmap.josm.io.OsmApi; 53 import org.openstreetmap.josm.io.auth.CredentialsManager; 54 import org.openstreetmap.josm.io.remotecontrol.RemoteControl; 45 55 import org.openstreetmap.josm.spi.preferences.Config; 46 56 import org.openstreetmap.josm.tools.GBC; 47 57 import org.openstreetmap.josm.tools.ImageProvider; … … 58 68 private boolean canceled; 59 69 private final AuthorizationProcedure procedure; 60 70 private final String apiUrl; 71 private final OAuthVersion oAuthVersion; 61 72 62 73 private FullyAutomaticAuthorizationUI pnlFullyAutomaticAuthorisationUI; 63 private SemiAutomaticAuthorizationUI pnlSemiAutomaticAuthorisationUI;64 74 private ManualAuthorizationUI pnlManualAuthorisationUI; 65 75 private JScrollPane spAuthorisationProcedureUI; 66 76 private final transient Executor executor; 67 77 68 78 /** 69 * Launches the wizard, {@link OAuthAccessTokenHolder#setAccessToken( OAuthToken) sets the token}79 * Launches the wizard, {@link OAuthAccessTokenHolder#setAccessToken(String, IOAuthToken)} sets the token 70 80 * and {@link OAuthAccessTokenHolder#setSaveToPreferences(boolean) saves to preferences}. 81 * @param callback Callback to run when authorization is finished 71 82 * @throws UserCancelException if user cancels the operation 72 83 */ 73 public void showDialog() throws UserCancelException { 74 setVisible(true); 75 if (isCanceled()) { 76 throw new UserCancelException(); 84 public void showDialog(Consumer<Optional<IOAuthToken>> callback) throws UserCancelException { 85 if ((this.oAuthVersion == OAuthVersion.OAuth20 || this.oAuthVersion == OAuthVersion.OAuth21) 86 && this.procedure == AuthorizationProcedure.FULLY_AUTOMATIC) { 87 authorize(true, callback, this.oAuthVersion); 88 } else { 89 setVisible(true); 90 if (isCanceled()) { 91 throw new UserCancelException(); 92 } 77 93 } 78 94 OAuthAccessTokenHolder holder = OAuthAccessTokenHolder.getInstance(); 79 holder.setAccessToken( getAccessToken());95 holder.setAccessToken(apiUrl, getAccessToken()); 80 96 holder.setSaveToPreferences(isSaveAccessTokenToPreferences()); 81 97 } 82 98 99 /** 100 * Perform the oauth dance 101 * @param startRemoteControl {@code true} to start remote control if it is not already running 102 * @param callback The callback to use to notify that the OAuth dance succeeded 103 * @param oAuthVersion The OAuth version that the authorization dance is force 104 */ 105 static void authorize(boolean startRemoteControl, Consumer<Optional<IOAuthToken>> callback, OAuthVersion oAuthVersion) { 106 final boolean remoteControlIsRunning = Boolean.TRUE.equals(RemoteControl.PROP_REMOTECONTROL_ENABLED.get()); 107 // TODO: Ask user if they want to start remote control? 108 if (!remoteControlIsRunning && startRemoteControl) { 109 RemoteControl.start(); 110 } 111 new OAuth20Authorization().authorize(OAuthParameters.createDefault(OsmApi.getOsmApi().getServerUrl(), oAuthVersion), token -> { 112 if (!remoteControlIsRunning) { 113 RemoteControl.stop(); 114 } 115 OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().getServerUrl(), token.orElse(null)); 116 OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance()); 117 if (!token.isPresent()) { 118 GuiHelper.runInEDT(() -> JOptionPane.showMessageDialog(MainApplication.getMainPanel(), 119 tr("Authentication failed, please check browser for details."), 120 tr("OAuth Authentication Failed"), 121 JOptionPane.ERROR_MESSAGE)); 122 } 123 if (callback != null) { 124 callback.accept(token); 125 } 126 }, OsmScopes.read_gpx, OsmScopes.write_gpx, 127 OsmScopes.read_prefs, OsmScopes.write_prefs, 128 OsmScopes.write_api, OsmScopes.write_notes); 129 } 130 83 131 /** 84 132 * Builds the row with the action buttons 85 133 * … … 90 138 91 139 AcceptAccessTokenAction actAcceptAccessToken = new AcceptAccessTokenAction(); 92 140 pnlFullyAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken); 93 pnlSemiAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);94 141 pnlManualAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken); 95 142 96 143 pnl.add(new JButton(actAcceptAccessToken)); … … 153 200 spAuthorisationProcedureUI.getViewport().setView(pnlFullyAutomaticAuthorisationUI); 154 201 pnlFullyAutomaticAuthorisationUI.revalidate(); 155 202 break; 156 case SEMI_AUTOMATIC:157 spAuthorisationProcedureUI.getViewport().setView(pnlSemiAutomaticAuthorisationUI);158 pnlSemiAutomaticAuthorisationUI.revalidate();159 break;160 203 case MANUALLY: 161 204 spAuthorisationProcedureUI.getViewport().setView(pnlManualAuthorisationUI); 162 205 pnlManualAuthorisationUI.revalidate(); 163 206 break; 207 default: 208 throw new UnsupportedOperationException("Unsupported auth type: " + procedure); 164 209 } 165 210 validate(); 166 211 repaint(); … … 176 221 setTitle(tr("Get an Access Token for ''{0}''", apiUrl)); 177 222 this.setMinimumSize(new Dimension(500, 300)); 178 223 179 pnlFullyAutomaticAuthorisationUI = new FullyAutomaticAuthorizationUI(apiUrl, executor); 180 pnlSemiAutomaticAuthorisationUI = new SemiAutomaticAuthorizationUI(apiUrl, executor); 181 pnlManualAuthorisationUI = new ManualAuthorizationUI(apiUrl, executor); 224 pnlFullyAutomaticAuthorisationUI = new FullyAutomaticAuthorizationUI(apiUrl, executor, oAuthVersion); 225 pnlManualAuthorisationUI = new ManualAuthorizationUI(apiUrl, executor, oAuthVersion); 182 226 183 227 spAuthorisationProcedureUI = GuiHelper.embedInVerticalScrollPane(new JPanel()); 184 228 spAuthorisationProcedureUI.getVerticalScrollBar().addComponentListener( … … 212 256 * @param procedure the authorization procedure to use 213 257 * @param apiUrl the API URL. Must not be null. 214 258 * @param executor the executor used for running the HTTP requests for the authorization 259 * @param oAuthVersion The OAuth version this wizard is for 215 260 * @throws IllegalArgumentException if apiUrl is null 216 261 */ 217 public OAuthAuthorizationWizard(Component parent, AuthorizationProcedure procedure, String apiUrl, Executor executor) { 262 public OAuthAuthorizationWizard(Component parent, AuthorizationProcedure procedure, String apiUrl, 263 Executor executor, OAuthVersion oAuthVersion) { 218 264 super(GuiHelper.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL); 219 265 this.procedure = Objects.requireNonNull(procedure, "procedure"); 220 266 this.apiUrl = Objects.requireNonNull(apiUrl, "apiUrl"); 221 267 this.executor = executor; 268 this.oAuthVersion = oAuthVersion; 222 269 build(); 223 270 } 224 271 … … 235 282 switch(procedure) { 236 283 case FULLY_AUTOMATIC: return pnlFullyAutomaticAuthorisationUI; 237 284 case MANUALLY: return pnlManualAuthorisationUI; 238 case SEMI_AUTOMATIC: return pnlSemiAutomaticAuthorisationUI;239 285 default: return null; 240 286 } 241 287 } … … 245 291 * 246 292 * @return the access token. May be null if the wizard was canceled. 247 293 */ 248 public OAuthToken getAccessToken() {294 public IOAuthToken getAccessToken() { 249 295 return getCurrentAuthorisationUI().getAccessToken(); 250 296 } 251 297 … … 254 300 * 255 301 * @return the current OAuth parameters. 256 302 */ 257 public OAuthParameters getOAuthParameters() {258 return (OAuthParameters)getCurrentAuthorisationUI().getOAuthParameters();303 public IOAuthParameters getOAuthParameters() { 304 return getCurrentAuthorisationUI().getOAuthParameters(); 259 305 } 260 306 261 307 /** … … 275 321 */ 276 322 public void initFromPreferences() { 277 323 pnlFullyAutomaticAuthorisationUI.initialize(apiUrl); 278 pnlSemiAutomaticAuthorisationUI.initialize(apiUrl);279 324 pnlManualAuthorisationUI.initialize(apiUrl); 280 325 } 281 326 … … 308 353 * @throws InvocationTargetException if an exception is thrown while running OAuth authorization task 309 354 * @since 12803 310 355 */ 311 public static void obtainAccessToken(final UR LserverUrl) throws InvocationTargetException, InterruptedException {356 public static void obtainAccessToken(final URI serverUrl) throws InvocationTargetException, InterruptedException { 312 357 final Runnable authTask = new FutureTask<>(() -> { 313 358 // Concerning Utils.newDirectExecutor: Main worker cannot be used since this connection is already 314 359 // executed via main worker. The OAuth connections would block otherwise. 315 360 final OAuthAuthorizationWizard wizard = new OAuthAuthorizationWizard( 316 361 MainApplication.getMainFrame(), 317 362 AuthorizationProcedure.FULLY_AUTOMATIC, 318 serverUrl.toExternalForm(), Utils.newDirectExecutor()); 319 wizard.showDialog(); 363 serverUrl.toString(), Utils.newDirectExecutor(), 364 OAuthVersion.OAuth20); 365 wizard.showDialog(null); 320 366 return wizard; 321 367 }); 322 368 // exception handling differs from implementation at GuiHelper.runInEDTAndWait() … … 358 404 putValue(NAME, tr("Accept Access Token")); 359 405 new ImageProvider("ok").getResource().attachImageIcon(this); 360 406 putValue(SHORT_DESCRIPTION, tr("Close the dialog and accept the Access Token")); 361 updateEnabledState( null);407 updateEnabledState((IOAuthToken) null); 362 408 } 363 409 364 410 @Override … … 367 413 setVisible(false); 368 414 } 369 415 370 public final void updateEnabledState(OAuthToken token) { 416 /** 417 * Update the enabled state 418 * @param token The token to use 419 * @since xxx 420 */ 421 public final void updateEnabledState(IOAuthToken token) { 371 422 setEnabled(token != null); 372 423 } 373 424 … … 375 426 public void propertyChange(PropertyChangeEvent evt) { 376 427 if (!evt.getPropertyName().equals(AbstractAuthorizationUI.ACCESS_TOKEN_PROP)) 377 428 return; 378 updateEnabledState(( OAuthToken) evt.getNewValue());429 updateEnabledState((IOAuthToken) evt.getNewValue()); 379 430 } 380 431 } 381 432 -
deleted file core/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java
diff --git a/core/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java b/core/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.oauth;3 4 /**5 * OSM login failure exception.6 * @since 27467 */8 public class OsmLoginFailedException extends OsmOAuthAuthorizationException {9 10 /**11 * Constructs a new {@code OsmLoginFailedException} with the specified cause.12 * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method).13 */14 public OsmLoginFailedException(Throwable cause) {15 super(cause);16 }17 } -
deleted file core/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java
diff --git a/core/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java b/core/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.oauth;3 4 import static org.openstreetmap.josm.tools.I18n.tr;5 6 import java.io.BufferedReader;7 import java.io.IOException;8 import java.net.CookieHandler;9 import java.net.HttpURLConnection;10 import java.net.URISyntaxException;11 import java.net.URL;12 import java.nio.charset.StandardCharsets;13 import java.util.Collections;14 import java.util.HashMap;15 import java.util.Iterator;16 import java.util.List;17 import java.util.Map;18 import java.util.Map.Entry;19 import java.util.regex.Matcher;20 import java.util.regex.Pattern;21 22 import org.openstreetmap.josm.data.oauth.OAuthParameters;23 import org.openstreetmap.josm.data.oauth.OAuthToken;24 import org.openstreetmap.josm.data.oauth.OsmPrivileges;25 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;26 import org.openstreetmap.josm.gui.progress.ProgressMonitor;27 import org.openstreetmap.josm.io.OsmTransferCanceledException;28 import org.openstreetmap.josm.tools.CheckParameterUtil;29 import org.openstreetmap.josm.tools.HttpClient;30 import org.openstreetmap.josm.tools.Logging;31 import org.openstreetmap.josm.tools.Utils;32 33 import oauth.signpost.OAuth;34 import oauth.signpost.OAuthConsumer;35 import oauth.signpost.OAuthProvider;36 import oauth.signpost.exception.OAuthException;37 38 /**39 * An OAuth 1.0 authorization client.40 * @since 274641 */42 public class OsmOAuthAuthorizationClient {43 private final OAuthParameters oauthProviderParameters;44 private final OAuthConsumer consumer;45 private final OAuthProvider provider;46 private boolean canceled;47 private HttpClient connection;48 49 protected static class SessionId {50 protected String id;51 protected String token;52 protected String userName;53 }54 55 /**56 * Creates a new authorisation client with the parameters <code>parameters</code>.57 *58 * @param parameters the OAuth parameters. Must not be null.59 * @throws IllegalArgumentException if parameters is null60 */61 public OsmOAuthAuthorizationClient(OAuthParameters parameters) {62 CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");63 oauthProviderParameters = new OAuthParameters(parameters);64 consumer = oauthProviderParameters.buildConsumer();65 provider = oauthProviderParameters.buildProvider(consumer);66 }67 68 /**69 * Creates a new authorisation client with the parameters <code>parameters</code>70 * and an already known Request Token.71 *72 * @param parameters the OAuth parameters. Must not be null.73 * @param requestToken the request token. Must not be null.74 * @throws IllegalArgumentException if parameters is null75 * @throws IllegalArgumentException if requestToken is null76 */77 public OsmOAuthAuthorizationClient(OAuthParameters parameters, OAuthToken requestToken) {78 CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");79 oauthProviderParameters = new OAuthParameters(parameters);80 consumer = oauthProviderParameters.buildConsumer();81 provider = oauthProviderParameters.buildProvider(consumer);82 consumer.setTokenWithSecret(requestToken.getKey(), requestToken.getSecret());83 }84 85 /**86 * Cancels the current OAuth operation.87 */88 public void cancel() {89 canceled = true;90 synchronized (this) {91 if (connection != null) {92 connection.disconnect();93 }94 }95 }96 97 /**98 * Submits a request for a Request Token to the Request Token Endpoint Url of the OAuth Service99 * Provider and replies the request token.100 *101 * @param monitor a progress monitor. Defaults to {@link NullProgressMonitor#INSTANCE} if null102 * @return the OAuth Request Token103 * @throws OsmOAuthAuthorizationException if something goes wrong when retrieving the request token104 * @throws OsmTransferCanceledException if the user canceled the request105 */106 public OAuthToken getRequestToken(ProgressMonitor monitor) throws OsmOAuthAuthorizationException, OsmTransferCanceledException {107 if (monitor == null) {108 monitor = NullProgressMonitor.INSTANCE;109 }110 try {111 monitor.beginTask("");112 monitor.indeterminateSubTask(tr("Retrieving OAuth Request Token from ''{0}''", oauthProviderParameters.getRequestTokenUrl()));113 provider.retrieveRequestToken(consumer, "");114 return OAuthToken.createToken(consumer);115 } catch (OAuthException e) {116 if (canceled)117 throw new OsmTransferCanceledException(e);118 throw new OsmOAuthAuthorizationException(e);119 } finally {120 monitor.finishTask();121 }122 }123 124 /**125 * Submits a request for an Access Token to the Access Token Endpoint Url of the OAuth Service126 * Provider and replies the request token.127 *128 * You must have requested a Request Token using {@link #getRequestToken(ProgressMonitor)} first.129 *130 * @param monitor a progress monitor. Defaults to {@link NullProgressMonitor#INSTANCE} if null131 * @return the OAuth Access Token132 * @throws OsmOAuthAuthorizationException if something goes wrong when retrieving the request token133 * @throws OsmTransferCanceledException if the user canceled the request134 * @see #getRequestToken(ProgressMonitor)135 */136 public OAuthToken getAccessToken(ProgressMonitor monitor) throws OsmOAuthAuthorizationException, OsmTransferCanceledException {137 if (monitor == null) {138 monitor = NullProgressMonitor.INSTANCE;139 }140 try {141 monitor.beginTask("");142 monitor.indeterminateSubTask(tr("Retrieving OAuth Access Token from ''{0}''", oauthProviderParameters.getAccessTokenUrl()));143 provider.retrieveAccessToken(consumer, null);144 return OAuthToken.createToken(consumer);145 } catch (OAuthException e) {146 if (canceled)147 throw new OsmTransferCanceledException(e);148 throw new OsmOAuthAuthorizationException(e);149 } finally {150 monitor.finishTask();151 }152 }153 154 /**155 * Builds the authorise URL for a given Request Token. Users can be redirected to this URL.156 * There they can login to OSM and authorise the request.157 *158 * @param requestToken the request token159 * @return the authorise URL for this request160 */161 public String getAuthoriseUrl(OAuthToken requestToken) {162 StringBuilder sb = new StringBuilder(32);163 164 // OSM is an OAuth 1.0 provider and JOSM isn't a web app. We just add the oauth request token to165 // the authorisation request, no callback parameter.166 //167 sb.append(oauthProviderParameters.getAuthoriseUrl()).append('?'+OAuth.OAUTH_TOKEN+'=').append(requestToken.getKey());168 return sb.toString();169 }170 171 protected String extractToken() {172 try (BufferedReader r = connection.getResponse().getContentReader()) {173 String c;174 Pattern p = Pattern.compile(".*authenticity_token.*value=\"([^\"]+)\".*");175 while ((c = r.readLine()) != null) {176 Matcher m = p.matcher(c);177 if (m.find()) {178 return m.group(1);179 }180 }181 } catch (IOException e) {182 Logging.error(e);183 return null;184 }185 Logging.warn("No authenticity_token found in response!");186 return null;187 }188 189 protected SessionId extractOsmSession() throws IOException, URISyntaxException {190 // response headers might not contain the cookie, see #12584191 final List<String> setCookies = CookieHandler.getDefault()192 .get(connection.getURL().toURI(), Collections.<String, List<String>>emptyMap())193 .get("Cookie");194 if (setCookies == null) {195 Logging.warn("No 'Set-Cookie' in response header!");196 return null;197 }198 199 for (String setCookie: setCookies) {200 String[] kvPairs = setCookie.split(";", -1);201 for (String kvPair : kvPairs) {202 kvPair = kvPair.trim();203 String[] kv = kvPair.split("=", -1);204 if (kv.length != 2) {205 continue;206 }207 if ("_osm_session".equals(kv[0])) {208 // osm session cookie found209 String token = extractToken();210 if (token == null)211 return null;212 SessionId si = new SessionId();213 si.id = kv[1];214 si.token = token;215 return si;216 }217 }218 }219 Logging.warn("No suitable 'Set-Cookie' in response header found! {0}", setCookies);220 return null;221 }222 223 protected static String buildPostRequest(Map<String, String> parameters) {224 StringBuilder sb = new StringBuilder(32);225 226 for (Iterator<Entry<String, String>> it = parameters.entrySet().iterator(); it.hasNext();) {227 Entry<String, String> entry = it.next();228 String value = entry.getValue();229 value = (value == null) ? "" : value;230 sb.append(entry.getKey()).append('=').append(Utils.encodeUrl(value));231 if (it.hasNext()) {232 sb.append('&');233 }234 }235 return sb.toString();236 }237 238 /**239 * Submits a request to the OSM website for a login form. The OSM website replies a session ID in240 * a cookie.241 *242 * @return the session ID structure243 * @throws OsmOAuthAuthorizationException if something went wrong244 */245 protected SessionId fetchOsmWebsiteSessionId() throws OsmOAuthAuthorizationException {246 try {247 final URL url = new URL(oauthProviderParameters.getOsmLoginUrl() + "?cookie_test=true");248 synchronized (this) {249 connection = HttpClient.create(url).useCache(false);250 connection.connect();251 }252 SessionId sessionId = extractOsmSession();253 if (sessionId == null)254 throw new OsmOAuthAuthorizationException(255 tr("OSM website did not return a session cookie in response to ''{0}'',", url.toString()));256 return sessionId;257 } catch (IOException | URISyntaxException e) {258 throw new OsmOAuthAuthorizationException(e);259 } finally {260 synchronized (this) {261 connection = null;262 }263 }264 }265 266 /**267 * Submits a request to the OSM website for a OAuth form. The OSM website replies a session token in268 * a hidden parameter.269 * @param sessionId session id270 * @param requestToken request token271 *272 * @throws OsmOAuthAuthorizationException if something went wrong273 */274 protected void fetchOAuthToken(SessionId sessionId, OAuthToken requestToken) throws OsmOAuthAuthorizationException {275 try {276 URL url = new URL(getAuthoriseUrl(requestToken));277 synchronized (this) {278 connection = HttpClient.create(url)279 .useCache(false)280 .setHeader("Cookie", "_osm_session=" + sessionId.id + "; _osm_username=" + sessionId.userName);281 connection.connect();282 }283 sessionId.token = extractToken();284 if (sessionId.token == null)285 throw new OsmOAuthAuthorizationException(tr("OSM website did not return a session cookie in response to ''{0}'',",286 url.toString()));287 } catch (IOException e) {288 throw new OsmOAuthAuthorizationException(e);289 } finally {290 synchronized (this) {291 connection = null;292 }293 }294 }295 296 protected void authenticateOsmSession(SessionId sessionId, String userName, String password) throws OsmLoginFailedException {297 try {298 final URL url = new URL(oauthProviderParameters.getOsmLoginUrl());299 final HttpClient client = HttpClient.create(url, "POST").useCache(false);300 301 Map<String, String> parameters = new HashMap<>();302 parameters.put("username", userName);303 parameters.put("password", password);304 parameters.put("referer", "/");305 parameters.put("commit", "Login");306 parameters.put("authenticity_token", sessionId.token);307 client.setRequestBody(buildPostRequest(parameters).getBytes(StandardCharsets.UTF_8));308 309 client.setHeader("Content-Type", "application/x-www-form-urlencoded");310 client.setHeader("Cookie", "_osm_session=" + sessionId.id);311 // make sure we can catch 302 Moved Temporarily below312 client.setMaxRedirects(-1);313 314 synchronized (this) {315 connection = client;316 connection.connect();317 }318 319 // after a successful login the OSM website sends a redirect to a follow up page. Everything320 // else, including a 200 OK, is a failed login. A 200 OK is replied if the login form with321 // an error page is sent to back to the user.322 //323 int retCode = connection.getResponse().getResponseCode();324 if (retCode != HttpURLConnection.HTTP_MOVED_TEMP)325 throw new OsmOAuthAuthorizationException(tr("Failed to authenticate user ''{0}'' with password ''***'' as OAuth user",326 userName));327 } catch (OsmOAuthAuthorizationException | IOException e) {328 throw new OsmLoginFailedException(e);329 } finally {330 synchronized (this) {331 connection = null;332 }333 }334 }335 336 protected void logoutOsmSession(SessionId sessionId) throws OsmOAuthAuthorizationException {337 try {338 URL url = new URL(oauthProviderParameters.getOsmLogoutUrl());339 synchronized (this) {340 connection = HttpClient.create(url).setMaxRedirects(-1);341 connection.connect();342 }343 } catch (IOException e) {344 throw new OsmOAuthAuthorizationException(e);345 } finally {346 synchronized (this) {347 connection = null;348 }349 }350 }351 352 protected void sendAuthorisationRequest(SessionId sessionId, OAuthToken requestToken, OsmPrivileges privileges)353 throws OsmOAuthAuthorizationException {354 Map<String, String> parameters = new HashMap<>();355 fetchOAuthToken(sessionId, requestToken);356 parameters.put("oauth_token", requestToken.getKey());357 parameters.put("oauth_callback", "");358 parameters.put("authenticity_token", sessionId.token);359 parameters.put("allow_write_api", booleanParam(privileges.isAllowWriteApi()));360 parameters.put("allow_write_gpx", booleanParam(privileges.isAllowWriteGpx()));361 parameters.put("allow_read_gpx", booleanParam(privileges.isAllowReadGpx()));362 parameters.put("allow_write_prefs", booleanParam(privileges.isAllowWritePrefs()));363 parameters.put("allow_read_prefs", booleanParam(privileges.isAllowReadPrefs()));364 parameters.put("allow_write_notes", booleanParam(privileges.isAllowModifyNotes()));365 parameters.put("allow_write_diary", booleanParam(privileges.isAllowWriteDiary()));366 367 String request = buildPostRequest(parameters);368 try {369 URL url = new URL(oauthProviderParameters.getAuthoriseUrl());370 final HttpClient client = HttpClient.create(url, "POST").useCache(false);371 client.setHeader("Content-Type", "application/x-www-form-urlencoded");372 client.setHeader("Cookie", "_osm_session=" + sessionId.id + "; _osm_username=" + sessionId.userName);373 client.setMaxRedirects(-1);374 client.setRequestBody(request.getBytes(StandardCharsets.UTF_8));375 376 synchronized (this) {377 connection = client;378 connection.connect();379 }380 381 int retCode = connection.getResponse().getResponseCode();382 if (retCode != HttpURLConnection.HTTP_OK)383 throw new OsmOAuthAuthorizationException(tr("Failed to authorize OAuth request ''{0}''", requestToken.getKey()));384 } catch (IOException e) {385 throw new OsmOAuthAuthorizationException(e);386 } finally {387 synchronized (this) {388 connection = null;389 }390 }391 }392 393 private static String booleanParam(boolean param) {394 return param ? "1" : "0";395 }396 397 /**398 * Automatically authorises a request token for a set of privileges.399 *400 * @param requestToken the request token. Must not be null.401 * @param userName the OSM user name. Must not be null.402 * @param password the OSM password. Must not be null.403 * @param privileges the set of privileges. Must not be null.404 * @param monitor a progress monitor. Defaults to {@link NullProgressMonitor#INSTANCE} if null405 * @throws IllegalArgumentException if requestToken is null406 * @throws IllegalArgumentException if osmUserName is null407 * @throws IllegalArgumentException if osmPassword is null408 * @throws IllegalArgumentException if privileges is null409 * @throws OsmOAuthAuthorizationException if the authorisation fails410 * @throws OsmTransferCanceledException if the task is canceled by the user411 */412 public void authorise(OAuthToken requestToken, String userName, String password, OsmPrivileges privileges, ProgressMonitor monitor)413 throws OsmOAuthAuthorizationException, OsmTransferCanceledException {414 CheckParameterUtil.ensureParameterNotNull(requestToken, "requestToken");415 CheckParameterUtil.ensureParameterNotNull(userName, "userName");416 CheckParameterUtil.ensureParameterNotNull(password, "password");417 CheckParameterUtil.ensureParameterNotNull(privileges, "privileges");418 419 if (monitor == null) {420 monitor = NullProgressMonitor.INSTANCE;421 }422 try {423 monitor.beginTask(tr("Authorizing OAuth Request token ''{0}'' at the OSM website ...", requestToken.getKey()));424 monitor.setTicksCount(4);425 monitor.indeterminateSubTask(tr("Initializing a session at the OSM website..."));426 SessionId sessionId = fetchOsmWebsiteSessionId();427 sessionId.userName = userName;428 if (canceled)429 throw new OsmTransferCanceledException("Authorization canceled");430 monitor.worked(1);431 432 monitor.indeterminateSubTask(tr("Authenticating the session for user ''{0}''...", userName));433 authenticateOsmSession(sessionId, userName, password);434 if (canceled)435 throw new OsmTransferCanceledException("Authorization canceled");436 monitor.worked(1);437 438 monitor.indeterminateSubTask(tr("Authorizing request token ''{0}''...", requestToken.getKey()));439 sendAuthorisationRequest(sessionId, requestToken, privileges);440 if (canceled)441 throw new OsmTransferCanceledException("Authorization canceled");442 monitor.worked(1);443 444 monitor.indeterminateSubTask(tr("Logging out session ''{0}''...", sessionId));445 logoutOsmSession(sessionId);446 if (canceled)447 throw new OsmTransferCanceledException("Authorization canceled");448 monitor.worked(1);449 } catch (OsmOAuthAuthorizationException e) {450 if (canceled)451 throw new OsmTransferCanceledException(e);452 throw e;453 } finally {454 monitor.finishTask();455 }456 }457 } -
deleted file core/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java
diff --git a/core/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java b/core/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.oauth;3 4 import static org.openstreetmap.josm.tools.I18n.tr;5 6 import java.awt.Component;7 import java.io.IOException;8 9 import javax.swing.JOptionPane;10 11 import org.openstreetmap.josm.data.oauth.OAuthParameters;12 import org.openstreetmap.josm.data.oauth.OAuthToken;13 import org.openstreetmap.josm.gui.HelpAwareOptionPane;14 import org.openstreetmap.josm.gui.PleaseWaitRunnable;15 import org.openstreetmap.josm.gui.help.HelpUtil;16 import org.openstreetmap.josm.gui.util.GuiHelper;17 import org.openstreetmap.josm.io.OsmTransferCanceledException;18 import org.openstreetmap.josm.io.OsmTransferException;19 import org.openstreetmap.josm.tools.CheckParameterUtil;20 import org.openstreetmap.josm.tools.Logging;21 import org.xml.sax.SAXException;22 23 /**24 * Asynchronous task for retrieving an Access Token.25 *26 */27 public class RetrieveAccessTokenTask extends PleaseWaitRunnable {28 29 private boolean canceled;30 private OAuthToken accessToken;31 private final OAuthParameters parameters;32 private OsmOAuthAuthorizationClient client;33 private final OAuthToken requestToken;34 private final Component parent;35 36 /**37 * Creates the task38 *39 * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog40 * is displayed41 * @param parameters the OAuth parameters. Must not be null.42 * @param requestToken the request token for which an Access Token is retrieved. Must not be null.43 * @throws IllegalArgumentException if parameters is null.44 * @throws IllegalArgumentException if requestToken is null.45 */46 public RetrieveAccessTokenTask(Component parent, OAuthParameters parameters, OAuthToken requestToken) {47 super(parent, tr("Retrieving OAuth Access Token..."), false /* don't ignore exceptions */);48 CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");49 CheckParameterUtil.ensureParameterNotNull(requestToken, "requestToken");50 this.parameters = parameters;51 this.requestToken = requestToken;52 this.parent = parent;53 }54 55 @Override56 protected void cancel() {57 canceled = true;58 synchronized (this) {59 if (client != null) {60 client.cancel();61 }62 }63 }64 65 @Override66 protected void finish() { /* not used in this task */}67 68 protected void alertRetrievingAccessTokenFailed() {69 HelpAwareOptionPane.showOptionDialog(70 parent,71 tr(72 "<html>Retrieving an OAuth Access Token from ''{0}'' failed.</html>",73 parameters.getAccessTokenUrl()74 ),75 tr("Request Failed"),76 JOptionPane.ERROR_MESSAGE,77 HelpUtil.ht("/OAuth#NotAuthorizedException")78 );79 }80 81 @Override82 protected void realRun() throws SAXException, IOException, OsmTransferException {83 try {84 synchronized (this) {85 client = new OsmOAuthAuthorizationClient(parameters, requestToken);86 }87 accessToken = client.getAccessToken(getProgressMonitor().createSubTaskMonitor(0, false));88 } catch (OsmTransferCanceledException e) {89 Logging.trace(e);90 } catch (final OsmOAuthAuthorizationException e) {91 Logging.error(e);92 GuiHelper.runInEDT(this::alertRetrievingAccessTokenFailed);93 accessToken = null;94 } finally {95 synchronized (this) {96 client = null;97 }98 }99 }100 101 /**102 * Replies true if the task was canceled.103 *104 * @return {@code true} if user aborted operation105 */106 public boolean isCanceled() {107 return canceled;108 }109 110 /**111 * Replies the retrieved Access Token. null, if something went wrong.112 *113 * @return the retrieved Access Token114 */115 public OAuthToken getAccessToken() {116 return accessToken;117 }118 } -
deleted file core/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java
diff --git a/core/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java b/core/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.oauth;3 4 import static org.openstreetmap.josm.tools.I18n.tr;5 6 import java.awt.Component;7 import java.io.IOException;8 9 import javax.swing.JOptionPane;10 11 import org.openstreetmap.josm.data.oauth.OAuthParameters;12 import org.openstreetmap.josm.data.oauth.OAuthToken;13 import org.openstreetmap.josm.gui.HelpAwareOptionPane;14 import org.openstreetmap.josm.gui.PleaseWaitRunnable;15 import org.openstreetmap.josm.gui.help.HelpUtil;16 import org.openstreetmap.josm.gui.util.GuiHelper;17 import org.openstreetmap.josm.io.OsmTransferCanceledException;18 import org.openstreetmap.josm.io.OsmTransferException;19 import org.openstreetmap.josm.tools.CheckParameterUtil;20 import org.openstreetmap.josm.tools.Logging;21 import org.xml.sax.SAXException;22 23 /**24 * Asynchronous task for retrieving a request token25 */26 public class RetrieveRequestTokenTask extends PleaseWaitRunnable {27 28 private boolean canceled;29 private OAuthToken requestToken;30 private final OAuthParameters parameters;31 private OsmOAuthAuthorizationClient client;32 private final Component parent;33 34 /**35 * Creates the task36 *37 * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog38 * is displayed39 * @param parameters the OAuth parameters. Must not be null.40 * @throws IllegalArgumentException if parameters is null.41 */42 public RetrieveRequestTokenTask(Component parent, OAuthParameters parameters) {43 super(parent, tr("Retrieving OAuth Request Token..."), false /* don't ignore exceptions */);44 CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");45 this.parameters = parameters;46 this.parent = parent;47 }48 49 @Override50 protected void cancel() {51 canceled = true;52 synchronized (this) {53 if (client != null) {54 client.cancel();55 }56 }57 }58 59 @Override60 protected void finish() { /* not used in this task */}61 62 protected void alertRetrievingRequestTokenFailed() {63 HelpAwareOptionPane.showOptionDialog(64 parent,65 tr(66 "<html>Retrieving an OAuth Request Token from ''{0}'' failed.</html>",67 parameters.getRequestTokenUrl()68 ),69 tr("Request Failed"),70 JOptionPane.ERROR_MESSAGE,71 HelpUtil.ht("/OAuth#NotAuthorizedException")72 );73 }74 75 @Override76 protected void realRun() throws SAXException, IOException, OsmTransferException {77 try {78 synchronized (this) {79 client = new OsmOAuthAuthorizationClient(parameters);80 }81 requestToken = client.getRequestToken(getProgressMonitor().createSubTaskMonitor(0, false));82 } catch (OsmTransferCanceledException e) {83 Logging.trace(e);84 } catch (final OsmOAuthAuthorizationException e) {85 Logging.error(e);86 GuiHelper.runInEDT(this::alertRetrievingRequestTokenFailed);87 requestToken = null;88 } finally {89 synchronized (this) {90 client = null;91 }92 }93 }94 95 /**96 * Replies true if the task was canceled97 *98 * @return true if the task was canceled99 */100 public boolean isCanceled() {101 return canceled;102 }103 104 /**105 * Replies the request token. null, if something went wrong.106 *107 * @return the request token108 */109 public OAuthToken getRequestToken() {110 return requestToken;111 }112 } -
deleted file core/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java
diff --git a/core/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java b/core/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.oauth;3 4 import static org.openstreetmap.josm.tools.I18n.tr;5 6 import java.awt.BorderLayout;7 import java.awt.Color;8 import java.awt.FlowLayout;9 import java.awt.Font;10 import java.awt.GridBagConstraints;11 import java.awt.GridBagLayout;12 import java.awt.Insets;13 import java.awt.event.ActionEvent;14 import java.awt.event.ItemEvent;15 import java.util.concurrent.Executor;16 17 import javax.swing.AbstractAction;18 import javax.swing.BorderFactory;19 import javax.swing.JButton;20 import javax.swing.JCheckBox;21 import javax.swing.JLabel;22 import javax.swing.JPanel;23 24 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;25 import org.openstreetmap.josm.data.oauth.OAuthParameters;26 import org.openstreetmap.josm.data.oauth.OAuthToken;27 import org.openstreetmap.josm.gui.util.GuiHelper;28 import org.openstreetmap.josm.gui.widgets.HtmlPanel;29 import org.openstreetmap.josm.gui.widgets.JMultilineLabel;30 import org.openstreetmap.josm.gui.widgets.JosmTextField;31 import org.openstreetmap.josm.tools.ImageProvider;32 import org.openstreetmap.josm.tools.OpenBrowser;33 34 /**35 * This is the UI for running a semi-automatic authorisation procedure.36 *37 * In contrast to the fully-automatic procedure the user is dispatched to an38 * external browser for login and authorisation.39 *40 * @since 274641 */42 public class SemiAutomaticAuthorizationUI extends AbstractAuthorizationUI {43 private final AccessTokenInfoPanel pnlAccessTokenInfo = new AccessTokenInfoPanel();44 private transient OAuthToken requestToken;45 46 private RetrieveRequestTokenPanel pnlRetrieveRequestToken;47 private RetrieveAccessTokenPanel pnlRetrieveAccessToken;48 private ShowAccessTokenPanel pnlShowAccessToken;49 private final transient Executor executor;50 51 /**52 * build the UI53 */54 protected final void build() {55 setLayout(new BorderLayout());56 setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));57 pnlRetrieveRequestToken = new RetrieveRequestTokenPanel();58 pnlRetrieveAccessToken = new RetrieveAccessTokenPanel();59 pnlShowAccessToken = new ShowAccessTokenPanel();60 add(pnlRetrieveRequestToken, BorderLayout.CENTER);61 }62 63 /**64 * Constructs a new {@code SemiAutomaticAuthorizationUI} for the given API URL.65 * @param apiUrl The OSM API URL66 * @param executor the executor used for running the HTTP requests for the authorization67 * @since 542268 */69 public SemiAutomaticAuthorizationUI(String apiUrl, Executor executor) {70 super(apiUrl);71 this.executor = executor;72 build();73 }74 75 @Override76 public boolean isSaveAccessTokenToPreferences() {77 return pnlAccessTokenInfo.isSaveToPreferences();78 }79 80 protected void transitionToRetrieveAccessToken() {81 OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(82 (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()83 );84 String authoriseUrl = client.getAuthoriseUrl(requestToken);85 OpenBrowser.displayUrl(authoriseUrl);86 87 removeAll();88 pnlRetrieveAccessToken.setAuthoriseUrl(authoriseUrl);89 add(pnlRetrieveAccessToken, BorderLayout.CENTER);90 pnlRetrieveAccessToken.invalidate();91 validate();92 repaint();93 }94 95 protected void transitionToRetrieveRequestToken() {96 requestToken = null;97 setAccessToken(null);98 removeAll();99 add(pnlRetrieveRequestToken, BorderLayout.CENTER);100 pnlRetrieveRequestToken.invalidate();101 validate();102 repaint();103 }104 105 protected void transitionToShowAccessToken() {106 removeAll();107 add(pnlShowAccessToken, BorderLayout.CENTER);108 pnlShowAccessToken.invalidate();109 validate();110 repaint();111 pnlShowAccessToken.setAccessToken(getAccessToken());112 }113 114 static class StepLabel extends JLabel {115 StepLabel(String text) {116 super(text);117 setFont(getFont().deriveFont(16f));118 }119 }120 121 /**122 * This is the panel displayed in the first step of the semi-automatic authorisation process.123 */124 private class RetrieveRequestTokenPanel extends JPanel {125 126 /**127 * Constructs a new {@code RetrieveRequestTokenPanel}.128 */129 RetrieveRequestTokenPanel() {130 build();131 }132 133 protected JPanel buildAdvancedParametersPanel() {134 JPanel pnl = new JPanel(new GridBagLayout());135 GridBagConstraints gc = new GridBagConstraints();136 137 gc.anchor = GridBagConstraints.NORTHWEST;138 gc.fill = GridBagConstraints.HORIZONTAL;139 gc.weightx = 0.0;140 gc.insets = new Insets(0, 0, 0, 3);141 JCheckBox cbShowAdvancedParameters = new JCheckBox();142 pnl.add(cbShowAdvancedParameters, gc);143 cbShowAdvancedParameters.setSelected(false);144 cbShowAdvancedParameters.addItemListener(145 evt -> getAdvancedPropertiesPanel().setVisible(evt.getStateChange() == ItemEvent.SELECTED)146 );147 148 gc.gridx = 1;149 gc.weightx = 1.0;150 JMultilineLabel lbl = new JMultilineLabel(tr("Display Advanced OAuth Parameters"));151 lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));152 pnl.add(lbl, gc);153 154 gc.gridy = 1;155 gc.gridx = 1;156 gc.insets = new Insets(3, 0, 3, 0);157 gc.fill = GridBagConstraints.BOTH;158 gc.weightx = 1.0;159 gc.weighty = 1.0;160 pnl.add(getAdvancedPropertiesPanel(), gc);161 getAdvancedPropertiesPanel().setBorder(162 BorderFactory.createCompoundBorder(163 BorderFactory.createLineBorder(Color.GRAY, 1),164 BorderFactory.createEmptyBorder(3, 3, 3, 3)165 )166 );167 getAdvancedPropertiesPanel().setVisible(false);168 return pnl;169 }170 171 protected JPanel buildCommandPanel() {172 JPanel pnl = new JPanel(new GridBagLayout());173 GridBagConstraints gc = new GridBagConstraints();174 175 gc.anchor = GridBagConstraints.NORTHWEST;176 gc.fill = GridBagConstraints.BOTH;177 gc.weightx = 1.0;178 gc.weighty = 1.0;179 gc.insets = new Insets(0, 0, 0, 3);180 181 182 HtmlPanel h = new HtmlPanel();183 h.setText(tr("<html>"184 + "Please click on <strong>{0}</strong> to retrieve an OAuth Request Token from "185 + "''{1}''.</html>",186 tr("Retrieve Request Token"),187 ((OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()).getRequestTokenUrl()188 ));189 pnl.add(h, gc);190 191 JPanel pnl1 = new JPanel(new FlowLayout(FlowLayout.LEFT));192 pnl1.add(new JButton(new RetrieveRequestTokenAction()));193 gc.fill = GridBagConstraints.HORIZONTAL;194 gc.weightx = 1.0;195 gc.gridy = 1;196 pnl.add(pnl1, gc);197 return pnl;198 199 }200 201 protected final void build() {202 setLayout(new BorderLayout(0, 5));203 add(new StepLabel(tr("<html>Step 1/3: Retrieve an OAuth Request Token</html>")), BorderLayout.NORTH);204 add(buildAdvancedParametersPanel(), BorderLayout.CENTER);205 add(buildCommandPanel(), BorderLayout.SOUTH);206 }207 }208 209 /**210 * This is the panel displayed in the second step of the semi-automatic authorization process.211 */212 private class RetrieveAccessTokenPanel extends JPanel {213 214 private final JosmTextField tfAuthoriseUrl = new JosmTextField(null, null, 0, false);215 216 /**217 * Constructs a new {@code RetrieveAccessTokenPanel}.218 */219 RetrieveAccessTokenPanel() {220 build();221 }222 223 protected JPanel buildTitlePanel() {224 JPanel pnl = new JPanel(new BorderLayout());225 pnl.add(new StepLabel(tr("<html>Step 2/3: Authorize and retrieve an Access Token</html>")), BorderLayout.CENTER);226 return pnl;227 }228 229 protected JPanel buildContentPanel() {230 JPanel pnl = new JPanel(new GridBagLayout());231 GridBagConstraints gc = new GridBagConstraints();232 233 gc.anchor = GridBagConstraints.NORTHWEST;234 gc.fill = GridBagConstraints.HORIZONTAL;235 gc.weightx = 1.0;236 gc.gridwidth = 2;237 HtmlPanel html = new HtmlPanel();238 html.setText(tr("<html>"239 + "JOSM successfully retrieved a Request Token. "240 + "JOSM is now launching an authorization page in an external browser. "241 + "Please login with your OSM username and password and follow the instructions "242 + "to authorize the Request Token. Then switch back to this dialog and click on "243 + "<strong>{0}</strong><br><br>"244 + "If launching the external browser fails you can copy the following authorize URL "245 + "and paste it into the address field of your browser.</html>",246 tr("Request Access Token")247 ));248 pnl.add(html, gc);249 250 gc.gridx = 0;251 gc.gridy = 1;252 gc.weightx = 0.0;253 gc.gridwidth = 1;254 pnl.add(new JLabel(tr("Authorize URL:")), gc);255 256 gc.gridx = 1;257 gc.weightx = 1.0;258 pnl.add(tfAuthoriseUrl, gc);259 tfAuthoriseUrl.setEditable(false);260 261 return pnl;262 }263 264 protected JPanel buildActionPanel() {265 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));266 pnl.add(new JButton(new BackAction()));267 pnl.add(new JButton(new RetrieveAccessTokenAction()));268 return pnl;269 }270 271 protected final void build() {272 setLayout(new BorderLayout());273 add(buildTitlePanel(), BorderLayout.NORTH);274 add(buildContentPanel(), BorderLayout.CENTER);275 add(buildActionPanel(), BorderLayout.SOUTH);276 }277 278 public void setAuthoriseUrl(String url) {279 tfAuthoriseUrl.setText(url);280 }281 282 /**283 * Action to go back to step 1 in the process284 */285 class BackAction extends AbstractAction {286 BackAction() {287 putValue(NAME, tr("Back"));288 putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));289 new ImageProvider("dialogs", "previous").getResource().attachImageIcon(this);290 }291 292 @Override293 public void actionPerformed(ActionEvent arg0) {294 transitionToRetrieveRequestToken();295 }296 }297 }298 299 /**300 * Displays the retrieved Access Token in step 3.301 */302 class ShowAccessTokenPanel extends JPanel {303 304 /**305 * Constructs a new {@code ShowAccessTokenPanel}.306 */307 ShowAccessTokenPanel() {308 build();309 }310 311 protected JPanel buildTitlePanel() {312 JPanel pnl = new JPanel(new BorderLayout());313 pnl.add(new StepLabel(tr("<html>Step 3/3: Successfully retrieved an Access Token</html>")), BorderLayout.CENTER);314 return pnl;315 }316 317 protected JPanel buildContentPanel() {318 JPanel pnl = new JPanel(new GridBagLayout());319 GridBagConstraints gc = new GridBagConstraints();320 321 gc.anchor = GridBagConstraints.NORTHWEST;322 gc.fill = GridBagConstraints.HORIZONTAL;323 gc.weightx = 1.0;324 HtmlPanel html = new HtmlPanel();325 html.setText(tr("<html>"326 + "JOSM has successfully retrieved an Access Token. "327 + "You can now accept this token. JOSM will use it in the future for authentication "328 + "and authorization to the OSM server.<br><br>"329 + "The access token is: </html>"330 ));331 pnl.add(html, gc);332 333 gc.gridx = 0;334 gc.gridy = 1;335 gc.weightx = 1.0;336 gc.gridwidth = 1;337 pnl.add(pnlAccessTokenInfo, gc);338 pnlAccessTokenInfo.setSaveToPreferences(339 OAuthAccessTokenHolder.getInstance().isSaveToPreferences()340 );341 return pnl;342 }343 344 protected JPanel buildActionPanel() {345 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));346 pnl.add(new JButton(new RestartAction()));347 pnl.add(new JButton(new TestAccessTokenAction()));348 return pnl;349 }350 351 protected final void build() {352 setLayout(new BorderLayout());353 add(buildTitlePanel(), BorderLayout.NORTH);354 add(buildContentPanel(), BorderLayout.CENTER);355 add(buildActionPanel(), BorderLayout.SOUTH);356 }357 358 /**359 * Action to go back to step 1 in the process360 */361 class RestartAction extends AbstractAction {362 RestartAction() {363 putValue(NAME, tr("Restart"));364 putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));365 new ImageProvider("dialogs", "previous").getResource().attachImageIcon(this);366 }367 368 @Override369 public void actionPerformed(ActionEvent arg0) {370 transitionToRetrieveRequestToken();371 }372 }373 374 public void setAccessToken(OAuthToken accessToken) {375 pnlAccessTokenInfo.setAccessToken(accessToken);376 }377 }378 379 /**380 * Action for retrieving a request token381 */382 class RetrieveRequestTokenAction extends AbstractAction {383 384 RetrieveRequestTokenAction() {385 putValue(NAME, tr("Retrieve Request Token"));386 new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);387 putValue(SHORT_DESCRIPTION, tr("Click to retrieve a Request Token"));388 }389 390 @Override391 public void actionPerformed(ActionEvent evt) {392 final RetrieveRequestTokenTask task = new RetrieveRequestTokenTask(393 SemiAutomaticAuthorizationUI.this,394 (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()395 );396 executor.execute(task);397 Runnable r = () -> {398 if (task.isCanceled()) return;399 if (task.getRequestToken() == null) return;400 requestToken = task.getRequestToken();401 GuiHelper.runInEDT(SemiAutomaticAuthorizationUI.this::transitionToRetrieveAccessToken);402 };403 executor.execute(r);404 }405 }406 407 /**408 * Action for retrieving an Access Token409 */410 class RetrieveAccessTokenAction extends AbstractAction {411 412 RetrieveAccessTokenAction() {413 putValue(NAME, tr("Retrieve Access Token"));414 new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);415 putValue(SHORT_DESCRIPTION, tr("Click to retrieve an Access Token"));416 }417 418 @Override419 public void actionPerformed(ActionEvent evt) {420 final RetrieveAccessTokenTask task = new RetrieveAccessTokenTask(421 SemiAutomaticAuthorizationUI.this,422 (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters(),423 requestToken424 );425 executor.execute(task);426 Runnable r = () -> {427 if (task.isCanceled()) return;428 if (task.getAccessToken() == null) return;429 GuiHelper.runInEDT(() -> {430 setAccessToken(task.getAccessToken());431 transitionToShowAccessToken();432 });433 };434 executor.execute(r);435 }436 }437 438 /**439 * Action for testing an Access Token440 */441 class TestAccessTokenAction extends AbstractAction {442 443 TestAccessTokenAction() {444 putValue(NAME, tr("Test Access Token"));445 new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);446 putValue(SHORT_DESCRIPTION, tr("Click to test the Access Token"));447 }448 449 @Override450 public void actionPerformed(ActionEvent evt) {451 TestAccessTokenTask task = new TestAccessTokenTask(452 SemiAutomaticAuthorizationUI.this,453 getApiUrl(),454 (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters(),455 getAccessToken()456 );457 executor.execute(task);458 }459 }460 } -
core/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java b/core/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java
a b 14 14 import org.openstreetmap.josm.data.oauth.IOAuthParameters; 15 15 import org.openstreetmap.josm.data.oauth.IOAuthToken; 16 16 import org.openstreetmap.josm.data.oauth.OAuth20Token; 17 import org.openstreetmap.josm.data.oauth.OAuthParameters; 18 import org.openstreetmap.josm.data.oauth.OAuthToken; 17 import org.openstreetmap.josm.data.oauth.OAuthException; 19 18 import org.openstreetmap.josm.data.osm.UserInfo; 20 19 import org.openstreetmap.josm.gui.HelpAwareOptionPane; 21 20 import org.openstreetmap.josm.gui.PleaseWaitRunnable; … … 33 32 import org.w3c.dom.Document; 34 33 import org.xml.sax.SAXException; 35 34 36 import oauth.signpost.OAuthConsumer;37 import oauth.signpost.exception.OAuthException;38 39 35 /** 40 36 * Checks whether an OSM API server can be accessed with a specific Access Token. 41 * 37 * <p> 42 38 * It retrieves the user details for the user which is authorized to access the server with 43 39 * this token. 44 40 * 45 41 */ 46 42 public class TestAccessTokenTask extends PleaseWaitRunnable { 47 private final OAuthToken tokenOAuth1;48 43 private final IOAuthToken tokenOAuth2; 49 private final IOAuthParameters oauthParameters;50 44 private boolean canceled; 51 45 private final Component parent; 52 46 private final String apiUrl; … … 57 51 * 58 52 * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog is displayed 59 53 * @param apiUrl the API URL. Must not be null. 60 * @param parameters the OAuth parameters. Must not be null.61 * @param accessToken the Access Token. Must not be null.62 */63 public TestAccessTokenTask(Component parent, String apiUrl, OAuthParameters parameters, OAuthToken accessToken) {64 super(parent, tr("Testing OAuth Access Token"), false /* don't ignore exceptions */);65 CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");66 CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");67 CheckParameterUtil.ensureParameterNotNull(accessToken, "accessToken");68 this.tokenOAuth1 = accessToken;69 this.tokenOAuth2 = null;70 this.oauthParameters = parameters;71 this.parent = parent;72 this.apiUrl = apiUrl;73 }74 75 /**76 * Create the task77 *78 * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog is displayed79 * @param apiUrl the API URL. Must not be null.80 * @param parameters the OAuth parameters. Must not be null.81 54 * @param accessToken the Access Token. Must not be null. 82 55 * @since xxx 83 56 */ 84 public TestAccessTokenTask(Component parent, String apiUrl, IOAuth Parameters parameters, IOAuthToken accessToken) {57 public TestAccessTokenTask(Component parent, String apiUrl, IOAuthToken accessToken) { 85 58 super(parent, tr("Testing OAuth Access Token"), false /* don't ignore exceptions */); 86 59 CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl"); 87 CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");88 60 CheckParameterUtil.ensureParameterNotNull(accessToken, "accessToken"); 89 this.tokenOAuth1 = null;90 61 this.tokenOAuth2 = accessToken; 91 this.oauthParameters = parameters;92 62 this.parent = parent; 93 63 this.apiUrl = apiUrl; 94 64 } … … 109 79 } 110 80 111 81 protected void sign(HttpClient con) throws OAuthException { 112 if (oauthParameters instanceof OAuthParameters) { 113 OAuthConsumer consumer = ((OAuthParameters) oauthParameters).buildConsumer(); 114 consumer.setTokenWithSecret(tokenOAuth1.getKey(), tokenOAuth1.getSecret()); 115 consumer.sign(con); 116 } else { 117 try { 118 this.tokenOAuth2.sign(con); 119 } catch (org.openstreetmap.josm.data.oauth.OAuthException e) { 120 // Adapt our OAuthException to the SignPost OAuth exception 121 throw new OAuthException(e) {}; 122 } 123 } 82 this.tokenOAuth2.sign(con); 124 83 } 125 84 126 85 protected String normalizeApiUrl(String url) { … … 314 273 } 315 274 316 275 private String getAuthKey() { 317 if (this.tokenOAuth1 != null) {318 return this.tokenOAuth1.getKey();319 }320 276 if (this.tokenOAuth2 instanceof OAuth20Token) { 321 277 return ((OAuth20Token) this.tokenOAuth2).getBearerToken(); 322 278 } 323 throw new IllegalArgumentException("Only OAuth 1 and OAuth2 tokens are understood: " + this.tokenOAuth2);279 throw new IllegalArgumentException("Only OAuth2 tokens are understood: " + this.tokenOAuth2); 324 280 } 325 281 } -
core/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java b/core/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java
a b 18 18 import javax.swing.JRadioButton; 19 19 20 20 import org.openstreetmap.josm.data.UserIdentityManager; 21 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;22 21 import org.openstreetmap.josm.data.oauth.OAuthVersion; 23 22 import org.openstreetmap.josm.gui.help.HelpUtil; 24 23 import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel; 25 24 import org.openstreetmap.josm.io.OsmApi; 26 import org.openstreetmap.josm.io.auth.CredentialsManager;27 25 import org.openstreetmap.josm.spi.preferences.Config; 28 26 import org.openstreetmap.josm.tools.GBC; 29 27 import org.openstreetmap.josm.tools.Logging; … … 33 31 * @since 2745 34 32 */ 35 33 public class AuthenticationPreferencesPanel extends VerticallyScrollablePanel implements PropertyChangeListener { 36 37 /** indicates whether we use basic authentication */38 private final JRadioButton rbBasicAuthentication = new JRadioButton();39 /** indicates whether we use OAuth 1.0a as authentication scheme */40 private final JRadioButton rbOAuth = new JRadioButton();41 34 /** indicates whether we use OAuth 2.0 as authentication scheme */ 42 35 private final JRadioButton rbOAuth20 = new JRadioButton(); 43 36 /** the panel which contains the authentication parameters for the respective authentication scheme */ 44 37 private final JPanel pnlAuthenticationParameters = new JPanel(new BorderLayout()); 45 /** the panel for the basic authentication parameters */46 private BasicAuthenticationPreferencesPanel pnlBasicAuthPreferences;47 /** the panel for the OAuth 1.0a authentication parameters */48 private OAuthAuthenticationPreferencesPanel pnlOAuthPreferences;49 38 /** the panel for the OAuth 2.0 authentication parameters */ 50 39 private OAuthAuthenticationPreferencesPanel pnlOAuth20Preferences; 51 40 … … 67 56 AuthenticationMethodChangeListener authChangeListener = new AuthenticationMethodChangeListener(); 68 57 69 58 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEADING)); 70 // -- radio button for basic authentication71 buttonPanel.add(rbBasicAuthentication);72 rbBasicAuthentication.setText(tr("Use Basic Authentication"));73 rbBasicAuthentication.setToolTipText(tr("Select to use HTTP basic authentication with your OSM username and password"));74 rbBasicAuthentication.addItemListener(authChangeListener);75 76 //-- radio button for OAuth 1.0a77 buttonPanel.add(rbOAuth);78 rbOAuth.setText(tr("Use OAuth {0}", "1.0a"));79 rbOAuth.setToolTipText(tr("Select to use OAuth {0} as authentication mechanism", "1.0a"));80 rbOAuth.addItemListener(authChangeListener);81 82 59 //-- radio button for OAuth 2.0 83 60 buttonPanel.add(rbOAuth20); 84 61 rbOAuth20.setText(tr("Use OAuth {0}", "2.0")); … … 88 65 add(buttonPanel, GBC.eol()); 89 66 //-- radio button for OAuth 90 67 ButtonGroup bg = new ButtonGroup(); 91 bg.add(rbBasicAuthentication);92 bg.add(rbOAuth);93 68 bg.add(rbOAuth20); 94 69 95 70 //-- add the panel which will hold the authentication parameters … … 104 79 gc.weighty = 1.0; 105 80 add(pnlAuthenticationParameters, gc); 106 81 107 //-- the two panels for authentication parameters 108 pnlBasicAuthPreferences = new BasicAuthenticationPreferencesPanel(); 109 pnlOAuthPreferences = new OAuthAuthenticationPreferencesPanel(OAuthVersion.OAuth10a); 82 //-- the panels for authentication parameters 110 83 pnlOAuth20Preferences = new OAuthAuthenticationPreferencesPanel(OAuthVersion.OAuth20); 111 84 112 rb BasicAuthentication.setSelected(true);113 pnlAuthenticationParameters.add(pnl BasicAuthPreferences, BorderLayout.CENTER);85 rbOAuth20.setSelected(true); 86 pnlAuthenticationParameters.add(pnlOAuth20Preferences, BorderLayout.CENTER); 114 87 } 115 88 116 89 /** … … 118 91 */ 119 92 public final void initFromPreferences() { 120 93 final String authMethod = OsmApi.getAuthMethod(); 121 switch (authMethod) { 122 case "basic": 123 rbBasicAuthentication.setSelected(true); 124 break; 125 case "oauth": 126 rbOAuth.setSelected(true); 127 break; 128 case "oauth20": 129 rbOAuth20.setSelected(true); 130 break; 131 default: 132 Logging.warn(tr("Unsupported value in preference ''{0}'', got ''{1}''. Using authentication method ''Basic Authentication''.", 133 "osm-server.auth-method", authMethod)); 134 rbBasicAuthentication.setSelected(true); 94 if ("oauth20".equals(authMethod)) { 95 rbOAuth20.setSelected(true); 96 } else { 97 Logging.warn( 98 tr("Unsupported value in preference ''{0}'', got ''{1}''. Using authentication method ''OAuth 2.0 Authentication''.", 99 "osm-server.auth-method", authMethod)); 100 rbOAuth20.setSelected(true); 135 101 } 136 pnlBasicAuthPreferences.initFromPreferences();137 pnlOAuthPreferences.initFromPreferences();138 102 pnlOAuth20Preferences.initFromPreferences(); 139 103 } 140 104 … … 144 108 public final void saveToPreferences() { 145 109 // save the authentication method 146 110 String authMethod; 147 if (rbBasicAuthentication.isSelected()) { 148 authMethod = "basic"; 149 } else if (rbOAuth.isSelected()) { 150 authMethod = "oauth"; 151 } else if (rbOAuth20.isSelected()) { 111 if (rbOAuth20.isSelected()) { 152 112 authMethod = "oauth20"; 153 113 } else { 154 114 throw new IllegalStateException("One of OAuth 2.0, OAuth 1.0a, or Basic authentication must be checked"); 155 115 } 156 116 final boolean initUser = Config.getPref().put("osm-server.auth-method", authMethod); 157 if ("basic".equals(authMethod)) { 158 // save username and password and clear the OAuth token 159 pnlBasicAuthPreferences.saveToPreferences(); 160 OAuthAccessTokenHolder.getInstance().clear(); 161 OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance()); 162 } else if ("oauth".equals(authMethod)) { 163 // clear the password in the preferences 164 pnlBasicAuthPreferences.clearPassword(); 165 pnlBasicAuthPreferences.saveToPreferences(); 166 pnlOAuthPreferences.saveToPreferences(); 167 } else { // oauth20 168 // clear the password in the preferences 169 pnlBasicAuthPreferences.clearPassword(); 170 pnlBasicAuthPreferences.saveToPreferences(); 171 pnlOAuth20Preferences.saveToPreferences(); 172 } 117 // oauth20 118 pnlOAuth20Preferences.saveToPreferences(); 173 119 if (initUser) { 174 if ( "basic".equals(authMethod)) {175 UserIdentityManager.getInstance().initFrom Preferences();120 if (OsmApi.isUsingOAuthAndOAuthSetUp(OsmApi.getOsmApi())) { 121 UserIdentityManager.getInstance().initFromOAuth(); 176 122 } else { 177 UserIdentityManager.getInstance(). initFromOAuth();123 UserIdentityManager.getInstance().setAnonymous(); 178 124 } 179 125 } 180 126 } … … 186 132 @Override 187 133 public void itemStateChanged(ItemEvent e) { 188 134 pnlAuthenticationParameters.removeAll(); 189 if (rbBasicAuthentication.isSelected()) { 190 pnlAuthenticationParameters.add(pnlBasicAuthPreferences, BorderLayout.CENTER); 191 pnlBasicAuthPreferences.revalidate(); 192 } else if (rbOAuth.isSelected()) { 193 pnlAuthenticationParameters.add(pnlOAuthPreferences, BorderLayout.CENTER); 194 pnlOAuthPreferences.saveToPreferences(); 195 pnlOAuthPreferences.initFromPreferences(); 196 pnlOAuthPreferences.revalidate(); 197 } else if (rbOAuth20.isSelected()) { 135 if (rbOAuth20.isSelected()) { 198 136 pnlAuthenticationParameters.add(pnlOAuth20Preferences, BorderLayout.CENTER); 199 137 pnlOAuth20Preferences.saveToPreferences(); 200 138 pnlOAuth20Preferences.initFromPreferences(); … … 206 144 207 145 @Override 208 146 public void propertyChange(PropertyChangeEvent evt) { 209 if (pnlOAuth Preferences != null) {210 pnlOAuth Preferences.propertyChange(evt);147 if (pnlOAuth20Preferences != null) { 148 pnlOAuth20Preferences.propertyChange(evt); 211 149 } 212 150 } 213 151 } -
deleted file core/src/org/openstreetmap/josm/gui/preferences/server/BasicAuthenticationPreferencesPanel.java
diff --git a/core/src/org/openstreetmap/josm/gui/preferences/server/BasicAuthenticationPreferencesPanel.java b/core/src/org/openstreetmap/josm/gui/preferences/server/BasicAuthenticationPreferencesPanel.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.preferences.server;3 4 import static org.openstreetmap.josm.tools.I18n.tr;5 6 import java.awt.BorderLayout;7 import java.awt.GridBagConstraints;8 import java.awt.GridBagLayout;9 import java.awt.Insets;10 import java.net.Authenticator.RequestorType;11 import java.net.PasswordAuthentication;12 13 import javax.swing.BorderFactory;14 import javax.swing.JLabel;15 import javax.swing.JPanel;16 17 import org.openstreetmap.josm.gui.widgets.JosmPasswordField;18 import org.openstreetmap.josm.gui.widgets.JosmTextField;19 import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;20 import org.openstreetmap.josm.io.OsmApi;21 import org.openstreetmap.josm.io.auth.CredentialsAgent;22 import org.openstreetmap.josm.io.auth.CredentialsAgentException;23 import org.openstreetmap.josm.io.auth.CredentialsManager;24 import org.openstreetmap.josm.tools.Logging;25 26 /**27 * The preferences panel for parameters necessary for the Basic Authentication Scheme.28 * @since 274529 */30 public class BasicAuthenticationPreferencesPanel extends JPanel {31 32 /** the OSM user name */33 private final JosmTextField tfOsmUserName = new JosmTextField();34 /** the OSM password */35 private final JosmPasswordField tfOsmPassword = new JosmPasswordField();36 /** a panel with further information, e.g. some warnings */37 private JPanel decorationPanel;38 39 /**40 * Constructs a new {@code BasicAuthenticationPreferencesPanel}.41 */42 public BasicAuthenticationPreferencesPanel() {43 build();44 }45 46 /**47 * builds the UI48 */49 protected final void build() {50 setLayout(new GridBagLayout());51 setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));52 GridBagConstraints gc = new GridBagConstraints();53 54 // -- OSM user name55 gc.fill = GridBagConstraints.HORIZONTAL;56 gc.anchor = GridBagConstraints.NORTHWEST;57 gc.weightx = 0.0;58 gc.insets = new Insets(0, 0, 3, 3);59 add(new JLabel(tr("OSM username:")), gc);60 61 gc.gridx = 1;62 gc.weightx = 1.0;63 add(tfOsmUserName, gc);64 SelectAllOnFocusGainedDecorator.decorate(tfOsmUserName);65 UserNameValidator valUserName = new UserNameValidator(tfOsmUserName);66 valUserName.validate();67 68 // -- OSM password69 gc.gridx = 0;70 gc.gridy = 1;71 gc.weightx = 0.0;72 add(new JLabel(tr("OSM password:")), gc);73 74 gc.gridx = 1;75 gc.weightx = 1.0;76 add(tfOsmPassword, gc);77 SelectAllOnFocusGainedDecorator.decorate(tfOsmPassword);78 tfOsmPassword.setToolTipText(tr("Please enter your OSM password"));79 80 // -- an info panel with a warning message81 gc.gridx = 0;82 gc.gridy = 2;83 gc.gridwidth = 2;84 gc.weightx = 1.0;85 gc.weighty = 1.0;86 gc.insets = new Insets(5, 0, 0, 0);87 gc.fill = GridBagConstraints.BOTH;88 decorationPanel = new JPanel(new BorderLayout());89 add(decorationPanel, gc);90 }91 92 /**93 * Inits contents from preferences.94 */95 public void initFromPreferences() {96 CredentialsAgent cm = CredentialsManager.getInstance();97 try {98 decorationPanel.removeAll();99 decorationPanel.add(cm.getPreferencesDecorationPanel(), BorderLayout.CENTER);100 PasswordAuthentication pa = cm.lookup(RequestorType.SERVER, OsmApi.getOsmApi().getHost());101 if (pa == null) {102 tfOsmUserName.setText("");103 tfOsmPassword.setText("");104 } else {105 tfOsmUserName.setText(pa.getUserName() == null ? "" : pa.getUserName());106 tfOsmPassword.setText(pa.getPassword() == null ? "" : String.valueOf(pa.getPassword()));107 }108 } catch (CredentialsAgentException e) {109 Logging.error(e);110 Logging.warn(tr("Failed to retrieve OSM credentials from credential manager."));111 Logging.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));112 tfOsmUserName.setText("");113 tfOsmPassword.setText("");114 }115 }116 117 /**118 * Saves contents to preferences.119 */120 public void saveToPreferences() {121 CredentialsAgent cm = CredentialsManager.getInstance();122 try {123 PasswordAuthentication pa = new PasswordAuthentication(124 tfOsmUserName.getText().trim(),125 tfOsmPassword.getPassword()126 );127 cm.store(RequestorType.SERVER, OsmApi.getOsmApi().getHost(), pa);128 } catch (CredentialsAgentException e) {129 Logging.error(e);130 Logging.warn(tr("Failed to save OSM credentials to credential manager."));131 Logging.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));132 }133 }134 135 /**136 * Clears the password field.137 */138 public void clearPassword() {139 tfOsmPassword.setText("");140 }141 } -
core/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java b/core/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java
a b 5 5 6 6 import java.awt.BorderLayout; 7 7 import java.awt.Color; 8 import java.awt.Component; 8 9 import java.awt.FlowLayout; 9 10 import java.awt.Font; 10 11 import java.awt.GridBagConstraints; … … 14 15 import java.awt.event.ItemEvent; 15 16 import java.beans.PropertyChangeEvent; 16 17 import java.beans.PropertyChangeListener; 18 import java.util.Arrays; 19 import java.util.Objects; 17 20 18 21 import javax.swing.AbstractAction; 19 22 import javax.swing.BorderFactory; 20 23 import javax.swing.JButton; 21 24 import javax.swing.JCheckBox; 22 25 import javax.swing.JLabel; 23 import javax.swing.JOptionPane;24 26 import javax.swing.JPanel; 25 27 26 28 import org.openstreetmap.josm.actions.ExpertToggleAction; 27 29 import org.openstreetmap.josm.data.oauth.IOAuthToken; 28 import org.openstreetmap.josm.data.oauth.OAuth20Authorization;29 30 import org.openstreetmap.josm.data.oauth.OAuth20Token; 30 31 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder; 31 32 import org.openstreetmap.josm.data.oauth.OAuthParameters; 32 import org.openstreetmap.josm.data.oauth.OAuthToken;33 33 import org.openstreetmap.josm.data.oauth.OAuthVersion; 34 import org.openstreetmap.josm.data.oauth.osm.OsmScopes;35 34 import org.openstreetmap.josm.gui.MainApplication; 36 35 import org.openstreetmap.josm.gui.oauth.AdvancedOAuthPropertiesPanel; 37 36 import org.openstreetmap.josm.gui.oauth.AuthorizationProcedure; … … 42 41 import org.openstreetmap.josm.gui.widgets.JosmTextField; 43 42 import org.openstreetmap.josm.io.OsmApi; 44 43 import org.openstreetmap.josm.io.auth.CredentialsManager; 45 import org.openstreetmap.josm.io.remotecontrol.RemoteControl;46 44 import org.openstreetmap.josm.tools.GBC; 47 45 import org.openstreetmap.josm.tools.ImageProvider; 48 46 import org.openstreetmap.josm.tools.Logging; 49 47 import org.openstreetmap.josm.tools.UserCancelException; 48 import org.openstreetmap.josm.tools.Utils; 50 49 51 50 /** 52 51 * The preferences panel for the OAuth 1.0a preferences. This just a summary panel … … 67 66 private final OAuthVersion oAuthVersion; 68 67 private String apiUrl; 69 68 70 /**71 * Create the panel. Uses {@link OAuthVersion#OAuth10a}.72 */73 public OAuthAuthenticationPreferencesPanel() {74 this(OAuthVersion.OAuth10a);75 }76 77 69 /** 78 70 * Create the panel. 79 71 * @param oAuthVersion The OAuth version to use … … 138 130 139 131 protected void refreshView() { 140 132 pnlAuthorisationMessage.removeAll(); 141 if ((this.oAuthVersion == OAuthVersion.OAuth10a && 142 OAuthAccessTokenHolder.getInstance().containsAccessToken()) 143 || OAuthAccessTokenHolder.getInstance().getAccessToken(this.apiUrl, this.oAuthVersion) != null) { 133 if (OAuthAccessTokenHolder.getInstance().getAccessToken(this.apiUrl, this.oAuthVersion) != null) { 144 134 pnlAuthorisationMessage.add(pnlAlreadyAuthorised, BorderLayout.CENTER); 145 135 pnlAlreadyAuthorised.refreshView(); 146 136 pnlAlreadyAuthorised.revalidate(); … … 159 149 public void setApiUrl(String apiUrl) { 160 150 this.apiUrl = apiUrl; 161 151 pnlAdvancedProperties.setApiUrl(apiUrl); 152 for (JPanel panel : Arrays.asList(this.pnlNotYetAuthorised, (JPanel) this.pnlAlreadyAuthorised.getComponent(6))) { 153 for (Component component : panel.getComponents()) { 154 if (component instanceof JButton && ((JButton) component).getAction() instanceof AuthoriseNowAction) { 155 ((AuthoriseNowAction) ((JButton) component).getAction()).updateEnabledState(); 156 } 157 } 158 } 162 159 } 163 160 164 161 /** … … 203 200 lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN)); 204 201 205 202 // Action for authorising now 206 if (oAuthVersion == OAuthVersion.OAuth10a) { 207 add(new JButton(new AuthoriseNowAction(AuthorizationProcedure.FULLY_AUTOMATIC)), GBC.eol()); 208 } 209 add(new JButton(new AuthoriseNowAction(AuthorizationProcedure.SEMI_AUTOMATIC)), GBC.eol()); 210 if (oAuthVersion == OAuthVersion.OAuth10a) { 211 JButton authManually = new JButton(new AuthoriseNowAction(AuthorizationProcedure.MANUALLY)); 212 add(authManually, GBC.eol()); 213 ExpertToggleAction.addVisibilitySwitcher(authManually); 214 } 203 add(new JButton(new AuthoriseNowAction(AuthorizationProcedure.FULLY_AUTOMATIC)), GBC.eol()); 204 JButton authManually = new JButton(new AuthoriseNowAction(AuthorizationProcedure.MANUALLY)); 205 add(authManually, GBC.eol()); 206 ExpertToggleAction.addVisibilitySwitcher(authManually); 215 207 216 208 // filler - grab remaining space 217 209 add(new JPanel(), GBC.std().fill(GBC.BOTH)); … … 224 216 */ 225 217 private class AlreadyAuthorisedPanel extends JPanel { 226 218 private final JosmTextField tfAccessTokenKey = new JosmTextField(null, null, 0, false); 227 private final JosmTextField tfAccessTokenSecret = new JosmTextField(null, null, 0, false);228 219 229 220 /** 230 221 * Constructs a new {@code AlreadyAuthorisedPanel}. … … 265 256 gc.weightx = 0.0; 266 257 add(new JLabel(tr("Access Token Secret:")), gc); 267 258 268 gc.gridx = 1;269 gc.weightx = 1.0;270 add(tfAccessTokenSecret, gc);271 tfAccessTokenSecret.setEditable(false);272 273 259 // -- access token secret 274 260 gc.gridy = 3; 275 261 gc.gridx = 0; … … 280 266 281 267 // -- action buttons 282 268 JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT)); 283 if (oAuthVersion == OAuthVersion.OAuth10a) { 284 // these want the OAuth 1.0 token information 285 btns.add(new JButton(new RenewAuthorisationAction(AuthorizationProcedure.FULLY_AUTOMATIC))); 286 } 287 btns.add(new JButton(new TestAuthorisationAction(oAuthVersion))); 269 btns.add(new JButton(new RenewAuthorisationAction(AuthorizationProcedure.FULLY_AUTOMATIC))); 270 btns.add(new JButton(new TestAuthorisationAction())); 288 271 btns.add(new JButton(new RemoveAuthorisationAction())); 289 272 gc.gridy = 4; 290 273 gc.gridx = 0; … … 309 292 310 293 protected final void refreshView() { 311 294 switch (oAuthVersion) { 312 case OAuth10a:313 String v = OAuthAccessTokenHolder.getInstance().getAccessTokenKey();314 tfAccessTokenKey.setText(v == null ? "" : v);315 v = OAuthAccessTokenHolder.getInstance().getAccessTokenSecret();316 tfAccessTokenSecret.setText(v == null ? "" : v);317 tfAccessTokenSecret.setVisible(true);318 break;319 295 case OAuth20: 320 296 case OAuth21: 321 297 String token = ""; … … 324 300 token = bearerToken == null ? "" : bearerToken.getBearerToken(); 325 301 } 326 302 tfAccessTokenKey.setText(token == null ? "" : token); 327 tfAccessTokenSecret.setVisible(false); 303 break; 304 default: 328 305 } 329 306 cbSaveToPreferences.setSelected(OAuthAccessTokenHolder.getInstance().isSaveToPreferences()); 330 307 } … … 340 317 this.procedure = procedure; 341 318 putValue(NAME, tr("{0} ({1})", tr("Authorize now"), procedure.getText())); 342 319 putValue(SHORT_DESCRIPTION, procedure.getDescription()); 343 if (procedure == AuthorizationProcedure.FULLY_AUTOMATIC 344 || OAuthAuthenticationPreferencesPanel.this.oAuthVersion != OAuthVersion.OAuth10a) { 320 if (procedure == AuthorizationProcedure.FULLY_AUTOMATIC) { 345 321 new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this); 346 322 } 323 updateEnabledState(); 324 } 325 326 void updateEnabledState() { 327 if (procedure == AuthorizationProcedure.MANUALLY) { 328 this.setEnabled(true); 329 } else { 330 final String currentApiUrl = apiUrl; 331 MainApplication.worker.execute(() -> { 332 final String clientId = OAuthParameters.createDefault(apiUrl, oAuthVersion).getClientId(); 333 if (Objects.equals(apiUrl, currentApiUrl)) { 334 GuiHelper.runInEDT(() -> this.setEnabled(!Utils.isEmpty(clientId))); 335 } 336 }); 337 } 347 338 } 348 339 349 340 @Override 350 341 public void actionPerformed(ActionEvent arg0) { 351 if (OAuthAuthenticationPreferencesPanel.this.oAuthVersion == OAuthVersion.OAuth10a) { 352 OAuthAuthorizationWizard wizard = new OAuthAuthorizationWizard( 353 OAuthAuthenticationPreferencesPanel.this, 354 procedure, 355 apiUrl, 356 MainApplication.worker); 357 try { 358 wizard.showDialog(); 359 } catch (UserCancelException ignore) { 360 Logging.trace(ignore); 361 return; 362 } 363 pnlAdvancedProperties.setAdvancedParameters(wizard.getOAuthParameters()); 364 refreshView(); 365 } else { 366 final boolean remoteControlIsRunning = Boolean.TRUE.equals(RemoteControl.PROP_REMOTECONTROL_ENABLED.get()); 367 // TODO: Ask user if they want to start remote control? 368 if (!remoteControlIsRunning) { 369 RemoteControl.start(); 370 } 371 new OAuth20Authorization().authorize(OAuthParameters.createDefault(OsmApi.getOsmApi().getServerUrl(), oAuthVersion), token -> { 372 if (!remoteControlIsRunning) { 373 RemoteControl.stop(); 374 } 375 OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().getServerUrl(), token.orElse(null)); 376 OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance()); 377 GuiHelper.runInEDT(OAuthAuthenticationPreferencesPanel.this::refreshView); 378 if (!token.isPresent()) { 379 GuiHelper.runInEDT(() -> JOptionPane.showMessageDialog(MainApplication.getMainPanel(), 380 tr("Authentication failed, please check browser for details."), 381 tr("OAuth Authentication Failed"), 382 JOptionPane.ERROR_MESSAGE)); 383 } 384 }, OsmScopes.read_gpx, OsmScopes.write_gpx, 385 OsmScopes.read_prefs, OsmScopes.write_prefs, 386 OsmScopes.write_api, OsmScopes.write_notes); 387 } 342 OAuthAuthorizationWizard wizard = new OAuthAuthorizationWizard( 343 OAuthAuthenticationPreferencesPanel.this, 344 procedure, 345 apiUrl, 346 MainApplication.worker, 347 oAuthVersion); 348 try { 349 wizard.showDialog(token -> GuiHelper.runInEDT(OAuthAuthenticationPreferencesPanel.this::refreshView)); 350 } catch (UserCancelException userCancelException) { 351 Logging.trace(userCancelException); 352 return; 353 } 354 pnlAdvancedProperties.setAdvancedParameters(wizard.getOAuthParameters()); 355 refreshView(); 388 356 } 389 357 } 390 358 … … 400 368 401 369 @Override 402 370 public void actionPerformed(ActionEvent e) { 403 if (oAuthVersion == OAuthVersion.OAuth10a) { 404 OAuthAccessTokenHolder.getInstance().setAccessToken(null); 405 } else { 406 OAuthAccessTokenHolder.getInstance().setAccessToken(apiUrl, (IOAuthToken) null); 407 } 371 OAuthAccessTokenHolder.getInstance().setAccessToken(apiUrl, null); 408 372 OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance()); 409 373 refreshView(); 410 374 } … … 429 393 * Runs a test whether we can access the OSM server with the current Access Token 430 394 */ 431 395 private class TestAuthorisationAction extends AbstractAction { 432 private final OAuthVersion oAuthVersion;433 434 396 /** 435 397 * Constructs a new {@code TestAuthorisationAction}. 436 398 */ 437 TestAuthorisationAction(OAuthVersion oAuthVersion) { 438 this.oAuthVersion = oAuthVersion; 399 TestAuthorisationAction() { 439 400 putValue(NAME, tr("Test Access Token")); 440 401 putValue(SHORT_DESCRIPTION, tr("Click test access to the OSM server with the current access token")); 441 402 new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this); … … 443 404 444 405 @Override 445 406 public void actionPerformed(ActionEvent evt) { 446 if (this.oAuthVersion == OAuthVersion.OAuth10a) { 447 OAuthToken token = OAuthAccessTokenHolder.getInstance().getAccessToken(); 448 OAuthParameters parameters = OAuthParameters.createFromApiUrl(OsmApi.getOsmApi().getServerUrl()); 449 TestAccessTokenTask task = new TestAccessTokenTask( 450 OAuthAuthenticationPreferencesPanel.this, 451 apiUrl, 452 parameters, 453 token 454 ); 455 MainApplication.worker.submit(task); 456 } else { 457 IOAuthToken token = OAuthAccessTokenHolder.getInstance().getAccessToken(OsmApi.getOsmApi().getBaseUrl(), OAuthVersion.OAuth20); 458 TestAccessTokenTask task = new TestAccessTokenTask( 459 OAuthAuthenticationPreferencesPanel.this, 460 apiUrl, 461 token.getParameters(), 462 token 463 ); 464 MainApplication.worker.submit(task); 465 } 407 IOAuthToken token = OAuthAccessTokenHolder.getInstance().getAccessToken(OsmApi.getOsmApi().getBaseUrl(), OAuthVersion.OAuth20); 408 TestAccessTokenTask task = new TestAccessTokenTask( 409 OAuthAuthenticationPreferencesPanel.this, 410 apiUrl, 411 token 412 ); 413 MainApplication.worker.submit(task); 466 414 } 467 415 } 468 416 -
core/src/org/openstreetmap/josm/io/auth/CredentialsAgent.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/io/auth/CredentialsAgent.java b/core/src/org/openstreetmap/josm/io/auth/CredentialsAgent.java
a b 8 8 import javax.annotation.Nullable; 9 9 10 10 import org.openstreetmap.josm.data.oauth.IOAuthToken; 11 import org.openstreetmap.josm.data.oauth.OAuthToken;12 11 13 12 /** 14 13 * A CredentialsAgent manages two credentials: … … 64 63 * 65 64 * @return the current OAuth Access Token to access the OSM server. 66 65 * @throws CredentialsAgentException if something goes wrong 66 * @deprecated since xxx -- OAuth 1.0 is being removed from the OSM API 67 67 */ 68 OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException; 68 @Deprecated 69 default IOAuthToken lookupOAuthAccessToken() throws CredentialsAgentException { 70 throw new CredentialsAgentException("Call to deprecated method"); 71 } 69 72 70 73 /** 71 74 * Lookup the current OAuth Access Token to access the specified server. Replies null, if no … … 84 87 * 85 88 * @param accessToken the access Token. null, to remove the Access Token. 86 89 * @throws CredentialsAgentException if something goes wrong 90 * @deprecated since xxx -- OAuth 1.0 is being removed from the OSM API 87 91 */ 88 void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException; 92 @Deprecated 93 default void storeOAuthAccessToken(IOAuthToken accessToken) throws CredentialsAgentException { 94 throw new CredentialsAgentException("Call to deprecated method"); 95 } 89 96 90 97 /** 91 98 * Stores the OAuth Access Token <code>accessToken</code>. 92 99 * 93 100 * @param host The host the access token is for 94 101 * @param accessToken the access Token. null, to remove the Access Token. This will remove all IOAuthTokens <i>not</i> managed by 95 * {@link #storeOAuthAccessToken( OAuthToken)}.102 * {@link #storeOAuthAccessToken(IOAuthToken)}. 96 103 * @throws CredentialsAgentException if something goes wrong 97 104 * @since 18650 98 105 */ -
core/src/org/openstreetmap/josm/io/auth/CredentialsManager.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/io/auth/CredentialsManager.java b/core/src/org/openstreetmap/josm/io/auth/CredentialsManager.java
a b 8 8 9 9 import org.openstreetmap.josm.data.UserIdentityManager; 10 10 import org.openstreetmap.josm.data.oauth.IOAuthToken; 11 import org.openstreetmap.josm.data.oauth.OAuthToken;12 11 import org.openstreetmap.josm.io.OsmApi; 13 12 import org.openstreetmap.josm.tools.CheckParameterUtil; 14 13 import org.openstreetmap.josm.tools.Logging; … … 16 15 17 16 /** 18 17 * CredentialManager is a factory for the single credential agent used. 19 * 18 * <p> 20 19 * Currently, it defaults to replying an instance of {@link JosmPreferencesCredentialAgent}. 21 20 * @since 2641 22 21 */ … … 156 155 return credentials; 157 156 } 158 157 159 @Override160 public OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException {161 return delegate.lookupOAuthAccessToken();162 }163 164 158 @Override 165 159 public IOAuthToken lookupOAuthAccessToken(String host) throws CredentialsAgentException { 166 160 return delegate.lookupOAuthAccessToken(host); 167 161 } 168 162 169 @Override170 public void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException {171 delegate.storeOAuthAccessToken(accessToken);172 }173 174 163 @Override 175 164 public void storeOAuthAccessToken(String host, IOAuthToken accessToken) throws CredentialsAgentException { 176 165 delegate.storeOAuthAccessToken(host, accessToken); -
core/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialAgent.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialAgent.java b/core/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialAgent.java
a b 17 17 import org.openstreetmap.josm.data.oauth.OAuth20Exception; 18 18 import org.openstreetmap.josm.data.oauth.OAuth20Parameters; 19 19 import org.openstreetmap.josm.data.oauth.OAuth20Token; 20 import org.openstreetmap.josm.data.oauth.OAuthToken;21 20 import org.openstreetmap.josm.data.oauth.OAuthVersion; 22 21 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 23 22 import org.openstreetmap.josm.io.DefaultProxySelector; … … 102 101 } 103 102 } 104 103 105 /**106 * Lookup the current OAuth Access Token to access the OSM server. Replies null, if no107 * Access Token is currently managed by this CredentialManager.108 *109 * @return the current OAuth Access Token to access the OSM server.110 * @throws CredentialsAgentException if something goes wrong111 */112 @Override113 public OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException {114 String accessTokenKey = Config.getPref().get("oauth.access-token.key", null);115 String accessTokenSecret = Config.getPref().get("oauth.access-token.secret", null);116 if (accessTokenKey == null && accessTokenSecret == null)117 return null;118 return new OAuthToken(accessTokenKey, accessTokenSecret);119 }120 121 104 @Override 122 105 public IOAuthToken lookupOAuthAccessToken(String host) throws CredentialsAgentException { 123 106 Set<String> keySet = new HashSet<>(Config.getPref().getKeySet()); … … 142 125 return null; 143 126 } 144 127 145 /**146 * Stores the OAuth Access Token <code>accessToken</code>.147 *148 * @param accessToken the access Token. null, to remove the Access Token.149 * @throws CredentialsAgentException if something goes wrong150 */151 @Override152 public void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException {153 if (accessToken == null) {154 Config.getPref().put("oauth.access-token.key", null);155 Config.getPref().put("oauth.access-token.secret", null);156 } else {157 Config.getPref().put("oauth.access-token.key", accessToken.getKey());158 Config.getPref().put("oauth.access-token.secret", accessToken.getSecret());159 }160 }161 162 128 @Override 163 129 public void storeOAuthAccessToken(String host, IOAuthToken accessToken) throws CredentialsAgentException { 164 130 Objects.requireNonNull(host, "host"); -
core/src/org/openstreetmap/josm/io/MessageNotifier.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/io/MessageNotifier.java b/core/src/org/openstreetmap/josm/io/MessageNotifier.java
a b 144 144 CredentialsManager credManager = CredentialsManager.getInstance(); 145 145 try { 146 146 if (JosmPreferencesCredentialAgent.class.equals(credManager.getCredentialsAgentClass())) { 147 if (OsmApi.isUsingOAuth(OAuthVersion.OAuth10a)) { 148 return credManager.lookupOAuthAccessToken() != null; 149 } else if (OsmApi.isUsingOAuth(OAuthVersion.OAuth20) || OsmApi.isUsingOAuth(OAuthVersion.OAuth21)) { 147 if (OsmApi.isUsingOAuth(OAuthVersion.OAuth20) || OsmApi.isUsingOAuth(OAuthVersion.OAuth21)) { 150 148 return credManager.lookupOAuthAccessToken(OsmApi.getOsmApi().getHost()) != null; 151 149 } else if (OsmApi.isUsingOAuth()) { 152 150 // Ensure we do not forget to update this section -
core/src/org/openstreetmap/josm/io/NetworkManager.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/io/NetworkManager.java b/core/src/org/openstreetmap/josm/io/NetworkManager.java
a b 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.io; 3 3 4 import java.net.URI; 4 5 import java.net.URL; 5 6 import java.util.Collections; 6 7 import java.util.EnumSet; … … 57 58 } 58 59 return null; 59 60 } 61 62 /** 63 * Adds a new network error that occur to give a hint about broken Internet connection. 64 * Do not use this method for errors known for sure thrown because of a bad proxy configuration. 65 * 66 * @param url The accessed URL that caused the error 67 * @param t The network error 68 * @return The previous error associated to the given resource, if any. Can be {@code null} 69 * @since xxx 70 */ 71 public static Throwable addNetworkError(URI url, Throwable t) { 72 if (url != null && t != null) { 73 Throwable old = addNetworkError(url.toString(), t); 74 if (old != null) { 75 Logging.warn("Already here "+old); 76 } 77 return old; 78 } 79 return null; 80 } 60 81 61 82 /** 62 83 * Returns the network errors that occurred until now. -
core/src/org/openstreetmap/josm/io/OsmApi.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/io/OsmApi.java b/core/src/org/openstreetmap/josm/io/OsmApi.java
a b 11 11 import java.net.Authenticator.RequestorType; 12 12 import java.net.ConnectException; 13 13 import java.net.HttpURLConnection; 14 import java.net.MalformedURLException;15 14 import java.net.NoRouteToHostException; 16 15 import java.net.PortUnreachableException; 17 16 import java.net.SocketException; 18 17 import java.net.SocketTimeoutException; 18 import java.net.URI; 19 import java.net.URISyntaxException; 19 20 import java.net.URL; 20 21 import java.nio.charset.StandardCharsets; 21 22 import java.util.Collection; … … 84 85 private static final Map<String, OsmApi> instances = new HashMap<>(); 85 86 86 87 private static final ListenerList<OsmApiInitializationListener> listeners = ListenerList.create(); 87 /** This is used to make certain we have set osm-server.auth-method to the "right" default */88 private static boolean oauthCompatibilitySwitch;89 88 90 89 private URL url; 91 90 … … 194 193 public String getHost() { 195 194 String host = null; 196 195 try { 197 host = new UR L(serverUrl).getHost();198 } catch ( MalformedURLException e) {196 host = new URI(serverUrl).getHost(); 197 } catch (URISyntaxException e) { 199 198 Logging.warn(e); 200 199 } 201 200 return host; … … 455 454 /** 456 455 * Creates a new changeset based on the keys in <code>changeset</code>. If this 457 456 * method succeeds, changeset.getId() replies the id the server assigned to the new changeset 458 * 457 * <p> 459 458 * The changeset must not be null, but its key/value-pairs may be empty. 460 459 * 461 460 * @param changeset the changeset toe be created. Must not be null. … … 652 651 * @since 6349 653 652 */ 654 653 public static boolean isUsingOAuth() { 655 return isUsingOAuth(OAuthVersion.OAuth10a) 656 || isUsingOAuth(OAuthVersion.OAuth20) 654 return isUsingOAuth(OAuthVersion.OAuth20) 657 655 || isUsingOAuth(OAuthVersion.OAuth21); 658 656 } 659 657 … … 664 662 * @since 18650 665 663 */ 666 664 public static boolean isUsingOAuth(OAuthVersion version) { 667 if (version == OAuthVersion.OAuth10a) { 668 return "oauth".equalsIgnoreCase(getAuthMethod()); 669 } else if (version == OAuthVersion.OAuth20 || version == OAuthVersion.OAuth21) { 670 return "oauth20".equalsIgnoreCase(getAuthMethod()); 665 if (version == OAuthVersion.OAuth20 || version == OAuthVersion.OAuth21) { 666 return getAuthMethodVersion() == OAuthVersion.OAuth20 || getAuthMethodVersion() == OAuthVersion.OAuth21; 671 667 } 672 668 return false; 673 669 } … … 679 675 */ 680 676 public static boolean isUsingOAuthAndOAuthSetUp(OsmApi api) { 681 677 if (OsmApi.isUsingOAuth()) { 682 if (OsmApi.isUsingOAuth(OAuthVersion.OAuth10a)) {683 return OAuthAccessTokenHolder.getInstance().containsAccessToken();684 }685 678 if (OsmApi.isUsingOAuth(OAuthVersion.OAuth20)) { 686 679 return OAuthAccessTokenHolder.getInstance().getAccessToken(api.getBaseUrl(), OAuthVersion.OAuth20) != null; 687 680 } … … 697 690 * @return the authentication method 698 691 */ 699 692 public static String getAuthMethod() { 700 setCurrentAuthMethod();701 693 return Config.getPref().get("osm-server.auth-method", "oauth20"); 702 694 } 703 695 704 696 /** 705 * This is a compatibility method for users who currently use OAuth 1.0 -- we are changing the default from oauth to oauth20,706 * but since oauth was the default, pre-existing users will suddenly be switched to oauth20.707 * This should be removed whenever {@link OAuthVersion#OAuth10a} support is removed.697 * Returns the authentication method set in the preferences 698 * @return the authentication method 699 * @since xxx 708 700 */ 709 private static void setCurrentAuthMethod() { 710 if (!oauthCompatibilitySwitch) { 711 oauthCompatibilitySwitch = true; 712 final String prefKey = "osm-server.auth-method"; 713 if ("oauth20".equals(Config.getPref().get(prefKey, "oauth20")) 714 && !isUsingOAuthAndOAuthSetUp(OsmApi.getOsmApi()) 715 && OAuthAccessTokenHolder.getInstance().containsAccessToken()) { 716 Config.getPref().put(prefKey, "oauth"); 717 } 701 public static OAuthVersion getAuthMethodVersion() { 702 switch (getAuthMethod()) { 703 case "oauth20": return OAuthVersion.OAuth20; 704 case "oauth21": return OAuthVersion.OAuth21; 705 default: 706 Config.getPref().put("osm-server.auth-method", null); 707 return getAuthMethodVersion(); 718 708 } 719 709 } 720 710 -
core/src/org/openstreetmap/josm/io/OsmConnection.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/io/OsmConnection.java b/core/src/org/openstreetmap/josm/io/OsmConnection.java
a b 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 6 import java.lang.reflect.InvocationTargetException; 7 import java.net. Authenticator.RequestorType;8 import java.net. MalformedURLException;7 import java.net.URI; 8 import java.net.URISyntaxException; 9 9 import java.net.URL; 10 10 import java.nio.charset.StandardCharsets; 11 11 import java.util.Base64; … … 27 27 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 28 28 import org.openstreetmap.josm.gui.MainApplication; 29 29 import org.openstreetmap.josm.gui.util.GuiHelper; 30 import org.openstreetmap.josm.io.auth.CredentialsAgentException;31 import org.openstreetmap.josm.io.auth.CredentialsAgentResponse;32 30 import org.openstreetmap.josm.io.auth.CredentialsManager; 33 31 import org.openstreetmap.josm.io.remotecontrol.RemoteControl; 34 32 import org.openstreetmap.josm.tools.HttpClient; 35 33 import org.openstreetmap.josm.tools.JosmRuntimeException; 36 34 import org.openstreetmap.josm.tools.Logging; 37 35 38 import oauth.signpost.OAuthConsumer;39 import oauth.signpost.exception.OAuthException;40 36 41 37 /** 42 38 * Base class that handles common things like authentication for the reader and writer … … 50 46 51 47 protected boolean cancel; 52 48 protected HttpClient activeConnection; 53 protected OAuthParameters oauthParameters;54 49 protected IOAuthParameters oAuth20Parameters; 55 50 56 51 /** … … 64 59 * @throws InterruptedException if we're interrupted while waiting for the event dispatching thread to finish OAuth authorization task 65 60 * @throws InvocationTargetException if an exception is thrown while running OAuth authorization task 66 61 */ 67 void obtainAccessToken(URL serverUrl) throws InvocationTargetException, InterruptedException; 62 default void obtainAccessToken(URL serverUrl) throws InvocationTargetException, InterruptedException { 63 try { 64 this.obtainAccessToken(serverUrl.toURI()); 65 } catch (URISyntaxException e) { 66 throw new JosmRuntimeException(e); 67 } 68 } 69 70 /** 71 * Obtains an OAuth access token for the connection. Afterwards, the token is accessible via {@link OAuthAccessTokenHolder}. 72 * @param serverUrl the URL to OSM server 73 * @throws InterruptedException if we're interrupted while waiting for the event dispatching thread to finish OAuth authorization task 74 * @throws InvocationTargetException if an exception is thrown while running OAuth authorization task 75 */ 76 void obtainAccessToken(URI serverUrl) throws InvocationTargetException, InterruptedException; 68 77 } 69 78 70 79 static volatile OAuthAccessTokenFetcher fetcher = u -> { … … 116 125 return null; 117 126 } 118 127 119 /**120 * Adds an authentication header for basic authentication121 *122 * @param con the connection123 * @throws OsmTransferException if something went wrong. Check for nested exceptions124 */125 protected void addBasicAuthorizationHeader(HttpClient con) throws OsmTransferException {126 CredentialsAgentResponse response;127 try {128 synchronized (CredentialsManager.getInstance()) {129 response = CredentialsManager.getInstance().getCredentials(RequestorType.SERVER,130 con.getURL().getHost(), false /* don't know yet whether the credentials will succeed */);131 }132 } catch (CredentialsAgentException e) {133 throw new OsmTransferException(e);134 }135 if (response != null) {136 if (response.isCanceled()) {137 cancel = true;138 } else {139 String username = response.getUsername() == null ? "" : response.getUsername();140 String password = response.getPassword() == null ? "" : String.valueOf(response.getPassword());141 String token = username + ':' + password;142 con.setHeader("Authorization", BASIC_AUTH + Base64.getEncoder().encodeToString(token.getBytes(StandardCharsets.UTF_8)));143 }144 }145 }146 147 /**148 * Signs the connection with an OAuth authentication header149 *150 * @param connection the connection151 *152 * @throws MissingOAuthAccessTokenException if there is currently no OAuth Access Token configured153 * @throws OsmTransferException if signing fails154 */155 protected void addOAuthAuthorizationHeader(HttpClient connection) throws OsmTransferException {156 if (oauthParameters == null) {157 oauthParameters = OAuthParameters.createFromApiUrl(OsmApi.getOsmApi().getServerUrl());158 }159 OAuthConsumer consumer = oauthParameters.buildConsumer();160 OAuthAccessTokenHolder holder = OAuthAccessTokenHolder.getInstance();161 if (!holder.containsAccessToken()) {162 obtainAccessToken(connection);163 }164 if (!holder.containsAccessToken()) { // check if wizard completed165 throw new MissingOAuthAccessTokenException();166 }167 consumer.setTokenWithSecret(holder.getAccessTokenKey(), holder.getAccessTokenSecret());168 try {169 consumer.sign(connection);170 } catch (OAuthException e) {171 throw new OsmTransferException(tr("Failed to sign a HTTP connection with an OAuth Authentication header"), e);172 }173 }174 175 /**176 * Obtains an OAuth access token for the connection.177 * Afterwards, the token is accessible via {@link OAuthAccessTokenHolder} / {@link CredentialsManager}.178 * @param connection connection for which the access token should be obtained179 * @throws MissingOAuthAccessTokenException if the process cannot be completed successfully180 */181 protected void obtainAccessToken(final HttpClient connection) throws MissingOAuthAccessTokenException {182 try {183 final URL apiUrl = new URL(OsmApi.getOsmApi().getServerUrl());184 if (!Objects.equals(apiUrl.getHost(), connection.getURL().getHost())) {185 throw new MissingOAuthAccessTokenException();186 }187 fetcher.obtainAccessToken(apiUrl);188 OAuthAccessTokenHolder.getInstance().setSaveToPreferences(true);189 OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance());190 } catch (MalformedURLException | InvocationTargetException e) {191 throw new MissingOAuthAccessTokenException(e);192 } catch (InterruptedException e) {193 Thread.currentThread().interrupt();194 throw new MissingOAuthAccessTokenException(e);195 }196 }197 198 128 /** 199 129 * Obtains an OAuth access token for the connection. 200 130 * Afterwards, the token is accessible via {@link OAuthAccessTokenHolder} / {@link CredentialsManager}. … … 220 150 RemoteControl.stop(); 221 151 } 222 152 // Clean up old token/password 223 OAuthAccessTokenHolder.getInstance().setAccessToken(null);224 153 OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().getServerUrl(), authToken.orElse(null)); 225 154 OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance()); 226 155 done.countDown(); … … 276 205 277 206 protected void addAuth(HttpClient connection) throws OsmTransferException { 278 207 final String authMethod = OsmApi.getAuthMethod(); 279 switch (authMethod) { 280 case "basic": 281 addBasicAuthorizationHeader(connection); 282 return; 283 case "oauth": 284 addOAuthAuthorizationHeader(connection); 285 return; 286 case "oauth20": 287 addOAuth20AuthorizationHeader(connection); 288 return; 289 default: 290 String msg = tr("Unexpected value for preference ''{0}''. Got ''{1}''.", "osm-server.auth-method", authMethod); 291 Logging.warn(msg); 292 throw new OsmTransferException(msg); 293 } 208 if ("oauth20".equals(authMethod)) { 209 addOAuth20AuthorizationHeader(connection); 210 return; 211 } 212 String msg = tr("Unexpected value for preference ''{0}''. Got ''{1}''.", "osm-server.auth-method", authMethod); 213 Logging.warn(msg); 214 throw new OsmTransferException(msg); 294 215 } 295 216 296 217 /** -
core/src/org/openstreetmap/josm/tools/ExceptionUtil.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/tools/ExceptionUtil.java b/core/src/org/openstreetmap/josm/tools/ExceptionUtil.java
a b 297 297 + "Authentication at the OSM server with the OAuth token ''{0}'' failed.<br>" 298 298 + "Please launch the preferences dialog and retrieve another OAuth token." 299 299 + "</html>", 300 OAuthAccessTokenHolder.getInstance().getAccessToken Key()300 OAuthAccessTokenHolder.getInstance().getAccessToken(e.getUrl(), OsmApi.getAuthMethodVersion()) 301 301 ); 302 302 } 303 303 … … 343 343 + "''{1}''.<br>" 344 344 + "Please launch the preferences dialog and retrieve another OAuth token." 345 345 + "</html>", 346 OAuthAccessTokenHolder.getInstance().getAccessToken Key(),346 OAuthAccessTokenHolder.getInstance().getAccessToken(e.getUrl(), OsmApi.getAuthMethodVersion()), 347 347 e.getAccessedUrl() == null ? tr("unknown") : e.getAccessedUrl() 348 348 ); 349 349 } -
core/src/org/openstreetmap/josm/tools/HttpClient.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/src/org/openstreetmap/josm/tools/HttpClient.java b/core/src/org/openstreetmap/josm/tools/HttpClient.java
a b 6 6 import java.io.BufferedReader; 7 7 import java.io.IOException; 8 8 import java.io.InputStream; 9 import java.io.UncheckedIOException; 9 10 import java.net.CookieHandler; 10 11 import java.net.CookieManager; 11 12 import java.net.HttpURLConnection; 12 13 import java.net.MalformedURLException; 14 import java.net.URI; 15 import java.net.URISyntaxException; 13 16 import java.net.URL; 14 17 import java.nio.charset.StandardCharsets; 15 18 import java.util.List; … … 54 57 * @return a new instance 55 58 */ 56 59 HttpClient create(URL url, String requestMethod); 60 61 /** 62 * Creates a new instance for the given URL and a {@code GET} request 63 * 64 * @param url the URL 65 * @param requestMethod the HTTP request method to perform when calling 66 * @return a new instance 67 * @since xxx 68 */ 69 default HttpClient create(URI url, String requestMethod) { 70 try { 71 return create(url.toURL(), requestMethod); 72 } catch (MalformedURLException e) { 73 throw new UncheckedIOException(e); 74 } 75 } 57 76 } 58 77 59 78 private URL url; … … 535 554 public static HttpClient create(URL url) { 536 555 return create(url, "GET"); 537 556 } 557 558 /** 559 * Creates a new instance for the given URL and a {@code GET} request 560 * 561 * @param url the URL 562 * @return a new instance 563 */ 564 public static HttpClient create(URI url) { 565 return create(url, "GET"); 566 } 538 567 539 568 /** 540 569 * Creates a new instance for the given URL and a {@code GET} request … … 551 580 // #18812: specify `Accept=*/*` to prevent Java from adding `Accept=text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2` 552 581 .setAccept("*/*"); 553 582 } 583 584 /** 585 * Creates a new instance for the given URL and a {@code GET} request 586 * 587 * @param url the URL 588 * @param requestMethod the HTTP request method to perform when calling 589 * @return a new instance 590 * @since xxx 591 */ 592 public static HttpClient create(URI url, String requestMethod) { 593 if (factory == null) { 594 throw new IllegalStateException("HTTP factory has not been set"); 595 } 596 return factory.create(url, requestMethod) 597 // #18812: specify `Accept=*/*` to prevent Java from adding `Accept=text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2` 598 .setAccept("*/*"); 599 } 554 600 555 601 /** 556 602 * Returns the URL set for this connection. -
core/test/functional/org/openstreetmap/josm/io/OsmServerBackreferenceReaderTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/functional/org/openstreetmap/josm/io/OsmServerBackreferenceReaderTest.java b/core/test/functional/org/openstreetmap/josm/io/OsmServerBackreferenceReaderTest.java
a b 16 16 import java.io.OutputStreamWriter; 17 17 import java.io.PrintWriter; 18 18 import java.nio.charset.StandardCharsets; 19 import java.nio.file.Files; 19 20 import java.text.MessageFormat; 20 21 import java.util.HashSet; 21 22 import java.util.Locale; … … 42 43 import org.openstreetmap.josm.data.projection.Projections; 43 44 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 44 45 import org.openstreetmap.josm.spi.preferences.Config; 46 import org.openstreetmap.josm.testutils.annotations.TestUser; 45 47 import org.openstreetmap.josm.tools.Logging; 46 48 47 49 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; … … 51 53 * @since 1806 52 54 */ 53 55 @SuppressFBWarnings(value = "CRLF_INJECTION_LOGS") 56 @org.openstreetmap.josm.testutils.annotations.OsmApi(org.openstreetmap.josm.testutils.annotations.OsmApi.APIType.DEV) 57 @TestUser 54 58 class OsmServerBackreferenceReaderTest { 55 59 private static final Logger logger = Logger.getLogger(OsmServerBackreferenceReader.class.getName()); 56 60 … … 159 163 */ 160 164 @BeforeAll 161 165 public static void setUpBeforeClass() throws OsmTransferException, CyclicUploadDependencyException, IOException { 162 if (!TestUtils.areCredentialsProvided()) { 163 logger.severe("OSM DEV API credentials not provided. Please define them with -Dosm.username and -Dosm.password"); 164 return; 165 } 166 assumeTrue(TestUtils.areCredentialsProvided(), 167 "OSM DEV API credentials not provided. Please define them with -Dosm.oauth2"); 168 166 169 logger.info("initializing ..."); 167 170 168 JOSMFixture.createFunctionalTestFixture().init();169 170 Config.getPref().put("osm-server.auth-method", "basic");171 172 171 // don't use atomic upload, the test API server can't cope with large diff uploads 173 172 // 174 173 Config.getPref().putBoolean("osm-server.atomic-upload", false); … … 196 195 197 196 try ( 198 197 PrintWriter pw = new PrintWriter( 199 new OutputStreamWriter( new FileOutputStream(dataSetCacheOutputFile), StandardCharsets.UTF_8)198 new OutputStreamWriter(Files.newOutputStream(dataSetCacheOutputFile.toPath()), StandardCharsets.UTF_8) 200 199 )) { 201 200 logger.info(MessageFormat.format("caching test data set in ''{0}'' ...", dataSetCacheOutputFile.toString())); 202 201 try (OsmWriter w = new OsmWriter(pw, false, testDataSet.getVersion())) { … … 218 217 */ 219 218 @BeforeEach 220 219 public void setUp() throws IOException, IllegalDataException, FileNotFoundException { 221 if (!TestUtils.areCredentialsProvided()) {222 return;223 }224 220 File f = new File(System.getProperty("java.io.tmpdir"), MultiFetchServerObjectReaderTest.class.getName() + ".dataset"); 225 221 logger.info(MessageFormat.format("reading cached dataset ''{0}''", f.toString())); 226 222 ds = new DataSet(); … … 291 287 */ 292 288 @Test 293 289 void testBackreferenceForNodeFull() throws OsmTransferException { 294 assumeTrue(TestUtils.areCredentialsProvided());295 290 Node n = lookupNode(ds, 0); 296 291 assertNotNull(n); 297 292 … … 338 333 */ 339 334 @Test 340 335 void testBackreferenceForWay() throws OsmTransferException { 341 assumeTrue(TestUtils.areCredentialsProvided());342 336 Way w = lookupWay(ds, 1); 343 337 assertNotNull(w); 344 338 // way with name "way-1" is referred to by two relations … … 381 375 */ 382 376 @Test 383 377 void testBackreferenceForWayFull() throws OsmTransferException { 384 assumeTrue(TestUtils.areCredentialsProvided());385 378 Way w = lookupWay(ds, 1); 386 379 assertNotNull(w); 387 380 // way with name "way-1" is referred to by two relations … … 418 411 */ 419 412 @Test 420 413 void testBackreferenceForRelation() throws OsmTransferException { 421 assumeTrue(TestUtils.areCredentialsProvided());422 414 Relation r = lookupRelation(ds, 1); 423 415 assertNotNull(r); 424 416 // way with name "relation-1" is referred to by four relations: … … 536 528 */ 537 529 @Test 538 530 void testBackreferenceForRelationFull() throws OsmTransferException { 539 assumeTrue(TestUtils.areCredentialsProvided());540 531 Relation r = lookupRelation(ds, 1); 541 532 assertNotNull(r); 542 533 // way with name "relation-1" is referred to by four relations: -
core/test/performance/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSourceFilterTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/performance/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSourceFilterTest.java b/core/test/performance/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSourceFilterTest.java
a b 12 12 import org.openstreetmap.josm.data.osm.OsmDataGenerator; 13 13 import org.openstreetmap.josm.data.osm.OsmDataGenerator.KeyValueDataGenerator; 14 14 import org.openstreetmap.josm.gui.mappaint.MultiCascade; 15 import org.openstreetmap.josm.testutils.annotations.Main; 16 import org.openstreetmap.josm.testutils.annotations.Projection; 15 17 16 18 /** 17 19 * Tests how fast {@link MapCSSStyleSource} finds the right style candidates for one object. 18 20 * @author Michael Zangl 19 21 */ 20 @Timeout(value = 15, unit = TimeUnit.MINUTES) 22 @Main 23 @Projection 24 @Timeout(value = 5, unit = TimeUnit.MINUTES) 21 25 class MapCSSStyleSourceFilterTest { 22 26 23 27 private static final int TEST_RULE_COUNT = 10000; … … 80 84 81 85 private static final int APPLY_CALLS = 100000; 82 86 83 /**84 * Prepare the test.85 */86 @BeforeAll87 public static void createJOSMFixture() {88 JOSMFixture.createPerformanceTestFixture().init(true);89 }90 91 87 /** 92 88 * Time how long it takes to evaluate [key=value] rules 93 89 */ -
core/test/unit/org/openstreetmap/josm/data/oauth/OAuth20AuthorizationTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/data/oauth/OAuth20AuthorizationTest.java b/core/test/unit/org/openstreetmap/josm/data/oauth/OAuth20AuthorizationTest.java
a b 185 185 final OAuth20Authorization authorization = new OAuth20Authorization(); 186 186 OAuth20Parameters parameters = (OAuth20Parameters) OAuthParameters.createDefault(OsmApi.getOsmApi().getBaseUrl(), OAuthVersion.OAuth20); 187 187 RemoteControl.start(); 188 authorization.authorize(new OAuth20Parameters( parameters.getClientId(), parameters.getClientSecret(),188 authorization.authorize(new OAuth20Parameters(CLIENT_ID_VALUE, parameters.getClientSecret(), 189 189 wireMockRuntimeInfo.getHttpBaseUrl() + "/oauth2", wireMockRuntimeInfo.getHttpBaseUrl() + "/api", 190 190 parameters.getRedirectUri()), consumer::set, OsmScopes.read_gpx); 191 191 assertEquals(1, OpenBrowserMocker.getCalledURIs().size()); -
core/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java b/core/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java
a b 5 5 import static org.junit.jupiter.api.Assertions.assertNotEquals; 6 6 import static org.junit.jupiter.api.Assertions.assertNotNull; 7 7 8 import java.util.Collections; 9 import java.util.List; 10 8 11 import org.junit.jupiter.api.extension.RegisterExtension; 9 12 import org.junit.jupiter.api.Test; 13 import org.junit.jupiter.params.ParameterizedTest; 14 import org.junit.jupiter.params.provider.MethodSource; 10 15 import org.openstreetmap.josm.TestUtils; 11 16 import org.openstreetmap.josm.spi.preferences.Config; 12 17 import org.openstreetmap.josm.testutils.JOSMTestRules; … … 19 24 * Unit tests for class {@link OAuthParameters}. 20 25 */ 21 26 class OAuthParametersTest { 22 23 /**24 * Setup test.25 */26 @RegisterExtension27 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")28 public JOSMTestRules test = new JOSMTestRules();29 30 27 /** 31 28 * Unit test of method {@link OAuthParameters#createDefault}. 32 29 */ 33 30 @Test 34 31 @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") 35 32 void testCreateDefault() { 36 OAuthParameters def = OAuthParameters.createDefault();33 IOAuthParameters def = OAuthParameters.createDefault(); 37 34 assertNotNull(def); 38 assertEquals(def, OAuthParameters.createDefault(Config.getUrls().getDefaultOsmApiUrl() ));39 OAuthParameters dev = OAuthParameters.createDefault("https://api06.dev.openstreetmap.org/api");35 assertEquals(def, OAuthParameters.createDefault(Config.getUrls().getDefaultOsmApiUrl(), OAuthVersion.OAuth20)); 36 IOAuthParameters dev = OAuthParameters.createDefault("https://api06.dev.openstreetmap.org/api", OAuthVersion.OAuth20); 40 37 assertNotNull(dev); 41 38 assertNotEquals(def, dev); 42 39 Logging.setLogLevel(Logging.LEVEL_TRACE); // enable trace for line coverage 43 assertEquals(def, OAuthParameters.createDefault("wrong_url")); 44 OAuthParameters dev2 = new OAuthParameters(dev); 45 assertEquals(dev, dev2); 40 assertEquals(def, OAuthParameters.createDefault("wrong_url", OAuthVersion.OAuth20)); 41 } 42 43 static List<Class<? extends IOAuthParameters>> testEqualsContract() { 44 return Collections.singletonList(OAuth20Parameters.class); 46 45 } 47 46 48 47 /** 49 48 * Unit test of methods {@link OAuthParameters#equals} and {@link OAuthParameters#hashCode}. 50 49 */ 51 @Test 52 void testEqualsContract() { 50 @ParameterizedTest 51 @MethodSource 52 void testEqualsContract(Class<? extends IOAuthParameters> clazz) { 53 53 TestUtils.assumeWorkingEqualsVerifier(); 54 EqualsVerifier.forClass( OAuthParameters.class).usingGetClass().verify();54 EqualsVerifier.forClass(clazz).usingGetClass().verify(); 55 55 } 56 56 } -
deleted file core/test/unit/org/openstreetmap/josm/data/oauth/OAuthTokenTest.java
diff --git a/core/test/unit/org/openstreetmap/josm/data/oauth/OAuthTokenTest.java b/core/test/unit/org/openstreetmap/josm/data/oauth/OAuthTokenTest.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.data.oauth;3 4 import static org.junit.jupiter.api.Assertions.assertEquals;5 import static org.junit.jupiter.api.Assertions.assertNotNull;6 7 import org.junit.jupiter.api.Test;8 import org.openstreetmap.josm.TestUtils;9 10 import nl.jqno.equalsverifier.EqualsVerifier;11 import oauth.signpost.OAuthConsumer;12 13 /**14 * Unit tests for class {@link OAuthToken}.15 */16 class OAuthTokenTest {17 18 /**19 * Unit test of method {@link OAuthToken#createToken}.20 */21 @Test22 void testCreateToken() {23 OAuthConsumer defCon = OAuthParameters.createDefault().buildConsumer();24 assertNotNull(defCon);25 OAuthToken defTok = OAuthToken.createToken(defCon);26 assertNotNull(defTok);27 assertEquals(defCon.getToken(), defTok.getKey());28 assertEquals(defCon.getTokenSecret(), defTok.getSecret());29 assertEquals(defTok, new OAuthToken(defTok));30 }31 32 /**33 * Unit test of methods {@link OAuthToken#equals} and {@link OAuthToken#hashCode}.34 */35 @Test36 void testEqualsContract() {37 TestUtils.assumeWorkingEqualsVerifier();38 EqualsVerifier.forClass(OAuthToken.class).usingGetClass().verify();39 }40 } -
deleted file core/test/unit/org/openstreetmap/josm/data/oauth/SignpostAdaptersTest.java
diff --git a/core/test/unit/org/openstreetmap/josm/data/oauth/SignpostAdaptersTest.java b/core/test/unit/org/openstreetmap/josm/data/oauth/SignpostAdaptersTest.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.data.oauth;3 4 import static org.junit.jupiter.api.Assertions.assertEquals;5 import static org.junit.jupiter.api.Assertions.assertNotNull;6 import static org.junit.jupiter.api.Assertions.assertNull;7 import static org.junit.jupiter.api.Assertions.assertThrows;8 9 import java.io.IOException;10 import java.net.MalformedURLException;11 import java.net.URL;12 13 import org.junit.jupiter.api.Test;14 import org.junit.jupiter.api.extension.RegisterExtension;15 import org.openstreetmap.josm.data.oauth.SignpostAdapters.HttpRequest;16 import org.openstreetmap.josm.data.oauth.SignpostAdapters.HttpResponse;17 import org.openstreetmap.josm.data.oauth.SignpostAdapters.OAuthConsumer;18 import org.openstreetmap.josm.testutils.JOSMTestRules;19 import org.openstreetmap.josm.tools.HttpClient;20 21 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;22 import net.trajano.commons.testing.UtilityClassTestUtil;23 24 /**25 * Unit tests for class {@link SignpostAdapters}.26 */27 class SignpostAdaptersTest {28 29 /**30 * Setup test.31 */32 @RegisterExtension33 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")34 public JOSMTestRules test = new JOSMTestRules().https();35 36 private static HttpClient newClient() throws MalformedURLException {37 return HttpClient.create(new URL("https://www.openstreetmap.org"));38 }39 40 /**41 * Tests that {@code SignpostAdapters} satisfies utility class criteria.42 * @throws ReflectiveOperationException if an error occurs43 */44 @Test45 void testUtilityClass() throws ReflectiveOperationException {46 UtilityClassTestUtil.assertUtilityClassWellDefined(SignpostAdapters.class);47 }48 49 /**50 * Unit test of method {@link SignpostAdapters.OAuthConsumer#wrap}.51 * @throws MalformedURLException never52 */53 @Test54 void testOAuthConsumerWrap() throws MalformedURLException {55 assertNotNull(new OAuthConsumer("", "").wrap(newClient()));56 }57 58 /**59 * Unit test of method {@link SignpostAdapters.HttpRequest#getMessagePayload}.60 * @throws IOException never61 */62 @Test63 void testHttpRequestGetMessagePayload() throws IOException {64 assertNull(new HttpRequest(newClient()).getMessagePayload());65 }66 67 /**68 * Unit test of method {@link SignpostAdapters.HttpRequest#setRequestUrl}.69 */70 @Test71 void testHttpRequestSetRequestUrl() {72 assertThrows(IllegalStateException.class, () -> new HttpRequest(newClient()).setRequestUrl(null));73 }74 75 /**76 * Unit test of method {@link SignpostAdapters.HttpRequest#getAllHeaders}.77 */78 @Test79 void testHttpRequestGetAllHeaders() {80 assertThrows(IllegalStateException.class, () -> new HttpRequest(newClient()).getAllHeaders());81 }82 83 /**84 * Unit test of method {@link SignpostAdapters.HttpRequest#unwrap}.85 */86 @Test87 void testHttpRequestUnwrap() {88 assertThrows(IllegalStateException.class, () -> new HttpRequest(newClient()).unwrap());89 }90 91 /**92 * Unit test of method {@link SignpostAdapters.HttpResponse#getReasonPhrase()}.93 * @throws Exception never94 */95 @Test96 void testHttpResponseGetReasonPhrase() throws Exception {97 assertEquals("OK", new HttpResponse(new HttpRequest(newClient()).request.connect()).getReasonPhrase());98 }99 100 /**101 * Unit test of method {@link SignpostAdapters.HttpResponse#unwrap}.102 */103 @Test104 void testHttpResponseUnwrap() {105 assertThrows(IllegalStateException.class, () -> new HttpResponse(new HttpRequest(newClient()).request.connect()).unwrap());106 }107 } -
core/test/unit/org/openstreetmap/josm/gui/io/importexport/OsmPbfImporterTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/gui/io/importexport/OsmPbfImporterTest.java b/core/test/unit/org/openstreetmap/josm/gui/io/importexport/OsmPbfImporterTest.java
a b 18 18 19 19 import org.junit.jupiter.api.BeforeAll; 20 20 import org.junit.jupiter.api.Test; 21 import org.junit.jupiter.params.ParameterizedTest;22 import org.junit.jupiter.params.provider.ValueSource;23 21 import org.openstreetmap.josm.TestUtils; 24 22 import org.openstreetmap.josm.data.coor.ILatLon; 25 23 import org.openstreetmap.josm.data.coor.LatLon; -
core/test/unit/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTaskTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTaskTest.java b/core/test/unit/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTaskTest.java
a b 5 5 import static org.junit.jupiter.api.Assertions.assertNotNull; 6 6 import static org.junit.jupiter.api.Assertions.assertNull; 7 7 import static org.junit.jupiter.api.Assertions.assertTrue; 8 import static org.junit.jupiter.api.Assumptions.assumeTrue; 8 9 9 10 import java.awt.GraphicsEnvironment; 10 11 import java.net.URL; 11 12 import java.util.Collections; 13 import java.util.HashMap; 14 import java.util.Map; 12 15 13 16 import javax.swing.JOptionPane; 14 17 import javax.swing.JPanel; … … 21 24 import org.openstreetmap.josm.gui.oauth.OAuthAuthorizationWizard; 22 25 import org.openstreetmap.josm.spi.preferences.Config; 23 26 import org.openstreetmap.josm.testutils.JOSMTestRules; 27 import org.openstreetmap.josm.testutils.annotations.BasicPreferences; 28 import org.openstreetmap.josm.testutils.annotations.OsmApi; 24 29 import org.openstreetmap.josm.testutils.mockers.JOptionPaneSimpleMocker; 25 30 import org.openstreetmap.josm.testutils.mockers.WindowMocker; 26 31 import org.openstreetmap.josm.tools.UserCancelException; 32 import org.openstreetmap.josm.tools.Utils; 27 33 28 34 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 35 import jdk.nashorn.internal.scripts.JO; 29 36 import mockit.Invocation; 30 37 import mockit.Mock; 31 38 import mockit.MockUp; … … 33 40 /** 34 41 * Unit tests of {@link DownloadOpenChangesetsTask} class. 35 42 */ 43 @BasicPreferences 44 @OsmApi(OsmApi.APIType.DEV) 36 45 class DownloadOpenChangesetsTaskTest { 37 38 /**39 * Setup tests40 */41 @RegisterExtension42 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")43 public JOSMTestRules test = new JOSMTestRules().preferences().devAPI();44 45 46 /** 46 47 * OAuth wizard mocker. 47 48 */ … … 69 70 } 70 71 } 71 72 72 /**73 * These tests were written with {@link org.openstreetmap.josm.data.oauth.OAuthVersion#OAuth10a} as the default auth method.74 */75 @BeforeEach76 void setup() {77 Config.getPref().put("osm-server.auth-method", "oauth");78 }79 80 73 /** 81 74 * Test of {@link DownloadOpenChangesetsTask} class when anonymous. 82 75 */ … … 86 79 if (GraphicsEnvironment.isHeadless()) { 87 80 new WindowMocker(); 88 81 } 89 final OAuthWizardMocker oaWizardMocker = new OAuthWizardMocker(); 90 final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker( 91 Collections.singletonMap( 92 "<html>Could not retrieve the list of your open changesets because<br>JOSM does not know " 82 final Map<String, Object> optionPaneMock = new HashMap<>(2); 83 optionPaneMock.put("<html>Could not retrieve the list of your open changesets because<br>JOSM does not know " 93 84 + "your identity.<br>You have either chosen to work anonymously or you are not " 94 + "entitled<br>to know the identity of the user on whose behalf you are working.</html>", JOptionPane.OK_OPTION 95 )96 );85 + "entitled<br>to know the identity of the user on whose behalf you are working.</html>", JOptionPane.OK_OPTION); 86 optionPaneMock.put("Obtain OAuth 2.0 token for authentication?", JOptionPane.NO_OPTION); 87 final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(optionPaneMock); 97 88 98 89 DownloadOpenChangesetsTask task = new DownloadOpenChangesetsTask(new JPanel()); 99 90 assertNull(task.getChangesets()); … … 102 93 task.run(); 103 94 assertNull(task.getChangesets()); 104 95 105 assertEquals( 1, jopsMocker.getInvocationLog().size());106 Object[] invocationLogEntry = jopsMocker.getInvocationLog().get( 0);96 assertEquals(2, jopsMocker.getInvocationLog().size()); 97 Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(1); 107 98 assertEquals(JOptionPane.OK_OPTION, (int) invocationLogEntry[0]); 108 99 assertEquals("Missing user identity", invocationLogEntry[2]); 109 100 110 assertTrue(oaWizardMocker.called); 101 invocationLogEntry = jopsMocker.getInvocationLog().get(0); 102 assertEquals(JOptionPane.NO_OPTION, (int) invocationLogEntry[0]); 103 assertEquals("Obtain authentication to OSM servers", invocationLogEntry[2]); 111 104 } 112 105 113 106 /** … … 119 112 if (GraphicsEnvironment.isHeadless()) { 120 113 new WindowMocker(); 121 114 } 122 final OAuthWizardMocker oaWizardMocker = new OAuthWizardMocker();123 final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(124 Collections.singletonMap("There are no open changesets", JOptionPane.OK_OPTION)125 );115 final Map<String, Object> optionPaneMock = new HashMap<>(2); 116 optionPaneMock.put("There are no open changesets", JOptionPane.OK_OPTION); 117 optionPaneMock.put("Obtain OAuth 2.0 token for authentication?", JOptionPane.NO_OPTION); 118 final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(optionPaneMock); 126 119 127 120 DownloadOpenChangesetsTask task = new DownloadOpenChangesetsTask(new JPanel()); 128 121 UserIdentityManager.getInstance().setPartiallyIdentified(System.getProperty("osm.username", "josm_test")); … … 130 123 task.run(); 131 124 assertNotNull(task.getChangesets()); 132 125 133 assertEquals( 1, jopsMocker.getInvocationLog().size());134 Object[] invocationLogEntry = jopsMocker.getInvocationLog().get( 0);126 assertEquals(2, jopsMocker.getInvocationLog().size()); 127 Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(1); 135 128 assertEquals(JOptionPane.OK_OPTION, (int) invocationLogEntry[0]); 136 129 assertEquals("No open changesets", invocationLogEntry[2]); 137 130 138 assertTrue(oaWizardMocker.called); 131 invocationLogEntry = jopsMocker.getInvocationLog().get(0); 132 assertEquals(JOptionPane.NO_OPTION, (int) invocationLogEntry[0]); 133 assertEquals("Obtain authentication to OSM servers", invocationLogEntry[2]); 139 134 } 140 135 } -
core/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java b/core/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java
a b 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.gui.oauth; 3 3 4 import static org.junit.jupiter.api.Assertions.assert NotNull;4 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 5 5 6 import org.junit.jupiter.params.ParameterizedTest; 7 import org.junit.jupiter.params.provider.EnumSource; 8 import org.openstreetmap.josm.data.oauth.OAuthVersion; 6 9 import org.openstreetmap.josm.gui.MainApplication; 7 10 import org.openstreetmap.josm.testutils.annotations.BasicPreferences; 8 11 9 import org.junit.jupiter.api.Test;10 11 12 /** 12 13 * Unit tests of {@link FullyAutomaticAuthorizationUI} class. 13 14 */ … … 16 17 /** 17 18 * Unit test of {@link FullyAutomaticAuthorizationUI#FullyAutomaticAuthorizationUI}. 18 19 */ 19 @Test 20 void testFullyAutomaticAuthorizationUI() { 21 assertNotNull(new FullyAutomaticAuthorizationUI("", MainApplication.worker)); 20 @ParameterizedTest 21 @EnumSource(OAuthVersion.class) 22 void testFullyAutomaticAuthorizationUI(OAuthVersion version) { 23 assertDoesNotThrow(() -> new FullyAutomaticAuthorizationUI("", MainApplication.worker, version)); 22 24 } 23 25 } -
core/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java b/core/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java
a b 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.gui.oauth; 3 3 4 import static org.junit.jupiter.api.Assertions.assert NotNull;4 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 5 5 6 6 import org.junit.jupiter.api.Test; 7 import org.openstreetmap.josm.data.oauth.OAuthVersion; 7 8 import org.openstreetmap.josm.gui.MainApplication; 8 9 import org.openstreetmap.josm.testutils.annotations.BasicPreferences; 9 10 … … 17 18 */ 18 19 @Test 19 20 void testManualAuthorizationUI() { 20 assert NotNull(new ManualAuthorizationUI("", MainApplication.worker));21 assertDoesNotThrow(() -> new ManualAuthorizationUI("", MainApplication.worker, OAuthVersion.OAuth20)); 21 22 } 22 23 } -
deleted file core/test/unit/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClientTest.java
diff --git a/core/test/unit/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClientTest.java b/core/test/unit/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClientTest.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.oauth;3 4 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;5 import static com.github.tomakehurst.wiremock.client.WireMock.get;6 import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;7 import static org.junit.jupiter.api.Assertions.assertEquals;8 import static org.junit.jupiter.api.Assertions.assertNotNull;9 import static org.junit.jupiter.api.Assertions.assertNull;10 11 import java.net.CookieHandler;12 import java.net.CookieManager;13 import java.net.URI;14 import java.util.Collections;15 16 import org.junit.jupiter.api.Test;17 import org.junit.jupiter.api.Timeout;18 import org.openstreetmap.josm.data.oauth.OAuthParameters;19 import org.openstreetmap.josm.data.oauth.OAuthToken;20 import org.openstreetmap.josm.io.OsmTransferCanceledException;21 import org.openstreetmap.josm.testutils.annotations.BasicPreferences;22 import org.openstreetmap.josm.testutils.annotations.BasicWiremock;23 import org.openstreetmap.josm.testutils.annotations.HTTP;24 25 import com.github.tomakehurst.wiremock.WireMockServer;26 27 /**28 * Unit tests of {@link OsmOAuthAuthorizationClient} class.29 */30 @Timeout(20)31 @BasicWiremock32 // Needed for OAuthParameters33 @BasicPreferences34 @HTTP35 class OsmOAuthAuthorizationClientTest {36 /**37 * HTTP mock.38 */39 @BasicWiremock40 WireMockServer wireMockServer;41 42 /**43 * Unit test of {@link OsmOAuthAuthorizationClient}.44 * @throws OsmOAuthAuthorizationException if OAuth authorization error occurs45 * @throws OsmTransferCanceledException if OSM transfer error occurs46 */47 @Test48 void testOsmOAuthAuthorizationClient() throws OsmTransferCanceledException, OsmOAuthAuthorizationException {49 // request token50 wireMockServer.stubFor(get(urlEqualTo("/oauth/request_token"))51 .willReturn(aResponse().withStatus(200).withBody(String.join("&",52 "oauth_token=entxUGuwRKV6KyVDF0OWScdGhbqXGMGmosXuiChR",53 "oauth_token_secret=nsBD2Hr5lLGDUeNoh3SnLaGsUV1TiPYM4qUr7tPB"))));54 OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(OAuthParameters.createDefault(55 wireMockServer.url("/api")));56 57 OAuthToken requestToken = client.getRequestToken(null);58 assertEquals("entxUGuwRKV6KyVDF0OWScdGhbqXGMGmosXuiChR", requestToken.getKey(), "requestToken.key");59 assertEquals("nsBD2Hr5lLGDUeNoh3SnLaGsUV1TiPYM4qUr7tPB", requestToken.getSecret(), "requestToken.secret");60 String url = client.getAuthoriseUrl(requestToken);61 assertEquals(wireMockServer.url("/oauth/authorize?oauth_token=entxUGuwRKV6KyVDF0OWScdGhbqXGMGmosXuiChR"), url, "url");62 63 // access token64 wireMockServer.stubFor(get(urlEqualTo("/oauth/access_token"))65 .willReturn(aResponse().withStatus(200).withBody(String.join("&",66 "oauth_token=eGMGmosXuiChRntxUGuwRKV6KyVDF0OWScdGhbqX",67 "oauth_token_secret=nsBUeNor7tPh3SHr5lLaGsGDUD2PYMV1TinL4qUB"))));68 69 OAuthToken accessToken = client.getAccessToken(null);70 assertEquals("eGMGmosXuiChRntxUGuwRKV6KyVDF0OWScdGhbqX", accessToken.getKey(), "accessToken.key");71 assertEquals("nsBUeNor7tPh3SHr5lLaGsGDUD2PYMV1TinL4qUB", accessToken.getSecret(), "accessToken.secret");72 }73 74 /**75 * Unit test for correct cookie handling when logging in to the OSM website.76 *77 * https://josm.openstreetmap.de/ticket/1258478 * @throws Exception if any error occurs79 */80 @Test81 void testCookieHandlingMock() throws Exception {82 wireMockServer.stubFor(get(urlEqualTo("/login?cookie_test=true"))83 .willReturn(aResponse()84 .withStatus(200)85 .withHeader("Set-Cookie", "_osm_session=7fe8e2ea36c6b803cb902301b28e0a; path=/; HttpOnly; SameSite=Lax")86 .withBody("<input type=\"hidden\" " +87 "name=\"authenticity_token\" " +88 "value=\"fzp6CWJhp6Vns09re3s2Tw==\" />")));89 final OAuthParameters parameters = OAuthParameters.createDefault(wireMockServer.url("/api"));90 final OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(parameters);91 final OsmOAuthAuthorizationClient.SessionId sessionId = client.fetchOsmWebsiteSessionId();92 assertNotNull(sessionId);93 assertEquals("7fe8e2ea36c6b803cb902301b28e0a", sessionId.id, "sessionId.id");94 assertEquals("fzp6CWJhp6Vns09re3s2Tw==", sessionId.token, "sessionId.token");95 assertNull(sessionId.userName, "sessionId.userName");96 }97 98 /**99 * Unit test for correct cookie handling when logging in to the OSM website.100 *101 * https://josm.openstreetmap.de/ticket/12584102 * @throws Exception if any error occurs103 */104 @Test105 void testCookieHandlingCookieManager() throws Exception {106 // emulate Java Web Start behaviour107 // see https://docs.oracle.com/javase/tutorial/deployment/doingMoreWithRIA/accessingCookies.html108 final OAuthParameters parameters = OAuthParameters.createDefault();109 final OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(parameters);110 final CookieManager cm = new CookieManager();111 cm.put(new URI(parameters.getOsmLoginUrl()),112 Collections.singletonMap("Cookie", Collections.singletonList("_osm_session=" + String.valueOf(Math.PI).substring(2))));113 CookieHandler.setDefault(cm);114 assertNotNull(client.fetchOsmWebsiteSessionId());115 }116 } -
deleted file core/test/unit/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUITest.java
diff --git a/core/test/unit/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUITest.java b/core/test/unit/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUITest.java deleted file mode 100644
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.oauth;3 4 import static org.junit.jupiter.api.Assertions.assertNotNull;5 6 import org.junit.jupiter.api.Test;7 import org.openstreetmap.josm.gui.MainApplication;8 import org.openstreetmap.josm.testutils.annotations.BasicPreferences;9 10 /**11 * Unit tests of {@link SemiAutomaticAuthorizationUI} class.12 */13 @BasicPreferences14 class SemiAutomaticAuthorizationUITest {15 /**16 * Unit test of {@link SemiAutomaticAuthorizationUI#SemiAutomaticAuthorizationUI}.17 */18 @Test19 void testSemiAutomaticAuthorizationUI() {20 assertNotNull(new SemiAutomaticAuthorizationUI("", MainApplication.worker));21 }22 } -
core/test/unit/org/openstreetmap/josm/gui/preferences/display/GPXPreferenceTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/gui/preferences/display/GPXPreferenceTest.java b/core/test/unit/org/openstreetmap/josm/gui/preferences/display/GPXPreferenceTest.java
a b 3 3 4 4 import static org.junit.jupiter.api.Assertions.assertNotNull; 5 5 6 import org.junit.jupiter.api.BeforeAll;7 6 import org.junit.jupiter.api.Test; 8 import org.openstreetmap.josm.JOSMFixture;9 7 import org.openstreetmap.josm.gui.preferences.PreferencesTestUtils; 8 import org.openstreetmap.josm.testutils.annotations.BasicPreferences; 10 9 11 10 /** 12 11 * Unit tests of {@link GPXPreference} class. 13 12 */ 13 @BasicPreferences 14 14 class GPXPreferenceTest { 15 16 /**17 * Setup test.18 */19 @BeforeAll20 public static void setUpBeforeClass() {21 JOSMFixture.createUnitTestFixture().init();22 }23 24 15 /** 25 16 * Unit test of {@link GPXPreference.Factory}. 26 17 */ -
core/test/unit/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanelTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanelTest.java b/core/test/unit/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanelTest.java
a b 20 20 import org.junit.jupiter.api.AfterEach; 21 21 import org.junit.jupiter.params.ParameterizedTest; 22 22 import org.junit.jupiter.params.provider.EnumSource; 23 import org.openstreetmap.josm.data.oauth.IOAuthToken;24 23 import org.openstreetmap.josm.data.oauth.OAuth20Exception; 25 24 import org.openstreetmap.josm.data.oauth.OAuth20Parameters; 26 25 import org.openstreetmap.josm.data.oauth.OAuth20Token; 27 26 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder; 28 import org.openstreetmap.josm.data.oauth.OAuthToken;29 27 import org.openstreetmap.josm.data.oauth.OAuthVersion; 30 28 import org.openstreetmap.josm.io.OsmApi; 31 29 import org.openstreetmap.josm.io.auth.CredentialsAgentException; … … 46 44 } 47 45 List<Exception> exceptionList = new ArrayList<>(); 48 46 try { 49 CredentialsManager.getInstance().storeOAuthAccessToken( null);47 CredentialsManager.getInstance().storeOAuthAccessToken(OsmApi.getOsmApi().getServerUrl(), null); 50 48 } catch (CredentialsAgentException exception) { 51 49 exceptionList.add(exception); 52 50 } … … 60 58 } 61 59 62 60 @ParameterizedTest 63 @EnumSource(value = OAuthVersion.class, names = {"OAuth 10a", "OAuth20"})61 @EnumSource(value = OAuthVersion.class, names = {"OAuth20"}) 64 62 void testRemoveToken(OAuthVersion oAuthVersion) throws ReflectiveOperationException, CredentialsAgentException, OAuth20Exception { 65 63 final OAuthAuthenticationPreferencesPanel panel = new OAuthAuthenticationPreferencesPanel(oAuthVersion); 66 64 final Field pnlNotYetAuthorised = OAuthAuthenticationPreferencesPanel.class.getDeclaredField("pnlNotYetAuthorised"); … … 75 73 panel.initFromPreferences(); 76 74 assertSame(pnlAlreadyAuthorised.get(panel), holder.getComponent(0), "Authentication should now be set"); 77 75 assertNotNull(getAuthorization(oAuthVersion)); 78 final JPanel buttons = (JPanel) ((JPanel) pnlAlreadyAuthorised.get(panel)).getComponent( 6);79 final JButton action = (JButton) buttons.getComponent( oAuthVersion == OAuthVersion.OAuth10a ? 2 : 1);76 final JPanel buttons = (JPanel) ((JPanel) pnlAlreadyAuthorised.get(panel)).getComponent(5); 77 final JButton action = (JButton) buttons.getComponent(2); 80 78 assertEquals(tr("Remove token"), action.getText(), "The selected button should be for removing the token"); 81 79 action.getAction().actionPerformed(null); 82 80 panel.saveToPreferences(); // Save to preferences should make the removal permanent … … 96 94 */ 97 95 private static void addAuthorization(OAuthVersion oAuthVersion) throws CredentialsAgentException, OAuth20Exception { 98 96 switch (oAuthVersion) { 99 case OAuth10a:100 CredentialsManager.getInstance().storeOAuthAccessToken(new OAuthToken("fake_key", "fake_secret"));101 break;102 97 case OAuth20: 103 98 case OAuth21: 104 99 CredentialsManager.getInstance().storeOAuthAccessToken(OsmApi.getOsmApi().getHost(), … … 116 111 */ 117 112 private static Object getAuthorization(OAuthVersion oAuthVersion) { 118 113 OAuthAccessTokenHolder.getInstance().clear(); 119 OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().get Host(), (IOAuthToken)null);114 OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().getServerUrl(), null); 120 115 OAuthAccessTokenHolder.getInstance().init(CredentialsManager.getInstance()); 121 116 // Ensure that we are not saving authorization data 122 switch (oAuthVersion) { 123 case OAuth10a: 124 return OAuthAccessTokenHolder.getInstance().getAccessToken(); 125 case OAuth20: 126 case OAuth21: 127 return OAuthAccessTokenHolder.getInstance().getAccessToken(OsmApi.getOsmApi().getHost(), oAuthVersion); 128 default: 129 throw new AssertionError("OAuth version not understood"); 130 } 117 return OAuthAccessTokenHolder.getInstance().getAccessToken(OsmApi.getOsmApi().getServerUrl(), oAuthVersion); 131 118 } 132 119 } -
core/test/unit/org/openstreetmap/josm/io/auth/CredentialsAgentTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/io/auth/CredentialsAgentTest.java b/core/test/unit/org/openstreetmap/josm/io/auth/CredentialsAgentTest.java
a b 18 18 import org.openstreetmap.josm.data.oauth.OAuth20Exception; 19 19 import org.openstreetmap.josm.data.oauth.OAuth20Parameters; 20 20 import org.openstreetmap.josm.data.oauth.OAuth20Token; 21 import org.openstreetmap.josm.data.oauth.OAuthToken;22 21 import org.openstreetmap.josm.io.OsmApi; 23 22 import org.openstreetmap.josm.testutils.annotations.BasicPreferences; 24 23 … … 75 74 assertNull(agent.lookup(null, null)); 76 75 } 77 76 78 @Test79 default void testLookUpAndStoreOAuth10() throws CredentialsAgentException {80 final T agent = createAgent();81 assertNull(agent.lookupOAuthAccessToken());82 final OAuthToken token = new OAuthToken("foo", "bar");83 agent.storeOAuthAccessToken(token);84 final OAuthToken actual = agent.lookupOAuthAccessToken();85 assertEquals(token, actual);86 agent.storeOAuthAccessToken(null);87 assertNull(agent.lookupOAuthAccessToken());88 }89 90 77 @ParameterizedTest 91 78 @MethodSource("getHosts") 92 79 default void testLookupAndStoreOAuthTokens(final String host) throws CredentialsAgentException, OAuth20Exception { -
core/test/unit/org/openstreetmap/josm/testutils/annotations/BasicPreferences.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/testutils/annotations/BasicPreferences.java b/core/test/unit/org/openstreetmap/josm/testutils/annotations/BasicPreferences.java
a b 54 54 public void afterEach(ExtensionContext context) throws Exception { 55 55 if (AnnotationSupport.isAnnotated(context.getElement(), BasicPreferences.class)) { 56 56 this.afterAll(context); 57 if (AnnotationSupport.isAnnotated(context.getTestClass(), BasicPreferences.class)) { 58 this.beforeAll(context); 59 } 57 60 } 58 61 } 59 62 -
core/test/unit/org/openstreetmap/josm/testutils/annotations/TestUser.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/testutils/annotations/TestUser.java b/core/test/unit/org/openstreetmap/josm/testutils/annotations/TestUser.java
a b 18 18 import org.junit.jupiter.api.extension.ExtensionContext; 19 19 import org.openstreetmap.josm.TestUtils; 20 20 import org.openstreetmap.josm.data.UserIdentityManager; 21 import org.openstreetmap.josm.data.oauth.OAuth20Token; 22 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder; 23 import org.openstreetmap.josm.data.oauth.OAuthParameters; 24 import org.openstreetmap.josm.data.osm.User; 21 25 import org.openstreetmap.josm.io.auth.CredentialsManager; 22 26 import org.openstreetmap.josm.spi.preferences.Config; 23 27 import org.openstreetmap.josm.tools.Utils; … … 47 51 @Override 48 52 public void beforeEach(ExtensionContext context) throws Exception { 49 53 assumeTrue(TestUtils.areCredentialsProvided(), 50 "OSM DEV API credentials not provided. Please define them with -Dosm.username and -Dosm.password"); 51 final String username = Utils.getSystemProperty("osm.username"); 52 final String password = Utils.getSystemProperty("osm.password"); 53 assumeTrue(username != null && !username.isEmpty(), "Please add -Dosm.username for the OSM DEV API"); 54 assumeTrue(password != null && !password.isEmpty(), "Please add -Dosm.password for the OSM DEV API"); 55 Config.getPref().put("osm-server.auth-method", "basic"); 54 "OSM DEV API credentials not provided. Please define them with -Dosm.oauth2"); 55 final String oauth2 = Utils.getSystemProperty("osm.oauth2"); 56 Config.getPref().put("osm-server.auth-method", "oauth20"); 56 57 57 58 // don't use atomic upload, the test API server can't cope with large diff uploads 58 59 Config.getPref().putBoolean("osm-server.atomic-upload", false); 59 CredentialsManager.getInstance().store(Authenticator.RequestorType.SERVER, org.openstreetmap.josm.io.OsmApi.getOsmApi().getHost(), 60 new PasswordAuthentication(username, password.toCharArray())); 60 final String serverUrl = org.openstreetmap.josm.io.OsmApi.getOsmApi().getServerUrl(); 61 final OAuth20Token token = new OAuth20Token(OAuthParameters.createDefault(), "{\"token_type\":\"bearer\", \"access_token\": \"" + oauth2 + "\"}"); 62 OAuthAccessTokenHolder.getInstance().setAccessToken(serverUrl, token); 63 CredentialsManager.getInstance().storeOAuthAccessToken(serverUrl, token); 64 if (!UserIdentityManager.getInstance().isFullyIdentified()) { 65 UserIdentityManager.getInstance().initFromOAuth(); 66 } 61 67 } 62 68 } 63 69 } -
core/test/unit/org/openstreetmap/josm/testutils/FakeOsmApi.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/testutils/FakeOsmApi.java b/core/test/unit/org/openstreetmap/josm/testutils/FakeOsmApi.java
a b 109 109 110 110 /** 111 111 * Gets and caches an instance of this API. 112 * @return The API in tance. Always the same object.112 * @return The API instance. Always the same object. 113 113 */ 114 114 public static synchronized FakeOsmApi getInstance() { 115 115 if (instance == null) { 116 116 instance = new FakeOsmApi(); 117 cacheInstance(instance);118 }117 } 118 cacheInstance(instance); 119 119 return instance; 120 120 } 121 121 } -
core/test/unit/org/openstreetmap/josm/tools/date/DateUtilsTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/tools/date/DateUtilsTest.java b/core/test/unit/org/openstreetmap/josm/tools/date/DateUtilsTest.java
a b 24 24 import org.junit.jupiter.params.ParameterizedTest; 25 25 import org.junit.jupiter.params.provider.ValueSource; 26 26 import org.openstreetmap.josm.testutils.JOSMTestRules; 27 import org.openstreetmap.josm.testutils.annotations.I18n; 27 28 import org.openstreetmap.josm.tools.UncheckedParseException; 28 29 29 30 /** 30 31 * Unit tests of {@link DateUtils} class. 31 32 */ 33 @I18n 32 34 public class DateUtilsTest { 33 34 /**35 * Set the timezone and timeout.36 * <p>37 * Timeouts need to be disabled because we change the time zone.38 */39 @RegisterExtension40 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")41 public JOSMTestRules test = new JOSMTestRules().i18n().preferences();42 43 35 /** 44 36 * Tests that {@code DateUtils} satisfies utility class criteria. 45 37 * @throws ReflectiveOperationException if an error occurs -
core/test/unit/org/openstreetmap/josm/TestUtils.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/test/unit/org/openstreetmap/josm/TestUtils.java b/core/test/unit/org/openstreetmap/josm/TestUtils.java
a b 658 658 659 659 /** 660 660 * Determines if OSM DEV_API credential have been provided. Required for functional tests. 661 * @return {@code true} if {@code osm. username} and {@code osm.password} have been defined on the command line661 * @return {@code true} if {@code osm.oauth2} have been defined on the command line 662 662 */ 663 663 public static boolean areCredentialsProvided() { 664 return Utils.getSystemProperty("osm. username") != null && Utils.getSystemProperty("osm.password") != null;664 return Utils.getSystemProperty("osm.oauth2") != null; 665 665 } 666 666 667 667 /** -
core/ivy.xml
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/core/ivy.xml b/core/ivy.xml
a b 35 35 <dependency conf="api->default" org="com.drewnoakes" name="metadata-extractor" rev="2.18.0" transitive="false"/> 36 36 <dependency conf="api->default" org="com.formdev" name="svgSalamander" rev="1.1.4"/> 37 37 <dependency conf="api->default" org="ch.poole" name="OpeningHoursParser" rev="0.27.0"/> 38 <dependency conf="api->default" org="oauth.signpost" name="signpost-core" rev="2.1.1"/>39 38 <!-- Don't forget to update org.openstreetmap.josm.tools.Tag2Link#PREF_SOURCE --> 40 39 <dependency conf="api->default" org="org.webjars.npm" name="tag2link" rev="2022.11.28"/> 41 40 <!-- sources->sources --> … … 52 51 <dependency conf="sources->sources" org="com.drewnoakes" name="metadata-extractor" rev="2.18.0" transitive="false"/> 53 52 <dependency conf="sources->sources" org="com.formdev" name="svgSalamander" rev="1.1.4"/> 54 53 <dependency conf="sources->sources" org="ch.poole" name="OpeningHoursParser" rev="0.27.0"/> 55 <dependency conf="sources->sources" org="oauth.signpost" name="signpost-core" rev="2.1.1"/>56 54 <dependency conf="sources->default" org="org.webjars.npm" name="tag2link" rev="2022.11.28"/><!-- sources->default sic! (tag2link-sources.jar is empty, see #19335) --> 57 55 <!-- commonslang->default --> 58 56 <dependency conf="commonslang->default" org="org.apache.commons" name="commons-lang3" rev="3.13.0"/> -
plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/InitializationWizard.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/InitializationWizard.java b/plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/InitializationWizard.java
a b 40 40 import javax.swing.border.EtchedBorder; 41 41 42 42 import org.netbeans.spi.keyring.KeyringProvider; 43 import org.openstreetmap.josm.data.oauth.OAuthToken;44 43 import org.openstreetmap.josm.gui.MainApplication; 45 44 import org.openstreetmap.josm.gui.util.WindowGeometry; 46 45 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 47 46 import org.openstreetmap.josm.io.DefaultProxySelector; 48 import org.openstreetmap.josm.io.OsmApi;49 47 import org.openstreetmap.josm.io.auth.CredentialsAgentException; 50 48 import org.openstreetmap.josm.io.auth.CredentialsManager; 51 49 import org.openstreetmap.josm.spi.preferences.Config; … … 55 53 56 54 public class InitializationWizard extends JDialog { 57 55 58 protected boolean canceled = false;56 protected boolean canceled; 59 57 protected JButton btnCancel, btnBack, btnNext; 60 58 protected Action nextAction, finishAction; 61 59 protected JPanel cardPanel; … … 66 64 private CardLayout cardLayout; 67 65 68 66 public InitializationWizard() { 69 super(JOptionPane.getFrameForComponent(MainApplication.getMainFrame()), tr("Native password manager plugin"), ModalityType.DOCUMENT_MODAL); 67 super(JOptionPane.getFrameForComponent(MainApplication.getMainFrame()), 68 tr("Native password manager plugin"), ModalityType.DOCUMENT_MODAL); 70 69 build(); 71 70 NPMType npm = detectNativePasswordManager(); 72 71 WizardPanel firstPanel; … … 145 144 /* The action to execute, when the user finall hits 'OK' and not 'Cancel' */ 146 145 void onOkAction(); 147 146 } 148 149 abstract privatestatic class AbstractWizardPanel implements WizardPanel {147 148 private abstract static class AbstractWizardPanel implements WizardPanel { 150 149 151 150 /** 152 151 * Put a logo to the left, as is customary for wizard dialogs … … 174 173 return getClass().getCanonicalName(); 175 174 } 176 175 177 abstract protectedJPanel getContentPanel();176 protected abstract JPanel getContentPanel(); 178 177 } 179 178 180 179 private static class NothingFoundPanel extends AbstractWizardPanel { … … 228 227 229 228 private static class SelectionPanel extends AbstractWizardPanel implements ActionListener { 230 229 231 private NPMType type;232 private InitializationWizard wizard;230 private final NPMType type; 231 private final InitializationWizard wizard; 233 232 234 233 private JRadioButton rbManage, rbPlain; 235 234 … … 349 348 public void onOkAction() { 350 349 351 350 CredentialsManager cm = CredentialsManager.getInstance(); 352 353 String server_username = Config.getPref().get("osm-server.username", null); 354 String server_password = Config.getPref().get("osm-server.password", null); 355 if (server_username != null || server_password != null) { 356 try { 357 cm.store(RequestorType.SERVER, OsmApi.getOsmApi().getHost(), new PasswordAuthentication(string(server_username), toCharArray(server_password))); 358 if (rbClear.isSelected()) { 359 Config.getPref().put("osm-server.username", null); 360 Config.getPref().put("osm-server.password", null); 361 } 362 } catch (CredentialsAgentException ex) { 363 Logging.error(ex); 364 } 365 } 366 367 String proxy_username = Config.getPref().get(DefaultProxySelector.PROXY_USER, null); 368 String proxy_password = Config.getPref().get(DefaultProxySelector.PROXY_PASS, null); 369 String proxy_host = Config.getPref().get(DefaultProxySelector.PROXY_HTTP_HOST, null); 370 if (proxy_username != null || proxy_password != null) { 351 352 String proxyUsername = Config.getPref().get(DefaultProxySelector.PROXY_USER, null); 353 String proxyPassword = Config.getPref().get(DefaultProxySelector.PROXY_PASS, null); 354 String proxyHost = Config.getPref().get(DefaultProxySelector.PROXY_HTTP_HOST, null); 355 if (proxyUsername != null || proxyPassword != null) { 371 356 try { 372 cm.store(RequestorType.PROXY, proxy _host, new PasswordAuthentication(string(proxy_username), toCharArray(proxy_password)));357 cm.store(RequestorType.PROXY, proxyHost, new PasswordAuthentication(string(proxyUsername), toCharArray(proxyPassword))); 373 358 if (rbClear.isSelected()) { 374 359 Config.getPref().put(DefaultProxySelector.PROXY_USER, null); 375 360 Config.getPref().put(DefaultProxySelector.PROXY_PASS, null); … … 378 363 Logging.error(ex); 379 364 } 380 365 } 381 382 String oauth_key = Config.getPref().get("oauth.access-token.key", null);383 String oauth_secret = Config.getPref().get("oauth.access-token.secret", null);384 if (oauth_key != null || oauth_secret != null) {385 try {386 cm.storeOAuthAccessToken(new OAuthToken(string(oauth_key), string(oauth_secret)));387 if (rbClear.isSelected()) {388 Config.getPref().put("oauth.access-token.key", null);389 Config.getPref().put("oauth.access-token.secret", null);390 }391 } catch (CredentialsAgentException ex) {392 Logging.error(ex);393 }394 }395 366 } 396 367 } 397 368 398 private final staticString NPM = "Native Password Manager Plugin: ";369 private static final String NPM = "Native Password Manager Plugin: "; 399 370 400 371 private static NPMType detectNativePasswordManager() { 401 372 NPMType[] potentialManagers; … … 444 415 new Dimension(600,400) 445 416 ) 446 417 ).applySafe(this); 447 } else if ( !visible &&isShowing()){418 } else if (isShowing()){ 448 419 new WindowGeometry(this).remember(getClass().getName() + ".geometry"); 449 420 } 450 421 super.setVisible(visible); … … 492 463 @Override 493 464 public void actionPerformed(ActionEvent evt) { 494 465 if (panelIndex <= 0) 495 throw new RuntimeException(); 466 // Java 9 will let us pass the panelIndex by itself 467 throw new IndexOutOfBoundsException("Index out of range: " + panelIndex); 496 468 panelIndex--; 497 469 cardLayout.show(cardPanel, panels.get(panelIndex).getId()); 498 470 updateButtons(); -
plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/NPMCredentialsAgent.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/NPMCredentialsAgent.java b/plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/NPMCredentialsAgent.java
a b 24 24 import org.openstreetmap.josm.data.oauth.OAuth20Exception; 25 25 import org.openstreetmap.josm.data.oauth.OAuth20Parameters; 26 26 import org.openstreetmap.josm.data.oauth.OAuth20Token; 27 import org.openstreetmap.josm.data.oauth.OAuthToken;28 27 import org.openstreetmap.josm.data.oauth.OAuthVersion; 29 28 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 30 29 import org.openstreetmap.josm.io.DefaultProxySelector; … … 51 50 * In contrast, this cache avoids read request the backend in general. 52 51 */ 53 52 private final Map<RequestorType, PasswordAuthentication> credentialsCache = new EnumMap<>(RequestorType.class); 54 private OAuthToken oauthCache; 53 55 54 56 55 /** 57 56 * Create a new {@link NPMCredentialsAgent} … … 188 187 } 189 188 } 190 189 191 @Override192 public OAuthToken lookupOAuthAccessToken() {193 if (oauthCache != null)194 return oauthCache;195 String prolog = getOAuthDescriptor();196 char[] key = getProvider().read(prolog+".key");197 char[] secret = getProvider().read(prolog+".secret");198 return new OAuthToken(stringNotNull(key), stringNotNull(secret));199 }200 201 190 @Override 202 191 public IOAuthToken lookupOAuthAccessToken(String host) throws CredentialsAgentException { 203 192 String prolog = getOAuthDescriptor(); … … 221 210 return null; 222 211 } 223 212 224 @Override225 public void storeOAuthAccessToken(OAuthToken oat) {226 String key, secret;227 if (oat == null) {228 key = null;229 secret = null;230 } else {231 key = oat.getKey();232 secret = oat.getSecret();233 }234 String prolog = getOAuthDescriptor();235 if (key == null || key.isEmpty() || secret == null || secret.isEmpty()) {236 getProvider().delete(prolog+".key");237 getProvider().delete(prolog+".secret");238 oauthCache = null;239 } else {240 getProvider().save(prolog+".key", key.toCharArray(), tr("JOSM/OAuth/OSM API/Key"));241 getProvider().save(prolog+".secret", secret.toCharArray(), tr("JOSM/OAuth/OSM API/Secret"));242 oauthCache = new OAuthToken(key, secret);243 }244 }245 246 213 @Override 247 214 public void storeOAuthAccessToken(String host, IOAuthToken accessToken) { 248 215 String prolog = getOAuthDescriptor(); -
plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialAgent.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialAgent.java b/plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialAgent.java
a b 12 12 import javax.swing.text.html.HTMLEditorKit; 13 13 14 14 import org.openstreetmap.josm.data.oauth.IOAuthToken; 15 import org.openstreetmap.josm.data.oauth.OAuthToken;16 15 import org.openstreetmap.josm.gui.io.CredentialDialog; 17 16 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 18 17 import org.openstreetmap.josm.io.DefaultProxySelector; … … 82 81 } 83 82 } 84 83 85 /**86 * Lookup the current OAuth Access Token to access the OSM server. Replies null, if no87 * Access Token is currently managed by this CredentialManager.88 *89 * @return the current OAuth Access Token to access the OSM server.90 */91 @Override92 public OAuthToken lookupOAuthAccessToken() {93 String accessTokenKey = Config.getPref().get("oauth.access-token.key", null);94 String accessTokenSecret = Config.getPref().get("oauth.access-token.secret", null);95 if (accessTokenKey == null && accessTokenSecret == null)96 return null;97 return new OAuthToken(accessTokenKey, accessTokenSecret);98 }99 100 84 @Override 101 85 public IOAuthToken lookupOAuthAccessToken(String host) { 102 86 throw new UnsupportedOperationException("SDS does not support OAuth tokens"); … … 126 110 return tr("Save user and password (unencrypted)"); 127 111 } 128 112 129 @Override130 public void storeOAuthAccessToken(OAuthToken accessToken) {131 // no-op132 }133 134 113 @Override 135 114 public void storeOAuthAccessToken(String host, IOAuthToken accessToken) { 136 115 throw new UnsupportedOperationException("SDS does not support OAuth tokens");