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

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

see #20129 - Fix typos and misspellings in the code (patch by gaben)

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