diff --git a/src/main/java/network/crypta/fs/Dirs.java b/src/main/java/network/crypta/fs/Dirs.java index d062edace5..2fbf5c5184 100644 --- a/src/main/java/network/crypta/fs/Dirs.java +++ b/src/main/java/network/crypta/fs/Dirs.java @@ -92,11 +92,20 @@ static void ensureDir(Path path, String perms) { throw new UncheckedIOException("Failed to create directory: " + path, e); } } + Set set; try { - if (Files.getFileStore(path).supportsFileAttributeView("posix")) { - Set set = PosixFilePermissions.fromString(perms); - Files.setPosixFilePermissions(path, set); - } + set = PosixFilePermissions.fromString(perms); + } catch (IllegalArgumentException e) { + LOG.warn("Failed to set POSIX permissions '{}' on {}: {}", perms, path, e.getMessage(), e); + return; + } + try { + Files.setPosixFilePermissions(path, set); + } catch (UnsupportedOperationException _) { + LOG.debug( + "Skipping POSIX permissions '{}' on {} because POSIX attributes are unsupported", + perms, + path); } catch (Exception e) { LOG.warn("Failed to set POSIX permissions '{}' on {}: {}", perms, path, e.getMessage(), e); } diff --git a/src/test/java/network/crypta/fs/DirsTest.java b/src/test/java/network/crypta/fs/DirsTest.java index 66dbf33971..1ff4a2f4e0 100644 --- a/src/test/java/network/crypta/fs/DirsTest.java +++ b/src/test/java/network/crypta/fs/DirsTest.java @@ -1,11 +1,14 @@ package network.crypta.fs; +import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.attribute.PosixFilePermission; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.mockito.MockedStatic; @@ -60,6 +63,48 @@ void ensureDir_whenPermissionsStringInvalid_expectNoException() { assertTrue(Files.isDirectory(target)); } + @Test + void ensureDir_whenSettingPermissionsThrowsIOException_expectNoException() { + // Arrange + Path target = tempDir.resolve("io-permissions-error"); + + // Act + try (MockedStatic files = Mockito.mockStatic(Files.class, Mockito.CALLS_REAL_METHODS)) { + files + .when( + () -> + Files.setPosixFilePermissions( + Mockito.eq(target), Mockito.>any())) + .thenThrow(new IOException("Mount point not found")); + + assertDoesNotThrow(() -> Dirs.ensureDir(target, Dirs.PERM_GROUP_RX)); + } + + // Assert + assertTrue(Files.isDirectory(target)); + } + + @Test + void ensureDir_whenPosixUnsupported_expectNoException() { + // Arrange + Path target = tempDir.resolve("unsupported-posix"); + + // Act + try (MockedStatic files = Mockito.mockStatic(Files.class, Mockito.CALLS_REAL_METHODS)) { + files + .when( + () -> + Files.setPosixFilePermissions( + Mockito.eq(target), Mockito.>any())) + .thenThrow(new UnsupportedOperationException("posix unsupported")); + + assertDoesNotThrow(() -> Dirs.ensureDir(target, Dirs.PERM_GROUP_RX)); + } + + // Assert + assertTrue(Files.isDirectory(target)); + } + @Test void isUnitTestRuntime_whenRunningUnderJUnit_expectTrue() { // Arrange