Changeset 36049 in osm for applications/editors/josm/plugins/native-password-manager
- Timestamp:
- 2023-02-08T18:32:01+01:00 (21 months ago)
- Location:
- applications/editors/josm/plugins/native-password-manager
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/native-password-manager/build.xml
r34472 r36049 5 5 <property name="commit.message" value="Commit message"/> 6 6 <!-- enter the *lowest* JOSM version this plugin is currently compatible with --> 7 <property name="plugin.main.version" value="1 4153"/>7 <property name="plugin.main.version" value="18650"/> 8 8 <property name="plugin.author" value="Paul Hartmann"/> 9 9 <property name="plugin.class" value="org.openstreetmap.josm.plugins.npm.NPMPlugin"/> -
applications/editors/josm/plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/NPMCredentialsAgent.java
r35665 r36049 7 7 import java.net.Authenticator.RequestorType; 8 8 import java.net.PasswordAuthentication; 9 import java.net.URI; 9 10 import java.nio.charset.StandardCharsets; 10 11 import java.util.ArrayList; 11 import java.util.HashMap; 12 import java.util.Arrays; 13 import java.util.EnumMap; 12 14 import java.util.List; 13 15 import java.util.Map; 16 import java.util.stream.Collectors; 14 17 import java.util.zip.CRC32; 15 18 … … 18 21 import org.netbeans.spi.keyring.KeyringProvider; 19 22 import org.openstreetmap.josm.data.Preferences; 23 import org.openstreetmap.josm.data.oauth.IOAuthToken; 24 import org.openstreetmap.josm.data.oauth.OAuth20Exception; 25 import org.openstreetmap.josm.data.oauth.OAuth20Parameters; 26 import org.openstreetmap.josm.data.oauth.OAuth20Token; 20 27 import org.openstreetmap.josm.data.oauth.OAuthToken; 28 import org.openstreetmap.josm.data.oauth.OAuthVersion; 21 29 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 22 30 import org.openstreetmap.josm.io.DefaultProxySelector; … … 26 34 import org.openstreetmap.josm.spi.preferences.Config; 27 35 36 /** 37 * The native password manager credentials agent 38 */ 28 39 public class NPMCredentialsAgent extends AbstractCredentialsAgent { 29 40 30 41 private KeyringProvider provider; 31 private NPMType type;42 private final NPMType type; 32 43 33 44 /** 34 * Cache the results since there might be pop 45 * Cache the results since there might be pop-ups and password prompts from 35 46 * the native manager. This can get annoying, if it shows too often. 36 * 47 * <br> 37 48 * Yes, there is another cache in AbstractCredentialsAgent. It is used 38 49 * to avoid prompting the user for login multiple times in one session, … … 40 51 * In contrast, this cache avoids read request the backend in general. 41 52 */ 42 private Map<RequestorType, PasswordAuthentication> credentialsCache = new HashMap<>();53 private final Map<RequestorType, PasswordAuthentication> credentialsCache = new EnumMap<>(RequestorType.class); 43 54 private OAuthToken oauthCache; 44 55 56 /** 57 * Create a new {@link NPMCredentialsAgent} 58 * @param type The backend storage type 59 */ 45 60 public NPMCredentialsAgent(NPMType type) { 46 61 this.type = type; … … 96 111 97 112 @Override 98 public PasswordAuthentication lookup(RequestorType rt, String host) throws CredentialsAgentException{113 public PasswordAuthentication lookup(RequestorType rt, String host) { 99 114 PasswordAuthentication cache = credentialsCache.get(rt); 100 115 if (cache != null) … … 126 141 127 142 @Override 128 public void store(RequestorType rt, String host, PasswordAuthentication credentials) throws CredentialsAgentException{143 public void store(RequestorType rt, String host, PasswordAuthentication credentials) { 129 144 char[] username, password; 130 145 if (credentials == null) { … … 170 185 getProvider().save(prefix+".password", password, passwordDescription); 171 186 } 172 credentialsCache.put(rt, new PasswordAuthentication(stringNotNull(username), password ));173 } 174 } 175 176 @Override 177 public OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException{187 credentialsCache.put(rt, new PasswordAuthentication(stringNotNull(username), password != null ? password : new char[0])); 188 } 189 } 190 191 @Override 192 public OAuthToken lookupOAuthAccessToken() { 178 193 if (oauthCache != null) 179 194 return oauthCache; … … 185 200 186 201 @Override 187 public void storeOAuthAccessToken(OAuthToken oat) throws CredentialsAgentException { 202 public IOAuthToken lookupOAuthAccessToken(String host) throws CredentialsAgentException { 203 String prolog = getOAuthDescriptor(); 204 OAuthVersion[] versions = OAuthVersion.values(); 205 // Prefer newer OAuth protocols 206 for (int i = versions.length - 1; i >= 0; i--) { 207 OAuthVersion version = versions[i]; 208 char[] tokenObject = getProvider().read(prolog + ".object." + version + "." + host); 209 char[] parametersObject = getProvider().read(prolog + ".parameters." + version + "." + host); 210 if (version == OAuthVersion.OAuth20 // There is currently only an OAuth 2.0 path 211 && tokenObject != null && tokenObject.length > 0 212 && parametersObject != null && parametersObject.length > 0) { 213 OAuth20Parameters oAuth20Parameters = new OAuth20Parameters(stringNotNull(parametersObject)); 214 try { 215 return new OAuth20Token(oAuth20Parameters, stringNotNull(tokenObject)); 216 } catch (OAuth20Exception e) { 217 throw new CredentialsAgentException(e); 218 } 219 } 220 } 221 return null; 222 } 223 224 @Override 225 public void storeOAuthAccessToken(OAuthToken oat) { 188 226 String key, secret; 189 227 if (oat == null) { 190 228 key = null; 191 229 secret = null; 192 } 193 else { 230 } else { 194 231 key = oat.getKey(); 195 232 secret = oat.getSecret(); … … 207 244 } 208 245 246 @Override 247 public void storeOAuthAccessToken(String host, IOAuthToken accessToken) { 248 String prolog = getOAuthDescriptor(); 249 if (accessToken == null) { 250 // Assume all oauth tokens must be removed 251 for (OAuthVersion version : OAuthVersion.values()) { 252 getProvider().delete(prolog + ".object." + version + "." + host); 253 getProvider().delete(prolog + ".parameters." + version + "." + host); 254 } 255 } else { 256 OAuthVersion oauthType = accessToken.getOAuthType(); 257 getProvider().save(prolog + ".object." + oauthType + "." + host, 258 accessToken.toPreferencesString().toCharArray(), 259 tr("JOSM/OAuth/{0}/Token", URI.create(host).getHost())); 260 getProvider().save(prolog + ".parameters." + oauthType + "." + host, 261 accessToken.getParameters().toPreferencesString().toCharArray(), 262 tr("JOSM/OAuth/{0}/Parameters", URI.create(host).getHost())); 263 } 264 } 265 209 266 private static String stringNotNull(char[] charData) { 210 267 if (charData == null) … … 217 274 HtmlPanel pnlMessage = new HtmlPanel(); 218 275 HTMLEditorKit kit = (HTMLEditorKit)pnlMessage.getEditorPane().getEditorKit(); 219 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;}"); 276 kit.getStyleSheet().addRule(".warning-body {background-color:rgb(253,255,221);padding: 10pt;" + 277 "border-color:rgb(128,128,128);border-style: solid;border-width: 1px;}"); 220 278 StringBuilder text = new StringBuilder(); 221 text.append("<html><body>" 222 + "<p class=\"warning-body\">" 223 + "<strong>"+tr("Native Password Manager Plugin")+"</strong><br>" 224 + tr("The username and password is protected by {0}.", type.getName()) 225 ); 279 text.append("<html><body><p class=\"warning-body\"><strong>") 280 .append(tr("Native Password Manager Plugin")) 281 .append("</strong><br>") 282 .append(tr("The username and password is protected by {0}.", type.getName())); 226 283 List<String> sensitive = new ArrayList<>(); 227 284 if (Config.getPref().get("osm-server.username", null) != null) { … … 243 300 sensitive.add(tr("oauth secret")); 244 301 } 302 List<String> otherKeys = Config.getPref().getSensitive().stream().sorted().collect(Collectors.toList()); 303 // Remove keys for which we have specific translated texts 304 otherKeys.removeAll(Arrays.asList("osm-server.username", "osm-server.password", 305 DefaultProxySelector.PROXY_USER, DefaultProxySelector.PROXY_PASS, 306 "oauth.access-token.key", "oauth.access-token.secret")); 307 sensitive.addAll(otherKeys); 245 308 if (!sensitive.isEmpty()) { 246 text.append(tr("<br><strong>Warning:</strong> There may be sensitive data left in your preference file. ({0})", String.join(", ", sensitive))); 309 text.append(tr("<br><strong>Warning:</strong> There may be sensitive data left in your preference file. ({0})", 310 String.join(", ", sensitive))); 247 311 } 248 312 pnlMessage.setText(text.toString());
Note:
See TracChangeset
for help on using the changeset viewer.