Throw more specific error about vault directory

This commit is contained in:
Armin Schrenk
2026-05-11 12:12:58 +02:00
parent 472b10a8a4
commit 6c925d6a1f
2 changed files with 111 additions and 3 deletions
@@ -36,6 +36,7 @@ import java.util.ResourceBundle;
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
import static org.cryptomator.common.vaults.VaultState.Value.*;
import static org.cryptomator.cryptofs.common.Constants.DATA_DIR_NAME;
@Singleton
public class VaultListManager {
@@ -74,9 +75,7 @@ public class VaultListManager {
public Vault add(Path pathToVault) throws IOException {
Path normalizedPathToVault = pathToVault.normalize().toAbsolutePath();
if (CryptoFileSystemProvider.checkDirStructureForVault(normalizedPathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) == DirStructure.UNRELATED) {
throw new NoSuchFileException(normalizedPathToVault.toString(), null, "Not a vault directory");
}
assertIsVaultDirectory(normalizedPathToVault);
return get(normalizedPathToVault) //
.orElseGet(() -> {
@@ -86,6 +85,43 @@ public class VaultListManager {
});
}
static void assertIsVaultDirectory(Path pathToVault) throws IOException {
if (CryptoFileSystemProvider.checkDirStructureForVault(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) == DirStructure.UNRELATED) {
throw new NoSuchFileException(pathToVault.toString(), null, "Not a vault directory: " + determineNotVaultDirectoryReason(pathToVault));
}
}
private static String determineNotVaultDirectoryReason(Path pathToVault) {
Path dataDir = pathToVault.resolve(DATA_DIR_NAME);
if (!Files.isDirectory(dataDir)) {
return describeNotDirectory(dataDir);
}
Path vaultConfig = pathToVault.resolve(VAULTCONFIG_FILENAME);
if (!Files.isReadable(vaultConfig)) {
Path masterkey = pathToVault.resolve(MASTERKEY_FILENAME);
return describeNotReadable(vaultConfig) + "; " + describeNotReadable(masterkey) + " for legacy vault detection";
}
return "directory structure is unsupported";
}
private static String describeNotDirectory(Path path) {
if (Files.exists(path)) {
return path.getFileName() + " is not a directory";
} else {
return path.getFileName() + " directory is missing";
}
}
private static String describeNotReadable(Path path) {
if (Files.exists(path)) {
return path.getFileName() + " is not readable";
} else {
return path.getFileName() + " is missing";
}
}
private VaultSettings newVaultSettings(Path path) {
VaultSettings vaultSettings = VaultSettings.withRandomId();
vaultSettings.path.set(path);
@@ -0,0 +1,72 @@
package org.cryptomator.common.vaults;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
import static org.cryptomator.cryptofs.common.Constants.DATA_DIR_NAME;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
class VaultListManagerTest {
@Test
void testAssertIsVaultDirectoryWhenDataDirIsMissing(@TempDir Path tmpDir) {
NoSuchFileException e = assertThrows(NoSuchFileException.class, () -> {
VaultListManager.assertIsVaultDirectory(tmpDir);
});
assertTrue(e.getReason().contains(DATA_DIR_NAME + " directory is missing"));
}
@Test
void testAssertIsVaultDirectoryWhenDataDirIsFile(@TempDir Path tmpDir) throws IOException {
Files.createFile(tmpDir.resolve(DATA_DIR_NAME));
NoSuchFileException e = assertThrows(NoSuchFileException.class, () -> {
VaultListManager.assertIsVaultDirectory(tmpDir);
});
assertTrue(e.getReason().contains(DATA_DIR_NAME + " is not a directory"));
}
@Test
void testAssertIsVaultDirectoryWhenVaultConfigAndMasterkeyAreMissing(@TempDir Path tmpDir) throws IOException {
Files.createDirectory(tmpDir.resolve(DATA_DIR_NAME));
NoSuchFileException e = assertThrows(NoSuchFileException.class, () -> {
VaultListManager.assertIsVaultDirectory(tmpDir);
});
assertTrue(e.getReason().contains(VAULTCONFIG_FILENAME + " is missing"));
assertTrue(e.getReason().contains(MASTERKEY_FILENAME + " is missing"));
}
@Test
void testAssertIsVaultDirectoryAcceptsModernVault(@TempDir Path tmpDir) throws IOException {
Files.createDirectory(tmpDir.resolve(DATA_DIR_NAME));
Files.createFile(tmpDir.resolve(VAULTCONFIG_FILENAME));
assertDoesNotThrow(() -> {
VaultListManager.assertIsVaultDirectory(tmpDir);
});
}
@Test
void testAssertIsVaultDirectoryAcceptsLegacyVaultCandidate(@TempDir Path tmpDir) throws IOException {
Files.createDirectory(tmpDir.resolve(DATA_DIR_NAME));
Files.createFile(tmpDir.resolve(MASTERKEY_FILENAME));
assertDoesNotThrow(() -> {
VaultListManager.assertIsVaultDirectory(tmpDir);
});
}
}