Changeset 12992 in josm for trunk/src


Ignore:
Timestamp:
2017-10-14T00:09:56+02:00 (7 years ago)
Author:
Don-vip
Message:

fix #15435 - do not cache incorrect login credentials when using basic auth

Location:
trunk/src/org/openstreetmap/josm
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/io/CredentialDialog.java

    r12854 r12992  
    2323import javax.swing.AbstractAction;
    2424import javax.swing.BorderFactory;
     25import javax.swing.JButton;
    2526import javax.swing.JCheckBox;
    2627import javax.swing.JDialog;
     
    3031
    3132import org.openstreetmap.josm.Main;
    32 import org.openstreetmap.josm.gui.SideButton;
    3333import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
    3434import org.openstreetmap.josm.gui.help.HelpUtil;
     
    127127    protected JPanel createButtonPanel() {
    128128        JPanel pnl = new JPanel(new FlowLayout());
    129         pnl.add(new SideButton(new OKAction()));
    130         pnl.add(new SideButton(new CancelAction()));
    131         pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/Password"))));
     129        pnl.add(new JButton(new OKAction()));
     130        pnl.add(new JButton(new CancelAction()));
     131        pnl.add(new JButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/Password"))));
    132132        return pnl;
    133133    }
     
    266266            gc.weighty = 1.0;
    267267            add(new JPanel(), gc);
    268 
    269268        }
    270269
     
    375374        public void focusGained(FocusEvent e) {
    376375            if (e.getSource() instanceof JTextField) {
    377                 JTextField tf = (JTextField) e.getSource();
    378                 tf.selectAll();
     376                ((JTextField) e.getSource()).selectAll();
    379377            }
    380378        }
     
    410408                    return;
    411409                } else {
    412                     OKAction okAction = owner.new OKAction();
    413                     okAction.actionPerformed(null);
     410                    owner.new OKAction().actionPerformed(null);
    414411                }
    415412            }
     
    421418            putValue(NAME, tr("Authenticate"));
    422419            putValue(SHORT_DESCRIPTION, tr("Authenticate with the supplied username and password"));
    423             putValue(SMALL_ICON, ImageProvider.get("ok"));
    424         }
    425 
    426         @Override
    427         public void actionPerformed(ActionEvent arg0) {
     420            new ImageProvider("ok").getResource().attachImageIcon(this);
     421        }
     422
     423        @Override
     424        public void actionPerformed(ActionEvent e) {
    428425            setCanceled(false);
    429426            setVisible(false);
     
    435432            putValue(NAME, tr("Cancel"));
    436433            putValue(SHORT_DESCRIPTION, tr("Cancel authentication"));
    437             putValue(SMALL_ICON, ImageProvider.get("cancel"));
     434            new ImageProvider("cancel").getResource().attachImageIcon(this);
    438435        }
    439436
     
    444441
    445442        @Override
    446         public void actionPerformed(ActionEvent arg0) {
     443        public void actionPerformed(ActionEvent e) {
    447444            cancel();
    448445        }
  • trunk/src/org/openstreetmap/josm/io/OsmApi.java

    r12846 r12992  
    99import java.io.StringReader;
    1010import java.io.StringWriter;
     11import java.net.Authenticator.RequestorType;
    1112import java.net.ConnectException;
    1213import java.net.HttpURLConnection;
     
    3334import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3435import org.openstreetmap.josm.io.Capabilities.CapabilitiesParser;
     36import org.openstreetmap.josm.io.auth.CredentialsManager;
    3537import org.openstreetmap.josm.spi.preferences.Config;
    3638import org.openstreetmap.josm.tools.CheckParameterUtil;
     
    704706                    else
    705707                        throw new OsmApiException(retCode, errorHeader, errorBody);
     708                case HttpURLConnection.HTTP_UNAUTHORIZED:
    706709                case HttpURLConnection.HTTP_FORBIDDEN:
    707                     OsmApiException e = new OsmApiException(retCode, errorHeader, errorBody);
    708                     e.setAccessedUrl(activeConnection.getURL().toString());
    709                     throw e;
     710                    CredentialsManager.getInstance().purgeCredentialsCache(RequestorType.SERVER);
     711                    throw new OsmApiException(retCode, errorHeader, errorBody, activeConnection.getURL().toString(),
     712                            doAuthenticate ? retrieveBasicAuthorizationLogin(client) : null);
    710713                default:
    711714                    throw new OsmApiException(retCode, errorHeader, errorBody);
  • trunk/src/org/openstreetmap/josm/io/OsmApiException.java

    r12620 r12992  
    1515    private String errorBody;
    1616    private String accessedUrl;
     17    private String login;
    1718
    1819    /**
     
    2324     * @param errorBody The error body, as transmitted in the HTTP response body
    2425     * @param accessedUrl The complete URL accessed when this error occured
    25      * @since 5584
    26      */
    27     public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl) {
     26     * @param login the login used to connect to OSM API (can be null)
     27     * @since 12992
     28     */
     29    public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl, String login) {
    2830        this.responseCode = responseCode;
    2931        this.errorHeader = errorHeader;
    3032        this.errorBody = errorBody;
    3133        this.accessedUrl = accessedUrl;
     34        this.login = login;
     35    }
     36
     37    /**
     38     * Constructs an {@code OsmApiException} with the specified response code, error header and error body
     39     * @param responseCode The HTTP response code replied by the OSM server.
     40     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
     41     * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
     42     * @param errorBody The error body, as transmitted in the HTTP response body
     43     * @param accessedUrl The complete URL accessed when this error occured
     44     * @since 5584
     45     */
     46    public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl) {
     47        this(responseCode, errorHeader, errorBody, accessedUrl, null);
    3248    }
    3349
     
    199215        return accessedUrl;
    200216    }
     217
     218    /**
     219     * Sets the login used to connect to OSM API.
     220     * @param login the login used to connect to OSM API
     221     * @since 12992
     222     */
     223    public void setLogin(String login) {
     224        this.login = login;
     225    }
     226
     227    /**
     228     * Replies the login used to connect to OSM API.
     229     * @return the login used to connect to OSM API, or {@code null}
     230     * @since 12992
     231     */
     232    public String getLogin() {
     233        return login;
     234    }
    201235}
  • trunk/src/org/openstreetmap/josm/io/OsmConnection.java

    r12931 r12992  
    3131 */
    3232public class OsmConnection {
     33
     34    private static final String BASIC_AUTH = "Basic ";
     35
    3336    protected boolean cancel;
    3437    protected HttpClient activeConnection;
     
    7578
    7679    /**
     80     * Retrieves login from basic authentication header, if set.
     81     *
     82     * @param con the connection
     83     * @return login from basic authentication header, or {@code null}
     84     * @throws OsmTransferException if something went wrong. Check for nested exceptions
     85     * @since 12992
     86     */
     87    protected String retrieveBasicAuthorizationLogin(HttpClient con) throws OsmTransferException {
     88        String auth = con.getRequestHeader("Authorization");
     89        if (auth != null && auth.startsWith(BASIC_AUTH)) {
     90            try {
     91                String[] token = new String(Base64.getDecoder().decode(auth.substring(BASIC_AUTH.length())),
     92                        StandardCharsets.UTF_8).split(":");
     93                if (token.length == 2) {
     94                    return token[0];
     95                }
     96            } catch (IllegalArgumentException e) {
     97                Logging.error(e);
     98            }
     99        }
     100        return null;
     101    }
     102
     103    /**
    77104     * Adds an authentication header for basic authentication
    78105     *
     
    98125                String password = response.getPassword() == null ? "" : String.valueOf(response.getPassword());
    99126                String token = username + ':' + password;
    100                 con.setHeader("Authorization", "Basic "+Base64.getEncoder().encodeToString(token.getBytes(StandardCharsets.UTF_8)));
     127                con.setHeader("Authorization", BASIC_AUTH + Base64.getEncoder().encodeToString(token.getBytes(StandardCharsets.UTF_8)));
    101128            }
    102129        }
  • trunk/src/org/openstreetmap/josm/io/OsmServerReader.java

    r12711 r12992  
    66import java.io.IOException;
    77import java.io.InputStream;
     8import java.net.Authenticator.RequestorType;
    89import java.net.HttpURLConnection;
    910import java.net.MalformedURLException;
     
    195196            }
    196197            try {
    197                 if (response.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED)
     198                if (response.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
     199                    CredentialsManager.getInstance().purgeCredentialsCache(RequestorType.SERVER);
    198200                    throw new OsmApiException(HttpURLConnection.HTTP_UNAUTHORIZED, null, null);
     201                }
    199202
    200203                if (response.getResponseCode() == HttpURLConnection.HTTP_PROXY_AUTH)
  • trunk/src/org/openstreetmap/josm/io/auth/AbstractCredentialsAgent.java

    r12869 r12992  
    6262
    6363        /*
    64          * Last request was successful and there was no credentials stored
    65          * in file (or only the username is stored).
    66          * -> Try to recall credentials that have been entered
    67          * manually in this session.
     64         * Last request was successful and there was no credentials stored in file (or only the username is stored).
     65         * -> Try to recall credentials that have been entered manually in this session.
    6866         */
    6967        if (!noSuccessWithLastResponse && memoryCredentialsCache.containsKey(requestorType) &&
     
    8987                        response.getPassword()
    9088                ));
    91             /*
    92              * User decides not to save credentials to file. Keep it
    93              * in memory so we don't have to ask over and over again.
    94              */
    9589            } else {
    96                 PasswordAuthentication pa = new PasswordAuthentication(response.getUsername(), response.getPassword());
    97                 memoryCredentialsCache.put(requestorType, pa);
     90                // User decides not to save credentials to file. Keep it in memory so we don't have to ask over and over again.
     91                memoryCredentialsCache.put(requestorType, new PasswordAuthentication(response.getUsername(), response.getPassword()));
    9892            }
    99         /*
    100          * We got it from file.
    101          */
    10293        } else {
     94            // We got it from file.
    10395            response.setUsername(username);
    10496            response.setPassword(password.toCharArray());
     
    10698        }
    10799        return response;
     100    }
     101
     102    @Override
     103    public final void purgeCredentialsCache(RequestorType requestorType) {
     104        memoryCredentialsCache.remove(requestorType);
    108105    }
    109106
  • trunk/src/org/openstreetmap/josm/io/auth/CredentialsAgent.java

    r8929 r12992  
    7474
    7575    /**
     76     * Purges the internal credentials cache for the given requestor type.
     77     * @param requestorType the type of service.
     78     * {@link RequestorType#SERVER} for the OSM API server, {@link RequestorType#PROXY} for a proxy server
     79     * @since 12992
     80     */
     81    void purgeCredentialsCache(RequestorType requestorType);
     82
     83    /**
    7684     * Provide a Panel that is shown below the API password / username fields
    7785     * in the JOSM Preferences. (E.g. a warning that password is saved unencrypted.)
  • trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java

    r12743 r12992  
    4343    private static CredentialsAgentFactory agentFactory;
    4444
     45    /**
     46     * Credentials agent factory.
     47     */
    4548    @FunctionalInterface
    4649    public interface CredentialsAgentFactory {
     50        /**
     51         * Returns the credentials agent instance.
     52         * @return the credentials agent instance
     53         */
    4754        CredentialsAgent getCredentialsAgent();
    4855    }
     
    148155        return delegate.getPreferencesDecorationPanel();
    149156    }
     157
     158    @Override
     159    public void purgeCredentialsCache(RequestorType requestorType) {
     160        delegate.purgeCredentialsCache(requestorType);
     161    }
    150162}
  • trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java

    r12686 r12992  
    266266                + "Please check the username and the password in the JOSM preferences."
    267267                + "</html>",
    268                 CredentialsManager.getInstance().getUsername()
     268                e.getLogin() != null ? e.getLogin() : CredentialsManager.getInstance().getUsername()
    269269        );
    270270    }
Note: See TracChangeset for help on using the changeset viewer.