|
62 | 62 | import java.nio.file.attribute.BasicFileAttributes; |
63 | 63 | import java.nio.file.attribute.DosFileAttributeView; |
64 | 64 | import java.util.Arrays; |
| 65 | +import java.util.Comparator; |
65 | 66 | import java.util.EnumSet; |
| 67 | +import java.util.Set; |
66 | 68 |
|
67 | 69 | import static java.nio.file.Files.readAllBytes; |
68 | 70 | import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; |
@@ -170,7 +172,7 @@ public void testCopyExceedingPathLengthLimit(String path) { |
170 | 172 | @Nested |
171 | 173 | @TestInstance(TestInstance.Lifecycle.PER_CLASS) |
172 | 174 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) |
173 | | - public class InMemory { |
| 175 | + public class InMemoryOrdered { |
174 | 176 |
|
175 | 177 | private FileSystem tmpFs; |
176 | 178 | private MasterkeyLoader keyLoader1; |
@@ -587,6 +589,68 @@ public void testMoveFileFromOneCryptoFileSystemToAnother() throws IOException { |
587 | 589 |
|
588 | 590 | } |
589 | 591 |
|
| 592 | + |
| 593 | + @Nested |
| 594 | + public class InMemory { |
| 595 | + |
| 596 | + private static FileSystem tmpFs; |
| 597 | + private static Path pathToVault; |
| 598 | + |
| 599 | + @BeforeAll |
| 600 | + public static void beforeAll() { |
| 601 | + tmpFs = Jimfs.newFileSystem(Configuration.unix()); |
| 602 | + pathToVault = tmpFs.getPath("/vault"); |
| 603 | + } |
| 604 | + |
| 605 | + @BeforeEach |
| 606 | + public void beforeEach() throws IOException { |
| 607 | + Files.createDirectory(pathToVault); |
| 608 | + } |
| 609 | + |
| 610 | + @AfterEach |
| 611 | + public void afterEach() throws IOException { |
| 612 | + try (var paths = Files.walk(pathToVault)) { |
| 613 | + var nodes = paths.sorted(Comparator.reverseOrder()).toList(); |
| 614 | + for (var node : nodes) { |
| 615 | + Files.delete(node); |
| 616 | + } |
| 617 | + } |
| 618 | + } |
| 619 | + |
| 620 | + @AfterAll |
| 621 | + public static void afterAll() throws IOException { |
| 622 | + tmpFs.close(); |
| 623 | + } |
| 624 | + |
| 625 | + @Test |
| 626 | + @DisplayName("Replace an existing, shortened file") |
| 627 | + public void testReplaceExistingShortenedFile() throws IOException { |
| 628 | + try (var fs = setupCryptoFs(50, 100, false)) { |
| 629 | + var fiftyCharName2 = "/50char2_50char2_50char2_50char2_50char2_50char.txt"; //since filename encryption increases filename length, 50 cleartext chars are sufficient |
| 630 | + var source = fs.getPath("/source.txt"); |
| 631 | + var target = fs.getPath(fiftyCharName2); |
| 632 | + Files.createFile(source); |
| 633 | + Files.createFile(target); |
| 634 | + |
| 635 | + Assertions.assertDoesNotThrow(() -> Files.move(source, target, REPLACE_EXISTING)); |
| 636 | + Assertions.assertTrue(Files.notExists(source)); |
| 637 | + Assertions.assertTrue(Files.exists(target)); |
| 638 | + } |
| 639 | + } |
| 640 | + |
| 641 | + private FileSystem setupCryptoFs(int ciphertextShorteningThreshold, int maxCleartextFilename, boolean readonly) throws IOException { |
| 642 | + byte[] key = new byte[64]; |
| 643 | + Arrays.fill(key, (byte) 0x55); |
| 644 | + var keyLoader = Mockito.mock(MasterkeyLoader.class); |
| 645 | + Mockito.when(keyLoader.loadKey(Mockito.any())).thenAnswer(ignored -> new Masterkey(key)); |
| 646 | + var properties = CryptoFileSystemProperties.cryptoFileSystemProperties().withKeyLoader(keyLoader).withShorteningThreshold(ciphertextShorteningThreshold).withMaxCleartextNameLength(maxCleartextFilename).withFlags(readonly ? Set.of(CryptoFileSystemProperties.FileSystemFlags.READONLY) : Set.of()).build(); |
| 647 | + CryptoFileSystemProvider.initialize(pathToVault, properties, URI.create("test:key")); |
| 648 | + URI fsUri = CryptoFileSystemUri.create(pathToVault); |
| 649 | + return FileSystems.newFileSystem(fsUri, cryptoFileSystemProperties().withKeyLoader(keyLoader).build()); |
| 650 | + } |
| 651 | + |
| 652 | + } |
| 653 | + |
590 | 654 | @Nested |
591 | 655 | @EnabledOnOs({OS.MAC, OS.LINUX}) |
592 | 656 | @TestInstance(TestInstance.Lifecycle.PER_CLASS) |
|
0 commit comments