Prechádzať zdrojové kódy

Isolate SimpleCollection via an interface and avoid imports for it
This is needed on other platforms than Linux to avoid class loading problems on runtime in case secret-service.jar is missing

Ralph Plawetzki 6 rokov pred
rodič
commit
5217546f73

+ 9 - 0
main/keychain/src/main/java/org/cryptomator/keychain/GnomeKeyringAccess.java

@@ -0,0 +1,9 @@
+package org.cryptomator.keychain;
+
+public interface GnomeKeyringAccess {
+	public void storePassword(String key, CharSequence passphrase);
+
+	public char[] loadPassword(String key);
+
+	public void deletePassword(String key);
+}

+ 52 - 0
main/keychain/src/main/java/org/cryptomator/keychain/GnomeKeyringAccessImpl.java

@@ -0,0 +1,52 @@
+package org.cryptomator.keychain;
+
+import org.freedesktop.secret.simple.SimpleCollection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class GnomeKeyringAccessImpl implements GnomeKeyringAccess {
+	private static final Logger LOG = LoggerFactory.getLogger(GnomeKeyringAccessImpl.class);
+	private SimpleCollection keyring;
+
+	public GnomeKeyringAccessImpl() {
+		try {
+			keyring = new SimpleCollection();
+		} catch (IOException e) {
+			LOG.error("D-Bus reports a problem.", e);
+		}
+	}
+
+	public void storePassword(String key, CharSequence passphrase) {
+		List<String> list = keyring.getItems(createAttributes(key));
+		if (list == null) {
+			keyring.createItem("Cryptomator", passphrase, createAttributes(key));
+		}
+	}
+
+	public char[] loadPassword(String key) {
+		List<String> list = keyring.getItems(createAttributes(key));
+		if (list != null) {
+			return keyring.getSecret(list.get(0));
+		} else {
+			return null;
+		}
+	}
+
+	public void deletePassword(String key) {
+		List<String> list = keyring.getItems(createAttributes(key));
+		if (list != null) {
+			keyring.deleteItem(list.get(0));
+		}
+	}
+
+	private Map<String, String> createAttributes(String key) {
+		Map<String, String> attributes = new HashMap();
+		attributes.put("Vault", key);
+		return attributes;
+	}
+}

+ 25 - 0
main/keychain/src/main/java/org/cryptomator/keychain/LinuxKeychainTester.java

@@ -0,0 +1,25 @@
+package org.cryptomator.keychain;
+
+import java.util.Optional;
+
+public class LinuxKeychainTester {
+	public static boolean secretServiceIsAvailable() {
+		try {
+			Class.forName("org.freedesktop.secret.simple.SimpleCollection");
+			return true;
+		} catch (ClassNotFoundException e) {
+			return false;
+		}
+	}
+
+	public static Optional<GnomeKeyringAccess> getSecretService() {
+		if (!secretServiceIsAvailable()) return Optional.empty();
+		try {
+			Class clazz = Class.forName("org.cryptomator.keychain.GnomeKeyringAccessImpl");
+			GnomeKeyringAccess keyring = (GnomeKeyringAccess) clazz.getDeclaredConstructor().newInstance();
+			return Optional.of(keyring);
+		} catch (Exception e) {
+			return Optional.empty();
+		}
+	}
+}

+ 6 - 34
main/keychain/src/main/java/org/cryptomator/keychain/LinuxSecretServiceAccess.java

@@ -2,66 +2,38 @@ package org.cryptomator.keychain;
 
 import com.google.common.base.Preconditions;
 import org.apache.commons.lang3.SystemUtils;
-import org.freedesktop.secret.simple.SimpleCollection;
 
 import javax.inject.Inject;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 
 public class LinuxSecretServiceAccess implements KeychainAccessStrategy {
-	private final Optional<SimpleCollection> gnomeLoginKeyring;
+	private final Optional<GnomeKeyringAccess> gnomeLoginKeyring;
 
 	@Inject
 	public LinuxSecretServiceAccess() {
-		SimpleCollection keyring = null;
-		try {
-			keyring = new SimpleCollection();
-		} catch (Exception e) {
-			// Accessing secret-service DBus API failed
-		} finally {
-			gnomeLoginKeyring = Optional.ofNullable(keyring);
-		}
+		gnomeLoginKeyring = LinuxKeychainTester.getSecretService();
 	}
 
 	@Override
 	public boolean isSupported() {
-		return SystemUtils.IS_OS_LINUX && gnomeLoginKeyring.isPresent();
+		return SystemUtils.IS_OS_LINUX && LinuxKeychainTester.getSecretService().isPresent();
 	}
 
 	@Override
 	public void storePassphrase(String key, CharSequence passphrase) {
 		Preconditions.checkState(gnomeLoginKeyring.isPresent());
-		List<String> list = gnomeLoginKeyring.get().getItems(createAttributes(key));
-		if (list == null) {
-			gnomeLoginKeyring.get().createItem("Cryptomator", passphrase, createAttributes(key));
-		}
+		gnomeLoginKeyring.get().storePassword(key, passphrase);
 	}
 
 	@Override
 	public char[] loadPassphrase(String key) {
 		Preconditions.checkState(gnomeLoginKeyring.isPresent());
-		List<String> list = gnomeLoginKeyring.get().getItems(createAttributes(key));
-		if (list != null) {
-			return gnomeLoginKeyring.get().getSecret(list.get(0));
-		} else {
-			return null;
-		}
+		return gnomeLoginKeyring.get().loadPassword(key);
 	}
 
 	@Override
 	public void deletePassphrase(String key) {
 		Preconditions.checkState(gnomeLoginKeyring.isPresent());
-		List<String> list = gnomeLoginKeyring.get().getItems(createAttributes(key));
-		if (list != null) {
-			gnomeLoginKeyring.get().deleteItem(list.get(0));
-		}
-	}
-
-	private Map<String, String> createAttributes(String key) {
-		Map<String, String> attributes = new HashMap();
-		attributes.put("Vault", key);
-		return attributes;
+		gnomeLoginKeyring.get().deletePassword(key);
 	}
 }