source: josm/trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java@ 13250

Last change on this file since 13250 was 12620, checked in by Don-vip, 7 years ago

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

  • Property svn:eol-style set to native
File size: 11.2 KB
RevLine 
[2801]1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.oauth;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Component;
7import java.io.IOException;
8import java.net.HttpURLConnection;
9import java.net.URL;
10
11import javax.swing.JOptionPane;
12import javax.xml.parsers.ParserConfigurationException;
13
14import org.openstreetmap.josm.data.oauth.OAuthParameters;
15import org.openstreetmap.josm.data.oauth.OAuthToken;
16import org.openstreetmap.josm.data.osm.UserInfo;
17import org.openstreetmap.josm.gui.HelpAwareOptionPane;
18import org.openstreetmap.josm.gui.PleaseWaitRunnable;
19import org.openstreetmap.josm.gui.help.HelpUtil;
20import org.openstreetmap.josm.io.OsmApiException;
21import org.openstreetmap.josm.io.OsmServerUserInfoReader;
22import org.openstreetmap.josm.io.OsmTransferException;
23import org.openstreetmap.josm.io.auth.DefaultAuthenticator;
24import org.openstreetmap.josm.tools.CheckParameterUtil;
[9172]25import org.openstreetmap.josm.tools.HttpClient;
[12620]26import org.openstreetmap.josm.tools.Logging;
[10404]27import org.openstreetmap.josm.tools.Utils;
[6906]28import org.openstreetmap.josm.tools.XmlParsingException;
[2801]29import org.w3c.dom.Document;
30import org.xml.sax.SAXException;
31
[9078]32import oauth.signpost.OAuthConsumer;
33import oauth.signpost.exception.OAuthException;
34
[2801]35/**
36 * Checks whether an OSM API server can be accessed with a specific Access Token.
[3530]37 *
[2801]38 * It retrieves the user details for the user which is authorized to access the server with
39 * this token.
[3530]40 *
[2801]41 */
42public class TestAccessTokenTask extends PleaseWaitRunnable {
[9078]43 private final OAuthToken token;
44 private final OAuthParameters oauthParameters;
[2801]45 private boolean canceled;
[9078]46 private final Component parent;
47 private final String apiUrl;
[9309]48 private HttpClient connection;
[2801]49
50 /**
51 * Create the task
[3530]52 *
[5266]53 * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog is displayed
[2801]54 * @param apiUrl the API URL. Must not be null.
55 * @param parameters the OAuth parameters. Must not be null.
56 * @param accessToken the Access Token. Must not be null.
57 */
58 public TestAccessTokenTask(Component parent, String apiUrl, OAuthParameters parameters, OAuthToken accessToken) {
59 super(parent, tr("Testing OAuth Access Token"), false /* don't ignore exceptions */);
60 CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
61 CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
62 CheckParameterUtil.ensureParameterNotNull(accessToken, "accessToken");
63 this.token = accessToken;
64 this.oauthParameters = parameters;
65 this.parent = parent;
66 this.apiUrl = apiUrl;
67 }
68
69 @Override
70 protected void cancel() {
71 canceled = true;
[8510]72 synchronized (this) {
[2801]73 if (connection != null) {
74 connection.disconnect();
75 }
76 }
77 }
78
79 @Override
[10173]80 protected void finish() {
81 // Do nothing
82 }
[2801]83
[9172]84 protected void sign(HttpClient con) throws OAuthException {
[2801]85 OAuthConsumer consumer = oauthParameters.buildConsumer();
86 consumer.setTokenWithSecret(token.getKey(), token.getSecret());
87 consumer.sign(con);
88 }
89
90 protected String normalizeApiUrl(String url) {
91 // remove leading and trailing white space
92 url = url.trim();
93
94 // remove trailing slashes
[8510]95 while (url.endsWith("/")) {
[6083]96 url = url.substring(0, url.lastIndexOf('/'));
[2801]97 }
98 return url;
99 }
100
[6906]101 protected UserInfo getUserDetails() throws OsmOAuthAuthorizationException, XmlParsingException, OsmTransferException {
[2801]102 boolean authenticatorEnabled = true;
103 try {
104 URL url = new URL(normalizeApiUrl(apiUrl) + "/0.6/user/details");
105 authenticatorEnabled = DefaultAuthenticator.getInstance().isEnabled();
106 DefaultAuthenticator.getInstance().setEnabled(false);
[9172]107
108 final HttpClient client = HttpClient.create(url);
109 sign(client);
[8510]110 synchronized (this) {
[9309]111 connection = client;
112 connection.connect();
[2801]113 }
114
[9309]115 if (connection.getResponse().getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED)
[8509]116 throw new OsmApiException(HttpURLConnection.HTTP_UNAUTHORIZED,
117 tr("Retrieving user details with Access Token Key ''{0}'' was rejected.", token.getKey()), null);
[2801]118
[9309]119 if (connection.getResponse().getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN)
[8509]120 throw new OsmApiException(HttpURLConnection.HTTP_FORBIDDEN,
121 tr("Retrieving user details with Access Token Key ''{0}'' was forbidden.", token.getKey()), null);
[2801]122
[9309]123 if (connection.getResponse().getResponseCode() != HttpURLConnection.HTTP_OK)
124 throw new OsmApiException(connection.getResponse().getResponseCode(),
125 connection.getResponse().getHeaderField("Error"), null);
[10404]126 Document d = Utils.parseSafeDOM(connection.getResponse().getContent());
[2801]127 return OsmServerUserInfoReader.buildFromXML(d);
[8510]128 } catch (SAXException | ParserConfigurationException e) {
[6906]129 throw new XmlParsingException(e);
[8510]130 } catch (IOException e) {
[2801]131 throw new OsmTransferException(e);
[8510]132 } catch (OAuthException e) {
[2861]133 throw new OsmOAuthAuthorizationException(e);
[2801]134 } finally {
135 DefaultAuthenticator.getInstance().setEnabled(authenticatorEnabled);
136 }
137 }
138
139 protected void notifySuccess(UserInfo userInfo) {
[6116]140 HelpAwareOptionPane.showMessageDialogInEDT(
[2801]141 parent,
142 tr("<html>"
143 + "Successfully used the Access Token ''{0}'' to<br>"
144 + "access the OSM server at ''{1}''.<br>"
[2850]145 + "You are accessing the OSM server as user ''{2}'' with id ''{3}''."
146 + "</html>",
[2801]147 token.getKey(),
148 apiUrl,
[11848]149 Utils.escapeReservedCharactersHTML(userInfo.getDisplayName()),
[2801]150 userInfo.getId()
151 ),
152 tr("Success"),
153 JOptionPane.INFORMATION_MESSAGE,
154 HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#AccessTokenOK")
155 );
156 }
157
158 protected void alertFailedAuthentication() {
[6116]159 HelpAwareOptionPane.showMessageDialogInEDT(
[2801]160 parent,
161 tr("<html>"
162 + "Failed to access the OSM server ''{0}''<br>"
[5411]163 + "with the Access Token ''{1}''.<br>"
[2877]164 + "The server rejected the Access Token as unauthorized. You will not<br>"
[2801]165 + "be able to access any protected resource on this server using this token."
166 +"</html>",
167 apiUrl,
168 token.getKey()
169 ),
170 tr("Test failed"),
171 JOptionPane.ERROR_MESSAGE,
172 HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#AccessTokenFailed")
173 );
174 }
175
176 protected void alertFailedAuthorisation() {
[6116]177 HelpAwareOptionPane.showMessageDialogInEDT(
[2801]178 parent,
179 tr("<html>"
[2840]180 + "The Access Token ''{1}'' is known to the OSM server ''{0}''.<br>"
[2801]181 + "The test to retrieve the user details for this token failed, though.<br>"
182 + "Depending on what rights are granted to this token you may nevertheless use it<br>"
183 + "to upload data, upload GPS traces, and/or access other protected resources."
184 +"</html>",
185 apiUrl,
186 token.getKey()
187 ),
188 tr("Token allows restricted access"),
189 JOptionPane.WARNING_MESSAGE,
190 HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#AccessTokenFailed")
191 );
192 }
193
194 protected void alertFailedConnection() {
[6116]195 HelpAwareOptionPane.showMessageDialogInEDT(
[2801]196 parent,
197 tr("<html>"
198 + "Failed to retrieve information about the current user"
[2840]199 + " from the OSM server ''{0}''.<br>"
[2801]200 + "This is probably not a problem caused by the tested Access Token, but<br>"
201 + "rather a problem with the server configuration. Carefully check the server<br>"
202 + "URL and your Internet connection."
203 +"</html>",
204 apiUrl,
205 token.getKey()
206 ),
207 tr("Test failed"),
208 JOptionPane.ERROR_MESSAGE,
209 HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#AccessTokenFailed")
210 );
211 }
212
213 protected void alertFailedSigning() {
[6116]214 HelpAwareOptionPane.showMessageDialogInEDT(
[2801]215 parent,
216 tr("<html>"
217 + "Failed to sign the request for the OSM server ''{0}'' with the "
218 + "token ''{1}''.<br>"
219 + "The token ist probably invalid."
220 +"</html>",
221 apiUrl,
222 token.getKey()
223 ),
224 tr("Test failed"),
225 JOptionPane.ERROR_MESSAGE,
226 HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#AccessTokenFailed")
227 );
228 }
229
230 protected void alertInternalError() {
[6116]231 HelpAwareOptionPane.showMessageDialogInEDT(
[2801]232 parent,
233 tr("<html>"
234 + "The test failed because the server responded with an internal error.<br>"
[2850]235 + "JOSM could not decide whether the token is valid. Please try again later."
236 + "</html>",
[2801]237 apiUrl,
238 token.getKey()
239 ),
240 tr("Test failed"),
241 JOptionPane.WARNING_MESSAGE,
242 HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#AccessTokenFailed")
243 );
244 }
245
246 @Override
247 protected void realRun() throws SAXException, IOException, OsmTransferException {
248 try {
249 getProgressMonitor().indeterminateSubTask(tr("Retrieving user info..."));
250 UserInfo userInfo = getUserDetails();
251 if (canceled) return;
252 notifySuccess(userInfo);
[8510]253 } catch (OsmOAuthAuthorizationException e) {
[2801]254 if (canceled) return;
[12620]255 Logging.error(e);
[2801]256 alertFailedSigning();
[8510]257 } catch (OsmApiException e) {
[2801]258 if (canceled) return;
[12620]259 Logging.error(e);
[2801]260 if (e.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR) {
261 alertInternalError();
262 return;
[6362]263 } else if (e.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
[2801]264 alertFailedAuthentication();
265 return;
266 } else if (e.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) {
267 alertFailedAuthorisation();
268 return;
269 }
270 alertFailedConnection();
[8510]271 } catch (OsmTransferException e) {
[2801]272 if (canceled) return;
[12620]273 Logging.error(e);
[2801]274 alertFailedConnection();
275 }
276 }
277}
Note: See TracBrowser for help on using the repository browser.