Sebastian Stenzel 9 gadi atpakaļ
vecāks
revīzija
7b68c427d6

+ 6 - 0
main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystemFactory.java

@@ -8,6 +8,8 @@
  *******************************************************************************/
 package org.cryptomator.filesystem.crypto;
 
+import static org.cryptomator.filesystem.crypto.Constants.MASTERKEY_FILENAME;
+
 import java.io.UncheckedIOException;
 
 import javax.inject.Inject;
@@ -31,6 +33,10 @@ public class CryptoFileSystemFactory {
 		this.blockAlignedFileSystemFactory = blockAlignedFileSystemFactory;
 	}
 
+	public boolean isValidVaultStructure(Folder vaultLocation) {
+		return vaultLocation.file(MASTERKEY_FILENAME).exists();
+	}
+
 	public void initializeNew(Folder vaultLocation, CharSequence passphrase) {
 		masterkeys.initialize(vaultLocation, passphrase);
 	}

+ 1 - 8
main/ui/src/main/java/org/cryptomator/ui/MainApplication.java

@@ -17,7 +17,6 @@ import java.util.concurrent.ExecutorService;
 
 import org.apache.commons.lang3.SystemUtils;
 import org.cryptomator.ui.controllers.MainController;
-import org.cryptomator.ui.model.Vault;
 import org.cryptomator.ui.util.ActiveWindowStyleSupport;
 import org.cryptomator.ui.util.DeferredCloser;
 import org.cryptomator.ui.util.SingleInstanceManager;
