source: josm/trunk/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java@ 9623

Last change on this file since 9623 was 9623, checked in by Don-vip, 8 years ago

fix transient/serializable findbugs warnings

  • Property svn:eol-style set to native
File size: 16.9 KB
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.BorderLayout;
7import java.awt.Color;
8import java.awt.FlowLayout;
9import java.awt.Font;
10import java.awt.GridBagConstraints;
11import java.awt.GridBagLayout;
12import java.awt.Insets;
13import java.awt.event.ActionEvent;
14import java.awt.event.ItemEvent;
15import java.awt.event.ItemListener;
16import java.util.concurrent.Executor;
17
18import javax.swing.AbstractAction;
19import javax.swing.BorderFactory;
20import javax.swing.JCheckBox;
21import javax.swing.JLabel;
22import javax.swing.JPanel;
23
24import org.openstreetmap.josm.data.oauth.OAuthToken;
25import org.openstreetmap.josm.gui.SideButton;
26import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
27import org.openstreetmap.josm.gui.util.GuiHelper;
28import org.openstreetmap.josm.gui.widgets.HtmlPanel;
29import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
30import org.openstreetmap.josm.gui.widgets.JosmTextField;
31import org.openstreetmap.josm.tools.ImageProvider;
32import org.openstreetmap.josm.tools.OpenBrowser;
33
34/**
35 * This is the UI for running a semic-automic authorisation procedure.
36 *
37 * In contrast to the fully-automatic procedure the user is dispatched to an
38 * external browser for login and authorisation.
39 *
40 * @since 2746
41 */
42public class SemiAutomaticAuthorizationUI extends AbstractAuthorizationUI {
43 private AccessTokenInfoPanel pnlAccessTokenInfo;
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 UI
53 */
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 URL
66 * @param executor the executor used for running the HTTP requests for the authorization
67 * @since 5422
68 */
69 public SemiAutomaticAuthorizationUI(String apiUrl, Executor executor) {
70 super(apiUrl);
71 this.executor = executor;
72 build();
73 }
74
75 @Override
76 public boolean isSaveAccessTokenToPreferences() {
77 return pnlAccessTokenInfo.isSaveToPreferences();
78 }
79
80 protected void transitionToRetrieveAccessToken() {
81 OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(
82 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 /**
115 * This is the panel displayed in the first step of the semi-automatic authorisation process.
116 */
117 private class RetrieveRequestTokenPanel extends JPanel {
118
119 /**
120 * Constructs a new {@code RetrieveRequestTokenPanel}.
121 */
122 RetrieveRequestTokenPanel() {
123 build();
124 }
125
126 protected JPanel buildAdvancedParametersPanel() {
127 JPanel pnl = new JPanel(new GridBagLayout());
128 GridBagConstraints gc = new GridBagConstraints();
129
130 gc.anchor = GridBagConstraints.NORTHWEST;
131 gc.fill = GridBagConstraints.HORIZONTAL;
132 gc.weightx = 0.0;
133 gc.insets = new Insets(0, 0, 0, 3);
134 JCheckBox cbShowAdvancedParameters = new JCheckBox();
135 pnl.add(cbShowAdvancedParameters, gc);
136 cbShowAdvancedParameters.setSelected(false);
137 cbShowAdvancedParameters.addItemListener(
138 new ItemListener() {
139 @Override
140 public void itemStateChanged(ItemEvent evt) {
141 getAdvancedPropertiesPanel().setVisible(evt.getStateChange() == ItemEvent.SELECTED);
142 }
143 }
144 );
145
146 gc.gridx = 1;
147 gc.weightx = 1.0;
148 JMultilineLabel lbl = new JMultilineLabel(tr("Display Advanced OAuth Parameters"));
149 lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
150 pnl.add(lbl, gc);
151
152 gc.gridy = 1;
153 gc.gridx = 1;
154 gc.insets = new Insets(3, 0, 3, 0);
155 gc.fill = GridBagConstraints.BOTH;
156 gc.weightx = 1.0;
157 gc.weighty = 1.0;
158 pnl.add(getAdvancedPropertiesPanel(), gc);
159 getAdvancedPropertiesPanel().setBorder(
160 BorderFactory.createCompoundBorder(
161 BorderFactory.createLineBorder(Color.GRAY, 1),
162 BorderFactory.createEmptyBorder(3, 3, 3, 3)
163 )
164 );
165 getAdvancedPropertiesPanel().setVisible(false);
166 return pnl;
167 }
168
169 protected JPanel buildCommandPanel() {
170 JPanel pnl = new JPanel(new GridBagLayout());
171 GridBagConstraints gc = new GridBagConstraints();
172
173 gc.anchor = GridBagConstraints.NORTHWEST;
174 gc.fill = GridBagConstraints.BOTH;
175 gc.weightx = 1.0;
176 gc.weighty = 1.0;
177 gc.insets = new Insets(0, 0, 0, 3);
178
179
180 HtmlPanel h = new HtmlPanel();
181 h.setText(tr("<html>"
182 + "Please click on <strong>{0}</strong> to retrieve an OAuth Request Token from "
183 + "''{1}''.</html>",
184 tr("Retrieve Request Token"),
185 getAdvancedPropertiesPanel().getAdvancedParameters().getRequestTokenUrl()
186 ));
187 pnl.add(h, gc);
188
189 JPanel pnl1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
190 pnl1.add(new SideButton(new RetrieveRequestTokenAction()));
191 gc.fill = GridBagConstraints.HORIZONTAL;
192 gc.weightx = 1.0;
193 gc.gridy = 1;
194 pnl.add(pnl1, gc);
195 return pnl;
196
197 }
198
199 protected final void build() {
200 setLayout(new BorderLayout(0, 5));
201 JLabel lbl = new JLabel(tr("<html>Step 1/3: Retrieve an OAuth Request Token</html>"));
202 lbl.setFont(lbl.getFont().deriveFont(16f));
203 add(lbl, 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 JosmTextField tfAuthoriseUrl;
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 JLabel lbl = new JLabel(tr("<html>Step 2/3: Authorize and retrieve an Access Token</html>"));
226 lbl.setFont(lbl.getFont().deriveFont(16f));
227 pnl.add(lbl, BorderLayout.CENTER);
228 return pnl;
229 }
230
231 protected JPanel buildContentPanel() {
232 JPanel pnl = new JPanel(new GridBagLayout());
233 GridBagConstraints gc = new GridBagConstraints();
234
235 gc.anchor = GridBagConstraints.NORTHWEST;
236 gc.fill = GridBagConstraints.HORIZONTAL;
237 gc.weightx = 1.0;
238 gc.gridwidth = 2;
239 HtmlPanel html = new HtmlPanel();
240 html.setText(tr("<html>"
241 + "JOSM successfully retrieved a Request Token. "
242 + "JOSM is now launching an authorization page in an external browser. "
243 + "Please login with your OSM username and password and follow the instructions "
244 + "to authorize the Request Token. Then switch back to this dialog and click on "
245 + "<strong>{0}</strong><br><br>"
246 + "If launching the external browser fails you can copy the following authorize URL "
247 + "and paste it into the address field of your browser.</html>",
248 tr("Request Access Token")
249 ));
250 pnl.add(html, gc);
251
252 gc.gridx = 0;
253 gc.gridy = 1;
254 gc.weightx = 0.0;
255 gc.gridwidth = 1;
256 pnl.add(new JLabel(tr("Authorize URL:")), gc);
257
258 gc.gridx = 1;
259 gc.weightx = 1.0;
260 pnl.add(tfAuthoriseUrl = new JosmTextField(), gc);
261 tfAuthoriseUrl.setEditable(false);
262
263 return pnl;
264 }
265
266 protected JPanel buildActionPanel() {
267 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
268
269 pnl.add(new SideButton(new BackAction()));
270 pnl.add(new SideButton(new RetrieveAccessTokenAction()));
271 return pnl;
272 }
273
274 protected final void build() {
275 setLayout(new BorderLayout());
276 add(buildTitlePanel(), BorderLayout.NORTH);
277 add(buildContentPanel(), BorderLayout.CENTER);
278 add(buildActionPanel(), BorderLayout.SOUTH);
279 }
280
281 public void setAuthoriseUrl(String url) {
282 tfAuthoriseUrl.setText(url);
283 }
284
285 /**
286 * Action to go back to step 1 in the process
287 */
288 class BackAction extends AbstractAction {
289 BackAction() {
290 putValue(NAME, tr("Back"));
291 putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));
292 putValue(SMALL_ICON, ImageProvider.get("dialogs", "previous"));
293 }
294
295 @Override
296 public void actionPerformed(ActionEvent arg0) {
297 transitionToRetrieveRequestToken();
298 }
299 }
300 }
301
302 /**
303 * Displays the retrieved Access Token in step 3.
304 */
305 class ShowAccessTokenPanel extends JPanel {
306
307 /**
308 * Constructs a new {@code ShowAccessTokenPanel}.
309 */
310 ShowAccessTokenPanel() {
311 build();
312 }
313
314 protected JPanel buildTitlePanel() {
315 JPanel pnl = new JPanel(new BorderLayout());
316 JLabel lbl = new JLabel(tr("<html>Step 3/3: Successfully retrieved an Access Token</html>"));
317 lbl.setFont(lbl.getFont().deriveFont(16f));
318 pnl.add(lbl, BorderLayout.CENTER);
319 return pnl;
320 }
321
322 protected JPanel buildContentPanel() {
323 JPanel pnl = new JPanel(new GridBagLayout());
324 GridBagConstraints gc = new GridBagConstraints();
325
326 gc.anchor = GridBagConstraints.NORTHWEST;
327 gc.fill = GridBagConstraints.HORIZONTAL;
328 gc.weightx = 1.0;
329 HtmlPanel html = new HtmlPanel();
330 html.setText(tr("<html>"
331 + "JOSM has successfully retrieved an Access Token. "
332 + "You can now accept this token. JOSM will use it in the future for authentication "
333 + "and authorization to the OSM server.<br><br>"
334 + "The access token is: </html>"
335 ));
336 pnl.add(html, gc);
337
338 gc.gridx = 0;
339 gc.gridy = 1;
340 gc.weightx = 1.0;
341 gc.gridwidth = 1;
342 pnl.add(pnlAccessTokenInfo = new AccessTokenInfoPanel(), gc);
343 pnlAccessTokenInfo.setSaveToPreferences(
344 OAuthAccessTokenHolder.getInstance().isSaveToPreferences()
345 );
346 return pnl;
347 }
348
349 protected JPanel buildActionPanel() {
350 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
351 pnl.add(new SideButton(new RestartAction()));
352 pnl.add(new SideButton(new TestAccessTokenAction()));
353 return pnl;
354 }
355
356 protected final void build() {
357 setLayout(new BorderLayout());
358 add(buildTitlePanel(), BorderLayout.NORTH);
359 add(buildContentPanel(), BorderLayout.CENTER);
360 add(buildActionPanel(), BorderLayout.SOUTH);
361 }
362
363 /**
364 * Action to go back to step 1 in the process
365 */
366 class RestartAction extends AbstractAction {
367 RestartAction() {
368 putValue(NAME, tr("Restart"));
369 putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));
370 putValue(SMALL_ICON, ImageProvider.get("dialogs", "previous"));
371 }
372
373 @Override
374 public void actionPerformed(ActionEvent arg0) {
375 transitionToRetrieveRequestToken();
376 }
377 }
378
379 public void setAccessToken(OAuthToken accessToken) {
380 pnlAccessTokenInfo.setAccessToken(accessToken);
381 }
382 }
383
384 /**
385 * Action for retrieving a request token
386 */
387 class RetrieveRequestTokenAction extends AbstractAction {
388
389 RetrieveRequestTokenAction() {
390 putValue(NAME, tr("Retrieve Request Token"));
391 putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth-small"));
392 putValue(SHORT_DESCRIPTION, tr("Click to retrieve a Request Token"));
393 }
394
395 @Override
396 public void actionPerformed(ActionEvent evt) {
397 final RetrieveRequestTokenTask task = new RetrieveRequestTokenTask(
398 SemiAutomaticAuthorizationUI.this,
399 getAdvancedPropertiesPanel().getAdvancedParameters()
400 );
401 executor.execute(task);
402 Runnable r = new Runnable() {
403 @Override
404 public void run() {
405 if (task.isCanceled()) return;
406 if (task.getRequestToken() == null) return;
407 requestToken = task.getRequestToken();
408 GuiHelper.runInEDT(new Runnable() {
409 @Override
410 public void run() {
411 transitionToRetrieveAccessToken();
412 }
413 });
414 }
415 };
416 executor.execute(r);
417 }
418 }
419
420 /**
421 * Action for retrieving an Access Token
422 */
423 class RetrieveAccessTokenAction extends AbstractAction {
424
425 RetrieveAccessTokenAction() {
426 putValue(NAME, tr("Retrieve Access Token"));
427 putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth-small"));
428 putValue(SHORT_DESCRIPTION, tr("Click to retrieve an Access Token"));
429 }
430
431 @Override
432 public void actionPerformed(ActionEvent evt) {
433 final RetrieveAccessTokenTask task = new RetrieveAccessTokenTask(
434 SemiAutomaticAuthorizationUI.this,
435 getAdvancedPropertiesPanel().getAdvancedParameters(),
436 requestToken
437 );
438 executor.execute(task);
439 Runnable r = new Runnable() {
440 @Override
441 public void run() {
442 if (task.isCanceled()) return;
443 if (task.getAccessToken() == null) return;
444 GuiHelper.runInEDT(new Runnable() {
445 @Override
446 public void run() {
447 setAccessToken(task.getAccessToken());
448 transitionToShowAccessToken();
449 }
450 });
451 }
452 };
453 executor.execute(r);
454 }
455 }
456
457 /**
458 * Action for testing an Access Token
459 */
460 class TestAccessTokenAction extends AbstractAction {
461
462 TestAccessTokenAction() {
463 putValue(NAME, tr("Test Access Token"));
464 putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth-small"));
465 putValue(SHORT_DESCRIPTION, tr("Click to test the Access Token"));
466 }
467
468 @Override
469 public void actionPerformed(ActionEvent evt) {
470 TestAccessTokenTask task = new TestAccessTokenTask(
471 SemiAutomaticAuthorizationUI.this,
472 getApiUrl(),
473 getAdvancedPropertiesPanel().getAdvancedParameters(),
474 getAccessToken()
475 );
476 executor.execute(task);
477 }
478 }
479}
Note: See TracBrowser for help on using the repository browser.