diff --git a/main/pom.xml b/main/pom.xml index 6a4dd6e33..46ffc3e5c 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -28,7 +28,7 @@ 1.8.5 2.0.0 1.2.0-SNAPSHOT - 1.1.8 + 1.2.0-SNAPSHOT 1.0.10 12 diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java index df0eaa571..ac2d1fb37 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java @@ -162,6 +162,7 @@ public class UnlockController implements ViewController { unlockButton.disableProperty().bind(unlocking.or(passwordField.textProperty().isEmpty())); mountName.addEventFilter(KeyEvent.KEY_TYPED, this::filterAlphanumericKeyEvents); mountName.textProperty().addListener(this::mountNameDidChange); + useReadOnlyMode.selectedProperty().addListener(this::useReadOnlyDidChange); useCustomMountFlags.selectedProperty().addListener(this::useCustomMountFlagsDidChange); mountFlags.disableProperty().bind(useCustomMountFlags.selectedProperty().not()); mountFlags.textProperty().addListener(this::mountFlagsDidChange); @@ -226,6 +227,7 @@ public class UnlockController implements ViewController { VaultSettings vaultSettings = vault.getVaultSettings(); unlockAfterStartup.setSelected(savePassword.isSelected() && vaultSettings.unlockAfterStartup().get()); revealAfterMount.setSelected(vaultSettings.revealAfterMount().get()); + useReadOnlyMode.setSelected(vaultSettings.usesReadOnlyMode().get()); // WEBDAV-dependent controls: if (VolumeImpl.WEBDAV.equals(settings.preferredVolumeImpl().get())) { @@ -241,15 +243,6 @@ public class UnlockController implements ViewController { } } - // DOKANY-dependent controls: - if (VolumeImpl.DOKANY.equals(settings.preferredVolumeImpl().get())) { - // readonly not yet supported by dokany - useReadOnlyMode.setSelected(false); - useReadOnlyMode.setVisible(false); - useReadOnlyMode.setManaged(false); - } else { - useReadOnlyMode.setSelected(vaultSettings.usesReadOnlyMode().get()); - } // OS-dependent controls: if (SystemUtils.IS_OS_WINDOWS) { @@ -324,7 +317,14 @@ public class UnlockController implements ViewController { vault.setMountName(newValue); } if (!useCustomMountFlags.isSelected()) { - mountFlags.setText(vault.getMountFlags()); // flags might depend on the volume name + mountFlags.setText(vault.getMountFlags()); // update default flags + } + } + + private void useReadOnlyDidChange(@SuppressWarnings("unused") ObservableValue property, @SuppressWarnings("unused")Boolean oldValue, Boolean newValue) { + vault.getVaultSettings().usesReadOnlyMode().setValue(newValue); + if (!useCustomMountFlags.isSelected()) { + mountFlags.setText(vault.getMountFlags()); // update default flags } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java b/main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java index 1c419830e..84d1a300b 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java @@ -48,7 +48,7 @@ public class DokanyVolume implements Volume { Path mountPath = getMountPoint(); String mountName = vaultSettings.mountName().get(); try { - this.mount = mountFactory.mount(fs.getPath("/"), mountPath, mountName, FS_TYPE_NAME); + this.mount = mountFactory.mount(fs.getPath("/"), mountPath, mountName, FS_TYPE_NAME, mountFlags); } catch (MountFailedException e) { if (vaultSettings.getIndividualMountPath().isPresent()) { LOG.warn("Failed to mount vault into {}. Is this directory currently accessed by another process (e.g. Windows Explorer)?", mountPath); diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java b/main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java index 8ca71d692..cb416557b 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java @@ -60,46 +60,72 @@ public class VaultModule { } } + // see: https://github.com/osxfuse/osxfuse/wiki/Mount-options private String getMacFuseDefaultMountFlags(Settings settings, VaultSettings vaultSettings) { assert SystemUtils.IS_OS_MAC_OSX; - // see: https://github.com/osxfuse/osxfuse/wiki/Mount-options + + StringBuilder flags = new StringBuilder(); + if (vaultSettings.usesReadOnlyMode().get()) { + flags.append(" -ordonly"); + } + flags.append(" -ovolname=").append(vaultSettings.mountName().get()); + flags.append(" -oatomic_o_trunc"); + flags.append(" -oauto_xattr"); + flags.append(" -oauto_cache"); + flags.append(" -omodules=iconv,from_code=UTF-8,to_code=UTF-8-MAC"); // show files names in Unicode NFD encoding + flags.append(" -onoappledouble"); // vastly impacts performance for some reason... + flags.append(" -odefault_permissions"); // let the kernel assume permissions based on file attributes etc + try { Path userHome = Paths.get(System.getProperty("user.home")); int uid = (int) Files.getAttribute(userHome, "unix:uid"); int gid = (int) Files.getAttribute(userHome, "unix:gid"); - return "-ovolname=" + vaultSettings.mountName().get() // volume name - + " -ouid=" + uid // - + " -ogid=" + gid // - + " -oatomic_o_trunc" // - + " -oauto_xattr" // - + " -oauto_cache" // - + " -omodules=iconv,from_code=UTF-8,to_code=UTF-8-MAC" // show files names in Unicode NFD encoding - + " -onoappledouble" // vastly impacts performance for some reason... - + " -odefault_permissions"; // let the kernel assume permissions based on file attributes etc + flags.append(" -ouid=").append(uid); + flags.append(" -ogid=").append(gid); } catch (IOException e) { LOG.error("Could not read uid/gid from USER_HOME", e); - return ""; } + + return flags.toString(); } + // see https://manpages.debian.org/testing/fuse/mount.fuse.8.en.html private String getLinuxFuseDefaultMountFlags(Settings settings, VaultSettings vaultSettings) { assert SystemUtils.IS_OS_LINUX; + + StringBuilder flags = new StringBuilder(); + if (vaultSettings.usesReadOnlyMode().get()) { + flags.append(" -oro"); + } + flags.append(" -oauto_unmount"); + try { Path userHome = Paths.get(System.getProperty("user.home")); int uid = (int) Files.getAttribute(userHome, "unix:uid"); int gid = (int) Files.getAttribute(userHome, "unix:gid"); - return "-oauto_unmount" // - + " -ouid=" + uid // - + " -ogid=" + gid; + flags.append(" -ouid=").append(uid); + flags.append(" -ogid=").append(gid); } catch (IOException e) { LOG.error("Could not read uid/gid from USER_HOME", e); - return ""; } + + return flags.toString(); } + // see https://github.com/cryptomator/dokany-nio-adapter/blob/develop/src/main/java/org/cryptomator/frontend/dokany/MountUtil.java#L30-L34 private String getDokanyDefaultMountFlags(Settings settings, VaultSettings vaultSettings) { - // TODO - return "--not-yet-supported"; + assert SystemUtils.IS_OS_WINDOWS; + + StringBuilder flags = new StringBuilder(); + flags.append(" --options CURRENT_SESSION"); + if (vaultSettings.usesReadOnlyMode().get()) { + flags.append(",WRITE_PROTECTION"); + } + flags.append(" --threadCount 5"); + flags.append(" --timeout 10000"); + flags.append(" --allocation-unit-size 4096"); + flags.append(" --sector-size 4096"); + return flags.toString(); } }