From 3ae8327300798d61fd27262251402aa83f58a0da Mon Sep 17 00:00:00 2001 From: Markus Kreusch Date: Wed, 10 Aug 2016 13:07:41 +0200 Subject: [PATCH] Added unique id to vaults / webdav urls. Issue #319, Issue #308 --- .../java/org/cryptomator/ui/model/Vault.java | 21 +++++++--- .../cryptomator/ui/model/VaultFactory.java | 38 ++++++++++++++++++- .../ui/model/VaultObjectMapperProvider.java | 8 +++- 3 files changed, 60 insertions(+), 7 deletions(-) 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 6868574ac..f4e94a214 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 @@ -8,6 +8,8 @@ *******************************************************************************/ package org.cryptomator.ui.model; +import static org.apache.commons.lang3.StringUtils.stripStart; + import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.FileAlreadyExistsException; @@ -70,7 +72,8 @@ public class Vault implements CryptoFileSystemDelegate { private final ObservableList namesOfResourcesWithInvalidMac = FXThreads.observableListOnMainThread(FXCollections.observableArrayList()); private final Set whitelistedResourcesWithInvalidMac = new HashSet<>(); private final AtomicReference nioFileSystem = new AtomicReference<>(); - + private final String id; + private String mountName; private Character winDriveLetter; private Optional statsFileSystem = Optional.empty(); @@ -78,13 +81,14 @@ public class Vault implements CryptoFileSystemDelegate { /** * Package private constructor, use {@link VaultFactory}. + * @param string */ - Vault(Path vaultDirectoryPath, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, DeferredCloser closer) { + Vault(String id, Path vaultDirectoryPath, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, DeferredCloser closer) { this.path = new SimpleObjectProperty(vaultDirectoryPath); this.shorteningFileSystemFactory = shorteningFileSystemFactory; this.cryptoFileSystemFactory = cryptoFileSystemFactory; this.closer = closer; - + this.id = id; try { setMountName(name().getValue()); } catch (IllegalArgumentException e) { @@ -129,8 +133,7 @@ public class Vault implements CryptoFileSystemDelegate { FileSystem normalizingFs = new NormalizedNameFileSystem(cryptoFs, SystemUtils.IS_OS_MAC_OSX ? Form.NFD : Form.NFC); StatsFileSystem statsFs = new StatsFileSystem(normalizingFs); statsFileSystem = Optional.of(statsFs); - String contextPath = StringUtils.prependIfMissing(mountName, "/"); - Frontend frontend = frontendFactory.create(statsFs, contextPath); + Frontend frontend = frontendFactory.create(statsFs, contextPath()); filesystemFrontend = closer.closeLater(frontend); frontend.mount(getMountParams(settings)); success = true; @@ -143,6 +146,10 @@ public class Vault implements CryptoFileSystemDelegate { } } + private String contextPath() { + return String.format("/%s/%s", id, stripStart(mountName, "/")); + } + public synchronized void deactivateFrontend() { filesystemFrontend.close(); statsFileSystem = Optional.empty(); @@ -305,6 +312,10 @@ public class Vault implements CryptoFileSystemDelegate { public void setWinDriveLetter(Character winDriveLetter) { this.winDriveLetter = winDriveLetter; } + + public String getId() { + return id; + } // ****************************************************************************** // Hashcode / Equals diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java b/main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java index ec0b0d420..148a4317a 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java @@ -8,7 +8,12 @@ *******************************************************************************/ package org.cryptomator.ui.model; +import static java.util.UUID.randomUUID; + +import java.nio.ByteBuffer; import java.nio.file.Path; +import java.util.Base64; +import java.util.UUID; import javax.inject.Inject; import javax.inject.Singleton; @@ -31,8 +36,39 @@ public class VaultFactory { this.closer = closer; } + public Vault createVault(String id, Path path) { + return new Vault(id, path, shorteningFileSystemFactory, cryptoFileSystemFactory, closer); + } + public Vault createVault(Path path) { - return new Vault(path, shorteningFileSystemFactory, cryptoFileSystemFactory, closer); + return createVault(generateId(), path); + } + + private String generateId() { + return asBase64String(nineBytesFrom(randomUUID())); + } + + private String asBase64String(ByteBuffer bytes) { + ByteBuffer base64Buffer = Base64.getUrlEncoder().encode(bytes); + return new String(asByteArray(base64Buffer)); + } + + private ByteBuffer nineBytesFrom(UUID uuid) { + ByteBuffer uuidBuffer = ByteBuffer.allocate(9); + uuidBuffer.putLong(uuid.getMostSignificantBits()); + uuidBuffer.put((byte)(uuid.getLeastSignificantBits() & 0xFF)); + uuidBuffer.flip(); + return uuidBuffer; + } + + private byte[] asByteArray(ByteBuffer buffer) { + if (buffer.hasArray()) { + return buffer.array(); + } else { + byte[] bytes = new byte[buffer.remaining()]; + buffer.get(bytes); + return bytes; + } } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/VaultObjectMapperProvider.java b/main/ui/src/main/java/org/cryptomator/ui/model/VaultObjectMapperProvider.java index d71626cf6..90e86abdc 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/VaultObjectMapperProvider.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/VaultObjectMapperProvider.java @@ -57,6 +57,7 @@ public class VaultObjectMapperProvider implements Provider { jgen.writeStartObject(); jgen.writeStringField("path", value.path().getValue().toString()); jgen.writeStringField("mountName", value.getMountName()); + jgen.writeStringField("id", value.getId()); final Character winDriveLetter = value.getWinDriveLetter(); if (winDriveLetter != null) { jgen.writeStringField("winDriveLetter", Character.toString(winDriveLetter)); @@ -76,7 +77,12 @@ public class VaultObjectMapperProvider implements Provider { } final String pathStr = node.get("path").asText(); final Path path = FileSystems.getDefault().getPath(pathStr); - final Vault vault = vaultFactoy.createVault(path); + final Vault vault; + if (node.has("id")) { + vault = vaultFactoy.createVault(node.get("id").asText(), path); + } else { + vault = vaultFactoy.createVault(path); + } if (node.has("mountName")) { vault.setMountName(node.get("mountName").asText()); }