();
- var priorEntry = ciphertextDirectories.asMap().putIfAbsent(cleartextPath, lazyEntry);
- if (priorEntry != null) {
- return priorEntry.join();
- } else {
+ CiphertextDirCache.CipherDirLoader cipherDirLoaderIfAbsent = () -> {
Path dirFile = getCiphertextFilePath(cleartextPath).getDirFilePath();
- CiphertextDirectory cipherDir = resolveDirectory(dirFile);
- lazyEntry.complete(cipherDir);
- return cipherDir;
- }
+ return resolveDirectory(dirFile);
+ };
+ return ciphertextDirCache.get(cleartextPath, cipherDirLoaderIfAbsent);
}
}
@@ -179,57 +173,4 @@ private CiphertextDirectory resolveDirectory(String dirId) {
Path dirPath = dataRoot.resolve(dirHash.substring(0, 2)).resolve(dirHash.substring(2));
return new CiphertextDirectory(dirId, dirPath);
}
-
- public static class CiphertextDirectory {
- public final String dirId;
- public final Path path;
-
- public CiphertextDirectory(String dirId, Path path) {
- this.dirId = Objects.requireNonNull(dirId);
- this.path = Objects.requireNonNull(path);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(dirId, path);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- } else if (obj instanceof CiphertextDirectory other) {
- return this.dirId.equals(other.dirId) && this.path.equals(other.path);
- } else {
- return false;
- }
- }
- }
-
- private static class DirIdAndName {
- public final String dirId;
- public final String name;
-
- public DirIdAndName(String dirId, String name) {
- this.dirId = Objects.requireNonNull(dirId);
- this.name = Objects.requireNonNull(name);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(dirId, name);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- } else if (obj instanceof DirIdAndName other) {
- return this.dirId.equals(other.dirId) && this.name.equals(other.name);
- } else {
- return false;
- }
- }
- }
-
}
diff --git a/src/main/java/org/cryptomator/cryptofs/DirIdAndName.java b/src/main/java/org/cryptomator/cryptofs/DirIdAndName.java
new file mode 100644
index 00000000..8367e556
--- /dev/null
+++ b/src/main/java/org/cryptomator/cryptofs/DirIdAndName.java
@@ -0,0 +1,19 @@
+package org.cryptomator.cryptofs;
+
+import java.util.Objects;
+
+//own file due to dagger
+
+/**
+ * Helper object to store the dir id of a directory along with its cleartext name (aka, the last element in the cleartext path)
+ * @param dirId
+ * @param clearNodeName
+ */
+record DirIdAndName(String dirId, String clearNodeName) {
+
+ public DirIdAndName(String dirId, String clearNodeName) {
+ this.dirId = Objects.requireNonNull(dirId);
+ this.clearNodeName = Objects.requireNonNull(clearNodeName);
+ }
+
+}
diff --git a/src/main/java/org/cryptomator/cryptofs/DirectoryIdBackup.java b/src/main/java/org/cryptomator/cryptofs/DirectoryIdBackup.java
index b3cdc0db..6dc2f7fe 100644
--- a/src/main/java/org/cryptomator/cryptofs/DirectoryIdBackup.java
+++ b/src/main/java/org/cryptomator/cryptofs/DirectoryIdBackup.java
@@ -26,17 +26,17 @@ public DirectoryIdBackup(Cryptor cryptor) {
}
/**
- * Performs the backup operation for the given {@link CryptoPathMapper.CiphertextDirectory} object.
+ * Performs the backup operation for the given {@link CiphertextDirectory} object.
*
- * The directory id is written via an encrypting channel to the file {@link CryptoPathMapper.CiphertextDirectory#path}/{@value Constants#DIR_BACKUP_FILE_NAME}.
+ * The directory id is written via an encrypting channel to the file {@link CiphertextDirectory#path()} /{@value Constants#DIR_BACKUP_FILE_NAME}.
*
* @param ciphertextDirectory The cipher dir object containing the dir id and the encrypted content root
* @throws IOException if an IOException is raised during the write operation
*/
- public void execute(CryptoPathMapper.CiphertextDirectory ciphertextDirectory) throws IOException {
- try (var channel = Files.newByteChannel(ciphertextDirectory.path.resolve(Constants.DIR_BACKUP_FILE_NAME), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); //
+ public void execute(CiphertextDirectory ciphertextDirectory) throws IOException {
+ try (var channel = Files.newByteChannel(ciphertextDirectory.path().resolve(Constants.DIR_BACKUP_FILE_NAME), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); //
var encryptingChannel = wrapEncryptionAround(channel, cryptor)) {
- encryptingChannel.write(ByteBuffer.wrap(ciphertextDirectory.dirId.getBytes(StandardCharsets.US_ASCII)));
+ encryptingChannel.write(ByteBuffer.wrap(ciphertextDirectory.dirId().getBytes(StandardCharsets.US_ASCII)));
}
}
@@ -44,10 +44,10 @@ public void execute(CryptoPathMapper.CiphertextDirectory ciphertextDirectory) th
* Static method to explicitly back up the directory id for a specified ciphertext directory.
*
* @param cryptor The cryptor to be used
- * @param ciphertextDirectory A {@link org.cryptomator.cryptofs.CryptoPathMapper.CiphertextDirectory} for which the dirId should be back up'd.
+ * @param ciphertextDirectory A {@link CiphertextDirectory} for which the dirId should be back up'd.
* @throws IOException when the dirId file already exists, or it cannot be written to.
*/
- public static void backupManually(Cryptor cryptor, CryptoPathMapper.CiphertextDirectory ciphertextDirectory) throws IOException {
+ public static void backupManually(Cryptor cryptor, CiphertextDirectory ciphertextDirectory) throws IOException {
new DirectoryIdBackup(cryptor).execute(ciphertextDirectory);
}
diff --git a/src/main/java/org/cryptomator/cryptofs/attr/AbstractCryptoFileAttributeView.java b/src/main/java/org/cryptomator/cryptofs/attr/AbstractCryptoFileAttributeView.java
index 82563853..7a91c2a6 100644
--- a/src/main/java/org/cryptomator/cryptofs/attr/AbstractCryptoFileAttributeView.java
+++ b/src/main/java/org/cryptomator/cryptofs/attr/AbstractCryptoFileAttributeView.java
@@ -60,7 +60,7 @@ private Path getCiphertextPath(CryptoPath path) throws IOException {
yield getCiphertextPath(resolved);
}
case DIRECTORY:
- yield pathMapper.getCiphertextDir(path).path;
+ yield pathMapper.getCiphertextDir(path).path();
case FILE:
yield pathMapper.getCiphertextFilePath(path).getFilePath();
};
diff --git a/src/main/java/org/cryptomator/cryptofs/attr/AttributeProvider.java b/src/main/java/org/cryptomator/cryptofs/attr/AttributeProvider.java
index b2195161..feff23db 100644
--- a/src/main/java/org/cryptomator/cryptofs/attr/AttributeProvider.java
+++ b/src/main/java/org/cryptomator/cryptofs/attr/AttributeProvider.java
@@ -53,7 +53,7 @@ public A readAttributes(CryptoPath cleartextPath
private Path getCiphertextPath(CryptoPath path, CiphertextFileType type) throws IOException {
return switch (type) {
case SYMLINK -> pathMapper.getCiphertextFilePath(path).getSymlinkFilePath();
- case DIRECTORY -> pathMapper.getCiphertextDir(path).path;
+ case DIRECTORY -> pathMapper.getCiphertextDir(path).path();
case FILE -> pathMapper.getCiphertextFilePath(path).getFilePath();
};
}
diff --git a/src/main/java/org/cryptomator/cryptofs/dir/BrokenDirectoryFilter.java b/src/main/java/org/cryptomator/cryptofs/dir/BrokenDirectoryFilter.java
index 2c05b34b..ba1e86ad 100644
--- a/src/main/java/org/cryptomator/cryptofs/dir/BrokenDirectoryFilter.java
+++ b/src/main/java/org/cryptomator/cryptofs/dir/BrokenDirectoryFilter.java
@@ -28,7 +28,7 @@ public Stream process(Node node) {
if (Files.isRegularFile(dirFile)) {
final Path dirPath;
try {
- dirPath = cryptoPathMapper.resolveDirectory(dirFile).path;
+ dirPath = cryptoPathMapper.resolveDirectory(dirFile).path();
} catch (IOException e) {
LOG.warn("Broken directory file: " + dirFile, e);
return Stream.empty();
diff --git a/src/main/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactory.java b/src/main/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactory.java
index 651d7dff..77ceb6f0 100644
--- a/src/main/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactory.java
+++ b/src/main/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactory.java
@@ -1,9 +1,9 @@
package org.cryptomator.cryptofs.dir;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.CryptoFileSystemScoped;
import org.cryptomator.cryptofs.CryptoPath;
import org.cryptomator.cryptofs.CryptoPathMapper;
-import org.cryptomator.cryptofs.CryptoPathMapper.CiphertextDirectory;
import org.cryptomator.cryptofs.common.Constants;
import javax.inject.Inject;
@@ -37,8 +37,8 @@ public synchronized CryptoDirectoryStream newDirectoryStream(CryptoPath cleartex
throw new ClosedFileSystemException();
}
CiphertextDirectory ciphertextDir = cryptoPathMapper.getCiphertextDir(cleartextDir);
- DirectoryStream ciphertextDirStream = Files.newDirectoryStream(ciphertextDir.path, this::matchesEncryptedContentPattern);
- var cleartextDirStream = directoryStreamComponentFactory.create(cleartextDir, ciphertextDir.dirId, ciphertextDirStream, filter, streams::remove).directoryStream();
+ DirectoryStream ciphertextDirStream = Files.newDirectoryStream(ciphertextDir.path(), this::matchesEncryptedContentPattern);
+ var cleartextDirStream = directoryStreamComponentFactory.create(cleartextDir, ciphertextDir.dirId(), ciphertextDirStream, filter, streams::remove).directoryStream();
streams.put(cleartextDirStream, ciphertextDirStream);
return cleartextDirStream;
}
diff --git a/src/main/java/org/cryptomator/cryptofs/health/dirid/MissingContentDir.java b/src/main/java/org/cryptomator/cryptofs/health/dirid/MissingContentDir.java
index 7e59d982..28cd3614 100644
--- a/src/main/java/org/cryptomator/cryptofs/health/dirid/MissingContentDir.java
+++ b/src/main/java/org/cryptomator/cryptofs/health/dirid/MissingContentDir.java
@@ -1,6 +1,6 @@
package org.cryptomator.cryptofs.health.dirid;
-import org.cryptomator.cryptofs.CryptoPathMapper;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.DirectoryIdBackup;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptofs.common.Constants;
@@ -51,7 +51,7 @@ void fix(Path pathToVault, Cryptor cryptor) throws IOException {
var dirIdHash = cryptor.fileNameCryptor().hashDirectoryId(dirId);
Path dirPath = pathToVault.resolve(Constants.DATA_DIR_NAME).resolve(dirIdHash.substring(0, 2)).resolve(dirIdHash.substring(2, 32));
Files.createDirectories(dirPath);
- DirectoryIdBackup.backupManually(cryptor, new CryptoPathMapper.CiphertextDirectory(dirId, dirPath));
+ DirectoryIdBackup.backupManually(cryptor, new CiphertextDirectory(dirId, dirPath));
}
@Override
diff --git a/src/main/java/org/cryptomator/cryptofs/health/dirid/MissingDirIdBackup.java b/src/main/java/org/cryptomator/cryptofs/health/dirid/MissingDirIdBackup.java
index be480db0..9002ba94 100644
--- a/src/main/java/org/cryptomator/cryptofs/health/dirid/MissingDirIdBackup.java
+++ b/src/main/java/org/cryptomator/cryptofs/health/dirid/MissingDirIdBackup.java
@@ -1,9 +1,8 @@
package org.cryptomator.cryptofs.health.dirid;
-import org.cryptomator.cryptofs.CryptoPathMapper;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.DirectoryIdBackup;
import org.cryptomator.cryptofs.VaultConfig;
-import org.cryptomator.cryptofs.common.Constants;
import org.cryptomator.cryptofs.health.api.DiagnosticResult;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.cryptolib.api.Masterkey;
@@ -30,7 +29,7 @@ public String toString() {
//visible for testing
void fix(Path pathToVault, Cryptor cryptor) throws IOException {
Path absCipherDir = pathToVault.resolve(contentDir);
- DirectoryIdBackup.backupManually(cryptor, new CryptoPathMapper.CiphertextDirectory(dirId, absCipherDir));
+ DirectoryIdBackup.backupManually(cryptor, new CiphertextDirectory(dirId, absCipherDir));
}
@Override
diff --git a/src/main/java/org/cryptomator/cryptofs/health/dirid/OrphanContentDir.java b/src/main/java/org/cryptomator/cryptofs/health/dirid/OrphanContentDir.java
index 505c0dc7..350616a9 100644
--- a/src/main/java/org/cryptomator/cryptofs/health/dirid/OrphanContentDir.java
+++ b/src/main/java/org/cryptomator/cryptofs/health/dirid/OrphanContentDir.java
@@ -1,7 +1,7 @@
package org.cryptomator.cryptofs.health.dirid;
import com.google.common.io.BaseEncoding;
-import org.cryptomator.cryptofs.CryptoPathMapper;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.DirectoryIdBackup;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptofs.common.CiphertextFileType;
@@ -115,7 +115,7 @@ private void fix(Path pathToVault, VaultConfig config, Cryptor cryptor) throws I
Files.deleteIfExists(orphanedDir.resolve(Constants.DIR_BACKUP_FILE_NAME));
try (var nonCryptomatorFiles = Files.newDirectoryStream(orphanedDir)) {
for (Path p : nonCryptomatorFiles) {
- Files.move(p, stepParentDir.path.resolve(p.getFileName()), LinkOption.NOFOLLOW_LINKS);
+ Files.move(p, stepParentDir.path().resolve(p.getFileName()), LinkOption.NOFOLLOW_LINKS);
}
}
Files.delete(orphanedDir);
@@ -154,7 +154,7 @@ Path prepareRecoveryDir(Path pathToVault, FileNameCryptor cryptor) throws IOExce
}
// visible for testing
- CryptoPathMapper.CiphertextDirectory prepareStepParent(Path dataDir, Path cipherRecoveryDir, Cryptor cryptor, String clearStepParentDirName) throws IOException {
+ CiphertextDirectory prepareStepParent(Path dataDir, Path cipherRecoveryDir, Cryptor cryptor, String clearStepParentDirName) throws IOException {
//create "stepparent" directory to move orphaned files to
String cipherStepParentDirName = encrypt(cryptor.fileNameCryptor(), clearStepParentDirName, Constants.RECOVERY_DIR_ID);
Path cipherStepParentDirFile = cipherRecoveryDir.resolve(cipherStepParentDirName + "/" + Constants.DIR_FILE_NAME);
@@ -169,7 +169,7 @@ CryptoPathMapper.CiphertextDirectory prepareStepParent(Path dataDir, Path cipher
String stepParentDirHash = cryptor.fileNameCryptor().hashDirectoryId(stepParentUUID);
Path stepParentDir = dataDir.resolve(stepParentDirHash.substring(0, 2)).resolve(stepParentDirHash.substring(2)).toAbsolutePath();
Files.createDirectories(stepParentDir);
- var stepParentCipherDir = new CryptoPathMapper.CiphertextDirectory(stepParentUUID, stepParentDir);
+ var stepParentCipherDir = new CiphertextDirectory(stepParentUUID, stepParentDir);
//only if it does not exist
try {
DirectoryIdBackup.backupManually(cryptor, stepParentCipherDir);
@@ -215,11 +215,11 @@ String decryptFileName(Path orphanedResource, boolean isShortened, String dirId,
}
// visible for testing
- void adoptOrphanedResource(Path oldCipherPath, String newClearName, boolean isShortened, CryptoPathMapper.CiphertextDirectory stepParentDir, FileNameCryptor cryptor, MessageDigest sha1) throws IOException {
- var newCipherName = encrypt(cryptor, newClearName, stepParentDir.dirId);
+ void adoptOrphanedResource(Path oldCipherPath, String newClearName, boolean isShortened, CiphertextDirectory stepParentDir, FileNameCryptor cryptor, MessageDigest sha1) throws IOException {
+ var newCipherName = encrypt(cryptor, newClearName, stepParentDir.dirId());
if (isShortened) {
var deflatedName = BaseEncoding.base64Url().encode(sha1.digest(newCipherName.getBytes(StandardCharsets.UTF_8))) + Constants.DEFLATED_FILE_SUFFIX;
- Path targetPath = stepParentDir.path.resolve(deflatedName);
+ Path targetPath = stepParentDir.path().resolve(deflatedName);
Files.move(oldCipherPath, targetPath);
//adjust name.c9s
@@ -227,7 +227,7 @@ void adoptOrphanedResource(Path oldCipherPath, String newClearName, boolean isSh
fc.write(ByteBuffer.wrap(newCipherName.getBytes(StandardCharsets.UTF_8)));
}
} else {
- Path targetPath = stepParentDir.path.resolve(newCipherName);
+ Path targetPath = stepParentDir.path().resolve(newCipherName);
Files.move(oldCipherPath, targetPath);
}
}
diff --git a/src/test/java/org/cryptomator/cryptofs/CiphertextDirCacheTest.java b/src/test/java/org/cryptomator/cryptofs/CiphertextDirCacheTest.java
new file mode 100644
index 00000000..9af0e613
--- /dev/null
+++ b/src/test/java/org/cryptomator/cryptofs/CiphertextDirCacheTest.java
@@ -0,0 +1,119 @@
+package org.cryptomator.cryptofs;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public class CiphertextDirCacheTest {
+
+ CiphertextDirCache cache;
+ CryptoPath clearPath;
+ CiphertextDirCache.CipherDirLoader dirLoader;
+
+
+ @BeforeEach
+ public void beforeEach() throws IOException {
+ cache = new CiphertextDirCache();
+ clearPath = Mockito.mock(CryptoPath.class);
+ dirLoader = Mockito.mock(CiphertextDirCache.CipherDirLoader.class);
+ var cipherDir = Mockito.mock(CiphertextDirectory.class);
+ Mockito.when(dirLoader.load()).thenReturn(cipherDir);
+ }
+
+ @Test
+ public void testPuttingNewEntryTriggersLoader() throws IOException {
+ var cipherDir = Mockito.mock(CiphertextDirectory.class);
+ Mockito.when(dirLoader.load()).thenReturn(cipherDir);
+
+ var result = cache.get(clearPath, dirLoader);
+ Assertions.assertEquals(cipherDir, result);
+ Mockito.verify(dirLoader).load();
+ }
+
+ @Test
+ public void testPuttingKnownEntryDoesNotTriggerLoader() throws IOException {
+ Mockito.when(dirLoader.load()).thenReturn(Mockito.mock(CiphertextDirectory.class));
+ var dirLoader2 = Mockito.mock(CiphertextDirCache.CipherDirLoader.class);
+
+ var result = cache.get(clearPath, dirLoader);
+ var result2 = cache.get(clearPath, dirLoader2);
+ Assertions.assertEquals(result2, result);
+ Mockito.verify(dirLoader2, Mockito.never()).load();
+ }
+
+ @Nested
+ public class RemovalTest {
+
+ CryptoPath prefixPath = Mockito.mock(CryptoPath.class);
+
+ @Test
+ public void entryRemovedOnPrefixSuccess() throws IOException {
+ Mockito.when(clearPath.startsWith(prefixPath)).thenReturn(true);
+
+ cache.get(clearPath, dirLoader); //triggers loader
+ cache.removeAllKeysWithPrefix(prefixPath);
+ cache.get(clearPath, dirLoader); //triggers loader
+
+ Mockito.verify(dirLoader, Mockito.times(2)).load();
+ }
+
+ @Test
+ public void entryStaysOnPrefixFailure() throws IOException {
+ Mockito.when(clearPath.startsWith(prefixPath)).thenReturn(false);
+
+ cache.get(clearPath, dirLoader); //triggers loader
+ cache.removeAllKeysWithPrefix(prefixPath);
+ cache.get(clearPath, dirLoader); //does not trigger
+
+ Mockito.verify(dirLoader).load();
+ }
+ }
+
+
+ @Nested
+ public class RemapTest {
+
+ CryptoPath newClearPath;
+ CryptoPath oldPrefixPath;
+ CryptoPath newPrefixPath;
+
+ @BeforeEach
+ public void beforeEach() throws IOException {
+ newClearPath = Mockito.mock(CryptoPath.class);
+ oldPrefixPath = Mockito.mock(CryptoPath.class);
+ newPrefixPath = Mockito.mock(CryptoPath.class);
+ Mockito.when(oldPrefixPath.relativize(Mockito.any(Path.class))).thenReturn(oldPrefixPath);
+ Mockito.when(newPrefixPath.resolve(Mockito.any(Path.class))).thenReturn(newClearPath);
+ }
+
+ @Test
+ public void entryRemappedOnPrefixSuccess() throws IOException {
+ Mockito.when(clearPath.startsWith(oldPrefixPath)).thenReturn(true);
+
+ cache.get(clearPath, dirLoader); //triggers loader
+ cache.recomputeAllKeysWithPrefix(oldPrefixPath, newPrefixPath);
+ cache.get(clearPath, dirLoader); //does trigger
+ cache.get(newClearPath, dirLoader); //does not trigger
+
+ Mockito.verify(dirLoader, Mockito.times(2)).load();
+ }
+
+ @Test
+ public void entryUntouchedOnPrefixFailure() throws IOException {
+ Mockito.when(clearPath.startsWith(oldPrefixPath)).thenReturn(false);
+
+ cache.get(clearPath, dirLoader); //triggers loader
+ cache.recomputeAllKeysWithPrefix(oldPrefixPath, newPrefixPath);
+ cache.get(clearPath, dirLoader); //does not trigger
+ cache.get(newClearPath, dirLoader); //does trigger
+
+ Mockito.verify(dirLoader, Mockito.times(2)).load();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java b/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java
index 5095b5cd..3b7d8462 100644
--- a/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java
@@ -1,6 +1,5 @@
package org.cryptomator.cryptofs;
-import org.cryptomator.cryptofs.CryptoPathMapper.CiphertextDirectory;
import org.cryptomator.cryptofs.attr.AttributeByNameProvider;
import org.cryptomator.cryptofs.attr.AttributeProvider;
import org.cryptomator.cryptofs.attr.AttributeViewProvider;
@@ -1258,11 +1257,11 @@ public void createDirectoryBackupsDirIdInCiphertextDirPath() throws IOException
Path ciphertextDirPath = mock(Path.class, "d/FF/FF/");
CiphertextFilePath ciphertextPath = mock(CiphertextFilePath.class, "ciphertext");
String dirId = "DirId1234ABC";
- CiphertextDirectory cipherDirObject = new CiphertextDirectory(dirId, ciphertextDirPath);
+ CiphertextDirectory ciphertextDirectoryObject = new CiphertextDirectory(dirId, ciphertextDirPath);
FileChannelMock channel = new FileChannelMock(100);
when(ciphertextRawPath.resolve("dir.c9r")).thenReturn(ciphertextDirFile);
when(cryptoPathMapper.getCiphertextFilePath(path)).thenReturn(ciphertextPath);
- when(cryptoPathMapper.getCiphertextDir(path)).thenReturn(cipherDirObject);
+ when(cryptoPathMapper.getCiphertextDir(path)).thenReturn(ciphertextDirectoryObject);
when(cryptoPathMapper.getCiphertextDir(parent)).thenReturn(new CiphertextDirectory("parentDirId", ciphertextParent));
when(cryptoPathMapper.getCiphertextFileType(path)).thenThrow(NoSuchFileException.class);
when(ciphertextPath.getRawPath()).thenReturn(ciphertextRawPath);
@@ -1278,7 +1277,7 @@ public void createDirectoryBackupsDirIdInCiphertextDirPath() throws IOException
inTest.createDirectory(path);
verify(readonlyFlag).assertWritable();
- verify(dirIdBackup, Mockito.times(1)).execute(cipherDirObject);
+ verify(dirIdBackup, Mockito.times(1)).execute(ciphertextDirectoryObject);
}
diff --git a/src/test/java/org/cryptomator/cryptofs/CryptoPathMapperTest.java b/src/test/java/org/cryptomator/cryptofs/CryptoPathMapperTest.java
index 32241fb8..93cdda8d 100644
--- a/src/test/java/org/cryptomator/cryptofs/CryptoPathMapperTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/CryptoPathMapperTest.java
@@ -64,6 +64,7 @@ public void setup() {
Mockito.when(fileSystem.getEmptyPath()).thenReturn(empty);
}
+
@Test
public void testPathEncryptionForRoot() throws IOException {
Path d00 = Mockito.mock(Path.class);
@@ -74,7 +75,7 @@ public void testPathEncryptionForRoot() throws IOException {
Mockito.when(d00.resolve("00")).thenReturn(d0000);
CryptoPathMapper mapper = new CryptoPathMapper(pathToVault, cryptor, dirIdProvider, longFileNameProvider, vaultConfig);
- Path path = mapper.getCiphertextDir(fileSystem.getRootPath()).path;
+ Path path = mapper.getCiphertextDir(fileSystem.getRootPath()).path();
Assertions.assertEquals(d0000, path);
}
@@ -98,7 +99,7 @@ public void testPathEncryptionForFoo() throws IOException {
Mockito.when(d00.resolve("01")).thenReturn(d0001);
CryptoPathMapper mapper = new CryptoPathMapper(pathToVault, cryptor, dirIdProvider, longFileNameProvider, vaultConfig);
- Path path = mapper.getCiphertextDir(fileSystem.getPath("/foo")).path;
+ Path path = mapper.getCiphertextDir(fileSystem.getPath("/foo")).path();
Assertions.assertEquals(d0001, path);
}
@@ -132,7 +133,7 @@ public void testPathEncryptionForFooBar() throws IOException {
Mockito.when(d00.resolve("02")).thenReturn(d0002);
CryptoPathMapper mapper = new CryptoPathMapper(pathToVault, cryptor, dirIdProvider, longFileNameProvider, vaultConfig);
- Path path = mapper.getCiphertextDir(fileSystem.getPath("/foo/bar")).path;
+ Path path = mapper.getCiphertextDir(fileSystem.getPath("/foo/bar")).path();
Assertions.assertEquals(d0002, path);
}
@@ -333,7 +334,113 @@ public void testGetCiphertextFileTypeForShortenedFile() throws IOException {
Assertions.assertEquals(CiphertextFileType.FILE, type);
}
+ }
+
+ @Nested
+ public class InvalidateOrMovePathMapping {
+
+ Path d00 = Mockito.mock(Path.class);
+ Path d0000 = Mockito.mock(Path.class, "d/00/00");
+ Path d0000oof = Mockito.mock(Path.class, "d/00/00/oof.c9r");
+ Path d0000oofdirFile = Mockito.mock(Path.class, "d/00/00/oof.c9r/dir.c9r");
+ Path d0001 = Mockito.mock(Path.class, "d/00/01");
+ Path d0001rab = Mockito.mock(Path.class, "d/00/01/rab.c9r");
+ Path d0000rabdirFile = Mockito.mock(Path.class, "d/00/00/rab.c9r/dir.c9r");
+ Path d0002 = Mockito.mock(Path.class);
+ Path d0000kik = Mockito.mock(Path.class, "d/00/00/kik.c9r");
+ Path d0000kikdirFile = Mockito.mock(Path.class, "d/00/00/kik.c9r/dir.c9r");
+ Path d0003 = Mockito.mock(Path.class, "d/00/03/kik.c9r");
+
+ @BeforeEach
+ void beforeEach() throws IOException {
+ Mockito.when(dataRoot.resolve("00")).thenReturn(d00);
+ Mockito.when(fileNameCryptor.hashDirectoryId("")).thenReturn("0000");
+
+ // /foo
+ Mockito.when(d00.resolve("00")).thenReturn(d0000);
+ Mockito.when(d0000.resolve("oof.c9r")).thenReturn(d0000oof);
+ Mockito.when(d0000oof.resolve("dir.c9r")).thenReturn(d0000oofdirFile);
+ Mockito.when(fileNameCryptor.encryptFilename(Mockito.any(), Mockito.eq("foo"), Mockito.any())).thenReturn("oof");
+ Mockito.when(dirIdProvider.load(d0000oofdirFile)).thenReturn("1");
+ Mockito.when(fileNameCryptor.hashDirectoryId("1")).thenReturn("0001");
+
+ // /kik
+ Mockito.when(d0000.resolve("kik.c9r")).thenReturn(d0000kik);
+ Mockito.when(d0000kik.resolve("dir.c9r")).thenReturn(d0000kikdirFile);
+ Mockito.when(fileNameCryptor.encryptFilename(Mockito.any(), Mockito.eq("kik"), Mockito.any())).thenReturn("kik");
+ Mockito.when(dirIdProvider.load(d0000kikdirFile)).thenReturn("3");
+ Mockito.when(fileNameCryptor.hashDirectoryId("3")).thenReturn("0003");
+
+ // /foo/bar
+ Mockito.when(d00.resolve("01")).thenReturn(d0001);
+ Mockito.when(d0001.resolve("rab.c9r")).thenReturn(d0001rab);
+ Mockito.when(d0001rab.resolve("dir.c9r")).thenReturn(d0000rabdirFile);
+ Mockito.when(fileNameCryptor.encryptFilename(Mockito.any(), Mockito.eq("bar"), Mockito.any())).thenReturn("rab");
+ Mockito.when(dirIdProvider.load(d0000rabdirFile)).thenReturn("2");
+ Mockito.when(fileNameCryptor.hashDirectoryId("2")).thenReturn("0002");
+
+ Mockito.when(d00.resolve("02")).thenReturn(d0002);
+ Mockito.when(d00.resolve("03")).thenReturn(d0003);
+ }
+
+ @Test
+ @DisplayName("Invalidating node causes cache miss on next retrieval")
+ public void testRemovedEntryMiss() throws IOException {
+ CryptoPathMapper mapper = new CryptoPathMapper(pathToVault, cryptor, dirIdProvider, longFileNameProvider, vaultConfig);
+ var fooPath = fileSystem.getPath("/foo");
+ mapper.getCiphertextDir(fooPath);
+ mapper.invalidatePathMapping(fooPath);
+ var mapperSpy = Mockito.spy(mapper);
+ mapperSpy.getCiphertextDir(fooPath);
+ Mockito.verify(mapperSpy, Mockito.atLeastOnce()).getCiphertextFilePath(fooPath); //loader is triggered, hence we have a cache miss
+ }
+
+ @Test
+ @DisplayName("Invalidating node also invalidates all children")
+ public void testRemovedEntryChildMiss() throws IOException {
+ var fooPath = fileSystem.getPath("/foo");
+ var fooBarPath = fileSystem.getPath("/foo/bar");
+
+ CryptoPathMapper mapper = new CryptoPathMapper(pathToVault, cryptor, dirIdProvider, longFileNameProvider, vaultConfig);
+ mapper.getCiphertextDir(fooPath);
+ mapper.getCiphertextDir(fooBarPath);
+ mapper.invalidatePathMapping(fooPath);
+ var mapperSpy = Mockito.spy(mapper);
+ mapperSpy.getCiphertextDir(fooBarPath);
+ Mockito.verify(mapperSpy, Mockito.atLeastOnce()).getCiphertextFilePath(fooBarPath); //loader is triggered, hence we have a cache miss
+ mapperSpy.getCiphertextDir(fooBarPath);
+ }
+
+ @Test
+ @DisplayName("Moving node causes cache miss for oldPath and cache hit for new")
+ public void testMoveEntryOldMissNewHit() throws IOException {
+ var fooPath = fileSystem.getPath("/foo");
+ var kikPath = fileSystem.getPath("/kik");
+
+ CryptoPathMapper mapper = new CryptoPathMapper(pathToVault, cryptor, dirIdProvider, longFileNameProvider, vaultConfig);
+ mapper.getCiphertextDir(fooPath);
+ mapper.movePathMapping(fooPath, kikPath);
+ var mapperSpy = Mockito.spy(mapper);
+ mapperSpy.getCiphertextDir(fooPath);
+ Mockito.verify(mapperSpy, Mockito.atLeastOnce()).getCiphertextFilePath(fooPath); //loader is triggered, hence we have a cache miss
+ Mockito.verify(mapperSpy, Mockito.never()).getCiphertextFilePath(kikPath); //loader is not triggered, hence we have a cache hit
+ }
+ @Test
+ @DisplayName("Moving node causes cache miss for childs of oldPath")
+ public void testMoveEntryOldChildMiss() throws IOException {
+ var fooPath = fileSystem.getPath("/foo");
+ var fooBarPath = fileSystem.getPath("/foo/bar");
+ var kikPath = fileSystem.getPath("/kik");
+
+ CryptoPathMapper mapper = new CryptoPathMapper(pathToVault, cryptor, dirIdProvider, longFileNameProvider, vaultConfig);
+ mapper.getCiphertextDir(fooPath);
+ mapper.getCiphertextDir(fooBarPath);
+ mapper.movePathMapping(fooPath, kikPath);
+ var mapperSpy = Mockito.spy(mapper);
+ mapperSpy.getCiphertextDir(fooBarPath);
+ Mockito.verify(mapperSpy, Mockito.atLeastOnce()).getCiphertextFilePath(fooBarPath); //loader is triggered, hence we have a cache miss
+ }
}
}
diff --git a/src/test/java/org/cryptomator/cryptofs/DirectoryIdBackupTest.java b/src/test/java/org/cryptomator/cryptofs/DirectoryIdBackupTest.java
index 19805b25..58739e90 100644
--- a/src/test/java/org/cryptomator/cryptofs/DirectoryIdBackupTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/DirectoryIdBackupTest.java
@@ -22,7 +22,7 @@ public class DirectoryIdBackupTest {
Path contentPath;
private String dirId = "12345678";
- private CryptoPathMapper.CiphertextDirectory cipherDirObject;
+ private CiphertextDirectory ciphertextDirectoryObject;
private EncryptingWritableByteChannel encChannel;
private Cryptor cryptor;
@@ -31,7 +31,7 @@ public class DirectoryIdBackupTest {
@BeforeEach
public void init() {
- cipherDirObject = new CryptoPathMapper.CiphertextDirectory(dirId, contentPath);
+ ciphertextDirectoryObject = new CiphertextDirectory(dirId, contentPath);
cryptor = Mockito.mock(Cryptor.class);
encChannel = Mockito.mock(EncryptingWritableByteChannel.class);
@@ -44,7 +44,7 @@ public void testIdFileCreated() throws IOException {
backupMock.when(() -> DirectoryIdBackup.wrapEncryptionAround(Mockito.any(), Mockito.eq(cryptor))).thenReturn(encChannel);
Mockito.when(encChannel.write(Mockito.any())).thenReturn(0);
- dirIdBackup.execute(cipherDirObject);
+ dirIdBackup.execute(ciphertextDirectoryObject);
Assertions.assertTrue(Files.exists(contentPath.resolve(Constants.DIR_BACKUP_FILE_NAME)));
}
@@ -58,7 +58,7 @@ public void testContentIsWritten() throws IOException {
try (MockedStatic backupMock = Mockito.mockStatic(DirectoryIdBackup.class)) {
backupMock.when(() -> DirectoryIdBackup.wrapEncryptionAround(Mockito.any(), Mockito.eq(cryptor))).thenReturn(encChannel);
- dirIdBackup.execute(cipherDirObject);
+ dirIdBackup.execute(ciphertextDirectoryObject);
Mockito.verify(encChannel, Mockito.times(1)).write(Mockito.argThat(b -> b.equals(expectedWrittenContent)));
}
diff --git a/src/test/java/org/cryptomator/cryptofs/attr/AttributeProviderTest.java b/src/test/java/org/cryptomator/cryptofs/attr/AttributeProviderTest.java
index d123f3df..33230151 100644
--- a/src/test/java/org/cryptomator/cryptofs/attr/AttributeProviderTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/attr/AttributeProviderTest.java
@@ -8,10 +8,10 @@
*******************************************************************************/
package org.cryptomator.cryptofs.attr;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.CiphertextFilePath;
import org.cryptomator.cryptofs.CryptoPath;
import org.cryptomator.cryptofs.CryptoPathMapper;
-import org.cryptomator.cryptofs.CryptoPathMapper.CiphertextDirectory;
import org.cryptomator.cryptofs.Symlinks;
import org.cryptomator.cryptofs.common.CiphertextFileType;
import org.junit.jupiter.api.Assertions;
diff --git a/src/test/java/org/cryptomator/cryptofs/dir/BrokenDirectoryFilterTest.java b/src/test/java/org/cryptomator/cryptofs/dir/BrokenDirectoryFilterTest.java
index e18810e1..c2bf66a9 100644
--- a/src/test/java/org/cryptomator/cryptofs/dir/BrokenDirectoryFilterTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/dir/BrokenDirectoryFilterTest.java
@@ -1,5 +1,6 @@
package org.cryptomator.cryptofs.dir;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.CryptoPathMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -31,7 +32,7 @@ public void testProcessNormalDirectoryNode(@TempDir Path dir) throws IOException
Path targetDir = Files.createDirectories(dir.resolve("d/ab/cdefg"));
Files.createDirectory(dir.resolve("foo.c9r"));
Files.write(dir.resolve("foo.c9r/dir.c9r"), "".getBytes());
- Mockito.when(cryptoPathMapper.resolveDirectory(Mockito.any())).thenReturn(new CryptoPathMapper.CiphertextDirectory("asd", targetDir));
+ Mockito.when(cryptoPathMapper.resolveDirectory(Mockito.any())).thenReturn(new CiphertextDirectory("asd", targetDir));
Node unfiltered = new Node(dir.resolve("foo.c9r"));
Stream result = brokenDirectoryFilter.process(unfiltered);
@@ -45,7 +46,7 @@ public void testProcessNodeWithMissingTargetDir(@TempDir Path dir) throws IOExce
Path targetDir = dir.resolve("d/ab/cdefg"); // not existing!
Files.createDirectory(dir.resolve("foo.c9r"));
Files.write(dir.resolve("foo.c9r/dir.c9r"), "".getBytes());
- Mockito.when(cryptoPathMapper.resolveDirectory(Mockito.any())).thenReturn(new CryptoPathMapper.CiphertextDirectory("asd", targetDir));
+ Mockito.when(cryptoPathMapper.resolveDirectory(Mockito.any())).thenReturn(new CiphertextDirectory("asd", targetDir));
Node unfiltered = new Node(dir.resolve("foo.c9r"));
Stream result = brokenDirectoryFilter.process(unfiltered);
diff --git a/src/test/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactoryTest.java b/src/test/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactoryTest.java
index c4361278..eada83a8 100644
--- a/src/test/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactoryTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactoryTest.java
@@ -1,8 +1,8 @@
package org.cryptomator.cryptofs.dir;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.CryptoPath;
import org.cryptomator.cryptofs.CryptoPathMapper;
-import org.cryptomator.cryptofs.CryptoPathMapper.CiphertextDirectory;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
diff --git a/src/test/java/org/cryptomator/cryptofs/health/dirid/MissingContentDirTest.java b/src/test/java/org/cryptomator/cryptofs/health/dirid/MissingContentDirTest.java
index 8a9aef15..10e9ba35 100644
--- a/src/test/java/org/cryptomator/cryptofs/health/dirid/MissingContentDirTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/health/dirid/MissingContentDirTest.java
@@ -1,6 +1,6 @@
package org.cryptomator.cryptofs.health.dirid;
-import org.cryptomator.cryptofs.CryptoPathMapper;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.DirectoryIdBackup;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptolib.api.Cryptor;
@@ -60,7 +60,7 @@ public void testFix() throws IOException {
result.fix(pathToVault, cryptor);
var expectedPath = pathToVault.resolve("d/ri/diculous-32-char-pseudo-hashhh");
- ArgumentMatcher cipherDirMatcher = obj -> obj.dirId.equals(dirId) && obj.path.endsWith(expectedPath);
+ ArgumentMatcher cipherDirMatcher = obj -> obj.dirId().equals(dirId) && obj.path().endsWith(expectedPath);
dirIdBackupMock.verify(() -> DirectoryIdBackup.backupManually(Mockito.eq(cryptor), Mockito.argThat(cipherDirMatcher)), Mockito.times(1));
var attr = Assertions.assertDoesNotThrow(() -> Files.readAttributes(expectedPath, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS));
Assertions.assertTrue(attr.isDirectory());
diff --git a/src/test/java/org/cryptomator/cryptofs/health/dirid/MissingDirIdBackupTest.java b/src/test/java/org/cryptomator/cryptofs/health/dirid/MissingDirIdBackupTest.java
index 09aedef5..cb97d0b7 100644
--- a/src/test/java/org/cryptomator/cryptofs/health/dirid/MissingDirIdBackupTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/health/dirid/MissingDirIdBackupTest.java
@@ -1,6 +1,6 @@
package org.cryptomator.cryptofs.health.dirid;
-import org.cryptomator.cryptofs.CryptoPathMapper;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.DirectoryIdBackup;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptolib.api.Cryptor;
@@ -43,7 +43,7 @@ public void testFix() throws IOException {
result.fix(pathToVault, cryptor);
var expectedPath = pathToVault.resolve(cipherDir);
- ArgumentMatcher cipherDirMatcher = obj -> obj.dirId.equals(dirId) && obj.path.isAbsolute() && obj.path.equals(expectedPath);
+ ArgumentMatcher cipherDirMatcher = obj -> obj.dirId().equals(dirId) && obj.path().isAbsolute() && obj.path().equals(expectedPath);
dirIdBackupMock.verify(() -> DirectoryIdBackup.backupManually(Mockito.eq(cryptor), Mockito.argThat(cipherDirMatcher)), Mockito.times(1));
}
}
diff --git a/src/test/java/org/cryptomator/cryptofs/health/dirid/OrphanDirTest.java b/src/test/java/org/cryptomator/cryptofs/health/dirid/OrphanDirTest.java
index fcc5888e..9f9c93b2 100644
--- a/src/test/java/org/cryptomator/cryptofs/health/dirid/OrphanDirTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/health/dirid/OrphanDirTest.java
@@ -1,7 +1,7 @@
package org.cryptomator.cryptofs.health.dirid;
import com.google.common.io.BaseEncoding;
-import org.cryptomator.cryptofs.CryptoPathMapper;
+import org.cryptomator.cryptofs.CiphertextDirectory;
import org.cryptomator.cryptofs.DirectoryIdBackup;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptofs.common.Constants;
@@ -20,7 +20,6 @@
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileAlreadyExistsException;
@@ -327,15 +326,15 @@ public void testAdoptOrphanedUnshortened() throws IOException {
String newClearName = "OliverTwist";
Files.writeString(oldCipherPath, expectedMsg, StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
- CryptoPathMapper.CiphertextDirectory stepParentDir = new CryptoPathMapper.CiphertextDirectory("aaaaaa", pathToVault.resolve("d/22/2222"));
- Files.createDirectories(stepParentDir.path);
+ CiphertextDirectory stepParentDir = new CiphertextDirectory("aaaaaa", pathToVault.resolve("d/22/2222"));
+ Files.createDirectories(stepParentDir.path());
- Mockito.doReturn("adopted").when(fileNameCryptor).encryptFilename(BaseEncoding.base64Url(), newClearName, stepParentDir.dirId.getBytes(StandardCharsets.UTF_8));
+ Mockito.doReturn("adopted").when(fileNameCryptor).encryptFilename(BaseEncoding.base64Url(), newClearName, stepParentDir.dirId().getBytes(StandardCharsets.UTF_8));
var sha1 = Mockito.mock(MessageDigest.class);
result.adoptOrphanedResource(oldCipherPath, newClearName, false, stepParentDir, fileNameCryptor, sha1);
- Assertions.assertEquals(expectedMsg, Files.readString(stepParentDir.path.resolve("adopted.c9r")));
+ Assertions.assertEquals(expectedMsg, Files.readString(stepParentDir.path().resolve("adopted.c9r")));
Assertions.assertTrue(Files.notExists(oldCipherPath));
}
@@ -348,8 +347,8 @@ public void testAdoptOrphanedShortened() throws IOException {
Files.createDirectories(oldCipherPath);
Files.createFile(oldCipherPath.resolve("name.c9s"));
- CryptoPathMapper.CiphertextDirectory stepParentDir = new CryptoPathMapper.CiphertextDirectory("aaaaaa", pathToVault.resolve("d/22/2222"));
- Files.createDirectories(stepParentDir.path);
+ CiphertextDirectory stepParentDir = new CiphertextDirectory("aaaaaa", pathToVault.resolve("d/22/2222"));
+ Files.createDirectories(stepParentDir.path());
Mockito.doReturn("adopted").when(fileNameCryptor).encryptFilename(Mockito.any(), Mockito.any(), Mockito.any());
try (var baseEncodingClass = Mockito.mockStatic(BaseEncoding.class)) {
@@ -363,8 +362,8 @@ public void testAdoptOrphanedShortened() throws IOException {
result.adoptOrphanedResource(oldCipherPath, newClearName, true, stepParentDir, fileNameCryptor, sha1);
}
- Assertions.assertTrue(Files.exists(stepParentDir.path.resolve("adopted_shortened.c9s")));
- Assertions.assertEquals("adopted.c9r", Files.readString(stepParentDir.path.resolve("adopted_shortened.c9s/name.c9s")));
+ Assertions.assertTrue(Files.exists(stepParentDir.path().resolve("adopted_shortened.c9s")));
+ Assertions.assertEquals("adopted.c9r", Files.readString(stepParentDir.path().resolve("adopted_shortened.c9s/name.c9s")));
Assertions.assertTrue(Files.notExists(oldCipherPath));
}
@@ -376,8 +375,8 @@ public void testAdoptOrphanedShortenedMissingNameC9s() throws IOException {
String newClearName = "TomSawyer";
Files.createDirectories(oldCipherPath);
- CryptoPathMapper.CiphertextDirectory stepParentDir = new CryptoPathMapper.CiphertextDirectory("aaaaaa", pathToVault.resolve("d/22/2222"));
- Files.createDirectories(stepParentDir.path);
+ CiphertextDirectory stepParentDir = new CiphertextDirectory("aaaaaa", pathToVault.resolve("d/22/2222"));
+ Files.createDirectories(stepParentDir.path());
Mockito.doReturn("adopted").when(fileNameCryptor).encryptFilename(Mockito.any(), Mockito.any(), Mockito.any());
try (var baseEncodingClass = Mockito.mockStatic(BaseEncoding.class)) {
@@ -391,8 +390,8 @@ public void testAdoptOrphanedShortenedMissingNameC9s() throws IOException {
result.adoptOrphanedResource(oldCipherPath, newClearName, true, stepParentDir, fileNameCryptor, sha1);
}
- Assertions.assertTrue(Files.exists(stepParentDir.path.resolve("adopted_shortened.c9s")));
- Assertions.assertEquals("adopted.c9r", Files.readString(stepParentDir.path.resolve("adopted_shortened.c9s/name.c9s")));
+ Assertions.assertTrue(Files.exists(stepParentDir.path().resolve("adopted_shortened.c9s")));
+ Assertions.assertEquals("adopted.c9r", Files.readString(stepParentDir.path().resolve("adopted_shortened.c9s/name.c9s")));
Assertions.assertTrue(Files.notExists(oldCipherPath));
}
@@ -410,7 +409,7 @@ public void testFixNoDirId() throws IOException {
Files.createFile(orphan1);
Files.createDirectories(orphan2);
- CryptoPathMapper.CiphertextDirectory stepParentDir = new CryptoPathMapper.CiphertextDirectory("aaaaaa", dataDir.resolve("22/2222"));
+ CiphertextDirectory stepParentDir = new CiphertextDirectory("aaaaaa", dataDir.resolve("22/2222"));
VaultConfig config = Mockito.mock(VaultConfig.class);
Mockito.doReturn(170).when(config).getShorteningThreshold();
@@ -443,7 +442,7 @@ public void testFixContinuesOnNotRecoverableFilename() throws IOException {
var dirId = Optional.of("trololo-id");
- CryptoPathMapper.CiphertextDirectory stepParentDir = new CryptoPathMapper.CiphertextDirectory("aaaaaa", dataDir.resolve("22/2222"));
+ CiphertextDirectory stepParentDir = new CiphertextDirectory("aaaaaa", dataDir.resolve("22/2222"));
VaultConfig config = Mockito.mock(VaultConfig.class);
Mockito.doReturn(170).when(config).getShorteningThreshold();
@@ -482,7 +481,7 @@ public void testFixWithDirId() throws IOException {
var dirId = Optional.of("trololo-id");
- CryptoPathMapper.CiphertextDirectory stepParentDir = new CryptoPathMapper.CiphertextDirectory("aaaaaa", dataDir.resolve("22/2222"));
+ CiphertextDirectory stepParentDir = new CiphertextDirectory("aaaaaa", dataDir.resolve("22/2222"));
VaultConfig config = Mockito.mock(VaultConfig.class);
Mockito.doReturn(170).when(config).getShorteningThreshold();
@@ -525,8 +524,8 @@ public void testFixWithNonCryptomatorFiles() throws IOException {
var dirId = Optional.of("trololo-id");
- CryptoPathMapper.CiphertextDirectory stepParentDir = new CryptoPathMapper.CiphertextDirectory("aaaaaa", dataDir.resolve("22/2222"));
- Files.createDirectories(stepParentDir.path); //needs to be created here, otherwise the Files.move(non-crypto-resource, stepparent) will fail
+ CiphertextDirectory stepParentDir = new CiphertextDirectory("aaaaaa", dataDir.resolve("22/2222"));
+ Files.createDirectories(stepParentDir.path()); //needs to be created here, otherwise the Files.move(non-crypto-resource, stepparent) will fail
VaultConfig config = Mockito.mock(VaultConfig.class);
Mockito.doReturn(170).when(config).getShorteningThreshold();
@@ -548,7 +547,7 @@ public void testFixWithNonCryptomatorFiles() throws IOException {
Mockito.verify(resultSpy, Mockito.never()).adoptOrphanedResource(Mockito.eq(unrelated), Mockito.any(), Mockito.anyBoolean(), Mockito.eq(stepParentDir), Mockito.eq(fileNameCryptor), Mockito.any());
Mockito.verify(resultSpy, Mockito.times(1)).adoptOrphanedResource(Mockito.eq(orphan1), Mockito.eq(lostName1), Mockito.anyBoolean(), Mockito.eq(stepParentDir), Mockito.eq(fileNameCryptor), Mockito.any());
Mockito.verify(resultSpy, Mockito.times(1)).adoptOrphanedResource(Mockito.eq(orphan2), Mockito.eq(lostName2), Mockito.anyBoolean(), Mockito.eq(stepParentDir), Mockito.eq(fileNameCryptor), Mockito.any());
- Assertions.assertTrue(Files.exists(stepParentDir.path.resolve("unrelated.file")));
+ Assertions.assertTrue(Files.exists(stepParentDir.path().resolve("unrelated.file")));
Assertions.assertTrue(Files.notExists(cipherOrphan));
}