diff --git a/src/main/java/org/cryptomator/cryptofs/CryptoFileSystems.java b/src/main/java/org/cryptomator/cryptofs/CryptoFileSystems.java index e64ab36a1..1efd9988f 100644 --- a/src/main/java/org/cryptomator/cryptofs/CryptoFileSystems.java +++ b/src/main/java/org/cryptomator/cryptofs/CryptoFileSystems.java @@ -34,13 +34,11 @@ class CryptoFileSystems { private final ConcurrentMap fileSystems = new ConcurrentHashMap<>(); private final CryptoFileSystemComponent.Factory cryptoFileSystemComponentFactory; - private final FileSystemCapabilityChecker capabilityChecker; private final SecureRandom csprng; @Inject - public CryptoFileSystems(CryptoFileSystemComponent.Factory cryptoFileSystemComponentFactory, FileSystemCapabilityChecker capabilityChecker, SecureRandom csprng) { + public CryptoFileSystems(CryptoFileSystemComponent.Factory cryptoFileSystemComponentFactory, SecureRandom csprng) { this.cryptoFileSystemComponentFactory = cryptoFileSystemComponentFactory; - this.capabilityChecker = capabilityChecker; this.csprng = csprng; } @@ -53,13 +51,12 @@ public CryptoFileSystemImpl create(CryptoFileSystemProvider provider, Path pathT try (Masterkey key = properties.keyLoader().loadKey(keyId)) { var config = configLoader.verify(key.getEncoded(), Constants.VAULT_VERSION); backupVaultConfigFile(normalizedPathToVault, properties); - var adjustedProperties = adjustForCapabilities(pathToVault, properties); var cryptor = CryptorProvider.forScheme(config.getCipherCombo()).provide(key.copy(), csprng); try { checkVaultRootExistence(pathToVault, cryptor); return fileSystems.compute(normalizedPathToVault, (path, fs) -> { if (fs == null) { - return cryptoFileSystemComponentFactory.create(cryptor, config, provider, normalizedPathToVault, adjustedProperties).cryptoFileSystem(); + return cryptoFileSystemComponentFactory.create(cryptor, config, provider, normalizedPathToVault, properties).cryptoFileSystem(); } else { throw new FileSystemAlreadyExistsException(); } @@ -123,23 +120,6 @@ private void backupVaultConfigFile(Path pathToVault, CryptoFileSystemProperties BackupHelper.attemptBackup(vaultConfigFile); } - private CryptoFileSystemProperties adjustForCapabilities(Path pathToVault, CryptoFileSystemProperties originalProperties) throws FileSystemCapabilityChecker.MissingCapabilityException { - if (!originalProperties.readonly()) { - try { - capabilityChecker.assertWriteAccess(pathToVault); - return originalProperties; - } catch (FileSystemCapabilityChecker.MissingCapabilityException e) { - capabilityChecker.assertReadAccess(pathToVault); - LOG.warn("No write access to vault. Fallback to read-only access."); - Set flags = EnumSet.copyOf(originalProperties.flags()); - flags.add(CryptoFileSystemProperties.FileSystemFlags.READONLY); - return CryptoFileSystemProperties.cryptoFileSystemPropertiesFrom(originalProperties).withFlags(flags).build(); - } - } else { - return originalProperties; - } - } - public void remove(CryptoFileSystemImpl cryptoFileSystem) { fileSystems.values().remove(cryptoFileSystem); } diff --git a/src/main/java/org/cryptomator/cryptofs/common/FileSystemCapabilityChecker.java b/src/main/java/org/cryptomator/cryptofs/common/FileSystemCapabilityChecker.java index 4dbba4ad0..f976e5781 100644 --- a/src/main/java/org/cryptomator/cryptofs/common/FileSystemCapabilityChecker.java +++ b/src/main/java/org/cryptomator/cryptofs/common/FileSystemCapabilityChecker.java @@ -7,8 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.inject.Inject; -import javax.inject.Singleton; import java.io.IOException; import java.nio.file.DirectoryIteratorException; import java.nio.file.DirectoryStream; @@ -17,8 +15,7 @@ import java.nio.file.Files; import java.nio.file.Path; -@Singleton -public class FileSystemCapabilityChecker { +public final class FileSystemCapabilityChecker { private static final Logger LOG = LoggerFactory.getLogger(FileSystemCapabilityChecker.class); @@ -38,8 +35,8 @@ public enum Capability { WRITE_ACCESS, } - @Inject - public FileSystemCapabilityChecker() { + private FileSystemCapabilityChecker() { + } /** @@ -50,7 +47,7 @@ public FileSystemCapabilityChecker() { * @implNote Only short-running tests with constant time are performed * @since 1.9.2 */ - public void assertAllCapabilities(Path pathToVault) throws MissingCapabilityException { + public static void assertAllCapabilities(Path pathToVault) throws MissingCapabilityException { assertReadAccess(pathToVault); assertWriteAccess(pathToVault); } @@ -62,7 +59,7 @@ public void assertAllCapabilities(Path pathToVault) throws MissingCapabilityExce * @throws MissingCapabilityException if the check fails * @since 1.9.3 */ - public void assertReadAccess(Path pathToVault) throws MissingCapabilityException { + public static void assertReadAccess(Path pathToVault) throws MissingCapabilityException { try (DirectoryStream ds = Files.newDirectoryStream(pathToVault)) { assert ds != null; } catch (IOException e) { @@ -77,7 +74,7 @@ public void assertReadAccess(Path pathToVault) throws MissingCapabilityException * @throws MissingCapabilityException if the check fails * @since 1.9.3 */ - public void assertWriteAccess(Path pathToVault) throws MissingCapabilityException { + public static void assertWriteAccess(Path pathToVault) throws MissingCapabilityException { Path checkDir = pathToVault.resolve("c"); try { Files.createDirectories(checkDir); @@ -90,7 +87,7 @@ public void assertWriteAccess(Path pathToVault) throws MissingCapabilityExceptio } } - public int determineSupportedCleartextFileNameLength(Path pathToVault) throws IOException { + public static int determineSupportedCleartextFileNameLength(Path pathToVault) throws IOException { int maxCiphertextLen = determineSupportedCiphertextFileNameLength(pathToVault); assert maxCiphertextLen >= Constants.MIN_CIPHER_NAME_LENGTH; // math explained in https://github.com/cryptomator/cryptofs/issues/60#issuecomment-523238303; @@ -105,7 +102,7 @@ public int determineSupportedCleartextFileNameLength(Path pathToVault) throws IO * @return Number of chars a .c9r file is allowed to have * @throws IOException If unable to perform this check */ - public int determineSupportedCiphertextFileNameLength(Path pathToVault) throws IOException { + public static int determineSupportedCiphertextFileNameLength(Path pathToVault) throws IOException { int subPathLength = Constants.MAX_ADDITIONAL_PATH_LENGTH - 2; // subtract "c/" return determineSupportedCiphertextFileNameLength(pathToVault.resolve("c"), subPathLength, Constants.MIN_CIPHER_NAME_LENGTH, Constants.MAX_CIPHER_NAME_LENGTH); } @@ -113,14 +110,14 @@ public int determineSupportedCiphertextFileNameLength(Path pathToVault) throws I /** * Determines the number of chars a filename is allowed to have inside of subdirectories of dir by running an experiment. * - * @param dir Path to a directory where to conduct the experiment (e.g. /path/to/vault/c) - * @param subPathLength Defines the combined number of chars of the subdirectories inside dir, including slashes but excluding the leading slash. Must be a minimum of 6 + * @param dir Path to a directory where to conduct the experiment (e.g. /path/to/vault/c) + * @param subPathLength Defines the combined number of chars of the subdirectories inside dir, including slashes but excluding the leading slash. Must be a minimum of 6 * @param minFileNameLength The minimum filename length to check * @param maxFileNameLength The maximum filename length to check * @return The supported filename length inside a subdirectory of dir with subPathLength chars * @throws IOException If unable to perform this check */ - public int determineSupportedCiphertextFileNameLength(Path dir, int subPathLength, int minFileNameLength, int maxFileNameLength) throws IOException { + public static int determineSupportedCiphertextFileNameLength(Path dir, int subPathLength, int minFileNameLength, int maxFileNameLength) throws IOException { Preconditions.checkArgument(subPathLength >= 6, "subPathLength must be larger than charcount(a/nnn/)"); Preconditions.checkArgument(minFileNameLength > 0); Preconditions.checkArgument(maxFileNameLength <= 999); @@ -141,7 +138,7 @@ public int determineSupportedCiphertextFileNameLength(Path dir, int subPathLengt } } - private int determineSupportedCiphertextFileNameLength(Path p, int lowerBoundIncl, int upperBoundExcl) { + private static int determineSupportedCiphertextFileNameLength(Path p, int lowerBoundIncl, int upperBoundExcl) { assert lowerBoundIncl < upperBoundExcl; int mid = (lowerBoundIncl + upperBoundExcl) / 2; assert mid < upperBoundExcl; @@ -156,7 +153,7 @@ private int determineSupportedCiphertextFileNameLength(Path p, int lowerBoundInc } } - private boolean canHandleFileNameLength(Path parent, int nameLength) { + private static boolean canHandleFileNameLength(Path parent, int nameLength) { Path checkDir = parent.resolve(String.format("%03d", nameLength)); Path checkFile = checkDir.resolve(Strings.repeat("a", nameLength)); try { @@ -175,7 +172,7 @@ private boolean canHandleFileNameLength(Path parent, int nameLength) { } } - private boolean canListDir(Path dir) { + private static boolean canListDir(Path dir) { try (DirectoryStream ds = Files.newDirectoryStream(dir)) { ds.iterator().hasNext(); // throws DirectoryIteratorException on Windows if child path too long return true; @@ -184,7 +181,7 @@ private boolean canListDir(Path dir) { } } - private void deleteSilently(Path path) { + private static void deleteSilently(Path path) { try { Files.delete(path); } catch (IOException e) { @@ -192,7 +189,7 @@ private void deleteSilently(Path path) { } } - private void deleteRecursivelySilently(Path dir) { + private static void deleteRecursivelySilently(Path dir) { try { if (Files.exists(dir)) { MoreFiles.deleteRecursively(dir, RecursiveDeleteOption.ALLOW_INSECURE); diff --git a/src/main/java/org/cryptomator/cryptofs/migration/MigrationModule.java b/src/main/java/org/cryptomator/cryptofs/migration/MigrationModule.java index fcc9ba7e1..4025765ec 100644 --- a/src/main/java/org/cryptomator/cryptofs/migration/MigrationModule.java +++ b/src/main/java/org/cryptomator/cryptofs/migration/MigrationModule.java @@ -25,11 +25,6 @@ @Module class MigrationModule { - @Provides - FileSystemCapabilityChecker provideFileSystemCapabilityChecker() { - return new FileSystemCapabilityChecker(); - } - @Provides @IntoMap @MigratorKey(Migration.FIVE_TO_SIX) diff --git a/src/main/java/org/cryptomator/cryptofs/migration/Migrators.java b/src/main/java/org/cryptomator/cryptofs/migration/Migrators.java index 09a43b95f..3f891af2a 100644 --- a/src/main/java/org/cryptomator/cryptofs/migration/Migrators.java +++ b/src/main/java/org/cryptomator/cryptofs/migration/Migrators.java @@ -46,12 +46,10 @@ public class Migrators { private static final MigrationComponent COMPONENT = DaggerMigrationComponent.builder().csprng(strongSecureRandom()).build(); private final Map migrators; - private final FileSystemCapabilityChecker fsCapabilityChecker; @Inject - Migrators(Map migrators, FileSystemCapabilityChecker fsCapabilityChecker) { + Migrators(Map migrators) { this.migrators = migrators; - this.fsCapabilityChecker = fsCapabilityChecker; } private static SecureRandom strongSecureRandom() { @@ -69,9 +67,9 @@ public static Migrators get() { /** * Inspects the vault and checks if it is supported by this library. * - * @param pathToVault Path to the vault's root + * @param pathToVault Path to the vault's root * @param vaultConfigFilename Name of the vault config file located in the vault - * @param masterkeyFilename Name of the masterkey file optionally located in the vault + * @param masterkeyFilename Name of the masterkey file optionally located in the vault * @return true if the vault at the given path is of an older format than supported by this library * @throws IOException if an I/O error occurs parsing the masterkey file */ @@ -83,19 +81,19 @@ public boolean needsMigration(Path pathToVault, String vaultConfigFilename, Stri /** * Performs the actual migration. This task may take a while and this method will block. * - * @param pathToVault Path to the vault's root - * @param vaultConfigFilename Name of the vault config file located inside pathToVault - * @param masterkeyFilename Name of the masterkey file located inside pathToVault - * @param passphrase The passphrase needed to unlock the vault - * @param progressListener Listener that will get notified of progress updates + * @param pathToVault Path to the vault's root + * @param vaultConfigFilename Name of the vault config file located inside pathToVault + * @param masterkeyFilename Name of the masterkey file located inside pathToVault + * @param passphrase The passphrase needed to unlock the vault + * @param progressListener Listener that will get notified of progress updates * @param continuationListener Listener that will get asked if there are events that require feedback - * @throws NoApplicableMigratorException If the vault can not be migrated, because no migrator could be found - * @throws InvalidPassphraseException If the passphrase could not be used to unlock the vault + * @throws NoApplicableMigratorException If the vault can not be migrated, because no migrator could be found + * @throws InvalidPassphraseException If the passphrase could not be used to unlock the vault * @throws FileSystemCapabilityChecker.MissingCapabilityException If the underlying filesystem lacks features required to store a vault - * @throws IOException if an I/O error occurs migrating the vault + * @throws IOException if an I/O error occurs migrating the vault */ public void migrate(Path pathToVault, String vaultConfigFilename, String masterkeyFilename, CharSequence passphrase, MigrationProgressListener progressListener, MigrationContinuationListener continuationListener) throws NoApplicableMigratorException, CryptoException, IOException { - fsCapabilityChecker.assertAllCapabilities(pathToVault); + FileSystemCapabilityChecker.assertAllCapabilities(pathToVault); int vaultVersion = determineVaultVersion(pathToVault, vaultConfigFilename, masterkeyFilename); try { Migrator migrator = findApplicableMigrator(vaultVersion).orElseThrow(NoApplicableMigratorException::new); diff --git a/src/main/java/org/cryptomator/cryptofs/migration/v7/Version7Migrator.java b/src/main/java/org/cryptomator/cryptofs/migration/v7/Version7Migrator.java index 86a3fdb89..510c4d995 100644 --- a/src/main/java/org/cryptomator/cryptofs/migration/v7/Version7Migrator.java +++ b/src/main/java/org/cryptomator/cryptofs/migration/v7/Version7Migrator.java @@ -66,7 +66,7 @@ public void migrate(Path vaultRoot, String vaultConfigFilename, String masterkey LOG.info("Backed up masterkey from {} to {}.", masterkeyFile.getFileName(), masterkeyBackupFile.getFileName()); // check file system capabilities: - int filenameLengthLimit = new FileSystemCapabilityChecker().determineSupportedCiphertextFileNameLength(vaultRoot.resolve("c"), 46, 28, 220); + int filenameLengthLimit = FileSystemCapabilityChecker.determineSupportedCiphertextFileNameLength(vaultRoot.resolve("c"), 46, 28, 220); int pathLengthLimit = filenameLengthLimit + 48; // TODO PreMigrationVisitor preMigrationVisitor; if (filenameLengthLimit >= 220) { diff --git a/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemsTest.java b/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemsTest.java index df1201421..7e646e578 100644 --- a/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemsTest.java +++ b/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemsTest.java @@ -41,7 +41,6 @@ public class CryptoFileSystemsTest { private final Path dataDirPath = mock(Path.class, "normalizedVaultPath/d"); private final Path preContenRootPath = mock(Path.class, "normalizedVaultPath/d/AB"); private final Path contenRootPath = mock(Path.class, "normalizedVaultPath/d/AB/CDEFGHIJKLMNOP"); - private final FileSystemCapabilityChecker capabilityChecker = mock(FileSystemCapabilityChecker.class); private final CryptoFileSystemProvider provider = mock(CryptoFileSystemProvider.class); private final CryptoFileSystemProperties properties = mock(CryptoFileSystemProperties.class); private final CryptoFileSystemComponent cryptoFileSystemComponent = mock(CryptoFileSystemComponent.class); @@ -65,7 +64,7 @@ public class CryptoFileSystemsTest { private MockedStatic cryptorProviderClass; private MockedStatic backupHelperClass; - private final CryptoFileSystems inTest = new CryptoFileSystems(cryptoFileSystemComponentFactory, capabilityChecker, csprng); + private final CryptoFileSystems inTest = new CryptoFileSystems(cryptoFileSystemComponentFactory, csprng); @BeforeEach public void setup() throws IOException, MasterkeyLoadingFailedException { diff --git a/src/test/java/org/cryptomator/cryptofs/common/FileSystemCapabilityCheckerTest.java b/src/test/java/org/cryptomator/cryptofs/common/FileSystemCapabilityCheckerTest.java index 1c363eaf4..4bb1ccb6f 100644 --- a/src/test/java/org/cryptomator/cryptofs/common/FileSystemCapabilityCheckerTest.java +++ b/src/test/java/org/cryptomator/cryptofs/common/FileSystemCapabilityCheckerTest.java @@ -20,18 +20,18 @@ import java.util.Collections; public class FileSystemCapabilityCheckerTest { - + @Nested @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class PathLengthLimits { - + private Path pathToVault = Mockito.mock(Path.class); private Path cDir = Mockito.mock(Path.class); private Path fillerDir = Mockito.mock(Path.class); private Path nnnDir = Mockito.mock(Path.class); private FileSystem fileSystem = Mockito.mock(FileSystem.class); private FileSystemProvider fileSystemProvider = Mockito.mock(FileSystemProvider.class); - + @BeforeEach public void setup() throws IOException { Mockito.when(pathToVault.getFileSystem()).thenReturn(fileSystem); @@ -55,15 +55,14 @@ public void testUnlimitedLength() throws IOException { String checkFileStr = invocation.getArgument(0); Path checkFileMock = Mockito.mock(Path.class, checkFileStr); Mockito.when(checkFileMock.getFileSystem()).thenReturn(fileSystem); - Mockito.when(fileSystemProvider.newByteChannel(Mockito.eq(checkFileMock), Mockito.any())) - .thenReturn(new SeekableByteChannelMock(0)); + Mockito.when(fileSystemProvider.newByteChannel(Mockito.eq(checkFileMock), Mockito.any())).thenReturn(new SeekableByteChannelMock(0)); return checkFileMock; }); Mockito.when(fileSystemProvider.newDirectoryStream(Mockito.eq(checkDirMock), Mockito.any())).thenReturn(DirectoryStreamMock.empty()); return checkDirMock; }); - int determinedLimit = new FileSystemCapabilityChecker().determineSupportedCiphertextFileNameLength(pathToVault); + int determinedLimit = FileSystemCapabilityChecker.determineSupportedCiphertextFileNameLength(pathToVault); Assertions.assertEquals(220, determinedLimit); } @@ -80,13 +79,12 @@ public void testLimitedLengthDuringDirListing() throws IOException { String checkFileStr = invocation.getArgument(0); Path checkFileMock = Mockito.mock(Path.class, checkFileStr); Mockito.when(checkFileMock.getFileSystem()).thenReturn(fileSystem); - Mockito.when(fileSystemProvider.newByteChannel(Mockito.eq(checkFileMock), Mockito.any())) - .thenReturn(new SeekableByteChannelMock(0)); + Mockito.when(fileSystemProvider.newByteChannel(Mockito.eq(checkFileMock), Mockito.any())).thenReturn(new SeekableByteChannelMock(0)); return checkFileMock; }); Mockito.when(fileSystemProvider.newDirectoryStream(Mockito.eq(checkDirMock), Mockito.any())).then(invocation3 -> { Iterable iterable = Mockito.mock(Iterable.class); - if (Integer.valueOf(checkDirStr) > limit) { + if (Integer.parseInt(checkDirStr) > limit) { Mockito.when(iterable.iterator()).thenThrow(new DirectoryIteratorException(new IOException("path too long"))); } else { Mockito.when(iterable.iterator()).thenReturn(Collections.emptyIterator()); @@ -96,8 +94,8 @@ public void testLimitedLengthDuringDirListing() throws IOException { return checkDirMock; }); - int determinedLimit = new FileSystemCapabilityChecker().determineSupportedCiphertextFileNameLength(pathToVault); - + int determinedLimit = FileSystemCapabilityChecker.determineSupportedCiphertextFileNameLength(pathToVault); + Assertions.assertEquals(limit, determinedLimit); } @@ -113,12 +111,10 @@ public void testLimitedLengthDuringFileCreation() throws IOException { String checkFileStr = invocation.getArgument(0); Path checkFileMock = Mockito.mock(Path.class, checkFileStr); Mockito.when(checkFileMock.getFileSystem()).thenReturn(fileSystem); - if (Integer.valueOf(checkDirStr) > limit) { - Mockito.when(fileSystemProvider.newByteChannel(Mockito.eq(checkFileMock), Mockito.any())) - .thenThrow(new IOException("name too long")); + if (Integer.parseInt(checkDirStr) > limit) { + Mockito.when(fileSystemProvider.newByteChannel(Mockito.eq(checkFileMock), Mockito.any())).thenThrow(new IOException("name too long")); } else { - Mockito.when(fileSystemProvider.newByteChannel(Mockito.eq(checkFileMock), Mockito.any())) - .thenReturn(new SeekableByteChannelMock(0)); + Mockito.when(fileSystemProvider.newByteChannel(Mockito.eq(checkFileMock), Mockito.any())).thenReturn(new SeekableByteChannelMock(0)); } return checkFileMock; }); @@ -126,7 +122,7 @@ public void testLimitedLengthDuringFileCreation() throws IOException { return checkDirMock; }); - int determinedLimit = new FileSystemCapabilityChecker().determineSupportedCiphertextFileNameLength(pathToVault); + int determinedLimit = FileSystemCapabilityChecker.determineSupportedCiphertextFileNameLength(pathToVault); Assertions.assertEquals(limit, determinedLimit); } @@ -136,14 +132,14 @@ public void testLimitedLengthDuringFileCreation() throws IOException { @CsvSource({"220, 146", "219, 143", "218, 143", "217, 143", "216, 143", "215, 140"}) public void testDetermineSupportedCleartextFileNameLength(int ciphertextLimit, int expectedCleartextLimit) throws IOException { Path path = Mockito.mock(Path.class); - FileSystemCapabilityChecker checker = Mockito.spy(new FileSystemCapabilityChecker()); - Mockito.doReturn(ciphertextLimit).when(checker).determineSupportedCiphertextFileNameLength(path); - - int result = checker.determineSupportedCleartextFileNameLength(path); - - Assertions.assertEquals(expectedCleartextLimit, result); + try (var staticCheckerMock = Mockito.mockStatic(FileSystemCapabilityChecker.class)) { + staticCheckerMock.when(() -> FileSystemCapabilityChecker.determineSupportedCiphertextFileNameLength(path)).thenReturn(ciphertextLimit); + staticCheckerMock.when(() -> FileSystemCapabilityChecker.determineSupportedCleartextFileNameLength(path)).thenCallRealMethod(); + int result = FileSystemCapabilityChecker.determineSupportedCleartextFileNameLength(path); + Assertions.assertEquals(expectedCleartextLimit, result); + } } - + } } \ No newline at end of file diff --git a/src/test/java/org/cryptomator/cryptofs/migration/MigratorsTest.java b/src/test/java/org/cryptomator/cryptofs/migration/MigratorsTest.java index 5cb2295ee..4bb038355 100644 --- a/src/test/java/org/cryptomator/cryptofs/migration/MigratorsTest.java +++ b/src/test/java/org/cryptomator/cryptofs/migration/MigratorsTest.java @@ -7,7 +7,6 @@ import org.cryptomator.cryptofs.VaultConfig; import org.cryptomator.cryptofs.common.Constants; -import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker; import org.cryptomator.cryptofs.migration.api.MigrationContinuationListener; import org.cryptomator.cryptofs.migration.api.MigrationProgressListener; import org.cryptomator.cryptofs.migration.api.Migrator; @@ -30,12 +29,8 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; import java.nio.file.Files; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.spi.FileSystemProvider; import java.util.Collections; import java.util.Map; @@ -44,20 +39,18 @@ public class MigratorsTest { private Path pathToVault; private Path vaultConfigPath; private Path masterkeyPath; - private FileSystemCapabilityChecker fsCapabilityChecker; @BeforeEach public void setup(@TempDir Path tmpDir) { pathToVault = tmpDir; vaultConfigPath = tmpDir.resolve("vault.cryptomator"); masterkeyPath = tmpDir.resolve("masterkey.cryptomator"); - fsCapabilityChecker = Mockito.mock(FileSystemCapabilityChecker.class); } @Test @DisplayName("can't determine vault version without masterkey.cryptomator or vault.cryptomator") public void throwsExceptionIfNeitherMasterkeyNorVaultConfigExists() { - Migrators migrators = new Migrators(Collections.emptyMap(), fsCapabilityChecker); + Migrators migrators = new Migrators(Collections.emptyMap()); IOException thrown = Assertions.assertThrows(IOException.class, () -> { migrators.needsMigration(pathToVault, "vault.cryptomator", "masterkey.cryptomator"); @@ -92,7 +85,7 @@ public void tearDown() { @DisplayName("needs migration if vault version < Constants.VAULT_VERSION") public void testNeedsMigration() throws IOException { Mockito.when(unverifiedVaultConfig.allegedVaultVersion()).thenReturn(Constants.VAULT_VERSION - 1); - Migrators migrators = new Migrators(Collections.emptyMap(), fsCapabilityChecker); + Migrators migrators = new Migrators(Collections.emptyMap()); boolean result = migrators.needsMigration(pathToVault, "vault.cryptomator", "masterkey.cryptomator"); @@ -103,7 +96,7 @@ public void testNeedsMigration() throws IOException { @DisplayName("needs no migration if vault version >= Constants.VAULT_VERSION") public void testNeedsNoMigration() throws IOException { Mockito.when(unverifiedVaultConfig.allegedVaultVersion()).thenReturn(Constants.VAULT_VERSION); - Migrators migrators = new Migrators(Collections.emptyMap(), fsCapabilityChecker); + Migrators migrators = new Migrators(Collections.emptyMap()); boolean result = migrators.needsMigration(pathToVault, "vault.cryptomator", "masterkey.cryptomator"); @@ -115,7 +108,7 @@ public void testNeedsNoMigration() throws IOException { public void testMigrateWithoutMigrators() { Mockito.when(unverifiedVaultConfig.allegedVaultVersion()).thenReturn(42); - Migrators migrators = new Migrators(Collections.emptyMap(), fsCapabilityChecker); + Migrators migrators = new Migrators(Collections.emptyMap()); Assertions.assertThrows(NoApplicableMigratorException.class, () -> { migrators.migrate(pathToVault, "vault.cryptomator", "masterkey.cryptomator", "secret", MigrationProgressListener.IGNORE, MigrationContinuationListener.CANCEL_ALWAYS); }); @@ -129,7 +122,7 @@ public void testMigrate() throws NoApplicableMigratorException, CryptoException, MigrationContinuationListener continuationListener = Mockito.mock(MigrationContinuationListener.class); Migrator migrator = Mockito.mock(Migrator.class); Mockito.when(unverifiedVaultConfig.allegedVaultVersion()).thenReturn(0); - Migrators migrators = new Migrators(Map.of(Migration.ZERO_TO_ONE, migrator), fsCapabilityChecker); + Migrators migrators = new Migrators(Map.of(Migration.ZERO_TO_ONE, migrator)); migrators.migrate(pathToVault, "vault.cryptomator", "masterkey.cryptomator", "secret", progressListener, continuationListener); @@ -141,7 +134,7 @@ public void testMigrate() throws NoApplicableMigratorException, CryptoException, @SuppressWarnings("deprecation") public void testMigrateUnsupportedVaultFormat() throws NoApplicableMigratorException, CryptoException, IOException { Migrator migrator = Mockito.mock(Migrator.class); - Migrators migrators = new Migrators(Map.of(Migration.ZERO_TO_ONE, migrator), fsCapabilityChecker); + Migrators migrators = new Migrators(Map.of(Migration.ZERO_TO_ONE, migrator)); Mockito.when(unverifiedVaultConfig.allegedVaultVersion()).thenReturn(0); Mockito.doThrow(new UnsupportedVaultFormatException(Integer.MAX_VALUE, 1)).when(migrator).migrate(Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any()); @@ -174,7 +167,7 @@ public void tearDown() { @DisplayName("needs migration if vault version < Constants.VAULT_VERSION") public void testNeedsMigration() throws IOException { masterkeyFileAccessClass.when(() -> MasterkeyFileAccess.readAllegedVaultVersion(Mockito.any())).thenReturn(Constants.VAULT_VERSION - 1); - Migrators migrators = new Migrators(Collections.emptyMap(), fsCapabilityChecker); + Migrators migrators = new Migrators(Collections.emptyMap()); boolean result = migrators.needsMigration(pathToVault, "vault.cryptomator", "masterkey.cryptomator"); @@ -185,7 +178,7 @@ public void testNeedsMigration() throws IOException { @DisplayName("needs no migration if vault version >= Constants.VAULT_VERSION") public void testNeedsNoMigration() throws IOException { masterkeyFileAccessClass.when(() -> MasterkeyFileAccess.readAllegedVaultVersion(Mockito.any())).thenReturn(Constants.VAULT_VERSION); - Migrators migrators = new Migrators(Collections.emptyMap(), fsCapabilityChecker); + Migrators migrators = new Migrators(Collections.emptyMap()); boolean result = migrators.needsMigration(pathToVault, "vault.cryptomator", "masterkey.cryptomator"); @@ -197,7 +190,7 @@ public void testNeedsNoMigration() throws IOException { public void testMigrateWithoutMigrators() { masterkeyFileAccessClass.when(() -> MasterkeyFileAccess.readAllegedVaultVersion(Mockito.any())).thenReturn(1337); - Migrators migrators = new Migrators(Collections.emptyMap(), fsCapabilityChecker); + Migrators migrators = new Migrators(Collections.emptyMap()); Assertions.assertThrows(NoApplicableMigratorException.class, () -> { migrators.migrate(pathToVault, "vault.cryptomator", "masterkey.cryptomator", "secret", MigrationProgressListener.IGNORE, MigrationContinuationListener.CANCEL_ALWAYS); }); @@ -211,7 +204,7 @@ public void testMigrate() throws NoApplicableMigratorException, CryptoException, MigrationContinuationListener continuationListener = Mockito.mock(MigrationContinuationListener.class); Migrator migrator = Mockito.mock(Migrator.class); masterkeyFileAccessClass.when(() -> MasterkeyFileAccess.readAllegedVaultVersion(Mockito.any())).thenReturn(0); - Migrators migrators = new Migrators(Map.of(Migration.ZERO_TO_ONE, migrator), fsCapabilityChecker); + Migrators migrators = new Migrators(Map.of(Migration.ZERO_TO_ONE, migrator)); migrators.migrate(pathToVault, "vault.cryptomator", "masterkey.cryptomator", "secret", progressListener, continuationListener); @@ -223,7 +216,7 @@ public void testMigrate() throws NoApplicableMigratorException, CryptoException, @SuppressWarnings("deprecation") public void testMigrateUnsupportedVaultFormat() throws NoApplicableMigratorException, CryptoException, IOException { Migrator migrator = Mockito.mock(Migrator.class); - Migrators migrators = new Migrators(Map.of(Migration.ZERO_TO_ONE, migrator), fsCapabilityChecker); + Migrators migrators = new Migrators(Map.of(Migration.ZERO_TO_ONE, migrator)); masterkeyFileAccessClass.when(() -> MasterkeyFileAccess.readAllegedVaultVersion(Mockito.any())).thenReturn(0); Mockito.doThrow(new UnsupportedVaultFormatException(Integer.MAX_VALUE, 1)).when(migrator).migrate(Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any());