source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/server/ProxyPreferencesPanel.java @ 5241

Revision 4690, 14.2 KB checked in by stoecker, 5 months ago (diff)

see #7086 - fix passing auth information to wrong server

  • Property svn:eol-style set to native
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;
5import static org.openstreetmap.josm.tools.I18n.trc;
6
7import java.awt.Component;
8import java.awt.Dimension;
9import java.awt.GridBagConstraints;
10import java.awt.GridBagLayout;
11import java.awt.Insets;
12import java.awt.event.ItemEvent;
13import java.awt.event.ItemListener;
14import java.net.PasswordAuthentication;
15import java.net.ProxySelector;
16import java.net.Authenticator.RequestorType;
17import java.util.HashMap;
18import java.util.Map;
19
20import javax.swing.BorderFactory;
21import javax.swing.ButtonGroup;
22import javax.swing.JLabel;
23import javax.swing.JPanel;
24import javax.swing.JPasswordField;
25import javax.swing.JRadioButton;
26import javax.swing.JTextField;
27
28import org.openstreetmap.josm.Main;
29import org.openstreetmap.josm.gui.JMultilineLabel;
30import org.openstreetmap.josm.gui.help.HelpUtil;
31import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
32import org.openstreetmap.josm.io.DefaultProxySelector;
33import org.openstreetmap.josm.io.auth.CredentialsAgent;
34import org.openstreetmap.josm.io.auth.CredentialsAgentException;
35import org.openstreetmap.josm.io.auth.CredentialsManager;
36import org.openstreetmap.josm.tools.GBC;
37
38public class ProxyPreferencesPanel extends VerticallyScrollablePanel {
39
40    public enum ProxyPolicy {
41        NO_PROXY("no-proxy"),
42        USE_SYSTEM_SETTINGS("use-system-settings"),
43        USE_HTTP_PROXY("use-http-proxy"),
44        USE_SOCKS_PROXY("use-socks-proxy");
45
46        private String policyName;
47        ProxyPolicy(String policyName) {
48            this.policyName = policyName;
49        }
50
51        public String getName() {
52            return policyName;
53        }
54
55        static public ProxyPolicy fromName(String policyName) {
56            if (policyName == null) return null;
57            policyName = policyName.trim().toLowerCase();
58            for(ProxyPolicy pp: values()) {
59                if (pp.getName().equals(policyName))
60                    return pp;
61            }
62            return null;
63        }
64    }
65
66    public static final String PROXY_POLICY = "proxy.policy";
67    public static final String PROXY_HTTP_HOST = "proxy.http.host";
68    public static final String PROXY_HTTP_PORT = "proxy.http.port";
69    public static final String PROXY_SOCKS_HOST = "proxy.socks.host";
70    public static final String PROXY_SOCKS_PORT = "proxy.socks.port";
71    public static final String PROXY_USER = "proxy.user";
72    public static final String PROXY_PASS = "proxy.pass";
73
74    private ButtonGroup bgProxyPolicy;
75    private Map<ProxyPolicy, JRadioButton> rbProxyPolicy;
76    private JTextField tfProxyHttpHost;
77    private JTextField tfProxyHttpPort;
78    private JTextField tfProxySocksHost;
79    private JTextField tfProxySocksPort;
80    private JTextField tfProxyHttpUser;
81    private JPasswordField tfProxyHttpPassword;
82
83    private JPanel pnlHttpProxyConfigurationPanel;
84    private JPanel pnlSocksProxyConfigurationPanel;
85
86    /**
87     * Builds the panel for the HTTP proxy configuration
88     *
89     * @return
90     */
91    protected JPanel buildHttpProxyConfigurationPanel() {
92        JPanel pnl = new JPanel(new GridBagLayout()) {
93            @Override
94            public Dimension getMinimumSize() {
95                return getPreferredSize();
96            }
97        };
98        GridBagConstraints gc = new GridBagConstraints();
99
100        gc.anchor = GridBagConstraints.WEST;
101        gc.insets = new Insets(5,5,0,0);
102        gc.fill = GridBagConstraints.HORIZONTAL;
103        gc.weightx = 0.0;
104        pnl.add(new JLabel(tr("Host:")), gc);
105
106        gc.gridx = 1;
107        gc.weightx = 1.0;
108        pnl.add(tfProxyHttpHost = new JTextField(),gc);
109
110        gc.gridy = 1;
111        gc.gridx = 0;
112        gc.fill = GridBagConstraints.NONE;
113        gc.weightx = 0.0;
114        pnl.add(new JLabel(trc("server", "Port:")), gc);
115
116        gc.gridx = 1;
117        gc.weightx = 1.0;
118        pnl.add(tfProxyHttpPort = new JTextField(5),gc);
119        tfProxyHttpPort.setMinimumSize(tfProxyHttpPort.getPreferredSize());
120
121        gc.gridy = 2;
122        gc.gridx = 0;
123        gc.gridwidth = 2;
124        gc.fill = GridBagConstraints.HORIZONTAL;
125        gc.weightx = 1.0;
126        pnl.add(new JMultilineLabel(tr("Please enter a username and a password if your proxy requires authentication.")), gc);
127
128        gc.gridy = 3;
129        gc.gridx = 0;
130        gc.gridwidth = 1;
131        gc.fill = GridBagConstraints.NONE;
132        gc.weightx = 0.0;
133        pnl.add(new JLabel(tr("User:")), gc);
134
135        gc.gridy = 3;
136        gc.gridx = 1;
137        gc.weightx = 1.0;
138        pnl.add(tfProxyHttpUser = new JTextField(20),gc);
139        tfProxyHttpUser.setMinimumSize(tfProxyHttpUser.getPreferredSize());
140
141        gc.gridy = 4;
142        gc.gridx = 0;
143        gc.weightx = 0.0;
144        pnl.add(new JLabel(tr("Password:")), gc);
145
146        gc.gridx = 1;
147        gc.weightx = 1.0;
148        pnl.add(tfProxyHttpPassword = new JPasswordField(20),gc);
149        tfProxyHttpPassword.setMinimumSize(tfProxyHttpPassword.getPreferredSize());
150
151        // add an extra spacer, otherwise the layout is broken
152        gc.gridy = 5;
153        gc.gridx = 0;
154        gc.gridwidth = 2;
155        gc.fill = GridBagConstraints.BOTH;
156        gc.weightx = 1.0;
157        gc.weighty = 1.0;
158        pnl.add(new JPanel(), gc);
159        return pnl;
160    }
161
162    /**
163     * Builds the panel for the SOCKS proxy configuration
164     *
165     * @return
166     */
167    protected JPanel buildSocksProxyConfigurationPanel() {
168        JPanel pnl = new JPanel(new GridBagLayout()) {
169            @Override
170            public Dimension getMinimumSize() {
171                return getPreferredSize();
172            }
173        };
174        GridBagConstraints gc = new GridBagConstraints();
175        gc.anchor = GridBagConstraints.WEST;
176        gc.insets = new Insets(5,5,0,0);
177        gc.fill = GridBagConstraints.HORIZONTAL;
178        gc.weightx = 0.0;
179        pnl.add(new JLabel(tr("Host:")), gc);
180
181        gc.gridx = 1;
182        gc.weightx = 1.0;
183        pnl.add(tfProxySocksHost = new JTextField(20),gc);
184
185        gc.gridy = 1;
186        gc.gridx = 0;
187        gc.weightx = 0.0;
188        gc.fill = GridBagConstraints.NONE;
189        pnl.add(new JLabel(trc("server", "Port:")), gc);
190
191        gc.gridx = 1;
192        gc.weightx = 1.0;
193        pnl.add(tfProxySocksPort = new JTextField(5), gc);
194        tfProxySocksPort.setMinimumSize(tfProxySocksPort.getPreferredSize());
195
196        // add an extra spacer, otherwise the layout is broken
197        gc.gridy = 2;
198        gc.gridx = 0;
199        gc.gridwidth = 2;
200        gc.fill = GridBagConstraints.BOTH;
201        gc.weightx = 1.0;
202        gc.weighty = 1.0;
203        pnl.add(new JPanel(), gc);
204        return pnl;
205    }
206
207    protected JPanel buildProxySettingsPanel() {
208        JPanel pnl = new JPanel(new GridBagLayout());
209        GridBagConstraints gc = new GridBagConstraints();
210
211        bgProxyPolicy = new ButtonGroup();
212        rbProxyPolicy = new HashMap<ProxyPolicy, JRadioButton>();
213        ProxyPolicyChangeListener policyChangeListener = new ProxyPolicyChangeListener();
214        for (ProxyPolicy pp: ProxyPolicy.values()) {
215            rbProxyPolicy.put(pp, new JRadioButton());
216            bgProxyPolicy.add(rbProxyPolicy.get(pp));
217            rbProxyPolicy.get(pp).addItemListener(policyChangeListener);
218        }
219
220        // radio button "No proxy"
221        gc.gridx = 0;
222        gc.gridy = 0;
223        gc.fill = GridBagConstraints.HORIZONTAL;
224        gc.anchor = GridBagConstraints.NORTHWEST;
225        gc.weightx = 0.0;
226        pnl.add(rbProxyPolicy.get(ProxyPolicy.NO_PROXY),gc);
227
228        gc.gridx = 1;
229        gc.weightx = 1.0;
230        pnl.add(new JLabel(tr("No proxy")), gc);
231
232        // radio button "System settings"
233        gc.gridx = 0;
234        gc.gridy = 1;
235        gc.weightx = 0.0;
236        pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_SYSTEM_SETTINGS),gc);
237
238        gc.gridx = 1;
239        gc.weightx = 1.0;
240        String msg;
241        if (DefaultProxySelector.willJvmRetrieveSystemProxies()) {
242            msg = tr("Use standard system settings");
243        } else {
244            msg = tr("Use standard system settings (disabled. Start JOSM with <tt>-Djava.net.useSystemProxies=true</tt> to enable)");
245        }
246        pnl.add(new JMultilineLabel("<html>" + msg + "</html>"), gc);
247
248        // radio button http proxy
249        gc.gridx = 0;
250        gc.gridy = 2;
251        gc.weightx = 0.0;
252        pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY),gc);
253
254        gc.gridx = 1;
255        gc.weightx = 1.0;
256        pnl.add(new JLabel(tr("Manually configure a HTTP proxy")),gc);
257
258        // the panel with the http proxy configuration parameters
259        gc.gridx = 1;
260        gc.gridy = 3;
261        gc.fill = GridBagConstraints.HORIZONTAL;
262        gc.weightx = 1.0;
263        gc.weighty = 0.0;
264        pnl.add(pnlHttpProxyConfigurationPanel = buildHttpProxyConfigurationPanel(),gc);
265
266        // radio button SOCKS proxy
267        gc.gridx = 0;
268        gc.gridy = 4;
269        gc.weightx = 0.0;
270        pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_SOCKS_PROXY),gc);
271
272        gc.gridx = 1;
273        gc.weightx = 1.0;
274        pnl.add(new JLabel(tr("Use a SOCKS proxy")),gc);
275
276        // the panel with the SOCKS configuration parameters
277        gc.gridx = 1;
278        gc.gridy = 5;
279        gc.fill = GridBagConstraints.BOTH;
280        gc.anchor = GridBagConstraints.WEST;
281        gc.weightx = 1.0;
282        gc.weighty = 0.0;
283        pnl.add(pnlSocksProxyConfigurationPanel = buildSocksProxyConfigurationPanel(),gc);
284
285        return pnl;
286    }
287
288    /**
289     * Initializes the panel with the values from the preferences
290     */
291    public void initFromPreferences() {
292        String policy = Main.pref.get(PROXY_POLICY, null);
293        ProxyPolicy pp = ProxyPolicy.fromName(policy);
294        if (pp == null) {
295            pp = ProxyPolicy.NO_PROXY;
296        }
297        rbProxyPolicy.get(pp).setSelected(true);
298        String value = Main.pref.get("proxy.host", null);
299        if (value != null) {
300            // legacy support
301            tfProxyHttpHost.setText(value);
302            Main.pref.put("proxy.host", null);
303        } else {
304            tfProxyHttpHost.setText(Main.pref.get(PROXY_HTTP_HOST, ""));
305        }
306        value = Main.pref.get("proxy.port", null);
307        if (value != null) {
308            // legacy support
309            tfProxyHttpPort.setText(value);
310            Main.pref.put("proxy.port", null);
311        } else {
312            tfProxyHttpPort.setText(Main.pref.get(PROXY_HTTP_PORT, ""));
313        }
314        tfProxySocksHost.setText(Main.pref.get(PROXY_SOCKS_HOST, ""));
315        tfProxySocksPort.setText(Main.pref.get(PROXY_SOCKS_PORT, ""));
316
317        if (pp.equals(ProxyPolicy.USE_SYSTEM_SETTINGS) && ! DefaultProxySelector.willJvmRetrieveSystemProxies()) {
318            System.err.println(tr("Warning: JOSM is configured to use proxies from the system setting, but the JVM is not configured to retrieve them. Resetting preferences to ''No proxy''"));
319            pp = ProxyPolicy.NO_PROXY;
320            rbProxyPolicy.get(pp).setSelected(true);
321        }
322
323        // save the proxy user and the proxy password to a credentials store managed by
324        // the credentials manager
325        CredentialsAgent cm = CredentialsManager.getInstance();
326        try {
327            PasswordAuthentication pa = cm.lookup(RequestorType.PROXY, tfProxyHttpHost.getText());
328            if (pa == null) {
329                tfProxyHttpUser.setText("");
330                tfProxyHttpPassword.setText("");
331            } else {
332                tfProxyHttpUser.setText(pa.getUserName() == null ? "" : pa.getUserName());
333                tfProxyHttpPassword.setText(pa.getPassword() == null ? "" : String.valueOf(pa.getPassword()));
334            }
335        } catch(CredentialsAgentException e) {
336            e.printStackTrace();
337            tfProxyHttpUser.setText("");
338            tfProxyHttpPassword.setText("");
339        }
340    }
341
342    protected void updateEnabledState() {
343        boolean isHttpProxy = rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY).isSelected();
344        for (Component c: pnlHttpProxyConfigurationPanel.getComponents()) {
345            c.setEnabled(isHttpProxy);
346        }
347
348        boolean isSocksProxy = rbProxyPolicy.get(ProxyPolicy.USE_SOCKS_PROXY).isSelected();
349        for (Component c: pnlSocksProxyConfigurationPanel.getComponents()) {
350            c.setEnabled(isSocksProxy);
351        }
352
353        rbProxyPolicy.get(ProxyPolicy.USE_SYSTEM_SETTINGS).setEnabled(DefaultProxySelector.willJvmRetrieveSystemProxies());
354    }
355
356    class ProxyPolicyChangeListener implements ItemListener {
357        @Override
358        public void itemStateChanged(ItemEvent arg0) {
359            updateEnabledState();
360        }
361    }
362
363    public ProxyPreferencesPanel() {
364        setLayout(new GridBagLayout());
365        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
366        add(buildProxySettingsPanel(), GBC.eop().anchor(GridBagConstraints.NORTHWEST).fill(GridBagConstraints.BOTH));
367
368        initFromPreferences();
369        updateEnabledState();
370
371        HelpUtil.setHelpContext(this, HelpUtil.ht("/Preferences/Connection#ProxySettings"));
372    }
373
374    /**
375     * Saves the current values to the preferences
376     */
377    public void saveToPreferences() {
378        ProxyPolicy policy = null;
379        for (ProxyPolicy pp: ProxyPolicy.values()) {
380            if (rbProxyPolicy.get(pp).isSelected()) {
381                policy = pp;
382                break;
383            }
384        }
385        if (policy == null) {
386            policy = ProxyPolicy.NO_PROXY;
387        }
388        Main.pref.put(PROXY_POLICY, policy.getName());
389        Main.pref.put(PROXY_HTTP_HOST, tfProxyHttpHost.getText());
390        Main.pref.put(PROXY_HTTP_PORT, tfProxyHttpPort.getText());
391        Main.pref.put(PROXY_SOCKS_HOST, tfProxySocksHost.getText());
392        Main.pref.put(PROXY_SOCKS_PORT, tfProxySocksPort.getText());
393
394        // update the proxy selector
395        ProxySelector selector = ProxySelector.getDefault();
396        if (selector instanceof DefaultProxySelector) {
397            ((DefaultProxySelector)selector).initFromPreferences();
398        }
399
400        CredentialsAgent cm = CredentialsManager.getInstance();
401        try {
402            PasswordAuthentication pa = new PasswordAuthentication(
403                    tfProxyHttpUser.getText().trim(),
404                    tfProxyHttpPassword.getPassword()
405            );
406            cm.store(RequestorType.PROXY, tfProxyHttpHost.getText(), pa);
407        } catch(CredentialsAgentException e) {
408            e.printStackTrace();
409        }
410    }
411}
Note: See TracBrowser for help on using the repository browser.