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