[298] | 1 | // License: GPL. Copyright 2007 by Immanuel Scholz and others
|
---|
[626] | 2 | package org.openstreetmap.josm.io;
|
---|
| 3 |
|
---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 |
|
---|
| 6 | import java.awt.Font;
|
---|
| 7 | import java.awt.GridBagLayout;
|
---|
| 8 | import java.net.Authenticator;
|
---|
| 9 | import java.net.HttpURLConnection;
|
---|
| 10 | import java.net.PasswordAuthentication;
|
---|
[662] | 11 | import java.nio.ByteBuffer;
|
---|
| 12 | import java.nio.CharBuffer;
|
---|
| 13 | import java.nio.charset.Charset;
|
---|
| 14 | import java.nio.charset.CharsetEncoder;
|
---|
| 15 | import java.nio.charset.CharacterCodingException;
|
---|
[626] | 16 |
|
---|
| 17 | import javax.swing.JCheckBox;
|
---|
| 18 | import javax.swing.JLabel;
|
---|
| 19 | import javax.swing.JPanel;
|
---|
| 20 | import javax.swing.JPasswordField;
|
---|
| 21 | import javax.swing.JTextField;
|
---|
| 22 |
|
---|
| 23 | import org.openstreetmap.josm.Main;
|
---|
[1670] | 24 | import org.openstreetmap.josm.gui.ExtendedDialog;
|
---|
[626] | 25 | import org.openstreetmap.josm.tools.Base64;
|
---|
| 26 | import 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 | */
|
---|
| 34 | public class OsmConnection {
|
---|
| 35 |
|
---|
[1169] | 36 | protected boolean cancel = false;
|
---|
| 37 | protected HttpURLConnection activeConnection;
|
---|
[626] | 38 |
|
---|
[1169] | 39 | private static OsmAuth authentication = new OsmAuth();
|
---|
| 40 | /**
|
---|
| 41 | * Initialize the http defaults and the authenticator.
|
---|
| 42 | */
|
---|
| 43 | static {
|
---|
[1523] | 44 | // TODO: current authentication handling is sub-optimal in that it seems to use the same authenticator for
|
---|
| 45 | // any kind of request. HTTP requests executed by plugins, e.g. to password-protected WMS servers,
|
---|
| 46 | // will use the same username/password which is undesirable.
|
---|
[1169] | 47 | try {
|
---|
| 48 | HttpURLConnection.setFollowRedirects(true);
|
---|
| 49 | Authenticator.setDefault(authentication);
|
---|
[626] | 50 | } catch (SecurityException e) {
|
---|
| 51 | }
|
---|
[1169] | 52 | }
|
---|
[626] | 53 |
|
---|
[1169] | 54 | /**
|
---|
| 55 | * The authentication class handling the login requests.
|
---|
| 56 | */
|
---|
| 57 | private static class OsmAuth extends Authenticator {
|
---|
| 58 | /**
|
---|
| 59 | * Set to true, when the autenticator tried the password once.
|
---|
| 60 | */
|
---|
| 61 | boolean passwordtried = false;
|
---|
| 62 | /**
|
---|
| 63 | * Whether the user cancelled the password dialog
|
---|
| 64 | */
|
---|
| 65 | boolean authCancelled = false;
|
---|
[626] | 66 |
|
---|
[1169] | 67 | @Override protected PasswordAuthentication getPasswordAuthentication() {
|
---|
| 68 | String username = Main.pref.get("osm-server.username");
|
---|
| 69 | String password = Main.pref.get("osm-server.password");
|
---|
| 70 | if (passwordtried || username.equals("") || password.equals("")) {
|
---|
| 71 | JPanel p = new JPanel(new GridBagLayout());
|
---|
[1670] | 72 | if (!username.equals("") && !password.equals("")) {
|
---|
[1169] | 73 | p.add(new JLabel(tr("Incorrect password or username.")), GBC.eop());
|
---|
[1670] | 74 | }
|
---|
[1169] | 75 | p.add(new JLabel(tr("Username")), GBC.std().insets(0,0,10,0));
|
---|
| 76 | JTextField usernameField = new JTextField(username, 20);
|
---|
| 77 | p.add(usernameField, GBC.eol());
|
---|
| 78 | p.add(new JLabel(tr("Password")), GBC.std().insets(0,0,10,0));
|
---|
| 79 | JPasswordField passwordField = new JPasswordField(password, 20);
|
---|
| 80 | p.add(passwordField, GBC.eol());
|
---|
| 81 | JLabel warning = new JLabel(tr("Warning: The password is transferred unencrypted."));
|
---|
| 82 | warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
|
---|
| 83 | p.add(warning, GBC.eop());
|
---|
[626] | 84 |
|
---|
[1169] | 85 | JCheckBox savePassword = new JCheckBox(tr("Save user and password (unencrypted)"), !username.equals("") && !password.equals(""));
|
---|
| 86 | p.add(savePassword, GBC.eop());
|
---|
[626] | 87 |
|
---|
[1670] | 88 | int choice = new ExtendedDialog(Main.parent,
|
---|
| 89 | tr("Enter Password"),
|
---|
[1397] | 90 | p,
|
---|
[1670] | 91 | new String[] {tr("Login"), tr("Cancel")},
|
---|
| 92 | new String[] {"ok.png", "cancel.png"}).getValue();
|
---|
| 93 |
|
---|
[1397] | 94 | if (choice != 1) {
|
---|
[1169] | 95 | authCancelled = true;
|
---|
| 96 | return null;
|
---|
| 97 | }
|
---|
| 98 | username = usernameField.getText();
|
---|
| 99 | password = String.valueOf(passwordField.getPassword());
|
---|
| 100 | if (savePassword.isSelected()) {
|
---|
| 101 | Main.pref.put("osm-server.username", username);
|
---|
| 102 | Main.pref.put("osm-server.password", password);
|
---|
| 103 | }
|
---|
| 104 | if (username.equals(""))
|
---|
| 105 | return null;
|
---|
| 106 | }
|
---|
| 107 | passwordtried = true;
|
---|
| 108 | return new PasswordAuthentication(username, password.toCharArray());
|
---|
| 109 | }
|
---|
| 110 | }
|
---|
[626] | 111 |
|
---|
[1169] | 112 | /**
|
---|
| 113 | * Must be called before each connection attemp to initialize the authentication.
|
---|
| 114 | */
|
---|
| 115 | protected final void initAuthentication() {
|
---|
| 116 | authentication.authCancelled = false;
|
---|
| 117 | authentication.passwordtried = false;
|
---|
| 118 | }
|
---|
[626] | 119 |
|
---|
[1169] | 120 | /**
|
---|
| 121 | * @return Whether the connection was cancelled.
|
---|
| 122 | */
|
---|
| 123 | protected final boolean isAuthCancelled() {
|
---|
| 124 | return authentication.authCancelled;
|
---|
| 125 | }
|
---|
[626] | 126 |
|
---|
[1169] | 127 | public void cancel() {
|
---|
| 128 | Main.pleaseWaitDlg.currentAction.setText(tr("Aborting..."));
|
---|
| 129 | cancel = true;
|
---|
| 130 | if (activeConnection != null) {
|
---|
| 131 | activeConnection.setConnectTimeout(100);
|
---|
| 132 | activeConnection.setReadTimeout(100);
|
---|
| 133 | try {
|
---|
| 134 | Thread.sleep(100);
|
---|
| 135 | } catch (InterruptedException ex) {}
|
---|
| 136 | activeConnection.disconnect();
|
---|
| 137 | }
|
---|
| 138 | }
|
---|
[626] | 139 |
|
---|
[1169] | 140 | protected void addAuth(HttpURLConnection con) throws CharacterCodingException {
|
---|
| 141 | CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
|
---|
| 142 | String auth = Main.pref.get("osm-server.username") + ":" + Main.pref.get("osm-server.password");
|
---|
| 143 | ByteBuffer bytes = encoder.encode(CharBuffer.wrap(auth));
|
---|
| 144 | con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes));
|
---|
| 145 | }
|
---|
[626] | 146 | }
|
---|