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

Revision 3530, 11.3 KB checked in by stoecker, 21 months ago (diff)

fix array preferences

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