@@ -90,18 +89,12 @@ public class MainApplication extends Application {
 	}
 
 	private void handleCommandLineArg(String arg) {
-		// only open files with our file extension:
-		if (!arg.endsWith(Vault.VAULT_FILE_EXTENSION)) {
-			LOG.warn("Invalid vault path %s", arg);
-			return;
-		}
-
 		// find correct location:
 		final Path path = FileSystems.getDefault().getPath(arg);
 		final Path vaultPath;
 		if (Files.isDirectory(path)) {
 			vaultPath = path;
-		} else if (Files.isRegularFile(path) && path.getParent().getFileName().toString().endsWith(Vault.VAULT_FILE_EXTENSION)) {
+		} else if (Files.isRegularFile(path)) {
 			vaultPath = path.getParent();
 		} else {
 			LOG.warn("Invalid vault path %s", arg);

+ 8 - 12
main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java

@@ -181,7 +181,7 @@ public class MainController extends AbstractFXMLViewController {
 	 * @param path non-null, writable, existing directory
 	 */
 	public void addVault(final Path path, boolean select) {
-		// TODO: Files.isWritable is broken on windows. Fix in Java 8u72, see https://bugs.openjdk.java.net/browse/JDK-8034057
+		// TODO: `|| !Files.isWritable(path)` is broken on windows. Fix in Java 8u72, see https://bugs.openjdk.java.net/browse/JDK-8034057
 		if (path == null) {
 			return;
 		}
@@ -189,7 +189,7 @@ public class MainController extends AbstractFXMLViewController {
 		final Path vaultPath;
 		if (path != null && Files.isDirectory(path)) {
 			vaultPath = path;
-		} else if (path != null && Files.isRegularFile(path) && path.getParent().getFileName().toString().endsWith(Vault.VAULT_FILE_EXTENSION)) {
+		} else if (path != null && Files.isRegularFile(path)) {
 			vaultPath = path.getParent();
 		} else {
 			return;
@@ -244,16 +244,12 @@ public class MainController extends AbstractFXMLViewController {
 	// ****************************************
 
 	private void showVault(Vault vault) {
-		try {
-			if (vault.isUnlocked()) {
-				this.showUnlockedView(vault);
-			} else if (vault.containsMasterKey()) {
-				this.showUnlockView(vault);
-			} else {
-				this.showInitializeView(vault);
-			}
-		} catch (IOException e) {
-			LOG.error("Failed to analyze directory.", e);
+		if (vault.isUnlocked()) {
+			this.showUnlockedView(vault);
+		} else if (vault.isValidVaultDirectory()) {
+			this.showUnlockView(vault);
+		} else {
+			this.showInitializeView(vault);
 		}
 	}
 

+ 11 - 14
main/ui/src/main/java/org/cryptomator/ui/model/Vault.java

@@ -12,7 +12,6 @@ import java.io.IOException;
 import java.io.Serializable;
 import java.io.UncheckedIOException;
 import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.Files;
 import java.nio.file.Path;
 import java.text.Normalizer;
 import java.text.Normalizer.Form;
@@ -20,9 +19,11 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.commons.lang3.CharUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.cryptomator.common.LazyInitializer;
 import org.cryptomator.common.Optionals;
 import org.cryptomator.crypto.engine.InvalidPassphraseException;
 import org.cryptomator.filesystem.FileSystem;
@@ -54,9 +55,6 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 
 	public static final String VAULT_FILE_EXTENSION = ".cryptomator";
 
-	@Deprecated
-	public static final String VAULT_MASTERKEY_FILE = "masterkey.cryptomator";
-
 	private final Path path;
 	private final Lazy<FrontendFactory> frontendFactory;
 	private final DeferredCloser closer;
@@ -65,6 +63,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 	private final ObjectProperty<Boolean> unlocked = new SimpleObjectProperty<Boolean>(this, "unlocked", Boolean.FALSE);
 	private final ObservableList<String> namesOfResourcesWithInvalidMac = FXThreads.observableListOnMainThread(FXCollections.observableArrayList());
 	private final Set<String> whitelistedResourcesWithInvalidMac = new HashSet<>();
+	private final AtomicReference<FileSystem> nioFileSystem = new AtomicReference<>();
 
 	private String mountName;
 	private Character winDriveLetter;
@@ -88,13 +87,17 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 		}
 	}
 
+	private FileSystem getNioFileSystem() {
+		return LazyInitializer.initializeLazily(nioFileSystem, () -> NioFileSystem.rootedAt(path));
+	}
+
 	// ******************************************************************************
 	// Commands
 	// ********************************************************************************/
 
 	public void create(CharSequence passphrase) throws IOException {
 		try {
-			FileSystem fs = NioFileSystem.rootedAt(path);
+			FileSystem fs = getNioFileSystem();
 			if (fs.children().count() > 0) {
 				throw new FileAlreadyExistsException(null, null, "Vault location not empty.");
 			}
@@ -106,8 +109,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 
 	public void changePassphrase(CharSequence oldPassphrase, CharSequence newPassphrase) throws IOException, InvalidPassphraseException {
 		try {
-			FileSystem fs = NioFileSystem.rootedAt(path);
-			cryptoFileSystemFactory.changePassphrase(fs, oldPassphrase, newPassphrase);
+			cryptoFileSystemFactory.changePassphrase(getNioFileSystem(), oldPassphrase, newPassphrase);
 		} catch (UncheckedIOException e) {
 			throw new IOException(e);
 		}
@@ -115,7 +117,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 
 	public synchronized void activateFrontend(CharSequence passphrase) throws FrontendCreationFailedException {
 		try {
-			FileSystem fs = NioFileSystem.rootedAt(path);
+			FileSystem fs = getNioFileSystem();
 			FileSystem shorteningFs = shorteningFileSystemFactory.get(fs);
 			FileSystem cryptoFs = cryptoFileSystemFactory.unlockExisting(shorteningFs, passphrase, this);
 			StatsFileSystem statsFs = new StatsFileSystem(cryptoFs);
@@ -191,12 +193,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 	}
 
 	public boolean isValidVaultDirectory() {
-		return Files.isDirectory(path) && path.getFileName().toString().endsWith(VAULT_FILE_EXTENSION);
-	}
-
-	public boolean containsMasterKey() throws IOException {
-		final Path masterKeyPath = path.resolve(VAULT_MASTERKEY_FILE);
-		return Files.isRegularFile(masterKeyPath);
+		return cryptoFileSystemFactory.isValidVaultStructure(getNioFileSystem());
 	}
 
 	public ObjectProperty<Boolean> unlockedProperty() {

+ 1 - 0
main/ui/src/main/resources/localization.properties

@@ -26,6 +26,7 @@ welcome.newVersionMessage=Version %s can be downloaded. This is %s.
 initialize.label.password=Password
 initialize.label.retypePassword=Retype password
 initialize.button.ok=Create vault
+initialize.messageLabel.alreadyInitialized=Vault already initialized
 
 # unlock.fxml
 unlock.label.password=Password