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