source: josm/trunk/src/org/openstreetmap/josm/io/OsmConnection.java@ 2001

Last change on this file since 2001 was 1962, checked in by Gubaer, 15 years ago

fixed #3250

  • Property svn:eol-style set to native
File size: 10.1 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Font;
7import java.awt.GridBagLayout;
8import java.net.Authenticator;
9import java.net.HttpURLConnection;
10import java.net.PasswordAuthentication;
11import java.nio.ByteBuffer;
12import java.nio.CharBuffer;
13import java.nio.charset.CharacterCodingException;
14import java.nio.charset.Charset;
15import java.nio.charset.CharsetEncoder;
16
17import javax.swing.JCheckBox;
18import javax.swing.JLabel;
19import javax.swing.JPanel;
20import javax.swing.JPasswordField;
21import javax.swing.JTextField;
22
23import org.openstreetmap.josm.Main;
24import org.openstreetmap.josm.gui.ExtendedDialog;
25import org.openstreetmap.josm.tools.Base64;
26import org.openstreetmap.josm.tools.GBC;
27
28/**
29 * Base class that handles common things like authentication for the reader and writer
30 * to the osm server.
31 *
32 * @author imi
33 */
34public class OsmConnection {
35
36 protected boolean cancel = false;
37 protected HttpURLConnection activeConnection;
38 /**
39 * Handles password storage and some related gui-components.
40 * It can be set by a plugin. This may happen at startup and
41 * by changing the preferences.
42 * Syncronize on this object to get or set a consistent
43 * username/password pair.
44 */
45 public static CredentialsManager credentialsManager = new PlainCredentialsManager();
46
47 private static OsmAuth authentication = new OsmAuth();
48
49 /**
50 * Initialize the http defaults and the authenticator.
51 */
52 static {
53 // TODO: current authentication handling is sub-optimal in that it seems to use the same authenticator for
54 // any kind of request. HTTP requests executed by plugins, e.g. to password-protected WMS servers,
55 // will use the same username/password which is undesirable.
56 try {
57 HttpURLConnection.setFollowRedirects(true);
58 Authenticator.setDefault(authentication);
59 } catch (SecurityException e) {
60 }
61 }
62
63 /**
64 * The authentication class handling the login requests.
65 */
66 public static class OsmAuth extends Authenticator {
67 /**
68 * Set to true, when the autenticator tried the password once.
69 */
70 public boolean passwordtried = false;
71 /**
72 * Whether the user cancelled the password dialog
73 */
74 public boolean authCancelled = false;
75 @Override protected PasswordAuthentication getPasswordAuthentication() {
76 return credentialsManager.getPasswordAuthentication(this);
77 }
78 }
79
80 /**
81 * Must be called before each connection attemp to initialize the authentication.
82 */
83 protected final void initAuthentication() {
84 authentication.authCancelled = false;
85 authentication.passwordtried = false;
86 }
87
88 /**
89 * @return Whether the connection was cancelled.
90 */
91 protected final boolean isAuthCancelled() {
92 return authentication.authCancelled;
93 }
94
95 public void cancel() {
96 //TODO
97 //Main.pleaseWaitDlg.currentAction.setText(tr("Aborting..."));
98 cancel = true;
99 if (activeConnection != null) {
100 activeConnection.setConnectTimeout(100);
101 activeConnection.setReadTimeout(100);
102 try {
103 Thread.sleep(100);
104 } catch (InterruptedException ex) {}
105 activeConnection.disconnect();
106 }
107 }
108
109 protected void addAuth(HttpURLConnection con) throws CharacterCodingException {
110 CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
111 String auth;
112 try {
113 synchronized (credentialsManager) {
114 auth = credentialsManager.lookupUsername() + ":" + credentialsManager.lookupPassword();
115 }
116 } catch (CredentialsManager.CMException e) {
117 auth = ":";
118 }
119 ByteBuffer bytes = encoder.encode(CharBuffer.wrap(auth));
120 con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes));
121 }
122
123 /**
124 * Replies true if this connection is canceled
125 *
126 * @return true if this connection is canceled
127 * @return
128 */
129 public boolean isCanceled() {
130 return cancel;
131 }
132
133 public static class PlainCredentialsManager implements CredentialsManager {
134 public String lookupUsername() throws CMException {
135 String username = Main.pref.get("osm-server.username", null);
136 if (username == null) throw new CredentialsManager.NoContentException();
137 return username;
138 }
139 public String lookupPassword() throws CMException {
140 String password = Main.pref.get("osm-server.password");
141 if (password == null) throw new CredentialsManager.NoContentException();
142 return password;
143 }
144 public void storeUsername(String username) {
145 Main.pref.put("osm-server.username", username);
146 }
147 public void storePassword(String password) {
148 Main.pref.put("osm-server.password", password);
149 }
150 public PasswordAuthentication getPasswordAuthentication(OsmAuth caller) {
151 String username, password;
152 try {
153 username = lookupUsername();
154 } catch (CMException e) {
155 username = "";
156 }
157 try {
158 password = lookupPassword();
159 } catch (CMException e) {
160 password = "";
161 }
162 if (caller.passwordtried || username.equals("") || password.equals("")) {
163 JPanel p = new JPanel(new GridBagLayout());
164 if (!username.equals("") && !password.equals("")) {
165 p.add(new JLabel(tr("Incorrect password or username.")), GBC.eop());
166 }
167 p.add(new JLabel(tr("Username")), GBC.std().insets(0,0,10,0));
168 JTextField usernameField = new JTextField(username, 20);
169 p.add(usernameField, GBC.eol());
170 p.add(new JLabel(tr("Password")), GBC.std().insets(0,0,10,0));
171 JPasswordField passwordField = new JPasswordField(password, 20);
172 p.add(passwordField, GBC.eol());
173 JLabel warning = new JLabel(tr("Warning: The password is transferred unencrypted."));
174 warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
175 p.add(warning, GBC.eop());
176
177 JCheckBox savePassword = new JCheckBox(tr("Save user and password (unencrypted)"), !username.equals("") && !password.equals(""));
178 p.add(savePassword, GBC.eop());
179
180 int choice = new ExtendedDialog(Main.parent,
181 tr("Enter Password"),
182 p,
183 new String[] {tr("Login"), tr("Cancel")},
184 new String[] {"ok.png", "cancel.png"}).getValue();
185
186 if (choice != 1) {
187 caller.authCancelled = true;
188 return null;
189 }
190 username = usernameField.getText();
191 password = String.valueOf(passwordField.getPassword());
192 if (savePassword.isSelected()) {
193 storeUsername(username);
194 storePassword(password);
195 }
196 if (username.equals(""))
197 return null;
198 }
199 caller.passwordtried = true;
200 return new PasswordAuthentication(username, password.toCharArray());
201 }
202 public PreferenceAdditions newPreferenceAdditions() {
203 return new PreferenceAdditions() {
204 /**
205 * Editfield for the username to the OSM account.
206 */
207 private JTextField osmDataUsername = new JTextField(20);
208 /**
209 * Passwordfield for the userpassword of the REST API.
210 */
211 private JPasswordField osmDataPassword = new JPasswordField(20);
212
213 private String oldUsername = "";
214 private String oldPassword = "";
215
216 public void addPreferenceOptions(JPanel panel) {
217 try {
218 oldUsername = lookupUsername();
219 } catch (CMException e) {
220 oldUsername = "";
221 }
222 try {
223 oldPassword = lookupPassword();
224 } catch (CMException e) {
225 oldPassword = "";
226 }
227 osmDataUsername.setText(oldUsername);
228 osmDataPassword.setText(oldPassword);
229 osmDataUsername.setToolTipText(tr("Login name (e-mail) to the OSM account."));
230 osmDataPassword.setToolTipText(tr("Login password to the OSM account. Leave blank to not store any password."));
231 panel.add(new JLabel(tr("OSM username (e-mail)")), GBC.std());
232 panel.add(osmDataUsername, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
233 panel.add(new JLabel(tr("OSM password")), GBC.std());
234 panel.add(osmDataPassword, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,0));
235 JLabel warning = new JLabel(tr("<html>" +
236 "WARNING: The password is stored in plain text in the preferences file.<br>" +
237 "The password is transferred in plain text to the server, encoded in the URL.<br>" +
238 "<b>Do not use a valuable Password.</b></html>"));
239 warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
240 panel.add(warning, GBC.eop().fill(GBC.HORIZONTAL));
241 }
242 public void preferencesChanged() {
243 String newUsername = osmDataUsername.getText();
244 String newPassword = String.valueOf(osmDataPassword.getPassword());
245 if (!oldUsername.equals(newUsername)) {
246 storeUsername(newUsername);
247 }
248 if (!oldPassword.equals(newPassword)) {
249 storePassword(newPassword);
250 }
251 }
252 };
253 }
254 }
255}
Note: See TracBrowser for help on using the repository browser.