diff --git a/azure/pom.xml b/azure/pom.xml index afdb293cfaa..a577a50e4ae 100644 --- a/azure/pom.xml +++ b/azure/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT azure diff --git a/azure/src/test/java/ch/cyberduck/core/azure/AbstractAzureTest.java b/azure/src/test/java/ch/cyberduck/core/azure/AbstractAzureTest.java index cd7876e88ee..9e8af2507f4 100644 --- a/azure/src/test/java/ch/cyberduck/core/azure/AbstractAzureTest.java +++ b/azure/src/test/java/ch/cyberduck/core/azure/AbstractAzureTest.java @@ -21,7 +21,7 @@ import ch.cyberduck.core.DisabledProgressListener; import ch.cyberduck.core.Host; import ch.cyberduck.core.LoginConnectionService; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -34,11 +34,11 @@ public class AbstractAzureTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureDirectoryFeatureTest.java b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureDirectoryFeatureTest.java index 72f478660b3..eac1c2205c0 100644 --- a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureDirectoryFeatureTest.java +++ b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureDirectoryFeatureTest.java @@ -31,8 +31,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -42,7 +44,6 @@ import java.util.EnumSet; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -51,9 +52,9 @@ public class AzureDirectoryFeatureTest extends AbstractAzureTest { @Test public void testMakeDirectoryEncrypted() throws Exception { final Path home = new Path("cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = cryptomator.getFeature(session, Directory.class, new AzureDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new AzureWriteFeature(session)), new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); @@ -62,13 +63,15 @@ public void testMakeDirectoryEncrypted() throws Exception { cryptomator.getFeature(session, Delete.class, new AzureDeleteFeature(session)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); } + + //TODO enable @Test + @Ignore(value = "Filename shortening not yet implemented") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = cryptomator.getFeature(session, Directory.class, new AzureDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new AzureWriteFeature(session)), new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); diff --git a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureListServiceTest.java b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureListServiceTest.java index 174e34b2600..994d385f037 100644 --- a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureListServiceTest.java +++ b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureListServiceTest.java @@ -27,11 +27,13 @@ import ch.cyberduck.core.cryptomator.features.CryptoListService; import ch.cyberduck.core.cryptomator.features.CryptoTouchFeature; import ch.cyberduck.core.cryptomator.features.CryptoWriteFeature; +import ch.cyberduck.core.cryptomator.features.CryptoWriteFeature; import ch.cyberduck.core.features.Delete; import ch.cyberduck.core.shared.DefaultTouchFeature; import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -52,9 +54,9 @@ public class AzureListServiceTest extends AbstractAzureTest { @Test public void testListCryptomator() throws Exception { final Path home = new Path("cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); assertTrue(new CryptoListService(session, new AzureObjectListService(session), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); diff --git a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureMoveFeatureTest.java b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureMoveFeatureTest.java index 3aa606d75fc..35a553bdf02 100644 --- a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureMoveFeatureTest.java +++ b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureMoveFeatureTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -58,9 +59,9 @@ public class AzureMoveFeatureTest extends AbstractAzureTest { @Test public void testMove() throws Exception { final Path home = new Path("cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path folder = cryptomator.getFeature(session, Directory.class, new AzureDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new AzureWriteFeature(session)), new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); diff --git a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureTouchFeatureTest.java b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureTouchFeatureTest.java index b8a257cd4df..a6952a94854 100644 --- a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureTouchFeatureTest.java +++ b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureTouchFeatureTest.java @@ -32,8 +32,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -44,19 +46,20 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) public class AzureTouchFeatureTest extends AbstractAzureTest { + //TODO + @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new AzureTouchFeature(session), cryptomator).touch( @@ -68,12 +71,12 @@ public void testTouchLongFilenameEncrypted() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new AzureTouchFeature(session), cryptomator).touch( diff --git a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureWriteFeatureTest.java b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureWriteFeatureTest.java index a11d3355b97..11c66b56332 100644 --- a/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureWriteFeatureTest.java +++ b/azure/src/test/java/ch/cyberduck/core/cryptomator/AzureWriteFeatureTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -66,9 +67,9 @@ public void testWrite() throws Exception { final byte[] content = RandomUtils.nextBytes(1048576); status.setLength(content.length); final Path home = new Path("cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new AzureWriteFeature(session), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); diff --git a/azure/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/azure/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index 1e3bc02b566..459a0c75a3b 100644 --- a/azure/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/azure/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -47,12 +47,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -76,8 +78,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -102,8 +104,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -120,11 +122,14 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { new DeleteWorker(new DisabledLoginCallback(), Collections.singletonList(vault), new DisabledProgressListener()).run(session); } + //TODO @Test + @Ignore(value = "Filename shortening not yet implemented") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { final Path home = new Path("cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault(new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); @@ -147,8 +152,9 @@ public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception @Test public void testCopyFolder() throws Exception { final Path home = new Path("cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault(new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); @@ -185,8 +191,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new AzureFindFeature(session).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new AzureDirectoryFeature(session)).mkdir( @@ -214,8 +220,8 @@ public void testCopyDirectoryIntoVault() throws Exception { new AzureTouchFeature(session).touch(new AzureWriteFeature(session), cleartextFile, new TransferStatus()); assertTrue(new AzureFindFeature(session).find(cleartextFolder)); assertTrue(new AzureFindFeature(session).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -239,8 +245,8 @@ public void testCopyFileOutsideVault() throws Exception { new AzureDirectoryFeature(session).mkdir(new AzureWriteFeature(session), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new AzureDirectoryFeature(session)).mkdir( @@ -265,8 +271,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new AzureDirectoryFeature(session)).mkdir( diff --git a/azure/src/test/java/ch/cyberduck/core/cryptomator/CryptoAzureSingleTransferWorkerTest.java b/azure/src/test/java/ch/cyberduck/core/cryptomator/CryptoAzureSingleTransferWorkerTest.java index 4ac361ed8c5..008e34a8fd6 100644 --- a/azure/src/test/java/ch/cyberduck/core/cryptomator/CryptoAzureSingleTransferWorkerTest.java +++ b/azure/src/test/java/ch/cyberduck/core/cryptomator/CryptoAzureSingleTransferWorkerTest.java @@ -51,6 +51,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -77,8 +78,9 @@ public class CryptoAzureSingleTransferWorkerTest extends AbstractAzureTest { @Test public void testUpload() throws Exception { final Path home = new Path("cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path dir1 = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory, Path.Type.placeholder)); final Local localDirectory1 = new Local(System.getProperty("java.io.tmpdir"), new AlphanumericRandomStringService().random()); diff --git a/backblaze/pom.xml b/backblaze/pom.xml index 170eeec3f8b..0103dfa5ddd 100644 --- a/backblaze/pom.xml +++ b/backblaze/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT backblaze jar diff --git a/backblaze/src/test/java/ch/cyberduck/core/b2/AbstractB2Test.java b/backblaze/src/test/java/ch/cyberduck/core/b2/AbstractB2Test.java index 898fdd7c710..fa8c3f533ed 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/b2/AbstractB2Test.java +++ b/backblaze/src/test/java/ch/cyberduck/core/b2/AbstractB2Test.java @@ -26,10 +26,10 @@ import ch.cyberduck.core.LoginOptions; import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -47,11 +47,11 @@ public class AbstractB2Test extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2DirectoryFeatureTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2DirectoryFeatureTest.java index c3207396c44..5dd9b60c437 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2DirectoryFeatureTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2DirectoryFeatureTest.java @@ -39,8 +39,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -52,7 +54,6 @@ import java.util.stream.Collectors; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -61,9 +62,9 @@ public class B2DirectoryFeatureTest extends AbstractB2Test { @Test public void testMakeDirectoryEncrypted() throws Exception { final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); final Path test = cryptomator.getFeature(session, Directory.class, new B2DirectoryFeature(session, fileid)).mkdir( @@ -82,12 +83,12 @@ public void testMakeDirectoryEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not yet implemented") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); final Path test = cryptomator.getFeature(session, Directory.class, new B2DirectoryFeature(session, fileid)).mkdir( diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2LargeUploadServiceTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2LargeUploadServiceTest.java index 868c5e95afb..197fa82e616 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2LargeUploadServiceTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2LargeUploadServiceTest.java @@ -46,6 +46,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -76,9 +77,9 @@ public class B2LargeUploadServiceTest extends AbstractB2Test { public void testWrite() throws Exception { // 5L * 1024L * 1024L final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); final CryptoUploadFeature service = new CryptoUploadFeature<>(session, @@ -111,9 +112,9 @@ public void testWrite() throws Exception { public void testUploadWithBulk() throws Exception { // 5L * 1024L * 1024L final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus writeStatus = new TransferStatus(); diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2LargeUploadWriteFeatureTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2LargeUploadWriteFeatureTest.java index 664d372a3f5..1a332aba815 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2LargeUploadWriteFeatureTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2LargeUploadWriteFeatureTest.java @@ -35,6 +35,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -61,9 +62,9 @@ public class B2LargeUploadWriteFeatureTest extends AbstractB2Test { @Test public void testWrite() throws Exception { final Path container = new Path("test-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault( - new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); final CryptoWriteFeature feature = new CryptoWriteFeature<>(session, new B2LargeUploadWriteFeature(session, fileid), cryptomator); diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2ListServiceTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2ListServiceTest.java index 4e67fcf8ad0..9b5c0987f7b 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2ListServiceTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2ListServiceTest.java @@ -34,6 +34,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -56,9 +57,9 @@ public class B2ListServiceTest extends AbstractB2Test { @Test public void testListCryptomator() throws Exception { final Path home = new Path("test-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); assertTrue(new CryptoListService(session, new B2ListService(session, fileid), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2TouchFeatureTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2TouchFeatureTest.java index c2744bcfc23..a8fa2ab5208 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2TouchFeatureTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2TouchFeatureTest.java @@ -36,8 +36,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -50,7 +52,6 @@ import synapticloop.b2.response.BaseB2Response; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -59,9 +60,9 @@ public class B2TouchFeatureTest extends AbstractB2Test { @Test public void testTouchEncrypted() throws Exception { final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); final TransferStatus status = new TransferStatus(); @@ -76,12 +77,12 @@ public void testTouchEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); final TransferStatus status = new TransferStatus(); @@ -96,9 +97,9 @@ public void testTouchLongFilenameEncrypted() throws Exception { @Test public void testTouchEncryptedDefaultFeature() throws Exception { final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); final TransferStatus status = new TransferStatus(); diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2WriteFeatureTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2WriteFeatureTest.java index 7713007577b..b955c1c504f 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2WriteFeatureTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/B2WriteFeatureTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -69,9 +70,9 @@ public void testWrite() throws Exception { final byte[] content = RandomUtils.nextBytes(length); status.setLength(content.length); final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index d54dede8408..a00d8c836e7 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -46,12 +46,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -66,7 +68,6 @@ import synapticloop.b2.response.BaseB2Response; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -78,8 +79,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -105,8 +106,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); @@ -125,15 +126,15 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("/test-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); @@ -157,8 +158,8 @@ public void testCopyFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); @@ -194,8 +195,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new B2FindFeature(session, fileid).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new B2DirectoryFeature(session, fileid)).mkdir( @@ -221,8 +222,8 @@ public void testCopyDirectoryIntoVault() throws Exception { new B2TouchFeature(session, fileid).touch(new B2WriteFeature(session, fileid), cleartextFile, new TransferStatus()); assertTrue(new B2FindFeature(session, fileid).find(cleartextFolder)); assertTrue(new B2FindFeature(session, fileid).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -247,8 +248,8 @@ public void testCopyFileOutsideVault() throws Exception { new B2DirectoryFeature(session, fileid).mkdir(new B2WriteFeature(session, fileid), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new B2DirectoryFeature(session, fileid)).mkdir( @@ -273,8 +274,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/CryptoB2SingleTransferWorkerTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/CryptoB2SingleTransferWorkerTest.java index a061a4203d2..64df31ff4ae 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/CryptoB2SingleTransferWorkerTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/CryptoB2SingleTransferWorkerTest.java @@ -50,6 +50,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -91,8 +92,8 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { diff --git a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java index 93b8af69087..78bb4a4f431 100644 --- a/backblaze/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java +++ b/backblaze/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java @@ -40,6 +40,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.MoveWorker; import ch.cyberduck.test.IntegrationTest; @@ -68,8 +69,8 @@ public void testMoveFileIntoVault() throws Exception { assertTrue(new DefaultFindFeature(session).find(clearFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new B2DirectoryFeature(session, fileid)).mkdir( @@ -95,8 +96,8 @@ public void testMoveDirectoryIntoVault() throws Exception { new B2TouchFeature(session, fileid).touch(new B2WriteFeature(session, fileid), clearFile, new TransferStatus()); assertTrue(new DefaultFindFeature(session).find(clearFolder)); assertTrue(new DefaultFindFeature(session).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -121,8 +122,8 @@ public void testMoveFileOutsideVault() throws Exception { new B2DirectoryFeature(session, fileid).mkdir(new B2WriteFeature(session, fileid), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new B2DirectoryFeature(session, fileid)).mkdir( @@ -148,8 +149,8 @@ public void testMoveDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final B2VersionIdProvider fileid = new B2VersionIdProvider(session); diff --git a/binding/pom.xml b/binding/pom.xml index ee6406562ff..f59d90638de 100644 --- a/binding/pom.xml +++ b/binding/pom.xml @@ -19,7 +19,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT binding jar diff --git a/bonjour/dll/pom.xml b/bonjour/dll/pom.xml index 80b55d2576d..5d061e3f8d1 100644 --- a/bonjour/dll/pom.xml +++ b/bonjour/dll/pom.xml @@ -5,7 +5,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Bonjour pom diff --git a/bonjour/native/pom.xml b/bonjour/native/pom.xml index 7f28e0b32f9..b89c0bfed8a 100644 --- a/bonjour/native/pom.xml +++ b/bonjour/native/pom.xml @@ -5,7 +5,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Bonjour.Native pom diff --git a/bonjour/pom.xml b/bonjour/pom.xml index ec313109d6e..cce161af507 100644 --- a/bonjour/pom.xml +++ b/bonjour/pom.xml @@ -18,7 +18,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT 4.0.0 diff --git a/box/pom.xml b/box/pom.xml index 2e75ca42111..b794f712662 100644 --- a/box/pom.xml +++ b/box/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT box diff --git a/box/src/test/java/ch/cyberduck/core/box/AbstractBoxTest.java b/box/src/test/java/ch/cyberduck/core/box/AbstractBoxTest.java index 5ece290f673..d3ba73eb22f 100644 --- a/box/src/test/java/ch/cyberduck/core/box/AbstractBoxTest.java +++ b/box/src/test/java/ch/cyberduck/core/box/AbstractBoxTest.java @@ -27,10 +27,10 @@ import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; import ch.cyberduck.core.Scheme; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -48,11 +48,11 @@ public class AbstractBoxTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/box/src/test/java/ch/cyberduck/core/cryptomator/BoxThresholdUploadServiceTest.java b/box/src/test/java/ch/cyberduck/core/cryptomator/BoxThresholdUploadServiceTest.java index 1c604e5f503..e83b706d8af 100644 --- a/box/src/test/java/ch/cyberduck/core/cryptomator/BoxThresholdUploadServiceTest.java +++ b/box/src/test/java/ch/cyberduck/core/cryptomator/BoxThresholdUploadServiceTest.java @@ -47,6 +47,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -77,8 +78,8 @@ public void testUploadVaultWithBulkFeature() throws Exception { final Path container = new BoxDirectoryFeature(session, fileid).mkdir(new BoxWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(AbstractPath.Type.directory)), new TransferStatus().setLength(0L)); final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final Local local = new Local(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); diff --git a/box/src/test/java/ch/cyberduck/core/cryptomator/BoxWriteFeatureTest.java b/box/src/test/java/ch/cyberduck/core/cryptomator/BoxWriteFeatureTest.java index daa3c8cec1a..eceb543152e 100644 --- a/box/src/test/java/ch/cyberduck/core/cryptomator/BoxWriteFeatureTest.java +++ b/box/src/test/java/ch/cyberduck/core/cryptomator/BoxWriteFeatureTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -66,8 +67,8 @@ public void testWriteVault() throws Exception { final Path container = new BoxDirectoryFeature(session, fileid).mkdir(new BoxWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature feature = new CryptoWriteFeature<>(session, new BoxWriteFeature(session, fileid), cryptomator); final byte[] content = RandomUtils.nextBytes(6 * 1024 * 1024); @@ -99,8 +100,8 @@ public void testWriteVaultWithTimeStamp() throws Exception { final Path container = new BoxDirectoryFeature(session, fileid).mkdir(new BoxWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature feature = new CryptoWriteFeature<>(session, new BoxWriteFeature(session, fileid), cryptomator); final byte[] content = RandomUtils.nextBytes(6 * 1024 * 1024); diff --git a/box/src/test/java/ch/cyberduck/core/cryptomator/BufferWriteFeatureTest.java b/box/src/test/java/ch/cyberduck/core/cryptomator/BufferWriteFeatureTest.java index 0f36353221c..4eedbd39489 100644 --- a/box/src/test/java/ch/cyberduck/core/cryptomator/BufferWriteFeatureTest.java +++ b/box/src/test/java/ch/cyberduck/core/cryptomator/BufferWriteFeatureTest.java @@ -39,6 +39,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -66,8 +67,8 @@ public void testWriteVault() throws Exception { final Path container = new BoxDirectoryFeature(session, fileid).mkdir(new BoxWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature feature = new CryptoWriteFeature<>(session, new BufferWriteFeature(session), cryptomator); final byte[] content = RandomUtils.nextBytes(1024 * 1024); diff --git a/brick/pom.xml b/brick/pom.xml index c5ef41a7455..0cdf85349b2 100644 --- a/brick/pom.xml +++ b/brick/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT brick jar diff --git a/brick/src/main/java/ch/cyberduck/core/brick/BrickCopyFeature.java b/brick/src/main/java/ch/cyberduck/core/brick/BrickCopyFeature.java index b1ea3afff2c..394d54f73a6 100644 --- a/brick/src/main/java/ch/cyberduck/core/brick/BrickCopyFeature.java +++ b/brick/src/main/java/ch/cyberduck/core/brick/BrickCopyFeature.java @@ -62,7 +62,7 @@ public Path copy(final Path file, final Path target, final TransferStatus status if(entity.getFileMigrationId() != null) { this.poll(client, entity); } - return new Path(target).withAttributes(new PathAttributes(file.attributes()).setVault(null)); + return new Path(target).withAttributes(new PathAttributes(file.attributes()).setVaultMetadata(null)); } catch(ApiException e) { throw new BrickExceptionMappingService().map("Cannot copy {0}", e, file); diff --git a/brick/src/main/java/ch/cyberduck/core/brick/BrickMoveFeature.java b/brick/src/main/java/ch/cyberduck/core/brick/BrickMoveFeature.java index c4d356a8c6c..aa7d48d8183 100644 --- a/brick/src/main/java/ch/cyberduck/core/brick/BrickMoveFeature.java +++ b/brick/src/main/java/ch/cyberduck/core/brick/BrickMoveFeature.java @@ -60,7 +60,7 @@ public Path move(final Path file, final Path target, final TransferStatus status if(entity.getFileMigrationId() != null) { this.poll(client, entity); } - return new Path(target).withAttributes(new PathAttributes(file.attributes()).setVault(null)); + return new Path(target).withAttributes(new PathAttributes(file.attributes()).setVaultMetadata(null)); } catch(ApiException e) { throw new BrickExceptionMappingService().map("Cannot rename {0}", e, file); diff --git a/brick/src/test/java/ch/cyberduck/core/brick/AbstractBrickTest.java b/brick/src/test/java/ch/cyberduck/core/brick/AbstractBrickTest.java index 119ddc004c6..7f5ac86fdfb 100644 --- a/brick/src/test/java/ch/cyberduck/core/brick/AbstractBrickTest.java +++ b/brick/src/test/java/ch/cyberduck/core/brick/AbstractBrickTest.java @@ -26,10 +26,10 @@ import ch.cyberduck.core.LoginOptions; import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -47,11 +47,11 @@ public class AbstractBrickTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/brick/src/test/java/ch/cyberduck/core/brick/cryptomator/BrickListServiceTest.java b/brick/src/test/java/ch/cyberduck/core/brick/cryptomator/BrickListServiceTest.java index 54f85e1b235..7c63c8e6176 100644 --- a/brick/src/test/java/ch/cyberduck/core/brick/cryptomator/BrickListServiceTest.java +++ b/brick/src/test/java/ch/cyberduck/core/brick/cryptomator/BrickListServiceTest.java @@ -26,7 +26,8 @@ import ch.cyberduck.core.brick.BrickListService; import ch.cyberduck.core.brick.BrickWriteFeature; import ch.cyberduck.core.brick.io.swagger.client.model.FileEntity; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.AbstractVault; +import ch.cyberduck.core.cryptomator.CryptoVaultProvider; import ch.cyberduck.core.cryptomator.features.CryptoListService; import ch.cyberduck.core.cryptomator.features.CryptoTouchFeature; import ch.cyberduck.core.cryptomator.features.CryptoWriteFeature; @@ -35,6 +36,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Assert; @@ -58,8 +60,8 @@ public void testListCryptomator() throws Exception { EnumSet.of(Path.Type.directory, Path.Type.volume)), new TransferStatus()); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertTrue(new CryptoListService(session, new BrickListService(session), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( diff --git a/brick/src/test/java/ch/cyberduck/core/cryptomator/DefaultTouchFeatureTest.java b/brick/src/test/java/ch/cyberduck/core/cryptomator/DefaultTouchFeatureTest.java index 6e518e70b37..3d96f051ce2 100644 --- a/brick/src/test/java/ch/cyberduck/core/cryptomator/DefaultTouchFeatureTest.java +++ b/brick/src/test/java/ch/cyberduck/core/cryptomator/DefaultTouchFeatureTest.java @@ -33,8 +33,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -45,19 +47,20 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) public class DefaultTouchFeatureTest extends AbstractBrickTest { + //TODO + @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("/", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -68,12 +71,12 @@ public void testTouchLongFilenameEncrypted() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("/", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( diff --git a/cli/dll/pom.xml b/cli/dll/pom.xml index 045f5dc5e3b..28857440673 100644 --- a/cli/dll/pom.xml +++ b/cli/dll/pom.xml @@ -20,7 +20,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Cli pom diff --git a/cli/linux/pom.xml b/cli/linux/pom.xml index 2f8896ea363..df5c6636a3f 100644 --- a/cli/linux/pom.xml +++ b/cli/linux/pom.xml @@ -20,7 +20,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT cli-linux Cyberduck CLI Linux diff --git a/cli/osx/pom.xml b/cli/osx/pom.xml index 8c4769b818f..8916ba5d7f0 100644 --- a/cli/osx/pom.xml +++ b/cli/osx/pom.xml @@ -20,7 +20,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT cli-osx Cyberduck CLI Mac diff --git a/cli/pom.xml b/cli/pom.xml index 8a75fa3aa1b..a0b507d645e 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -19,7 +19,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT cli diff --git a/cli/src/main/java/ch/cyberduck/cli/Terminal.java b/cli/src/main/java/ch/cyberduck/cli/Terminal.java index c7f002840c8..486be082873 100644 --- a/cli/src/main/java/ch/cyberduck/cli/Terminal.java +++ b/cli/src/main/java/ch/cyberduck/cli/Terminal.java @@ -48,6 +48,7 @@ import ch.cyberduck.core.transfer.TransferPrompt; import ch.cyberduck.core.transfer.TransferSpeedometer; import ch.cyberduck.core.vault.LoadingVaultLookupListener; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.vault.VaultRegistry; import ch.cyberduck.core.vault.VaultRegistryFactory; import ch.cyberduck.core.worker.AttributesWorker; @@ -247,7 +248,7 @@ public void uncaughtException(final Thread t, final Throwable e) { log.debug("Attempting to load vault from {}", vault); try { this.execute(new TerminalBackgroundAction<>(controller, source, new LoadVaultWorker(new LoadingVaultLookupListener(source.getVaultRegistry(), - new TerminalPasswordCallback()), vault))); + new TerminalPasswordCallback()), new VaultMetadata(vault, VaultMetadata.Type.valueOf(preferences.getProperty("cryptomator.vault.default")))))); } catch(TerminalBackgroundException e) { return Exit.failure; diff --git a/cli/src/main/java/ch/cyberduck/cli/TerminalPreferences.java b/cli/src/main/java/ch/cyberduck/cli/TerminalPreferences.java index dd13d2bfc4f..9e33bd55c60 100644 --- a/cli/src/main/java/ch/cyberduck/cli/TerminalPreferences.java +++ b/cli/src/main/java/ch/cyberduck/cli/TerminalPreferences.java @@ -17,7 +17,8 @@ import ch.cyberduck.core.DisabledConnectionTimeout; import ch.cyberduck.core.Local; import ch.cyberduck.core.Permission; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.CryptoVaultProvider; +import ch.cyberduck.core.cryptomator.impl.v8.CryptoVault; import ch.cyberduck.core.cryptomator.random.FastSecureRandomProvider; import ch.cyberduck.core.preferences.Preferences; import ch.cyberduck.core.transfer.Transfer; @@ -58,7 +59,9 @@ protected void setFactories() { for(Transfer.Type t : Transfer.Type.values()) { this.setDefault(String.format("factory.transferpromptcallback.%s.class", t.name()), TerminalTransferPrompt.class.getName()); } + //TODO braucht es diesen eintrag noch? this.setDefault("factory.vault.class", CryptoVault.class.getName()); + this.setDefault("factory.vaultprovider.class", CryptoVaultProvider.class.getName()); this.setDefault("factory.securerandom.class", FastSecureRandomProvider.class.getName()); this.setDefault("factory.connectiontimeout.class", DisabledConnectionTimeout.class.getName()); } diff --git a/cli/windows/pom.xml b/cli/windows/pom.xml index b7ef39c6e37..5c9049cec31 100644 --- a/cli/windows/pom.xml +++ b/cli/windows/pom.xml @@ -20,7 +20,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT cli-windows Cyberduck CLI Windows diff --git a/core/dll/pom.xml b/core/dll/pom.xml index 250ef599fbd..484e070b332 100644 --- a/core/dll/pom.xml +++ b/core/dll/pom.xml @@ -5,7 +5,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Core pom diff --git a/core/dylib/pom.xml b/core/dylib/pom.xml index dfdbb04f2da..103444e49a7 100644 --- a/core/dylib/pom.xml +++ b/core/dylib/pom.xml @@ -5,7 +5,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT libcore diff --git a/core/native/pom.xml b/core/native/pom.xml index 0a632569837..3c895e72946 100644 --- a/core/native/pom.xml +++ b/core/native/pom.xml @@ -5,7 +5,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Core.Native pom diff --git a/core/native/refresh/pom.xml b/core/native/refresh/pom.xml index 3835095fd9e..8e97f0d1e9b 100644 --- a/core/native/refresh/pom.xml +++ b/core/native/refresh/pom.xml @@ -5,7 +5,7 @@ ch.cyberduck Cyberduck.Core.Native ../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Core.Refresh pom diff --git a/core/pom.xml b/core/pom.xml index f4734797079..5f0027fda6f 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT core jar diff --git a/core/src/main/java/ch/cyberduck/core/PathAttributes.java b/core/src/main/java/ch/cyberduck/core/PathAttributes.java index 69ae359ef2b..d54f39a3d80 100644 --- a/core/src/main/java/ch/cyberduck/core/PathAttributes.java +++ b/core/src/main/java/ch/cyberduck/core/PathAttributes.java @@ -23,6 +23,7 @@ import ch.cyberduck.core.io.Checksum; import ch.cyberduck.core.serializer.Serializer; import ch.cyberduck.core.transfer.TransferStatus; +import ch.cyberduck.core.vault.VaultMetadata; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; @@ -145,6 +146,11 @@ public class PathAttributes extends Attributes implements Serializable { * Cryptomator vault */ private Path vault; + + /** + * Cryptomator vault metadata + */ + private VaultMetadata vaultMetadata; /** * Cryptomator decrypted path */ @@ -156,7 +162,7 @@ public class PathAttributes extends Attributes implements Serializable { /** * Unique identifier for cryptomator */ - private String directoryId; + private byte[] directoryId; private Map custom = Collections.emptyMap(); @@ -199,6 +205,7 @@ public PathAttributes(final PathAttributes copy) { custom = new HashMap<>(copy.custom); verdict = copy.verdict; vault = copy.vault; + vaultMetadata = copy.vaultMetadata; decrypted = copy.decrypted; encrypted = copy.encrypted; directoryId = copy.directoryId; @@ -287,6 +294,16 @@ public T serialize(final Serializer dict) { dict.setObjectForKey(vault, "Vault"); } } + if(vaultMetadata != null) { + if(vaultMetadata.root != null) { + if(vaultMetadata.root.attributes() == this) { + log.debug("Skip serializing vault metadata root attribute {} to avoid recursion", vaultMetadata.root); + } + else { + dict.setObjectForKey(vaultMetadata.root, "Vault Metadata"); + } + } + } if(!custom.isEmpty()) { dict.setMapForKey(custom, "Custom"); } @@ -480,11 +497,11 @@ public PathAttributes setLockId(final String lockId) { return this; } - public String getDirectoryId() { + public byte[] getDirectoryId() { return directoryId; } - public PathAttributes setDirectoryId(final String directoryId) { + public PathAttributes setDirectoryId(final byte[] directoryId) { this.directoryId = directoryId; return this; } @@ -534,6 +551,15 @@ public Path getVault() { return vault; } + public PathAttributes setVaultMetadata(final VaultMetadata vaultMetadata) { + this.vaultMetadata = vaultMetadata; + return this; + } + + public VaultMetadata getVaultMetadata() { + return vaultMetadata; + } + /** * If the path should not be displayed in a browser by default unless the user explicitly chooses to show hidden * files. @@ -803,7 +829,7 @@ public PathAttributes setLockId(final String lockId) { } @Override - public PathAttributes setDirectoryId(final String directoryId) { + public PathAttributes setDirectoryId(final byte[] directoryId) { return this; } diff --git a/core/src/main/java/ch/cyberduck/core/features/Vault.java b/core/src/main/java/ch/cyberduck/core/features/Vault.java index 23243500404..1267d61d4ca 100644 --- a/core/src/main/java/ch/cyberduck/core/features/Vault.java +++ b/core/src/main/java/ch/cyberduck/core/features/Vault.java @@ -24,6 +24,7 @@ import ch.cyberduck.core.exception.UnsupportedException; import ch.cyberduck.core.vault.DisabledVault; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; public interface Vault { @@ -35,7 +36,7 @@ public interface Vault { * @throws BackgroundException Failure reading master key from server * @throws NotfoundException No master key file in home */ - Path create(Session session, String region, VaultCredentials credentials) throws BackgroundException; + Vault create(Session session, String region, VaultCredentials credentials) throws BackgroundException; /** * Open existing vault @@ -102,6 +103,8 @@ public interface Vault { */ Path getHome(); + VaultMetadata getMetadata(); + enum State { open, closed diff --git a/core/src/main/java/ch/cyberduck/core/serializer/PathAttributesDictionary.java b/core/src/main/java/ch/cyberduck/core/serializer/PathAttributesDictionary.java index 0ad7f805a2b..a54bfed364f 100644 --- a/core/src/main/java/ch/cyberduck/core/serializer/PathAttributesDictionary.java +++ b/core/src/main/java/ch/cyberduck/core/serializer/PathAttributesDictionary.java @@ -24,6 +24,7 @@ import ch.cyberduck.core.features.Quota; import ch.cyberduck.core.io.Checksum; import ch.cyberduck.core.io.HashAlgorithm; +import ch.cyberduck.core.vault.VaultMetadataDictionary; import java.util.Collections; import java.util.Map; @@ -117,6 +118,10 @@ public PathAttributes deserialize(final T serialized) { if(vaultObj != null) { attributes.setVault(new PathDictionary<>(factory).deserialize(vaultObj)); } + final T vaultMetadataObj = dict.objectForKey("Vault Metadata"); + if(vaultMetadataObj != null) { + attributes.setVaultMetadata(new VaultMetadataDictionary<>(factory).deserialize(vaultMetadataObj)); + } final Map customObj = dict.mapForKey("Custom"); if(customObj != null) { attributes.setCustom(customObj); diff --git a/core/src/main/java/ch/cyberduck/core/vault/DefaultVaultRegistry.java b/core/src/main/java/ch/cyberduck/core/vault/DefaultVaultRegistry.java index 9550e607bbe..6787da34a05 100644 --- a/core/src/main/java/ch/cyberduck/core/vault/DefaultVaultRegistry.java +++ b/core/src/main/java/ch/cyberduck/core/vault/DefaultVaultRegistry.java @@ -23,14 +23,12 @@ import ch.cyberduck.core.SimplePathPredicate; import ch.cyberduck.core.UrlProvider; import ch.cyberduck.core.features.*; -import ch.cyberduck.core.preferences.HostPreferencesFactory; import ch.cyberduck.core.preferences.PreferencesFactory; import ch.cyberduck.core.vault.registry.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.concurrent.CopyOnWriteArraySet; @@ -41,9 +39,14 @@ public class DefaultVaultRegistry extends CopyOnWriteArraySet implements PreferencesFactory.get().getProperty("cryptomator.vault.masterkey.filename"); public static final String DEFAULT_BACKUPKEY_FILE_NAME = String.format("%s.bkup", PreferencesFactory.get().getProperty("cryptomator.vault.masterkey.filename")); + + // TODO können die weg? wird z.b. weiter unten via hostpreferences geholt public static final String DEFAULT_VAULTCONFIG_FILE_NAME = PreferencesFactory.get().getProperty("cryptomator.vault.config.filename"); + public static final String DEFAULT_VAULTCONFIGUVF_FILE_NAME = + PreferencesFactory.get().getProperty("cryptomator.vault.config.filename.uvf"); + private final PasswordCallback prompt; public DefaultVaultRegistry(final PasswordCallback prompt) { @@ -73,7 +76,7 @@ public boolean close(final Path directory) { }); } finally { - directory.attributes().setVault(null); + directory.attributes().setVaultMetadata(null); } } @@ -107,18 +110,14 @@ public Vault find(final Session session, final Path file, final boolean autol } if(autoload) { final LoadingVaultLookupListener listener = new LoadingVaultLookupListener(this, prompt); - if(file.attributes().getVault() != null) { - return listener.load(session, file.attributes().getVault(), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.masterkey.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.config.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8)); + if(file.attributes().getVaultMetadata() != null) { + return listener.load(session, file.attributes().getVaultMetadata() + ); } final Path directory = file.getParent(); - if(directory.attributes().getVault() != null) { - return listener.load(session, directory.attributes().getVault(), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.masterkey.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.config.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8)); + if(directory.attributes().getVaultMetadata() != null) { + return listener.load(session, directory.attributes().getVaultMetadata() + ); } } return Vault.DISABLED; diff --git a/core/src/main/java/ch/cyberduck/core/vault/DisabledVault.java b/core/src/main/java/ch/cyberduck/core/vault/DisabledVault.java index 70d119aede1..76b7d0541f2 100644 --- a/core/src/main/java/ch/cyberduck/core/vault/DisabledVault.java +++ b/core/src/main/java/ch/cyberduck/core/vault/DisabledVault.java @@ -36,7 +36,7 @@ public DisabledVault(final Path home) { } @Override - public Path create(final Session session, final String region, final VaultCredentials credentials) { + public Vault create(final Session session, final String region, final VaultCredentials credentials) { return null; } @@ -96,6 +96,10 @@ public Path getHome() { return home; } + @Override + public VaultMetadata getMetadata() { + return null; + } @Override public boolean equals(final Object o) { diff --git a/core/src/main/java/ch/cyberduck/core/vault/DisabledVaultLookupListener.java b/core/src/main/java/ch/cyberduck/core/vault/DisabledVaultLookupListener.java index f1cd16e3f11..2eff02bead2 100644 --- a/core/src/main/java/ch/cyberduck/core/vault/DisabledVaultLookupListener.java +++ b/core/src/main/java/ch/cyberduck/core/vault/DisabledVaultLookupListener.java @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; import ch.cyberduck.core.features.Vault; @@ -26,8 +25,8 @@ public final class DisabledVaultLookupListener implements VaultLookupListener { private static final Logger log = LogManager.getLogger(DisabledVaultLookupListener.class); @Override - public Vault load(final Session session, final Path directory, final String masterkey, final String config, final byte[] pepper) { - log.warn("Ignore vault {}", directory); + public Vault load(final Session session, final VaultMetadata metadata) { + log.warn("Ignore vault {}", metadata); return Vault.DISABLED; } } diff --git a/core/src/main/java/ch/cyberduck/core/vault/DisabledVaultProvider.java b/core/src/main/java/ch/cyberduck/core/vault/DisabledVaultProvider.java new file mode 100644 index 00000000000..e096580ac26 --- /dev/null +++ b/core/src/main/java/ch/cyberduck/core/vault/DisabledVaultProvider.java @@ -0,0 +1,50 @@ +package ch.cyberduck.core.vault; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.ListProgressListener; +import ch.cyberduck.core.Path; +import ch.cyberduck.core.Session; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.features.Find; +import ch.cyberduck.core.features.Vault; + +public class DisabledVaultProvider implements VaultProvider { + @Override + public boolean isVault(final Path path) { + return false; + } + + @Override + public VaultMetadata metadata(final Path path) { + return null; + } + + @Override + public VaultMetadata find(final Path directory, final Find find, final ListProgressListener listener) throws BackgroundException { + return null; + } + + @Override + public Vault provide(final Session session, final VaultMetadata metadata) { + return Vault.DISABLED; + } + + @Override + public Vault create(final Session session, final String region, final VaultCredentials credentials, final VaultMetadata metadata) throws BackgroundException { + return Vault.DISABLED; + } +} diff --git a/core/src/main/java/ch/cyberduck/core/vault/LoadingVaultLookupListener.java b/core/src/main/java/ch/cyberduck/core/vault/LoadingVaultLookupListener.java index 242f903b8d5..49ed4fb9d3d 100644 --- a/core/src/main/java/ch/cyberduck/core/vault/LoadingVaultLookupListener.java +++ b/core/src/main/java/ch/cyberduck/core/vault/LoadingVaultLookupListener.java @@ -16,8 +16,6 @@ */ import ch.cyberduck.core.PasswordCallback; -import ch.cyberduck.core.PasswordStore; -import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Vault; @@ -37,21 +35,21 @@ public LoadingVaultLookupListener(final VaultRegistry registry, final PasswordCa } @Override - public Vault load(final Session session, final Path directory, final String masterkey, final String config, final byte[] pepper) throws VaultUnlockCancelException { + public Vault load(final Session session, final VaultMetadata metadata) throws VaultUnlockCancelException { synchronized(registry) { - if(registry.contains(directory)) { - return registry.find(session, directory); + if(registry.contains(metadata.root)) { + return registry.find(session, metadata.root); } - final Vault vault = VaultFactory.get(directory, masterkey, config, pepper); - log.info("Loading vault {} for session {}", vault, session); + log.info("Loading vault for session {}", session); + final Vault vault = VaultProviderFactory.get(session).provide(session, metadata); try { registry.add(vault.load(session, prompt)); + return vault; } catch(BackgroundException e) { - log.warn("Failure {} loading vault {}", e, vault); + log.warn("Failure {} loading vault", e); throw new VaultUnlockCancelException(vault, e); } - return vault; } } } diff --git a/core/src/main/java/ch/cyberduck/core/vault/VaultFinderListProgressListener.java b/core/src/main/java/ch/cyberduck/core/vault/VaultFinderListProgressListener.java index 4f9eb821ce2..4c0249678e9 100644 --- a/core/src/main/java/ch/cyberduck/core/vault/VaultFinderListProgressListener.java +++ b/core/src/main/java/ch/cyberduck/core/vault/VaultFinderListProgressListener.java @@ -23,12 +23,10 @@ import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.exception.ConnectionCanceledException; import ch.cyberduck.core.features.Vault; -import ch.cyberduck.core.preferences.HostPreferencesFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; @@ -38,21 +36,17 @@ public class VaultFinderListProgressListener extends IndexedListProgressListener private final Session session; private final VaultLookupListener lookup; private final ListProgressListener proxy; - private final String config; - private final String masterkey; - private final byte[] pepper; // Number of files to wait for until proxy is notified of files private final int filecount; private final AtomicBoolean canceled = new AtomicBoolean(); + private final VaultProvider provider; public VaultFinderListProgressListener(final Session session, final VaultLookupListener lookup, final ListProgressListener proxy, final int filecount) { this.session = session; this.lookup = lookup; this.proxy = proxy; - this.config = HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.config.filename"); - this.masterkey = HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.masterkey.filename"); - this.pepper = HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8); this.filecount = filecount; + this.provider = VaultProviderFactory.get(session); } @Override @@ -83,10 +77,10 @@ public void chunk(final Path folder, final AttributedList list) throws Con @Override public void visit(final AttributedList list, final int index, final Path file) throws ConnectionCanceledException { - final Path directory = file.getParent(); - if(config.equals(file.getName()) || masterkey.equals(file.getName())) { + final VaultMetadata metadata = provider.metadata(file); + if(metadata != null) { log.info("Found vault config or masterkey file {}", file); - final Vault vault = lookup.load(session, directory, masterkey, config, pepper); + final Vault vault = lookup.load(session, metadata); if(vault.equals(Vault.DISABLED)) { return; } diff --git a/core/src/main/java/ch/cyberduck/core/vault/VaultLookupListener.java b/core/src/main/java/ch/cyberduck/core/vault/VaultLookupListener.java index 7e4f12cbbb2..56782de4096 100644 --- a/core/src/main/java/ch/cyberduck/core/vault/VaultLookupListener.java +++ b/core/src/main/java/ch/cyberduck/core/vault/VaultLookupListener.java @@ -15,10 +15,9 @@ * GNU General Public License for more details. */ -import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; import ch.cyberduck.core.features.Vault; public interface VaultLookupListener { - Vault load(final Session session, Path directory, String masterkey, final String config, byte[] pepper) throws VaultUnlockCancelException; + Vault load(final Session session, VaultMetadata metadata) throws VaultUnlockCancelException; } diff --git a/core/src/main/java/ch/cyberduck/core/vault/VaultMetadata.java b/core/src/main/java/ch/cyberduck/core/vault/VaultMetadata.java new file mode 100644 index 00000000000..468b609d344 --- /dev/null +++ b/core/src/main/java/ch/cyberduck/core/vault/VaultMetadata.java @@ -0,0 +1,87 @@ +package ch.cyberduck.core.vault; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.Path; +import ch.cyberduck.core.Serializable; +import ch.cyberduck.core.serializer.Serializer; + +import java.util.Objects; + +public class VaultMetadata implements Serializable { + + public Path root; + public Type type; + + public enum Type { + V8, UVF + } + + public VaultMetadata() { + } + + public VaultMetadata(final Path path, final Type type) { + this.root = path; + this.type = type; + } + + @Override + public T serialize(final Serializer dict) { + if(root != null) { + dict.setObjectForKey(root, "Root"); + } + if(type != null) { + dict.setStringForKey(type.name(), "Type"); + } + return dict.getSerialized(); + } + + @Override + public final boolean equals(final Object o) { + if(o == this) { + return true; + } + if(!(o instanceof VaultMetadata)) { + return false; + } + + VaultMetadata that = (VaultMetadata) o; + if(!Objects.equals(root, that.root)) { + return false; + } + if(type != that.type) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int result = Objects.hashCode(root); + result = 31 * result + Objects.hashCode(type); + return result; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("VaultMetadata{"); + sb.append("root=").append(root); + sb.append(", type=").append(type); + sb.append('}'); + return sb.toString(); + } +} + diff --git a/core/src/main/java/ch/cyberduck/core/vault/VaultMetadataDictionary.java b/core/src/main/java/ch/cyberduck/core/vault/VaultMetadataDictionary.java new file mode 100644 index 00000000000..e3bd813a80e --- /dev/null +++ b/core/src/main/java/ch/cyberduck/core/vault/VaultMetadataDictionary.java @@ -0,0 +1,47 @@ +package ch.cyberduck.core.vault; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.DeserializerFactory; +import ch.cyberduck.core.serializer.Deserializer; +import ch.cyberduck.core.serializer.PathDictionary; + +public class VaultMetadataDictionary { + + private final DeserializerFactory factory; + + public VaultMetadataDictionary() { + this.factory = new DeserializerFactory<>(); + } + + public VaultMetadataDictionary(final DeserializerFactory factory) { + this.factory = factory; + } + + public VaultMetadata deserialize(final T serialized) { + final Deserializer dict = factory.create(serialized); + final VaultMetadata vaultMetadata = new VaultMetadata(); + final T vaultObj = dict.objectForKey("Root"); + if(vaultObj != null) { + vaultMetadata.root = new PathDictionary<>(factory).deserialize(vaultObj); + } + final String type = dict.stringForKey("Type"); + if(type != null) { + vaultMetadata.type = VaultMetadata.Type.valueOf(type); + } + return vaultMetadata; + } +} diff --git a/core/src/main/java/ch/cyberduck/core/vault/VaultProvider.java b/core/src/main/java/ch/cyberduck/core/vault/VaultProvider.java new file mode 100644 index 00000000000..7415052e739 --- /dev/null +++ b/core/src/main/java/ch/cyberduck/core/vault/VaultProvider.java @@ -0,0 +1,37 @@ +package ch.cyberduck.core.vault; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.ListProgressListener; +import ch.cyberduck.core.Path; +import ch.cyberduck.core.Session; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.features.Find; +import ch.cyberduck.core.features.Vault; + +public interface VaultProvider { + boolean isVault(Path path); + + VaultMetadata metadata(Path path); + + VaultMetadata find(Path directory, Find find, ListProgressListener listener) throws BackgroundException; + + Vault provide(Session session, VaultMetadata metadata); + + Vault create(Session session, String region, VaultCredentials credentials, VaultMetadata metadata) throws BackgroundException; + + VaultProvider DISABLED = new DisabledVaultProvider(); +} diff --git a/core/src/main/java/ch/cyberduck/core/vault/VaultProviderFactory.java b/core/src/main/java/ch/cyberduck/core/vault/VaultProviderFactory.java new file mode 100644 index 00000000000..172fc59d255 --- /dev/null +++ b/core/src/main/java/ch/cyberduck/core/vault/VaultProviderFactory.java @@ -0,0 +1,55 @@ +package ch.cyberduck.core.vault; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.Factory; +import ch.cyberduck.core.Session; + +import org.apache.commons.lang3.reflect.ConstructorUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +public class VaultProviderFactory extends Factory { + private static final Logger log = LogManager.getLogger(VaultProviderFactory.class); + + private VaultProviderFactory() { + super("factory.vaultprovider.class"); + } + + public static VaultProvider get(final Session session) { + return new VaultProviderFactory().create(session); + } + + private VaultProvider create(final Session session) { + try { + final Constructor constructor = ConstructorUtils.getMatchingAccessibleConstructor(clazz, + session.getClass()); + if(null == constructor) { + log.warn("No matching constructor for parameter {}", session.getClass()); + // Call default constructor for disabled implementations + return clazz.getDeclaredConstructor().newInstance(); + } + return constructor.newInstance(session); + } + catch(InstantiationException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { + log.error("Failure loading callback class {}. {}", clazz, e.getMessage()); + return VaultProvider.DISABLED; + } + } +} diff --git a/core/src/main/java/ch/cyberduck/core/vault/registry/VaultRegistryFindFeature.java b/core/src/main/java/ch/cyberduck/core/vault/registry/VaultRegistryFindFeature.java index 90570bc7c35..c05b9d2a0c5 100644 --- a/core/src/main/java/ch/cyberduck/core/vault/registry/VaultRegistryFindFeature.java +++ b/core/src/main/java/ch/cyberduck/core/vault/registry/VaultRegistryFindFeature.java @@ -23,13 +23,15 @@ import ch.cyberduck.core.features.Vault; import ch.cyberduck.core.preferences.HostPreferencesFactory; import ch.cyberduck.core.vault.VaultLookupListener; +import ch.cyberduck.core.vault.VaultMetadata; +import ch.cyberduck.core.vault.VaultProvider; +import ch.cyberduck.core.vault.VaultProviderFactory; import ch.cyberduck.core.vault.VaultRegistry; import ch.cyberduck.core.vault.VaultUnlockCancelException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.nio.charset.StandardCharsets; import java.util.EnumSet; public class VaultRegistryFindFeature implements Find { @@ -40,6 +42,7 @@ public class VaultRegistryFindFeature implements Find { private final VaultRegistry registry; private final VaultLookupListener lookup; private final boolean autodetect; + private final VaultProvider provider; public VaultRegistryFindFeature(final Session session, final Find proxy, final VaultRegistry registry, final VaultLookupListener lookup) { this.session = session; @@ -48,6 +51,7 @@ public VaultRegistryFindFeature(final Session session, final Find proxy, fina this.lookup = lookup; this.autodetect = HostPreferencesFactory.get(session.getHost()).getBoolean("cryptomator.vault.autodetect") && HostPreferencesFactory.get(session.getHost()).getBoolean("cryptomator.enable"); + this.provider = VaultProviderFactory.get(session); } @Override @@ -60,14 +64,13 @@ public boolean find(final Path file, final ListProgressListener listener) throws HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.config.filename"), EnumSet.of(Path.Type.file)); final Path key = new Path(directory, HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.masterkey.filename"), EnumSet.of(Path.Type.file)); - if(proxy.find(vaultConfig, listener) || proxy.find(key, listener)) { + + final VaultMetadata metadata = provider.find(directory, proxy, listener); + if(metadata != null) { log.info("Found vault config {} or masterkey {}", vaultConfig, key); try { log.info("Found vault {}", directory); - return lookup.load(session, directory, - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.masterkey.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.config.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8)) + return lookup.load(session, metadata) .getFeature(session, Find.class, proxy) .find(file, listener); } diff --git a/core/src/main/java/ch/cyberduck/core/worker/CreateVaultWorker.java b/core/src/main/java/ch/cyberduck/core/worker/CreateVaultWorker.java index 85d274acccf..7dedd68669b 100644 --- a/core/src/main/java/ch/cyberduck/core/worker/CreateVaultWorker.java +++ b/core/src/main/java/ch/cyberduck/core/worker/CreateVaultWorker.java @@ -16,38 +16,38 @@ */ import ch.cyberduck.core.LocaleFactory; -import ch.cyberduck.core.PasswordStore; -import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Vault; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; +import ch.cyberduck.core.vault.VaultProviderFactory; import java.text.MessageFormat; import java.util.Objects; -public class CreateVaultWorker extends Worker { +public class CreateVaultWorker extends Worker { private final String region; private final VaultCredentials passphrase; - private final Vault vault; + private final VaultMetadata metadata; - public CreateVaultWorker(final String region, final VaultCredentials passphrase, final Vault vault) { + public CreateVaultWorker(final String region, final VaultCredentials passphrase, final VaultMetadata metadata) { this.region = region; this.passphrase = passphrase; - this.vault = vault; + this.metadata = metadata; } @Override - public Path run(final Session session) throws BackgroundException { - final Path home = vault.create(session, region, passphrase); + public Vault run(final Session session) throws BackgroundException { + final Vault vault = VaultProviderFactory.get(session).create(session, region, passphrase, metadata); vault.close(); - return home; + return vault; } @Override public String getActivity() { - return MessageFormat.format(LocaleFactory.localizedString("Making directory {0}", "Status"), vault.getHome().getName()); + return MessageFormat.format(LocaleFactory.localizedString("Making directory {0}", "Status"), metadata.root.getName()); } @Override @@ -59,18 +59,18 @@ public boolean equals(final Object o) { return false; } final CreateVaultWorker that = (CreateVaultWorker) o; - return Objects.equals(vault, that.vault); + return Objects.equals(metadata, that.metadata); } @Override public int hashCode() { - return Objects.hash(vault); + return Objects.hash(metadata); } @Override public String toString() { final StringBuilder sb = new StringBuilder("CreateVaultWorker{"); - sb.append("vault=").append(vault); + sb.append("metadata=").append(metadata); sb.append('}'); return sb.toString(); } diff --git a/core/src/main/java/ch/cyberduck/core/worker/LoadVaultWorker.java b/core/src/main/java/ch/cyberduck/core/worker/LoadVaultWorker.java index 334d3b2c189..1b56778c45e 100644 --- a/core/src/main/java/ch/cyberduck/core/worker/LoadVaultWorker.java +++ b/core/src/main/java/ch/cyberduck/core/worker/LoadVaultWorker.java @@ -16,32 +16,27 @@ */ import ch.cyberduck.core.LocaleFactory; -import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Vault; -import ch.cyberduck.core.preferences.HostPreferencesFactory; import ch.cyberduck.core.vault.VaultLookupListener; +import ch.cyberduck.core.vault.VaultMetadata; -import java.nio.charset.StandardCharsets; import java.util.Objects; public class LoadVaultWorker extends Worker { private final VaultLookupListener listener; - private final Path directory; + private final VaultMetadata metadata; - public LoadVaultWorker(final VaultLookupListener listener, final Path directory) { + public LoadVaultWorker(final VaultLookupListener listener, final VaultMetadata metadata) { this.listener = listener; - this.directory = directory; + this.metadata = metadata; } @Override public Vault run(final Session session) throws BackgroundException { - return listener.load(session, directory, - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.masterkey.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.config.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8)); + return listener.load(session, metadata); } @Override @@ -58,18 +53,18 @@ public boolean equals(final Object o) { return false; } final LoadVaultWorker that = (LoadVaultWorker) o; - return Objects.equals(directory, that.directory); + return Objects.equals(metadata, that.metadata); } @Override public int hashCode() { - return Objects.hash(directory); + return Objects.hash(metadata); } @Override public String toString() { final StringBuilder sb = new StringBuilder("LoadVaultWorker{"); - sb.append("directory=").append(directory); + sb.append("metadata=").append(metadata); sb.append('}'); return sb.toString(); } diff --git a/cryptomator/dll/pom.xml b/cryptomator/dll/pom.xml index da67b9b2759..c9e6351c51d 100644 --- a/cryptomator/dll/pom.xml +++ b/cryptomator/dll/pom.xml @@ -20,7 +20,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Cryptomator pom diff --git a/cryptomator/pom.xml b/cryptomator/pom.xml index 22b797aa85e..da6f89fc77b 100644 --- a/cryptomator/pom.xml +++ b/cryptomator/pom.xml @@ -19,13 +19,13 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT cryptomator jar - 2.1.2.1 + 2.3.0.uvfdraft-SNAPSHOT diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/AbstractVault.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/AbstractVault.java new file mode 100644 index 00000000000..03739370d5c --- /dev/null +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/AbstractVault.java @@ -0,0 +1,421 @@ +package ch.cyberduck.core.cryptomator; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.ListService; +import ch.cyberduck.core.Path; +import ch.cyberduck.core.PathAttributes; +import ch.cyberduck.core.Permission; +import ch.cyberduck.core.Session; +import ch.cyberduck.core.SimplePathPredicate; +import ch.cyberduck.core.UrlProvider; +import ch.cyberduck.core.cryptomator.features.*; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.features.*; +import ch.cyberduck.core.shared.DefaultTouchFeature; +import ch.cyberduck.core.transfer.TransferStatus; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.cryptomator.cryptolib.api.AuthenticationFailedException; +import org.cryptomator.cryptolib.api.Cryptor; +import org.cryptomator.cryptolib.api.DirectoryContentCryptor; +import org.cryptomator.cryptolib.api.DirectoryMetadata; +import org.cryptomator.cryptolib.api.FileContentCryptor; +import org.cryptomator.cryptolib.api.FileHeaderCryptor; +import org.cryptomator.cryptolib.api.Masterkey; + +import java.util.EnumSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class AbstractVault implements Vault { + + private static final Logger log = LogManager.getLogger(AbstractVault.class); + + public abstract Path getMasterkeyPath(); + + public abstract Masterkey getMasterkey(); + + public abstract Path getConfig(); + + public abstract FileHeaderCryptor getFileHeaderCryptor(); + + public abstract FileContentCryptor getFileContentCryptor(); + + public abstract CryptoFilename getFilenameProvider(); + + public abstract CryptoDirectory getDirectoryProvider(); + + public abstract Cryptor getCryptor(); + + public abstract int getNonceSize(); + + public abstract Pattern getFilenamePattern(); + + public int numberOfChunks(long cleartextFileSize) { + return (int) (cleartextFileSize / this.getFileContentCryptor().cleartextChunkSize() + + ((cleartextFileSize % this.getFileContentCryptor().cleartextChunkSize() > 0) ? 1 : 0)); + } + + public long toCleartextSize(final long cleartextFileOffset, final long ciphertextFileSize) throws CryptoInvalidFilesizeException { + if(TransferStatus.UNKNOWN_LENGTH == ciphertextFileSize) { + return TransferStatus.UNKNOWN_LENGTH; + } + final int headerSize; + if(0L == cleartextFileOffset) { + headerSize = this.getFileHeaderCryptor().headerSize(); + } + else { + headerSize = 0; + } + try { + return this.getFileContentCryptor().cleartextSize(ciphertextFileSize - headerSize); + } + catch(AssertionError e) { + throw new CryptoInvalidFilesizeException(String.format("Encrypted file size must be at least %d bytes", headerSize)); + } + catch(IllegalArgumentException e) { + throw new CryptoInvalidFilesizeException(String.format("Invalid file size. %s", e.getMessage())); + } + } + + @Override + public State getState() { + return this.isUnlocked() ? State.open : State.closed; + } + + @Override + public long toCiphertextSize(final long cleartextFileOffset, final long cleartextFileSize) { + if(TransferStatus.UNKNOWN_LENGTH == cleartextFileSize) { + return TransferStatus.UNKNOWN_LENGTH; + } + final int headerSize; + if(0L == cleartextFileOffset) { + headerSize = this.getCryptor().fileHeaderCryptor().headerSize(); + } + else { + headerSize = 0; + } + return headerSize + this.getCryptor().fileContentCryptor().ciphertextSize(cleartextFileSize); + } + + @Override + public Path encrypt(Session session, Path file) throws BackgroundException { + return this.encrypt(session, file, false); + } + + @Override + public Path encrypt(Session session, Path file, boolean metadata) throws BackgroundException { + final Path encrypted; + if(file.isFile() || metadata) { + if(file.getType().contains(Path.Type.vault)) { + log.warn("Skip file {} because it is marked as an internal vault path", file); + return file; + } + if(new SimplePathPredicate(file).test(this.getHome())) { + log.warn("Skip vault home {} because the root has no metadata file", file); + return file; + } + final Path parent; + final String filename; + if(file.getType().contains(Path.Type.encrypted)) { + final Path decrypted = file.attributes().getDecrypted(); + parent = this.getDirectoryProvider().toEncrypted(session, decrypted.getParent()); + filename = this.getDirectoryProvider().toEncrypted(session, decrypted.getParent(), decrypted.getName(), decrypted.getType()); + } + else { + parent = this.getDirectoryProvider().toEncrypted(session, file.getParent()); + filename = this.getDirectoryProvider().toEncrypted(session, file.getParent(), file.getName(), file.getType()); + } + final PathAttributes attributes = new PathAttributes(file.attributes()); + attributes.setDirectoryId(null); + if(!file.isFile() && !metadata) { + // The directory is different from the metadata file used to resolve the actual folder + attributes.setVersionId(null); + attributes.setFileId(null); + } + // Translate file size + attributes.setSize(this.toCiphertextSize(0L, file.attributes().getSize())); + final EnumSet type = EnumSet.copyOf(file.getType()); + type.remove(Path.Type.decrypted); + type.add(Path.Type.encrypted); + encrypted = new Path(parent, filename, type, attributes); + } + else { + if(file.getType().contains(Path.Type.encrypted)) { + log.warn("Skip file {} because it is already marked as an encrypted path", file); + return file; + } + if(file.getType().contains(Path.Type.vault)) { + return this.getDirectoryProvider().toEncrypted(session, this.getHome()); + } + encrypted = this.getDirectoryProvider().toEncrypted(session, file); + } + // Add reference to decrypted file + if(!file.getType().contains(Path.Type.encrypted)) { + encrypted.attributes().setDecrypted(file); + } + // Add reference for vault + file.attributes().setVaultMetadata(this.getMetadata()); + encrypted.attributes().setVaultMetadata(this.getMetadata()); + return encrypted; + } + + @Override + public Path decrypt(final Session session, final Path file) throws BackgroundException { + if(file.getType().contains(Path.Type.decrypted)) { + log.warn("Skip file {} because it is already marked as a decrypted path", file); + return file; + } + if(file.getType().contains(Path.Type.vault)) { + log.warn("Skip file {} because it is marked as an internal vault path", file); + return file; + } + final Path inflated = this.inflate(session, file); + final Pattern pattern = this.getFilenamePattern(); + final Matcher m = pattern.matcher(inflated.getName()); + if(m.matches()) { + try { + //TODO lädt das recovery metadaten file anstatt normales + final DirectoryContentCryptor.Decrypting decrypting = this.getFilenameDecryptor(session, file); + //TODO hier hatten wir caching via CryptorCache + final String cleartextFilename = decrypting.decrypt(inflated.getName()); + final PathAttributes attributes = new PathAttributes(file.attributes()); + if(this.isDirectory(inflated)) { + if(Permission.EMPTY != attributes.getPermission()) { + final Permission permission = new Permission(attributes.getPermission()); + permission.setUser(permission.getUser().or(Permission.Action.execute)); + permission.setGroup(permission.getGroup().or(Permission.Action.execute)); + permission.setOther(permission.getOther().or(Permission.Action.execute)); + attributes.setPermission(permission); + } + // Reset size for folders + attributes.setSize(-1L); + attributes.setVersionId(null); + attributes.setFileId(null); + } + else { + // Translate file size + attributes.setSize(this.toCleartextSize(0L, file.attributes().getSize())); + } + // Add reference to encrypted file + attributes.setEncrypted(file); + // Add reference for vault + attributes.setVaultMetadata(this.getMetadata()); + final EnumSet type = EnumSet.copyOf(file.getType()); + type.remove(this.isDirectory(inflated) ? Path.Type.file : Path.Type.directory); + type.add(this.isDirectory(inflated) ? Path.Type.directory : Path.Type.file); + type.remove(Path.Type.encrypted); + type.add(Path.Type.decrypted); + final Path decrypted = new Path(file.getParent().attributes().getDecrypted(), cleartextFilename, type, attributes); + if(type.contains(Path.Type.symboliclink)) { + decrypted.setSymlinkTarget(file.getSymlinkTarget()); + } + return decrypted; + } + catch(AuthenticationFailedException e) { + throw new CryptoAuthenticationException( + "Failure to decrypt due to an unauthentic ciphertext", e); + } + } + else { + throw new CryptoFilenameMismatchException( + String.format("Failure to decrypt %s due to missing pattern match for %s", inflated.getName(), pattern)); + } + } + + private DirectoryContentCryptor.Decrypting getFilenameDecryptor(final Session session, final Path directory) throws BackgroundException { + // Read directory id from file + log.debug("Read directory ID from {}", directory); + final DirectoryMetadata metadata = this.getDirectoryProvider().getOrCreateDirectoryId(session, directory.getParent()); + return this.getCryptor().directoryContentCryptor().fileNameDecryptor(metadata); + } + + private boolean isDirectory(final Path p) { + return p.isDirectory(); + } + + private Path inflate(final Session session, final Path file) throws BackgroundException { + final String fileName = file.getName(); + if(this.getFilenameProvider().isDeflated(fileName)) { + final String filename = this.getFilenameProvider().inflate(session, fileName); + return new Path(file.getParent(), filename, EnumSet.of(Path.Type.file), file.attributes()); + } + return file; + } + + public synchronized boolean isUnlocked() { + return this.getCryptor() != null; + } + + @Override + public boolean contains(final Path file) { + if(this.isUnlocked()) { + return new SimplePathPredicate(file).test(this.getHome()) || file.isChild(this.getHome()); + } + return false; + } + + public abstract String getRegularFileExtension(); + + public abstract String getDirectoryMetadataFilename(); + + public abstract String getBackupDirectoryMetadataFilename(); + + public abstract DirectoryMetadata getRootDirId(); + + @Override + public synchronized void close() { + if(this.isUnlocked()) { + if(this.getCryptor() != null) { + getCryptor().destroy(); + } + if(this.getDirectoryProvider() != null) { + this.getDirectoryProvider().destroy(); + } + if(this.getFilenameProvider() != null) { + this.getFilenameProvider().destroy(); + } + } + } + + @Override + @SuppressWarnings("unchecked") + public T getFeature(final Session session, final Class type, final T delegate) { + if(this.isUnlocked()) { + if(type == ListService.class) { + return (T) new CryptoListService(session, (ListService) delegate, this); + } + if(type == Touch.class) { + // Use default touch feature because touch with remote implementation will not add encrypted file header + return (T) new CryptoTouchFeature(session, new DefaultTouchFeature(session), this); + } + if(type == Directory.class) { + //TODO + return (T) new CryptoDirectoryV7Feature(session, (Directory) delegate, this); +// return (T) (this.getVersion() == VAULT_VERSION_DEPRECATED ? +// new CryptoDirectoryV6Feature(session, (Directory) delegate, session._getFeature(Write.class), this) : +// new CryptoDirectoryV7Feature(session, (Directory) delegate, session._getFeature(Write.class), this) +// ); + } + if(type == Upload.class) { + return (T) new CryptoUploadFeature(session, (Upload) delegate, this); + } + if(type == Download.class) { + return (T) new CryptoDownloadFeature(session, (Download) delegate, session._getFeature(Read.class), this); + } + if(type == Read.class) { + return (T) new CryptoReadFeature(session, (Read) delegate, this); + } + if(type == Write.class) { + return (T) new CryptoWriteFeature(session, (Write) delegate, this); + } + if(type == MultipartWrite.class) { + return (T) new CryptoMultipartWriteFeature(session, (Write) delegate, this); + } + if(type == Move.class) { + //TODO + return (T) new CryptoMoveV7Feature(session, (Move) delegate, this); +// return (T) (this.getVersion() == VAULT_VERSION_DEPRECATED ? +// new CryptoMoveV6Feature(session, (Move) delegate, this) : +// new CryptoMoveV7Feature(session, (Move) delegate, this)); + + } + if(type == AttributesFinder.class) { + return (T) new CryptoAttributesFeature(session, (AttributesFinder) delegate, this); + } + if(type == Find.class) { + return (T) new CryptoFindFeature(session, (Find) delegate, this); + } + if(type == UrlProvider.class) { + return (T) new CryptoUrlProvider(session, (UrlProvider) delegate, this); + } + if(type == FileIdProvider.class) { + return (T) new CryptoFileIdProvider(session, (FileIdProvider) delegate, this); + } + if(type == VersionIdProvider.class) { + return (T) new CryptoVersionIdProvider(session, (VersionIdProvider) delegate, this); + } + if(type == Delete.class) { + return (T) new CryptoDeleteV7Feature(session, (Delete) delegate, this); + //TODO +// return (T) (this.getVersion() == VAULT_VERSION_DEPRECATED ? +// new CryptoDeleteV6Feature(session, (Delete) delegate, this) : +// new CryptoDeleteV7Feature(session, (Delete) delegate, this)); + } + if(type == Trash.class) { + //TODO + return (T) new CryptoDeleteV7Feature(session, (Delete) delegate, this); +// return (T) (this.getVersion() == VAULT_VERSION_DEPRECATED ? +// new CryptoDeleteV6Feature(session, (Delete) delegate, this) : +// new CryptoDeleteV7Feature(session, (Delete) delegate, this)); + } + if(type == Symlink.class) { + return (T) new CryptoSymlinkFeature(session, (Symlink) delegate, this); + } + if(type == Headers.class) { + return (T) new CryptoHeadersFeature(session, (Headers) delegate, this); + } + if(type == Compress.class) { + return (T) new CryptoCompressFeature(session, (Compress) delegate, this); + } + if(type == Bulk.class) { + return (T) new CryptoBulkFeature(session, (Bulk) delegate, this); + } + if(type == UnixPermission.class) { + return (T) new CryptoUnixPermission(session, (UnixPermission) delegate, this); + } + if(type == AclPermission.class) { + return (T) new CryptoAclPermission(session, (AclPermission) delegate, this); + } + if(type == Copy.class) { + return (T) new CryptoCopyFeature(session, (Copy) delegate, this); + } + if(type == Timestamp.class) { + return (T) new CryptoTimestampFeature(session, (Timestamp) delegate, this); + } + if(type == Encryption.class) { + return (T) new CryptoEncryptionFeature(session, (Encryption) delegate, this); + } + if(type == Lifecycle.class) { + return (T) new CryptoLifecycleFeature(session, (Lifecycle) delegate, this); + } + if(type == Location.class) { + return (T) new CryptoLocationFeature(session, (Location) delegate, this); + } + if(type == Lock.class) { + return (T) new CryptoLockFeature(session, (Lock) delegate, this); + } + if(type == Logging.class) { + return (T) new CryptoLoggingFeature(session, (Logging) delegate, this); + } + if(type == Redundancy.class) { + return (T) new CryptoRedundancyFeature(session, (Redundancy) delegate, this); + } + if(type == Search.class) { + return (T) new CryptoSearchFeature(session, (Search) delegate, this); + } + if(type == TransferAcceleration.class) { + return (T) new CryptoTransferAccelerationFeature<>(session, (TransferAcceleration) delegate, this); + } + if(type == Versioning.class) { + return (T) new CryptoVersioningFeature(session, (Versioning) delegate, this); + } + } + return delegate; + } +} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/ContentReader.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/ContentReader.java index 21282729888..452af7e12b5 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/ContentReader.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/ContentReader.java @@ -21,10 +21,12 @@ import ch.cyberduck.core.Session; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Read; +import ch.cyberduck.core.io.StreamCopier; import ch.cyberduck.core.transfer.TransferStatus; import org.apache.commons.io.IOUtils; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -49,6 +51,19 @@ public String read(final Path file) throws BackgroundException { } } + public byte[] readBytes(final Path file) throws BackgroundException { + final Read read = session._getFeature(Read.class); + final TransferStatus status = new TransferStatus().setLength(file.attributes().getSize()); + try (final InputStream in = read.read(file, status, new DisabledConnectionCallback())) { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + new StreamCopier(status, status).transfer(in, out); + return out.toByteArray(); + } + catch(IOException e) { + throw new DefaultIOExceptionMappingService().map(e); + } + } + public Reader getReader(final Path file) throws BackgroundException { final Read read = session._getFeature(Read.class); return new InputStreamReader(read.read(file, new TransferStatus().setLength(file.attributes().getSize()), new DisabledConnectionCallback()), StandardCharsets.UTF_8); diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoAclPermission.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoAclPermission.java index 4b31674db9b..7bcac44e2f3 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoAclPermission.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoAclPermission.java @@ -22,16 +22,15 @@ import ch.cyberduck.core.features.AclPermission; import ch.cyberduck.core.transfer.TransferStatus; -import java.util.EnumSet; import java.util.List; public class CryptoAclPermission implements AclPermission { private final Session session; private final AclPermission delegate; - private final CryptoVault cryptomator; + private final AbstractVault cryptomator; - public CryptoAclPermission(final Session session, final AclPermission delegate, final CryptoVault cryptomator) { + public CryptoAclPermission(final Session session, final AclPermission delegate, final AbstractVault cryptomator) { this.session = session; this.delegate = delegate; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoDirectory.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoDirectory.java index 88ccb32e736..b61023a58d5 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoDirectory.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoDirectory.java @@ -19,6 +19,8 @@ import ch.cyberduck.core.Session; import ch.cyberduck.core.exception.BackgroundException; +import org.cryptomator.cryptolib.api.DirectoryMetadata; + import java.util.EnumSet; public interface CryptoDirectory { @@ -27,21 +29,20 @@ public interface CryptoDirectory { * Get encrypted filename for given clear text filename with id of parent encrypted directory. * * @param session Connection - * @param directoryId Parent folder directory id + * @param parent Parent folder * @param filename Clear text filename * @param type File type * @return Encrypted filename */ - String toEncrypted(Session session, String directoryId, String filename, EnumSet type) throws BackgroundException; + String toEncrypted(Session session, Path parent, String filename, EnumSet type) throws BackgroundException; /** * Get encrypted reference for clear text directory path. * - * @param session Connection - * @param directoryId Directory ID or null to read directory id from metadata file - * @param directory Clear text + * @param session Connection + * @param directory Clear text */ - Path toEncrypted(Session session, String directoryId, Path directory) throws BackgroundException; + Path toEncrypted(Session session, Path directory) throws BackgroundException; /** * Remove from cache @@ -49,4 +50,8 @@ public interface CryptoDirectory { void delete(Path directory); void destroy(); + + DirectoryMetadata getOrCreateDirectoryId(Session session, Path directory) throws BackgroundException; + + DirectoryMetadata createDirectoryId(final Path directory); } diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoTransferStatus.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoTransferStatus.java index bcb52f32f5f..8cc455558bc 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoTransferStatus.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoTransferStatus.java @@ -27,9 +27,9 @@ public class CryptoTransferStatus extends ProxyTransferStatus implements StreamCancelation, StreamProgress { private static final Logger log = LogManager.getLogger(CryptoTransferStatus.class); - private final CryptoVault vault; + private final AbstractVault vault; - public CryptoTransferStatus(final CryptoVault vault, final TransferStatus proxy) { + public CryptoTransferStatus(final AbstractVault vault, final TransferStatus proxy) { super(proxy); this.vault = vault; this.setLength(vault.toCiphertextSize(proxy.getOffset(), proxy.getLength())) @@ -42,7 +42,7 @@ public CryptoTransferStatus(final CryptoVault vault, final TransferStatus proxy) public TransferStatus setResponse(final PathAttributes attributes) { try { attributes.setSize(vault.toCleartextSize(0L, attributes.getSize())); - attributes.setVault(vault.getHome()); + attributes.setVaultMetadata(vault.getMetadata()); super.setResponse(attributes); } catch(CryptoInvalidFilesizeException e) { diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoVault.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoVault.java deleted file mode 100644 index 431da0f2ee4..00000000000 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoVault.java +++ /dev/null @@ -1,853 +0,0 @@ -package ch.cyberduck.core.cryptomator; - -/* - * Copyright (c) 2002-2016 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.*; -import ch.cyberduck.core.cryptomator.features.*; -import ch.cyberduck.core.cryptomator.impl.CryptoDirectoryV6Provider; -import ch.cyberduck.core.cryptomator.impl.CryptoDirectoryV7Provider; -import ch.cyberduck.core.cryptomator.impl.CryptoFilenameV6Provider; -import ch.cyberduck.core.cryptomator.impl.CryptoFilenameV7Provider; -import ch.cyberduck.core.cryptomator.random.FastSecureRandomProvider; -import ch.cyberduck.core.exception.BackgroundException; -import ch.cyberduck.core.exception.LocalAccessDeniedException; -import ch.cyberduck.core.exception.LoginCanceledException; -import ch.cyberduck.core.exception.NotfoundException; -import ch.cyberduck.core.features.*; -import ch.cyberduck.core.preferences.Preferences; -import ch.cyberduck.core.preferences.PreferencesFactory; -import ch.cyberduck.core.shared.DefaultTouchFeature; -import ch.cyberduck.core.shared.DefaultUrlProvider; -import ch.cyberduck.core.transfer.TransferStatus; -import ch.cyberduck.core.vault.DefaultVaultRegistry; -import ch.cyberduck.core.vault.VaultCredentials; -import ch.cyberduck.core.vault.VaultException; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.cryptomator.cryptolib.api.AuthenticationFailedException; -import org.cryptomator.cryptolib.api.Cryptor; -import org.cryptomator.cryptolib.api.CryptorProvider; -import org.cryptomator.cryptolib.api.FileContentCryptor; -import org.cryptomator.cryptolib.api.FileHeaderCryptor; -import org.cryptomator.cryptolib.api.InvalidPassphraseException; -import org.cryptomator.cryptolib.api.Masterkey; -import org.cryptomator.cryptolib.common.MasterkeyFile; -import org.cryptomator.cryptolib.common.MasterkeyFileAccess; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.text.MessageFormat; -import java.util.EnumSet; -import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.auth0.jwt.JWT; -import com.auth0.jwt.JWTVerifier; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.InvalidClaimException; -import com.auth0.jwt.exceptions.JWTVerificationException; -import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.google.common.io.BaseEncoding; -import com.google.gson.JsonParseException; - -import static ch.cyberduck.core.vault.DefaultVaultRegistry.DEFAULT_VAULTCONFIG_FILE_NAME; - -/** - * Cryptomator vault implementation - */ -public class CryptoVault implements Vault { - private static final Logger log = LogManager.getLogger(CryptoVault.class); - - public static final int VAULT_VERSION_DEPRECATED = 6; - public static final int VAULT_VERSION = PreferencesFactory.get().getInteger("cryptomator.vault.version"); - public static final byte[] VAULT_PEPPER = PreferencesFactory.get().getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8); - - public static final String DIR_PREFIX = "0"; - - private static final Pattern BASE32_PATTERN = Pattern.compile("^0?(([A-Z2-7]{8})*[A-Z2-7=]{8})"); - private static final Pattern BASE64URL_PATTERN = Pattern.compile("^([A-Za-z0-9_=-]+).c9r"); - - private static final String JSON_KEY_VAULTVERSION = "format"; - private static final String JSON_KEY_CIPHERCONFIG = "cipherCombo"; - private static final String JSON_KEY_SHORTENING_THRESHOLD = "shorteningThreshold"; - - /** - * Root of vault directory - */ - private final Path home; - private final Path masterkey; - - private final Path config; - private final Path vault; - private int vaultVersion; - private int nonceSize; - - private final PasswordStore keychain = PasswordStoreFactory.get(); - private final Preferences preferences = PreferencesFactory.get(); - private Cryptor cryptor; - private CryptorCache fileNameCryptor; - - private CryptoFilename filenameProvider; - private CryptoDirectory directoryProvider; - - private final byte[] pepper; - - public CryptoVault(final Path home) { - this(home, DefaultVaultRegistry.DEFAULT_MASTERKEY_FILE_NAME, DEFAULT_VAULTCONFIG_FILE_NAME, VAULT_PEPPER); - } - - public CryptoVault(final Path home, final String masterkey, final String config, final byte[] pepper) { - this.home = home; - this.masterkey = new Path(home, masterkey, EnumSet.of(Path.Type.file, Path.Type.vault)); - this.config = new Path(home, config, EnumSet.of(Path.Type.file, Path.Type.vault)); - this.pepper = pepper; - // New vault home with vault flag set for internal use - final EnumSet type = EnumSet.copyOf(home.getType()); - type.add(Path.Type.vault); - if(home.isRoot()) { - this.vault = new Path(home.getAbsolute(), type, new PathAttributes(home.attributes())); - } - else { - this.vault = new Path(home.getParent(), home.getName(), type, new PathAttributes(home.attributes())); - } - } - - public synchronized Path create(final Session session, final VaultCredentials credentials, final int version) throws BackgroundException { - return this.create(session, null, credentials, version); - } - - public synchronized Path create(final Session session, final String region, final VaultCredentials credentials, final int version) throws BackgroundException { - final Host bookmark = session.getHost(); - if(credentials.isSaved()) { - try { - keychain.addPassword(String.format("Cryptomator Passphrase (%s)", bookmark.getCredentials().getUsername()), - new DefaultUrlProvider(bookmark).toUrl(masterkey, EnumSet.of(DescriptiveUrl.Type.provider)).find(DescriptiveUrl.Type.provider).getUrl(), credentials.getPassword()); - } - catch(LocalAccessDeniedException e) { - log.error("Failure {} saving credentials for {} in password store", e, bookmark); - } - } - final String passphrase = credentials.getPassword(); - final ByteArrayOutputStream mkArray = new ByteArrayOutputStream(); - final Masterkey mk = Masterkey.generate(FastSecureRandomProvider.get().provide()); - final MasterkeyFileAccess access = new MasterkeyFileAccess(pepper, FastSecureRandomProvider.get().provide()); - final MasterkeyFile masterkeyFile; - try { - access.persist(mk, mkArray, passphrase, version); - masterkeyFile = MasterkeyFile.read(new StringReader(new String(mkArray.toByteArray(), StandardCharsets.UTF_8))); - } - catch(IOException e) { - throw new VaultException("Failure creating master key", e); - } - log.debug("Write master key to {}", masterkey); - // Obtain non encrypted directory writer - final Directory directory = session._getFeature(Directory.class); - final TransferStatus status = new TransferStatus().setRegion(region); - final Encryption encryption = session._getFeature(Encryption.class); - if(encryption != null) { - status.setEncryption(encryption.getDefault(home)); - } - final Path vault = directory.mkdir(session._getFeature(Write.class), home, status); - new ContentWriter(session).write(masterkey, mkArray.toByteArray()); - if(VAULT_VERSION == version) { - // Create vaultconfig.cryptomator - final Algorithm algorithm = Algorithm.HMAC256(mk.getEncoded()); - final String conf = JWT.create() - .withJWTId(new UUIDRandomStringService().random()) - .withKeyId(String.format("masterkeyfile:%s", masterkey.getName())) - .withClaim(JSON_KEY_VAULTVERSION, version) - .withClaim(JSON_KEY_CIPHERCONFIG, CryptorProvider.Scheme.SIV_GCM.toString()) - .withClaim(JSON_KEY_SHORTENING_THRESHOLD, CryptoFilenameV7Provider.DEFAULT_NAME_SHORTENING_THRESHOLD) - .sign(algorithm); - new ContentWriter(session).write(config, conf.getBytes(StandardCharsets.US_ASCII)); - this.open(parseVaultConfigFromJWT(conf).withMasterkeyFile(masterkeyFile), passphrase); - } - else { - this.open(new VaultConfig(version, CryptoFilenameV6Provider.DEFAULT_NAME_SHORTENING_THRESHOLD, - CryptorProvider.Scheme.SIV_CTRMAC, null, null).withMasterkeyFile(masterkeyFile), passphrase); - } - final Path secondLevel = directoryProvider.toEncrypted(session, home.attributes().getDirectoryId(), home); - final Path firstLevel = secondLevel.getParent(); - final Path dataDir = firstLevel.getParent(); - log.debug("Create vault root directory at {}", secondLevel); - directory.mkdir(session._getFeature(Write.class), dataDir, status); - directory.mkdir(session._getFeature(Write.class), firstLevel, status); - directory.mkdir(session._getFeature(Write.class), secondLevel, status); - return vault; - } - - @Override - public synchronized Path create(final Session session, final String region, final VaultCredentials credentials) throws BackgroundException { - return this.create(session, region, credentials, VAULT_VERSION); - } - - @Override - public synchronized CryptoVault load(final Session session, final PasswordCallback prompt) throws BackgroundException { - if(this.isUnlocked()) { - log.warn("Skip unlock of open vault {}", this); - return this; - } - final Host bookmark = session.getHost(); - String passphrase = keychain.getPassword(String.format("Cryptomator Passphrase (%s)", bookmark.getCredentials().getUsername()), - new DefaultUrlProvider(bookmark).toUrl(masterkey, EnumSet.of(DescriptiveUrl.Type.provider)).find(DescriptiveUrl.Type.provider).getUrl()); - if(null == passphrase) { - // Legacy - passphrase = keychain.getPassword(String.format("Cryptomator Passphrase %s", bookmark.getHostname()), - new DefaultUrlProvider(bookmark).toUrl(masterkey, EnumSet.of(DescriptiveUrl.Type.provider)).find(DescriptiveUrl.Type.provider).getUrl()); - } - return this.unlock(session, prompt, bookmark, passphrase); - } - - private VaultConfig readVaultConfig(final Session session) throws BackgroundException { - final MasterkeyFile masterkeyFile = this.readMasterkeyFile(session, masterkey); - try { - return parseVaultConfigFromJWT(new ContentReader(session).read(config)) - .withMasterkeyFile(masterkeyFile); - } - catch(NotfoundException e) { - log.debug("Ignore failure reading vault configuration {}", config); - return parseVaultConfigFromMasterKey(masterkeyFile) - .withMasterkeyFile(masterkeyFile); - } - } - - private static VaultConfig parseVaultConfigFromMasterKey(final MasterkeyFile masterkeyFile) { - return new VaultConfig(masterkeyFile.version, - masterkeyFile.version == VAULT_VERSION_DEPRECATED ? - CryptoFilenameV6Provider.DEFAULT_NAME_SHORTENING_THRESHOLD : - CryptoFilenameV7Provider.DEFAULT_NAME_SHORTENING_THRESHOLD, - CryptorProvider.Scheme.SIV_CTRMAC, null, null); - } - - - private static VaultConfig parseVaultConfigFromJWT(final String token) { - final DecodedJWT decoded = JWT.decode(token); - return new VaultConfig( - decoded.getClaim(JSON_KEY_VAULTVERSION).asInt(), - decoded.getClaim(JSON_KEY_SHORTENING_THRESHOLD).asInt(), - CryptorProvider.Scheme.valueOf(decoded.getClaim(JSON_KEY_CIPHERCONFIG).asString()), - decoded.getAlgorithm(), decoded); - } - - private MasterkeyFile readMasterkeyFile(final Session session, final Path file) throws BackgroundException { - log.debug("Read master key {}", file); - try(Reader reader = new ContentReader(session).getReader(file)) { - return MasterkeyFile.read(reader); - } - catch(JsonParseException | IllegalArgumentException | IllegalStateException | IOException e) { - throw new VaultException(String.format("Failure reading vault master key file %s", file.getName()), e); - } - } - - public CryptoVault unlock(final Session session, final PasswordCallback prompt, final Host bookmark, final String passphrase) throws BackgroundException { - final VaultConfig vaultConfig = this.readVaultConfig(session); - this.unlock(vaultConfig, passphrase, bookmark, prompt, - MessageFormat.format(LocaleFactory.localizedString("Provide your passphrase to unlock the Cryptomator Vault {0}", "Cryptomator"), home.getName()) - ); - return this; - } - - public void unlock(final VaultConfig vaultConfig, final String passphrase, final Host bookmark, final PasswordCallback prompt, - final String message) throws BackgroundException { - final Credentials credentials; - if(null == passphrase) { - credentials = prompt.prompt( - bookmark, LocaleFactory.localizedString("Unlock Vault", "Cryptomator"), - message, - new LoginOptions() - .save(preferences.getBoolean("cryptomator.vault.keychain")) - .user(false) - .anonymous(false) - .icon("cryptomator.tiff") - .passwordPlaceholder(LocaleFactory.localizedString("Passphrase", "Cryptomator"))); - if(null == credentials.getPassword()) { - throw new LoginCanceledException(); - } - } - else { - credentials = new VaultCredentials(passphrase).withSaved(false); - } - try { - this.open(vaultConfig, credentials.getPassword()); - if(credentials.isSaved()) { - log.info("Save passphrase for {}", masterkey); - // Save password with hostname and path to masterkey.cryptomator in keychain - keychain.addPassword(String.format("Cryptomator Passphrase (%s)", bookmark.getCredentials().getUsername()), - new DefaultUrlProvider(bookmark).toUrl(masterkey, EnumSet.of(DescriptiveUrl.Type.provider)).find(DescriptiveUrl.Type.provider).getUrl(), credentials.getPassword()); - } - } - catch(CryptoAuthenticationException e) { - this.unlock(vaultConfig, null, bookmark, prompt, String.format("%s %s.", e.getDetail(), - MessageFormat.format(LocaleFactory.localizedString("Provide your passphrase to unlock the Cryptomator Vault {0}", "Cryptomator"), home.getName()))); - } - } - - @Override - public synchronized void close() { - if(this.isUnlocked()) { - log.info("Close vault with cryptor {}", cryptor); - if(cryptor != null) { - cryptor.destroy(); - } - if(directoryProvider != null) { - directoryProvider.destroy(); - } - if(filenameProvider != null) { - filenameProvider.destroy(); - } - } - cryptor = null; - fileNameCryptor = null; - } - - protected CryptoFilename createFilenameProvider(final VaultConfig vaultConfig) { - switch(vaultConfig.version) { - case VAULT_VERSION_DEPRECATED: - return new CryptoFilenameV6Provider(vault); - default: - return new CryptoFilenameV7Provider(vaultConfig.getShorteningThreshold()); - } - } - - protected CryptoDirectory createDirectoryProvider(final VaultConfig vaultConfig) { - switch(vaultConfig.version) { - case VAULT_VERSION_DEPRECATED: - return new CryptoDirectoryV6Provider(vault, this); - default: - return new CryptoDirectoryV7Provider(vault, this); - } - } - - protected void open(final VaultConfig vaultConfig, final CharSequence passphrase) throws BackgroundException { - this.open(vaultConfig, passphrase, this.createFilenameProvider(vaultConfig), this.createDirectoryProvider(vaultConfig)); - } - - protected void open(final VaultConfig vaultConfig, final CharSequence passphrase, - final CryptoFilename filenameProvider, final CryptoDirectory directoryProvider) throws BackgroundException { - try { - final Masterkey masterKey = this.getMasterKey(vaultConfig.getMkfile(), passphrase); - this.open(vaultConfig, masterKey, filenameProvider, directoryProvider); - } - catch(IllegalArgumentException | IOException e) { - throw new VaultException("Failure reading key file", e); - } - catch(InvalidPassphraseException e) { - throw new CryptoAuthenticationException("Failure to decrypt master key file", e); - } - } - - protected void open(final VaultConfig vaultConfig, final Masterkey masterKey) throws BackgroundException { - this.open(vaultConfig, masterKey, this.createFilenameProvider(vaultConfig), this.createDirectoryProvider(vaultConfig)); - } - - protected void open(final VaultConfig vaultConfig, final Masterkey masterKey, - final CryptoFilename filenameProvider, final CryptoDirectory directoryProvider) throws BackgroundException { - this.vaultVersion = vaultConfig.version; - final CryptorProvider provider = CryptorProvider.forScheme(vaultConfig.getCipherCombo()); - log.debug("Initialized crypto provider {}", provider); - vaultConfig.verify(masterKey.getEncoded(), VAULT_VERSION); - this.cryptor = provider.provide(masterKey, FastSecureRandomProvider.get().provide()); - this.fileNameCryptor = new CryptorCache(cryptor.fileNameCryptor()); - this.filenameProvider = filenameProvider; - this.directoryProvider = directoryProvider; - this.nonceSize = vaultConfig.getNonceSize(); - } - - private Masterkey getMasterKey(final MasterkeyFile mkFile, final CharSequence passphrase) throws IOException { - final StringWriter writer = new StringWriter(); - mkFile.write(writer); - return new MasterkeyFileAccess(pepper, FastSecureRandomProvider.get().provide()).load( - new ByteArrayInputStream(writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8)), passphrase); - } - - public synchronized boolean isUnlocked() { - return cryptor != null; - } - - @Override - public State getState() { - return this.isUnlocked() ? State.open : State.closed; - } - - @Override - public boolean contains(final Path file) { - return new SimplePathPredicate(file).test(home) || file.isChild(home); - } - - @Override - public Path encrypt(final Session session, final Path file) throws BackgroundException { - return this.encrypt(session, file, file.attributes().getDirectoryId(), false); - } - - @Override - public Path encrypt(final Session session, final Path file, boolean metadata) throws BackgroundException { - return this.encrypt(session, file, file.attributes().getDirectoryId(), metadata); - } - - public Path encrypt(final Session session, final Path file, final String directoryId, boolean metadata) throws BackgroundException { - final Path encrypted; - if(file.isFile() || metadata) { - if(file.getType().contains(Path.Type.vault)) { - log.warn("Skip file {} because it is marked as an internal vault path", file); - return file; - } - if(new SimplePathPredicate(file).test(home)) { - log.warn("Skip vault home {} because the root has no metadata file", file); - return file; - } - final Path parent; - final String filename; - if(file.getType().contains(Path.Type.encrypted)) { - final Path decrypted = file.attributes().getDecrypted(); - parent = directoryProvider.toEncrypted(session, decrypted.getParent().attributes().getDirectoryId(), decrypted.getParent()); - filename = directoryProvider.toEncrypted(session, parent.attributes().getDirectoryId(), decrypted.getName(), decrypted.getType()); - } - else { - parent = directoryProvider.toEncrypted(session, file.getParent().attributes().getDirectoryId(), file.getParent()); - filename = directoryProvider.toEncrypted(session, parent.attributes().getDirectoryId(), file.getName(), file.getType()); - } - final PathAttributes attributes = new PathAttributes(file.attributes()); - attributes.setDirectoryId(null); - if(!file.isFile() && !metadata) { - // The directory is different from the metadata file used to resolve the actual folder - attributes.setVersionId(null); - attributes.setFileId(null); - } - // Translate file size - attributes.setSize(this.toCiphertextSize(0L, file.attributes().getSize())); - final EnumSet type = EnumSet.copyOf(file.getType()); - if(metadata && vaultVersion == VAULT_VERSION_DEPRECATED) { - type.remove(Path.Type.directory); - type.add(Path.Type.file); - } - type.remove(Path.Type.decrypted); - type.add(Path.Type.encrypted); - encrypted = new Path(parent, filename, type, attributes); - } - else { - if(file.getType().contains(Path.Type.encrypted)) { - log.warn("Skip file {} because it is already marked as an encrypted path", file); - return file; - } - if(file.getType().contains(Path.Type.vault)) { - return directoryProvider.toEncrypted(session, home.attributes().getDirectoryId(), home); - } - encrypted = directoryProvider.toEncrypted(session, directoryId, file); - } - // Add reference to decrypted file - if(!file.getType().contains(Path.Type.encrypted)) { - encrypted.attributes().setDecrypted(file); - } - // Add reference for vault - file.attributes().setVault(home); - encrypted.attributes().setVault(home); - return encrypted; - } - - @Override - public Path decrypt(final Session session, final Path file) throws BackgroundException { - if(file.getType().contains(Path.Type.decrypted)) { - log.warn("Skip file {} because it is already marked as an decrypted path", file); - return file; - } - if(file.getType().contains(Path.Type.vault)) { - log.warn("Skip file {} because it is marked as an internal vault path", file); - return file; - } - final Path inflated = this.inflate(session, file); - final Pattern pattern = vaultVersion == VAULT_VERSION_DEPRECATED ? BASE32_PATTERN : BASE64URL_PATTERN; - final Matcher m = pattern.matcher(inflated.getName()); - if(m.matches()) { - final String ciphertext = m.group(1); - try { - final String cleartextFilename = fileNameCryptor.decryptFilename( - vaultVersion == VAULT_VERSION_DEPRECATED ? BaseEncoding.base32() : BaseEncoding.base64Url(), - ciphertext, file.getParent().attributes().getDirectoryId().getBytes(StandardCharsets.UTF_8)); - final PathAttributes attributes = new PathAttributes(file.attributes()); - if(this.isDirectory(inflated)) { - if(Permission.EMPTY != attributes.getPermission()) { - final Permission permission = new Permission(attributes.getPermission()); - permission.setUser(permission.getUser().or(Permission.Action.execute)); - permission.setGroup(permission.getGroup().or(Permission.Action.execute)); - permission.setOther(permission.getOther().or(Permission.Action.execute)); - attributes.setPermission(permission); - } - // Reset size for folders - attributes.setSize(-1L); - attributes.setVersionId(null); - attributes.setFileId(null); - } - else { - // Translate file size - attributes.setSize(this.toCleartextSize(0L, file.attributes().getSize())); - } - // Add reference to encrypted file - attributes.setEncrypted(file); - // Add reference for vault - attributes.setVault(home); - final EnumSet type = EnumSet.copyOf(file.getType()); - type.remove(this.isDirectory(inflated) ? Path.Type.file : Path.Type.directory); - type.add(this.isDirectory(inflated) ? Path.Type.directory : Path.Type.file); - type.remove(Path.Type.encrypted); - type.add(Path.Type.decrypted); - final Path decrypted = new Path(file.getParent().attributes().getDecrypted(), cleartextFilename, type, attributes); - if(type.contains(Path.Type.symboliclink)) { - decrypted.setSymlinkTarget(file.getSymlinkTarget()); - } - return decrypted; - } - catch(AuthenticationFailedException e) { - throw new CryptoAuthenticationException( - "Failure to decrypt due to an unauthentic ciphertext", e); - } - } - else { - throw new CryptoFilenameMismatchException( - String.format("Failure to decrypt %s due to missing pattern match for %s", inflated.getName(), pattern)); - } - } - - private boolean isDirectory(final Path p) { - if(vaultVersion == VAULT_VERSION_DEPRECATED) { - return p.getName().startsWith(DIR_PREFIX); - } - return p.isDirectory(); - } - - @Override - public long toCiphertextSize(final long cleartextFileOffset, final long cleartextFileSize) { - if(TransferStatus.UNKNOWN_LENGTH == cleartextFileSize) { - return TransferStatus.UNKNOWN_LENGTH; - } - final int headerSize; - if(0L == cleartextFileOffset) { - headerSize = cryptor.fileHeaderCryptor().headerSize(); - } - else { - headerSize = 0; - } - return headerSize + cryptor.fileContentCryptor().ciphertextSize(cleartextFileSize); - } - - @Override - public long toCleartextSize(final long cleartextFileOffset, final long ciphertextFileSize) throws CryptoInvalidFilesizeException { - if(TransferStatus.UNKNOWN_LENGTH == ciphertextFileSize) { - return TransferStatus.UNKNOWN_LENGTH; - } - final int headerSize; - if(0L == cleartextFileOffset) { - headerSize = cryptor.fileHeaderCryptor().headerSize(); - } - else { - headerSize = 0; - } - try { - return cryptor.fileContentCryptor().cleartextSize(ciphertextFileSize - headerSize); - } - catch(AssertionError e) { - throw new CryptoInvalidFilesizeException(String.format("Encrypted file size must be at least %d bytes", headerSize)); - } - catch(IllegalArgumentException e) { - throw new CryptoInvalidFilesizeException(String.format("Invalid file size. %s", e.getMessage())); - } - } - - private Path inflate(final Session session, final Path file) throws BackgroundException { - final String fileName = file.getName(); - if(filenameProvider.isDeflated(fileName)) { - final String filename = filenameProvider.inflate(session, fileName); - return new Path(file.getParent(), filename, EnumSet.of(Path.Type.file), file.attributes()); - } - return file; - } - - public Path getHome() { - return home; - } - - public Path getMasterkey() { - return masterkey; - } - - public Path getConfig() { - return config; - } - - public FileHeaderCryptor getFileHeaderCryptor() { - return cryptor.fileHeaderCryptor(); - } - - public FileContentCryptor getFileContentCryptor() { - return cryptor.fileContentCryptor(); - } - - public CryptorCache getFileNameCryptor() { - return fileNameCryptor; - } - - public CryptoFilename getFilenameProvider() { - return filenameProvider; - } - - public CryptoDirectory getDirectoryProvider() { - return directoryProvider; - } - - public int getNonceSize() { - return nonceSize; - } - - public int numberOfChunks(final long cleartextFileSize) { - return (int) (cleartextFileSize / cryptor.fileContentCryptor().cleartextChunkSize() + - ((cleartextFileSize % cryptor.fileContentCryptor().cleartextChunkSize() > 0) ? 1 : 0)); - } - - @Override - @SuppressWarnings("unchecked") - public T getFeature(final Session session, final Class type, final T delegate) { - if(this.isUnlocked()) { - if(type == ListService.class) { - return (T) new CryptoListService(session, (ListService) delegate, this); - } - if(type == Touch.class) { - // Use default touch feature because touch with remote implementation will not add encrypted file header - return (T) new CryptoTouchFeature(session, new DefaultTouchFeature(session), this); - } - if(type == Directory.class) { - return (T) (vaultVersion == VAULT_VERSION_DEPRECATED ? - new CryptoDirectoryV6Feature(session, (Directory) delegate, this) : - new CryptoDirectoryV7Feature(session, (Directory) delegate, this) - ); - } - if(type == Upload.class) { - return (T) new CryptoUploadFeature(session, (Upload) delegate, this); - } - if(type == Download.class) { - return (T) new CryptoDownloadFeature(session, (Download) delegate, this); - } - if(type == Read.class) { - return (T) new CryptoReadFeature(session, (Read) delegate, this); - } - if(type == Write.class) { - return (T) new CryptoWriteFeature(session, (Write) delegate, this); - } - if(type == MultipartWrite.class) { - return (T) new CryptoMultipartWriteFeature(session, (Write) delegate, this); - } - if(type == Move.class) { - return (T) (vaultVersion == VAULT_VERSION_DEPRECATED ? - new CryptoMoveV6Feature(session, (Move) delegate, this) : - new CryptoMoveV7Feature(session, (Move) delegate, this)); - - } - if(type == AttributesFinder.class) { - return (T) new CryptoAttributesFeature(session, (AttributesFinder) delegate, this); - } - if(type == Find.class) { - return (T) new CryptoFindFeature(session, (Find) delegate, this); - } - if(type == UrlProvider.class) { - return (T) new CryptoUrlProvider(session, (UrlProvider) delegate, this); - } - if(type == FileIdProvider.class) { - return (T) new CryptoFileIdProvider(session, (FileIdProvider) delegate, this); - } - if(type == VersionIdProvider.class) { - return (T) new CryptoVersionIdProvider(session, (VersionIdProvider) delegate, this); - } - if(type == Delete.class) { - return (T) (vaultVersion == VAULT_VERSION_DEPRECATED ? - new CryptoDeleteV6Feature(session, (Delete) delegate, this) : - new CryptoDeleteV7Feature(session, (Delete) delegate, this)); - } - if(type == Trash.class) { - return (T) (vaultVersion == VAULT_VERSION_DEPRECATED ? - new CryptoDeleteV6Feature(session, (Delete) delegate, this) : - new CryptoDeleteV7Feature(session, (Delete) delegate, this)); - } - if(type == Symlink.class) { - return (T) new CryptoSymlinkFeature(session, (Symlink) delegate, this); - } - if(type == Headers.class) { - return (T) new CryptoHeadersFeature(session, (Headers) delegate, this); - } - if(type == Compress.class) { - return (T) new CryptoCompressFeature(session, (Compress) delegate, this); - } - if(type == Bulk.class) { - return (T) new CryptoBulkFeature(session, (Bulk) delegate, this); - } - if(type == UnixPermission.class) { - return (T) new CryptoUnixPermission(session, (UnixPermission) delegate, this); - } - if(type == AclPermission.class) { - return (T) new CryptoAclPermission(session, (AclPermission) delegate, this); - } - if(type == Copy.class) { - return (T) new CryptoCopyFeature(session, (Copy) delegate, this); - } - if(type == Timestamp.class) { - return (T) new CryptoTimestampFeature(session, (Timestamp) delegate, this); - } - if(type == Encryption.class) { - return (T) new CryptoEncryptionFeature(session, (Encryption) delegate, this); - } - if(type == Lifecycle.class) { - return (T) new CryptoLifecycleFeature(session, (Lifecycle) delegate, this); - } - if(type == Location.class) { - return (T) new CryptoLocationFeature(session, (Location) delegate, this); - } - if(type == Lock.class) { - return (T) new CryptoLockFeature(session, (Lock) delegate, this); - } - if(type == Logging.class) { - return (T) new CryptoLoggingFeature(session, (Logging) delegate, this); - } - if(type == Redundancy.class) { - return (T) new CryptoRedundancyFeature(session, (Redundancy) delegate, this); - } - if(type == Search.class) { - return (T) new CryptoSearchFeature(session, (Search) delegate, this); - } - if(type == TransferAcceleration.class) { - return (T) new CryptoTransferAccelerationFeature<>(session, (TransferAcceleration) delegate, this); - } - if(type == Versioning.class) { - return (T) new CryptoVersioningFeature(session, (Versioning) delegate, this); - } - } - return delegate; - } - - @Override - public boolean equals(final Object o) { - if(this == o) { - return true; - } - if(!(o instanceof CryptoVault)) { - return false; - } - final CryptoVault that = (CryptoVault) o; - return new SimplePathPredicate(home).test(that.home); - } - - @Override - public int hashCode() { - return Objects.hash(new SimplePathPredicate(home)); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CryptoVault{"); - sb.append("home=").append(home); - sb.append(", cryptor=").append(cryptor); - sb.append('}'); - return sb.toString(); - } - - public static class VaultConfig { - - private final int version; - private final int shorteningThreshold; - private final CryptorProvider.Scheme cipherCombo; - private final String algorithm; - private final DecodedJWT token; - private MasterkeyFile mkfile; - - public VaultConfig(int version, int shorteningThreshold, CryptorProvider.Scheme cipherCombo, String algorithm, DecodedJWT token) { - this.version = version; - this.shorteningThreshold = shorteningThreshold; - this.cipherCombo = cipherCombo; - this.algorithm = algorithm; - this.token = token; - } - - public int vaultVersion() { - return version; - } - - public VaultConfig withMasterkeyFile(final MasterkeyFile mkfile) { - this.mkfile = mkfile; - return this; - } - - public MasterkeyFile getMkfile() { - return mkfile; - } - - public int getShorteningThreshold() { - return shorteningThreshold; - } - - public CryptorProvider.Scheme getCipherCombo() { - return cipherCombo; - } - - public int getNonceSize() throws VaultException { - switch(cipherCombo) { - case SIV_CTRMAC: - return 16; - case SIV_GCM: - return 12; - default: - throw new VaultException(String.format("Unsupported cipher scheme %s", cipherCombo)); - } - } - - private Algorithm initAlgorithm(byte[] rawKey) throws VaultException { - switch(algorithm) { - case "HS256": - return Algorithm.HMAC256(rawKey); - case "HS384": - return Algorithm.HMAC384(rawKey); - case "HS512": - return Algorithm.HMAC512(rawKey); - default: - throw new VaultException(String.format("Unsupported signature algorithm %s", algorithm)); - } - } - - public void verify(byte[] rawKey, int expectedVaultVersion) throws VaultException { - try { - if(token == null) { - return; - } - JWTVerifier verifier = JWT.require(initAlgorithm(rawKey)) - .withClaim(JSON_KEY_VAULTVERSION, expectedVaultVersion) - .build(); - verifier.verify(token); - } - catch(SignatureVerificationException e) { - throw new VaultException("Invalid JWT signature", e); - } - catch(InvalidClaimException e) { - throw new VaultException(String.format("Expected vault config for version %d", expectedVaultVersion), e); - } - catch(JWTVerificationException e) { - throw new VaultException(String.format("Failed to verify vault config %s", token), e); - } - } - } -} \ No newline at end of file diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoVaultProvider.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoVaultProvider.java new file mode 100644 index 00000000000..aff3414203e --- /dev/null +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptoVaultProvider.java @@ -0,0 +1,107 @@ +package ch.cyberduck.core.cryptomator; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.ListProgressListener; +import ch.cyberduck.core.Path; +import ch.cyberduck.core.Session; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.features.Find; +import ch.cyberduck.core.preferences.HostPreferencesFactory; +import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; +import ch.cyberduck.core.vault.VaultProvider; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.EnumSet; +import java.util.Map; + +import com.google.common.collect.ImmutableMap; + +/** + * Cryptomator vault implementation + */ +public class CryptoVaultProvider implements VaultProvider { + private static final Logger log = LogManager.getLogger(CryptoVaultProvider.class); + + private final Map markers; + + public CryptoVaultProvider(final Session session) { + this.markers = ImmutableMap.of( + HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.masterkey.filename"), VaultMetadata.Type.V8, + HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.config.filename.uvf"), VaultMetadata.Type.UVF + ); + } + + @Override + public boolean isVault(final Path path) { + return markers.keySet().stream().anyMatch(marker -> path.getName().equals(marker)); + } + + @Override + public VaultMetadata metadata(final Path path) { + if(this.isVault(path)) { + return new VaultMetadata(path.getParent(), markers.get(path.getName())); + } + return null; + } + + @Override + public VaultMetadata find(final Path directory, final Find find, final ListProgressListener listener) throws BackgroundException { + for(String marker : markers.keySet()) { + final Path m = new Path(directory, marker, EnumSet.of(Path.Type.file)); + if(find.find(m, listener)) { + return new VaultMetadata(m.getParent(), markers.get(marker)); + } + } + return null; + } + + //TODO prompt parameter wegnehmen? + @Override + public synchronized AbstractVault provide(final Session session, final VaultMetadata metadata) { + switch(metadata.type) { + case V8: + return new ch.cyberduck.core.cryptomator.impl.v8.CryptoVault(metadata.root); + case UVF: + return new ch.cyberduck.core.cryptomator.impl.uvf.CryptoVault(metadata.root); + default: + log.error("Unknown vault type {}", metadata.type); + // TODO schmeissen, DISABLED zurück geben geht nicht weil kein AbstractVault + // throw new ... + return null; + } + } + + //TODO create methode braucht es glaube ich nicht unbedingt + + @Override + public AbstractVault create(final Session session, final String region, final VaultCredentials credentials, final VaultMetadata metadata) throws BackgroundException { + switch(metadata.type) { + case V8: + return new ch.cyberduck.core.cryptomator.impl.v8.CryptoVault(metadata.root).create(session, region, credentials); + case UVF: + return new ch.cyberduck.core.cryptomator.impl.uvf.CryptoVault(metadata.root).create(session, region, credentials); + default: + log.error("Unknown vault type {}", metadata.type); + // TODO schmeissen, DISABLED zurück geben geht nicht weil kein AbstractVault + // throw new ... + return null; + } + } +} \ No newline at end of file diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptorCache.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptorCache.java index f62cf502146..96bc1893bbf 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptorCache.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/CryptorCache.java @@ -20,6 +20,7 @@ import org.cryptomator.cryptolib.api.AuthenticationFailedException; import org.cryptomator.cryptolib.api.FileNameCryptor; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Objects; @@ -29,7 +30,7 @@ public class CryptorCache { public static final BaseEncoding BASE32 = BaseEncoding.base32(); - private final LRUCache directoryIdCache = LRUCache.build(250); + private final LRUCache directoryIdCache = LRUCache.build(250); private final LRUCache decryptCache = LRUCache.build(5000); private final LRUCache encryptCache = LRUCache.build(5000); @@ -39,11 +40,12 @@ public CryptorCache(final FileNameCryptor impl) { this.impl = impl; } - public String hashDirectoryId(final String cleartextDirectoryId) { - if(!directoryIdCache.contains(cleartextDirectoryId)) { - directoryIdCache.put(cleartextDirectoryId, impl.hashDirectoryId(cleartextDirectoryId)); + public String hashDirectoryId(final byte[] cleartextDirectoryId) { + final ByteBuffer wrap = ByteBuffer.wrap(cleartextDirectoryId); + if(!directoryIdCache.contains(wrap)) { + directoryIdCache.put(wrap, impl.hashDirectoryId(cleartextDirectoryId)); } - return directoryIdCache.get(cleartextDirectoryId); + return directoryIdCache.get(wrap); } public String encryptFilename(final BaseEncoding encoding, final String cleartextName, final byte[] associatedData) { diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoAttributesFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoAttributesFeature.java index 5276d3e3d03..3b66ca2b21a 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoAttributesFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoAttributesFeature.java @@ -51,7 +51,7 @@ public PathAttributes find(final Path file, final ListProgressListener listener) if(file.isDirectory()) { attributes.setSize(-1L); } - attributes.setVault(vault.getHome()); + attributes.setVaultMetadata(vault.getMetadata()); return attributes; } diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoBulkFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoBulkFeature.java index 90f7be910c4..2aa4f98ff72 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoBulkFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoBulkFeature.java @@ -21,7 +21,7 @@ import ch.cyberduck.core.RandomStringService; import ch.cyberduck.core.Session; import ch.cyberduck.core.UUIDRandomStringService; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.cryptomator.random.RotatingNonceGenerator; import ch.cyberduck.core.exception.BackgroundException; @@ -45,9 +45,9 @@ public class CryptoBulkFeature implements Bulk { private final Session session; private final Bulk delegate; - private final CryptoVault cryptomator; + private final AbstractVault cryptomator; - public CryptoBulkFeature(final Session session, final Bulk delegate, final CryptoVault cryptomator) { + public CryptoBulkFeature(final Session session, final Bulk delegate, final AbstractVault cryptomator) { this.session = session; this.delegate = delegate; this.cryptomator = cryptomator; @@ -82,9 +82,8 @@ public int compare(final Map.Entry o1, final Map.E if(!status.isExists()) { switch(type) { case upload: - // Preset directory ID for new folders to avert lookup with not found failure in directory ID provider - final String directoryId = random.random(); - encrypted.put(new TransferItem(cryptomator.encrypt(session, file, directoryId, false), local), status); + cryptomator.getDirectoryProvider().createDirectoryId(file); + encrypted.put(new TransferItem(cryptomator.encrypt(session, file, false), local), status); break; default: encrypted.put(new TransferItem(cryptomator.encrypt(session, file), local), status); diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoChecksumCompute.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoChecksumCompute.java index c591b99d69c..41ae969b7fd 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoChecksumCompute.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoChecksumCompute.java @@ -15,8 +15,8 @@ * GNU General Public License for more details. */ +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.CryptoOutputStream; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.cryptomator.random.RotatingNonceGenerator; import ch.cyberduck.core.exception.BackgroundException; @@ -55,11 +55,11 @@ public class CryptoChecksumCompute extends AbstractChecksumCompute { private static final Logger log = LogManager.getLogger(CryptoChecksumCompute.class); - private final CryptoVault cryptomator; + private final AbstractVault cryptomator; private final ChecksumCompute delegate; - public CryptoChecksumCompute(final ChecksumCompute delegate, final CryptoVault vault) { - this.cryptomator = vault; + public CryptoChecksumCompute(final ChecksumCompute delegate, final AbstractVault CryptoVaultInterface) { + this.cryptomator = CryptoVaultInterface; this.delegate = delegate; } diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoCopyFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoCopyFeature.java index 83d536d17b2..cc172478978 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoCopyFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoCopyFeature.java @@ -19,7 +19,7 @@ import ch.cyberduck.core.Path; import ch.cyberduck.core.PathAttributes; import ch.cyberduck.core.Session; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.cryptomator.random.RotatingNonceGenerator; import ch.cyberduck.core.exception.BackgroundException; @@ -37,11 +37,11 @@ public class CryptoCopyFeature implements Copy { private final Session session; private final Copy proxy; - private final CryptoVault vault; + private final AbstractVault vault; private Session target; - public CryptoCopyFeature(final Session session, final Copy proxy, final CryptoVault vault) { + public CryptoCopyFeature(final Session session, final Copy proxy, final AbstractVault vault) { this.session = session; this.target = session; this.proxy = proxy; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDeleteV6Feature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDeleteV6Feature.java deleted file mode 100644 index cbdda42cf13..00000000000 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDeleteV6Feature.java +++ /dev/null @@ -1,142 +0,0 @@ -package ch.cyberduck.core.cryptomator.features; - -/* - * Copyright (c) 2002-2020 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.DisabledListProgressListener; -import ch.cyberduck.core.ListService; -import ch.cyberduck.core.PasswordCallback; -import ch.cyberduck.core.Path; -import ch.cyberduck.core.Session; -import ch.cyberduck.core.cryptomator.CryptoFilename; -import ch.cyberduck.core.cryptomator.CryptoVault; -import ch.cyberduck.core.exception.AccessDeniedException; -import ch.cyberduck.core.exception.BackgroundException; -import ch.cyberduck.core.exception.NotfoundException; -import ch.cyberduck.core.features.Delete; -import ch.cyberduck.core.features.Find; -import ch.cyberduck.core.features.Trash; -import ch.cyberduck.core.transfer.TransferStatus; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; - -public class CryptoDeleteV6Feature implements Delete, Trash { - private static final Logger log = LogManager.getLogger(CryptoDeleteV6Feature.class); - - private final Session session; - private final Delete proxy; - private final CryptoVault vault; - private final CryptoFilename filenameProvider; - - public CryptoDeleteV6Feature(final Session session, final Delete proxy, final CryptoVault vault) { - this.session = session; - this.proxy = proxy; - this.vault = vault; - this.filenameProvider = vault.getFilenameProvider(); - } - - @Override - public void delete(final Map files, final PasswordCallback prompt, final Callback callback) throws BackgroundException { - for(Path f : files.keySet()) { - final List metadataFiles = new ArrayList<>(); - if(!f.equals(vault.getHome())) { - final Path encrypt = vault.encrypt(session, f); - try { - proxy.delete(Collections.singletonList(encrypt), prompt, callback); - } - catch(NotfoundException | AccessDeniedException e) { - if(f.isDirectory()) { - log.error("Failure {} deleting directory {}", e, encrypt); - } - else { - throw e; - } - } - final Path metadata = vault.encrypt(session, f, true); - if(f.isDirectory()) { - // Delete metadata file for directory - log.debug("Add metadata file {}", metadata); - metadataFiles.add(metadata); - vault.getDirectoryProvider().delete(f); - } - if(filenameProvider.isDeflated(metadata.getName())) { - filenameProvider.invalidate(filenameProvider.inflate(session, metadata.getName())); - final Path metadataFile = filenameProvider.resolve(metadata.getName()); - log.debug("Add metadata file {}", metadata); - metadataFiles.add(metadataFile); - } - } - if(!metadataFiles.isEmpty()) { - proxy.delete(metadataFiles, prompt, callback); - } - } - for(Path f : files.keySet()) { - if(f.equals(vault.getHome())) { - log.warn("Recursively delete vault {}", f); - final List metadata = new ArrayList<>(); - if(!proxy.features(f).contains(Delete.Flags.recursive)) { - final Find find = session._getFeature(Find.class); - final Path dataRoot = new Path(f, "d", f.getType()); - if(find.find(dataRoot)) { - for(Path d : session._getFeature(ListService.class).list(dataRoot, new DisabledListProgressListener()).toList()) { - metadata.addAll(session._getFeature(ListService.class).list(d, new DisabledListProgressListener()).toList()); - metadata.add(d); - } - metadata.add(dataRoot); - } - final Path metaRoot = new Path(f, "m", f.getType()); - if(find.find(metaRoot)) { - for(Path m : session._getFeature(ListService.class).list(metaRoot, new DisabledListProgressListener()).toList()) { - for(Path m2 : session._getFeature(ListService.class).list(m, new DisabledListProgressListener()).toList()) { - metadata.addAll(session._getFeature(ListService.class).list(m2, new DisabledListProgressListener()).toList()); - metadata.add(m2); - } - metadata.add(m); - } - metadata.add(metaRoot); - } - metadata.add(vault.getMasterkey()); - } - metadata.add(f); - proxy.delete(metadata, prompt, callback); - } - } - } - - @Override - public void preflight(final Path file) throws BackgroundException { - proxy.preflight(vault.encrypt(session, file)); - } - - @Override - public EnumSet features(final Path file) { - return proxy.features(file); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CryptoDeleteV6Feature{"); - sb.append("proxy=").append(proxy); - sb.append('}'); - return sb.toString(); - } -} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDeleteV7Feature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDeleteV7Feature.java index ab1d6b34b73..1c8c02c26bd 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDeleteV7Feature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDeleteV7Feature.java @@ -15,14 +15,14 @@ * GNU General Public License for more details. */ +import ch.cyberduck.core.AbstractPath; import ch.cyberduck.core.DisabledListProgressListener; import ch.cyberduck.core.ListService; import ch.cyberduck.core.PasswordCallback; import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.CryptoFilename; -import ch.cyberduck.core.cryptomator.CryptoVault; -import ch.cyberduck.core.cryptomator.impl.CryptoDirectoryV7Provider; import ch.cyberduck.core.exception.AccessDeniedException; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.exception.NotfoundException; @@ -45,10 +45,10 @@ public class CryptoDeleteV7Feature implements Delete, Trash { private final Session session; private final Delete proxy; - private final CryptoVault vault; + private final AbstractVault vault; private final CryptoFilename filenameProvider; - public CryptoDeleteV7Feature(final Session session, final Delete proxy, final CryptoVault vault) { + public CryptoDeleteV7Feature(final Session session, final Delete proxy, final AbstractVault vault) { this.session = session; this.proxy = proxy; this.vault = vault; @@ -62,8 +62,8 @@ public void delete(final Map files, final PasswordCallback if(!f.equals(vault.getHome())) { final Path encrypt = vault.encrypt(session, f); if(f.isDirectory()) { - final Path backup = new Path(encrypt, CryptoDirectoryV7Provider.BACKUP_DIRECTORY_METADATAFILE, - EnumSet.of(Path.Type.file)); + final Path backup = new Path(encrypt, vault.getBackupDirectoryMetadataFilename(), + EnumSet.of(AbstractPath.Type.file)); try { log.debug("Deleting directory id backup file {}", backup); proxy.delete(Collections.singletonList(backup), prompt, callback); @@ -87,7 +87,7 @@ public void delete(final Map files, final PasswordCallback } final Path metadata = vault.encrypt(session, f, true); if(f.isDirectory()) { - final Path metadataFile = new Path(metadata, CryptoDirectoryV7Provider.DIRECTORY_METADATAFILE, EnumSet.of(Path.Type.file)); + final Path metadataFile = new Path(metadata, vault.getDirectoryMetadataFilename(), EnumSet.of(Path.Type.file)); log.debug("Add metadata file {}", metadataFile); metadataFiles.add(metadataFile); metadataFiles.add(metadata); @@ -124,8 +124,8 @@ public void delete(final Map files, final PasswordCallback } metadata.add(dataRoot); } - if(vault.getMasterkey() != null) { - metadata.add(vault.getMasterkey()); + if(vault.getMasterkeyPath() != null) { + metadata.add(vault.getMasterkeyPath()); } if(find.find(vault.getConfig())) { metadata.add(vault.getConfig()); diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryV6Feature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryUVFFeature.java similarity index 54% rename from cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryV6Feature.java rename to cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryUVFFeature.java index 1f92916e928..1dcacf4cd28 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryV6Feature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryUVFFeature.java @@ -1,7 +1,7 @@ package ch.cyberduck.core.cryptomator.features; /* - * Copyright (c) 2002-2020 iterate GmbH. All rights reserved. + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. * https://cyberduck.io/ * * This program is free software; you can redistribute it and/or modify @@ -16,11 +16,9 @@ */ import ch.cyberduck.core.Path; -import ch.cyberduck.core.RandomStringService; import ch.cyberduck.core.Session; -import ch.cyberduck.core.UUIDRandomStringService; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.ContentWriter; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Directory; @@ -30,64 +28,67 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.cryptomator.cryptolib.api.DirectoryMetadata; import org.cryptomator.cryptolib.api.FileHeader; -import java.nio.charset.StandardCharsets; +import java.util.EnumSet; -public class CryptoDirectoryV6Feature implements Directory { - private static final Logger log = LogManager.getLogger(CryptoDirectoryV6Feature.class); +public class CryptoDirectoryUVFFeature extends CryptoDirectoryV7Feature { + private static final Logger log = LogManager.getLogger(CryptoDirectoryUVFFeature.class); private final Session session; private final Directory delegate; - private final CryptoVault vault; - private final RandomStringService random = new UUIDRandomStringService(); + private final AbstractVault vault; - public CryptoDirectoryV6Feature(final Session session, final Directory delegate, final CryptoVault cryptomator) { + public CryptoDirectoryUVFFeature(final Session session, final Directory delegate, final AbstractVault vault) { + super(session, delegate, vault); this.session = session; this.delegate = delegate; - this.vault = cryptomator; + this.vault = vault; } + //TODO check if we can merge this implementation with the one in the superclass. Here we additionally write the recovery metadata file. @Override public Path mkdir(final Write writer, final Path folder, final TransferStatus status) throws BackgroundException { - final Path encrypt = vault.encrypt(session, folder, random.random(), false); - final String directoryId = encrypt.attributes().getDirectoryId(); + final DirectoryMetadata dirMetadata = vault.getDirectoryProvider().createDirectoryId(folder); // Create metadata file for directory - final Path directoryMetadataFile = vault.encrypt(session, folder, true); + final Path directoryMetadataFolder = session._getFeature(Directory.class).mkdir(writer, vault.encrypt(session, folder, true), + new TransferStatus().setRegion(status.getRegion())); + final Path directoryMetadataFile = new Path(directoryMetadataFolder, + vault.getDirectoryMetadataFilename(), + EnumSet.of(Path.Type.file)); log.debug("Write metadata {} for folder {}", directoryMetadataFile, folder); - new ContentWriter(session).write(directoryMetadataFile, directoryId.getBytes(StandardCharsets.UTF_8)); + final byte[] encryptedMetadata = this.vault.getCryptor().directoryContentCryptor().encryptDirectoryMetadata(dirMetadata); + new ContentWriter(session).write(directoryMetadataFile, encryptedMetadata); + final Path encrypt = vault.encrypt(session, folder, false); final Path intermediate = encrypt.getParent(); if(!session._getFeature(Find.class).find(intermediate)) { - session._getFeature(Directory.class).mkdir(session._getFeature(Write.class), intermediate, new TransferStatus().setRegion(status.getRegion())); + session._getFeature(Directory.class).mkdir(writer, intermediate, new TransferStatus().setRegion(status.getRegion())); } - // Write header + + // Write metadata final FileHeader header = vault.getFileHeaderCryptor().create(); status.setHeader(vault.getFileHeaderCryptor().encryptHeader(header)); status.setNonces(new RandomNonceGenerator(vault.getNonceSize())); final Path target = delegate.mkdir(writer, encrypt, status); + final Path recoveryDirectoryMetadataFile = new Path(target, + vault.getDirectoryMetadataFilename(), + EnumSet.of(Path.Type.file)); + log.debug("Write recovery metadata {} for folder {}", recoveryDirectoryMetadataFile, folder); + new ContentWriter(session).write(recoveryDirectoryMetadataFile, this.vault.getCryptor().directoryContentCryptor().encryptDirectoryMetadata(dirMetadata)); // Implementation may return new copy of attributes without encryption attributes - target.attributes().setDirectoryId(directoryId); + target.attributes().setDirectoryId(encryptedMetadata); target.attributes().setDecrypted(folder); // Make reference of encrypted path in attributes of decrypted file point to metadata file final Path decrypt = vault.decrypt(session, vault.encrypt(session, target, true)); - decrypt.attributes().setFileId(directoryMetadataFile.attributes().getFileId()); - decrypt.attributes().setVersionId(directoryMetadataFile.attributes().getVersionId()); + decrypt.attributes().setFileId(directoryMetadataFolder.attributes().getFileId()); + decrypt.attributes().setVersionId(directoryMetadataFolder.attributes().getVersionId()); return decrypt; } - @Override - public boolean isSupported(final Path workdir, final String name) { - return delegate.isSupported(workdir, name); - } - - @Override - public void preflight(final Path workdir, final String filename) throws BackgroundException { - delegate.preflight(vault.encrypt(session, workdir), filename); - } - @Override public String toString() { - final StringBuilder sb = new StringBuilder("CryptoDirectoryFeature{"); + final StringBuilder sb = new StringBuilder("CryptoDirectoryUVFFeature{"); sb.append("proxy=").append(delegate); sb.append('}'); return sb.toString(); diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryV7Feature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryV7Feature.java index b32f8eb7733..20ed3259674 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryV7Feature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDirectoryV7Feature.java @@ -16,12 +16,9 @@ */ import ch.cyberduck.core.Path; -import ch.cyberduck.core.RandomStringService; import ch.cyberduck.core.Session; -import ch.cyberduck.core.UUIDRandomStringService; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.ContentWriter; -import ch.cyberduck.core.cryptomator.CryptoVault; -import ch.cyberduck.core.cryptomator.impl.CryptoDirectoryV7Provider; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Directory; @@ -31,9 +28,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.cryptomator.cryptolib.api.DirectoryMetadata; import org.cryptomator.cryptolib.api.FileHeader; -import java.nio.charset.StandardCharsets; import java.util.EnumSet; public class CryptoDirectoryV7Feature implements Directory { @@ -41,28 +38,28 @@ public class CryptoDirectoryV7Feature implements Directory { private final Session session; private final Directory delegate; - private final CryptoVault vault; - private final RandomStringService random = new UUIDRandomStringService(); + private final AbstractVault vault; - public CryptoDirectoryV7Feature(final Session session, final Directory delegate, final CryptoVault cryptomator) { + public CryptoDirectoryV7Feature(final Session session, final Directory delegate, final AbstractVault vault) { this.session = session; this.delegate = delegate; - this.vault = cryptomator; + this.vault = vault; } @Override public Path mkdir(final Write writer, final Path folder, final TransferStatus status) throws BackgroundException { - final Path encrypt = vault.encrypt(session, folder, random.random(), false); - final String directoryId = encrypt.attributes().getDirectoryId(); + final DirectoryMetadata dirMetadata = vault.getDirectoryProvider().createDirectoryId(folder); // Create metadata file for directory final Path directoryMetadataFolder = session._getFeature(Directory.class).mkdir( session._getFeature(Write.class), vault.encrypt(session, folder, true), new TransferStatus().setRegion(status.getRegion())); final Path directoryMetadataFile = new Path(directoryMetadataFolder, - CryptoDirectoryV7Provider.DIRECTORY_METADATAFILE, + vault.getDirectoryMetadataFilename(), EnumSet.of(Path.Type.file)); log.debug("Write metadata {} for folder {}", directoryMetadataFile, folder); - new ContentWriter(session).write(directoryMetadataFile, directoryId.getBytes(StandardCharsets.UTF_8)); + final byte[] encryptedMetadata = this.vault.getCryptor().directoryContentCryptor().encryptDirectoryMetadata(dirMetadata); + new ContentWriter(session).write(directoryMetadataFile, encryptedMetadata); + final Path encrypt = vault.encrypt(session, folder, false); final Path intermediate = encrypt.getParent(); if(!session._getFeature(Find.class).find(intermediate)) { session._getFeature(Directory.class).mkdir(session._getFeature(Write.class), intermediate, new TransferStatus().setRegion(status.getRegion())); @@ -73,7 +70,7 @@ public Path mkdir(final Write writer, final Path folder, final TransferSt status.setNonces(new RandomNonceGenerator(vault.getNonceSize())); final Path target = delegate.mkdir(writer, encrypt, status); // Implementation may return new copy of attributes without encryption attributes - target.attributes().setDirectoryId(directoryId); + target.attributes().setDirectoryId(encryptedMetadata); target.attributes().setDecrypted(folder); // Make reference of encrypted path in attributes of decrypted file point to metadata file final Path decrypt = vault.decrypt(session, vault.encrypt(session, target, true)); @@ -94,7 +91,7 @@ public void preflight(final Path workdir, final String filename) throws Backgrou @Override public String toString() { - final StringBuilder sb = new StringBuilder("CryptoDirectoryFeature{"); + final StringBuilder sb = new StringBuilder("CryptoDirectoryV7Feature{"); sb.append("proxy=").append(delegate); sb.append('}'); return sb.toString(); diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDownloadFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDownloadFeature.java index e3dceec4da6..17119b99785 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDownloadFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoDownloadFeature.java @@ -19,12 +19,11 @@ import ch.cyberduck.core.Local; import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.exception.NotfoundException; import ch.cyberduck.core.features.Download; import ch.cyberduck.core.features.Read; -import ch.cyberduck.core.features.Vault; import ch.cyberduck.core.io.BandwidthThrottle; import ch.cyberduck.core.io.StreamListener; import ch.cyberduck.core.transfer.TransferStatus; @@ -33,9 +32,9 @@ public class CryptoDownloadFeature implements Download { private final Session session; private final Download proxy; - private final Vault vault; + private final AbstractVault vault; - public CryptoDownloadFeature(final Session session, final Download proxy, final CryptoVault vault) { + public CryptoDownloadFeature(final Session session, final Download proxy, final Read reader, final AbstractVault vault) { this.session = session; this.proxy = proxy; this.vault = vault; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoEncryptionFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoEncryptionFeature.java index 9f30a97b1be..6dc07f6edf2 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoEncryptionFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoEncryptionFeature.java @@ -18,7 +18,6 @@ import ch.cyberduck.core.LoginCallback; import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Encryption; import ch.cyberduck.core.features.Vault; @@ -31,7 +30,7 @@ public class CryptoEncryptionFeature implements Encryption { private final Encryption delegate; private final Vault vault; - public CryptoEncryptionFeature(final Session session, final Encryption delegate, final CryptoVault vault) { + public CryptoEncryptionFeature(final Session session, final Encryption delegate, final Vault vault) { this.session = session; this.delegate = delegate; this.vault = vault; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMoveV6Feature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMoveV6Feature.java deleted file mode 100644 index e43afc0965d..00000000000 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMoveV6Feature.java +++ /dev/null @@ -1,92 +0,0 @@ -package ch.cyberduck.core.cryptomator.features; - -/* - * Copyright (c) 2002-2017 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.ConnectionCallback; -import ch.cyberduck.core.LocaleFactory; -import ch.cyberduck.core.Path; -import ch.cyberduck.core.Session; -import ch.cyberduck.core.cryptomator.CryptoVault; -import ch.cyberduck.core.exception.BackgroundException; -import ch.cyberduck.core.exception.InvalidFilenameException; -import ch.cyberduck.core.features.Delete; -import ch.cyberduck.core.features.Move; -import ch.cyberduck.core.transfer.TransferStatus; - -import java.text.MessageFormat; -import java.util.EnumSet; -import java.util.Optional; - -public class CryptoMoveV6Feature implements Move { - - private final Session session; - private final Move proxy; - private final CryptoVault vault; - - public CryptoMoveV6Feature(final Session session, final Move delegate, final CryptoVault cryptomator) { - this.session = session; - this.proxy = delegate; - this.vault = cryptomator; - } - - @Override - public Path move(final Path file, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback) throws BackgroundException { - // Move inside vault moves actual files and only metadata files for directories but not the actual directories - final Path target = proxy.move( - vault.encrypt(session, file, file.isDirectory()), - vault.encrypt(session, renamed, file.isDirectory()), status, callback, connectionCallback); - if(file.isDirectory()) { - vault.getDirectoryProvider().delete(file); - } - if(vault.contains(target)) { - return vault.decrypt(session, target); - } - return target; - } - - @Override - public EnumSet features(final Path source, final Path target) { - // No need to handle recursion with encrypted filenames - return EnumSet.of(Flags.recursive); - } - - @Override - public void preflight(final Path source, final Optional target) throws BackgroundException { - if(target.isPresent()) { - if(!vault.getFilenameProvider().isValid(target.get().getName())) { - throw new InvalidFilenameException(MessageFormat.format(LocaleFactory.localizedString("Cannot create {0}", "Error"), target.get().getName())).withFile(source); - } - proxy.preflight(vault.encrypt(session, source, source.isDirectory()), Optional.of(vault.encrypt(session, target.get(), source.isDirectory()))); - } - else { - proxy.preflight(vault.encrypt(session, source, source.isDirectory()), target); - } - } - - @Override - public Move withTarget(final Session session) { - proxy.withTarget(session); - return this; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CryptoMoveFeature{"); - sb.append("proxy=").append(proxy); - sb.append('}'); - return sb.toString(); - } -} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMoveV7Feature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMoveV7Feature.java index a0bd1c8eb7f..ea1c2fd5659 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMoveV7Feature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMoveV7Feature.java @@ -19,8 +19,7 @@ import ch.cyberduck.core.LocaleFactory; import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; -import ch.cyberduck.core.cryptomator.CryptoVault; -import ch.cyberduck.core.cryptomator.impl.CryptoDirectoryV7Provider; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.exception.InvalidFilenameException; import ch.cyberduck.core.features.Delete; @@ -35,12 +34,12 @@ public class CryptoMoveV7Feature implements Move { private final Session session; private final Move proxy; - private final CryptoVault vault; + private final AbstractVault vault; - public CryptoMoveV7Feature(final Session session, final Move delegate, final CryptoVault cryptomator) { + public CryptoMoveV7Feature(final Session session, final Move delegate, final AbstractVault vault) { this.session = session; this.proxy = delegate; - this.vault = cryptomator; + this.vault = vault; } @Override @@ -51,8 +50,8 @@ public Path move(final Path file, final Path renamed, final TransferStatus statu final Path target = proxy.move(sourceEncrypted, targetEncrypted, status, callback, connectionCallback); if(file.isDirectory()) { if(!proxy.isRecursive(file, renamed)) { - proxy.move(new Path(sourceEncrypted, CryptoDirectoryV7Provider.DIRECTORY_METADATAFILE, EnumSet.of(Path.Type.file)), - new Path(targetEncrypted, CryptoDirectoryV7Provider.DIRECTORY_METADATAFILE, EnumSet.of(Path.Type.file)), + proxy.move(new Path(sourceEncrypted, vault.getDirectoryMetadataFilename(), EnumSet.of(Path.Type.file)), + new Path(targetEncrypted, vault.getBackupDirectoryMetadataFilename(), EnumSet.of(Path.Type.file)), new TransferStatus(status), callback, connectionCallback); } vault.getDirectoryProvider().delete(file); diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMultipartWriteFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMultipartWriteFeature.java index 4943f838a28..f5d6de84717 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMultipartWriteFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoMultipartWriteFeature.java @@ -16,18 +16,18 @@ */ import ch.cyberduck.core.Session; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.features.AttributesFinder; import ch.cyberduck.core.features.Find; import ch.cyberduck.core.features.MultipartWrite; import ch.cyberduck.core.features.Write; public class CryptoMultipartWriteFeature extends CryptoWriteFeature implements MultipartWrite { - public CryptoMultipartWriteFeature(final Session session, final Write delegate, final CryptoVault vault) { + public CryptoMultipartWriteFeature(final Session session, final Write delegate, final AbstractVault vault) { super(session, delegate, vault); } - public CryptoMultipartWriteFeature(final Session session, final Write delegate, final Find finder, final AttributesFinder attributes, final CryptoVault vault) { + public CryptoMultipartWriteFeature(final Session session, final Write delegate, final Find finder, final AttributesFinder attributes, final AbstractVault vault) { super(session, delegate, vault); } } diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoReadFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoReadFeature.java index ec8286a4624..45e499a7ed2 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoReadFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoReadFeature.java @@ -19,8 +19,8 @@ import ch.cyberduck.core.DefaultIOExceptionMappingService; import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.CryptoInputStream; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Read; import ch.cyberduck.core.transfer.TransferStatus; @@ -36,9 +36,9 @@ public class CryptoReadFeature implements Read { private final Session session; private final Read proxy; - private final CryptoVault vault; + private final AbstractVault vault; - public CryptoReadFeature(final Session session, final Read proxy, final CryptoVault vault) { + public CryptoReadFeature(final Session session, final Read proxy, final AbstractVault vault) { this.session = session; this.proxy = proxy; this.vault = vault; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoTimestampFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoTimestampFeature.java index 9db63f0ae3d..437a3c0697e 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoTimestampFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoTimestampFeature.java @@ -17,8 +17,8 @@ import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.CryptoTransferStatus; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Timestamp; import ch.cyberduck.core.transfer.TransferStatus; @@ -27,9 +27,9 @@ public class CryptoTimestampFeature implements Timestamp { private final Session session; private final Timestamp proxy; - private final CryptoVault vault; + private final AbstractVault vault; - public CryptoTimestampFeature(final Session session, final Timestamp proxy, final CryptoVault vault) { + public CryptoTimestampFeature(final Session session, final Timestamp proxy, final AbstractVault vault) { this.session = session; this.proxy = proxy; this.vault = vault; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoTouchFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoTouchFeature.java index e8864566a94..7a0493e49d3 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoTouchFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoTouchFeature.java @@ -19,7 +19,7 @@ import ch.cyberduck.core.Path; import ch.cyberduck.core.PathAttributes; import ch.cyberduck.core.Session; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.exception.InvalidFilenameException; @@ -35,9 +35,9 @@ public class CryptoTouchFeature implements Touch { private final Session session; private final Touch proxy; - private final CryptoVault vault; + private final AbstractVault vault; - public CryptoTouchFeature(final Session session, final Touch proxy, final CryptoVault cryptomator) { + public CryptoTouchFeature(final Session session, final Touch proxy, final AbstractVault cryptomator) { this.session = session; this.proxy = proxy; this.vault = cryptomator; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoUploadFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoUploadFeature.java index 2f2c1317338..4d65ed8745d 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoUploadFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoUploadFeature.java @@ -20,8 +20,8 @@ import ch.cyberduck.core.Path; import ch.cyberduck.core.ProgressListener; import ch.cyberduck.core.Session; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.CryptoTransferStatus; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.features.Upload; import ch.cyberduck.core.features.Write; @@ -33,9 +33,9 @@ public class CryptoUploadFeature implements Upload { private final Session session; private final Upload proxy; - private final CryptoVault vault; + private final AbstractVault vault; - public CryptoUploadFeature(final Session session, final Upload delegate, final CryptoVault vault) { + public CryptoUploadFeature(final Session session, final Upload delegate, final AbstractVault vault) { this.session = session; this.proxy = delegate; this.vault = vault; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoWriteFeature.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoWriteFeature.java index 7a8ea6f211b..7142146e0e1 100644 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoWriteFeature.java +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/features/CryptoWriteFeature.java @@ -19,9 +19,9 @@ import ch.cyberduck.core.DefaultIOExceptionMappingService; import ch.cyberduck.core.Path; import ch.cyberduck.core.Session; +import ch.cyberduck.core.cryptomator.AbstractVault; import ch.cyberduck.core.cryptomator.CryptoOutputStream; import ch.cyberduck.core.cryptomator.CryptoTransferStatus; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.cryptomator.random.RotatingNonceGenerator; import ch.cyberduck.core.exception.BackgroundException; @@ -42,9 +42,9 @@ public class CryptoWriteFeature implements Write { private final Session session; private final Write proxy; - private final CryptoVault vault; + private final AbstractVault vault; - public CryptoWriteFeature(final Session session, final Write proxy, final CryptoVault vault) { + public CryptoWriteFeature(final Session session, final Write proxy, final AbstractVault vault) { this.session = session; this.proxy = proxy; this.vault = vault; diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryUVFProvider.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryUVFProvider.java new file mode 100644 index 00000000000..4ea8fa352ee --- /dev/null +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryUVFProvider.java @@ -0,0 +1,77 @@ +package ch.cyberduck.core.cryptomator.impl; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.Path; +import ch.cyberduck.core.Session; +import ch.cyberduck.core.SimplePathPredicate; +import ch.cyberduck.core.cryptomator.AbstractVault; +import ch.cyberduck.core.cryptomator.ContentReader; +import ch.cyberduck.core.cryptomator.CryptoFilename; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.exception.NotfoundException; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.cryptomator.cryptolib.api.DirectoryMetadata; + +import java.util.EnumSet; + +public class CryptoDirectoryUVFProvider extends CryptoDirectoryV8Provider { + private static final Logger log = LogManager.getLogger(CryptoDirectoryUVFProvider.class); + + private final Path home; + private final AbstractVault vault; + private final CryptoFilename filenameProvider; + + public CryptoDirectoryUVFProvider(final AbstractVault vault, final CryptoFilename filenameProvider) { + super(vault, filenameProvider); + this.filenameProvider = filenameProvider; + this.home = vault.getHome(); + this.vault = vault; + } + + //TODO kann das auch ersetzt werden mit der impl der superklasse? hier wird load verwendet? nötig? + @Override + public String toEncrypted(final Session session, final Path parent, final String filename, final EnumSet type) throws BackgroundException { + final DirectoryMetadata dirMetadata = load(session, parent); + this.vault.getCryptor().directoryContentCryptor().fileNameEncryptor(dirMetadata).encrypt(filename); + final String ciphertextName = this.vault.getCryptor().directoryContentCryptor().fileNameEncryptor(dirMetadata).encrypt(filename) + vault.getRegularFileExtension(); + log.debug("Encrypted filename {} to {}", filename, ciphertextName); + return filenameProvider.deflate(session, ciphertextName); + } + + protected DirectoryMetadata load(final Session session, final Path directory) throws BackgroundException { + if(new SimplePathPredicate(home).test(directory)) { + return vault.getRootDirId(); + } + final Path parent = this.toEncrypted(session, directory.getParent()); + final String cleartextName = directory.getName(); + final String ciphertextName = this.toEncrypted(session, directory.getParent(), cleartextName, EnumSet.of(Path.Type.directory)); + final Path metadataParent = new Path(parent, ciphertextName, EnumSet.of(Path.Type.directory)); + // Read directory id from file + try { + log.debug("Read directory ID for folder {} from {}", directory, ciphertextName); + final Path metadataFile = new Path(metadataParent, vault.getDirectoryMetadataFilename(), EnumSet.of(Path.Type.file, Path.Type.encrypted)); + final byte[] ciphertext = new ContentReader(session).readBytes(metadataFile); + return this.vault.getCryptor().directoryContentCryptor().decryptDirectoryMetadata(ciphertext); + } + catch(NotfoundException e) { + log.warn("Missing directory ID for folder {}", directory); + return this.getOrCreateDirectoryId(session, directory); + } + } +} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV6Provider.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV6Provider.java deleted file mode 100644 index 13b1323fb98..00000000000 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV6Provider.java +++ /dev/null @@ -1,169 +0,0 @@ -package ch.cyberduck.core.cryptomator.impl; - -/* - * Copyright (c) 2002-2020 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.CacheReference; -import ch.cyberduck.core.Path; -import ch.cyberduck.core.PathAttributes; -import ch.cyberduck.core.RandomStringService; -import ch.cyberduck.core.Session; -import ch.cyberduck.core.SimplePathPredicate; -import ch.cyberduck.core.UUIDRandomStringService; -import ch.cyberduck.core.cache.LRUCache; -import ch.cyberduck.core.cryptomator.ContentReader; -import ch.cyberduck.core.cryptomator.CryptoDirectory; -import ch.cyberduck.core.cryptomator.CryptoVault; -import ch.cyberduck.core.cryptomator.CryptorCache; -import ch.cyberduck.core.exception.BackgroundException; -import ch.cyberduck.core.exception.NotfoundException; -import ch.cyberduck.core.preferences.PreferencesFactory; - -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.nio.charset.StandardCharsets; -import java.util.EnumSet; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -public class CryptoDirectoryV6Provider implements CryptoDirectory { - private static final Logger log = LogManager.getLogger(CryptoDirectoryV6Provider.class); - - private static final String DATA_DIR_NAME = "d"; - private static final String ROOT_DIR_ID = StringUtils.EMPTY; - - private final Path dataRoot; - private final Path home; - private final CryptoVault cryptomator; - - private final RandomStringService random - = new UUIDRandomStringService(); - - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private final LRUCache, String> cache = LRUCache.build( - PreferencesFactory.get().getInteger("cryptomator.cache.size")); - - public CryptoDirectoryV6Provider(final Path vault, final CryptoVault cryptomator) { - this.home = vault; - this.dataRoot = new Path(vault, DATA_DIR_NAME, vault.getType()); - this.cryptomator = cryptomator; - } - - @Override - public String toEncrypted(final Session session, final String directoryId, final String filename, final EnumSet type) throws BackgroundException { - final String prefix = type.contains(Path.Type.directory) ? CryptoVault.DIR_PREFIX : ""; - final String ciphertextName = prefix + cryptomator.getFileNameCryptor().encryptFilename(CryptorCache.BASE32, filename, directoryId.getBytes(StandardCharsets.UTF_8)); - log.debug("Encrypted filename {} to {}", filename, ciphertextName); - return cryptomator.getFilenameProvider().deflate(session, ciphertextName); - } - - @Override - public Path toEncrypted(final Session session, final String directoryId, final Path directory) throws BackgroundException { - if(!directory.isDirectory()) { - throw new NotfoundException(directory.getAbsolute()); - } - if(new SimplePathPredicate(directory).test(home) || directory.isChild(home)) { - final PathAttributes attributes = new PathAttributes(directory.attributes()); - // The root of the vault is a different target directory and file ids always correspond to the metadata file - attributes.setVersionId(null); - attributes.setFileId(null); - // Remember random directory id for use in vault - final String id = this.toDirectoryId(session, directory, directoryId); - log.debug("Use directory ID '{}' for folder {}", id, directory); - attributes.setDirectoryId(id); - attributes.setDecrypted(directory); - final String directoryIdHash = cryptomator.getFileNameCryptor().hashDirectoryId(id); - // Intermediate directory - final Path intermediate = new Path(dataRoot, directoryIdHash.substring(0, 2), dataRoot.getType()); - // Add encrypted type - final EnumSet type = EnumSet.copyOf(directory.getType()); - type.add(Path.Type.encrypted); - type.remove(Path.Type.decrypted); - return new Path(intermediate, directoryIdHash.substring(2), type, attributes); - } - throw new NotfoundException(directory.getAbsolute()); - } - - private String toDirectoryId(final Session session, final Path directory, final String directoryId) throws BackgroundException { - if(new SimplePathPredicate(home).test(directory)) { - return ROOT_DIR_ID; - } - try { - lock.readLock().lock(); - if(cache.contains(new SimplePathPredicate(directory))) { - final String existing = cache.get(new SimplePathPredicate(directory)); - if(StringUtils.isNotBlank(directoryId)) { - if(!existing.equals(directoryId)) { - log.warn("Do not override already cached id {} with {}", existing, directoryId); - } - } - return existing; - } - } - finally { - lock.readLock().unlock(); - } - try { - log.debug("Acquire lock for {}", directory); - lock.writeLock().lock(); - final String id = StringUtils.isBlank(directoryId) ? this.load(session, directory) : directoryId; - cache.put(new SimplePathPredicate(directory), id); - return id; - } - finally { - lock.writeLock().unlock(); - } - } - - protected String load(final Session session, final Path directory) throws BackgroundException { - final Path parent = this.toEncrypted(session, directory.getParent().attributes().getDirectoryId(), directory.getParent()); - final String cleartextName = directory.getName(); - final String ciphertextName = this.toEncrypted(session, parent.attributes().getDirectoryId(), cleartextName, EnumSet.of(Path.Type.directory)); - // Read directory id from file - try { - log.debug("Read directory ID for folder {} from {}", directory, ciphertextName); - final Path metadataFile = new Path(parent, ciphertextName, EnumSet.of(Path.Type.file, Path.Type.encrypted)); - return new ContentReader(session).read(metadataFile); - } - catch(NotfoundException e) { - log.warn("Missing directory ID for folder {}", directory); - return random.random(); - } - } - - public void delete(final Path directory) { - try { - lock.writeLock().lock(); - cache.remove(new SimplePathPredicate(directory)); - } - finally { - lock.writeLock().unlock(); - } - } - - @Override - public void destroy() { - try { - lock.writeLock().lock(); - cache.clear(); - } - finally { - lock.writeLock().unlock(); - } - } -} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV7Provider.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV7Provider.java deleted file mode 100644 index 28b4bb6211d..00000000000 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV7Provider.java +++ /dev/null @@ -1,78 +0,0 @@ -package ch.cyberduck.core.cryptomator.impl; - -/* - * Copyright (c) 2002-2020 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.Path; -import ch.cyberduck.core.RandomStringService; -import ch.cyberduck.core.Session; -import ch.cyberduck.core.UUIDRandomStringService; -import ch.cyberduck.core.cryptomator.ContentReader; -import ch.cyberduck.core.cryptomator.CryptoVault; -import ch.cyberduck.core.exception.BackgroundException; -import ch.cyberduck.core.exception.NotfoundException; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.nio.charset.StandardCharsets; -import java.util.EnumSet; - -import com.google.common.io.BaseEncoding; - -public class CryptoDirectoryV7Provider extends CryptoDirectoryV6Provider { - private static final Logger log = LogManager.getLogger(CryptoDirectoryV7Provider.class); - - public static final String EXTENSION_REGULAR = ".c9r"; - public static final String FILENAME_DIRECTORYID = "dir"; - public static final String DIRECTORY_METADATAFILE = String.format("%s%s", FILENAME_DIRECTORYID, EXTENSION_REGULAR); - public static final String BACKUP_FILENAME_DIRECTORYID = "dirid"; - public static final String BACKUP_DIRECTORY_METADATAFILE = String.format("%s%s", BACKUP_FILENAME_DIRECTORYID, EXTENSION_REGULAR); - - private final CryptoVault cryptomator; - - private final RandomStringService random - = new UUIDRandomStringService(); - - public CryptoDirectoryV7Provider(final Path vault, final CryptoVault cryptomator) { - super(vault, cryptomator); - this.cryptomator = cryptomator; - } - - @Override - public String toEncrypted(final Session session, final String directoryId, final String filename, final EnumSet type) throws BackgroundException { - final String ciphertextName = cryptomator.getFileNameCryptor().encryptFilename(BaseEncoding.base64Url(), - filename, directoryId.getBytes(StandardCharsets.UTF_8)) + EXTENSION_REGULAR; - log.debug("Encrypted filename {} to {}", filename, ciphertextName); - return cryptomator.getFilenameProvider().deflate(session, ciphertextName); - } - - protected String load(final Session session, final Path directory) throws BackgroundException { - final Path parent = this.toEncrypted(session, directory.getParent().attributes().getDirectoryId(), directory.getParent()); - final String cleartextName = directory.getName(); - final String ciphertextName = this.toEncrypted(session, parent.attributes().getDirectoryId(), cleartextName, EnumSet.of(Path.Type.directory)); - final Path metadataParent = new Path(parent, ciphertextName, EnumSet.of(Path.Type.directory)); - // Read directory id from file - try { - log.debug("Read directory ID for folder {} from {}", directory, ciphertextName); - final Path metadataFile = new Path(metadataParent, CryptoDirectoryV7Provider.DIRECTORY_METADATAFILE, EnumSet.of(Path.Type.file, Path.Type.encrypted)); - return new ContentReader(session).read(metadataFile); - } - catch(NotfoundException e) { - log.warn("Missing directory ID for folder {}", directory); - return random.random(); - } - } -} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV8Provider.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV8Provider.java new file mode 100644 index 00000000000..04faac5007b --- /dev/null +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV8Provider.java @@ -0,0 +1,195 @@ +package ch.cyberduck.core.cryptomator.impl; + +/* + * Copyright (c) 2002-2020 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.AbstractPath; +import ch.cyberduck.core.CacheReference; +import ch.cyberduck.core.Path; +import ch.cyberduck.core.PathAttributes; +import ch.cyberduck.core.RandomStringService; +import ch.cyberduck.core.Session; +import ch.cyberduck.core.SimplePathPredicate; +import ch.cyberduck.core.UUIDRandomStringService; +import ch.cyberduck.core.cache.LRUCache; +import ch.cyberduck.core.cryptomator.AbstractVault; +import ch.cyberduck.core.cryptomator.ContentReader; +import ch.cyberduck.core.cryptomator.CryptoDirectory; +import ch.cyberduck.core.cryptomator.CryptoFilename; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.exception.NotfoundException; +import ch.cyberduck.core.preferences.PreferencesFactory; + +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.cryptomator.cryptolib.api.DirectoryMetadata; + +import java.util.EnumSet; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class CryptoDirectoryV8Provider implements CryptoDirectory { + private static final Logger log = LogManager.getLogger(CryptoDirectoryV8Provider.class); + + private static final String DATA_DIR_NAME = "d"; + + private final AbstractVault vault; + private final Path dataRoot; + private final Path home; + private final CryptoFilename filenameProvider; + + private final RandomStringService random + = new UUIDRandomStringService(); + + protected final ReadWriteLock lock = new ReentrantReadWriteLock(); + protected final LRUCache, byte[]> cache = LRUCache.build( + PreferencesFactory.get().getInteger("cryptomator.cache.size")); + + + public CryptoDirectoryV8Provider(final AbstractVault vault, final CryptoFilename filenameProvider) { + this.home = vault.getHome(); + this.dataRoot = new Path(vault.getHome(), DATA_DIR_NAME, vault.getHome().getType()); + this.filenameProvider = filenameProvider; + this.vault = vault; + } + + @Override + public String toEncrypted(final Session session, final Path parent, final String filename, final EnumSet type) throws BackgroundException { + final DirectoryMetadata dirMetadata = this.getOrCreateDirectoryId(session, parent); + this.vault.getCryptor().directoryContentCryptor().fileNameEncryptor(dirMetadata).encrypt(filename); + final String ciphertextName = this.vault.getCryptor().directoryContentCryptor().fileNameEncryptor(dirMetadata).encrypt(filename); + log.debug("Encrypted filename {} to {}", filename, ciphertextName); + return filenameProvider.deflate(session, ciphertextName); + } + + @Override + public Path toEncrypted(final Session session, final Path directory) throws BackgroundException { + if(!directory.isDirectory()) { + throw new NotfoundException(directory.getAbsolute()); + } + if(new SimplePathPredicate(directory).test(home) || directory.isChild(home)) { + final PathAttributes attributes = new PathAttributes(directory.attributes()); + // The root of the vault is a different target directory and file ids always correspond to the metadata file + attributes.setVersionId(null); + attributes.setFileId(null); + // Remember random directory metadata for use in vault + final DirectoryMetadata dirMetadata = this.getOrCreateDirectoryId(session, directory); + log.debug("Use directory ID '{}' for folder {}", dirMetadata, directory); + attributes.setDirectoryId(this.vault.getCryptor().directoryContentCryptor().encryptDirectoryMetadata(dirMetadata)); + attributes.setDecrypted(directory); + final String dirPath = this.vault.getCryptor().directoryContentCryptor().dirPath(dirMetadata); + final String[] segments = StringUtils.split(dirPath, '/'); + // Intermediate directory + final Path intermediate = new Path(dataRoot, segments[1], dataRoot.getType()); + // Add encrypted type + final EnumSet type = EnumSet.copyOf(directory.getType()); + type.add(Path.Type.encrypted); + type.remove(Path.Type.decrypted); + return new Path(intermediate, segments[2], type, attributes); + } + throw new NotfoundException(directory.getAbsolute()); + } + + protected DirectoryMetadata toDirectoryId(final Session session, final Path directory) throws BackgroundException { + if(new SimplePathPredicate(home).test(directory)) { + return this.vault.getRootDirId(); + } + lock.readLock().lock(); + try { + if(cache.contains(new SimplePathPredicate(directory))) { + return this.vault.getCryptor().directoryContentCryptor().decryptDirectoryMetadata(cache.get(new SimplePathPredicate(directory))); + } + } + finally { + lock.readLock().unlock(); + } + try { + log.debug("Acquire lock for {}", directory); + lock.writeLock().lock(); + final DirectoryMetadata id = this.load(session, directory); + cache.put(new SimplePathPredicate(directory), this.vault.getCryptor().directoryContentCryptor().encryptDirectoryMetadata(id)); + return id; + } + finally { + lock.writeLock().unlock(); + } + } + + public void delete(final Path directory) { + lock.writeLock().lock(); + try { + cache.remove(new SimplePathPredicate(directory)); + } + finally { + lock.writeLock().unlock(); + } + } + + @Override + public void destroy() { + lock.writeLock().lock(); + try { + cache.clear(); + } + finally { + lock.writeLock().unlock(); + } + } + + @Override + public DirectoryMetadata getOrCreateDirectoryId(final Session session, final Path file) throws BackgroundException { + if(file.attributes().getDirectoryId() != null) { + return this.vault.getCryptor().directoryContentCryptor().decryptDirectoryMetadata(file.attributes().getDirectoryId()); + } + final Path decrypted = file.getType().contains(AbstractPath.Type.encrypted) ? file.attributes().getDecrypted() : file; + return this.toDirectoryId(session, decrypted.getType().contains(AbstractPath.Type.file) ? decrypted.getParent() : decrypted); + } + + @Override + public DirectoryMetadata createDirectoryId(final Path directory) { + lock.writeLock().lock(); + try { + final DirectoryMetadata metadata = vault.getCryptor().directoryContentCryptor().newDirectoryMetadata(); + final byte[] encrypted = vault.getCryptor().directoryContentCryptor().encryptDirectoryMetadata(metadata); + cache.put(new SimplePathPredicate(directory), encrypted); + return metadata; + } + finally { + lock.writeLock().unlock(); + } + } + + protected DirectoryMetadata load(final Session session, final Path directory) throws BackgroundException { + final Path encryptedParent = this.toEncrypted(session, directory.getParent()); + final String cleartextName = directory.getName(); + final String ciphertextName = this.toEncrypted(session, directory.getParent(), cleartextName, EnumSet.of(Path.Type.directory)); + final Path metadataParent = new Path(encryptedParent, ciphertextName, EnumSet.of(Path.Type.directory)); + // Read directory id from file + try { + log.debug("Read directory ID for folder {} from {}", directory, ciphertextName); + final Path metadataFile = new Path(metadataParent, vault.getDirectoryMetadataFilename(), EnumSet.of(Path.Type.file, Path.Type.encrypted)); + final byte[] bytes = new ContentReader(session).readBytes(metadataFile); + return this.vault.getCryptor().directoryContentCryptor().decryptDirectoryMetadata(bytes); + } + catch(NotfoundException e) { + log.warn("Missing directory ID for folder {}", directory); + return this.createDirectoryId(directory); + //TODO check if we need to propagtae exception instead? + // throw e; + + } + } +} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoFilenameV6Provider.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoFilenameV6Provider.java deleted file mode 100644 index 6cb8efa9160..00000000000 --- a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/CryptoFilenameV6Provider.java +++ /dev/null @@ -1,131 +0,0 @@ -package ch.cyberduck.core.cryptomator.impl; - -/* - * Copyright (c) 2002-2020 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.Path; -import ch.cyberduck.core.Session; -import ch.cyberduck.core.cache.LRUCache; -import ch.cyberduck.core.cryptomator.ContentReader; -import ch.cyberduck.core.cryptomator.ContentWriter; -import ch.cyberduck.core.cryptomator.CryptoFilename; -import ch.cyberduck.core.exception.BackgroundException; -import ch.cyberduck.core.features.Directory; -import ch.cyberduck.core.features.Find; -import ch.cyberduck.core.features.Write; -import ch.cyberduck.core.preferences.PreferencesFactory; -import ch.cyberduck.core.transfer.TransferStatus; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.cryptomator.cryptolib.common.MessageDigestSupplier; - -import java.util.EnumSet; - -import com.google.common.io.BaseEncoding; - -import static java.nio.charset.StandardCharsets.UTF_8; - -public class CryptoFilenameV6Provider implements CryptoFilename { - private static final Logger log = LogManager.getLogger(CryptoFilenameV6Provider.class); - - private static final BaseEncoding BASE32 = BaseEncoding.base32(); - private static final String LONG_NAME_FILE_EXT = ".lng"; - private static final String METADATA_DIR_NAME = "m"; - - public static final int DEFAULT_NAME_SHORTENING_THRESHOLD = 130; - - private final int shorteningThreshold; - private final Path metadataRoot; - - private final LRUCache cache = LRUCache.build( - PreferencesFactory.get().getLong("cryptomator.cache.size")); - - public CryptoFilenameV6Provider(final Path vault) { - this(vault, DEFAULT_NAME_SHORTENING_THRESHOLD); - } - - public CryptoFilenameV6Provider(final Path vault, final int shorteningThreshold) { - this.metadataRoot = new Path(vault, METADATA_DIR_NAME, vault.getType()); - this.shorteningThreshold = shorteningThreshold; - } - - @Override - public boolean isDeflated(final String filename) { - return filename.endsWith(LONG_NAME_FILE_EXT); - } - - @Override - public boolean isValid(final String filename) { - return true; - } - - @Override - public String inflate(final Session session, final String shortName) throws BackgroundException { - return new ContentReader(session).read(this.resolve(shortName)); - } - - @Override - public String deflate(final Session session, final String filename) throws BackgroundException { - if(filename.length() < shorteningThreshold) { - return filename; - } - if(cache.contains(filename)) { - return cache.get(filename); - } - final byte[] longFileNameBytes = filename.getBytes(UTF_8); - final byte[] hash = MessageDigestSupplier.SHA1.get().digest(longFileNameBytes); - final String shortName = BASE32.encode(hash) + LONG_NAME_FILE_EXT; - final Path metadataFile = this.resolve(shortName); - final Path secondLevel = metadataFile.getParent(); - final Path firstLevel = secondLevel.getParent(); - final Directory mkdir = session._getFeature(Directory.class); - final Find find = session._getFeature(Find.class); - if(!find.find(metadataRoot)) { - mkdir.mkdir(session._getFeature(Write.class), metadataRoot, new TransferStatus()); - } - if(!find.find(firstLevel)) { - mkdir.mkdir(session._getFeature(Write.class), firstLevel, new TransferStatus()); - } - if(!find.find(secondLevel)) { - mkdir.mkdir(session._getFeature(Write.class), secondLevel, new TransferStatus()); - } - if(!find.find(metadataFile)) { - new ContentWriter(session).write(metadataFile, longFileNameBytes); - } - log.info("Deflated {} to {}", filename, shortName); - cache.put(filename, shortName); - return shortName; - } - - @Override - public Path resolve(final String filename) { - // Intermediate directory - final Path first = new Path(metadataRoot, filename.substring(0, 2), metadataRoot.getType()); - // Intermediate directory - final Path second = new Path(first, filename.substring(2, 4), metadataRoot.getType()); - return new Path(second, filename, EnumSet.of(Path.Type.file, Path.Type.encrypted, Path.Type.vault)); - } - - @Override - public void invalidate(final String filename) { - cache.remove(filename); - } - - @Override - public void destroy() { - cache.clear(); - } -} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/uvf/CryptoVault.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/uvf/CryptoVault.java new file mode 100644 index 00000000000..a3428fcea57 --- /dev/null +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/uvf/CryptoVault.java @@ -0,0 +1,291 @@ +package ch.cyberduck.core.cryptomator.impl.uvf; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.LocaleFactory; +import ch.cyberduck.core.LoginOptions; +import ch.cyberduck.core.PasswordCallback; +import ch.cyberduck.core.Path; +import ch.cyberduck.core.PathAttributes; +import ch.cyberduck.core.Session; +import ch.cyberduck.core.SimplePathPredicate; +import ch.cyberduck.core.cryptomator.AbstractVault; +import ch.cyberduck.core.cryptomator.CryptoDirectory; +import ch.cyberduck.core.cryptomator.CryptoFilename; +import ch.cyberduck.core.cryptomator.features.CryptoDirectoryUVFFeature; +import ch.cyberduck.core.cryptomator.impl.CryptoDirectoryUVFProvider; +import ch.cyberduck.core.cryptomator.impl.CryptoFilenameV7Provider; +import ch.cyberduck.core.cryptomator.random.FastSecureRandomProvider; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.features.Directory; +import ch.cyberduck.core.features.Vault; +import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.cryptomator.cryptolib.api.Cryptor; +import org.cryptomator.cryptolib.api.CryptorProvider; +import org.cryptomator.cryptolib.api.DirectoryMetadata; +import org.cryptomator.cryptolib.api.FileContentCryptor; +import org.cryptomator.cryptolib.api.FileHeaderCryptor; +import org.cryptomator.cryptolib.api.RevolvingMasterkey; +import org.cryptomator.cryptolib.api.UVFMasterkey; + +import java.text.MessageFormat; +import java.util.EnumSet; +import java.util.Objects; +import java.util.regex.Pattern; + +import com.google.auto.service.AutoService; + +@AutoService(Vault.class) +public class CryptoVault extends AbstractVault { + private static final Logger log = LogManager.getLogger(CryptoVault.class); + + private static final String REGULAR_FILE_EXTENSION = ".uvf"; + private static final String FILENAME_DIRECTORYID = "dir"; + private static final String DIRECTORY_METADATA_FILENAME = String.format("%s%s", FILENAME_DIRECTORYID, REGULAR_FILE_EXTENSION); + private static final String BACKUP_FILENAME_DIRECTORYID = "dirid"; + private static final String BACKUP_DIRECTORY_METADATA_FILENAME = String.format("%s%s", BACKUP_FILENAME_DIRECTORYID, REGULAR_FILE_EXTENSION); + + private static final Pattern FILENAME_PATTERN = Pattern.compile("^([A-Za-z0-9_=-]+)" + REGULAR_FILE_EXTENSION); + + /** + * Root of vault directory + */ + private final Path home; + + private RevolvingMasterkey masterKey; + + private Cryptor cryptor; + private CryptoFilename filenameProvider; + private CryptoDirectory directoryProvider; + + private int nonceSize; + + public CryptoVault(final Path home) { + this.home = home; + } + + @Override + public AbstractVault create(final Session session, final String region, final VaultCredentials credentials) throws BackgroundException { + throw new UnsupportedOperationException(); + } + + // load -> unlock -> open + @Override + public CryptoVault load(final Session session, final PasswordCallback prompt) throws BackgroundException { + masterKey = UVFMasterkey.fromDecryptedPayload(prompt.prompt(session.getHost(), + LocaleFactory.localizedString("Unlock Vault", "Cryptomator"), + MessageFormat.format(LocaleFactory.localizedString("Provide your passphrase to unlock the Cryptomator Vault {0}", "Cryptomator"), home.getName()), + new LoginOptions() + .save(false) + .user(false) + .anonymous(false) + .icon("cryptomator.tiff") + .passwordPlaceholder(LocaleFactory.localizedString("Passphrase", "Cryptomator"))).getPassword()); + final CryptorProvider provider = CryptorProvider.forScheme(CryptorProvider.Scheme.UVF_DRAFT); + log.debug("Initialized crypto provider {}", provider); + this.cryptor = provider.provide(masterKey, FastSecureRandomProvider.get().provide()); + this.filenameProvider = new CryptoFilenameV7Provider(Integer.MAX_VALUE); + this.directoryProvider = new CryptoDirectoryUVFProvider(this, filenameProvider); + this.nonceSize = 12; + return this; + } + + @Override + public Path encrypt(Session session, Path file, boolean metadata) throws BackgroundException { + final Path encrypted; + if(file.isFile() || metadata) { + if(file.getType().contains(Path.Type.vault)) { + log.warn("Skip file {} because it is marked as an internal vault path", file); + return file; + } + if(new SimplePathPredicate(file).test(this.getHome())) { + log.warn("Skip vault home {} because the root has no metadata file", file); + return file; + } + final Path parent; + final String filename; + if(file.getType().contains(Path.Type.encrypted)) { + final Path decrypted = file.attributes().getDecrypted(); + parent = this.getDirectoryProvider().toEncrypted(session, decrypted.getParent()); + filename = this.getDirectoryProvider().toEncrypted(session, decrypted.getParent(), decrypted.getName(), decrypted.getType()); + } + else { + parent = this.getDirectoryProvider().toEncrypted(session, file.getParent()); + // / diff to AbstractVault.encrypt + filename = this.getDirectoryProvider().toEncrypted(session, file.getParent(), file.getName(), file.getType()); + // \ diff to AbstractVault.decrypt + } + final PathAttributes attributes = new PathAttributes(file.attributes()); + if(!file.isFile() && !metadata) { + // The directory is different from the metadata file used to resolve the actual folder + attributes.setVersionId(null); + attributes.setFileId(null); + } + // Translate file size + attributes.setSize(this.toCiphertextSize(0L, file.attributes().getSize())); + final EnumSet type = EnumSet.copyOf(file.getType()); + type.remove(Path.Type.decrypted); + type.add(Path.Type.encrypted); + encrypted = new Path(parent, filename, type, attributes); + } + else { + if(file.getType().contains(Path.Type.encrypted)) { + log.warn("Skip file {} because it is already marked as an encrypted path", file); + return file; + } + if(file.getType().contains(Path.Type.vault)) { + return this.getDirectoryProvider().toEncrypted(session, this.getHome()); + } + encrypted = this.getDirectoryProvider().toEncrypted(session, file); + } + // Add reference to decrypted file + if(!file.getType().contains(Path.Type.encrypted)) { + encrypted.attributes().setDecrypted(file); + } + // Add reference for vault + file.attributes().setVaultMetadata(this.getMetadata()); + encrypted.attributes().setVaultMetadata(this.getMetadata()); + return encrypted; + } + + @Override + public synchronized void close() { + super.close(); + cryptor.destroy(); + } + + @Override + public Path getMasterkeyPath() { + //TODO: implement + return null; + } + + @Override + public RevolvingMasterkey getMasterkey() { + return masterKey; + } + + @Override + public Path getConfig() { + //TODO: implement + return null; + } + + @Override + public Path getHome() { + return home; + } + + @Override + public FileHeaderCryptor getFileHeaderCryptor() { + return cryptor.fileHeaderCryptor(); + } + + @Override + public FileContentCryptor getFileContentCryptor() { + return cryptor.fileContentCryptor(); + } + + @Override + public CryptoFilename getFilenameProvider() { + return filenameProvider; + } + + @Override + public CryptoDirectory getDirectoryProvider() { + return directoryProvider; + } + + @Override + public Cryptor getCryptor() { + return cryptor; + } + + @Override + public int getNonceSize() { + return nonceSize; + } + + @Override + public Pattern getFilenamePattern() { + return FILENAME_PATTERN; + } + + @Override + public String getRegularFileExtension() { + return REGULAR_FILE_EXTENSION; + } + + @Override + public String getDirectoryMetadataFilename() { + return DIRECTORY_METADATA_FILENAME; + } + + @Override + public String getBackupDirectoryMetadataFilename() { + return BACKUP_DIRECTORY_METADATA_FILENAME; + } + + public DirectoryMetadata getRootDirId() { + return this.cryptor.directoryContentCryptor().rootDirectoryMetadata(); + } + + @Override + public VaultMetadata getMetadata() { + return new VaultMetadata(this.getHome(), VaultMetadata.Type.UVF); + } + + @Override + public T getFeature(final Session session, final Class type, final T delegate) { + + if(type == Directory.class) { + return (T) new CryptoDirectoryUVFFeature(session, (Directory) delegate, this + ); + } + + return super.getFeature(session, type, delegate); + } + + @Override + public boolean equals(final Object o) { + if(this == o) { + return true; + } + if(!(o instanceof CryptoVault)) { + return false; + } + final CryptoVault that = (CryptoVault) o; + return new SimplePathPredicate(home).test(that.home); + } + + @Override + public int hashCode() { + return Objects.hash(new SimplePathPredicate(home)); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("UVFVault{"); + sb.append("home=").append(home); + sb.append(", cryptor=").append(cryptor); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/v8/CryptoVault.java b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/v8/CryptoVault.java new file mode 100644 index 00000000000..9a9e0c1a2ce --- /dev/null +++ b/cryptomator/src/main/java/ch/cyberduck/core/cryptomator/impl/v8/CryptoVault.java @@ -0,0 +1,514 @@ +package ch.cyberduck.core.cryptomator.impl.v8; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.Credentials; +import ch.cyberduck.core.DescriptiveUrl; +import ch.cyberduck.core.Host; +import ch.cyberduck.core.LocaleFactory; +import ch.cyberduck.core.LoginOptions; +import ch.cyberduck.core.PasswordCallback; +import ch.cyberduck.core.PasswordStore; +import ch.cyberduck.core.PasswordStoreFactory; +import ch.cyberduck.core.Path; +import ch.cyberduck.core.Session; +import ch.cyberduck.core.SimplePathPredicate; +import ch.cyberduck.core.UUIDRandomStringService; +import ch.cyberduck.core.cryptomator.AbstractVault; +import ch.cyberduck.core.cryptomator.ContentReader; +import ch.cyberduck.core.cryptomator.ContentWriter; +import ch.cyberduck.core.cryptomator.CryptoAuthenticationException; +import ch.cyberduck.core.cryptomator.CryptoDirectory; +import ch.cyberduck.core.cryptomator.CryptoFilename; +import ch.cyberduck.core.cryptomator.impl.CryptoDirectoryV8Provider; +import ch.cyberduck.core.cryptomator.impl.CryptoFilenameV7Provider; +import ch.cyberduck.core.cryptomator.random.FastSecureRandomProvider; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.exception.LocalAccessDeniedException; +import ch.cyberduck.core.exception.LoginCanceledException; +import ch.cyberduck.core.exception.NotfoundException; +import ch.cyberduck.core.features.Directory; +import ch.cyberduck.core.features.Encryption; +import ch.cyberduck.core.features.Vault; +import ch.cyberduck.core.features.Write; +import ch.cyberduck.core.preferences.Preferences; +import ch.cyberduck.core.preferences.PreferencesFactory; +import ch.cyberduck.core.shared.DefaultUrlProvider; +import ch.cyberduck.core.transfer.TransferStatus; +import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultException; +import ch.cyberduck.core.vault.VaultMetadata; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.cryptomator.cryptolib.api.Cryptor; +import org.cryptomator.cryptolib.api.CryptorProvider; +import org.cryptomator.cryptolib.api.DirectoryMetadata; +import org.cryptomator.cryptolib.api.FileContentCryptor; +import org.cryptomator.cryptolib.api.FileHeaderCryptor; +import org.cryptomator.cryptolib.api.InvalidPassphraseException; +import org.cryptomator.cryptolib.api.Masterkey; +import org.cryptomator.cryptolib.api.PerpetualMasterkey; +import org.cryptomator.cryptolib.common.MasterkeyFile; +import org.cryptomator.cryptolib.common.MasterkeyFileAccess; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Objects; +import java.util.regex.Pattern; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.InvalidClaimException; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.exceptions.SignatureVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.google.auto.service.AutoService; +import com.google.gson.JsonParseException; + +@AutoService(Vault.class) +public class CryptoVault extends AbstractVault { + + private static final Logger log = LogManager.getLogger(CryptoVault.class); + + + public static final String REGULAR_FILE_EXTENSION = ".c9r"; + public static final int VAULT_VERSION = 8; + + private static final String FILENAME_DIRECTORYID = "dir"; + private static final String DIRECTORY_METADATA_FILENAME = String.format("%s%s", FILENAME_DIRECTORYID, REGULAR_FILE_EXTENSION); + private static final String BACKUP_FILENAME_DIRECTORYID = "dirid"; + private static final String BACKUP_DIRECTORY_METADATA_FILENAME = String.format("%s%s", BACKUP_FILENAME_DIRECTORYID, REGULAR_FILE_EXTENSION); + private static final Pattern FILENAME_PATTERN = Pattern.compile("^([A-Za-z0-9_=-]+)" + REGULAR_FILE_EXTENSION); + + private static final List SUPPORTED_VERSIONS = Arrays.asList(7, 8); + + private static final String JSON_KEY_VAULTVERSION = "format"; + private static final String JSON_KEY_CIPHERCONFIG = "cipherCombo"; + private static final String JSON_KEY_SHORTENING_THRESHOLD = "shorteningThreshold"; + + private final Path home; + private Masterkey masterkey; + private final Path masterkeyPath; + private final byte[] pepper; + + private final PasswordStore keychain = PasswordStoreFactory.get(); + private final Preferences preferences = PreferencesFactory.get(); + + private final Path config; + + private int nonceSize; + private Cryptor cryptor; + + private CryptoFilename filenameProvider; + private CryptoDirectory directoryProvider; + + public CryptoVault(final Path home) { + this.home = home; + this.masterkeyPath = new Path(home, preferences.getProperty("cryptomator.vault.masterkey.filename"), EnumSet.of(Path.Type.file, Path.Type.vault)); + this.config = new Path(home, preferences.getProperty("cryptomator.vault.config.filename"), EnumSet.of(Path.Type.file, Path.Type.vault)); + this.pepper = preferences.getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8); + + //TODO nötig? + // New vault home with vault flag set for internal use + final EnumSet type = EnumSet.copyOf(home.getType()); + type.add(Path.Type.vault); + } + + public Path getHome() { + return home; + } + + @Override + public Path getMasterkeyPath() { + return masterkeyPath; + } + + public Masterkey getMasterkey() { + return masterkey; + } + + @Override + public Path getConfig() { + return config; + } + + @Override + public FileHeaderCryptor getFileHeaderCryptor() { + return cryptor.fileHeaderCryptor(); + } + + @Override + public FileContentCryptor getFileContentCryptor() { + return cryptor.fileContentCryptor(); + } + + @Override + public CryptoFilename getFilenameProvider() { + return filenameProvider; + } + + @Override + public CryptoDirectory getDirectoryProvider() { + return directoryProvider; + } + + @Override + public Cryptor getCryptor() { + return cryptor; + } + + @Override + public int getNonceSize() { + return nonceSize; + } + + @Override + public String getRegularFileExtension() { + return REGULAR_FILE_EXTENSION; + } + + @Override + public String getDirectoryMetadataFilename() { + return DIRECTORY_METADATA_FILENAME; + } + + @Override + public String getBackupDirectoryMetadataFilename() { + return BACKUP_DIRECTORY_METADATA_FILENAME; + } + + @Override + public DirectoryMetadata getRootDirId() { + return this.cryptor.directoryContentCryptor().rootDirectoryMetadata(); + } + + @Override + public Pattern getFilenamePattern() { + return FILENAME_PATTERN; + } + + @Override + public synchronized AbstractVault create(final Session session, final String region, final VaultCredentials credentials) throws BackgroundException { + final Host bookmark = session.getHost(); + if(credentials.isSaved()) { + try { + keychain.addPassword(String.format("Cryptomator Passphrase (%s)", bookmark.getCredentials().getUsername()), + new DefaultUrlProvider(bookmark).toUrl(masterkeyPath, EnumSet.of(DescriptiveUrl.Type.provider)).find(DescriptiveUrl.Type.provider).getUrl(), credentials.getPassword()); + } + catch(LocalAccessDeniedException e) { + log.error("Failure {} saving credentials for {} in password store", e, bookmark); + } + } + final String passphrase = credentials.getPassword(); + final ByteArrayOutputStream mkArray = new ByteArrayOutputStream(); + final PerpetualMasterkey mk = Masterkey.generate(FastSecureRandomProvider.get().provide()); + final MasterkeyFileAccess access = new MasterkeyFileAccess(pepper, FastSecureRandomProvider.get().provide()); + final MasterkeyFile masterkeyFile; + try { + access.persist(mk, mkArray, passphrase, VAULT_VERSION); + masterkeyFile = MasterkeyFile.read(new StringReader(new String(mkArray.toByteArray(), StandardCharsets.UTF_8))); + } + catch(IOException e) { + throw new VaultException("Failure creating master key", e); + } + log.debug("Write master key to {}", masterkeyPath); + // Obtain non encrypted directory writer + final Directory directory = session._getFeature(Directory.class); + final TransferStatus status = new TransferStatus().setRegion(region); + final Encryption encryption = session._getFeature(Encryption.class); + if(encryption != null) { + status.setEncryption(encryption.getDefault(home)); + } + final Path vault = directory.mkdir(session._getFeature(Write.class), home, status); + new ContentWriter(session).write(masterkeyPath, mkArray.toByteArray()); + // Create vaultconfig.cryptomator + final Algorithm algorithm = Algorithm.HMAC256(mk.getEncoded()); + final String conf = JWT.create() + .withJWTId(new UUIDRandomStringService().random()) + .withKeyId(String.format("masterkeyfile:%s", masterkeyPath.getName())) + .withClaim(JSON_KEY_VAULTVERSION, VAULT_VERSION) + .withClaim(JSON_KEY_CIPHERCONFIG, CryptorProvider.Scheme.SIV_GCM.toString()) + .withClaim(JSON_KEY_SHORTENING_THRESHOLD, CryptoFilenameV7Provider.DEFAULT_NAME_SHORTENING_THRESHOLD) + .sign(algorithm); + new ContentWriter(session).write(config, conf.getBytes(StandardCharsets.US_ASCII)); + this.open(parseVaultConfigFromJWT(conf).withMasterkeyFile(masterkeyFile), passphrase); + final Path secondLevel = directoryProvider.toEncrypted(session, home); + final Path firstLevel = secondLevel.getParent(); + final Path dataDir = firstLevel.getParent(); + log.debug("Create vault root directory at {}", secondLevel); + directory.mkdir(session._getFeature(Write.class), dataDir, status); + directory.mkdir(session._getFeature(Write.class), firstLevel, status); + directory.mkdir(session._getFeature(Write.class), secondLevel, status); + return this; + } + + private static VaultConfig parseVaultConfigFromMasterKey(final MasterkeyFile masterkeyFile) { + return new VaultConfig(masterkeyFile.version, CryptoFilenameV7Provider.DEFAULT_NAME_SHORTENING_THRESHOLD, + CryptorProvider.Scheme.SIV_CTRMAC, null, null); + } + + @Override + public Vault load(final Session session, final PasswordCallback prompt) throws BackgroundException { + final Host bookmark = session.getHost(); + String passphrase = keychain.getPassword(String.format("Cryptomator Passphrase (%s)", bookmark.getCredentials().getUsername()), + new DefaultUrlProvider(bookmark).toUrl(masterkeyPath, EnumSet.of(DescriptiveUrl.Type.provider)).find(DescriptiveUrl.Type.provider).getUrl()); + if(null == passphrase) { + // Legacy + passphrase = keychain.getPassword(String.format("Cryptomator Passphrase %s", bookmark.getHostname()), + new DefaultUrlProvider(bookmark).toUrl(masterkeyPath, EnumSet.of(DescriptiveUrl.Type.provider)).find(DescriptiveUrl.Type.provider).getUrl()); + } + return this.unlock(session, prompt, bookmark, passphrase); + } + + public Vault unlock(final Session session, final PasswordCallback prompt, final Host bookmark, final String passphrase) throws BackgroundException { + final ch.cyberduck.core.cryptomator.impl.v8.CryptoVault.VaultConfig vaultConfig = this.readVaultConfig(session); + this.unlock(vaultConfig, passphrase, bookmark, prompt, + MessageFormat.format(LocaleFactory.localizedString("Provide your passphrase to unlock the Cryptomator Vault {0}", "Cryptomator"), home.getName()) + ); + return this; + } + + public void unlock(final ch.cyberduck.core.cryptomator.impl.v8.CryptoVault.VaultConfig vaultConfig, final String passphrase, final Host bookmark, final PasswordCallback prompt, + final String message) throws BackgroundException { + final Credentials credentials; + if(null == passphrase) { + credentials = prompt.prompt( + bookmark, LocaleFactory.localizedString("Unlock Vault", "Cryptomator"), + message, + new LoginOptions() + .save(preferences.getBoolean("cryptomator.vault.keychain")) + .user(false) + .anonymous(false) + .icon("cryptomator.tiff") + .passwordPlaceholder(LocaleFactory.localizedString("Passphrase", "Cryptomator"))); + if(null == credentials.getPassword()) { + throw new LoginCanceledException(); + } + } + else { + credentials = new VaultCredentials(passphrase).withSaved(false); + } + try { + this.open(vaultConfig, credentials.getPassword()); + if(credentials.isSaved()) { + log.info("Save passphrase for {}", masterkeyPath); + // Save password with hostname and path to masterkey.cryptomator in keychain + keychain.addPassword(String.format("Cryptomator Passphrase (%s)", bookmark.getCredentials().getUsername()), + new DefaultUrlProvider(bookmark).toUrl(masterkeyPath, EnumSet.of(DescriptiveUrl.Type.provider)).find(DescriptiveUrl.Type.provider).getUrl(), credentials.getPassword()); + } + } + catch(CryptoAuthenticationException e) { + this.unlock(vaultConfig, null, bookmark, prompt, String.format("%s %s.", e.getDetail(), + MessageFormat.format(LocaleFactory.localizedString("Provide your passphrase to unlock the Cryptomator Vault {0}", "Cryptomator"), home.getName()))); + } + } + + private ch.cyberduck.core.cryptomator.impl.v8.CryptoVault.VaultConfig readVaultConfig(final Session session) throws BackgroundException { + final MasterkeyFile masterkeyFile = this.readMasterkeyFile(session, masterkeyPath); + try { + return parseVaultConfigFromJWT(new ContentReader(session).read(config)).withMasterkeyFile(masterkeyFile); + } + catch(NotfoundException e) { + log.debug("Ignore failure reading vault configuration {}", config); + return parseVaultConfigFromMasterKey(masterkeyFile).withMasterkeyFile(masterkeyFile); + } + } + + public static ch.cyberduck.core.cryptomator.impl.v8.CryptoVault.VaultConfig parseVaultConfigFromJWT(final String token) { + final DecodedJWT decoded = JWT.decode(token); + return new ch.cyberduck.core.cryptomator.impl.v8.CryptoVault.VaultConfig( + decoded.getClaim(JSON_KEY_VAULTVERSION).asInt(), + decoded.getClaim(JSON_KEY_SHORTENING_THRESHOLD).asInt(), + CryptorProvider.Scheme.valueOf(decoded.getClaim(JSON_KEY_CIPHERCONFIG).asString()), + decoded.getAlgorithm(), decoded); + } + + private MasterkeyFile readMasterkeyFile(final Session session, final Path file) throws BackgroundException { + log.debug("Read master key {}", file); + try(Reader reader = new ContentReader(session).getReader(file)) { + return MasterkeyFile.read(reader); + } + catch(JsonParseException | IllegalArgumentException | IllegalStateException | IOException e) { + throw new VaultException(String.format("Failure reading vault master key file %s", file.getName()), e); + } + } + + protected void open(final ch.cyberduck.core.cryptomator.impl.v8.CryptoVault.VaultConfig vaultConfig, final CharSequence passphrase) throws BackgroundException { + try { + final PerpetualMasterkey masterKey = this.getMasterKey(vaultConfig.getMkfile(), passphrase); + this.open(vaultConfig, masterKey); + } + catch(IllegalArgumentException | IOException e) { + throw new VaultException("Failure reading key file", e); + } + catch(InvalidPassphraseException e) { + throw new CryptoAuthenticationException("Failure to decrypt master key file", e); + } + } + + protected void open(final ch.cyberduck.core.cryptomator.impl.v8.CryptoVault.VaultConfig vaultConfig, final PerpetualMasterkey masterKey) throws BackgroundException { + if(!SUPPORTED_VERSIONS.contains(vaultConfig.vaultVersion())) { + throw new VaultException(String.format("Unsupported vault version %d", vaultConfig.vaultVersion())); + } + final CryptorProvider provider = CryptorProvider.forScheme(vaultConfig.getCipherCombo()); + log.debug("Initialized crypto provider {}", provider); + vaultConfig.verify(masterKey.getEncoded(), VAULT_VERSION); + this.masterkey = masterKey; + this.cryptor = provider.provide(masterKey, FastSecureRandomProvider.get().provide()); + this.filenameProvider = new CryptoFilenameV7Provider(vaultConfig.getShorteningThreshold()); + this.directoryProvider = new CryptoDirectoryV8Provider(this, this.filenameProvider); + this.nonceSize = vaultConfig.getNonceSize(); + } + + private PerpetualMasterkey getMasterKey(final MasterkeyFile mkFile, final CharSequence passphrase) throws IOException { + final StringWriter writer = new StringWriter(); + mkFile.write(writer); + return new MasterkeyFileAccess(pepper, FastSecureRandomProvider.get().provide()).load( + new ByteArrayInputStream(writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8)), passphrase); + } + + @Override + public VaultMetadata getMetadata() { + return new VaultMetadata(this.getHome(), VaultMetadata.Type.V8); + } + + @Override + public synchronized void close() { + super.close(); + cryptor = null; + } + + public static class VaultConfig { + + private final int version; + private final int shorteningThreshold; + private final CryptorProvider.Scheme cipherCombo; + private final String algorithm; + private final DecodedJWT token; + private MasterkeyFile mkfile; + + public VaultConfig(int version, int shorteningThreshold, CryptorProvider.Scheme cipherCombo, String algorithm, DecodedJWT token) { + this.version = version; + this.shorteningThreshold = shorteningThreshold; + this.cipherCombo = cipherCombo; + this.algorithm = algorithm; + this.token = token; + } + + public int vaultVersion() { + return version; + } + + public VaultConfig withMasterkeyFile(final MasterkeyFile mkfile) { + this.mkfile = mkfile; + return this; + } + + public MasterkeyFile getMkfile() { + return mkfile; + } + + public int getShorteningThreshold() { + return shorteningThreshold; + } + + public CryptorProvider.Scheme getCipherCombo() { + return cipherCombo; + } + + public int getNonceSize() throws VaultException { + switch(cipherCombo) { + case SIV_CTRMAC: + return 16; + case SIV_GCM: + return 12; + default: + throw new VaultException(String.format("Unsupported cipher scheme %s", cipherCombo)); + } + } + + private Algorithm initAlgorithm(byte[] rawKey) throws VaultException { + switch(algorithm) { + case "HS256": + return Algorithm.HMAC256(rawKey); + case "HS384": + return Algorithm.HMAC384(rawKey); + case "HS512": + return Algorithm.HMAC512(rawKey); + default: + throw new VaultException(String.format("Unsupported signature algorithm %s", algorithm)); + } + } + + public void verify(byte[] rawKey, int expectedVaultVersion) throws VaultException { + try { + if(token == null) { + return; + } + JWTVerifier verifier = JWT.require(initAlgorithm(rawKey)) + .withClaim(JSON_KEY_VAULTVERSION, expectedVaultVersion) + .build(); + verifier.verify(token); + } + catch(SignatureVerificationException e) { + throw new VaultException("Invalid JWT signature", e); + } + catch(InvalidClaimException e) { + throw new VaultException(String.format("Expected vault config for version %d", expectedVaultVersion), e); + } + catch(JWTVerificationException e) { + throw new VaultException(String.format("Failed to verify vault config %s", token), e); + } + } + } + + @Override + public boolean equals(final Object o) { + if(this == o) { + return true; + } + if(!(o instanceof CryptoVault)) { + return false; + } + final CryptoVault that = (CryptoVault) o; + return new SimplePathPredicate(home).test(that.home); + } + + @Override + public int hashCode() { + return Objects.hash(new SimplePathPredicate(home)); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("CryptoVault{"); + sb.append("home=").append(home); + sb.append(", cryptor=").append(cryptor); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoChecksumComputeTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoChecksumComputeTest.java index a539352f90f..4935d094072 100644 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoChecksumComputeTest.java +++ b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoChecksumComputeTest.java @@ -20,6 +20,7 @@ import ch.cyberduck.core.Path; import ch.cyberduck.core.TestProtocol; import ch.cyberduck.core.cryptomator.features.CryptoChecksumCompute; +import ch.cyberduck.core.cryptomator.impl.v8.CryptoVault; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.features.Directory; import ch.cyberduck.core.features.Write; @@ -61,7 +62,6 @@ public Path mkdir(final Write writer, final Path folder, final TransferStatus st cryptomator.create(session, null, new VaultCredentials("test")); final ByteBuffer header = cryptomator.getFileHeaderCryptor().encryptHeader(cryptomator.getFileHeaderCryptor().create()); // DEFAULT_PIPE_SIZE=1024 - final Path file = new Path(vault, "f", EnumSet.of(Path.Type.file)); final SHA256ChecksumCompute sha = new SHA256ChecksumCompute(); final CryptoChecksumCompute compute = new CryptoChecksumCompute(sha, cryptomator); final RandomNonceGenerator nonces = new RandomNonceGenerator(cryptomator.getNonceSize()); diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoOutputStreamTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoOutputStreamTest.java index eff5c2e279a..a5f848ade45 100644 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoOutputStreamTest.java +++ b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoOutputStreamTest.java @@ -19,6 +19,7 @@ import ch.cyberduck.core.NullSession; import ch.cyberduck.core.Path; import ch.cyberduck.core.TestProtocol; +import ch.cyberduck.core.cryptomator.impl.v8.CryptoVault; import ch.cyberduck.core.cryptomator.random.RandomNonceGenerator; import ch.cyberduck.core.features.Directory; import ch.cyberduck.core.features.Write; diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoWriteFeatureTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoWriteFeatureTest.java index ecacf7650c8..3c2d81679a3 100644 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoWriteFeatureTest.java +++ b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoWriteFeatureTest.java @@ -19,6 +19,7 @@ import ch.cyberduck.core.NullSession; import ch.cyberduck.core.Path; import ch.cyberduck.core.TestProtocol; +import ch.cyberduck.core.cryptomator.impl.v8.CryptoVault; import ch.cyberduck.core.features.Directory; import ch.cyberduck.core.features.Write; import ch.cyberduck.core.transfer.TransferStatus; @@ -33,43 +34,6 @@ public class CryptoWriteFeatureTest { - @Test - public void testCiphertextSize_CTR() throws Exception { - final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); - final NullSession session = new NullSession(new Host(new TestProtocol())) { - @Override - @SuppressWarnings("unchecked") - public T _getFeature(final Class type) { - if(type == Directory.class) { - return (T) new Directory() { - - @Override - public Path mkdir(final Write writer, final Path folder, final TransferStatus status) { - assertTrue(folder.equals(home) || folder.isChild(home)); - return folder; - } - }; - } - return super._getFeature(type); - } - }; - final CryptoVault vault = new CryptoVault(home); - vault.create(session, null, new VaultCredentials("test"), CryptoVault.VAULT_VERSION_DEPRECATED); - int headerSize = vault.getFileHeaderCryptor().headerSize(); - // zero file size - assertEquals(headerSize, vault.toCiphertextSize(0L, 0)); - // one-byte file - assertEquals(headerSize + 48 + 1, vault.toCiphertextSize(0L, 1)); - // file with chunk size length - assertEquals(headerSize + vault.getFileContentCryptor().ciphertextChunkSize(), vault.toCiphertextSize(0L, vault.getFileContentCryptor().cleartextChunkSize())); - // file with chunk size length + 1 - assertEquals(headerSize + vault.getFileContentCryptor().ciphertextChunkSize() + 48 + 1, vault.toCiphertextSize(0L, vault.getFileContentCryptor().cleartextChunkSize() + 1)); - // file with 2 * chunk size length - assertEquals(headerSize + 2 * vault.getFileContentCryptor().ciphertextChunkSize(), vault.toCiphertextSize(0L, 2 * vault.getFileContentCryptor().cleartextChunkSize())); - // file with 2 * chunk size length + 100 - assertEquals(headerSize + 2 * vault.getFileContentCryptor().ciphertextChunkSize() + 48 + 100, vault.toCiphertextSize(0L, 2 * vault.getFileContentCryptor().cleartextChunkSize() + 100)); - } - @Test public void testCiphertextSize_GCM() throws Exception { final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); @@ -91,7 +55,7 @@ public Path mkdir(final Write writer, final Path folder, final TransferStatus st } }; final CryptoVault vault = new CryptoVault(home); - vault.create(session, null, new VaultCredentials("test"), CryptoVault.VAULT_VERSION); + vault.create(session, null, new VaultCredentials("test")); int headerSize = vault.getFileHeaderCryptor().headerSize(); // zero file size assertEquals(headerSize, vault.toCiphertextSize(0L, 0)); diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptorCacheTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptorCacheTest.java index f88038fc29e..94deb11d3d5 100644 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptorCacheTest.java +++ b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptorCacheTest.java @@ -19,10 +19,11 @@ import org.cryptomator.cryptolib.api.FileNameCryptor; import org.junit.Test; +import java.nio.charset.StandardCharsets; + import com.google.common.io.BaseEncoding; import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; public class CryptorCacheTest { @@ -31,10 +32,10 @@ public class CryptorCacheTest { public void TestHashDirectoryId() { final FileNameCryptor mock = mock(FileNameCryptor.class); final CryptorCache cryptor = new CryptorCache(mock); - when(mock.hashDirectoryId(anyString())).thenReturn("hashed"); - assertEquals("hashed", cryptor.hashDirectoryId("id")); - assertEquals("hashed", cryptor.hashDirectoryId("id")); - verify(mock, times(1)).hashDirectoryId(anyString()); + when(mock.hashDirectoryId(any(byte[].class))).thenReturn("hashed"); + assertEquals("hashed", cryptor.hashDirectoryId("id".getBytes(StandardCharsets.US_ASCII))); + assertEquals("hashed", cryptor.hashDirectoryId("id".getBytes(StandardCharsets.US_ASCII))); + verify(mock, times(1)).hashDirectoryId(any(byte[].class)); verifyNoMoreInteractions(mock); } diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/features/CryptoBulkFeatureTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/features/CryptoBulkFeatureTest.java index 2bde499b600..bcc398e2bd5 100644 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/features/CryptoBulkFeatureTest.java +++ b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/features/CryptoBulkFeatureTest.java @@ -22,7 +22,7 @@ import ch.cyberduck.core.NullSession; import ch.cyberduck.core.Path; import ch.cyberduck.core.TestProtocol; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.impl.v8.CryptoVault; import ch.cyberduck.core.features.Bulk; import ch.cyberduck.core.features.Directory; import ch.cyberduck.core.features.Write; @@ -88,7 +88,7 @@ public boolean test(final TransferItem item) { return item.remote.isDirectory(); } }).findFirst().get().remote; - final String directoryId = encryptedDirectory.attributes().getDirectoryId(); + final byte[] directoryId = encryptedDirectory.attributes().getDirectoryId(); assertNotNull(directoryId); for(TransferItem file : pre.keySet().stream().filter(new Predicate() { @Override diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/features/CryptoReadFeatureTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/features/CryptoReadFeatureTest.java index b0f53977c41..d87e329fdd8 100644 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/features/CryptoReadFeatureTest.java +++ b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/features/CryptoReadFeatureTest.java @@ -23,7 +23,7 @@ import ch.cyberduck.core.NullSession; import ch.cyberduck.core.Path; import ch.cyberduck.core.TestProtocol; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.impl.v8.CryptoVault; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.exception.NotfoundException; import ch.cyberduck.core.features.Read; @@ -38,12 +38,12 @@ import java.nio.charset.Charset; import java.util.EnumSet; -import static ch.cyberduck.core.cryptomator.CryptoVault.VAULT_VERSION; -import static ch.cyberduck.core.cryptomator.CryptoVaultTest.createJWT; +import static ch.cyberduck.core.cryptomator.impl.v8.CryptoVaultTest.createJWT; import static org.junit.Assert.assertEquals; public class CryptoReadFeatureTest { + //TODO prüfen, ob CTR in 7 vorkommen kann. oder nur GCM @Test public void testCalculations_CTR() throws Exception { final NullSession session = new NullSession(new Host(new TestProtocol())) { @@ -61,7 +61,7 @@ public InputStream read(final Path file, final TransferStatus status, final Conn " \"primaryMasterKey\": \"Q7pGo1l0jmZssoQh9rXFPKJE9NIXvPbL+HcnVSR9CHdkeR8AwgFtcw==\",\n" + " \"hmacMasterKey\": \"xzBqT4/7uEcQbhHFLC0YmMy4ykVKbuvJEA46p1Xm25mJNuTc20nCbw==\",\n" + " \"versionMac\": \"hlNr3dz/CmuVajhaiGyCem9lcVIUjDfSMLhjppcXOrM=\",\n" + - " \"version\": 6\n" + + " \"version\": 7\n" + "}"; if("masterkey.cryptomator".equals(file.getName())) { return IOUtils.toInputStream(masterKey, Charset.defaultCharset()); @@ -141,7 +141,7 @@ public InputStream read(final Path file, final TransferStatus status, final Conn return IOUtils.toInputStream(masterKey, Charset.defaultCharset()); } if("vault.cryptomator".equals(file.getName())) { - return IOUtils.toInputStream(createJWT(masterKey, VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault"), Charset.defaultCharset()); + return IOUtils.toInputStream(createJWT(masterKey, CryptoVault.VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault"), Charset.defaultCharset()); } throw new NotfoundException(String.format("%s not found", file.getName())); } diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV6ProviderTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV6ProviderTest.java deleted file mode 100644 index a2f78fa324e..00000000000 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV6ProviderTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package ch.cyberduck.core.cryptomator.impl; - -/* - * Copyright (c) 2002-2020 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.ConnectionCallback; -import ch.cyberduck.core.Credentials; -import ch.cyberduck.core.DisabledPasswordCallback; -import ch.cyberduck.core.Host; -import ch.cyberduck.core.LoginOptions; -import ch.cyberduck.core.NullSession; -import ch.cyberduck.core.Path; -import ch.cyberduck.core.TestProtocol; -import ch.cyberduck.core.cryptomator.CryptoDirectory; -import ch.cyberduck.core.cryptomator.CryptoVault; -import ch.cyberduck.core.exception.BackgroundException; -import ch.cyberduck.core.exception.NotfoundException; -import ch.cyberduck.core.features.Read; -import ch.cyberduck.core.transfer.TransferStatus; -import ch.cyberduck.core.vault.VaultCredentials; - -import org.apache.commons.io.IOUtils; -import org.junit.Test; - -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.EnumSet; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class CryptoDirectoryV6ProviderTest { - - @Test(expected = NotfoundException.class) - public void testToEncryptedInvalidArgument() throws Exception { - final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); - final CryptoVault vault = new CryptoVault(home); - final CryptoDirectory provider = new CryptoDirectoryV6Provider(home, vault); - provider.toEncrypted(new NullSession(new Host(new TestProtocol())), null, new Path("/vault/f", EnumSet.of(Path.Type.file))); - } - - @Test(expected = NotfoundException.class) - public void testToEncryptedInvalidPath() throws Exception { - final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); - final CryptoVault vault = new CryptoVault(home); - final CryptoDirectory provider = new CryptoDirectoryV6Provider(home, vault); - provider.toEncrypted(new NullSession(new Host(new TestProtocol())), null, new Path("/", EnumSet.of(Path.Type.directory))); - } - - @Test - public void testToEncryptedDirectory() throws Exception { - final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); - final NullSession session = new NullSession(new Host(new TestProtocol())) { - @Override - @SuppressWarnings("unchecked") - public T _getFeature(final Class type) { - if(type == Read.class) { - return (T) new Read() { - @Override - public InputStream read(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException { - final String masterKey = "{\n" + - " \"scryptSalt\": \"NrC7QGG/ouc=\",\n" + - " \"scryptCostParam\": 16384,\n" + - " \"scryptBlockSize\": 8,\n" + - " \"primaryMasterKey\": \"Q7pGo1l0jmZssoQh9rXFPKJE9NIXvPbL+HcnVSR9CHdkeR8AwgFtcw==\",\n" + - " \"hmacMasterKey\": \"xzBqT4/7uEcQbhHFLC0YmMy4ykVKbuvJEA46p1Xm25mJNuTc20nCbw==\",\n" + - " \"versionMac\": \"hlNr3dz/CmuVajhaiGyCem9lcVIUjDfSMLhjppcXOrM=\",\n" + - " \"version\": 5\n" + - "}"; - if("masterkey.cryptomator".equals(file.getName())) { - return IOUtils.toInputStream(masterKey, Charset.defaultCharset()); - } - throw new NotfoundException(String.format("%s not found", file.getName())); - } - - @Override - public boolean offset(final Path file) { - return false; - } - }; - } - return super._getFeature(type); - } - }; - final CryptoVault vault = new CryptoVault(home); - vault.load(session, new DisabledPasswordCallback() { - @Override - public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { - return new VaultCredentials("vault"); - } - }); - final CryptoDirectory provider = new CryptoDirectoryV6Provider(home, vault); - assertNotNull(provider.toEncrypted(session, null, home)); - final Path f = new Path("/vault/f", EnumSet.of(Path.Type.directory)); - assertNotNull(provider.toEncrypted(session, null, f)); - assertEquals(provider.toEncrypted(session, null, f), provider.toEncrypted(session, null, f)); - } -} diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV7ProviderTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV8ProviderTest.java similarity index 61% rename from cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV7ProviderTest.java rename to cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV8ProviderTest.java index ee372bed4d0..866d98a1a0f 100644 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV7ProviderTest.java +++ b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/CryptoDirectoryV8ProviderTest.java @@ -24,7 +24,8 @@ import ch.cyberduck.core.Path; import ch.cyberduck.core.TestProtocol; import ch.cyberduck.core.cryptomator.CryptoDirectory; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.impl.v8.CryptoVault; +import ch.cyberduck.core.cryptomator.impl.v8.CryptoVaultTest; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.exception.NotfoundException; import ch.cyberduck.core.features.Read; @@ -37,34 +38,36 @@ import java.io.InputStream; import java.nio.charset.Charset; +import java.security.SecureRandom; import java.util.EnumSet; -import static ch.cyberduck.core.cryptomator.CryptoVault.VAULT_VERSION; -import static ch.cyberduck.core.cryptomator.CryptoVaultTest.createJWT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -public class CryptoDirectoryV7ProviderTest { +public class CryptoDirectoryV8ProviderTest { @Test(expected = NotfoundException.class) public void testToEncryptedInvalidArgument() throws Exception { final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); - final CryptoVault vault = new CryptoVault(home); - final CryptoDirectory provider = new CryptoDirectoryV7Provider(home, vault); - provider.toEncrypted(new NullSession(new Host(new TestProtocol())), null, new Path("/vault/f", EnumSet.of(Path.Type.file))); + final CryptorProvider crypto = CryptorProvider.forScheme(CryptorProvider.Scheme.SIV_GCM); + final SecureRandom random = new SecureRandom(); + final NullSession session = new NullSession(new Host(new TestProtocol())); + final CryptoDirectory provider = new CryptoDirectoryV8Provider(new CryptoVault(home), new CryptoFilenameV7Provider()); + provider.toEncrypted(session, new Path("/vault/f", EnumSet.of(Path.Type.file))); } @Test(expected = NotfoundException.class) public void testToEncryptedInvalidPath() throws Exception { final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); - final CryptoVault vault = new CryptoVault(home); - final CryptoDirectory provider = new CryptoDirectoryV7Provider(home, vault); - provider.toEncrypted(new NullSession(new Host(new TestProtocol())), null, new Path("/", EnumSet.of(Path.Type.directory))); + final CryptorProvider crypto = CryptorProvider.forScheme(CryptorProvider.Scheme.SIV_GCM); + final SecureRandom random = new SecureRandom(); + final NullSession session = new NullSession(new Host(new TestProtocol())); + final CryptoDirectory provider = new CryptoDirectoryV8Provider(new CryptoVault(home), new CryptoFilenameV7Provider()); + provider.toEncrypted(session, new Path("/", EnumSet.of(Path.Type.directory))); } @Test public void testToEncryptedDirectory() throws Exception { - final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); final NullSession session = new NullSession(new Host(new TestProtocol())) { @Override @SuppressWarnings("unchecked") @@ -74,19 +77,20 @@ public T _getFeature(final Class type) { @Override public InputStream read(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException { final String masterKey = "{\n" + - " \"scryptSalt\": \"NrC7QGG/ouc=\",\n" + - " \"scryptCostParam\": 16384,\n" + + " \"version\": 8,\n" + + " \"scryptSalt\": \"RVAAirkArDU=\",\n" + + " \"scryptCostParam\": 32768,\n" + " \"scryptBlockSize\": 8,\n" + - " \"primaryMasterKey\": \"Q7pGo1l0jmZssoQh9rXFPKJE9NIXvPbL+HcnVSR9CHdkeR8AwgFtcw==\",\n" + - " \"hmacMasterKey\": \"xzBqT4/7uEcQbhHFLC0YmMy4ykVKbuvJEA46p1Xm25mJNuTc20nCbw==\",\n" + - " \"versionMac\": \"hlNr3dz/CmuVajhaiGyCem9lcVIUjDfSMLhjppcXOrM=\",\n" + - " \"version\": 8\n" + + " \"primaryMasterKey\": \"+03NkJNWVsJ9Tb1CTpKhXyfINzjDirFFI+iJLOWIOySyxB+abpx34Q==\",\n" + + " \"hmacMasterKey\": \"aMoDtn7Y6kIXxyHo2zl47p5jCYTlRnfx3l3AMgULmIDSYAxVAraSgg==\",\n" + + " \"versionMac\": \"FzirA8UhwCmS5RsC4JvxbO+ZBxaCbIkzqD2Ocagd+A8=\"\n" + "}"; + if("masterkey.cryptomator".equals(file.getName())) { return IOUtils.toInputStream(masterKey, Charset.defaultCharset()); } if("vault.cryptomator".equals(file.getName())) { - return IOUtils.toInputStream(createJWT(masterKey, VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault"), Charset.defaultCharset()); + return IOUtils.toInputStream(CryptoVaultTest.createJWT(masterKey, CryptoVault.VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); } throw new NotfoundException(String.format("%s not found", file.getName())); } @@ -100,17 +104,18 @@ public boolean offset(final Path file) { return super._getFeature(type); } }; + final Path home = new Path("/vault", EnumSet.of((Path.Type.directory))); final CryptoVault vault = new CryptoVault(home); vault.load(session, new DisabledPasswordCallback() { @Override public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { - return new VaultCredentials("vault"); + return new VaultCredentials("vault123"); } }); - final CryptoDirectory provider = new CryptoDirectoryV7Provider(home, vault); - assertNotNull(provider.toEncrypted(session, null, home)); + final CryptoDirectory provider = new CryptoDirectoryV8Provider(vault, new CryptoFilenameV7Provider()); + assertNotNull(provider.toEncrypted(session, home)); final Path f = new Path("/vault/f", EnumSet.of(Path.Type.directory)); - assertNotNull(provider.toEncrypted(session, null, f)); - assertEquals(provider.toEncrypted(session, null, f), provider.toEncrypted(session, null, f)); + assertNotNull(provider.toEncrypted(session, f)); + assertEquals(provider.toEncrypted(session, f), provider.toEncrypted(session, f)); } } diff --git a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoVaultTest.java b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/v8/CryptoVaultTest.java similarity index 89% rename from cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoVaultTest.java rename to cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/v8/CryptoVaultTest.java index 0a9361a6de7..494dbf8b510 100644 --- a/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/CryptoVaultTest.java +++ b/cryptomator/src/test/java/ch/cyberduck/core/cryptomator/impl/v8/CryptoVaultTest.java @@ -1,7 +1,7 @@ -package ch.cyberduck.core.cryptomator; +package ch.cyberduck.core.cryptomator.impl.v8; /* - * Copyright (c) 2002-2020 iterate GmbH. All rights reserved. + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. * https://cyberduck.io/ * * This program is free software; you can redistribute it and/or modify @@ -25,6 +25,7 @@ import ch.cyberduck.core.SerializerFactory; import ch.cyberduck.core.TestProtocol; import ch.cyberduck.core.UUIDRandomStringService; +import ch.cyberduck.core.cryptomator.CryptoInvalidFilesizeException; import ch.cyberduck.core.cryptomator.impl.CryptoFilenameV7Provider; import ch.cyberduck.core.cryptomator.random.FastSecureRandomProvider; import ch.cyberduck.core.exception.BackgroundException; @@ -39,10 +40,11 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import org.apache.commons.io.IOUtils; import org.cryptomator.cryptolib.api.CryptorProvider; -import org.cryptomator.cryptolib.api.Masterkey; +import org.cryptomator.cryptolib.api.PerpetualMasterkey; import org.cryptomator.cryptolib.common.MasterkeyFile; import org.cryptomator.cryptolib.common.MasterkeyFileAccess; import org.junit.Test; @@ -60,7 +62,6 @@ import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; -import static ch.cyberduck.core.cryptomator.CryptoVault.VAULT_VERSION; import static org.junit.Assert.*; public class CryptoVaultTest { @@ -89,7 +90,7 @@ public InputStream read(final Path file, final TransferStatus status, final Conn return IOUtils.toInputStream(masterKey, Charset.defaultCharset()); } if("vault.cryptomator".equals(file.getName())) { - return IOUtils.toInputStream(createJWT(masterKey, VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); + return IOUtils.toInputStream(createJWT(masterKey, CryptoVault.VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); } throw new NotfoundException(String.format("%s not found", file.getName())); } @@ -118,8 +119,10 @@ public Credentials prompt(final Host bookmark, final String title, final String assertEquals(vault.encrypt(session, home), vault.encrypt(session, home)); final Path directory = new Path(home, "dir", EnumSet.of(Path.Type.directory)); assertNull(directory.attributes().getVault()); - assertEquals(home, vault.encrypt(session, directory).attributes().getVault()); - assertEquals(home, directory.attributes().getVault()); + assertEquals(home, vault.encrypt(session, directory).attributes().getVaultMetadata().root); + assertEquals(VaultMetadata.Type.V8, vault.encrypt(session, directory).attributes().getVaultMetadata().type); + assertEquals(home, directory.attributes().getVaultMetadata().root); + assertEquals(VaultMetadata.Type.V8, directory.attributes().getVaultMetadata().type); assertEquals(vault.encrypt(session, directory), vault.encrypt(session, directory)); assertEquals(new Path(home, directory.getName(), EnumSet.of(Path.Type.directory, Path.Type.decrypted)), vault.decrypt(session, vault.encrypt(session, directory, true))); final Path placeholder = new Path(home, "placeholder", EnumSet.of(Path.Type.directory, Path.Type.placeholder)); @@ -171,7 +174,7 @@ public InputStream read(final Path file, final TransferStatus status, final Conn return IOUtils.toInputStream(masterKey, Charset.defaultCharset()); } if("vault.cryptomator".equals(file.getName())) { - return IOUtils.toInputStream(createJWT(masterKey, VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); + return IOUtils.toInputStream(createJWT(masterKey, CryptoVault.VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); } throw new NotfoundException(String.format("%s not found", file.getName())); } @@ -222,7 +225,7 @@ public InputStream read(final Path file, final TransferStatus status, final Conn return IOUtils.toInputStream(masterKey, Charset.defaultCharset()); } if("vault.cryptomator".equals(file.getName())) { - return IOUtils.toInputStream(createJWT(masterKey, VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); + return IOUtils.toInputStream(createJWT(masterKey, CryptoVault.VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); } throw new NotfoundException(String.format("%s not found", file.getName())); } @@ -272,7 +275,7 @@ public InputStream read(final Path file, final TransferStatus status, final Conn return IOUtils.toInputStream(masterKey, Charset.defaultCharset()); } if("vault.cryptomator".equals(file.getName())) { - return IOUtils.toInputStream(createJWT(masterKey, VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); + return IOUtils.toInputStream(createJWT(masterKey, CryptoVault.VAULT_VERSION, CryptorProvider.Scheme.SIV_GCM, "vault123"), Charset.defaultCharset()); } throw new NotfoundException(String.format("%s not found", file.getName())); } @@ -433,51 +436,6 @@ public Path mkdir(final Write writer, final Path folder, final TransferStatus st vault.create(session, null, new VaultCredentials("test")); } - @Test - public void testCleartextSizeV6() throws Exception { - final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); - final NullSession session = new NullSession(new Host(new TestProtocol())) { - @Override - @SuppressWarnings("unchecked") - public T _getFeature(final Class type) { - if(type == Directory.class) { - return (T) new Directory() { - - @Override - public Path mkdir(final Write writer, final Path folder, final TransferStatus status) { - assertTrue(folder.equals(home) || folder.isChild(home)); - return folder; - } - }; - } - return super._getFeature(type); - } - }; - final CryptoVault vault = new CryptoVault( - home); - vault.create(session, null, new VaultCredentials("test"), 6); - // zero ciphertextFileSize - try { - vault.toCleartextSize(0L, 0); - fail(); - } - catch(CryptoInvalidFilesizeException e) { - } - // ciphertextFileSize == headerSize - assertEquals(0L, vault.toCleartextSize(0L, vault.getFileHeaderCryptor().headerSize())); - // ciphertextFileSize == headerSize + 1 - try { - vault.toCleartextSize(0L, vault.toCleartextSize(0L, vault.getFileHeaderCryptor().headerSize()) + 1); - fail(); - } - catch(CryptoInvalidFilesizeException e) { - } - // ciphertextFileSize == headerSize + chunkHeaderSize + 1 - assertEquals(1L, vault.toCleartextSize(0L, vault.getFileHeaderCryptor().headerSize() + 48 + 1)); - // ciphertextFileSize == headerSize + (32768 + chunkHeaderSize) + (1 + chunkHeaderSize) + 1 - assertEquals(32769L, vault.toCleartextSize(0L, vault.getFileHeaderCryptor().headerSize() + (32768 + 48) + (1 + 48))); - } - @Test public void testCleartextSizeV8() throws Exception { final Path home = new Path("/vault", EnumSet.of(Path.Type.directory)); @@ -498,8 +456,7 @@ public Path mkdir(final Write writer, final Path folder, final TransferStatus st return super._getFeature(type); } }; - final CryptoVault vault = new CryptoVault( - home); + final CryptoVault vault = new CryptoVault(home); vault.create(session, null, new VaultCredentials("test")); // zero ciphertextFileSize try { @@ -548,8 +505,7 @@ public boolean isSupported(final Path workdir, final String name) { return super._getFeature(type); } }; - final CryptoVault vault = new CryptoVault( - home); + final CryptoVault vault = new CryptoVault(home); vault.create(session, null, new VaultCredentials("test")); for(int i = 0; i < 26000000; i++) { assertEquals(i, vault.toCleartextSize(0L, vault.toCiphertextSize(0L, i))); @@ -564,7 +520,7 @@ public static String createJWT(final String masterkeyCryptomator, final MasterkeyFile mkFile = MasterkeyFile.read(new StringReader(masterkeyCryptomator)); final StringWriter writer = new StringWriter(); mkFile.write(writer); - final Masterkey masterkey = new MasterkeyFileAccess(PreferencesFactory.get().getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8), + final PerpetualMasterkey masterkey = new MasterkeyFileAccess(PreferencesFactory.get().getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8), FastSecureRandomProvider.get().provide()).load(new ByteArrayInputStream(writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8)), passphrase); final Algorithm algorithm = Algorithm.HMAC256(masterkey.getEncoded()); return JWT.create() diff --git a/ctera/pom.xml b/ctera/pom.xml index 249b2e6f7db..89a386c51c4 100644 --- a/ctera/pom.xml +++ b/ctera/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT ctera jar diff --git a/deepbox/pom.xml b/deepbox/pom.xml index 1d7dd42f32d..8d9df7170c9 100644 --- a/deepbox/pom.xml +++ b/deepbox/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT deepbox diff --git a/defaults/pom.xml b/defaults/pom.xml index c27c855ec83..0cf1e56d401 100644 --- a/defaults/pom.xml +++ b/defaults/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT defaults diff --git a/defaults/src/main/resources/default.properties b/defaults/src/main/resources/default.properties index 710dec5d6d8..926ca6c5b80 100644 --- a/defaults/src/main/resources/default.properties +++ b/defaults/src/main/resources/default.properties @@ -703,13 +703,14 @@ terminal.command.ssh=ssh -t {0} {1}@{2} -p {3} \"cd {4} && exec \\$SHELL -l\" threading.pool.size.max=20 threading.pool.keepalive.seconds=60 cryptomator.enable=true -cryptomator.vault.version=8 +cryptomator.vault.default=v8 cryptomator.vault.autodetect=true cryptomator.vault.autodetect.filecount=10 # Load and add to registry when vault is referenced in file attributes cryptomator.vault.autoload=true cryptomator.vault.masterkey.filename=masterkey.cryptomator cryptomator.vault.config.filename=vault.cryptomator +cryptomator.vault.config.filename.uvf=vault.uvf cryptomator.vault.pepper= cryptomator.vault.skip.regex=dirid.c9r cryptomator.cache.size=1000 diff --git a/defaults/src/main/resources/default/log4j.xml b/defaults/src/main/resources/default/log4j.xml index a02f90d3f10..ce4787cd17e 100644 --- a/defaults/src/main/resources/default/log4j.xml +++ b/defaults/src/main/resources/default/log4j.xml @@ -1,11 +1,11 @@ - + + + - - + + + diff --git a/dracoon/pom.xml b/dracoon/pom.xml index a3e4aec8bfc..516c68d76a1 100644 --- a/dracoon/pom.xml +++ b/dracoon/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT dracoon diff --git a/dropbox/pom.xml b/dropbox/pom.xml index 40bf3f4ffbf..0e1fe38d080 100644 --- a/dropbox/pom.xml +++ b/dropbox/pom.xml @@ -18,7 +18,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT 4.0.0 dropbox diff --git a/dropbox/src/test/java/ch/cyberduck/core/AbstractDropboxTest.java b/dropbox/src/test/java/ch/cyberduck/core/AbstractDropboxTest.java index 361a6586246..552af6ebe8c 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/AbstractDropboxTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/AbstractDropboxTest.java @@ -15,12 +15,12 @@ * GNU General Public License for more details. */ -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.dropbox.DropboxProtocol; import ch.cyberduck.core.dropbox.DropboxSession; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -38,11 +38,11 @@ public class AbstractDropboxTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index 84f25f9340d..1060e833a55 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -46,12 +46,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -66,7 +68,6 @@ import com.dropbox.core.v2.files.Metadata; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -78,8 +79,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -104,8 +105,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -121,16 +122,17 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { new DeleteWorker(new DisabledLoginCallback(), Collections.singletonList(vault), new DisabledProgressListener()).run(session); } + //TODO @Test + @Ignore(value = "Filename shortening not yet implemented") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -152,8 +154,8 @@ public void testCopyFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( @@ -187,8 +189,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new DropboxFindFeature(session).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( @@ -213,8 +215,8 @@ public void testCopyDirectoryIntoVault() throws Exception { new DropboxTouchFeature(session).touch(new DropboxWriteFeature(session), cleartextFile, new TransferStatus()); assertTrue(new DropboxFindFeature(session).find(cleartextFolder)); assertTrue(new DropboxFindFeature(session).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -238,8 +240,8 @@ public void testCopyFileOutsideVault() throws Exception { new DropboxDirectoryFeature(session).mkdir(new DropboxWriteFeature(session), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( @@ -264,8 +266,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( diff --git a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/CryptoDropboxSingleTransferWorkerTest.java b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/CryptoDropboxSingleTransferWorkerTest.java index ac5582d36aa..b91cc053ab9 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/CryptoDropboxSingleTransferWorkerTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/CryptoDropboxSingleTransferWorkerTest.java @@ -50,6 +50,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -91,8 +92,8 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { diff --git a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxDirectoryFeatureTest.java b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxDirectoryFeatureTest.java index 3b6fa9869fd..f322ba2ef5d 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxDirectoryFeatureTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxDirectoryFeatureTest.java @@ -35,8 +35,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -47,7 +49,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -57,8 +58,8 @@ public class DropboxDirectoryFeatureTest extends AbstractDropboxTest { public void testMakeDirectoryEncrypted() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new DropboxWriteFeature(session)), new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); @@ -69,13 +70,13 @@ public void testMakeDirectoryEncrypted() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new DropboxWriteFeature(session)), test, new TransferStatus()); diff --git a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxListServiceTest.java b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxListServiceTest.java index ef2ce97f56a..46d80a19ac0 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxListServiceTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxListServiceTest.java @@ -33,6 +33,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -56,8 +57,8 @@ public class DropboxListServiceTest extends AbstractDropboxTest { public void testListCryptomator() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertTrue(new CryptoListService(session, new DropboxListService(session), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature( diff --git a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxMoveFeatureTest.java b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxMoveFeatureTest.java index d40ecf497ab..d5efcce3615 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxMoveFeatureTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxMoveFeatureTest.java @@ -39,6 +39,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -64,8 +65,8 @@ public void testMove() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new DropboxWriteFeature(session)), folder, new TransferStatus()); diff --git a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxTouchFeatureTest.java b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxTouchFeatureTest.java index 1c7bfd7cc38..99bf044b0e9 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxTouchFeatureTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxTouchFeatureTest.java @@ -35,8 +35,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -49,19 +51,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) public class DropboxTouchFeatureTest extends AbstractDropboxTest { + //TODO @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -74,12 +76,12 @@ public void testTouchLongFilenameEncrypted() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( diff --git a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxWriteFeatureTest.java b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxWriteFeatureTest.java index 13545619d4c..bb942fd195b 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxWriteFeatureTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/DropboxWriteFeatureTest.java @@ -40,6 +40,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -72,8 +73,8 @@ public void testWrite() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new DropboxWriteFeature(session), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); diff --git a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java index 47f1208e211..e71563b8795 100644 --- a/dropbox/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java +++ b/dropbox/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java @@ -42,9 +42,11 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.MoveWorker; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -55,7 +57,6 @@ import java.util.EnumSet; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -67,8 +68,8 @@ public void testMoveSameFolderCryptomator() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DropboxTouchFeature(session), cryptomator).touch( new CryptoWriteFeature<>(session, new DropboxWriteFeature(session), cryptomator), source, new TransferStatus()); @@ -87,8 +88,8 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DropboxTouchFeature(session), cryptomator).touch( new CryptoWriteFeature<>(session, new DropboxWriteFeature(session), cryptomator), source, new TransferStatus()); @@ -103,16 +104,17 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { cryptomator.getFeature(session, Delete.class, new DropboxDeleteFeature(session)).delete(Arrays.asList(target, targetFolder, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); } + //TODO @Test + @Ignore(value = "Filename shortening not yet implemented") public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DropboxTouchFeature(session), cryptomator).touch( new CryptoWriteFeature<>(session, new DropboxWriteFeature(session), cryptomator), source, new TransferStatus()); @@ -133,8 +135,8 @@ public void testMoveFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new DropboxWriteFeature(session)), folder, new TransferStatus()); @@ -173,8 +175,8 @@ public void testMoveFileIntoVault() throws Exception { assertTrue(new DefaultFindFeature(session).find(clearFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( @@ -199,8 +201,8 @@ public void testMoveDirectoryIntoVault() throws Exception { new DropboxTouchFeature(session).touch(new DropboxWriteFeature(session), clearFile, new TransferStatus()); assertTrue(new DefaultFindFeature(session).find(clearFolder)); assertTrue(new DefaultFindFeature(session).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -224,8 +226,8 @@ public void testMoveFileOutsideVault() throws Exception { new DropboxDirectoryFeature(session).mkdir(new DropboxWriteFeature(session), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( @@ -251,8 +253,8 @@ public void testMoveDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DropboxDirectoryFeature(session)).mkdir( diff --git a/eue/pom.xml b/eue/pom.xml index c264b8473a0..d499f136cc3 100644 --- a/eue/pom.xml +++ b/eue/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT eue jar diff --git a/eue/src/test/java/ch/cyberduck/core/cryptomator/EueSingleUploadServiceTest.java b/eue/src/test/java/ch/cyberduck/core/cryptomator/EueSingleUploadServiceTest.java deleted file mode 100644 index 883a1996c04..00000000000 --- a/eue/src/test/java/ch/cyberduck/core/cryptomator/EueSingleUploadServiceTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package ch.cyberduck.core.cryptomator; - -/* - * Copyright (c) 2002-2021 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.AbstractPath; -import ch.cyberduck.core.AlphanumericRandomStringService; -import ch.cyberduck.core.BytecountStreamListener; -import ch.cyberduck.core.DisabledConnectionCallback; -import ch.cyberduck.core.DisabledLoginCallback; -import ch.cyberduck.core.DisabledPasswordCallback; -import ch.cyberduck.core.DisabledProgressListener; -import ch.cyberduck.core.Local; -import ch.cyberduck.core.Path; -import ch.cyberduck.core.cryptomator.features.CryptoReadFeature; -import ch.cyberduck.core.cryptomator.features.CryptoUploadFeature; -import ch.cyberduck.core.cryptomator.features.CryptoWriteFeature; -import ch.cyberduck.core.eue.AbstractEueSessionTest; -import ch.cyberduck.core.eue.EueAttributesFinderFeature; -import ch.cyberduck.core.eue.EueDeleteFeature; -import ch.cyberduck.core.eue.EueDirectoryFeature; -import ch.cyberduck.core.eue.EueFindFeature; -import ch.cyberduck.core.eue.EueReadFeature; -import ch.cyberduck.core.eue.EueResourceIdProvider; -import ch.cyberduck.core.eue.EueSingleUploadService; -import ch.cyberduck.core.eue.EueWriteFeature; -import ch.cyberduck.core.features.AttributesFinder; -import ch.cyberduck.core.features.Delete; -import ch.cyberduck.core.features.Find; -import ch.cyberduck.core.io.BandwidthThrottle; -import ch.cyberduck.core.io.StreamCopier; -import ch.cyberduck.core.transfer.TransferStatus; -import ch.cyberduck.core.vault.DefaultVaultRegistry; -import ch.cyberduck.core.vault.VaultCredentials; -import ch.cyberduck.test.IntegrationTest; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.RandomUtils; -import org.cryptomator.cryptolib.api.FileHeader; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.UUID; - -import static org.junit.Assert.*; - -@Category(IntegrationTest.class) -@RunWith(value = Parameterized.class) -public class EueSingleUploadServiceTest extends AbstractEueSessionTest { - - @Test - public void testUploadVault() throws Exception { - final EueResourceIdProvider fileid = new EueResourceIdProvider(session); - final Path container = new EueDirectoryFeature(session, fileid).mkdir(new EueWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(AbstractPath.Type.directory)), new TransferStatus().setLength(0L)); - final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); - session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); - final Local local = new Local(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); - final byte[] content = RandomUtils.nextBytes(502400); - IOUtils.write(content, local.getOutputStream(false)); - final TransferStatus writeStatus = new TransferStatus(); - final FileHeader header = cryptomator.getFileHeaderCryptor().create(); - writeStatus.setHeader(cryptomator.getFileHeaderCryptor().encryptHeader(header)); - writeStatus.setLength(content.length); - final BytecountStreamListener count = new BytecountStreamListener(); - final CryptoUploadFeature feature = new CryptoUploadFeature<>(session, - new EueSingleUploadService(session, fileid), - cryptomator); - feature.upload(new CryptoWriteFeature<>(session, new EueWriteFeature(session, fileid), cryptomator), test, local, new BandwidthThrottle(BandwidthThrottle.UNLIMITED), new DisabledProgressListener(), count, writeStatus, null); - assertEquals(content.length, count.getSent()); - assertTrue(writeStatus.isComplete()); - assertTrue(cryptomator.getFeature(session, Find.class, new EueFindFeature(session, fileid)).find(test)); - assertEquals(content.length, cryptomator.getFeature(session, AttributesFinder.class, new EueAttributesFinderFeature(session, fileid)).find(test).getSize()); - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(content.length); - final TransferStatus readStatus = new TransferStatus().setLength(content.length); - final InputStream in = new CryptoReadFeature(session, new EueReadFeature(session, fileid), cryptomator).read(test, readStatus, new DisabledConnectionCallback()); - new StreamCopier(readStatus, readStatus).transfer(in, buffer); - assertArrayEquals(content, buffer.toByteArray()); - cryptomator.getFeature(session, Delete.class, new EueDeleteFeature(session, fileid)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); - local.delete(); - } -} diff --git a/eue/src/test/java/ch/cyberduck/core/cryptomator/EueThresholdUploadServiceTest.java b/eue/src/test/java/ch/cyberduck/core/cryptomator/EueThresholdUploadServiceTest.java deleted file mode 100644 index 9855b7e9cd1..00000000000 --- a/eue/src/test/java/ch/cyberduck/core/cryptomator/EueThresholdUploadServiceTest.java +++ /dev/null @@ -1,145 +0,0 @@ -package ch.cyberduck.core.cryptomator; - -/* - * Copyright (c) 2002-2021 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.AlphanumericRandomStringService; -import ch.cyberduck.core.BytecountStreamListener; -import ch.cyberduck.core.DisabledConnectionCallback; -import ch.cyberduck.core.DisabledLoginCallback; -import ch.cyberduck.core.DisabledPasswordCallback; -import ch.cyberduck.core.DisabledProgressListener; -import ch.cyberduck.core.Local; -import ch.cyberduck.core.Path; -import ch.cyberduck.core.cryptomator.features.CryptoBulkFeature; -import ch.cyberduck.core.cryptomator.features.CryptoReadFeature; -import ch.cyberduck.core.cryptomator.features.CryptoUploadFeature; -import ch.cyberduck.core.cryptomator.features.CryptoWriteFeature; -import ch.cyberduck.core.eue.AbstractEueSessionTest; -import ch.cyberduck.core.eue.EueAttributesFinderFeature; -import ch.cyberduck.core.eue.EueDeleteFeature; -import ch.cyberduck.core.eue.EueDirectoryFeature; -import ch.cyberduck.core.eue.EueFindFeature; -import ch.cyberduck.core.eue.EueReadFeature; -import ch.cyberduck.core.eue.EueResourceIdProvider; -import ch.cyberduck.core.eue.EueThresholdUploadService; -import ch.cyberduck.core.eue.EueWriteFeature; -import ch.cyberduck.core.features.AttributesFinder; -import ch.cyberduck.core.features.Delete; -import ch.cyberduck.core.features.Find; -import ch.cyberduck.core.io.BandwidthThrottle; -import ch.cyberduck.core.io.StreamCopier; -import ch.cyberduck.core.shared.DisabledBulkFeature; -import ch.cyberduck.core.transfer.Transfer; -import ch.cyberduck.core.transfer.TransferItem; -import ch.cyberduck.core.transfer.TransferStatus; -import ch.cyberduck.core.vault.DefaultVaultRegistry; -import ch.cyberduck.core.vault.VaultCredentials; -import ch.cyberduck.test.IntegrationTest; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.RandomUtils; -import org.cryptomator.cryptolib.api.FileHeader; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.EnumSet; -import java.util.Map; -import java.util.UUID; - -import static org.junit.Assert.*; - -@Category(IntegrationTest.class) -@RunWith(value = Parameterized.class) -public class EueThresholdUploadServiceTest extends AbstractEueSessionTest { - - @Test - public void testUploadVault() throws Exception { - final EueResourceIdProvider fileid = new EueResourceIdProvider(session); - final Path container = new EueDirectoryFeature(session, fileid).mkdir(new EueWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus().setLength(0L)); - final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); - final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); - session.withRegistry(registry); - final Local local = new Local(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); - final byte[] content = RandomUtils.nextBytes(8840780); - IOUtils.write(content, local.getOutputStream(false)); - final TransferStatus writeStatus = new TransferStatus(); - final FileHeader header = cryptomator.getFileHeaderCryptor().create(); - writeStatus.setHeader(cryptomator.getFileHeaderCryptor().encryptHeader(header)); - writeStatus.setLength(content.length); - final BytecountStreamListener count = new BytecountStreamListener(); - final CryptoUploadFeature feature = new CryptoUploadFeature<>(session, - new EueThresholdUploadService(session, fileid, registry), - cryptomator); - feature.upload(new CryptoWriteFeature<>(session, new EueWriteFeature(session, fileid), cryptomator), test, local, new BandwidthThrottle(BandwidthThrottle.UNLIMITED), new DisabledProgressListener(), count, writeStatus, new DisabledConnectionCallback()); - assertEquals(content.length, count.getSent()); - assertTrue(writeStatus.isComplete()); - assertTrue(cryptomator.getFeature(session, Find.class, new EueFindFeature(session, fileid)).find(test)); - assertEquals(content.length, cryptomator.getFeature(session, AttributesFinder.class, new EueAttributesFinderFeature(session, fileid)).find(test).getSize()); - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(content.length); - final TransferStatus readStatus = new TransferStatus().setLength(content.length); - final InputStream in = new CryptoReadFeature(session, new EueReadFeature(session, fileid), cryptomator).read(test, readStatus, new DisabledConnectionCallback()); - new StreamCopier(readStatus, readStatus).transfer(in, buffer); - assertArrayEquals(content, buffer.toByteArray()); - cryptomator.getFeature(session, Delete.class, new EueDeleteFeature(session, fileid)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); - local.delete(); - } - - @Test - public void testUploadVaultWithBulkFeature() throws Exception { - final EueResourceIdProvider fileid = new EueResourceIdProvider(session); - final Path container = new EueDirectoryFeature(session, fileid).mkdir(new EueWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus().setLength(0L)); - final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); - final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); - session.withRegistry(registry); - final Local local = new Local(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); - final byte[] content = RandomUtils.nextBytes(50240000); - IOUtils.write(content, local.getOutputStream(false)); - final TransferStatus writeStatus = new TransferStatus(); - final FileHeader header = cryptomator.getFileHeaderCryptor().create(); - writeStatus.setHeader(cryptomator.getFileHeaderCryptor().encryptHeader(header)); - writeStatus.setLength(content.length); - final CryptoBulkFeature> bulk = new CryptoBulkFeature<>(session, new DisabledBulkFeature(), cryptomator); - bulk.pre(Transfer.Type.upload, Collections.singletonMap(new TransferItem(test), writeStatus), new DisabledConnectionCallback()); - final BytecountStreamListener count = new BytecountStreamListener(); - final CryptoUploadFeature feature = new CryptoUploadFeature<>(session, - new EueThresholdUploadService(session, fileid, registry), - cryptomator); - feature.upload(new CryptoWriteFeature<>(session, new EueWriteFeature(session, fileid), cryptomator), test, local, new BandwidthThrottle(BandwidthThrottle.UNLIMITED), new DisabledProgressListener(), count, writeStatus, new DisabledConnectionCallback()); - assertEquals(content.length, count.getSent()); - assertTrue(writeStatus.isComplete()); - assertTrue(cryptomator.getFeature(session, Find.class, new EueFindFeature(session, fileid)).find(test)); - assertEquals(content.length, cryptomator.getFeature(session, AttributesFinder.class, new EueAttributesFinderFeature(session, fileid)).find(test).getSize()); - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(content.length); - final TransferStatus readStatus = new TransferStatus().setLength(content.length); - final InputStream in = new CryptoReadFeature(session, new EueReadFeature(session, fileid), cryptomator).read(test, readStatus, new DisabledConnectionCallback()); - new StreamCopier(readStatus, readStatus).transfer(in, buffer); - assertArrayEquals(content, buffer.toByteArray()); - cryptomator.getFeature(session, Delete.class, new EueDeleteFeature(session, fileid)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); - local.delete(); - } -} diff --git a/eue/src/test/java/ch/cyberduck/core/cryptomator/EueUploadServiceTest.java b/eue/src/test/java/ch/cyberduck/core/cryptomator/EueUploadServiceTest.java deleted file mode 100644 index 27ecf049804..00000000000 --- a/eue/src/test/java/ch/cyberduck/core/cryptomator/EueUploadServiceTest.java +++ /dev/null @@ -1,145 +0,0 @@ -package ch.cyberduck.core.cryptomator; - -/* - * Copyright (c) 2002-2021 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.AbstractPath; -import ch.cyberduck.core.AlphanumericRandomStringService; -import ch.cyberduck.core.BytecountStreamListener; -import ch.cyberduck.core.DisabledConnectionCallback; -import ch.cyberduck.core.DisabledLoginCallback; -import ch.cyberduck.core.DisabledPasswordCallback; -import ch.cyberduck.core.DisabledProgressListener; -import ch.cyberduck.core.Local; -import ch.cyberduck.core.Path; -import ch.cyberduck.core.cryptomator.features.CryptoBulkFeature; -import ch.cyberduck.core.cryptomator.features.CryptoReadFeature; -import ch.cyberduck.core.cryptomator.features.CryptoUploadFeature; -import ch.cyberduck.core.cryptomator.features.CryptoWriteFeature; -import ch.cyberduck.core.eue.AbstractEueSessionTest; -import ch.cyberduck.core.eue.EueAttributesFinderFeature; -import ch.cyberduck.core.eue.EueDeleteFeature; -import ch.cyberduck.core.eue.EueDirectoryFeature; -import ch.cyberduck.core.eue.EueFindFeature; -import ch.cyberduck.core.eue.EueMultipartWriteFeature; -import ch.cyberduck.core.eue.EueReadFeature; -import ch.cyberduck.core.eue.EueResourceIdProvider; -import ch.cyberduck.core.eue.EueUploadService; -import ch.cyberduck.core.eue.EueWriteFeature; -import ch.cyberduck.core.features.AttributesFinder; -import ch.cyberduck.core.features.Delete; -import ch.cyberduck.core.features.Find; -import ch.cyberduck.core.io.BandwidthThrottle; -import ch.cyberduck.core.io.StreamCopier; -import ch.cyberduck.core.shared.DisabledBulkFeature; -import ch.cyberduck.core.transfer.Transfer; -import ch.cyberduck.core.transfer.TransferItem; -import ch.cyberduck.core.transfer.TransferStatus; -import ch.cyberduck.core.vault.DefaultVaultRegistry; -import ch.cyberduck.core.vault.VaultCredentials; -import ch.cyberduck.test.IntegrationTest; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.RandomUtils; -import org.cryptomator.cryptolib.api.FileHeader; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.EnumSet; -import java.util.Map; -import java.util.UUID; - -import static org.junit.Assert.*; - -@Category(IntegrationTest.class) -@RunWith(value = Parameterized.class) -public class EueUploadServiceTest extends AbstractEueSessionTest { - - @Test - public void testUploadVault() throws Exception { - final EueResourceIdProvider fileid = new EueResourceIdProvider(session); - final Path container = new EueDirectoryFeature(session, fileid).mkdir(new EueWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(AbstractPath.Type.directory)), new TransferStatus().setLength(0L)); - final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); - session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); - final Local local = new Local(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); - final byte[] content = RandomUtils.nextBytes(50240000); - IOUtils.write(content, local.getOutputStream(false)); - final TransferStatus writeStatus = new TransferStatus(); - final FileHeader header = cryptomator.getFileHeaderCryptor().create(); - writeStatus.setHeader(cryptomator.getFileHeaderCryptor().encryptHeader(header)); - writeStatus.setLength(content.length); - final BytecountStreamListener count = new BytecountStreamListener(); - final CryptoUploadFeature feature = new CryptoUploadFeature<>(session, - new EueUploadService(session), - cryptomator); - feature.upload(new CryptoWriteFeature<>(session, new EueMultipartWriteFeature(session, fileid), cryptomator), test, local, new BandwidthThrottle(BandwidthThrottle.UNLIMITED), new DisabledProgressListener(), count, writeStatus, new DisabledConnectionCallback()); - assertEquals(content.length, count.getSent()); - assertTrue(writeStatus.isComplete()); - assertTrue(cryptomator.getFeature(session, Find.class, new EueFindFeature(session, fileid)).find(test)); - assertEquals(content.length, cryptomator.getFeature(session, AttributesFinder.class, new EueAttributesFinderFeature(session, fileid)).find(test).getSize()); - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(content.length); - final TransferStatus readStatus = new TransferStatus().setLength(content.length); - final InputStream in = new CryptoReadFeature(session, new EueReadFeature(session, fileid), cryptomator).read(test, readStatus, new DisabledConnectionCallback()); - new StreamCopier(readStatus, readStatus).transfer(in, buffer); - assertArrayEquals(content, buffer.toByteArray()); - cryptomator.getFeature(session, Delete.class, new EueDeleteFeature(session, fileid)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); - local.delete(); - } - - @Test - public void testUploadVaultWithBulkFeature() throws Exception { - final EueResourceIdProvider fileid = new EueResourceIdProvider(session); - final Path container = new EueDirectoryFeature(session, fileid).mkdir(new EueWriteFeature(session, fileid), new Path(new AlphanumericRandomStringService().random(), EnumSet.of(AbstractPath.Type.directory)), new TransferStatus().setLength(0L)); - final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); - session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); - final Local local = new Local(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); - final byte[] content = RandomUtils.nextBytes(50240000); - IOUtils.write(content, local.getOutputStream(false)); - final TransferStatus writeStatus = new TransferStatus(); - final FileHeader header = cryptomator.getFileHeaderCryptor().create(); - writeStatus.setHeader(cryptomator.getFileHeaderCryptor().encryptHeader(header)); - writeStatus.setLength(content.length); - final CryptoBulkFeature> bulk = new CryptoBulkFeature<>(session, new DisabledBulkFeature(), cryptomator); - bulk.pre(Transfer.Type.upload, Collections.singletonMap(new TransferItem(test), writeStatus), new DisabledConnectionCallback()); - final BytecountStreamListener count = new BytecountStreamListener(); - final CryptoUploadFeature feature = new CryptoUploadFeature<>(session, - new EueUploadService(session), - cryptomator); - feature.upload(new CryptoWriteFeature<>(session, new EueMultipartWriteFeature(session, fileid), cryptomator), test, local, new BandwidthThrottle(BandwidthThrottle.UNLIMITED), new DisabledProgressListener(), count, writeStatus, new DisabledConnectionCallback()); - assertEquals(content.length, count.getSent()); - assertTrue(writeStatus.isComplete()); - assertTrue(cryptomator.getFeature(session, Find.class, new EueFindFeature(session, fileid)).find(test)); - assertEquals(content.length, cryptomator.getFeature(session, AttributesFinder.class, new EueAttributesFinderFeature(session, fileid)).find(test).getSize()); - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(content.length); - final TransferStatus readStatus = new TransferStatus().setLength(content.length); - final InputStream in = new CryptoReadFeature(session, new EueReadFeature(session, fileid), cryptomator).read(test, readStatus, new DisabledConnectionCallback()); - new StreamCopier(readStatus, readStatus).transfer(in, buffer); - assertArrayEquals(content, buffer.toByteArray()); - cryptomator.getFeature(session, Delete.class, new EueDeleteFeature(session, fileid)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); - local.delete(); - } -} diff --git a/eue/src/test/java/ch/cyberduck/core/cryptomator/EueWriteFeatureTest.java b/eue/src/test/java/ch/cyberduck/core/cryptomator/EueWriteFeatureTest.java deleted file mode 100644 index ee7f0729570..00000000000 --- a/eue/src/test/java/ch/cyberduck/core/cryptomator/EueWriteFeatureTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package ch.cyberduck.core.cryptomator; - -/* - * Copyright (c) 2002-2017 iterate GmbH. All rights reserved. - * https://cyberduck.io/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -import ch.cyberduck.core.AlphanumericRandomStringService; -import ch.cyberduck.core.DisabledConnectionCallback; -import ch.cyberduck.core.DisabledLoginCallback; -import ch.cyberduck.core.DisabledPasswordCallback; -import ch.cyberduck.core.Path; -import ch.cyberduck.core.PathAttributes; -import ch.cyberduck.core.cryptomator.features.CryptoReadFeature; -import ch.cyberduck.core.cryptomator.features.CryptoWriteFeature; -import ch.cyberduck.core.cryptomator.random.RotatingNonceGenerator; -import ch.cyberduck.core.eue.AbstractEueSessionTest; -import ch.cyberduck.core.eue.EueDeleteFeature; -import ch.cyberduck.core.eue.EueFindFeature; -import ch.cyberduck.core.eue.EueReadFeature; -import ch.cyberduck.core.eue.EueResourceIdProvider; -import ch.cyberduck.core.eue.EueWriteFeature; -import ch.cyberduck.core.features.Delete; -import ch.cyberduck.core.features.Find; -import ch.cyberduck.core.io.StreamCopier; -import ch.cyberduck.core.preferences.HostPreferencesFactory; -import ch.cyberduck.core.shared.DefaultHomeFinderService; -import ch.cyberduck.core.transfer.TransferStatus; -import ch.cyberduck.core.vault.DefaultVaultRegistry; -import ch.cyberduck.core.vault.VaultCredentials; -import ch.cyberduck.test.IntegrationTest; - -import org.apache.commons.lang3.RandomUtils; -import org.cryptomator.cryptolib.api.FileHeader; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.EnumSet; - -import static org.junit.Assert.*; - -@Category(IntegrationTest.class) -@RunWith(value = Parameterized.class) -public class EueWriteFeatureTest extends AbstractEueSessionTest { - - @Test - public void testWrite() throws Exception { - final TransferStatus status = new TransferStatus(); - final int length = 1048576; - final byte[] content = RandomUtils.nextBytes(length); - status.setLength(content.length); - final Path home = new DefaultHomeFinderService(session).find(); - final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault, - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.masterkey.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.config.filename"), - HostPreferencesFactory.get(session.getHost()).getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8)); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); - session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); - final EueResourceIdProvider fileid = new EueResourceIdProvider(session); - final CryptoWriteFeature writer = new CryptoWriteFeature(session, new EueWriteFeature(session, fileid), cryptomator); - final FileHeader header = cryptomator.getFileHeaderCryptor().create(); - status.setHeader(cryptomator.getFileHeaderCryptor().encryptHeader(header)); - status.setNonces(new RotatingNonceGenerator(cryptomator.getNonceSize(), cryptomator.numberOfChunks(content.length))); - status.setChecksum(writer.checksum(test, status).compute(new ByteArrayInputStream(content), status)); - final OutputStream out = writer.write(test, status, new DisabledConnectionCallback()); - assertNotNull(out); - new StreamCopier(status, status).transfer(new ByteArrayInputStream(content), out); - out.close(); - assertEquals(PathAttributes.EMPTY, status.getResponse()); - assertTrue(cryptomator.getFeature(session, Find.class, new EueFindFeature(session, fileid)).find(test)); - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(content.length); - final InputStream in = new CryptoReadFeature(session, new EueReadFeature(session, fileid), cryptomator).read(test, new TransferStatus().setLength(content.length), new DisabledConnectionCallback()); - new StreamCopier(status, status).transfer(in, buffer); - assertArrayEquals(content, buffer.toByteArray()); - cryptomator.getFeature(session, Delete.class, new EueDeleteFeature(session, fileid)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); - } -} diff --git a/eue/src/test/java/ch/cyberduck/core/eue/AbstractEueSessionTest.java b/eue/src/test/java/ch/cyberduck/core/eue/AbstractEueSessionTest.java index 61e9963eb82..fbb0ecd92c5 100644 --- a/eue/src/test/java/ch/cyberduck/core/eue/AbstractEueSessionTest.java +++ b/eue/src/test/java/ch/cyberduck/core/eue/AbstractEueSessionTest.java @@ -16,7 +16,6 @@ */ import ch.cyberduck.core.*; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.eue.io.swagger.client.ApiException; import ch.cyberduck.core.eue.io.swagger.client.api.CreateShareApi; import ch.cyberduck.core.eue.io.swagger.client.model.ShareCreationRequestModel; @@ -29,6 +28,7 @@ import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DisabledX509TrustManager; import ch.cyberduck.core.transfer.TransferStatus; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -48,7 +48,7 @@ public class AbstractEueSessionTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter diff --git a/freenet/pom.xml b/freenet/pom.xml index 03783840876..6fae4774954 100644 --- a/freenet/pom.xml +++ b/freenet/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT freenet jar diff --git a/ftp/pom.xml b/ftp/pom.xml index 6f8d39ab821..ab1f03241f1 100644 --- a/ftp/pom.xml +++ b/ftp/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT ftp jar diff --git a/ftp/src/main/java/ch/cyberduck/core/ftp/FTPMoveFeature.java b/ftp/src/main/java/ch/cyberduck/core/ftp/FTPMoveFeature.java index 4918708ac78..bc1292d5998 100644 --- a/ftp/src/main/java/ch/cyberduck/core/ftp/FTPMoveFeature.java +++ b/ftp/src/main/java/ch/cyberduck/core/ftp/FTPMoveFeature.java @@ -51,7 +51,7 @@ public Path move(final Path file, final Path renamed, final TransferStatus statu throw new FTPException(session.getClient().getReplyCode(), session.getClient().getReplyString()); } // Copy original file attributes - return new Path(renamed).withAttributes(new PathAttributes(file.attributes()).setVault(null)); + return new Path(renamed).withAttributes(new PathAttributes(file.attributes()).setVaultMetadata(null)); } catch(IOException e) { throw new FTPExceptionMappingService().map("Cannot rename {0}", e, file); diff --git a/ftp/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/ftp/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index a6606753f84..a252b7ee0a9 100644 --- a/ftp/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -50,12 +50,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -69,7 +71,6 @@ import java.util.EnumSet; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -81,8 +82,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -112,8 +113,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -134,15 +135,15 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -168,8 +169,8 @@ public void testCopyFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( @@ -207,8 +208,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new DefaultFindFeature(session).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( @@ -237,8 +238,8 @@ public void testCopyDirectoryIntoVault() throws Exception { session).touch(new FTPWriteFeature(session), cleartextFile, new TransferStatus()); assertTrue(new DefaultFindFeature(session).find(cleartextFolder)); assertTrue(new DefaultFindFeature(session).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -265,8 +266,8 @@ public void testCopyFileOutsideVault() throws Exception { new FTPDirectoryFeature(session).mkdir(new FTPWriteFeature(session), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( @@ -294,8 +295,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( diff --git a/ftp/src/test/java/ch/cyberduck/core/cryptomator/CryptoFTPSingleTransferWorkerTest.java b/ftp/src/test/java/ch/cyberduck/core/cryptomator/CryptoFTPSingleTransferWorkerTest.java index 4f0bb490a8a..ea7a7ad32c4 100644 --- a/ftp/src/test/java/ch/cyberduck/core/cryptomator/CryptoFTPSingleTransferWorkerTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/cryptomator/CryptoFTPSingleTransferWorkerTest.java @@ -50,6 +50,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -91,8 +92,8 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { diff --git a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPDirectoryFeatureTest.java b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPDirectoryFeatureTest.java index ea4c791fddb..e4d716462ff 100644 --- a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPDirectoryFeatureTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPDirectoryFeatureTest.java @@ -32,8 +32,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -44,7 +46,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -57,8 +58,8 @@ public void testMakeDirectoryEncrypted() throws Exception { final Path testdirectory = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path testdirectory2 = new Path(testdirectory, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path testfile2 = new Path(testdirectory2, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new FTPWriteFeature(session)), testdirectory, new TransferStatus()); @@ -71,13 +72,13 @@ public void testMakeDirectoryEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new FTPWriteFeature(session)), test, new TransferStatus()); diff --git a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPListServiceTest.java b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPListServiceTest.java index 8eefa271447..175910e52a2 100644 --- a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPListServiceTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPListServiceTest.java @@ -41,6 +41,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -63,8 +64,8 @@ public void testListCryptomator() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertTrue(new CryptoListService(session, new FTPListService(session), cryptomator).list(vault).isEmpty()); new CryptoTouchFeature<>(session, new DefaultTouchFeature( diff --git a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPMoveFeatureTest.java b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPMoveFeatureTest.java index b5f00a980b4..a67efa3c849 100644 --- a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPMoveFeatureTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPMoveFeatureTest.java @@ -37,6 +37,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -60,8 +61,8 @@ public void testMove() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( new CryptoWriteFeature<>(session, new FTPWriteFeature(session), cryptomator), folder, new TransferStatus()); diff --git a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPTouchFeatureTest.java b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPTouchFeatureTest.java index 64d7d458c06..1fc469ac17b 100644 --- a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPTouchFeatureTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPTouchFeatureTest.java @@ -35,8 +35,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -47,7 +49,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -57,8 +58,8 @@ public class FTPTouchFeatureTest extends AbstractFTPTest { public void testTouchEncrypted() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus().setLength(0L); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -72,12 +73,12 @@ public void testTouchEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -88,12 +89,12 @@ public void testTouchLongFilenameEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( diff --git a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPWriteFeatureTest.java b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPWriteFeatureTest.java index 0af02eaf7a8..98488d5f8d6 100644 --- a/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPWriteFeatureTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/cryptomator/FTPWriteFeatureTest.java @@ -41,6 +41,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -72,8 +73,8 @@ public void testWrite() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new FTPWriteFeature(session), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); diff --git a/ftp/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java b/ftp/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java index e12337a030d..d66becd2149 100644 --- a/ftp/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java @@ -47,9 +47,11 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.MoveWorker; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -61,7 +63,6 @@ import java.util.UUID; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -73,8 +74,8 @@ public void testMoveSameFolderCryptomator() throws Exception { final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(new FTPWriteFeature(session), source, new TransferStatus()); @@ -93,8 +94,8 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(new FTPWriteFeature(session), source, new TransferStatus()); @@ -111,16 +112,16 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path sourceFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(sourceFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir(cryptomator.getFeature(session, Write.class, new FTPWriteFeature(session)), sourceFolder, new TransferStatus()); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -142,8 +143,8 @@ public void testMoveFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new FTPWriteFeature(session)), folder, new TransferStatus()); @@ -182,8 +183,8 @@ public void testMoveFileIntoVault() throws Exception { assertTrue(new DefaultFindFeature(session).find(clearFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( @@ -211,8 +212,8 @@ public void testMoveDirectoryIntoVault() throws Exception { new DefaultTouchFeature(session).touch(new FTPWriteFeature(session), clearFile, new TransferStatus()); assertTrue(new DefaultFindFeature(session).find(clearFolder)); assertTrue(new DefaultFindFeature(session).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -239,8 +240,8 @@ public void testMoveFileOutsideVault() throws Exception { new FTPDirectoryFeature(session).mkdir(new FTPWriteFeature(session), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( @@ -269,8 +270,8 @@ public void testMoveDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new FTPDirectoryFeature(session)).mkdir( diff --git a/ftp/src/test/java/ch/cyberduck/core/ftp/AbstractFTPTest.java b/ftp/src/test/java/ch/cyberduck/core/ftp/AbstractFTPTest.java index c10c44305cc..b5347ae05c0 100644 --- a/ftp/src/test/java/ch/cyberduck/core/ftp/AbstractFTPTest.java +++ b/ftp/src/test/java/ch/cyberduck/core/ftp/AbstractFTPTest.java @@ -29,7 +29,6 @@ import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; import ch.cyberduck.core.Scheme; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.exception.AccessDeniedException; import ch.cyberduck.core.exception.BackgroundException; import ch.cyberduck.core.exception.NotfoundException; @@ -37,6 +36,7 @@ import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import org.apache.ftpserver.FtpServer; import org.apache.ftpserver.FtpServerFactory; @@ -69,11 +69,11 @@ public class AbstractFTPTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() { diff --git a/googledrive/pom.xml b/googledrive/pom.xml index a0fb597063a..cdd58b424b1 100644 --- a/googledrive/pom.xml +++ b/googledrive/pom.xml @@ -18,7 +18,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT 4.0.0 googledrive diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index 91df747da3d..4fafe93594b 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -47,12 +47,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -67,7 +69,6 @@ import com.google.api.services.drive.model.File; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -79,8 +80,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -106,8 +107,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); @@ -125,16 +126,17 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { new DeleteWorker(new DisabledLoginCallback(), Collections.singletonList(vault), new DisabledProgressListener()).run(session); } + //TODO @Test + @Ignore("File name shortening not implemented yet") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); @@ -158,8 +160,8 @@ public void testCopyFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); @@ -195,8 +197,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new DriveFindFeature(session, fileid).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( @@ -222,8 +224,8 @@ public void testCopyDirectoryIntoVault() throws Exception { new DriveTouchFeature(session, fileid).touch(new DriveWriteFeature(session, fileid), cleartextFile, new TransferStatus()); assertTrue(new DriveFindFeature(session, fileid).find(cleartextFolder)); assertTrue(new DriveFindFeature(session, fileid).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -248,8 +250,8 @@ public void testCopyFileOutsideVault() throws Exception { new DriveDirectoryFeature(session, fileid).mkdir(new DriveWriteFeature(session, fileid), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( @@ -273,8 +275,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/CryptoDriveTransferWorkerTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/CryptoDriveTransferWorkerTest.java index 353798ef0a4..c245faeaca2 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/CryptoDriveTransferWorkerTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/CryptoDriveTransferWorkerTest.java @@ -51,6 +51,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -91,8 +92,8 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); Assert.assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveAttributesFinderFeatureTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveAttributesFinderFeatureTest.java index 9b0915f23ce..1b3ca1a3a74 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveAttributesFinderFeatureTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveAttributesFinderFeatureTest.java @@ -46,6 +46,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -68,8 +69,8 @@ public class DriveAttributesFinderFeatureTest extends AbstractDriveTest { public void testFindCustomAttributesFinderCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -85,8 +86,8 @@ public void testFindCustomAttributesFinderCryptomator() throws Exception { public void testFindDefaultAttributesFinderCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -102,8 +103,8 @@ public void testFindDefaultAttributesFinderCryptomator() throws Exception { public void testFindDirectoryDefaultAttributesFinderCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( @@ -120,8 +121,8 @@ public void testFindDirectoryDefaultAttributesFinderCryptomator() throws Excepti public void testFindDefaultAttributesFinderWithCacheCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -142,8 +143,8 @@ public void testFindDefaultAttributesFinderWithCacheCryptomator() throws Excepti public void testFindAttributesFinderWithCacheCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -164,8 +165,8 @@ public void testFindAttributesFinderWithCacheCryptomator() throws Exception { public void testFindDirectoryDefaultAttributesFinderWithCacheCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); assertEquals(new CryptoFileIdProvider(session, fileid, cryptomator).getFileId(vault), diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveDirectoryFeatureTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveDirectoryFeatureTest.java index b16f19d3489..68ba389b26c 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveDirectoryFeatureTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveDirectoryFeatureTest.java @@ -41,8 +41,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -54,7 +56,6 @@ import java.util.stream.Collectors; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -63,9 +64,9 @@ public class DriveDirectoryFeatureTest extends AbstractDriveTest { @Test public void testMakeDirectoryEncrypted() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( @@ -84,13 +85,14 @@ public void testMakeDirectoryEncrypted() throws Exception { cryptomator.getFeature(session, Delete.class, new DriveDeleteFeature(session, fileid)).delete(Collections.singletonList(vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); } + //TODO @Test + @Ignore("File name shortening not implemented yet") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveListServiceTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveListServiceTest.java index 8737f0f2518..b70030439f9 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveListServiceTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveListServiceTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -60,9 +61,9 @@ public class DriveListServiceTest extends AbstractDriveTest { @Test public void testListCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); assertTrue(new CryptoListService(session, new DriveDefaultListService(session, fileid), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveMoveFeatureTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveMoveFeatureTest.java index 9ee2e402f34..7f6e3519eeb 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveMoveFeatureTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveMoveFeatureTest.java @@ -40,6 +40,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -61,9 +62,9 @@ public class DriveMoveFeatureTest extends AbstractDriveTest { @Test public void testMove() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path folder = cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveTouchFeatureTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveTouchFeatureTest.java index 65276bcddab..35b8f363b6c 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveTouchFeatureTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveTouchFeatureTest.java @@ -37,8 +37,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -51,7 +53,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -60,9 +61,9 @@ public class DriveTouchFeatureTest extends AbstractDriveTest { @Test public void testTouch() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -74,13 +75,14 @@ public void testTouch() throws Exception { cryptomator.getFeature(session, Delete.class, new DriveDeleteFeature(session, fileid)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); } + //TODO @Test + @Ignore("Filename shorterning not implemented yet") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -93,12 +95,12 @@ public void testTouchLongFilenameEncrypted() throws Exception { } @Test + @Ignore("Filename shorterning not implemented yet") public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveWriteFeatureTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveWriteFeatureTest.java index 64a7b77aa27..32df51d3f15 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveWriteFeatureTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/DriveWriteFeatureTest.java @@ -51,6 +51,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -82,9 +83,9 @@ public void testWrite() throws Exception { final byte[] content = RandomUtils.nextBytes(length); status.setLength(content.length); final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); @@ -117,8 +118,8 @@ public void testWriteWithCache() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new DriveWriteFeature(session, fileid), cryptomator); diff --git a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java index 959a53c3dfb..7956127a6a8 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java @@ -51,12 +51,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.MoveWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -72,7 +74,6 @@ import com.google.api.services.drive.model.File; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -81,9 +82,9 @@ public class MoveWorkerTest extends AbstractDriveTest { @Test public void testMoveSameFolderCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); @@ -106,9 +107,9 @@ public void testMoveSameFolderCryptomator() throws Exception { @Test public void testMoveToDifferentFolderCryptomator() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); @@ -125,13 +126,14 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { cryptomator.getFeature(session, Delete.class, new DriveDeleteFeature(session, fileid)).delete(Arrays.asList(target, targetFolder, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); } + //TODO @Test + @Ignore("File name shortening not implemented yet") public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); @@ -152,9 +154,9 @@ public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception @Test public void testMoveFolder() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); final Path folder = cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( @@ -192,9 +194,9 @@ public void testMoveFileIntoVault() throws Exception { final DriveFileIdProvider fileid = new DriveFileIdProvider(session); new DriveTouchFeature(session, fileid).touch(new DriveWriteFeature(session, fileid), clearFile, new TransferStatus()); assertTrue(new DefaultFindFeature(session).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final Path encryptedFolder = cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( @@ -219,9 +221,9 @@ public void testMoveDirectoryIntoVault() throws Exception { new DriveTouchFeature(session, fileid).touch(new DriveWriteFeature(session, fileid), clearFile, new TransferStatus()); assertTrue(new DefaultFindFeature(session).find(clearFolder)); assertTrue(new DefaultFindFeature(session).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -241,9 +243,9 @@ public void testMoveFileOutsideVault() throws Exception { final Path clearFolder = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); new DriveDirectoryFeature(session, fileid).mkdir(new DriveWriteFeature(session, fileid), clearFolder, new TransferStatus()); - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final Path encryptedFolder = cryptomator.getFeature(session, Directory.class, new DriveDirectoryFeature(session, fileid)).mkdir( @@ -265,9 +267,9 @@ public void testMoveFileOutsideVault() throws Exception { @Test public void testMoveDirectoryOutsideVault() throws Exception { final Path home = DriveHomeFinderService.MYDRIVE_FOLDER; - final CryptoVault cryptomator = new CryptoVault( - new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final DriveFileIdProvider fileid = new DriveFileIdProvider(session); diff --git a/googledrive/src/test/java/ch/cyberduck/core/googledrive/AbstractDriveTest.java b/googledrive/src/test/java/ch/cyberduck/core/googledrive/AbstractDriveTest.java index ddbddb5b41b..11dc8aa92f8 100644 --- a/googledrive/src/test/java/ch/cyberduck/core/googledrive/AbstractDriveTest.java +++ b/googledrive/src/test/java/ch/cyberduck/core/googledrive/AbstractDriveTest.java @@ -27,10 +27,10 @@ import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; import ch.cyberduck.core.Scheme; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -48,11 +48,11 @@ public class AbstractDriveTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/googlestorage/pom.xml b/googlestorage/pom.xml index 578951e8d4e..01388bb2faf 100644 --- a/googlestorage/pom.xml +++ b/googlestorage/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT googlestorage diff --git a/googlestorage/src/test/java/ch/cyberduck/core/cryptomator/GoogleStorageListServiceTest.java b/googlestorage/src/test/java/ch/cyberduck/core/cryptomator/GoogleStorageListServiceTest.java index 27615928310..21236f58d16 100644 --- a/googlestorage/src/test/java/ch/cyberduck/core/cryptomator/GoogleStorageListServiceTest.java +++ b/googlestorage/src/test/java/ch/cyberduck/core/cryptomator/GoogleStorageListServiceTest.java @@ -34,6 +34,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -53,12 +54,13 @@ public class GoogleStorageListServiceTest extends AbstractGoogleStorageTest { @Test public void testListCryptomator() throws Exception { final Path container = new Path("cyberduck-test-eu", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault( - new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), CryptoVault.VAULT_VERSION); + final Path vault = new Path(container, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertTrue(new CryptoListService(session, new GoogleStorageObjectListService(session), cryptomator).list(vault).isEmpty()); - final CryptoDirectoryV7Feature mkdir = new CryptoDirectoryV7Feature<>(session, new GoogleStorageDirectoryFeature(session), cryptomator); + final CryptoDirectoryV7Feature mkdir = new CryptoDirectoryV7Feature<>(session, new GoogleStorageDirectoryFeature(session), + cryptomator); final Path directory1 = mkdir.mkdir( cryptomator.getFeature(session, Write.class, new GoogleStorageWriteFeature(session)), new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); assertNotNull(new CryptoListService(session, new GoogleStorageObjectListService(session), cryptomator).list(vault) diff --git a/googlestorage/src/test/java/ch/cyberduck/core/googlestorage/AbstractGoogleStorageTest.java b/googlestorage/src/test/java/ch/cyberduck/core/googlestorage/AbstractGoogleStorageTest.java index 34b09d61604..0bee72dc5cd 100644 --- a/googlestorage/src/test/java/ch/cyberduck/core/googlestorage/AbstractGoogleStorageTest.java +++ b/googlestorage/src/test/java/ch/cyberduck/core/googlestorage/AbstractGoogleStorageTest.java @@ -27,10 +27,10 @@ import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; import ch.cyberduck.core.Scheme; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -48,11 +48,11 @@ public class AbstractGoogleStorageTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/hubic/pom.xml b/hubic/pom.xml index 1abda33afba..3179b41458d 100644 --- a/hubic/pom.xml +++ b/hubic/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT hubic jar diff --git a/i18n/pom.xml b/i18n/pom.xml index 110d38419eb..bd2e2a7960b 100644 --- a/i18n/pom.xml +++ b/i18n/pom.xml @@ -18,7 +18,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT 4.0.0 jar diff --git a/i18n/src/main/resources/en.lproj/Bookmark.xib b/i18n/src/main/resources/en.lproj/Bookmark.xib index d9fc8aa0225..17100f04297 100644 --- a/i18n/src/main/resources/en.lproj/Bookmark.xib +++ b/i18n/src/main/resources/en.lproj/Bookmark.xib @@ -1,7 +1,8 @@ - + - + @@ -40,12 +41,14 @@ - + - + @@ -54,7 +57,9 @@ - + @@ -66,7 +71,9 @@ - + @@ -75,7 +82,9 @@ - + @@ -92,7 +101,7 @@ - + @@ -107,7 +116,9 @@ - + @@ -116,7 +127,9 @@ - + @@ -128,7 +141,9 @@ - + @@ -137,7 +152,9 @@ - + @@ -149,7 +166,9 @@ - + @@ -158,7 +177,9 @@ - + @@ -167,7 +188,9 @@ - + @@ -176,7 +199,9 @@ - + @@ -188,7 +213,10 @@ - + @@ -205,7 +233,9 @@ - + @@ -250,7 +280,9 @@ - + @@ -259,7 +291,9 @@ - + @@ -272,7 +306,10 @@ - + @@ -285,7 +322,9 @@ - + @@ -294,7 +333,9 @@ - + @@ -315,7 +356,9 @@ - + @@ -333,7 +376,9 @@ - + @@ -350,7 +395,9 @@ - + @@ -359,7 +406,9 @@ - + @@ -401,7 +450,9 @@ - + @@ -419,7 +470,9 @@ - + @@ -437,7 +490,9 @@ - + @@ -446,7 +501,9 @@ - + @@ -489,93 +546,95 @@ YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05T -S2V5ZWRBcmNoaXZlctEICVRyb290gAGuCwwZGh8UJCgpMDM2PD9VJG51bGzWDQ4PEBESExQVFhcYVk5T -U2l6ZV5OU1Jlc2l6aW5nTW9kZVYkY2xhc3NcTlNJbWFnZUZsYWdzVk5TUmVwc1dOU0NvbG9ygAIQAIAN -EiDDAACAA4ALVnsxLCAxfdIbDxweWk5TLm9iamVjdHOhHYAEgArSGw8gI6IhIoAFgAaACdIlDyYnXxAU -TlNUSUZGUmVwcmVzZW50YXRpb26AB4AITxESOE1NACoAAAAKAAAAEAEAAAMAAAABAAEAAAEBAAMAAAAB -AAEAAAECAAMAAAACAAgACAEDAAMAAAABAAEAAAEGAAMAAAABAAEAAAEKAAMAAAABAAEAAAERAAQAAAAB -AAAACAESAAMAAAABAAEAAAEVAAMAAAABAAIAAAEWAAMAAAABAAEAAAEXAAQAAAABAAAAAgEcAAMAAAAB -AAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAFTAAMAAAACAAEAAYdzAAcAABFoAAAA0AAAAAAAABFo -YXBwbAIAAABtbnRyR1JBWVhZWiAH3AAIABcADwAuAA9hY3NwQVBQTAAAAABub25lAAAAAAAAAAAAAAAA -AAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAVkZXNjAAAAwAAAAHlkc2NtAAABPAAAB+hjcHJ0AAAJJAAAACN3dHB0AAAJSAAAABRrVFJD -AAAJXAAACAxkZXNjAAAAAAAAAB9HZW5lcmljIEdyYXkgR2FtbWEgMi4yIFByb2ZpbGUAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAbWx1YwAAAAAAAAAfAAAADHNrU0sAAAAuAAABhGRhREsAAAA4AAABsmNhRVMAAAA4 -AAAB6nZpVk4AAABAAAACInB0QlIAAABKAAACYnVrVUEAAAAsAAACrGZyRlUAAAA+AAAC2Gh1SFUAAAA0 -AAADFnpoVFcAAAAeAAADSm5iTk8AAAA6AAADaGNzQ1oAAAAoAAADomhlSUwAAAAkAAADyml0SVQAAABO -AAAD7nJvUk8AAAAqAAAEPGRlREUAAABOAAAEZmtvS1IAAAAiAAAEtHN2U0UAAAA4AAABsnpoQ04AAAAe -AAAE1mphSlAAAAAmAAAE9GVsR1IAAAAqAAAFGnB0UE8AAABSAAAFRG5sTkwAAABAAAAFlmVzRVMAAABM -AAAF1nRoVEgAAAAyAAAGInRyVFIAAAAkAAAGVGZpRkkAAABGAAAGeGhySFIAAAA+AAAGvnBsUEwAAABK -AAAG/HJ1UlUAAAA6AAAHRmVuVVMAAAA8AAAHgGFyRUcAAAAsAAAHvABWAWEAZQBvAGIAZQBjAG4A4QAg -AHMAaQB2AOEAIABnAGEAbQBhACAAMgAsADIARwBlAG4AZQByAGkAcwBrACAAZwByAOUAIAAyACwAMgAg -AGcAYQBtAG0AYQBwAHIAbwBmAGkAbABHAGEAbQBtAGEAIABkAGUAIABnAHIAaQBzAG8AcwAgAGcAZQBu -AOgAcgBpAGMAYQAgADIALgAyAEMepQB1ACAAaADsAG4AaAAgAE0A4AB1ACAAeADhAG0AIABDAGgAdQBu -AGcAIABHAGEAbQBtAGEAIAAyAC4AMgBQAGUAcgBmAGkAbAAgAEcAZQBuAOkAcgBpAGMAbwAgAGQAYQAg -AEcAYQBtAGEAIABkAGUAIABDAGkAbgB6AGEAcwAgADIALAAyBBcEMAQzBDAEOwRMBD0EMAAgAEcAcgBh -AHkALQQzBDAEPAQwACAAMgAuADIAUAByAG8AZgBpAGwAIABnAOkAbgDpAHIAaQBxAHUAZQAgAGcAcgBp -AHMAIABnAGEAbQBtAGEAIAAyACwAMgDBAGwAdABhAGwA4QBuAG8AcwAgAHMAegD8AHIAawBlACAAZwBh -AG0AbQBhACAAMgAuADKQGnUocHCWjlFJXqYAIAAyAC4AMgAggnJfaWPPj/AARwBlAG4AZQByAGkAcwBr -ACAAZwByAOUAIABnAGEAbQBtAGEAIAAyACwAMgAtAHAAcgBvAGYAaQBsAE8AYgBlAGMAbgDhACABYQBl -AGQA4QAgAGcAYQBtAGEAIAAyAC4AMgXSBdAF3gXUACAF0AXkBdUF6AAgBdsF3AXcBdkAIAAyAC4AMgBQ -AHIAbwBmAGkAbABvACAAZwByAGkAZwBpAG8AIABnAGUAbgBlAHIAaQBjAG8AIABkAGUAbABsAGEAIABn -AGEAbQBtAGEAIAAyACwAMgBHAGEAbQBhACAAZwByAGkAIABnAGUAbgBlAHIAaQBjAQMAIAAyACwAMgBB + S2V5ZWRBcmNoaXZlctEICVRyb290gAGuCwwbHCEaJissMzY5P0JVJG51bGzXDQ4PEBESExQVFhcYGRpW + TlNTaXplViRjbGFzc1xOU0ltYWdlRmxhZ3NWTlNSZXBzW05TVGludENvbG9yV05TQ29sb3JeTlNSZXNp + emluZ01vZGWAAoANEiDDAACAA4AAgAsQAFZ7MSwgMX3SHQ4eIFpOUy5vYmplY3RzoR+ABIAK0h0OIiWi + IySABYAGgAnTDicoKSoaXxAUTlNUSUZGUmVwcmVzZW50YXRpb25fEBlOU0ludGVybmFsTGF5b3V0RGly + ZWN0aW9ugAiAB08REmxNTQAqAAAACgAAABABAAADAAAAAQABAAABAQADAAAAAQABAAABAgADAAAAAgAI + AAgBAwADAAAAAQABAAABBgADAAAAAQABAAABCgADAAAAAQABAAABEQAEAAAAAQAAAAgBEgADAAAAAQAB + AAABFQADAAAAAQACAAABFgADAAAAAQABAAABFwAEAAAAAQAAAAIBHAADAAAAAQABAAABKAADAAAAAQAC + AAABUgADAAAAAQABAAABUwADAAAAAgABAAGHcwAHAAARnAAAANAAAAAAAAARnGFwcGwCAAAAbW50ckdS + QVlYWVogB9wACAAXAA8ALgAPYWNzcEFQUEwAAAAAbm9uZQAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA + 0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZGVzYwAA + AMAAAAB5ZHNjbQAAATwAAAgaY3BydAAACVgAAAAjd3RwdAAACXwAAAAUa1RSQwAACZAAAAgMZGVzYwAA + AAAAAAAfR2VuZXJpYyBHcmF5IEdhbW1hIDIuMiBQcm9maWxlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1s + dWMAAAAAAAAAHwAAAAxza1NLAAAALgAAAYRkYURLAAAAOgAAAbJjYUVTAAAAOAAAAex2aVZOAAAAQAAA + AiRwdEJSAAAASgAAAmR1a1VBAAAALAAAAq5mckZVAAAAPgAAAtpodUhVAAAANAAAAxh6aFRXAAAAGgAA + A0xrb0tSAAAAIgAAA2ZuYk5PAAAAOgAAA4hjc0NaAAAAKAAAA8JoZUlMAAAAJAAAA+pyb1JPAAAAKgAA + BA5kZURFAAAATgAABDhpdElUAAAATgAABIZzdlNFAAAAOAAABNR6aENOAAAAGgAABQxqYUpQAAAAJgAA + BSZlbEdSAAAAKgAABUxwdFBPAAAAUgAABXZubE5MAAAAQAAABchlc0VTAAAATAAABgh0aFRIAAAAMgAA + BlR0clRSAAAAJAAABoZmaUZJAAAARgAABqpockhSAAAAPgAABvBwbFBMAAAASgAABy5hckVHAAAALAAA + B3hydVJVAAAAOgAAB6RlblVTAAAAPAAAB94AVgFhAGUAbwBiAGUAYwBuAOEAIABzAGkAdgDhACAAZwBh + AG0AYQAgADIALAAyAEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAMgAsADIAIABnAGEAbQBtAGEALQBw + AHIAbwBmAGkAbABHAGEAbQBtAGEAIABkAGUAIABnAHIAaQBzAG8AcwAgAGcAZQBuAOgAcgBpAGMAYQAg + ADIALgAyAEMepQB1ACAAaADsAG4AaAAgAE0A4AB1ACAAeADhAG0AIABDAGgAdQBuAGcAIABHAGEAbQBt + AGEAIAAyAC4AMgBQAGUAcgBmAGkAbAAgAEcAZQBuAOkAcgBpAGMAbwAgAGQAYQAgAEcAYQBtAGEAIABk + AGUAIABDAGkAbgB6AGEAcwAgADIALAAyBBcEMAQzBDAEOwRMBD0EMAAgAEcAcgBhAHkALQQzBDAEPAQw + ACAAMgAuADIAUAByAG8AZgBpAGwAIABnAOkAbgDpAHIAaQBxAHUAZQAgAGcAcgBpAHMAIABnAGEAbQBt + AGEAIAAyACwAMgDBAGwAdABhAGwA4QBuAG8AcwAgAHMAegD8AHIAawBlACAAZwBhAG0AbQBhACAAMgAu + ADKQGnUocHCWjlFJXqYAMgAuADKCcl9pY8+P8Md8vBgAINaMwMkAIKwQucgAIAAyAC4AMgAg1QS4XNMM + x3wARwBlAG4AZQByAGkAcwBrACAAZwByAOUAIABnAGEAbQBtAGEAIAAyACwAMgAtAHAAcgBvAGYAaQBs + AE8AYgBlAGMAbgDhACABYQBlAGQA4QAgAGcAYQBtAGEAIAAyAC4AMgXSBdAF3gXUACAF0AXkBdUF6AAg + BdsF3AXcBdkAIAAyAC4AMgBHAGEAbQBhACAAZwByAGkAIABnAGUAbgBlAHIAaQBjAQMAIAAyACwAMgBB AGwAbABnAGUAbQBlAGkAbgBlAHMAIABHAHIAYQB1AHMAdAB1AGYAZQBuAC0AUAByAG8AZgBpAGwAIABH -AGEAbQBtAGEAIAAyACwAMsd8vBgAINaMwMkAIKwQucgAIAAyAC4AMgAg1QS4XNMMx3xmbpAacHBepnz7 -ZXAAIAAyAC4AMgAgY8+P8GWHTvZOAIIsMLAw7DCkMKww8zDeACAAMgAuADIAIDDXMO0w1TChMKQw6wOT -A7UDvQO5A7oDzAAgA5MDugPBA7kAIAOTA6wDvAO8A7EAIAAyAC4AMgBQAGUAcgBmAGkAbAAgAGcAZQBu -AOkAcgBpAGMAbwAgAGQAZQAgAGMAaQBuAHoAZQBuAHQAbwBzACAAZABhACAARwBhAG0AbQBhACAAMgAs -ADIAQQBsAGcAZQBtAGUAZQBuACAAZwByAGkAagBzACAAZwBhAG0AbQBhACAAMgAsADIALQBwAHIAbwBm -AGkAZQBsAFAAZQByAGYAaQBsACAAZwBlAG4A6QByAGkAYwBvACAAZABlACAAZwBhAG0AbQBhACAAZABl -ACAAZwByAGkAcwBlAHMAIAAyACwAMg4jDjEOBw4qDjUOQQ4BDiEOIQ4yDkAOAQ4jDiIOTA4XDjEOSA4n -DkQOGwAgADIALgAyAEcAZQBuAGUAbAAgAEcAcgBpACAARwBhAG0AYQAgADIALAAyAFkAbABlAGkAbgBl -AG4AIABoAGEAcgBtAGEAYQBuACAAZwBhAG0AbQBhACAAMgAsADIAIAAtAHAAcgBvAGYAaQBpAGwAaQBH -AGUAbgBlAHIAaQENAGsAaQAgAEcAcgBhAHkAIABHAGEAbQBtAGEAIAAyAC4AMgAgAHAAcgBvAGYAaQBs -AFUAbgBpAHcAZQByAHMAYQBsAG4AeQAgAHAAcgBvAGYAaQBsACAAcwB6AGEAcgBvAVsAYwBpACAAZwBh -AG0AbQBhACAAMgAsADIEHgQxBEkEMARPACAEQQQ1BEAEMARPACAEMwQwBDwEPAQwACAAMgAsADIALQQ/ -BEAEPgREBDgEOwRMAEcAZQBuAGUAcgBpAGMAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABQ -AHIAbwBmAGkAbABlBjoGJwZFBicAIAAyAC4AMgAgBkQGSAZGACAGMQZFBicGLwZKACAGOQYnBkV0ZXh0 -AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDEyAABYWVogAAAAAAAA81EAAQAAAAEWzGN1cnYAAAAA -AAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3AHwAgQCG -AIsAkACVAJoAnwCkAKkArgCyALcAvADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQETARkBHwEl -ASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHpAfIB+gID -AgwCFAIdAiYCLwI4AkECSwJUAl0CZwJxAnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAMLAxYDIQMt -AzgDQwNPA1oDZgNyA34DigOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+BIwEmgSo -BLYExATTBOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicGNwZIBlkGagZ7 -BowGnQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgyCEYIWghuCIIIlgiq -CL4I0gjnCPsJEAklCToJTwlkCXkJjwmkCboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3ArzCwsLIgs5 -C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakNww3eDfgOEw4u -DkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPURExExEU8RbRGM -EaoRyRHoEgcSJhJFEmQShBKjEsMS4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTwFRIVNBVW -FXgVmxW9FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkgGUUZaxmR -GbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzMHPUdHh1HHXAdmR3DHeweFh5A -HmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFIIXUhoSHOIfsiJyJVIoIiryLdIwojOCNm -I5QjwiPwJB8kTSR8JKsk2iUJJTglaCWXJccl9yYnJlcmhya3JugnGCdJJ3onqyfcKA0oPyhxKKIo1CkG -KTgpaymdKdAqAio1KmgqmyrPKwIrNitpK50r0SwFLDksbiyiLNctDC1BLXYtqy3hLhYuTC6CLrcu7i8k -L1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUTNU01hzXC -Nf02NzZyNq426TckN2A3nDfXOBQ4UDiMOMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o76DwnPGU8pDzj -PSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/iQCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPARANER0SK -RM5FEkVVRZpF3kYiRmdGq0bwRzVHe0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpMcky6 -TQJNSk2TTdxOJU5uTrdPAE9JT5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSPVNtVKFV1 -VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1kaWWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSddeF3JXhpebF69 -Xw9fYV+zYAVgV2CqYPxhT2GiYfViSWKcYvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeTZ+loP2iW -aOxpQ2maafFqSGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpxlXHwcktypnMB -c11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJeed6RnqlewR7Y3vCfCF8gXzhfUF9oX4B -fmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSDV4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhpiM6JM4mZ -if6KZIrKizCLlov8jGOMyo0xjZiN/45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSKlPSVX5XJ -ljSWn5cKl3WX4JhMmLiZJJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFHobaiJqKW -owajdqPmpFakx6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6hrxavi7AA -sHWw6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6tbsuu6e8IbybvRW9j74K -voS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbDx0HHv8g9yLzJOsm5yjjKt8s2y7bMNcy1 -zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp22vvbgNwF -3IrdEN2W3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3mlucf56noMui86Ubp0Opb6uXrcOv7 -7IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe9m32+/eK+Bn4qPk4+cf6V/rn+3f8B/yY -/Sn9uv5L/tz/bf//0iorLC1aJGNsYXNzbmFtZVgkY2xhc3Nlc18QEE5TQml0bWFwSW1hZ2VSZXCjLC4v -Wk5TSW1hZ2VSZXBYTlNPYmplY3TSKisxMldOU0FycmF5ojEv0iorNDVeTlNNdXRhYmxlQXJyYXmjNDEv -0zc4Dzk6O1dOU1doaXRlXE5TQ29sb3JTcGFjZUQwIDAAEAOADNIqKz0+V05TQ29sb3KiPS/SKitAQVdO -U0ltYWdlokAvAAgAEQAaACQAKQAyADcASQBMAFEAUwBiAGgAdQB8AIsAkgCfAKYArgCwALIAtAC5ALsA -vQDEAMkA1ADWANgA2gDfAOIA5ADmAOgA7QEEAQYBCBNEE0kTVBNdE3ATdBN/E4gTjROVE5gTnROsE7AT -txO/E8wT0RPTE9UT2hPiE+UT6hPyAAAAAAAAAgEAAAAAAAAAQgAAAAAAAAAAAAAAAAAAE/U + AGEAbQBtAGEAIAAyACwAMgBQAHIAbwBmAGkAbABvACAAZwByAGkAZwBpAG8AIABnAGUAbgBlAHIAaQBj + AG8AIABkAGUAbABsAGEAIABnAGEAbQBtAGEAIAAyACwAMgBHAGUAbgBlAHIAaQBzAGsAIABnAHIA5QAg + ADIALAAyACAAZwBhAG0AbQBhAHAAcgBvAGYAaQBsZm6QGnBwXqZ8+2VwADIALgAyY8+P8GWHTvZOAIIs + MLAw7DCkMKww8zDeACAAMgAuADIAIDDXMO0w1TChMKQw6wOTA7UDvQO5A7oDzAAgA5MDugPBA7kAIAOT + A6wDvAO8A7EAIAAyAC4AMgBQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGMAaQBu + AHoAZQBuAHQAbwBzACAAZABhACAARwBhAG0AbQBhACAAMgAsADIAQQBsAGcAZQBtAGUAZQBuACAAZwBy + AGkAagBzACAAZwBhAG0AbQBhACAAMgAsADIALQBwAHIAbwBmAGkAZQBsAFAAZQByAGYAaQBsACAAZwBl + AG4A6QByAGkAYwBvACAAZABlACAAZwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBlAHMAIAAyACwAMg4j + DjEOBw4qDjUOQQ4BDiEOIQ4yDkAOAQ4jDiIOTA4XDjEOSA4nDkQOGwAgADIALgAyAEcAZQBuAGUAbAAg + AEcAcgBpACAARwBhAG0AYQAgADIALAAyAFkAbABlAGkAbgBlAG4AIABoAGEAcgBtAGEAYQBuACAAZwBh + AG0AbQBhACAAMgAsADIAIAAtAHAAcgBvAGYAaQBpAGwAaQBHAGUAbgBlAHIAaQENAGsAaQAgAEcAcgBh + AHkAIABHAGEAbQBtAGEAIAAyAC4AMgAgAHAAcgBvAGYAaQBsAFUAbgBpAHcAZQByAHMAYQBsAG4AeQAg + AHAAcgBvAGYAaQBsACAAcwB6AGEAcgBvAVsAYwBpACAAZwBhAG0AbQBhACAAMgAsADIGOgYnBkUGJwAg + ADIALgAyACAGRAZIBkYAIAYxBkUGJwYvBkoAIAY5BicGRQQeBDEESQQwBE8AIARBBDUEQAQwBE8AIAQz + BDAEPAQ8BDAAIAAyACwAMgAtBD8EQAQ+BEQEOAQ7BEwARwBlAG4AZQByAGkAYwAgAEcAcgBhAHkAIABH + AGEAbQBtAGEAIAAyAC4AMgAgAFAAcgBvAGYAaQBsAGUAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIElu + Yy4sIDIwMTIAAFhZWiAAAAAAAADzUQABAAAAARbMY3VydgAAAAAAAAQAAAAABQAKAA8AFAAZAB4AIwAo + AC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACBAIYAiwCQAJUAmgCfAKQAqQCuALIAtwC8 + AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7AQEBBwENARMBGQEfASUBKwEyATgBPgFFAUwBUgFZAWABZwFu + AXUBfAGDAYsBkgGaAaEBqQGxAbkBwQHJAdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgCQQJLAlQCXQJn + AnECegKEAo4CmAKiAqwCtgLBAssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNmA3IDfgOKA5YDogOu + A7oDxwPTA+AD7AP5BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASaBKgEtgTEBNME4QTwBP4FDQUcBSsFOgVJ + BVgFZwV3BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3BkgGWQZqBnsGjAadBq8GwAbRBuMG9QcHBxkHKwc9 + B08HYQd0B4YHmQesB78H0gflB/gICwgfCDIIRghaCG4IggiWCKoIvgjSCOcI+wkQCSUJOglPCWQJeQmP + CaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrcCvMLCwsiCzkLUQtpC4ALmAuwC8gL4Qv5DBIMKgxD + DFwMdQyODKcMwAzZDPMNDQ0mDUANWg10DY4NqQ3DDd4N+A4TDi4OSQ5kDn8Omw62DtIO7g8JDyUPQQ9e + D3oPlg+zD88P7BAJECYQQxBhEH4QmxC5ENcQ9RETETERTxFtEYwRqhHJEegSBxImEkUSZBKEEqMSwxLj + EwMTIxNDE2MTgxOkE8UT5RQGFCcUSRRqFIsUrRTOFPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbW + FvoXHRdBF2UXiReuF9IX9xgbGEAYZRiKGK8Y1Rj6GSAZRRlrGZEZtxndGgQaKhpRGncanhrFGuwbFBs7 + G2MbihuyG9ocAhwqHFIcexyjHMwc9R0eHUcdcB2ZHcMd7B4WHkAeah6UHr4e6R8THz4faR+UH78f6iAV + IEEgbCCYIMQg8CEcIUghdSGhIc4h+yInIlUigiKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVo + JZclxyX3JicmVyaHJrcm6CcYJ0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2 + K2krnSvRLAUsOSxuLKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDbMRIxSjGC + Mbox8jIqMmMymzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbpNyQ3YDecN9c4FDhQ + OIw4yDkFOUI5fzm8Ofk6Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1hPaE94D4gPmA+oD7gPyE/YT+i + P+JAI0BkQKZA50EpQWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RHRIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7 + R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrESwxLU0uaS+JMKkxyTLpNAk1KTZNN3E4lTm5Ot08AT0lPk0/d + UCdQcVC7UQZRUFGbUeZSMVJ8UsdTE1NfU6pT9lRCVI9U21UoVXVVwlYPVlxWqVb3V0RXklfgWC9YfVjL + WRpZaVm4WgdaVlqmWvVbRVuVW+VcNVyGXNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg/GFPYaJh9WJJ + Ypxi8GNDY5dj62RAZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpIap9q92tPa6dr/2xX + bK9tCG1gbbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFzXXO4dBR0cHTMdSh1hXXhdj52m3b4 + d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyBfOF9QX2hfgF+Yn7CfyN/hH/lgEeAqIEKgWuBzYIw + gpKC9INXg7qEHYSAhOOFR4Wrhg6GcobXhzuHn4gEiGmIzokziZmJ/opkisqLMIuWi/yMY4zKjTGNmI3/ + jmaOzo82j56QBpBukNaRP5GokhGSepLjk02TtpQglIqU9JVflcmWNJaflwqXdZfgmEyYuJkkmZCZ/Jpo + mtWbQpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUehtqImopajBqN2o+akVqTHpTilqaYapoum/adu + p+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4trqGvFq+LsACwdbDqsWCx1rJLssKzOLOutCW0nLUT + tYq2AbZ5tvC3aLfguFm40blKucK6O7q1uy67p7whvJu9Fb2Pvgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NY + w9TEUcTOxUvFyMZGxsPHQce/yD3IvMk6ybnKOMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/ + 0sHTRNPG1EnUy9VO1dHWVdbY11zX4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM + 4lPi2+Nj4+vkc+T85YTmDeaW5x/nqegy6LzpRunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/ + 8ozzGfOn9DT0wvVQ9d72bfb794r4Gfio+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t///SLS4vMFokY2xh + c3NuYW1lWCRjbGFzc2VzXxAQTlNCaXRtYXBJbWFnZVJlcKMvMTJaTlNJbWFnZVJlcFhOU09iamVjdNIt + LjQ1V05TQXJyYXmiNDLSLS43OF5OU011dGFibGVBcnJheaM3NDLTOjsOPD0+V05TV2hpdGVcTlNDb2xv + clNwYWNlRDAgMAAQA4AM0i0uQEFXTlNDb2xvcqJAMtItLkNEV05TSW1hZ2WiQzIACAARABoAJAApADIA + NwBJAEwAUQBTAGIAaAB3AH4AhQCSAJkApQCtALwAvgDAAMUAxwDJAMsAzQDUANkA5ADmAOgA6gDvAPIA + 9AD2APgA/wEWATIBNAE2E6YTqxO2E78T0hPWE+ET6hPvE/cT+hP/FA4UEhQZFCEULhQzFDUUNxQ8FEQU + RxRMFFQAAAAAAAACAQAAAAAAAABFAAAAAAAAAAAAAAAAAAAUVw diff --git a/i18n/src/main/resources/en.lproj/Prompt.xib b/i18n/src/main/resources/en.lproj/Prompt.xib index 2d32fe1d0f3..bfabcbc7523 100644 --- a/i18n/src/main/resources/en.lproj/Prompt.xib +++ b/i18n/src/main/resources/en.lproj/Prompt.xib @@ -1,7 +1,8 @@ - + - + @@ -28,12 +29,13 @@ - + - - + @@ -140,7 +146,9 @@ Gw - + @@ -149,7 +157,9 @@ Gw - + @@ -158,7 +168,9 @@ Gw - + @@ -167,7 +179,9 @@ Gw - + @@ -176,7 +190,9 @@ Gw - + @@ -185,7 +201,9 @@ Gw - + @@ -194,7 +212,9 @@ Gw - + @@ -203,7 +223,9 @@ Gw - + diff --git a/importer/dll/pom.xml b/importer/dll/pom.xml index 578b1680d69..7c537b51bc9 100644 --- a/importer/dll/pom.xml +++ b/importer/dll/pom.xml @@ -5,7 +5,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Importer pom diff --git a/importer/pom.xml b/importer/pom.xml index ce26c4d384d..bcc28d28960 100644 --- a/importer/pom.xml +++ b/importer/pom.xml @@ -18,7 +18,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT 4.0.0 diff --git a/irods/pom.xml b/irods/pom.xml index ba6609fe2c5..a17ef4b750f 100644 --- a/irods/pom.xml +++ b/irods/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT irods jar diff --git a/jersey/pom.xml b/jersey/pom.xml index 76f0faf8abc..92d15c2fe54 100644 --- a/jersey/pom.xml +++ b/jersey/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT jersey diff --git a/manta/pom.xml b/manta/pom.xml index 0ee20aeba2c..64e571cf26e 100644 --- a/manta/pom.xml +++ b/manta/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT manta diff --git a/manta/src/main/java/ch/cyberduck/core/manta/MantaMoveFeature.java b/manta/src/main/java/ch/cyberduck/core/manta/MantaMoveFeature.java index d8efbf4d722..c1dde0b4eab 100644 --- a/manta/src/main/java/ch/cyberduck/core/manta/MantaMoveFeature.java +++ b/manta/src/main/java/ch/cyberduck/core/manta/MantaMoveFeature.java @@ -48,7 +48,7 @@ public Path move(final Path file, final Path renamed, final TransferStatus statu try { session.getClient().move(file.getAbsolute(), renamed.getAbsolute()); // Copy original file attributes - return new Path(renamed).withAttributes(new PathAttributes(file.attributes()).setVault(null)); + return new Path(renamed).withAttributes(new PathAttributes(file.attributes()).setVaultMetadata(null)); } catch(MantaException e) { throw new MantaExceptionMappingService().map("Cannot rename {0}", e, file); diff --git a/nextcloud/pom.xml b/nextcloud/pom.xml index d4dfd605051..3bafa19d80a 100644 --- a/nextcloud/pom.xml +++ b/nextcloud/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT nextcloud jar diff --git a/nio/pom.xml b/nio/pom.xml index 7171f186155..c5fac97f6bd 100644 --- a/nio/pom.xml +++ b/nio/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT nio jar diff --git a/nio/src/test/java/ch/cyberduck/core/cryptomator/CryptoLocalSingleTransferWorkerTest.java b/nio/src/test/java/ch/cyberduck/core/cryptomator/CryptoLocalSingleTransferWorkerTest.java index c000350effb..cd5920e5371 100644 --- a/nio/src/test/java/ch/cyberduck/core/cryptomator/CryptoLocalSingleTransferWorkerTest.java +++ b/nio/src/test/java/ch/cyberduck/core/cryptomator/CryptoLocalSingleTransferWorkerTest.java @@ -44,7 +44,6 @@ import ch.cyberduck.core.nio.LocalReadFeature; import ch.cyberduck.core.nio.LocalSession; import ch.cyberduck.core.notification.DisabledNotificationService; -import ch.cyberduck.core.preferences.PreferencesFactory; import ch.cyberduck.core.proxy.DisabledProxyFinder; import ch.cyberduck.core.transfer.DisabledTransferErrorCallback; import ch.cyberduck.core.transfer.DisabledTransferPrompt; @@ -57,6 +56,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -82,11 +82,11 @@ public class CryptoLocalSingleTransferWorkerTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @Test public void testUpload() throws Exception { @@ -113,15 +113,14 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback() { @Override public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { return new VaultCredentials("test"); } })); - PreferencesFactory.get().setProperty("factory.vault.class", CryptoVault.class.getName()); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { @Override diff --git a/oauth/pom.xml b/oauth/pom.xml index 89b0245d4e6..f425d1de9fd 100644 --- a/oauth/pom.xml +++ b/oauth/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT oauth diff --git a/onedrive/pom.xml b/onedrive/pom.xml index 04d2328c88f..a2e22527a1f 100644 --- a/onedrive/pom.xml +++ b/onedrive/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT onedrive diff --git a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index b48b7f32d91..57fe57cbb64 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -47,12 +47,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -66,7 +68,6 @@ import java.util.EnumSet; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -78,8 +79,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -105,8 +106,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -123,15 +124,15 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -153,8 +154,8 @@ public void testCopyFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( @@ -190,8 +191,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new GraphFindFeature(session, fileid).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( @@ -221,8 +222,8 @@ public void testCopyDirectoryIntoVault() throws Exception { session).touch(new GraphWriteFeature(session, fileid), cleartextFile, new TransferStatus()); assertTrue(new GraphFindFeature(session, fileid).find(cleartextFolder)); assertTrue(new GraphFindFeature(session, fileid).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -246,8 +247,8 @@ public void testCopyFileOutsideVault() throws Exception { new GraphDirectoryFeature(session, fileid).mkdir(new GraphWriteFeature(session, fileid), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( @@ -272,8 +273,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( diff --git a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/CryptoOneDriveSingleTransferWorkerTest.java b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/CryptoOneDriveSingleTransferWorkerTest.java index dcbb526d07f..1ef3e24ab06 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/CryptoOneDriveSingleTransferWorkerTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/CryptoOneDriveSingleTransferWorkerTest.java @@ -50,6 +50,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -91,8 +92,8 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { diff --git a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphDirectoryFeatureTest.java b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphDirectoryFeatureTest.java index 9fdc54709f3..ae3907b16ab 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphDirectoryFeatureTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphDirectoryFeatureTest.java @@ -40,8 +40,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -53,7 +55,6 @@ import java.util.stream.Collectors; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -63,8 +64,8 @@ public class GraphDirectoryFeatureTest extends AbstractOneDriveTest { public void testMakeDirectoryEncrypted() throws Exception { final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( cryptomator.getFeature(session, Write.class, new GraphWriteFeature(session, fileid)), new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); @@ -84,12 +85,12 @@ public void testMakeDirectoryEncrypted() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( cryptomator.getFeature(session, Write.class, new GraphWriteFeature(session, fileid)), new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); diff --git a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphMoveFeatureTest.java b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphMoveFeatureTest.java index 12de9fca06c..2dbaf874da5 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphMoveFeatureTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphMoveFeatureTest.java @@ -40,6 +40,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -62,8 +63,8 @@ public void testMove() throws Exception { final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( cryptomator.getFeature(session, Write.class, new GraphWriteFeature(session, fileid)), folder, new TransferStatus()); diff --git a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphTouchFeatureTest.java b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphTouchFeatureTest.java index be98c69d2fc..0aeaaf9a83c 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphTouchFeatureTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphTouchFeatureTest.java @@ -36,8 +36,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -48,19 +50,18 @@ import java.util.EnumSet; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) public class GraphTouchFeatureTest extends AbstractOneDriveTest { @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( @@ -76,12 +77,12 @@ public void testTouchLongFilenameEncrypted() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), cryptomator).touch( diff --git a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphWriteFeatureTest.java b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphWriteFeatureTest.java index 875948c1662..98bd4a30524 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphWriteFeatureTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/GraphWriteFeatureTest.java @@ -40,6 +40,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -72,8 +73,8 @@ public void testWrite() throws Exception { final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new GraphWriteFeature(session, fileid), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); diff --git a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java index 13ac904b2aa..b0e995662af 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java @@ -52,11 +52,13 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.MoveWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -70,7 +72,6 @@ import java.util.EnumSet; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -82,8 +83,8 @@ public void testMoveSameFolderCryptomator() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final byte[] content = RandomUtils.nextBytes(40500); final TransferStatus status = new TransferStatus(); @@ -107,8 +108,8 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(cryptomator.getFeature(session, Write.class, new GraphWriteFeature(session, fileid)), source, new TransferStatus()); @@ -123,16 +124,17 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { cryptomator.getFeature(session, Delete.class, new GraphDeleteFeature(session, fileid)).delete(Arrays.asList(target, targetFolder, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); } + //TODO @Test + @Ignore("Filename shortening not yet implemented") public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(cryptomator.getFeature(session, Write.class, new GraphWriteFeature(session, fileid)), source, new TransferStatus()); @@ -153,8 +155,8 @@ public void testMoveFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( cryptomator.getFeature(session, Write.class, new GraphWriteFeature(session, fileid)), folder, new TransferStatus()); @@ -187,8 +189,8 @@ public void testMoveFileIntoVault() throws Exception { assertTrue(new DefaultFindFeature(session).find(clearFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( @@ -214,8 +216,8 @@ public void testMoveDirectoryIntoVault() throws Exception { session).touch(new GraphWriteFeature(session, fileid), clearFile, new TransferStatus()); assertTrue(new DefaultFindFeature(session).find(clearFolder)); assertTrue(new DefaultFindFeature(session).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -239,8 +241,8 @@ public void testMoveFileOutsideVault() throws Exception { new GraphDirectoryFeature(session, fileid).mkdir(new GraphWriteFeature(session, fileid), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( @@ -267,8 +269,8 @@ public void testMoveDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new GraphDirectoryFeature(session, fileid)).mkdir( diff --git a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/OneDriveListServiceTest.java b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/OneDriveListServiceTest.java index b7a15b186eb..48ac0dbb726 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/cryptomator/OneDriveListServiceTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/cryptomator/OneDriveListServiceTest.java @@ -34,6 +34,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -57,8 +58,8 @@ public void testListCryptomator() throws Exception { final Path home = new OneDriveHomeFinderService().find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertTrue(new CryptoListService(session, new GraphItemListService(session, fileid), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); new CryptoTouchFeature<>(session, new DefaultTouchFeature( diff --git a/onedrive/src/test/java/ch/cyberduck/core/onedrive/AbstractOneDriveTest.java b/onedrive/src/test/java/ch/cyberduck/core/onedrive/AbstractOneDriveTest.java index 26e9e131eb9..bb01fa9da76 100644 --- a/onedrive/src/test/java/ch/cyberduck/core/onedrive/AbstractOneDriveTest.java +++ b/onedrive/src/test/java/ch/cyberduck/core/onedrive/AbstractOneDriveTest.java @@ -20,9 +20,9 @@ import ch.cyberduck.core.HostPasswordStore; import ch.cyberduck.core.Protocol; import ch.cyberduck.core.Scheme; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.ssl.X509KeyManager; import ch.cyberduck.core.ssl.X509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.runners.Parameterized; @@ -34,11 +34,11 @@ public abstract class AbstractOneDriveTest extends AbstractGraphTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @Override protected Protocol protocol() { diff --git a/openstack/pom.xml b/openstack/pom.xml index 64dbee46605..97e1956d429 100644 --- a/openstack/pom.xml +++ b/openstack/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT openstack jar diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index bb939ea9231..3feb8e8103e 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -46,12 +46,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -66,7 +68,6 @@ import ch.iterate.openstack.swift.model.StorageObject; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -78,8 +79,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -104,8 +105,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -122,15 +123,15 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("test.cyberduck.ch", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -152,8 +153,8 @@ public void testCopyFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SwiftDirectoryFeature(session)).mkdir( @@ -189,8 +190,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new SwiftFindFeature(session).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SwiftDirectoryFeature(session)).mkdir( @@ -218,8 +219,8 @@ public void testCopyDirectoryIntoVault() throws Exception { new SwiftTouchFeature(session, new SwiftRegionService(session)).touch(new SwiftWriteFeature(session, new SwiftRegionService(session)), cleartextFile, new TransferStatus()); assertTrue(new SwiftFindFeature(session).find(cleartextFolder)); assertTrue(new SwiftFindFeature(session).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -243,8 +244,8 @@ public void testCopyFileOutsideVault() throws Exception { new SwiftDirectoryFeature(session).mkdir(new SwiftWriteFeature(session, new SwiftRegionService(session)), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SwiftDirectoryFeature(session)).mkdir( @@ -269,8 +270,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SwiftDirectoryFeature(session)).mkdir( diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/CryptoSwiftSingleTransferWorkerTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/CryptoSwiftSingleTransferWorkerTest.java index 67e32df7521..0a1660cfd7d 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/CryptoSwiftSingleTransferWorkerTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/CryptoSwiftSingleTransferWorkerTest.java @@ -50,6 +50,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -91,8 +92,8 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftDirectoryFeatureTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftDirectoryFeatureTest.java index 16a9a6f0218..4e4bb919cd1 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftDirectoryFeatureTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftDirectoryFeatureTest.java @@ -32,8 +32,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -43,7 +45,6 @@ import java.util.EnumSet; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -54,8 +55,8 @@ public void testMakeDirectoryEncrypted() throws Exception { final Path home = new Path("/test.cyberduck.ch", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SwiftDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new SwiftWriteFeature(session, new SwiftRegionService(session))), test, new TransferStatus()); @@ -64,13 +65,13 @@ public void testMakeDirectoryEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not yet implemented") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("/test.cyberduck.ch", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SwiftDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new SwiftWriteFeature(session, new SwiftRegionService(session))), test, new TransferStatus()); diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftLargeObjectUploadFeatureTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftLargeObjectUploadFeatureTest.java index 3044112839d..cfd30588f7d 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftLargeObjectUploadFeatureTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftLargeObjectUploadFeatureTest.java @@ -43,6 +43,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -74,8 +75,8 @@ public void testLargeObjectUpload() throws Exception { home.attributes().setRegion("IAD"); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final SwiftRegionService regionService = new SwiftRegionService(session); final CryptoUploadFeature service = new CryptoUploadFeature<>(session, diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftLargeUploadWriteFeatureTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftLargeUploadWriteFeatureTest.java index 3d3d54518c0..d2ec933a8da 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftLargeUploadWriteFeatureTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftLargeUploadWriteFeatureTest.java @@ -37,6 +37,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -65,8 +66,8 @@ public void testWrite() throws Exception { home.attributes().setRegion("IAD"); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final SwiftRegionService regionService = new SwiftRegionService(session); final CryptoWriteFeature feature = new CryptoWriteFeature<>(session, new SwiftLargeUploadWriteFeature(session, regionService, diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftListServiceTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftListServiceTest.java index eb7c9e2507d..6a6adc0a1a4 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftListServiceTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftListServiceTest.java @@ -33,6 +33,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -58,8 +59,8 @@ public void testListCryptomator() throws Exception { home.attributes().setRegion("IAD"); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertTrue(new CryptoListService(session, new SwiftObjectListService(session), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); final SwiftRegionService regionService = new SwiftRegionService(session); diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftMoveFeatureTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftMoveFeatureTest.java index 4d55f73a363..ed5abfda566 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftMoveFeatureTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftMoveFeatureTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -61,8 +62,8 @@ public void testMove() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final SwiftRegionService regionService = new SwiftRegionService(session); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SwiftDirectoryFeature(session, regionService)).mkdir( diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftTouchFeatureTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftTouchFeatureTest.java index b1e15592eca..1552d6512f5 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftTouchFeatureTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftTouchFeatureTest.java @@ -34,8 +34,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -48,19 +50,20 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) public class SwiftTouchFeatureTest extends AbstractSwiftTest { + //TODO + @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("/test.cyberduck.ch", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final SwiftRegionService regionService = new SwiftRegionService(session); final TransferStatus status = new TransferStatus(); @@ -73,12 +76,12 @@ public void testTouchLongFilenameEncrypted() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("/test.cyberduck.ch", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final Path test = new CryptoTouchFeature(session, new DefaultTouchFeature<>(session), cryptomator).touch( diff --git a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftWriteFeatureTest.java b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftWriteFeatureTest.java index f9efdbf7c60..add35c21d6a 100644 --- a/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftWriteFeatureTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/cryptomator/SwiftWriteFeatureTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -72,8 +73,8 @@ public void testWrite() throws Exception { home.attributes().setRegion("IAD"); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final SwiftRegionService regionService = new SwiftRegionService(session); final CryptoWriteFeature writer = new CryptoWriteFeature(session, new SwiftWriteFeature(session, regionService), cryptomator); diff --git a/openstack/src/test/java/ch/cyberduck/core/openstack/AbstractSwiftTest.java b/openstack/src/test/java/ch/cyberduck/core/openstack/AbstractSwiftTest.java index fed502ac0eb..d4ce50d6f93 100644 --- a/openstack/src/test/java/ch/cyberduck/core/openstack/AbstractSwiftTest.java +++ b/openstack/src/test/java/ch/cyberduck/core/openstack/AbstractSwiftTest.java @@ -24,9 +24,9 @@ import ch.cyberduck.core.Host; import ch.cyberduck.core.LoginConnectionService; import ch.cyberduck.core.LoginOptions; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DisabledX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -41,11 +41,11 @@ public abstract class AbstractSwiftTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { @@ -64,7 +64,7 @@ public Credentials prompt(final Host bookmark, final String title, final String return null; } }, new DisabledHostKeyCallback(), - new DisabledPasswordStore(), new DisabledProgressListener()); + new DisabledPasswordStore(), new DisabledProgressListener()); login.check(session, new DisabledCancelCallback()); } } diff --git a/osx/pom.xml b/osx/pom.xml index 82d6ca8323c..990abec5a70 100644 --- a/osx/pom.xml +++ b/osx/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT osx jar diff --git a/osx/src/main/java/ch/cyberduck/ui/cocoa/ApplicationUserDefaultsPreferences.java b/osx/src/main/java/ch/cyberduck/ui/cocoa/ApplicationUserDefaultsPreferences.java index bbac4a1fc1c..311746e7144 100644 --- a/osx/src/main/java/ch/cyberduck/ui/cocoa/ApplicationUserDefaultsPreferences.java +++ b/osx/src/main/java/ch/cyberduck/ui/cocoa/ApplicationUserDefaultsPreferences.java @@ -19,7 +19,7 @@ */ import ch.cyberduck.core.bonjour.RendezvousResponder; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.CryptoVaultProvider; import ch.cyberduck.core.cryptomator.random.FastSecureRandomProvider; import ch.cyberduck.core.local.FinderLocal; import ch.cyberduck.core.preferences.ApplicationPreferences; @@ -104,7 +104,7 @@ protected void setFactories() { this.setDefault("factory.transferpromptcallback.copy.class", CopyPromptController.class.getName()); this.setDefault("factory.transferpromptcallback.sync.class", SyncPromptController.class.getName()); this.setDefault("factory.rendezvous.class", RendezvousResponder.class.getName()); - this.setDefault("factory.vault.class", CryptoVault.class.getName()); + this.setDefault("factory.vault.class", CryptoVaultProvider.class.getName()); this.setDefault("factory.securerandom.class", FastSecureRandomProvider.class.getName()); } } diff --git a/osx/src/main/java/ch/cyberduck/ui/cocoa/controller/BrowserController.java b/osx/src/main/java/ch/cyberduck/ui/cocoa/controller/BrowserController.java index c92be45b1b0..dd20324a239 100644 --- a/osx/src/main/java/ch/cyberduck/ui/cocoa/controller/BrowserController.java +++ b/osx/src/main/java/ch/cyberduck/ui/cocoa/controller/BrowserController.java @@ -64,7 +64,6 @@ import ch.cyberduck.core.pasteboard.PathPasteboard; import ch.cyberduck.core.pasteboard.PathPasteboardFactory; import ch.cyberduck.core.pool.SessionPool; -import ch.cyberduck.core.preferences.HostPreferencesFactory; import ch.cyberduck.core.preferences.Preferences; import ch.cyberduck.core.preferences.PreferencesFactory; import ch.cyberduck.core.resources.IconCacheFactory; @@ -88,7 +87,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.LoadingVaultLookupListener; import ch.cyberduck.core.vault.VaultCredentials; -import ch.cyberduck.core.vault.VaultFactory; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.vault.VaultRegistry; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.CreateDirectoryWorker; @@ -142,7 +141,6 @@ import org.rococoa.cocoa.foundation.NSSize; import org.rococoa.cocoa.foundation.NSUInteger; -import java.nio.charset.StandardCharsets; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.text.MessageFormat; @@ -2432,12 +2430,10 @@ public void createEncryptedVaultButtonClicked(final ID sender) { @Override public void callback(final Path folder, final String region, final VaultCredentials passphrase) { background(new WorkerBackgroundAction<>(BrowserController.this, pool, - new CreateVaultWorker(region, passphrase, VaultFactory.get(folder, - HostPreferencesFactory.get(pool.getHost()).getProperty("cryptomator.vault.masterkey.filename"), - HostPreferencesFactory.get(pool.getHost()).getProperty("cryptomator.vault.config.filename"), - HostPreferencesFactory.get(pool.getHost()).getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8))) { + new CreateVaultWorker(region, passphrase, + new VaultMetadata(folder, VaultMetadata.Type.valueOf(preferences.getProperty("cryptomator.vault.default")))) { @Override - public void cleanup(final Path vault) { + public void cleanup(final Vault vault) { reload(BrowserController.this.workdir, Collections.singletonList(folder), Collections.singletonList(folder)); } }) @@ -2450,9 +2446,9 @@ public void cleanup(final Path vault) { @Action public void lockUnlockEncryptedVaultButtonClicked(final ID sender) { final Path directory = new UploadTargetFinder(workdir).find(this.getSelectedPath()); - if(directory.attributes().getVault() != null) { + if(directory.attributes().getVaultMetadata() != null) { // Lock and remove all open vaults - this.background(new WorkerBackgroundAction<>(this, pool, new LockVaultWorker(pool.getVaultRegistry(), directory.attributes().getVault()) { + this.background(new WorkerBackgroundAction<>(this, pool, new LockVaultWorker(pool.getVaultRegistry(), directory.attributes().getVaultMetadata().root) { @Override public void cleanup(final Path vault) { if(vault != null) { @@ -2464,7 +2460,8 @@ public void cleanup(final Path vault) { else { // Unlock vault this.background(new WorkerBackgroundAction<>(this, pool, new LoadVaultWorker(new LoadingVaultLookupListener(pool.getVaultRegistry(), - PasswordCallbackFactory.get(this)), directory) { + PasswordCallbackFactory.get(this)), + new VaultMetadata(directory, VaultMetadata.Type.valueOf(preferences.getProperty("cryptomator.vault.default")))) { @Override public void cleanup(final Vault vault) { if(vault != null) { diff --git a/osx/src/main/java/ch/cyberduck/ui/cocoa/toolbar/BrowserToolbarValidator.java b/osx/src/main/java/ch/cyberduck/ui/cocoa/toolbar/BrowserToolbarValidator.java index 4b1e73af4c3..b0a71df8f03 100644 --- a/osx/src/main/java/ch/cyberduck/ui/cocoa/toolbar/BrowserToolbarValidator.java +++ b/osx/src/main/java/ch/cyberduck/ui/cocoa/toolbar/BrowserToolbarValidator.java @@ -241,7 +241,7 @@ else if(action.equals(newfolder.action())) { } else if(action.equals(Foundation.selector("createEncryptedVaultButtonClicked:"))) { return this.isBrowser() && controller.isMounted() && controller.getSession().getVaultRegistry() != VaultRegistry.DISABLED && - null == controller.workdir().attributes().getVault() && + null == controller.workdir().attributes().getVaultMetadata() && controller.getSession().getFeature(Directory.class).isSupported( new UploadTargetFinder(controller.workdir()).find(controller.getSelectedPath()), StringUtils.EMPTY ); diff --git a/owncloud/pom.xml b/owncloud/pom.xml index 92a8ed6aa59..8e5ca683a92 100644 --- a/owncloud/pom.xml +++ b/owncloud/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT owncloud jar diff --git a/owncloud/src/test/java/ch/cyberduck/core/cryptomator/OcisUploadFeatureTest.java b/owncloud/src/test/java/ch/cyberduck/core/cryptomator/OcisUploadFeatureTest.java index 8d697d3e176..b8d8139ca90 100644 --- a/owncloud/src/test/java/ch/cyberduck/core/cryptomator/OcisUploadFeatureTest.java +++ b/owncloud/src/test/java/ch/cyberduck/core/cryptomator/OcisUploadFeatureTest.java @@ -46,6 +46,7 @@ import ch.cyberduck.core.tus.TusWriteFeature; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -75,9 +76,9 @@ public void testUploadVault() throws Exception { // 5L * 1024L * 1024L final Path directory = new DAVDirectoryFeature(session).mkdir(new NextcloudWriteFeature(session), new Path(new OwncloudHomeFeature(session.getHost()).find(), new AlphanumericRandomStringService().random(), EnumSet.of(AbstractPath.Type.directory)), new TransferStatus()); - final CryptoVault cryptomator = new CryptoVault( - new Path(directory, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(directory, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TusCapabilities capabilities = new TusCapabilities().withHashAlgorithm(HashAlgorithm.sha1); final CryptoUploadFeature service = new CryptoUploadFeature<>(session, diff --git a/owncloud/src/test/java/ch/cyberduck/core/owncloud/AbstractOcisTest.java b/owncloud/src/test/java/ch/cyberduck/core/owncloud/AbstractOcisTest.java index a585766e9a9..7de91c8efd3 100644 --- a/owncloud/src/test/java/ch/cyberduck/core/owncloud/AbstractOcisTest.java +++ b/owncloud/src/test/java/ch/cyberduck/core/owncloud/AbstractOcisTest.java @@ -27,10 +27,10 @@ import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; import ch.cyberduck.core.Scheme; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -48,11 +48,11 @@ public class AbstractOcisTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/pom.xml b/pom.xml index 35279ea92dd..6e58140ca46 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ parent Cyberduck pom - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT defaults @@ -93,6 +93,7 @@ 8u312b07 0.10.0 ch.cyberduck.test.IntegrationTest + ch.cyberduck.core.cryptomator.SFTPCryptomatorInteroperabilityTest @@ -563,6 +564,9 @@ ${project.build.directory} ${surefire.group.excluded} + + ${surefire.exclude} + false diff --git a/profiles/pom.xml b/profiles/pom.xml index be1312dfefc..c4db6609656 100644 --- a/profiles/pom.xml +++ b/profiles/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT profiles jar diff --git a/protocols/dll/pom.xml b/protocols/dll/pom.xml index abc082759b6..4497040cc0a 100644 --- a/protocols/dll/pom.xml +++ b/protocols/dll/pom.xml @@ -5,7 +5,7 @@ ch.cyberduck parent ../../pom.xml - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT Cyberduck.Protocols pom diff --git a/protocols/pom.xml b/protocols/pom.xml index e2c9aeb96b8..6754eafc6b0 100644 --- a/protocols/pom.xml +++ b/protocols/pom.xml @@ -18,7 +18,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT 4.0.0 pom diff --git a/s3/pom.xml b/s3/pom.xml index 02750aa06f0..38ebd9b0c9f 100644 --- a/s3/pom.xml +++ b/s3/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT s3 jar diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index ec59a84f522..1e5d59186af 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -46,12 +46,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -64,7 +66,6 @@ import java.util.EnumSet; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -76,8 +77,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -103,8 +104,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); @@ -123,11 +124,12 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault(new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); @@ -151,8 +153,9 @@ public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception @Test public void testCopyFolder() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); - final CryptoVault cryptomator = new CryptoVault(new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory))); - final Path vault = cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); @@ -191,8 +194,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new S3FindFeature(session, acl).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new S3DirectoryFeature(session, acl)).mkdir( @@ -221,8 +224,8 @@ public void testCopyDirectoryIntoVault() throws Exception { new S3TouchFeature(session, acl).touch(new S3WriteFeature(session, acl), cleartextFile, new TransferStatus()); assertTrue(new S3FindFeature(session, acl).find(cleartextFolder)); assertTrue(new S3FindFeature(session, acl).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -247,8 +250,8 @@ public void testCopyFileOutsideVault() throws Exception { new S3DirectoryFeature(session, acl).mkdir(new S3WriteFeature(session, acl), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new S3DirectoryFeature(session, acl)).mkdir( @@ -273,8 +276,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/CryptoS3SingleTransferWorkerTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/CryptoS3SingleTransferWorkerTest.java index 76dc330b928..e19b7d0f1e6 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/CryptoS3SingleTransferWorkerTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/CryptoS3SingleTransferWorkerTest.java @@ -50,6 +50,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -91,8 +92,8 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java index 7f1010f3417..6fbae9cd21a 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java @@ -52,11 +52,13 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.MoveWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -70,7 +72,6 @@ import java.util.UUID; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -82,8 +83,8 @@ public void testMoveSameFolderCryptomator() throws Exception { final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final byte[] content = RandomUtils.nextBytes(40500); final TransferStatus status = new TransferStatus(); @@ -106,8 +107,8 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); new CryptoTouchFeature<>(session, new S3TouchFeature(session, acl), cryptomator).touch( @@ -125,13 +126,13 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); new CryptoTouchFeature<>(session, new S3TouchFeature(session, acl), cryptomator).touch( @@ -152,8 +153,8 @@ public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception public void testMoveFolder() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final Path folder = cryptomator.getFeature(session, Directory.class, new S3DirectoryFeature(session, acl)).mkdir( @@ -193,8 +194,8 @@ public void testMoveFileIntoVault() throws Exception { final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); new S3TouchFeature(session, acl).touch(new S3WriteFeature(session, new S3AccessControlListFeature(session)), clearFile, new TransferStatus()); assertTrue(new S3FindFeature(session, acl).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final Path encryptedFolder = cryptomator.getFeature(session, Directory.class, new S3DirectoryFeature(session, acl)).mkdir( @@ -220,8 +221,8 @@ public void testMoveDirectoryIntoVault() throws Exception { new S3TouchFeature(session, acl).touch(new S3WriteFeature(session, new S3AccessControlListFeature(session)), clearFile, new TransferStatus()); assertTrue(new S3FindFeature(session, acl).find(clearFolder)); assertTrue(new S3FindFeature(session, acl).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -244,8 +245,8 @@ public void testMoveFileOutsideVault() throws Exception { final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final Path clearFolder = new S3DirectoryFeature(session, acl).mkdir( new S3WriteFeature(session, acl), new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus()); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final Path encryptedFolder = cryptomator.getFeature(session, Directory.class, new S3DirectoryFeature(session, acl)).mkdir( @@ -270,8 +271,8 @@ public void testMoveFileOutsideVault() throws Exception { public void testMoveDirectoryOutsideVault() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3DirectoryFeatureTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3DirectoryFeatureTest.java index 0a39e12db47..47dca475d8a 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3DirectoryFeatureTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3DirectoryFeatureTest.java @@ -38,8 +38,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -51,7 +53,6 @@ import java.util.stream.Collectors; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -61,8 +62,8 @@ public class S3DirectoryFeatureTest extends AbstractS3Test { public void testMakeDirectoryEncrypted() throws Exception { final Path home = new Path("versioning-test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final Path test = cryptomator.getFeature(session, Directory.class, new S3DirectoryFeature(session, acl)).mkdir( @@ -79,12 +80,12 @@ public void testMakeDirectoryEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final Path test = cryptomator.getFeature(session, Directory.class, new S3DirectoryFeature(session, acl)).mkdir( diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MoveFeatureTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MoveFeatureTest.java index 7d3a0a6bd8e..1949acfa711 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MoveFeatureTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MoveFeatureTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -61,8 +62,8 @@ public void testMove() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); cryptomator.getFeature(session, Directory.class, new S3DirectoryFeature(session, acl)).mkdir( diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MultipartUploadServiceTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MultipartUploadServiceTest.java index c53c19e2b46..6ba72e2526e 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MultipartUploadServiceTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MultipartUploadServiceTest.java @@ -47,6 +47,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -78,8 +79,8 @@ public void testUploadSinglePart() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final CryptoUploadFeature m = new CryptoUploadFeature<>(session, @@ -114,8 +115,8 @@ public void testUpload() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final CryptoUploadFeature m = new CryptoUploadFeature<>(session, @@ -147,8 +148,8 @@ public void testUploadWithBulk() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus writeStatus = new TransferStatus(); final byte[] content = RandomUtils.nextBytes(6 * 1024 * 1024); diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MultipartWriteFeatureTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MultipartWriteFeatureTest.java index e2429a530ed..04b2bef6aec 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MultipartWriteFeatureTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3MultipartWriteFeatureTest.java @@ -37,6 +37,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -63,8 +64,8 @@ public void testWrite() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final CryptoWriteFeature feature = new CryptoWriteFeature<>(session, new S3MultipartWriteFeature(session, acl), cryptomator); diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3ObjectListServiceTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3ObjectListServiceTest.java index 9ab29fa168f..d327f99d877 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3ObjectListServiceTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3ObjectListServiceTest.java @@ -33,6 +33,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -55,8 +56,8 @@ public void testListCryptomator() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); assertTrue(new CryptoListService(session, new S3ObjectListService(session, acl), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3SingleUploadServiceTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3SingleUploadServiceTest.java index 9a5395beac7..aa5098b29d8 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3SingleUploadServiceTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3SingleUploadServiceTest.java @@ -42,6 +42,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; @@ -70,8 +71,8 @@ public void testUploadVault() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Local local = new Local(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); final int length = 5242880; diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3TouchFeatureTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3TouchFeatureTest.java index 6ff42ecdb32..beec3ffc61f 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3TouchFeatureTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3TouchFeatureTest.java @@ -36,6 +36,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.jets3t.service.model.StorageObject; @@ -50,7 +51,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -60,8 +60,8 @@ public class S3TouchFeatureTest extends AbstractS3Test { public void testTouchEncrypted() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); @@ -75,12 +75,12 @@ public void testTouchEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); @@ -97,8 +97,8 @@ public void testTouchLongFilenameEncrypted() throws Exception { public void testTouchEncryptedDefaultFeature() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final TransferStatus status = new TransferStatus(); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3VersioningFeatureTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3VersioningFeatureTest.java index 1b41ddf177c..099db4e9e75 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3VersioningFeatureTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3VersioningFeatureTest.java @@ -47,6 +47,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -71,8 +72,8 @@ public class S3VersioningFeatureTest extends AbstractS3Test { public void testRevert() throws Exception { final Path bucket = new Path("versioning-test-eu-central-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); final Path vault = new Path(bucket, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final AttributesFinder f = cryptomator.getFeature(session, AttributesFinder.class, new S3AttributesFinderFeature(session, acl)); diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3WriteFeatureTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3WriteFeatureTest.java index 7a0cdb56a5e..9ef6f1d54dc 100644 --- a/s3/src/test/java/ch/cyberduck/core/cryptomator/S3WriteFeatureTest.java +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/S3WriteFeatureTest.java @@ -38,6 +38,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -70,8 +71,8 @@ public void testWrite() throws Exception { final Path home = new Path("test-eu-central-1-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory)); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final S3AccessControlListFeature acl = new S3AccessControlListFeature(session); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new S3WriteFeature(session, acl), cryptomator); diff --git a/s3/src/test/java/ch/cyberduck/core/cryptomator/UVFIntegrationTest.java b/s3/src/test/java/ch/cyberduck/core/cryptomator/UVFIntegrationTest.java new file mode 100644 index 00000000000..28f4eec870a --- /dev/null +++ b/s3/src/test/java/ch/cyberduck/core/cryptomator/UVFIntegrationTest.java @@ -0,0 +1,309 @@ +package ch.cyberduck.core.cryptomator; + +/* + * Copyright (c) 2002-2025 iterate GmbH. All rights reserved. + * https://cyberduck.io/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +import ch.cyberduck.core.*; +import ch.cyberduck.core.cryptomator.impl.uvf.CryptoVault; +import ch.cyberduck.core.exception.BackgroundException; +import ch.cyberduck.core.features.AttributesFinder; +import ch.cyberduck.core.features.Bulk; +import ch.cyberduck.core.features.Delete; +import ch.cyberduck.core.features.Directory; +import ch.cyberduck.core.features.Move; +import ch.cyberduck.core.features.Read; +import ch.cyberduck.core.features.Write; +import ch.cyberduck.core.io.StatusOutputStream; +import ch.cyberduck.core.proxy.ProxyFactory; +import ch.cyberduck.core.s3.S3BucketCreateService; +import ch.cyberduck.core.s3.S3Protocol; +import ch.cyberduck.core.s3.S3Session; +import ch.cyberduck.core.shared.DefaultPathHomeFeature; +import ch.cyberduck.core.sts.AbstractAssumeRoleWithWebIdentityTest; +import ch.cyberduck.core.transfer.Transfer; +import ch.cyberduck.core.transfer.TransferItem; +import ch.cyberduck.core.transfer.TransferStatus; +import ch.cyberduck.core.vault.DefaultVaultRegistry; +import ch.cyberduck.core.vault.VaultRegistry; +import ch.cyberduck.core.worker.DeleteWorker; +import ch.cyberduck.test.TestcontainerTest; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.RandomUtils; +import org.cryptomator.cryptolib.api.UVFMasterkey; +import org.jetbrains.annotations.NotNull; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.testcontainers.containers.ComposeContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.AbstractMap; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.*; + +/** + * Test {@link CryptoVault} implementation against test data from + * org.cryptomator.cryptolib.v3.UVFIntegrationTest + */ +@Category(TestcontainerTest.class) +public class UVFIntegrationTest { + + private static final ComposeContainer container = new ComposeContainer( + new File(AbstractAssumeRoleWithWebIdentityTest.class.getResource("/uvf/docker-compose.yml").getFile())) + .withPull(false) +// .withLocalCompose(true) + .withEnv( + Stream.of( + new AbstractMap.SimpleImmutableEntry<>("MINIO_PORT", "9000"), + new AbstractMap.SimpleImmutableEntry<>("MINIO_CONSOLE_PORT", "9001") + ).collect(Collectors.toMap(AbstractMap.SimpleImmutableEntry::getKey, AbstractMap.SimpleImmutableEntry::getValue))) + .withExposedService("minio-1", 9000, Wait.forListeningPort()); + + + @Test + public void listMinio() throws BackgroundException, IOException { + container.start(); + try { + final String bucketName = "cyberduckbucket"; + + final Host bookmark = getMinIOBookmark(); + final S3Session storage = getS3SessionForBookmark(bookmark); + + final Path bucket = new Path(bucketName, EnumSet.of(AbstractPath.Type.directory)); + new S3BucketCreateService(storage).create(bucket, "us-east-1"); + + final List files = Arrays.asList( + "/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/rExOms183v5evFwgIKiW0qvbsor1Hg==.uvf/dir.uvf", // -> /subir + "/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/dir.uvf", // -> / + "/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/GsMMTRvsuuP_6NjgRwopmWcuof-PyRQ=.uvf", // -> /foo.txt + "/d/6L/HPWBEU3OJP2EZUCP4CV3HHL47BXVEX/5qTOPMA1BouBRhz_G7qfmKety92geI4=.uvf", // -> /subdir/bar.txt + "/d/6L/HPWBEU3OJP2EZUCP4CV3HHL47BXVEX/dir.uvf" // /subdir + ); + final String jwe = "{\n" + + " \"fileFormat\": \"AES-256-GCM-32k\",\n" + + " \"nameFormat\": \"AES-SIV-512-B64URL\",\n" + + " \"seeds\": {\n" + + " \"HDm38g\": \"ypeBEsobvcr6wjGzmiPcTaeG7_gUfE5yuYB3ha_uSLs\",\n" + + " \"gBryKw\": \"PiPoFgA5WUoziU9lZOGxNIu9egCI1CxKy3PurtWcAJ0\",\n" + + " \"QBsJFg\": \"Ln0sA6lQeuJl7PW1NWiFpTOTogKdJBOUmXJloaJa78Y\"\n" + + " },\n" + + " \"initialSeed\": \"HDm38i\",\n" + + " \"latestSeed\": \"QBsJFo\",\n" + + " \"kdf\": \"HKDF-SHA512\",\n" + + " \"kdfSalt\": \"NIlr89R7FhochyP4yuXZmDqCnQ0dBB3UZ2D-6oiIjr8\",\n" + + " \"org.example.customfield\": 42\n" + + "}"; + + try { + for(final String fi : files) { + final Path file = new Path("/" + bucketName + "/" + fi, EnumSet.of(AbstractPath.Type.file)); + byte[] content = new byte[1000]; + final int size; + try(final InputStream in = UVFIntegrationTest.class.getResourceAsStream("/uvf/first_vault" + fi)) { + size = in.read(content); + } + final TransferStatus transferStatus = new TransferStatus().setLength(size); + transferStatus.setChecksum(storage.getFeature(Write.class).checksum(file, transferStatus).compute(new ByteArrayInputStream(content), transferStatus)); + storage.getFeature(Bulk.class).pre(Transfer.Type.upload, Collections.singletonMap(new TransferItem(file), transferStatus), new DisabledConnectionCallback()); + final StatusOutputStream out = storage.getFeature(Write.class).write(file, transferStatus, new DisabledConnectionCallback()); + IOUtils.copyLarge(UVFIntegrationTest.class.getResourceAsStream("/uvf/first_vault" + fi), out); + out.close(); + } + + final VaultRegistry vaults = new DefaultVaultRegistry(new DisabledPasswordCallback()); + bookmark.setDefaultPath("/" + bucketName); + final CryptoVault vault = new CryptoVault(new DefaultPathHomeFeature(bookmark).find()); + vaults.add(vault.load(storage, new DisabledPasswordCallback() { + @Override + public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { + return new Credentials().withPassword(jwe); + } + })); + final PathAttributes attr = storage.getFeature(AttributesFinder.class).find(vault.getHome()); + storage.withRegistry(vaults); + try(final UVFMasterkey masterKey = UVFMasterkey.fromDecryptedPayload(jwe)) { + assertArrayEquals(masterKey.rootDirId(), vault.getMasterkey().rootDirId()); + } + + final Path home = vault.getHome().withAttributes(attr).withType(EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.vault)); + { + final AttributedList list = storage.getFeature(ListService.class).list(home, new DisabledListProgressListener()); + assertEquals( + new HashSet<>(Arrays.asList( + new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/foo.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted))) + ), + new HashSet<>(list.toList())); + assertEquals("Hello Foo", readFile(storage, new Path("/cyberduckbucket/foo.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)))); + } + { + final byte[] expected = writeRandomFile(storage, new Path("/cyberduckbucket/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), 57); + final AttributedList list = storage.getFeature(ListService.class).list(home, new DisabledListProgressListener()); + assertEquals( + new HashSet<>(Arrays.asList( + new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/foo.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)))), + new HashSet<>(list.toList())); + + assertEquals(new String(expected), readFile(storage, new Path("/cyberduckbucket/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)))); + } + { + final PathAttributes subdir = storage.getFeature(AttributesFinder.class).find(new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted))); + final AttributedList list = storage.getFeature(ListService.class).list(new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)).withAttributes(subdir), new DisabledListProgressListener()); + assertEquals( + new HashSet<>(Collections.singletonList( + new Path("/cyberduckbucket/subdir/bar.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted))) + ), + new HashSet<>(list.toList())); + assertEquals("Hello Bar", readFile(storage, new Path("/cyberduckbucket/subdir/bar.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)))); + } + { + final byte[] expected = writeRandomFile(storage, new Path("/cyberduckbucket/subdir/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), 55); + final AttributedList list = storage.getFeature(ListService.class).list(new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), new DisabledListProgressListener()); + assertEquals( + new HashSet<>(Arrays.asList( + new Path("/cyberduckbucket/subdir/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/subdir/bar.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)))), + new HashSet<>(list.toList())); + assertEquals(new String(expected), readFile(storage, new Path("/cyberduckbucket/subdir/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)))); + } + { + storage._getFeature(Directory.class).mkdir(storage._getFeature(Write.class), new Path("/cyberduckbucket/subdir/subsubdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), new TransferStatus()); + final AttributedList list = storage.getFeature(ListService.class).list(new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), new DisabledListProgressListener()); + storage.getFeature(ListService.class).list(bucket, new DisabledListProgressListener()); + assertEquals( + new HashSet<>(Arrays.asList( + new Path("/cyberduckbucket/subdir/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/subdir/bar.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/subdir/subsubdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.decrypted)))), + new HashSet<>(list.toList())); + } + { + final byte[] expected = writeRandomFile(storage, new Path("/cyberduckbucket/subdir/subsubdir/foo.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), 5000); + final AttributedList list = storage.getFeature(ListService.class).list(new Path("/cyberduckbucket/subdir/subsubdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), new DisabledListProgressListener()); + assertEquals( + new HashSet<>(Collections.singletonList( + new Path("/cyberduckbucket/subdir/subsubdir/foo.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted))) + ), + new HashSet<>(list.toList())); + assertEquals(new String(expected), readFile(storage, new Path("/cyberduckbucket/subdir/subsubdir/foo.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)))); + } + { + storage.getFeature(Delete.class).delete(Collections.singletonList(new Path("/cyberduckbucket/subdir/bar.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted))), new DisabledPasswordCallback(), new Delete.DisabledCallback()); + final AttributedList list = storage.getFeature(ListService.class).list(new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), new DisabledListProgressListener()); + assertEquals(2, list.size()); + assertTrue(Arrays.toString(list.toArray()), list.contains(new Path("/cyberduckbucket/subdir/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)))); + assertEquals( + new HashSet<>(Arrays.asList( + new Path("/cyberduckbucket/subdir/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/subdir/subsubdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.decrypted))) + ), + new HashSet<>(list.toList())); + } + { + storage.getFeature(Move.class).move( + new Path("/cyberduckbucket/foo.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/subdir/Dave.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new TransferStatus(), new Delete.DisabledCallback(), new DisabledConnectionCallback() + ); + + final AttributedList listSubDir = storage.getFeature(ListService.class).list(new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), new DisabledListProgressListener()); + assertEquals( + new HashSet<>(Arrays.asList( + new Path("/cyberduckbucket/subdir/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/subdir/Dave.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/subdir/subsubdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.decrypted))) + ), + new HashSet<>(listSubDir.toList())); + final AttributedList listHome = storage.getFeature(ListService.class).list(new Path("/cyberduckbucket/", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted)), new DisabledListProgressListener()); + assertEquals( + new HashSet<>(Arrays.asList( + new Path("/cyberduckbucket/alice.txt", EnumSet.of(AbstractPath.Type.file, AbstractPath.Type.decrypted)), + new Path("/cyberduckbucket/subdir", EnumSet.of(AbstractPath.Type.directory, AbstractPath.Type.placeholder, AbstractPath.Type.decrypted))) + ), + new HashSet<>(listHome.toList())); + } + } + finally { + storage.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback())); + new DeleteWorker(new DisabledLoginCallback(), + storage.getFeature(ListService.class).list(bucket, new DisabledListProgressListener()).toList().stream() + .filter(f -> storage.getFeature(Delete.class).isSupported(f)).collect(Collectors.toList()), + new DisabledProgressListener()).run(storage); + storage.getFeature(Delete.class).delete(Collections.singletonList(bucket), new DisabledPasswordCallback(), new Delete.DisabledCallback()); + } + } + finally { + container.stop(); + } + } + + private static @NotNull Host getMinIOBookmark() { + final Host bookmark = new Host(new S3Protocol() { + @Override + public Scheme getScheme() { + return Scheme.http; + } + }, "localhost", 9000).withCredentials(new Credentials("minioadmin", "minioadmin")); + bookmark.setProperty("s3.bucket.virtualhost.disable", "true"); + bookmark.setDefaultPath("/"); + return bookmark; + } + + private static @NotNull S3Session getS3SessionForBookmark(final Host bookmark) throws BackgroundException { + final S3Session storage = new S3Session(bookmark); + storage.open(ProxyFactory.get(), new DisabledHostKeyCallback(), new DisabledLoginCallback(), new DisabledCancelCallback()); + storage.login(new DisabledLoginCallback() { + @Override + public Credentials prompt(final Host bookmark, final String username, final String title, final String reason, + final LoginOptions options) { + return storage.getHost().getCredentials(); + } + }, + new DisabledCancelCallback()); + return storage; + } + + private static byte @NotNull [] writeRandomFile(final Session session, final Path file, int size) throws BackgroundException, IOException { + final byte[] content = RandomUtils.nextBytes(size); + final TransferStatus transferStatus = new TransferStatus().setLength(content.length); + transferStatus.setChecksum(session.getFeature(Write.class).checksum(file, transferStatus).compute(new ByteArrayInputStream(content), transferStatus)); + session.getFeature(Bulk.class).pre(Transfer.Type.upload, Collections.singletonMap(new TransferItem(file), transferStatus), new DisabledConnectionCallback()); + final StatusOutputStream out = session.getFeature(Write.class).write(file, transferStatus, new DisabledConnectionCallback()); + IOUtils.copyLarge(new ByteArrayInputStream(content), out); + out.close(); + return content; + } + + private static String readFile(final Session session, final Path file) throws IOException, BackgroundException { + final Read read = session.getFeature(Read.class); + try(final InputStream in = read.read(file, new TransferStatus().setLength(file.attributes().getSize()), new DisabledConnectionCallback())) { + return IOUtils.toString(in, StandardCharsets.UTF_8); + } + } +} diff --git a/s3/src/test/java/ch/cyberduck/core/s3/AbstractS3Test.java b/s3/src/test/java/ch/cyberduck/core/s3/AbstractS3Test.java index 0a7ea787e4e..94801f37a04 100644 --- a/s3/src/test/java/ch/cyberduck/core/s3/AbstractS3Test.java +++ b/s3/src/test/java/ch/cyberduck/core/s3/AbstractS3Test.java @@ -26,10 +26,10 @@ import ch.cyberduck.core.LoginOptions; import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -57,11 +57,11 @@ public abstract class AbstractS3Test extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/s3/src/test/resources/uvf/docker-compose.yml b/s3/src/test/resources/uvf/docker-compose.yml new file mode 100644 index 00000000000..e739b4218cf --- /dev/null +++ b/s3/src/test/resources/uvf/docker-compose.yml @@ -0,0 +1,44 @@ +version: '3' + +services: + minio: + hostname: minio + image: minio/minio:latest + restart: on-failure + ports: + - "${MINIO_PORT}:${MINIO_PORT}" + - "${MINIO_CONSOLE_PORT}:${MINIO_CONSOLE_PORT}" + environment: + MINIO_ROOT_USER: minioadmin + MINIO_ROOT_PASSWORD: minioadmin + healthcheck: + test: [ "CMD", "bash", "-c", "curl -v --fail 127.0.0.1:${MINIO_PORT}/minio/health/ready" ] + interval: 5s + timeout: 1s + retries: 5 + command: server /data --console-address :9001 +# networks: +# - testContainerNetwork +# +# minio_setup: +# image: minio/mc:latest +# depends_on: +# minio: +# condition: service_healthy +# entrypoint: [ "/bin/sh","-c" ] +# command: +# - | +# set -x +# set -e +# /usr/bin/mc config host add myminio http://minio:${MINIO_PORT} minioadmin minioadmin +# +# # if container is restarted, the bucket already exists... +# /usr/bin/mc mb myminio/cyberduckbucket --with-versioning || true +# /usr/bin/mc rm --recursive --force myminio/cyberduckbucket +# +# echo "createbuckets successful" +# networks: +# - testContainerNetwork +# +#networks: +# testContainerNetwork: \ No newline at end of file diff --git a/s3/src/test/resources/uvf/first_vault/d/6L/HPWBEU3OJP2EZUCP4CV3HHL47BXVEX/5qTOPMA1BouBRhz_G7qfmKety92geI4=.uvf b/s3/src/test/resources/uvf/first_vault/d/6L/HPWBEU3OJP2EZUCP4CV3HHL47BXVEX/5qTOPMA1BouBRhz_G7qfmKety92geI4=.uvf new file mode 100644 index 00000000000..9df3310ef3f Binary files /dev/null and b/s3/src/test/resources/uvf/first_vault/d/6L/HPWBEU3OJP2EZUCP4CV3HHL47BXVEX/5qTOPMA1BouBRhz_G7qfmKety92geI4=.uvf differ diff --git a/s3/src/test/resources/uvf/first_vault/d/6L/HPWBEU3OJP2EZUCP4CV3HHL47BXVEX/dir.uvf b/s3/src/test/resources/uvf/first_vault/d/6L/HPWBEU3OJP2EZUCP4CV3HHL47BXVEX/dir.uvf new file mode 100644 index 00000000000..378fce0a7d2 Binary files /dev/null and b/s3/src/test/resources/uvf/first_vault/d/6L/HPWBEU3OJP2EZUCP4CV3HHL47BXVEX/dir.uvf differ diff --git a/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/GsMMTRvsuuP_6NjgRwopmWcuof-PyRQ=.uvf b/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/GsMMTRvsuuP_6NjgRwopmWcuof-PyRQ=.uvf new file mode 100644 index 00000000000..d7fdea3faa4 Binary files /dev/null and b/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/GsMMTRvsuuP_6NjgRwopmWcuof-PyRQ=.uvf differ diff --git a/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/dir.uvf b/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/dir.uvf new file mode 100644 index 00000000000..d947abc9558 Binary files /dev/null and b/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/dir.uvf differ diff --git a/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/rExOms183v5evFwgIKiW0qvbsor1Hg==.uvf/dir.uvf b/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/rExOms183v5evFwgIKiW0qvbsor1Hg==.uvf/dir.uvf new file mode 100644 index 00000000000..84ec139b177 Binary files /dev/null and b/s3/src/test/resources/uvf/first_vault/d/RZ/K7ZH7KBXULNEKBMGX3CU42PGUIAIX4/rExOms183v5evFwgIKiW0qvbsor1Hg==.uvf/dir.uvf differ diff --git a/smb/pom.xml b/smb/pom.xml index 25ab9acca88..68d3e00ba6f 100644 --- a/smb/pom.xml +++ b/smb/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT smb jar diff --git a/spectra/pom.xml b/spectra/pom.xml index 7a8d3fb003c..05c400e6100 100644 --- a/spectra/pom.xml +++ b/spectra/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT spectra jar diff --git a/ssh/pom.xml b/ssh/pom.xml index a2d5a50a7d6..346453b7ecd 100644 --- a/ssh/pom.xml +++ b/ssh/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT ssh jar diff --git a/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPMoveFeature.java b/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPMoveFeature.java index de5bd0f3991..e4ccca5f0ec 100644 --- a/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPMoveFeature.java +++ b/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPMoveFeature.java @@ -47,7 +47,7 @@ public Path move(final Path file, final Path renamed, final TransferStatus statu session.sftp().rename(file.getAbsolute(), renamed.getAbsolute(), status.isExists() ? new HashSet<>(Arrays.asList(RenameFlags.OVERWRITE, RenameFlags.NATIVE)) : Collections.singleton(RenameFlags.NATIVE)); // Copy original file attributes - return new Path(renamed).withAttributes(new PathAttributes(file.attributes()).setVault(null)); + return new Path(renamed).withAttributes(new PathAttributes(file.attributes()).setVaultMetadata(null)); } catch(IOException e) { throw new SFTPExceptionMappingService().map("Cannot rename {0}", e, file); diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index 3466e20d78f..b00052bfcfc 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -48,12 +48,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -66,7 +68,6 @@ import java.util.EnumSet; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -78,8 +79,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -105,8 +106,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -123,15 +124,15 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -153,8 +154,8 @@ public void testCopyFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( @@ -188,8 +189,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new SFTPFindFeature(session).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( @@ -214,8 +215,8 @@ public void testCopyDirectoryIntoVault() throws Exception { new SFTPTouchFeature(session).touch(new SFTPWriteFeature(session), cleartextFile, new TransferStatus()); assertTrue(new SFTPFindFeature(session).find(cleartextFolder)); assertTrue(new SFTPFindFeature(session).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -239,8 +240,8 @@ public void testCopyFileOutsideVault() throws Exception { new SFTPDirectoryFeature(session).mkdir(new SFTPWriteFeature(session), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( @@ -265,8 +266,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/CryptoSFTPSingleTransferWorkerTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/CryptoSFTPSingleTransferWorkerTest.java index b0c0c4dbb14..8b1335a42dd 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/CryptoSFTPSingleTransferWorkerTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/CryptoSFTPSingleTransferWorkerTest.java @@ -38,7 +38,6 @@ import ch.cyberduck.core.io.StreamCopier; import ch.cyberduck.core.local.DefaultLocalDirectoryFeature; import ch.cyberduck.core.notification.DisabledNotificationService; -import ch.cyberduck.core.preferences.PreferencesFactory; import ch.cyberduck.core.sftp.AbstractSFTPTest; import ch.cyberduck.core.sftp.SFTPAttributesFinderFeature; import ch.cyberduck.core.sftp.SFTPDeleteFeature; @@ -58,6 +57,7 @@ import ch.cyberduck.core.transfer.upload.UploadFilterOptions; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -104,18 +104,17 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback() { @Override public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { return new VaultCredentials("test"); } })); - PreferencesFactory.get().setProperty("factory.vault.class", CryptoVault.class.getName()); final Host host = new Host(new TestProtocol()); final Transfer t = new UploadTransfer(host, Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()) - .withOptions(new UploadFilterOptions(host).withTimestamp(true)); + .withOptions(new UploadFilterOptions(host).withTimestamp(true)); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { @Override public TransferAction prompt(final TransferItem file) { diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/DefaultTouchFeatureTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/DefaultTouchFeatureTest.java index 3e94c89b214..6a6273c4e1b 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/DefaultTouchFeatureTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/DefaultTouchFeatureTest.java @@ -31,6 +31,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -53,8 +54,8 @@ public void testTouchEncrypted() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator), test, new TransferStatus()); diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java index 57ca0de2b57..635d7f69ebe 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/MoveWorkerTest.java @@ -52,11 +52,13 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.MoveWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -70,7 +72,6 @@ import java.util.UUID; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -82,8 +83,8 @@ public void testMoveSameFolderCryptomator() throws Exception { final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final byte[] content = RandomUtils.nextBytes(40500); final TransferStatus status = new TransferStatus(); @@ -107,8 +108,8 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator), source, new TransferStatus()); @@ -124,15 +125,15 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator), source, new TransferStatus()); @@ -153,8 +154,8 @@ public void testMoveFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new SFTPWriteFeature(session)), folder, new TransferStatus()); @@ -193,8 +194,8 @@ public void testMoveFileIntoVault() throws Exception { assertTrue(new SFTPFindFeature(session).find(clearFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( @@ -219,8 +220,8 @@ public void testMoveDirectoryIntoVault() throws Exception { new SFTPTouchFeature(session).touch(new SFTPWriteFeature(session), clearFile, new TransferStatus()); assertTrue(new SFTPFindFeature(session).find(clearFolder)); assertTrue(new SFTPFindFeature(session).find(clearFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -244,8 +245,8 @@ public void testMoveFileOutsideVault() throws Exception { new SFTPDirectoryFeature(session).mkdir(new SFTPWriteFeature(session), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( @@ -271,8 +272,8 @@ public void testMoveDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPAttributesFinderFeatureTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPAttributesFinderFeatureTest.java index 0e48ecafaab..a834f72d7c8 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPAttributesFinderFeatureTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPAttributesFinderFeatureTest.java @@ -41,6 +41,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -61,8 +62,8 @@ public class SFTPAttributesFinderFeatureTest extends AbstractSFTPTest { public void testFindCryptomator() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch( @@ -74,7 +75,7 @@ public void testFindCryptomator() throws Exception { cryptomator.getFeature(session, Delete.class, new SFTPDeleteFeature(session)).delete(Arrays.asList(test, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); assertFalse(new SFTPFindFeature(session).find(vault)); assertFalse(new SFTPFindFeature(session).find(cryptomator.getHome())); - assertFalse(new SFTPFindFeature(session).find(cryptomator.getMasterkey())); + assertFalse(new SFTPFindFeature(session).find(cryptomator.getMasterkeyPath())); assertFalse(new SFTPFindFeature(session).find(cryptomator.getConfig())); } @@ -82,8 +83,8 @@ public void testFindCryptomator() throws Exception { public void testFindDefaultAttributesFinderCryptomator() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch( @@ -99,8 +100,8 @@ public void testFindDefaultAttributesFinderCryptomator() throws Exception { public void testFindDefaultAttributesFinderWithCacheCryptomator() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch( diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPCryptomatorInteroperabilityTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPCryptomatorInteroperabilityTest.java index 0dac54678ba..ad2b72444ad 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPCryptomatorInteroperabilityTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPCryptomatorInteroperabilityTest.java @@ -28,6 +28,7 @@ import ch.cyberduck.core.Path; import ch.cyberduck.core.cryptomator.features.CryptoReadFeature; import ch.cyberduck.core.cryptomator.random.FastSecureRandomProvider; +import ch.cyberduck.core.preferences.PreferencesFactory; import ch.cyberduck.core.proxy.DisabledProxyFinder; import ch.cyberduck.core.sftp.SFTPHomeDirectoryService; import ch.cyberduck.core.sftp.SFTPProtocol; @@ -38,6 +39,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -54,6 +56,7 @@ import org.cryptomator.cryptolib.api.Masterkey; import org.cryptomator.cryptolib.api.MasterkeyLoader; import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; +import org.cryptomator.cryptolib.api.PerpetualMasterkey; import org.cryptomator.cryptolib.common.MasterkeyFileAccess; import org.cryptomator.cryptolib.common.ReseedingSecureRandom; import org.junit.After; @@ -62,6 +65,7 @@ import java.io.InputStream; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.security.SecureRandom; @@ -99,8 +103,8 @@ public void startSerer() throws Exception { default: csprng = FastSecureRandomProvider.get().provide(); } - final Masterkey mk = Masterkey.generate(csprng); - final MasterkeyFileAccess mkAccess = new MasterkeyFileAccess(CryptoVault.VAULT_PEPPER, csprng); + final PerpetualMasterkey mk = Masterkey.generate(csprng); + final MasterkeyFileAccess mkAccess = new MasterkeyFileAccess(PreferencesFactory.get().getProperty("cryptomator.vault.pepper").getBytes(StandardCharsets.UTF_8), csprng); final java.nio.file.Path mkPath = Paths.get(vault.toString(), DefaultVaultRegistry.DEFAULT_MASTERKEY_FILE_NAME); mkAccess.persist(mk, mkPath, passphrase); CryptoFileSystemProperties properties = cryptoFileSystemProperties().withKeyLoader(new MasterkeyLoader() { @@ -143,15 +147,16 @@ public void testCryptomatorInteroperabilityLongFilename() throws Exception { session.open(new DisabledProxyFinder(), new DisabledHostKeyCallback(), new DisabledLoginCallback(), new DisabledCancelCallback()); session.login(new DisabledLoginCallback(), new DisabledCancelCallback()); final Path home = new SFTPHomeDirectoryService(session).find(); - final Path vault = new Path(home, "vault", EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault).load(session, new DisabledPasswordCallback() { + final Path vaultPath = new Path(home, "vault", EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).provide(session, new VaultMetadata(vaultPath, VaultMetadata.Type.V8)); + cryptomator.load(session, new DisabledPasswordCallback() { @Override public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { return new VaultCredentials(passphrase); } }); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); - Path p = new Path(new Path(vault, targetFolder.getFileName().toString(), EnumSet.of(Path.Type.directory)), targetFile.getFileName().toString(), EnumSet.of(Path.Type.file)); + Path p = new Path(new Path(vaultPath, targetFolder.getFileName().toString(), EnumSet.of(Path.Type.directory)), targetFile.getFileName().toString(), EnumSet.of(Path.Type.file)); final InputStream read = new CryptoReadFeature(session, new SFTPReadFeature(session), cryptomator).read(p, new TransferStatus(), new DisabledConnectionCallback()); final byte[] readContent = new byte[content.length]; IOUtils.readFully(read, readContent); @@ -177,15 +182,16 @@ public void testCryptomatorInteroperability() throws Exception { session.open(new DisabledProxyFinder(), new DisabledHostKeyCallback(), new DisabledLoginCallback(), new DisabledCancelCallback()); session.login(new DisabledLoginCallback(), new DisabledCancelCallback()); final Path home = new SFTPHomeDirectoryService(session).find(); - final Path vault = new Path(home, "vault", EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault).load(session, new DisabledPasswordCallback() { + final Path vaultPath = new Path(home, "vault", EnumSet.of(Path.Type.directory)); + final AbstractVault cryptomator = new CryptoVaultProvider(session).provide(session, new VaultMetadata(vaultPath, VaultMetadata.Type.V8)); + cryptomator.load(session, new DisabledPasswordCallback() { @Override public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { return new VaultCredentials(passphrase); } }); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); - Path p = new Path(new Path(vault, targetFolder.getFileName().toString(), EnumSet.of(Path.Type.directory)), targetFile.getFileName().toString(), EnumSet.of(Path.Type.file)); + Path p = new Path(new Path(vaultPath, targetFolder.getFileName().toString(), EnumSet.of(Path.Type.directory)), targetFile.getFileName().toString(), EnumSet.of(Path.Type.file)); final InputStream read = new CryptoReadFeature(session, new SFTPReadFeature(session), cryptomator).read(p, new TransferStatus(), new DisabledConnectionCallback()); final byte[] readContent = new byte[content.length]; IOUtils.readFully(read, readContent); diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPDirectoryFeatureTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPDirectoryFeatureTest.java index c5e2acc3513..8b80a92b5d0 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPDirectoryFeatureTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPDirectoryFeatureTest.java @@ -33,8 +33,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -44,7 +46,6 @@ import java.util.EnumSet; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -55,8 +56,8 @@ public void testMakeDirectoryEncrypted() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new SFTPWriteFeature(session)), test, new TransferStatus()); @@ -66,13 +67,13 @@ public void testMakeDirectoryEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir(new SFTPWriteFeature(session), test, new TransferStatus()); assertTrue(cryptomator.getFeature(session, Find.class, new SFTPFindFeature(session)).find(test)); diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPFindFeatureTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPFindFeatureTest.java index 0f2735a8575..9c2839989ab 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPFindFeatureTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPFindFeatureTest.java @@ -32,8 +32,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -45,7 +47,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -56,8 +57,8 @@ public void testFindCryptomator() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertFalse(cryptomator.getFeature(session, Find.class, new DefaultFindFeature(session)).find(new Path(vault, "a", EnumSet.of(Path.Type.directory)))); new CryptoTouchFeature<>(session, new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -67,14 +68,14 @@ public void testFindCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testFindLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator), cryptomator).touch(new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator), test, new TransferStatus()); diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPListServiceTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPListServiceTest.java index f1a060a8956..24cb7e5b757 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPListServiceTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPListServiceTest.java @@ -41,6 +41,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -63,8 +64,8 @@ public void testListCryptomator() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertTrue(new CryptoListService(session, new SFTPListService(session), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); new CryptoTouchFeature<>(session, new CryptoTouchFeature<>(session, new DefaultTouchFeature(session), diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPMoveFeatureTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPMoveFeatureTest.java index 067997a6a95..8ab711dd18e 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPMoveFeatureTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPMoveFeatureTest.java @@ -41,8 +41,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -54,7 +56,6 @@ import java.util.UUID; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -66,8 +67,8 @@ public void testMoveSameFolderCryptomator() throws Exception { final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator), cryptomator).touch(new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator), source, new TransferStatus()); @@ -86,8 +87,8 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator), cryptomator).touch(new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator), source, new TransferStatus()); @@ -103,15 +104,15 @@ public void testMoveToDifferentFolderCryptomator() throws Exception { } @Test + @Ignore("Filename shortening not implemented yet") public void testMoveToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator), cryptomator).touch(new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator), source, new TransferStatus()); @@ -130,8 +131,8 @@ public void testMoveFile() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new SFTPWriteFeature(session)), folder, new TransferStatus()); @@ -156,8 +157,8 @@ public void testMoveFolder() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new SFTPWriteFeature(session)), folder, new TransferStatus()); @@ -177,8 +178,8 @@ public void testMoveFolderWithFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, "folder-1", EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, "file-1", EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new SFTPDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new SFTPWriteFeature(session)), folder, new TransferStatus()); diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPReadFeatureTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPReadFeatureTest.java index adcb3462152..8251ed97db7 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPReadFeatureTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPReadFeatureTest.java @@ -39,6 +39,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -70,8 +71,8 @@ public void testReadRange() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPSymlinkFeatureTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPSymlinkFeatureTest.java index 7a74f516b4d..d39a63f7696 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPSymlinkFeatureTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPSymlinkFeatureTest.java @@ -37,8 +37,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -49,19 +51,18 @@ import java.util.UUID; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) public class SFTPSymlinkFeatureTest extends AbstractSFTPTest { @Test + @Ignore("Filename shortening not yet implemented") public void testSymlink() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, UUID.randomUUID().toString(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path target = new Path(vault, UUID.randomUUID().toString(), EnumSet.of(Path.Type.file)); new CryptoTouchFeature<>(session, new CryptoTouchFeature<>(session, new DefaultTouchFeature( diff --git a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPWriteFeatureTest.java b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPWriteFeatureTest.java index e290bdbf760..db460423266 100644 --- a/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPWriteFeatureTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/cryptomator/SFTPWriteFeatureTest.java @@ -46,6 +46,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -77,8 +78,8 @@ public void testWrite() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); @@ -108,8 +109,8 @@ public void testWriteWithCache() throws Exception { final Path home = new SFTPHomeDirectoryService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new SFTPWriteFeature(session), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); diff --git a/ssh/src/test/java/ch/cyberduck/core/sftp/AbstractSFTPTest.java b/ssh/src/test/java/ch/cyberduck/core/sftp/AbstractSFTPTest.java index 8a22f97fd29..75ed42c2039 100644 --- a/ssh/src/test/java/ch/cyberduck/core/sftp/AbstractSFTPTest.java +++ b/ssh/src/test/java/ch/cyberduck/core/sftp/AbstractSFTPTest.java @@ -28,10 +28,10 @@ import ch.cyberduck.core.LoginOptions; import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DisabledX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import org.apache.commons.lang3.StringUtils; import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory; @@ -71,11 +71,11 @@ public class AbstractSFTPTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @Before public void start() throws Exception { diff --git a/storegate/pom.xml b/storegate/pom.xml index 3342b7fdc5d..b072f2926e3 100644 --- a/storegate/pom.xml +++ b/storegate/pom.xml @@ -19,7 +19,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT storegate diff --git a/test/pom.xml b/test/pom.xml index 85387cbaa4f..db98fcd7240 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT 4.0.0 pom diff --git a/tus/pom.xml b/tus/pom.xml index 1fbe31e074b..db715fe4e5d 100644 --- a/tus/pom.xml +++ b/tus/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT tus jar diff --git a/webdav/pom.xml b/webdav/pom.xml index a0d3a056c84..f1656180592 100644 --- a/webdav/pom.xml +++ b/webdav/pom.xml @@ -18,7 +18,7 @@ ch.cyberduck parent - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT webdav jar diff --git a/webdav/src/main/java/ch/cyberduck/core/dav/DAVMoveFeature.java b/webdav/src/main/java/ch/cyberduck/core/dav/DAVMoveFeature.java index bdd8072f601..f8b98e350a1 100644 --- a/webdav/src/main/java/ch/cyberduck/core/dav/DAVMoveFeature.java +++ b/webdav/src/main/java/ch/cyberduck/core/dav/DAVMoveFeature.java @@ -62,7 +62,7 @@ public Path move(final Path file, final Path renamed, final TransferStatus statu status.isExists()); } // Copy original file attributes - return new Path(renamed).withAttributes(new PathAttributes(file.attributes()).setVault(null).setLockId(null)); + return new Path(renamed).withAttributes(new PathAttributes(file.attributes()).setVaultMetadata(null).setLockId(null)); } catch(SardineException e) { throw new DAVExceptionMappingService().map("Cannot rename {0}", e, file); diff --git a/webdav/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java b/webdav/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java index 20abda9c910..e60b9180028 100644 --- a/webdav/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/cryptomator/CopyWorkerTest.java @@ -45,12 +45,14 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.CopyWorker; import ch.cyberduck.core.worker.DeleteWorker; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -63,7 +65,6 @@ import java.util.EnumSet; import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -75,8 +76,8 @@ public void testCopyFile() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path target = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); final byte[] content = RandomUtils.nextBytes(40500); @@ -101,8 +102,8 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { final Path source = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -118,16 +119,17 @@ public void testCopyToDifferentFolderCryptomator() throws Exception { new DeleteWorker(new DisabledLoginCallback(), Collections.singletonList(vault), new DisabledProgressListener()).run(session); } + //TODO @Test + @Ignore(value = "Filename shortening not yet implemented") public void testCopyToDifferentFolderLongFilenameCryptomator() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path source = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path targetFolder = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); final Path target = new Path(targetFolder, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -149,8 +151,8 @@ public void testCopyFolder() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path file = new Path(folder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DAVDirectoryFeature(session)).mkdir( @@ -185,8 +187,8 @@ public void testCopyFileIntoVault() throws Exception { assertTrue(new DAVFindFeature(session).find(cleartextFile)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DAVDirectoryFeature(session)).mkdir( @@ -215,8 +217,8 @@ public void testCopyDirectoryIntoVault() throws Exception { session).touch(new DAVWriteFeature(session), cleartextFile, new TransferStatus()); assertTrue(new DAVFindFeature(session).find(cleartextFolder)); assertTrue(new DAVFindFeature(session).find(cleartextFile)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); // move directory into vault @@ -240,8 +242,8 @@ public void testCopyFileOutsideVault() throws Exception { new DAVDirectoryFeature(session).mkdir(new DAVWriteFeature(session), clearFolder, new TransferStatus()); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DAVDirectoryFeature(session)).mkdir( @@ -271,8 +273,8 @@ public void testCopyDirectoryOutsideVault() throws Exception { final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFolder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path encryptedFile = new Path(encryptedFolder, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); final DefaultVaultRegistry registry = new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator); session.withRegistry(registry); cryptomator.getFeature(session, Directory.class, new DAVDirectoryFeature(session)).mkdir( diff --git a/webdav/src/test/java/ch/cyberduck/core/cryptomator/CryptoDAVSingleTransferWorkerTest.java b/webdav/src/test/java/ch/cyberduck/core/cryptomator/CryptoDAVSingleTransferWorkerTest.java index a7b262d7fa3..8c76f09b678 100644 --- a/webdav/src/test/java/ch/cyberduck/core/cryptomator/CryptoDAVSingleTransferWorkerTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/cryptomator/CryptoDAVSingleTransferWorkerTest.java @@ -47,7 +47,6 @@ import ch.cyberduck.core.io.StreamCopier; import ch.cyberduck.core.local.DefaultLocalDirectoryFeature; import ch.cyberduck.core.notification.DisabledNotificationService; -import ch.cyberduck.core.preferences.PreferencesFactory; import ch.cyberduck.core.shared.DefaultHomeFinderService; import ch.cyberduck.core.transfer.DisabledTransferErrorCallback; import ch.cyberduck.core.transfer.DisabledTransferPrompt; @@ -61,6 +60,7 @@ import ch.cyberduck.core.transfer.UploadTransfer; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.core.worker.SingleTransferWorker; import ch.cyberduck.test.IntegrationTest; @@ -103,15 +103,14 @@ public void testUpload() throws Exception { final OutputStream out2 = localFile2.getOutputStream(false); IOUtils.write(content, out2); out2.close(); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback() { @Override public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { return new VaultCredentials("test"); } })); - PreferencesFactory.get().setProperty("factory.vault.class", CryptoVault.class.getName()); final Transfer t = new UploadTransfer(new Host(new TestProtocol()), Collections.singletonList(new TransferItem(dir1, localDirectory1)), new NullFilter<>()); assertTrue(new SingleTransferWorker(session, session, t, new TransferOptions(), new TransferSpeedometer(t), new DisabledTransferPrompt() { @Override @@ -145,12 +144,10 @@ public TransferAction prompt(final TransferItem file) { @Test public void testDownload() throws Exception { - PreferencesFactory.get().setProperty("factory.vault.class", CryptoVault.class.getName()); - final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback() { @Override public Credentials prompt(final Host bookmark, final String title, final String reason, final LoginOptions options) { @@ -178,7 +175,7 @@ public TransferAction prompt(final TransferItem file) { return TransferAction.overwrite; } }, new DisabledTransferErrorCallback(), - new DisabledProgressListener(), new DisabledStreamListener(), new DisabledLoginCallback(), new DisabledNotificationService()) { + new DisabledProgressListener(), new DisabledStreamListener(), new DisabledLoginCallback(), new DisabledNotificationService()) { }.run(session)); cryptomator.getFeature(session, Delete.class, new DAVDeleteFeature(session)).delete(Arrays.asList(file1, dir1, vault), new DisabledLoginCallback(), new Delete.DisabledCallback()); diff --git a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVDirectoryFeatureTest.java b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVDirectoryFeatureTest.java index df3f84fbc08..d4c7d1dd27a 100644 --- a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVDirectoryFeatureTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVDirectoryFeatureTest.java @@ -32,8 +32,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -43,7 +45,6 @@ import java.util.EnumSet; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) @@ -54,8 +55,8 @@ public void testMakeDirectoryEncrypted() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new DAVDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new DAVWriteFeature(session)), test, new TransferStatus()); @@ -64,13 +65,13 @@ public void testMakeDirectoryEncrypted() throws Exception { } @Test + @Ignore("Filename shortening not yet implemented") public void testMakeDirectoryLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new DAVDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new DAVWriteFeature(session)), test, new TransferStatus()); diff --git a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVListServiceTest.java b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVListServiceTest.java index 857675a1c0e..b842a8ca116 100644 --- a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVListServiceTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVListServiceTest.java @@ -33,6 +33,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -55,8 +56,8 @@ public void testListCryptomator() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); assertTrue(new CryptoListService(session, new DAVListService(session), cryptomator).list(vault, new DisabledListProgressListener()).isEmpty()); new CryptoTouchFeature<>(session, new DefaultTouchFeature( diff --git a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVMoveFeatureTest.java b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVMoveFeatureTest.java index 4ec36cda83c..33bf69ea993 100644 --- a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVMoveFeatureTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVMoveFeatureTest.java @@ -41,6 +41,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.junit.Test; @@ -62,8 +63,8 @@ public void testMove() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path folder = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); cryptomator.getFeature(session, Directory.class, new DAVDirectoryFeature(session)).mkdir( cryptomator.getFeature(session, Write.class, new DAVWriteFeature(session)), folder, new TransferStatus()); diff --git a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVReadFeatureTest.java b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVReadFeatureTest.java index 3f38d3f3b81..68c2da6e220 100644 --- a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVReadFeatureTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVReadFeatureTest.java @@ -42,6 +42,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -73,8 +74,8 @@ public void testReadRange() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new DAVWriteFeature(session), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); diff --git a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVTouchFeatureTest.java b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVTouchFeatureTest.java index 1dbbdd0c765..596edd3173d 100644 --- a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVTouchFeatureTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVTouchFeatureTest.java @@ -35,8 +35,10 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -48,19 +50,18 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; @Category(IntegrationTest.class) @RunWith(value = Parameterized.class) public class DAVTouchFeatureTest extends AbstractDAVTest { @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncrypted() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path template = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); final Path test = new CryptoTouchFeature<>(session, new DefaultTouchFeature( @@ -72,13 +73,13 @@ public void testTouchLongFilenameEncrypted() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(new CryptoWriteFeature<>(session, new DAVWriteFeature(session), cryptomator), test, new TransferStatus()); @@ -87,13 +88,13 @@ public void testTouchLongFilenameEncryptedDefaultFeature() throws Exception { } @Test + @Ignore(value = "Filename shortening not yet implemented") public void testTouchDeleteTouchLongFilename() throws Exception { - assumeTrue(vaultVersion == CryptoVault.VAULT_VERSION_DEPRECATED); final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService(130).random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); new CryptoTouchFeature<>(session, new DefaultTouchFeature( session), cryptomator).touch(new CryptoWriteFeature<>(session, new DAVWriteFeature(session), cryptomator), test, new TransferStatus()); diff --git a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVWriteFeatureTest.java b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVWriteFeatureTest.java index 1ca8f86568d..b8b1360342f 100644 --- a/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVWriteFeatureTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/cryptomator/DAVWriteFeatureTest.java @@ -16,6 +16,7 @@ */ import ch.cyberduck.core.AlphanumericRandomStringService; +import ch.cyberduck.core.AttributedList; import ch.cyberduck.core.DisabledConnectionCallback; import ch.cyberduck.core.DisabledListProgressListener; import ch.cyberduck.core.DisabledLoginCallback; @@ -42,6 +43,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.RandomUtils; @@ -73,8 +75,8 @@ public void testWrite() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); final Path test = new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(vault, vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final CryptoWriteFeature writer = new CryptoWriteFeature<>(session, new DAVWriteFeature(session), cryptomator); final FileHeader header = cryptomator.getFileHeaderCryptor().create(); @@ -86,7 +88,9 @@ public void testWrite() throws Exception { new StreamCopier(status, status).transfer(new ByteArrayInputStream(content), out); out.close(); assertTrue(cryptomator.getFeature(session, Find.class, new DAVFindFeature(session)).find(test)); - assertEquals(content.length, new CryptoListService(session, new DAVListService(session), cryptomator).list(test.getParent(), new DisabledListProgressListener()).get(test).attributes().getSize()); + final AttributedList list = new CryptoListService(session, new DAVListService(session), cryptomator).list(test.getParent(), new DisabledListProgressListener()); + assertEquals(1, list.size()); + assertEquals(content.length, list.get(test).attributes().getSize()); assertEquals(content.length, new CryptoUploadFeature<>(session, new DAVUploadFeature(session), cryptomator).append(test, status .setRemote(cryptomator.getFeature(session, AttributesFinder.class, new DAVAttributesFinderFeature(session)).find(test))).offset, 0L); final ByteArrayOutputStream buffer = new ByteArrayOutputStream(content.length); diff --git a/webdav/src/test/java/ch/cyberduck/core/dav/AbstractDAVTest.java b/webdav/src/test/java/ch/cyberduck/core/dav/AbstractDAVTest.java index 7ce02f130e9..8592c91d441 100644 --- a/webdav/src/test/java/ch/cyberduck/core/dav/AbstractDAVTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/dav/AbstractDAVTest.java @@ -29,11 +29,11 @@ import ch.cyberduck.core.Profile; import ch.cyberduck.core.ProtocolFactory; import ch.cyberduck.core.Scheme; -import ch.cyberduck.core.cryptomator.CryptoVault; import ch.cyberduck.core.local.FlatTemporaryFileService; import ch.cyberduck.core.serializer.impl.dd.ProfilePlistReader; import ch.cyberduck.core.ssl.DefaultX509KeyManager; import ch.cyberduck.core.ssl.DefaultX509TrustManager; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.VaultTest; import org.junit.After; @@ -93,11 +93,11 @@ public class AbstractDAVTest extends VaultTest { @Parameterized.Parameters(name = "vaultVersion = {0}") public static Object[] data() { - return new Object[]{CryptoVault.VAULT_VERSION_DEPRECATED, CryptoVault.VAULT_VERSION}; + return new Object[]{VaultMetadata.Type.V8, VaultMetadata.Type.UVF}; } @Parameterized.Parameter - public int vaultVersion; + public VaultMetadata.Type vaultVersion; @After public void disconnect() throws Exception { diff --git a/webdav/src/test/java/ch/cyberduck/core/dav/DAVAttributesFinderFeatureTest.java b/webdav/src/test/java/ch/cyberduck/core/dav/DAVAttributesFinderFeatureTest.java index 4405a6bc4a3..708b3230d4c 100644 --- a/webdav/src/test/java/ch/cyberduck/core/dav/DAVAttributesFinderFeatureTest.java +++ b/webdav/src/test/java/ch/cyberduck/core/dav/DAVAttributesFinderFeatureTest.java @@ -9,7 +9,8 @@ import ch.cyberduck.core.Host; import ch.cyberduck.core.Path; import ch.cyberduck.core.PathAttributes; -import ch.cyberduck.core.cryptomator.CryptoVault; +import ch.cyberduck.core.cryptomator.AbstractVault; +import ch.cyberduck.core.cryptomator.CryptoVaultProvider; import ch.cyberduck.core.cryptomator.features.CryptoTouchFeature; import ch.cyberduck.core.cryptomator.features.CryptoWriteFeature; import ch.cyberduck.core.date.RFC1123DateFormatter; @@ -25,6 +26,7 @@ import ch.cyberduck.core.transfer.TransferStatus; import ch.cyberduck.core.vault.DefaultVaultRegistry; import ch.cyberduck.core.vault.VaultCredentials; +import ch.cyberduck.core.vault.VaultMetadata; import ch.cyberduck.test.IntegrationTest; import org.apache.commons.lang3.StringUtils; @@ -188,8 +190,8 @@ public void testFindLock() throws Exception { public void testFindDefaultAttributesFinderCryptomator() throws Exception { final Path home = new DefaultHomeFinderService(session).find(); final Path vault = new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)); - final CryptoVault cryptomator = new CryptoVault(vault); - cryptomator.create(session, new VaultCredentials("test"), vaultVersion); + final AbstractVault cryptomator = new CryptoVaultProvider(session).create(session, null, new VaultCredentials("test"), + new VaultMetadata(new Path(home, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), vaultVersion)); session.withRegistry(new DefaultVaultRegistry(new DisabledPasswordCallback(), cryptomator)); final Path test = new CryptoTouchFeature<>(session, new DAVTouchFeature(session), cryptomator).touch( new CryptoWriteFeature<>(session, new DAVWriteFeature(session), cryptomator), new Path(vault, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), new TransferStatus()); diff --git a/windows/pom.xml b/windows/pom.xml index cd9d0c7edb9..b9fc506e7a2 100644 --- a/windows/pom.xml +++ b/windows/pom.xml @@ -18,7 +18,7 @@ parent ch.cyberduck - 9.3.0-SNAPSHOT + 9.3.0.uvfdraft-SNAPSHOT 4.0.0 Cyberduck.Native diff --git a/windows/src/main/csharp/ch/cyberduck/ui/controller/BrowserController.cs b/windows/src/main/csharp/ch/cyberduck/ui/controller/BrowserController.cs index b1fe476cc53..4402f44e97d 100644 --- a/windows/src/main/csharp/ch/cyberduck/ui/controller/BrowserController.cs +++ b/windows/src/main/csharp/ch/cyberduck/ui/controller/BrowserController.cs @@ -358,10 +358,10 @@ protected override void Invalidate() private void View_LockUnlockVault() { Path directory = new UploadTargetFinder(Workdir).find(SelectedPath); - if (directory.attributes().getVault() != null) + if (directory.attributes().getVaultMetadata() != null) { // Lock and remove all open vaults - LockVaultAction lockVault = new LockVaultAction(this, Pool.getVaultRegistry(), directory.attributes().getVault()); + LockVaultAction lockVault = new LockVaultAction(this, Pool.getVaultRegistry(), directory.attributes().getVaultMetadata().root); Background(lockVault); } else @@ -2069,7 +2069,7 @@ private bool View_ValidateNewFolder() private bool View_ValidateNewVault() { return IsMounted() && Pool.getVaultRegistry() != VaultRegistry.DISABLED && - null == Workdir.attributes().getVault() && + null == Workdir.attributes().getVaultMetadata() && ((Directory)Pool.getFeature(typeof(Directory))).isSupported( new UploadTargetFinder(Workdir).find(SelectedPath), String.Empty); }