001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.preferences.server;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import org.openstreetmap.josm.Main;
007import org.openstreetmap.josm.data.Preferences;
008import org.openstreetmap.josm.data.oauth.OAuthToken;
009import org.openstreetmap.josm.io.auth.CredentialsAgent;
010import org.openstreetmap.josm.io.auth.CredentialsAgentException;
011import org.openstreetmap.josm.tools.CheckParameterUtil;
012
013
014public class OAuthAccessTokenHolder {
015    private  static OAuthAccessTokenHolder instance;
016
017    public static OAuthAccessTokenHolder getInstance() {
018        if (instance == null) {
019            instance = new OAuthAccessTokenHolder();
020        }
021        return instance;
022    }
023
024    private boolean saveToPreferences;
025    private String accessTokenKey;
026    private String accessTokenSecret;
027
028    /**
029     * Replies true if current access token should be saved to the preferences file.
030     *
031     * @return true if current access token should be saved to the preferences file.
032     */
033    public boolean isSaveToPreferences() {
034        return saveToPreferences;
035    }
036
037    /**
038     * Sets whether the current access token should be saved to the preferences file.
039     *
040     * If true, the access token is saved in clear text to the preferences file. The same
041     * access token can therefore be used in multiple JOSM sessions.
042     *
043     * If false, the access token isn't saved to the preferences file. If JOSM is closed,
044     * the access token is lost and new token has to be generated by the OSM server the
045     * next time JOSM is used.
046     *
047     * @param saveToPreferences
048     */
049    public void setSaveToPreferences(boolean saveToPreferences) {
050        this.saveToPreferences = saveToPreferences;
051    }
052
053    /**
054     * Replies the access token key. null, if no access token key is currently set.
055     *
056     * @return the access token key
057     */
058    public String getAccessTokenKey() {
059        return accessTokenKey;
060    }
061
062    /**
063     * Sets the access token key. Pass in null to remove the current access token key.
064     *
065     * @param accessTokenKey the access token key
066     */
067    public void setAccessTokenKey(String accessTokenKey) {
068        this.accessTokenKey = accessTokenKey;
069    }
070
071    /**
072     * Replies the access token secret. null, if no access token secret is currently set.
073     *
074     * @return the access token secret
075     */
076    public String getAccessTokenSecret() {
077        return accessTokenSecret;
078    }
079
080    /**
081     * Sets the access token secret. Pass in null to remove the current access token secret.
082     *
083     * @param accessTokenSecret
084     */
085    public void setAccessTokenSecret(String accessTokenSecret) {
086        this.accessTokenSecret = accessTokenSecret;
087    }
088
089    public OAuthToken getAccessToken() {
090        if (!containsAccessToken())
091            return null;
092        return new OAuthToken(accessTokenKey, accessTokenSecret);
093    }
094
095    /**
096     * Sets the access token hold by this holder.
097     *
098     * @param accessTokenKey the access token key
099     * @param accessTokenSecret the access token secret
100     */
101    public void setAccessToken(String accessTokenKey, String accessTokenSecret) {
102        this.accessTokenKey = accessTokenKey;
103        this.accessTokenSecret = accessTokenSecret;
104    }
105
106    /**
107     * Sets the access token hold by this holder.
108     *
109     * @param token the access token. Can be null to clear the content in this holder.
110     */
111    public void setAccessToken(OAuthToken token) {
112        if (token == null) {
113            this.accessTokenKey = null;
114            this.accessTokenSecret = null;
115        } else {
116            this.accessTokenKey = token.getKey();
117            this.accessTokenSecret = token.getSecret();
118        }
119    }
120
121    /**
122     * Replies true if this holder contains an complete access token, consisting of an
123     * Access Token Key and an Access Token Secret.
124     *
125     * @return true if this holder contains an complete access token
126     */
127    public boolean containsAccessToken() {
128        return accessTokenKey != null && accessTokenSecret != null;
129    }
130
131    /**
132     * Initializes the content of this holder from the Access Token managed by the
133     * credential manager.
134     *
135     * @param pref the preferences. Must not be null.
136     * @param cm the credential manager. Must not be null.
137     * @throws IllegalArgumentException thrown if cm is null
138     */
139    public void init(Preferences pref, CredentialsAgent cm) throws IllegalArgumentException {
140        CheckParameterUtil.ensureParameterNotNull(pref, "pref");
141        CheckParameterUtil.ensureParameterNotNull(cm, "cm");
142        OAuthToken token = null;
143        try {
144            token = cm.lookupOAuthAccessToken();
145        } catch(CredentialsAgentException e) {
146            e.printStackTrace();
147            Main.warn(tr("Failed to retrieve OAuth Access Token from credential manager"));
148            Main.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
149        }
150        saveToPreferences = pref.getBoolean("oauth.access-token.save-to-preferences", true);
151        if (token != null) {
152            accessTokenKey = token.getKey();
153            accessTokenSecret = token.getSecret();
154        }
155    }
156
157    /**
158     * Saves the content of this holder to the preferences and a credential store managed
159     * by a credential manager.
160     *
161     * @param preferences the preferences. Must not be null.
162     * @param cm the credentials manager. Must not be null.
163     * @throws IllegalArgumentException thrown if preferences is null
164     * @throws IllegalArgumentException thrown if cm is null
165     */
166    public void save(Preferences preferences, CredentialsAgent cm) throws IllegalArgumentException {
167        CheckParameterUtil.ensureParameterNotNull(preferences, "preferences");
168        CheckParameterUtil.ensureParameterNotNull(cm, "cm");
169        preferences.put("oauth.access-token.save-to-preferences", saveToPreferences);
170        try {
171            if (!saveToPreferences) {
172                cm.storeOAuthAccessToken(null);
173            } else {
174                cm.storeOAuthAccessToken(new OAuthToken(accessTokenKey, accessTokenSecret));
175            }
176        } catch(CredentialsAgentException e){
177            e.printStackTrace();
178            Main.warn(tr("Failed to store OAuth Access Token to credentials manager"));
179            Main.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
180        }
181    }
182
183    /**
184     * Clears the content of this holder
185     */
186    public void clear() {
187        accessTokenKey = null;
188        accessTokenSecret = null;
189    }
190}