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