001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io.auth;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Component;
007import java.net.PasswordAuthentication;
008import java.net.Authenticator.RequestorType;
009
010import javax.swing.text.html.HTMLEditorKit;
011
012import org.openstreetmap.josm.Main;
013import org.openstreetmap.josm.data.oauth.OAuthToken;
014import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel;
015import org.openstreetmap.josm.gui.widgets.HtmlPanel;
016import org.openstreetmap.josm.io.OsmApi;
017import org.openstreetmap.josm.tools.Utils;
018
019/**
020 * This is the default credentials agent in JOSM. It keeps username and password for both
021 * the OSM API and an optional HTTP proxy in the JOSM preferences file.
022 *
023 */
024public class JosmPreferencesCredentialAgent extends AbstractCredentialsAgent {
025
026    /**
027     * @see CredentialsAgent#lookup
028     */
029    @Override
030    public PasswordAuthentication lookup(RequestorType requestorType, String host) throws CredentialsAgentException{
031        if (requestorType == null)
032            return null;
033        String user;
034        String password;
035        switch(requestorType) {
036        case SERVER:
037            if (Utils.equal(OsmApi.getOsmApi().getHost(), host)) {
038                user = Main.pref.get("osm-server.username", null);
039                password = Main.pref.get("osm-server.password", null);
040            } else if(host != null) {
041                user = Main.pref.get("server.username."+host, null);
042                password = Main.pref.get("server.password."+host, null);
043            } else {
044                user = null;
045                password = null;
046            }
047            if (user == null)
048                return null;
049            return new PasswordAuthentication(user, password == null ? new char[0] : password.toCharArray());
050        case PROXY:
051            user = Main.pref.get(ProxyPreferencesPanel.PROXY_USER, null);
052            password = Main.pref.get(ProxyPreferencesPanel.PROXY_PASS, null);
053            if (user == null)
054                return null;
055            return new PasswordAuthentication(user, password == null ? new char[0] : password.toCharArray());
056        }
057        return null;
058    }
059
060    /**
061     * @see CredentialsAgent#store
062     */
063    @Override
064    public void store(RequestorType requestorType, String host, PasswordAuthentication credentials) throws CredentialsAgentException {
065        if (requestorType == null)
066            return;
067        switch(requestorType) {
068        case SERVER:
069            if (Utils.equal(OsmApi.getOsmApi().getHost(), host)) {
070                Main.pref.put("osm-server.username", credentials.getUserName());
071                if (credentials.getPassword() == null) {
072                    Main.pref.put("osm-server.password", null);
073                } else {
074                    Main.pref.put("osm-server.password", String.valueOf(credentials.getPassword()));
075                }
076            } else if(host != null) {
077                Main.pref.put("server.username."+host, credentials.getUserName());
078                if (credentials.getPassword() == null) {
079                    Main.pref.put("server.password."+host, null);
080                } else {
081                    Main.pref.put("server.password."+host, String.valueOf(credentials.getPassword()));
082                }
083            }
084            break;
085        case PROXY:
086            Main.pref.put(ProxyPreferencesPanel.PROXY_USER, credentials.getUserName());
087            if (credentials.getPassword() == null) {
088                Main.pref.put(ProxyPreferencesPanel.PROXY_PASS, null);
089            } else {
090                Main.pref.put(ProxyPreferencesPanel.PROXY_PASS, String.valueOf(credentials.getPassword()));
091            }
092            break;
093        }
094    }
095
096    /**
097     * Lookup the current OAuth Access Token to access the OSM server. Replies null, if no
098     * Access Token is currently managed by this CredentialManager.
099     *
100     * @return the current OAuth Access Token to access the OSM server.
101     * @throws CredentialsAgentException thrown if something goes wrong
102     */
103    @Override
104    public OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException {
105        String accessTokenKey = Main.pref.get("oauth.access-token.key", null);
106        String accessTokenSecret = Main.pref.get("oauth.access-token.secret", null);
107        if (accessTokenKey == null && accessTokenSecret == null)
108            return null;
109        return new OAuthToken(accessTokenKey, accessTokenSecret);
110    }
111
112    /**
113     * Stores the OAuth Access Token <code>accessToken</code>.
114     *
115     * @param accessToken the access Token. null, to remove the Access Token.
116     * @throws CredentialsAgentException thrown if something goes wrong
117     */
118    @Override
119    public void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException {
120        if (accessToken == null) {
121            Main.pref.put("oauth.access-token.key", null);
122            Main.pref.put("oauth.access-token.secret", null);
123        } else {
124            Main.pref.put("oauth.access-token.key", accessToken.getKey());
125            Main.pref.put("oauth.access-token.secret", accessToken.getSecret());
126        }
127    }
128
129    @Override
130    public Component getPreferencesDecorationPanel() {
131        HtmlPanel pnlMessage = new HtmlPanel();
132        HTMLEditorKit kit = (HTMLEditorKit)pnlMessage.getEditorPane().getEditorKit();
133        kit.getStyleSheet().addRule(".warning-body {background-color:rgb(253,255,221);padding: 10pt; border-color:rgb(128,128,128);border-style: solid;border-width: 1px;}");
134        pnlMessage.setText(
135                tr(
136                        "<html><body>"
137                        + "<p class=\"warning-body\">"
138                        + "<strong>Warning:</strong> The password is stored in plain text in the JOSM preferences file. "
139                        + "Furthermore, it is transferred <strong>unencrypted</strong> in every request sent to the OSM server. "
140                        + "<strong>Do not use a valuable password.</strong>"
141                        + "</p>"
142                        + "</body></html>"
143                )
144        );
145        return pnlMessage;
146    }
147
148    @Override
149    public String getSaveUsernameAndPasswordCheckboxText() {
150        return tr("Save user and password (unencrypted)");
151    }
152
153}