001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.preferences.server;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.BorderLayout;
007import java.awt.GridBagConstraints;
008import java.awt.GridBagLayout;
009import java.awt.Insets;
010import java.awt.event.ItemEvent;
011import java.awt.event.ItemListener;
012import java.beans.PropertyChangeEvent;
013import java.beans.PropertyChangeListener;
014
015import javax.swing.ButtonGroup;
016import javax.swing.JPanel;
017import javax.swing.JRadioButton;
018import javax.swing.JSeparator;
019
020import org.openstreetmap.josm.Main;
021import org.openstreetmap.josm.gui.help.HelpUtil;
022import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
023import org.openstreetmap.josm.io.auth.CredentialsManager;
024
025/**
026 * This is the preference panel for the authentication method and the authentication
027 * parameters.
028 *
029 */
030public class AuthenticationPreferencesPanel extends VerticallyScrollablePanel implements PropertyChangeListener {
031
032    /** indicates whether we use basic authentication */
033    private JRadioButton rbBasicAuthentication;
034    /** indicates whether we use OAuth as authentication scheme */
035    private JRadioButton rbOAuth;
036    /** the panel which contains the authentication parameters for the respective
037     * authentication scheme
038     */
039    private JPanel pnlAuthenticationParameteters;
040    /** the panel for the basic authentication parameters */
041    private BasicAuthenticationPreferencesPanel pnlBasicAuthPreferences;
042    /** the panel for the OAuth authentication parameters */
043    private OAuthAuthenticationPreferencesPanel pnlOAuthPreferences;
044    /** the panel for messages notifier preferences */
045    private FeaturesPanel pnlFeaturesPreferences;
046
047    /**
048     * builds the UI
049     */
050    protected final void build() {
051        setLayout(new GridBagLayout());
052        GridBagConstraints gc = new GridBagConstraints();
053
054        AuthenticationMethodChangeListener authChangeListener = new AuthenticationMethodChangeListener();
055
056        // -- radio button for basic authentication
057        gc.anchor = GridBagConstraints.NORTHWEST;
058        gc.fill = GridBagConstraints.HORIZONTAL;
059        gc.weightx = 0.0;
060        gc.insets = new Insets(0, 0, 0, 3);
061        add(rbBasicAuthentication = new JRadioButton(), gc);
062        rbBasicAuthentication.setText(tr("Use Basic Authentication"));
063        rbBasicAuthentication.setToolTipText(tr("Select to use HTTP basic authentication with your OSM username and password"));
064        rbBasicAuthentication.addItemListener(authChangeListener);
065
066        //-- radio button for OAuth
067        gc.gridx = 1;
068        gc.weightx = 1.0;
069        add(rbOAuth = new JRadioButton(), gc);
070        rbOAuth.setText(tr("Use OAuth"));
071        rbOAuth.setToolTipText(tr("Select to use OAuth as authentication mechanism"));
072        rbOAuth.addItemListener(authChangeListener);
073
074        //-- radio button for OAuth
075        ButtonGroup bg = new ButtonGroup();
076        bg.add(rbBasicAuthentication);
077        bg.add(rbOAuth);
078
079        //-- add the panel which will hold the authentication parameters
080        gc.gridx = 0;
081        gc.gridy = 1;
082        gc.gridwidth = 2;
083        gc.fill = GridBagConstraints.BOTH;
084        gc.weightx = 1.0;
085        gc.weighty = 1.0;
086        pnlAuthenticationParameteters = new JPanel();
087        add(pnlAuthenticationParameteters, gc);
088        pnlAuthenticationParameteters.setLayout(new BorderLayout());
089
090        //-- the two panels for authentication parameters
091        pnlBasicAuthPreferences = new BasicAuthenticationPreferencesPanel();
092        pnlOAuthPreferences = new OAuthAuthenticationPreferencesPanel();
093
094        rbBasicAuthentication.setSelected(true);
095        pnlAuthenticationParameteters.add(pnlBasicAuthPreferences, BorderLayout.CENTER);
096
097        gc.gridy = 2;
098        add(new JSeparator(), gc);
099
100        //-- the panel for API feature preferences
101        gc.gridy = 3;
102        gc.fill = GridBagConstraints.NONE;
103        pnlFeaturesPreferences = new FeaturesPanel();
104        add(pnlFeaturesPreferences, gc);
105    }
106
107    /**
108     * Constructs a new {@code AuthenticationPreferencesPanel}.
109     */
110    public AuthenticationPreferencesPanel() {
111        build();
112        initFromPreferences();
113        HelpUtil.setHelpContext(this, HelpUtil.ht("/Preferences/Connection#AuthenticationSettings"));
114    }
115
116    /**
117     * Initializes the panel from preferences
118     */
119    public final void initFromPreferences() {
120        String authMethod = Main.pref.get("osm-server.auth-method", "basic");
121        if ("basic".equals(authMethod)) {
122            rbBasicAuthentication.setSelected(true);
123        } else if ("oauth".equals(authMethod)) {
124            rbOAuth.setSelected(true);
125        } else {
126            Main.warn(tr("Unsupported value in preference ''{0}'', got ''{1}''. Using authentication method ''Basic Authentication''.",
127                    "osm-server.auth-method", authMethod));
128            rbBasicAuthentication.setSelected(true);
129        }
130        pnlBasicAuthPreferences.initFromPreferences();
131        pnlOAuthPreferences.initFromPreferences();
132        pnlFeaturesPreferences.initFromPreferences();
133    }
134
135    /**
136     * Saves the current values to preferences
137     */
138    public final void saveToPreferences() {
139        // save the authentication method
140        String authMethod;
141        if (rbBasicAuthentication.isSelected()) {
142            authMethod = "basic";
143        } else {
144            authMethod = "oauth";
145        }
146        Main.pref.put("osm-server.auth-method", authMethod);
147        if ("basic".equals(authMethod)) {
148            // save username and password and clear the OAuth token
149            pnlBasicAuthPreferences.saveToPreferences();
150            OAuthAccessTokenHolder.getInstance().clear();
151            OAuthAccessTokenHolder.getInstance().save(Main.pref, CredentialsManager.getInstance());
152        } else if ("oauth".equals(authMethod)) {
153            // clear the password in the preferences
154            pnlBasicAuthPreferences.clearPassword();
155            pnlBasicAuthPreferences.saveToPreferences();
156            pnlOAuthPreferences.saveToPreferences();
157        }
158        // save message notifications preferences. To be done after authentication preferences.
159        pnlFeaturesPreferences.saveToPreferences();
160    }
161
162    /**
163     * Listens to changes in the authentication method
164     */
165    class AuthenticationMethodChangeListener implements ItemListener {
166        @Override
167        public void itemStateChanged(ItemEvent e) {
168            if (rbBasicAuthentication.isSelected()) {
169                pnlAuthenticationParameteters.removeAll();
170                pnlAuthenticationParameteters.add(pnlBasicAuthPreferences, BorderLayout.CENTER);
171                pnlBasicAuthPreferences.revalidate();
172            } else {
173                pnlAuthenticationParameteters.removeAll();
174                pnlAuthenticationParameteters.add(pnlOAuthPreferences, BorderLayout.CENTER);
175                pnlOAuthPreferences.revalidate();
176            }
177            repaint();
178        }
179    }
180
181    @Override
182    public void propertyChange(PropertyChangeEvent evt) {
183        if (pnlOAuthPreferences != null) {
184            pnlOAuthPreferences.propertyChange(evt);
185        }
186    }
187}