From dafa29d8a3b9f424e68c0ed0cb2775de038612d0 Mon Sep 17 00:00:00 2001 From: Markus Kreusch Date: Thu, 10 Nov 2016 22:58:45 +0100 Subject: [PATCH 1/2] Implemented #393 --- .../webdav/mount/WindowsWebDavMounter.java | 2 +- .../ui/controllers/UnlockedController.java | 11 ++++++ .../java/org/cryptomator/ui/model/Vault.java | 36 +++++++++++++++---- main/ui/src/main/resources/fxml/unlocked.fxml | 2 +- .../ui/src/main/resources/localization/de.txt | 1 + .../ui/src/main/resources/localization/en.txt | 1 + 6 files changed, 45 insertions(+), 8 deletions(-) diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java index bea6a5cdd..6e0134bf3 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java @@ -95,7 +95,7 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { } final String driveLetterStr = AUTO_ASSIGN_DRIVE_LETTER.equals(driveLetter) ? AUTO_ASSIGN_DRIVE_LETTER : driveLetter + ":"; - final Script mountScript = fromLines("net use %DRIVE_LETTER% \\\\%DAV_HOST%@%DAV_PORT%\\DavWWWRoot%DAV_UNC_PATH% /persistent:no"); + final Script mountScript = fromLines("net use %DRIVE_LETTER%a \\\\%DAV_HOST%@%DAV_PORT%\\DavWWWRoot%DAV_UNC_PATH% /persistent:no"); mountScript.addEnv("DRIVE_LETTER", driveLetterStr); mountScript.addEnv("DAV_HOST", uri.getHost()); mountScript.addEnv("DAV_PORT", String.valueOf(uri.getPort())); diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java index 3d0e58aa4..ae11098d2 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java @@ -38,6 +38,7 @@ import javafx.scene.chart.XYChart.Data; import javafx.scene.chart.XYChart.Series; import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; import javafx.scene.control.ToggleButton; import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; @@ -81,11 +82,16 @@ public class UnlockedController extends LocalizedFXMLViewController { @FXML private ContextMenu moreOptionsMenu; + @FXML + private MenuItem revealVaultMenuItem; + @Override public void initialize() { macWarningsController.initStage(macWarningsWindow); ActiveWindowStyleSupport.startObservingFocus(macWarningsWindow); + revealVaultMenuItem.disableProperty().bind(EasyBind.map(vault, vault -> vault != null && !vault.isMounted())); + EasyBind.subscribe(vault, this::vaultChanged); EasyBind.subscribe(moreOptionsMenu.showingProperty(), moreOptionsButton::setSelected); } @@ -109,6 +115,11 @@ public class UnlockedController extends LocalizedFXMLViewController { } }); + if (!vault.get().isMounted()) { + // TODO Markus Kreusch #393: hyperlink auf FAQ oder sowas? + messageLabel.setText(localization.getString("unlocked.label.mountFailed")); + } + // (re)start throughput statistics: stopIoSampling(); startIoSampling(); diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java index 086fffa90..0d36158fc 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java @@ -50,6 +50,8 @@ import org.cryptomator.ui.util.DeferredClosable; import org.cryptomator.ui.util.DeferredCloser; import org.cryptomator.ui.util.FXThreads; import org.fxmisc.easybind.EasyBind; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableMap; @@ -65,6 +67,8 @@ import javafx.collections.ObservableList; public class Vault implements CryptoFileSystemDelegate { + private static final Logger LOG = LoggerFactory.getLogger(CryptoFileSystemDelegate.class); + public static final String VAULT_FILE_EXTENSION = ".cryptomator"; private final ObjectProperty path; @@ -72,6 +76,7 @@ public class Vault implements CryptoFileSystemDelegate { private final CryptoFileSystemFactory cryptoFileSystemFactory; private final DeferredCloser closer; private final BooleanProperty unlocked = new SimpleBooleanProperty(); + private final BooleanProperty mounted = new SimpleBooleanProperty(); private final ObservableList namesOfResourcesWithInvalidMac = FXThreads.observableListOnMainThread(FXCollections.observableArrayList()); private final Set whitelistedResourcesWithInvalidMac = new HashSet<>(); private final AtomicReference nioFileSystem = new AtomicReference<>(); @@ -131,7 +136,8 @@ public class Vault implements CryptoFileSystemDelegate { } public synchronized void activateFrontend(FrontendFactory frontendFactory, Settings settings, CharSequence passphrase) throws FrontendCreationFailedException { - boolean success = false; + boolean launchSuccess = false; + boolean mountSuccess = false; try { FileSystem fs = getNioFileSystem(); FileSystem shorteningFs = shorteningFileSystemFactory.get(fs); @@ -140,22 +146,32 @@ public class Vault implements CryptoFileSystemDelegate { StatsFileSystem statsFs = new StatsFileSystem(normalizingFs); statsFileSystem = Optional.of(statsFs); Frontend frontend = frontendFactory.create(statsFs, FrontendId.from(id), stripStart(mountName, "/")); + launchSuccess = true; filesystemFrontend = closer.closeLater(frontend); frontend.mount(getMountParams(settings)); - success = true; - } catch (UncheckedIOException | CommandFailedException e) { + mountSuccess = true; + } catch (UncheckedIOException e) { throw new FrontendCreationFailedException(e); + } catch (CommandFailedException e) { + LOG.error("Failed to mount vault " + mountName, e); } finally { // unlocked is a observable property and should only be changed by the FX application thread - final boolean finalSuccess = success; - Platform.runLater(() -> unlocked.set(finalSuccess)); + boolean finalLaunchSuccess = launchSuccess; + boolean finalMountSuccess = mountSuccess; + Platform.runLater(() -> { + unlocked.set(finalLaunchSuccess); + mounted.set(finalMountSuccess); + }); } } public synchronized void deactivateFrontend() throws Exception { filesystemFrontend.close(); statsFileSystem = Optional.empty(); - Platform.runLater(() -> unlocked.set(false)); + Platform.runLater(() -> { + mounted.set(false); + unlocked.set(false); + }); } private Map> getMountParams(Settings settings) { @@ -239,10 +255,18 @@ public class Vault implements CryptoFileSystemDelegate { return unlocked; } + public BooleanProperty mountedProperty() { + return mounted; + } + public boolean isUnlocked() { return unlocked.get(); } + public boolean isMounted() { + return mounted.get(); + } + public ObservableList getNamesOfResourcesWithInvalidMac() { return namesOfResourcesWithInvalidMac; } diff --git a/main/ui/src/main/resources/fxml/unlocked.fxml b/main/ui/src/main/resources/fxml/unlocked.fxml index 05ead1532..81dfddd5f 100644 --- a/main/ui/src/main/resources/fxml/unlocked.fxml +++ b/main/ui/src/main/resources/fxml/unlocked.fxml @@ -28,7 +28,7 @@ - + diff --git a/main/ui/src/main/resources/localization/de.txt b/main/ui/src/main/resources/localization/de.txt index 7761861c9..2b301d0ae 100644 --- a/main/ui/src/main/resources/localization/de.txt +++ b/main/ui/src/main/resources/localization/de.txt @@ -48,6 +48,7 @@ changePassword.infoMessage.success = Passwort geändert unlocked.button.lock = Tresor sperren unlocked.moreOptions.reveal = Laufwerk anzeigen unlocked.moreOptions.copyUrl = WebDAV-URL kopieren +unlocked.label.mountFailed = Verbinden des Laufwerks fehlgeschlagen unlocked.label.revealFailed = Befehl fehlgeschlagen unlocked.label.unmountFailed = Trennen des Laufwerks fehlgeschlagen unlocked.label.statsEncrypted = verschlüsselt diff --git a/main/ui/src/main/resources/localization/en.txt b/main/ui/src/main/resources/localization/en.txt index 92cd4815a..63f8551b0 100644 --- a/main/ui/src/main/resources/localization/en.txt +++ b/main/ui/src/main/resources/localization/en.txt @@ -79,6 +79,7 @@ changePassword.errorMessage.decryptionFailed=Decryption failed unlocked.button.lock=Lock vault unlocked.moreOptions.reveal=Reveal drive unlocked.moreOptions.copyUrl=Copy WebDAV URL +unlocked.label.mountFailed=Connecting drive failed unlocked.label.revealFailed=Command failed unlocked.label.unmountFailed=Ejecting drive failed unlocked.label.statsEncrypted=encrypted From 1263b3af81aca4df1aa4ac532d1506536ee800b6 Mon Sep 17 00:00:00 2001 From: Markus Kreusch Date: Fri, 11 Nov 2016 09:56:30 +0100 Subject: [PATCH 2/2] fixed 'a' really bad thing in the last commit --- .../cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java index 6e0134bf3..bea6a5cdd 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java @@ -95,7 +95,7 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { } final String driveLetterStr = AUTO_ASSIGN_DRIVE_LETTER.equals(driveLetter) ? AUTO_ASSIGN_DRIVE_LETTER : driveLetter + ":"; - final Script mountScript = fromLines("net use %DRIVE_LETTER%a \\\\%DAV_HOST%@%DAV_PORT%\\DavWWWRoot%DAV_UNC_PATH% /persistent:no"); + final Script mountScript = fromLines("net use %DRIVE_LETTER% \\\\%DAV_HOST%@%DAV_PORT%\\DavWWWRoot%DAV_UNC_PATH% /persistent:no"); mountScript.addEnv("DRIVE_LETTER", driveLetterStr); mountScript.addEnv("DAV_HOST", uri.getHost()); mountScript.addEnv("DAV_PORT", String.valueOf(uri.getPort()));