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

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

refactor of some GUI/widgets classes (impacts some plugins):

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