From f53f2d2ca4b7eb0bde642eb82cca0a88041b0a22 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 17 Jun 2019 13:55:31 +0200 Subject: [PATCH] allow to store custom mount flags in the vault settings (required for #802) [ci skip] --- .../common/settings/VaultSettings.java | 6 ++++ .../settings/VaultSettingsJsonAdapter.java | 30 ++++++++++++++++++- .../VaultSettingsJsonAdapterTest.java | 28 ++++++++++++++++- main/pom.xml | 2 +- .../org/cryptomator/ui/model/FuseVolume.java | 18 +++++++++-- 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettings.java b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettings.java index 41c91efcf..8f30fd70f 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettings.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettings.java @@ -20,6 +20,7 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.Base64; +import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -44,6 +45,7 @@ public class VaultSettings { private final BooleanProperty usesIndividualMountPath = new SimpleBooleanProperty(DEFAULT_USES_INDIVIDUAL_MOUNTPATH); private final StringProperty individualMountPath = new SimpleStringProperty(); private final BooleanProperty usesReadOnlyMode = new SimpleBooleanProperty(DEFAULT_USES_READONLY_MODE); + private final ObjectProperty> mountFlags = new SimpleObjectProperty<>(List.of()); public VaultSettings(String id) { this.id = Objects.requireNonNull(id); @@ -147,6 +149,10 @@ public class VaultSettings { return usesReadOnlyMode; } + public ObjectProperty> mountFlags() { + return mountFlags; + } + /* Hashcode/Equals */ @Override diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java index 7a3f03b39..484e91e1c 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java @@ -6,12 +6,15 @@ package org.cryptomator.common.settings; import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; class VaultSettingsJsonAdapter { @@ -26,8 +29,10 @@ class VaultSettingsJsonAdapter { out.name("unlockAfterStartup").value(value.unlockAfterStartup().get()); out.name("revealAfterMount").value(value.revealAfterMount().get()); out.name("usesIndividualMountPath").value(value.usesIndividualMountPath().get()); - out.name("individualMountPath").value(value.individualMountPath().get()); //TODO: should this always be written? ( because it could contain metadata, which the user may not want to save!) + out.name("individualMountPath").value(value.individualMountPath().get()); out.name("usesReadOnlyMode").value(value.usesReadOnlyMode().get()); + out.name("mountFlags"); + writeMountFlags(out, value.mountFlags().get()); out.endObject(); } @@ -41,6 +46,7 @@ class VaultSettingsJsonAdapter { boolean revealAfterMount = VaultSettings.DEFAULT_REAVEAL_AFTER_MOUNT; boolean usesIndividualMountPath = VaultSettings.DEFAULT_USES_INDIVIDUAL_MOUNTPATH; boolean usesReadOnlyMode = VaultSettings.DEFAULT_USES_READONLY_MODE; + List mountFlags = null; in.beginObject(); while (in.hasNext()) { @@ -73,6 +79,9 @@ class VaultSettingsJsonAdapter { case "usesReadOnlyMode": usesReadOnlyMode = in.nextBoolean(); break; + case "mountFlags": + mountFlags = readMountFlags(in); + break; default: LOG.warn("Unsupported vault setting found in JSON: " + name); in.skipValue(); @@ -90,7 +99,26 @@ class VaultSettingsJsonAdapter { vaultSettings.usesIndividualMountPath().set(usesIndividualMountPath); vaultSettings.individualMountPath().set(individualMountPath); vaultSettings.usesReadOnlyMode().set(usesReadOnlyMode); + vaultSettings.mountFlags().set(mountFlags); return vaultSettings; } + private List readMountFlags(JsonReader in) throws IOException { + List result = new ArrayList<>(); + in.beginArray(); + while (!JsonToken.END_ARRAY.equals(in.peek())) { + result.add(in.nextString()); + } + in.endArray(); + return result; + } + + private void writeMountFlags(JsonWriter out, List flags) throws IOException { + out.beginArray(); + for (String flag : flags) { + out.value(flag); + } + out.endArray(); + } + } diff --git a/main/commons/src/test/java/org/cryptomator/common/settings/VaultSettingsJsonAdapterTest.java b/main/commons/src/test/java/org/cryptomator/common/settings/VaultSettingsJsonAdapterTest.java index 32f393842..eb3bb1582 100644 --- a/main/commons/src/test/java/org/cryptomator/common/settings/VaultSettingsJsonAdapterTest.java +++ b/main/commons/src/test/java/org/cryptomator/common/settings/VaultSettingsJsonAdapterTest.java @@ -6,12 +6,17 @@ package org.cryptomator.common.settings; import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.StringReader; +import java.io.StringWriter; import java.nio.file.Paths; +import java.util.Arrays; public class VaultSettingsJsonAdapterTest { @@ -19,7 +24,7 @@ public class VaultSettingsJsonAdapterTest { @Test public void testDeserialize() throws IOException { - String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"mountName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true, \"individualMountPath\": \"/home/test/crypto\"}"; + String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"mountName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true, \"individualMountPath\": \"/home/test/crypto\", \"mountFlags\":[\"--foo\", \"--bar\"]}"; JsonReader jsonReader = new JsonReader(new StringReader(json)); VaultSettings vaultSettings = adapter.read(jsonReader); @@ -28,6 +33,27 @@ public class VaultSettingsJsonAdapterTest { Assertions.assertEquals("test", vaultSettings.mountName().get()); Assertions.assertEquals("X", vaultSettings.winDriveLetter().get()); Assertions.assertEquals("/home/test/crypto", vaultSettings.individualMountPath().get()); + MatcherAssert.assertThat(vaultSettings.mountFlags().get(), CoreMatchers.hasItems("--foo", "--bar")); + + + } + + @Test + public void testSerialize() throws IOException { + VaultSettings vaultSettings = new VaultSettings("test"); + vaultSettings.path().set(Paths.get("/foo/bar")); + vaultSettings.mountName().set("mountyMcMountFace"); + vaultSettings.mountFlags().set(Arrays.asList("--foo", "--bar")); + + StringWriter buf = new StringWriter(); + JsonWriter jsonWriter = new JsonWriter(buf); + adapter.write(jsonWriter, vaultSettings); + String result = buf.toString(); + + MatcherAssert.assertThat(result, CoreMatchers.containsString("\"id\":\"test\"")); + MatcherAssert.assertThat(result, CoreMatchers.containsString("\"path\":\"/foo/bar\"")); + MatcherAssert.assertThat(result, CoreMatchers.containsString("\"mountName\":\"mountyMcMountFace\"")); + MatcherAssert.assertThat(result, CoreMatchers.containsString("\"mountFlags\":[\"--foo\",\"--bar\"]")); } } diff --git a/main/pom.xml b/main/pom.xml index ffe4cb6c5..6a4dd6e33 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -27,7 +27,7 @@ 1.2.1 1.8.5 2.0.0 - 1.1.3 + 1.2.0-SNAPSHOT 1.1.8 1.0.10 diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/FuseVolume.java b/main/ui/src/main/java/org/cryptomator/ui/model/FuseVolume.java index fcd69493d..dbce4eccb 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/FuseVolume.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/FuseVolume.java @@ -9,6 +9,7 @@ import org.cryptomator.frontend.fuse.mount.EnvironmentVariables; import org.cryptomator.frontend.fuse.mount.FuseMountFactory; import org.cryptomator.frontend.fuse.mount.FuseNotSupportedException; import org.cryptomator.frontend.fuse.mount.Mount; +import org.cryptomator.frontend.fuse.mount.Mounter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,6 +21,7 @@ import java.nio.file.Files; import java.nio.file.NotDirectoryException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.Optional; public class FuseVolume implements Volume { @@ -96,16 +98,26 @@ public class FuseVolume implements Volume { private void mount(Path root) throws VolumeException { try { + Mounter mounter = FuseMountFactory.getMounter(); EnvironmentVariables envVars = EnvironmentVariables.create() // - .withMountName(vaultSettings.mountName().getValue()) // - .withMountPath(mountPoint) // + .withFlags(mountFlags(mounter)) + .withMountPoint(mountPoint) // .build(); - this.fuseMnt = FuseMountFactory.getMounter().mount(root, envVars); + this.fuseMnt = mounter.mount(root, envVars); } catch (CommandFailedException e) { throw new VolumeException("Unable to mount Filesystem", e); } } + private String[] mountFlags(Mounter mounter) { + List mountFlags = vaultSettings.mountFlags().get(); + if (mountFlags.isEmpty()) { + return mounter.defaultMountFlags(); + } else { + return mountFlags.toArray(String[]::new); + } + } + @Override public void reveal() throws VolumeException { try {