From 45ca7e9e471c4377c2e3359fcd958bda13ca1cd5 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sun, 3 Jul 2016 16:16:23 +0200 Subject: [PATCH] migration from vault version 3 to 4 --- main/filesystem-crypto/pom.xml | 2 +- main/pom.xml | 7 --- .../ui/model/UpgradeVersion3to4.java | 63 ++++++++++++++++++- .../ui/src/main/resources/localization/en.txt | 6 +- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/main/filesystem-crypto/pom.xml b/main/filesystem-crypto/pom.xml index 1897ef0c9..403777a29 100644 --- a/main/filesystem-crypto/pom.xml +++ b/main/filesystem-crypto/pom.xml @@ -19,7 +19,7 @@ 1.51 - 1.0.2 + 1.0.4 diff --git a/main/pom.xml b/main/pom.xml index 321c0122e..cfb5ace1a 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -43,13 +43,6 @@ 2.4 - - - jitpack.io - https://jitpack.io - - - diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java index f660ae7d3..45c3a9ff6 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java @@ -2,8 +2,13 @@ package org.cryptomator.ui.model; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Provider; @@ -19,6 +24,8 @@ import org.slf4j.LoggerFactory; class UpgradeVersion3to4 extends UpgradeStrategy { private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion3to4.class); + private static final Pattern BASE32_FOLLOWED_BY_UNDERSCORE_PATTERN = Pattern.compile("^(([A-Z2-7]{8})*[A-Z2-7=]{8})_"); + private static final int FILE_MIN_SIZE = 88; // vault version 3 files have a header of 88 bytes (assuming no chunks at all) @Inject public UpgradeVersion3to4(Provider cryptorProvider, Localization localization) { @@ -32,7 +39,61 @@ class UpgradeVersion3to4 extends UpgradeStrategy { @Override protected void upgrade(Vault vault, Cryptor cryptor) throws UpgradeFailedException { - throw new UpgradeFailedException("not yet implemented"); + Path dataDir = vault.path().get().resolve("d"); + if (!Files.isDirectory(dataDir)) { + return; // empty vault. no migration needed. + } + try { + Files.walkFileTree(dataDir, new FileVisitor() { + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + migrate(file, attrs); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + throw exc; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + + }); + } catch (IOException e) { + LOG.error("Migration failed.", e); + throw new UpgradeFailedException(localization.getString("upgrade.version3to4.err.io")); + } + LOG.info("Migration finished."); + } + + private void migrate(Path file, BasicFileAttributes attrs) throws IOException { + String name = file.getFileName().toString(); + long size = attrs.size(); + Matcher m = BASE32_FOLLOWED_BY_UNDERSCORE_PATTERN.matcher(name); + if (m.find(0) && size < FILE_MIN_SIZE) { + String base32 = m.group(1); + String suffix = name.substring(m.end()); + String renamed = "0" + base32 + (suffix.isEmpty() ? "" : " " + suffix); + renameWithoutOverwriting(file, renamed); + } + } + + private void renameWithoutOverwriting(Path path, String newName) throws IOException { + Path newPath = path.resolveSibling(newName); + for (int i = 2; Files.exists(newPath); i++) { + newPath = path.resolveSibling(newName + " " + i); + } + Files.move(path, newPath); + LOG.info("Renaming {} to {}", path, newPath.getFileName()); } @Override diff --git a/main/ui/src/main/resources/localization/en.txt b/main/ui/src/main/resources/localization/en.txt index 489b0861e..a108831f7 100644 --- a/main/ui/src/main/resources/localization/en.txt +++ b/main/ui/src/main/resources/localization/en.txt @@ -26,7 +26,7 @@ initialize.label.password=Password initialize.label.retypePassword=Retype password initialize.button.ok=Create vault initialize.messageLabel.alreadyInitialized=Vault already initialized -initialize.messageLabel.initializationFailed=Could not initialize vault. See logfile for details. +initialize.messageLabel.initializationFailed=Could not initialize vault. See log file for details. initialize.messageLabel.passwordStrength.0=Very weak initialize.messageLabel.passwordStrength.1=Weak initialize.messageLabel.passwordStrength.2=Fair @@ -44,7 +44,7 @@ upgrade.version3dropBundleExtension.msg=This vault needs to be migrated to a new upgrade.version3dropBundleExtension.err.alreadyExists=Automatic migration failed.\n"%s" already exists. upgrade.version3to4.msg=This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding. - +upgrade.version3to4.err.io=Migration failed due to an I/O Exception. See log file for details. # unlock.fxml unlock.label.password=Password @@ -57,7 +57,7 @@ unlock.button.advancedOptions.show=More options unlock.button.advancedOptions.hide=Less options unlock.choicebox.winDriveLetter.auto=Assign automatically unlock.errorMessage.wrongPassword=Wrong password -unlock.errorMessage.mountingFailed=Mounting failed. See logfile for details. +unlock.errorMessage.mountingFailed=Mounting failed. See log file for details. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Unsupported vault. This vault has been created with an older version of Cryptomator. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault=Unsupported vault. This vault has been created with a newer version of Cryptomator. unlock.messageLabel.startServerFailed=Starting WebDAV server failed.