newDirectoryStream(CryptoPath cleartextDir, Filter<
ciphertextDir, //
cleartextDir, //
cryptor.fileNameCryptor(), //
+ cryptoPathMapper, //
longFileNameProvider, //
conflictResolver, //
filter, //
diff --git a/src/main/java/org/cryptomator/cryptofs/GlobToRegex.java b/src/main/java/org/cryptomator/cryptofs/GlobToRegex.java
index a43e29a4..a19c254e 100644
--- a/src/main/java/org/cryptomator/cryptofs/GlobToRegex.java
+++ b/src/main/java/org/cryptomator/cryptofs/GlobToRegex.java
@@ -40,14 +40,12 @@ class GlobToRegex {
* Basic conversions (assuming / as only separator):
*
*
- * {@code
* ? = [^/]
* * = [^/]*
* ** = .*
* [a-z] = [[^/]&&[a-z]]
* [!a-z] = [[^/]&&[^a-z]]
* {a,b,c} = (a|b|c)
- * }
*
*/
public static String toRegex(String glob, char separator) {
diff --git a/src/test/java/org/cryptomator/cryptofs/CryptoDirectoryStreamTest.java b/src/test/java/org/cryptomator/cryptofs/CryptoDirectoryStreamTest.java
index 60009ba1..c2a306aa 100644
--- a/src/test/java/org/cryptomator/cryptofs/CryptoDirectoryStreamTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/CryptoDirectoryStreamTest.java
@@ -19,6 +19,7 @@
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.Iterator;
@@ -57,6 +58,7 @@ public static void setupClass() {
private FileNameCryptor filenameCryptor;
private Path ciphertextDirPath;
private DirectoryStream dirStream;
+ private CryptoPathMapper cryptoPathMapper;
private LongFileNameProvider longFileNameProvider;
private ConflictResolver conflictResolver;
private FinallyUtil finallyUtil;
@@ -84,6 +86,20 @@ public void setup() throws IOException {
return StringUtils.removeEnd(shortName, ".lng");
}
});
+ cryptoPathMapper = Mockito.mock(CryptoPathMapper.class);
+ Mockito.when(cryptoPathMapper.resolveDirectory(Mockito.any())).then(invocation -> {
+ Path dirFilePath = invocation.getArgument(0);
+ if (dirFilePath.toString().contains("invalid")) {
+ throw new IOException("Invalid directory.");
+ }
+ Path dirPath = Mockito.mock(Path.class);
+ BasicFileAttributes attrs = Mockito.mock(BasicFileAttributes.class);
+ Mockito.when(dirPath.getFileSystem()).thenReturn(fs);
+ Mockito.when(provider.readAttributes(dirPath, BasicFileAttributes.class)).thenReturn(attrs);
+ Mockito.when(attrs.isDirectory()).thenReturn(!dirFilePath.toString().contains("noDirectory"));
+ return new Directory("asdf", dirPath);
+ });
+
Mockito.when(conflictResolver.resolveConflictsIfNecessary(Mockito.any(), Mockito.any())).then(returnsFirstArg());
doAnswer(invocation -> {
@@ -102,14 +118,16 @@ public void testDirListing() throws IOException {
ciphertextFileNames.add(filenameCryptor.encryptFilename("one", "foo".getBytes()));
ciphertextFileNames.add(filenameCryptor.encryptFilename("two", "foo".getBytes()) + "_conflict");
ciphertextFileNames.add("0" + filenameCryptor.encryptFilename("three", "foo".getBytes()));
+ ciphertextFileNames.add("0invalidDirectory");
+ ciphertextFileNames.add("0noDirectory");
ciphertextFileNames.add("invalidLongName.lng");
ciphertextFileNames.add(filenameCryptor.encryptFilename("four", "foo".getBytes()) + ".lng");
ciphertextFileNames.add(filenameCryptor.encryptFilename("invalid", "bar".getBytes()));
ciphertextFileNames.add("alsoInvalid");
Mockito.when(dirStream.spliterator()).thenReturn(ciphertextFileNames.stream().map(cleartextPath::resolve).spliterator());
- try (CryptoDirectoryStream stream = new CryptoDirectoryStream(new Directory("foo", ciphertextDirPath), cleartextPath, filenameCryptor, longFileNameProvider, conflictResolver, ACCEPT_ALL, DO_NOTHING_ON_CLOSE,
- finallyUtil)) {
+ try (CryptoDirectoryStream stream = new CryptoDirectoryStream(new Directory("foo", ciphertextDirPath), cleartextPath, filenameCryptor, cryptoPathMapper, longFileNameProvider, conflictResolver, ACCEPT_ALL,
+ DO_NOTHING_ON_CLOSE, finallyUtil)) {
Iterator iter = stream.iterator();
Assert.assertTrue(iter.hasNext());
Assert.assertEquals(cleartextPath.resolve("one"), iter.next());
@@ -131,8 +149,8 @@ public void testDirListingForEmptyDir() throws IOException {
Mockito.when(dirStream.spliterator()).thenReturn(Spliterators.emptySpliterator());
- try (CryptoDirectoryStream stream = new CryptoDirectoryStream(new Directory("foo", ciphertextDirPath), cleartextPath, filenameCryptor, longFileNameProvider, conflictResolver, ACCEPT_ALL, DO_NOTHING_ON_CLOSE,
- finallyUtil)) {
+ try (CryptoDirectoryStream stream = new CryptoDirectoryStream(new Directory("foo", ciphertextDirPath), cleartextPath, filenameCryptor, cryptoPathMapper, longFileNameProvider, conflictResolver, ACCEPT_ALL,
+ DO_NOTHING_ON_CLOSE, finallyUtil)) {
Iterator iter = stream.iterator();
Assert.assertFalse(iter.hasNext());
iter.next();
diff --git a/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java b/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java
index bed8d5d1..f67d7cbc 100644
--- a/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java
@@ -9,7 +9,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
@@ -493,7 +493,7 @@ public void moveDirectoryReplaceExistingNonEmpty() throws IOException {
thrown.expect(DirectoryNotEmptyException.class);
inTest.move(cleartextSource, cleartextTarget, StandardCopyOption.REPLACE_EXISTING);
} finally {
- verify(physicalFsProv, Mockito.never()).move(Mockito.any(), Mockito.any(), Mockito.anyVararg());
+ verify(physicalFsProv, Mockito.never()).move(Mockito.any(), Mockito.any(), Mockito.any());
}
}
@@ -505,7 +505,7 @@ public void moveDirectoryReplaceExistingAtomically() throws IOException {
thrown.expect(AtomicMoveNotSupportedException.class);
inTest.move(cleartextSource, cleartextTarget, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
} finally {
- verify(physicalFsProv, Mockito.never()).move(Mockito.any(), Mockito.any(), Mockito.anyVararg());
+ verify(physicalFsProv, Mockito.never()).move(Mockito.any(), Mockito.any(), Mockito.any());
}
}
@@ -519,7 +519,6 @@ public class Copy {
private final FileChannel ciphertextTargetDirFileChannel = mock(FileChannel.class);
@Before
- @SuppressWarnings("unchecked")
public void setup() throws IOException, ReflectiveOperationException {
when(cleartextTarget.getParent()).thenReturn(cleartextTargetParent);
when(cryptoPathMapper.getCiphertextDirPath(cleartextTargetParent)).thenReturn(ciphertextTargetParent);
@@ -528,7 +527,7 @@ public void setup() throws IOException, ReflectiveOperationException {
when(ciphertextTargetDir.getFileSystem()).thenReturn(physicalFs);
when(cryptoPathMapper.getCiphertextDir(cleartextTarget)).thenReturn(new Directory("42", ciphertextTargetDir));
- when(physicalFsProv.newFileChannel(Mockito.same(ciphertextTargetDirFile), Mockito.anySet(), Mockito.anyVararg())).thenReturn(ciphertextTargetDirFileChannel);
+ when(physicalFsProv.newFileChannel(Mockito.same(ciphertextTargetDirFile), Mockito.anySet(), Mockito.any())).thenReturn(ciphertextTargetDirFileChannel);
Field closeLockField = AbstractInterruptibleChannel.class.getDeclaredField("closeLock");
closeLockField.setAccessible(true);
closeLockField.set(ciphertextTargetDirFileChannel, new Object());
@@ -612,8 +611,8 @@ public void moveDirectoryCopyBasicAttributes() throws IOException {
when(srcAttrs.lastModifiedTime()).thenReturn(lastModifiedTime);
when(srcAttrs.lastAccessTime()).thenReturn(lastAccessTime);
when(srcAttrs.creationTime()).thenReturn(createTime);
- when(physicalFsProv.readAttributes(Mockito.same(ciphertextSourceDir), Mockito.same(BasicFileAttributes.class), Mockito.anyVararg())).thenReturn(srcAttrs);
- when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextTargetDir), Mockito.same(BasicFileAttributeView.class), Mockito.anyVararg())).thenReturn(dstAttrView);
+ when(physicalFsProv.readAttributes(Mockito.same(ciphertextSourceDir), Mockito.same(BasicFileAttributes.class), Mockito.any())).thenReturn(srcAttrs);
+ when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextTargetDir), Mockito.same(BasicFileAttributeView.class), Mockito.any())).thenReturn(dstAttrView);
inTest.copy(cleartextSource, cleartextTarget, StandardCopyOption.COPY_ATTRIBUTES);
verify(dstAttrView).setTimes(lastModifiedTime, lastAccessTime, createTime);
@@ -629,8 +628,8 @@ public void moveDirectoryCopyFileOwnerAttributes() throws IOException {
FileOwnerAttributeView srcAttrsView = mock(FileOwnerAttributeView.class);
FileOwnerAttributeView dstAttrView = mock(FileOwnerAttributeView.class);
when(srcAttrsView.getOwner()).thenReturn(owner);
- when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextSourceDir), Mockito.same(FileOwnerAttributeView.class), Mockito.anyVararg())).thenReturn(srcAttrsView);
- when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextTargetDir), Mockito.same(FileOwnerAttributeView.class), Mockito.anyVararg())).thenReturn(dstAttrView);
+ when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextSourceDir), Mockito.same(FileOwnerAttributeView.class), Mockito.any())).thenReturn(srcAttrsView);
+ when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextTargetDir), Mockito.same(FileOwnerAttributeView.class), Mockito.any())).thenReturn(dstAttrView);
inTest.copy(cleartextSource, cleartextTarget, StandardCopyOption.COPY_ATTRIBUTES);
verify(dstAttrView).setOwner(owner);
@@ -649,8 +648,8 @@ public void moveDirectoryCopyPosixAttributes() throws IOException {
PosixFileAttributeView dstAttrView = mock(PosixFileAttributeView.class);
when(srcAttrs.group()).thenReturn(group);
when(srcAttrs.permissions()).thenReturn(permissions);
- when(physicalFsProv.readAttributes(Mockito.same(ciphertextSourceDir), Mockito.same(PosixFileAttributes.class), Mockito.anyVararg())).thenReturn(srcAttrs);
- when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextTargetDir), Mockito.same(PosixFileAttributeView.class), Mockito.anyVararg())).thenReturn(dstAttrView);
+ when(physicalFsProv.readAttributes(Mockito.same(ciphertextSourceDir), Mockito.same(PosixFileAttributes.class), Mockito.any())).thenReturn(srcAttrs);
+ when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextTargetDir), Mockito.same(PosixFileAttributeView.class), Mockito.any())).thenReturn(dstAttrView);
inTest.copy(cleartextSource, cleartextTarget, StandardCopyOption.COPY_ATTRIBUTES);
verify(dstAttrView).setGroup(group);
@@ -669,8 +668,8 @@ public void moveDirectoryCopyDosAttributes() throws IOException {
when(srcAttrs.isHidden()).thenReturn(true);
when(srcAttrs.isReadOnly()).thenReturn(true);
when(srcAttrs.isSystem()).thenReturn(true);
- when(physicalFsProv.readAttributes(Mockito.same(ciphertextSourceDir), Mockito.same(DosFileAttributes.class), Mockito.anyVararg())).thenReturn(srcAttrs);
- when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextTargetDir), Mockito.same(DosFileAttributeView.class), Mockito.anyVararg())).thenReturn(dstAttrView);
+ when(physicalFsProv.readAttributes(Mockito.same(ciphertextSourceDir), Mockito.same(DosFileAttributes.class), Mockito.any())).thenReturn(srcAttrs);
+ when(physicalFsProv.getFileAttributeView(Mockito.same(ciphertextTargetDir), Mockito.same(DosFileAttributeView.class), Mockito.any())).thenReturn(dstAttrView);
inTest.copy(cleartextSource, cleartextTarget, StandardCopyOption.COPY_ATTRIBUTES);
verify(dstAttrView).setArchive(true);
diff --git a/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemProviderTest.java b/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemProviderTest.java
index e192a0c1..e0a9804d 100644
--- a/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemProviderTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/CryptoFileSystemProviderTest.java
@@ -4,12 +4,14 @@
import static java.nio.file.StandardOpenOption.APPEND;
import static java.util.Arrays.asList;
import static org.cryptomator.cryptofs.CryptoFileSystemProperties.cryptoFileSystemProperties;
+import static org.cryptomator.cryptofs.CryptoFileSystemProvider.containsVault;
+import static org.cryptomator.cryptofs.CryptoFileSystemProvider.newFileSystem;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -25,6 +27,7 @@
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
+import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
@@ -39,6 +42,7 @@
import java.util.Set;
import java.util.concurrent.ExecutorService;
+import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -51,6 +55,9 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+
@RunWith(Theories.class)
public class CryptoFileSystemProviderTest {
@@ -174,6 +181,98 @@ public void testNewFileSystemInvokesFileSystemsCreate() throws IOException {
assertThat(result, is(cryptoFileSystem));
}
+ @Test
+ public void testContainsVaultReturnsTrueIfDirectoryContainsMasterkeyFileAndDataDir() throws IOException {
+ FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
+
+ String masterkeyFilename = "masterkey.foo.baz";
+ Path pathToVault = fs.getPath("/vaultDir");
+
+ Path masterkeyFile = pathToVault.resolve(masterkeyFilename);
+ Path dataDir = pathToVault.resolve("d");
+ Files.createDirectories(dataDir);
+ Files.write(masterkeyFile, new byte[0]);
+
+ assertTrue(containsVault(pathToVault, masterkeyFilename));
+ }
+
+ @Test
+ public void testContainsVaultReturnsFalseIfDirectoryContainsNoMasterkeyFileButDataDir() throws IOException {
+ FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
+
+ String masterkeyFilename = "masterkey.foo.baz";
+ Path pathToVault = fs.getPath("/vaultDir");
+
+ Path dataDir = pathToVault.resolve("d");
+ Files.createDirectories(dataDir);
+
+ assertFalse(containsVault(pathToVault, masterkeyFilename));
+ }
+
+ @Test
+ public void testContainsVaultReturnsFalseIfDirectoryContainsMasterkeyFileButNoDataDir() throws IOException {
+ FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
+
+ String masterkeyFilename = "masterkey.foo.baz";
+ Path pathToVault = fs.getPath("/vaultDir");
+
+ Path masterkeyFile = pathToVault.resolve(masterkeyFilename);
+ Files.createDirectories(pathToVault);
+ Files.write(masterkeyFile, new byte[0]);
+
+ assertFalse(containsVault(pathToVault, masterkeyFilename));
+ }
+
+ @Test
+ public void testVaultWithChangedPassphraseCanBeOpenedWithNewPassphrase() throws IOException {
+ String oldPassphrase = "oldPassphrase838283";
+ String newPassphrase = "newPassphrase954810921";
+ String masterkeyFilename = "masterkey.foo.baz";
+ FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
+ Path pathToVault = fs.getPath("/vaultDir");
+ newFileSystem( //
+ pathToVault, //
+ cryptoFileSystemProperties() //
+ .withMasterkeyFilename(masterkeyFilename) //
+ .withPassphrase(oldPassphrase) //
+ .build()).close();
+
+ CryptoFileSystemProvider.changePassphrase(pathToVault, masterkeyFilename, oldPassphrase, newPassphrase);
+
+ newFileSystem( //
+ pathToVault, //
+ cryptoFileSystemProperties() //
+ .withMasterkeyFilename(masterkeyFilename) //
+ .withPassphrase(newPassphrase) //
+ .build()).close();
+ }
+
+ @Test
+ public void testVaultWithChangedPassphraseCanNotBeOpenedWithOldPassphrase() throws IOException {
+ String oldPassphrase = "oldPassphrase838283";
+ String newPassphrase = "newPassphrase954810921";
+ String masterkeyFilename = "masterkey.foo.baz";
+ FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
+ Path pathToVault = fs.getPath("/vaultDir");
+ newFileSystem( //
+ pathToVault, //
+ cryptoFileSystemProperties() //
+ .withMasterkeyFilename(masterkeyFilename) //
+ .withPassphrase(oldPassphrase) //
+ .build()).close();
+
+ CryptoFileSystemProvider.changePassphrase(pathToVault, masterkeyFilename, oldPassphrase, newPassphrase);
+
+ thrown.expect(InvalidPassphraseException.class);
+
+ newFileSystem( //
+ pathToVault, //
+ cryptoFileSystemProperties() //
+ .withMasterkeyFilename(masterkeyFilename) //
+ .withPassphrase(oldPassphrase) //
+ .build());
+ }
+
@Test
public void testGetFileSystemInvokesFileSystemsGetWithPathToVaultFromUri() {
Path pathToVault = get("a").toAbsolutePath();
diff --git a/src/test/java/org/cryptomator/cryptofs/MoveOperationTest.java b/src/test/java/org/cryptomator/cryptofs/MoveOperationTest.java
index 6db0e83f..7544f8e2 100644
--- a/src/test/java/org/cryptomator/cryptofs/MoveOperationTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/MoveOperationTest.java
@@ -5,8 +5,8 @@
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.same;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@@ -133,7 +133,6 @@ public void testMoveThrowsIOExceptionIfInvokedWithNonEmptyDirectory() throws IOE
}
@Test
- @SuppressWarnings("unchecked")
public void testMoveDoesNotThrowIOExceptionIfFileAttributesOfSourceCanNotBeRead() throws IOException {
when(provider.readAttributes(aPathFromFsA, BasicFileAttributes.class)).thenThrow(IOException.class);
diff --git a/src/test/java/org/cryptomator/cryptofs/WriteFileWhileReadonlyChannelIsOpenTest.java b/src/test/java/org/cryptomator/cryptofs/WriteFileWhileReadonlyChannelIsOpenTest.java
index fba9e643..9c3a90c9 100644
--- a/src/test/java/org/cryptomator/cryptofs/WriteFileWhileReadonlyChannelIsOpenTest.java
+++ b/src/test/java/org/cryptomator/cryptofs/WriteFileWhileReadonlyChannelIsOpenTest.java
@@ -19,7 +19,7 @@
import com.google.common.jimfs.Jimfs;
/**
- * @see https://github.com/cryptomator/cryptofs/issues/10
+ * @see CryptoFS issue 10
*/
public class WriteFileWhileReadonlyChannelIsOpenTest {