Przeglądaj źródła

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 lat temu
rodzic
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);
 	}
 }