source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java @ 12928

Last change on this file since 12928 was 12928, checked in by bastiK, 2 weeks ago

see #15229 - do not copy the entire preferences list, just to set a custom server API in OAuth wizard

  • Property svn:eol-style set to native
File size: 13.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences.server;
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.beans.PropertyChangeEvent;
16import java.beans.PropertyChangeListener;
17
18import javax.swing.AbstractAction;
19import javax.swing.BorderFactory;
20import javax.swing.JButton;
21import javax.swing.JCheckBox;
22import javax.swing.JLabel;
23import javax.swing.JPanel;
24
25import org.openstreetmap.josm.Main;
26import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
27import org.openstreetmap.josm.data.oauth.OAuthParameters;
28import org.openstreetmap.josm.data.oauth.OAuthToken;
29import org.openstreetmap.josm.gui.MainApplication;
30import org.openstreetmap.josm.gui.oauth.AdvancedOAuthPropertiesPanel;
31import org.openstreetmap.josm.gui.oauth.OAuthAuthorizationWizard;
32import org.openstreetmap.josm.gui.oauth.TestAccessTokenTask;
33import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
34import org.openstreetmap.josm.gui.widgets.JosmTextField;
35import org.openstreetmap.josm.io.OsmApi;
36import org.openstreetmap.josm.io.auth.CredentialsManager;
37import org.openstreetmap.josm.tools.ImageProvider;
38import org.openstreetmap.josm.tools.Logging;
39import org.openstreetmap.josm.tools.UserCancelException;
40
41/**
42 * The preferences panel for the OAuth preferences. This just a summary panel
43 * showing the current Access Token Key and Access Token Secret, if the
44 * user already has an Access Token.
45 *
46 * For initial authorisation see {@link OAuthAuthorizationWizard}.
47 * @since 2745
48 */
49public class OAuthAuthenticationPreferencesPanel extends JPanel implements PropertyChangeListener {
50    private final JCheckBox cbShowAdvancedParameters = new JCheckBox();
51    private final JCheckBox cbSaveToPreferences = new JCheckBox(tr("Save to preferences"));
52    private final JPanel pnlAuthorisationMessage = new JPanel(new BorderLayout());
53    private final NotYetAuthorisedPanel pnlNotYetAuthorised = new NotYetAuthorisedPanel();
54    private final AdvancedOAuthPropertiesPanel pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel();
55    private final AlreadyAuthorisedPanel pnlAlreadyAuthorised = new AlreadyAuthorisedPanel();
56    private String apiUrl;
57
58    /**
59     * Create the panel
60     */
61    public OAuthAuthenticationPreferencesPanel() {
62        build();
63        refreshView();
64    }
65
66    /**
67     * Builds the panel for entering the advanced OAuth parameters
68     *
69     * @return panel with advanced settings
70     */
71    protected JPanel buildAdvancedPropertiesPanel() {
72        JPanel pnl = new JPanel(new GridBagLayout());
73        GridBagConstraints gc = new GridBagConstraints();
74
75        gc.anchor = GridBagConstraints.NORTHWEST;
76        gc.fill = GridBagConstraints.HORIZONTAL;
77        gc.weightx = 0.0;
78        gc.insets = new Insets(0, 0, 0, 3);
79        pnl.add(cbShowAdvancedParameters, gc);
80        cbShowAdvancedParameters.setSelected(false);
81        cbShowAdvancedParameters.addItemListener(
82                evt -> pnlAdvancedProperties.setVisible(evt.getStateChange() == ItemEvent.SELECTED)
83        );
84
85        gc.gridx = 1;
86        gc.weightx = 1.0;
87        JMultilineLabel lbl = new JMultilineLabel(tr("Display Advanced OAuth Parameters"));
88        lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
89        pnl.add(lbl, gc);
90
91        gc.gridy = 1;
92        gc.gridx = 1;
93        gc.insets = new Insets(3, 0, 3, 0);
94        gc.fill = GridBagConstraints.BOTH;
95        gc.weightx = 1.0;
96        gc.weighty = 1.0;
97        pnl.add(pnlAdvancedProperties, gc);
98        pnlAdvancedProperties.initialize(OsmApi.getOsmApi().getServerUrl());
99        pnlAdvancedProperties.setBorder(
100                BorderFactory.createCompoundBorder(
101                        BorderFactory.createLineBorder(Color.GRAY, 1),
102                        BorderFactory.createEmptyBorder(3, 3, 3, 3)
103                )
104        );
105        pnlAdvancedProperties.setVisible(false);
106        return pnl;
107    }
108
109    /**
110     * builds the UI
111     */
112    protected final void build() {
113        setLayout(new GridBagLayout());
114        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
115        GridBagConstraints gc = new GridBagConstraints();
116
117        // the panel for the OAuth parameters. pnlAuthorisationMessage is an
118        // empty panel. It is going to be filled later, depending on the
119        // current OAuth state in JOSM.
120        gc.fill = GridBagConstraints.BOTH;
121        gc.anchor = GridBagConstraints.NORTHWEST;
122        gc.weighty = 1.0;
123        gc.weightx = 1.0;
124        gc.insets = new Insets(10, 0, 0, 0);
125        add(pnlAuthorisationMessage, gc);
126    }
127
128    protected void refreshView() {
129        pnlAuthorisationMessage.removeAll();
130        if (OAuthAccessTokenHolder.getInstance().containsAccessToken()) {
131            pnlAuthorisationMessage.add(pnlAlreadyAuthorised, BorderLayout.CENTER);
132            pnlAlreadyAuthorised.refreshView();
133            pnlAlreadyAuthorised.revalidate();
134        } else {
135            pnlAuthorisationMessage.add(pnlNotYetAuthorised, BorderLayout.CENTER);
136            pnlNotYetAuthorised.revalidate();
137        }
138        repaint();
139    }
140
141    /**
142     * Sets the URL of the OSM API for which this panel is currently displaying OAuth properties.
143     *
144     * @param apiUrl the api URL
145     */
146    public void setApiUrl(String apiUrl) {
147        this.apiUrl = apiUrl;
148        pnlAdvancedProperties.setApiUrl(apiUrl);
149    }
150
151    /**
152     * Initializes the panel from preferences
153     */
154    public void initFromPreferences() {
155        setApiUrl(OsmApi.getOsmApi().getServerUrl().trim());
156        refreshView();
157    }
158
159    /**
160     * Saves the current values to preferences
161     */
162    public void saveToPreferences() {
163        OAuthAccessTokenHolder.getInstance().setSaveToPreferences(cbSaveToPreferences.isSelected());
164        OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance());
165        pnlAdvancedProperties.rememberPreferences();
166    }
167
168    /**
169     * The preferences panel displayed if there is currently no Access Token available.
170     * This means that the user didn't run through the OAuth authorisation procedure yet.
171     *
172     */
173    private class NotYetAuthorisedPanel extends JPanel {
174        /**
175         * Constructs a new {@code NotYetAuthorisedPanel}.
176         */
177        NotYetAuthorisedPanel() {
178            build();
179        }
180
181        protected void build() {
182            setLayout(new GridBagLayout());
183            GridBagConstraints gc = new GridBagConstraints();
184
185            // A message explaining that the user isn't authorised yet
186            gc.anchor = GridBagConstraints.NORTHWEST;
187            gc.insets = new Insets(0, 0, 3, 0);
188            gc.fill = GridBagConstraints.HORIZONTAL;
189            gc.weightx = 1.0;
190            JMultilineLabel lbl = new JMultilineLabel(
191                    tr("You do not have an Access Token yet to access the OSM server using OAuth. Please authorize first."));
192            add(lbl, gc);
193            lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
194
195            // Action for authorising now
196            gc.gridy = 1;
197            gc.fill = GridBagConstraints.NONE;
198            gc.weightx = 0.0;
199            add(new JButton(new AuthoriseNowAction()), gc);
200
201            // filler - grab remaining space
202            gc.gridy = 2;
203            gc.fill = GridBagConstraints.BOTH;
204            gc.weightx = 1.0;
205            gc.weighty = 1.0;
206            add(new JPanel(), gc);
207        }
208    }
209
210    /**
211     * The preferences panel displayed if there is currently an AccessToken available.
212     *
213     */
214    private class AlreadyAuthorisedPanel extends JPanel {
215        private final JosmTextField tfAccessTokenKey = new JosmTextField();
216        private final JosmTextField tfAccessTokenSecret = new JosmTextField();
217
218        /**
219         * Constructs a new {@code AlreadyAuthorisedPanel}.
220         */
221        AlreadyAuthorisedPanel() {
222            build();
223            refreshView();
224        }
225
226        protected void build() {
227            setLayout(new GridBagLayout());
228            GridBagConstraints gc = new GridBagConstraints();
229            gc.anchor = GridBagConstraints.NORTHWEST;
230            gc.insets = new Insets(0, 0, 3, 3);
231            gc.fill = GridBagConstraints.HORIZONTAL;
232            gc.weightx = 1.0;
233            gc.gridwidth = 2;
234            JMultilineLabel lbl = new JMultilineLabel(tr("You already have an Access Token to access the OSM server using OAuth."));
235            add(lbl, gc);
236            lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
237
238            // -- access token key
239            gc.gridy = 1;
240            gc.gridx = 0;
241            gc.gridwidth = 1;
242            gc.weightx = 0.0;
243            add(new JLabel(tr("Access Token Key:")), gc);
244
245            gc.gridx = 1;
246            gc.weightx = 1.0;
247            add(tfAccessTokenKey, gc);
248            tfAccessTokenKey.setEditable(false);
249
250            // -- access token secret
251            gc.gridy = 2;
252            gc.gridx = 0;
253            gc.gridwidth = 1;
254            gc.weightx = 0.0;
255            add(new JLabel(tr("Access Token Secret:")), gc);
256
257            gc.gridx = 1;
258            gc.weightx = 1.0;
259            add(tfAccessTokenSecret, gc);
260            tfAccessTokenSecret.setEditable(false);
261
262            // -- access token secret
263            gc.gridy = 3;
264            gc.gridx = 0;
265            gc.gridwidth = 2;
266            gc.weightx = 1.0;
267            add(cbSaveToPreferences, gc);
268            cbSaveToPreferences.setSelected(OAuthAccessTokenHolder.getInstance().isSaveToPreferences());
269
270            // -- action buttons
271            JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT));
272            btns.add(new JButton(new RenewAuthorisationAction()));
273            btns.add(new JButton(new TestAuthorisationAction()));
274            gc.gridy = 4;
275            gc.gridx = 0;
276            gc.gridwidth = 2;
277            gc.weightx = 1.0;
278            add(btns, gc);
279
280            // the panel with the advanced options
281            gc.gridy = 5;
282            gc.gridx = 0;
283            gc.gridwidth = 2;
284            gc.weightx = 1.0;
285            add(buildAdvancedPropertiesPanel(), gc);
286
287            // filler - grab the remaining space
288            gc.gridy = 6;
289            gc.fill = GridBagConstraints.BOTH;
290            gc.weightx = 1.0;
291            gc.weighty = 1.0;
292            add(new JPanel(), gc);
293        }
294
295        protected final void refreshView() {
296            String v = OAuthAccessTokenHolder.getInstance().getAccessTokenKey();
297            tfAccessTokenKey.setText(v == null ? "" : v);
298            v = OAuthAccessTokenHolder.getInstance().getAccessTokenSecret();
299            tfAccessTokenSecret.setText(v == null ? "" : v);
300            cbSaveToPreferences.setSelected(OAuthAccessTokenHolder.getInstance().isSaveToPreferences());
301        }
302    }
303
304    /**
305     * Action to authorise the current user
306     */
307    private class AuthoriseNowAction extends AbstractAction {
308        AuthoriseNowAction() {
309            putValue(NAME, tr("Authorize now"));
310            putValue(SHORT_DESCRIPTION, tr("Click to step through the OAuth authorization process"));
311            new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);
312        }
313
314        @Override
315        public void actionPerformed(ActionEvent arg0) {
316            OAuthAuthorizationWizard wizard = new OAuthAuthorizationWizard(
317                    OAuthAuthenticationPreferencesPanel.this,
318                    apiUrl,
319                    MainApplication.worker);
320            try {
321                wizard.showDialog();
322            } catch (UserCancelException ignore) {
323                Logging.trace(ignore);
324                return;
325            }
326            pnlAdvancedProperties.setAdvancedParameters(wizard.getOAuthParameters());
327            refreshView();
328        }
329    }
330
331    /**
332     * Launches the OAuthAuthorisationWizard to generate a new Access Token
333     */
334    private class RenewAuthorisationAction extends AuthoriseNowAction {
335        /**
336         * Constructs a new {@code RenewAuthorisationAction}.
337         */
338        RenewAuthorisationAction() {
339            putValue(NAME, tr("New Access Token"));
340            putValue(SHORT_DESCRIPTION, tr("Click to step through the OAuth authorization process and generate a new Access Token"));
341            new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);
342        }
343    }
344
345    /**
346     * Runs a test whether we can access the OSM server with the current Access Token
347     */
348    private class TestAuthorisationAction extends AbstractAction {
349        /**
350         * Constructs a new {@code TestAuthorisationAction}.
351         */
352        TestAuthorisationAction() {
353            putValue(NAME, tr("Test Access Token"));
354            putValue(SHORT_DESCRIPTION, tr("Click test access to the OSM server with the current access token"));
355            new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);
356        }
357
358        @Override
359        public void actionPerformed(ActionEvent evt) {
360            OAuthToken token = OAuthAccessTokenHolder.getInstance().getAccessToken();
361            OAuthParameters parameters = OAuthParameters.createFromApiUrl(OsmApi.getOsmApi().getServerUrl());
362            TestAccessTokenTask task = new TestAccessTokenTask(
363                    OAuthAuthenticationPreferencesPanel.this,
364                    apiUrl,
365                    parameters,
366                    token
367            );
368            MainApplication.worker.submit(task);
369        }
370    }
371
372    @Override
373    public void propertyChange(PropertyChangeEvent evt) {
374        if (!evt.getPropertyName().equals(OsmApiUrlInputPanel.API_URL_PROP))
375            return;
376        setApiUrl((String) evt.getNewValue());
377    }
378}
Note: See TracBrowser for help on using the repository browser.