diff --git a/pom.xml b/pom.xml
index 105e212f..fb67f471 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
org.dataone
hashstore
- 1.0-SNAPSHOT
+ 1.1.0
hashstore
https://github.com/DataONEorg/hashstore-java
diff --git a/src/main/java/org/dataone/hashstore/filehashstore/FileHashStoreUtility.java b/src/main/java/org/dataone/hashstore/filehashstore/FileHashStoreUtility.java
index b180b050..5c15c769 100644
--- a/src/main/java/org/dataone/hashstore/filehashstore/FileHashStoreUtility.java
+++ b/src/main/java/org/dataone/hashstore/filehashstore/FileHashStoreUtility.java
@@ -8,6 +8,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -16,9 +17,11 @@
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Random;
+import java.util.Set;
import java.util.stream.Stream;
import javax.xml.bind.DatatypeConverter;
@@ -321,8 +324,9 @@ public static String getHierarchicalPathString(int depth, int width, String dige
}
/**
- * Creates an empty/temporary file in a given location. If this file is not moved, it will be
- * deleted upon JVM gracefully exiting or shutting down.
+ * Creates an empty/temporary file in a given location. This temporary file has the default
+ * permissions of 'rw- r-- ---' (owner read/write, and group read). If this file is not
+ * moved, it will be deleted upon JVM gracefully exiting or shutting down.
*
* @param prefix string to prepend before tmp file
* @param directory location to create tmp file
@@ -336,10 +340,19 @@ public static File generateTmpFile(String prefix, Path directory)
int randomNumber = rand.nextInt(1000000);
String newPrefix = prefix + "-" + System.currentTimeMillis() + randomNumber;
- Path newPath = Files.createTempFile(directory, newPrefix, null);
- File newFile = newPath.toFile();
- newFile.deleteOnExit();
- return newFile;
+ Path newTmpPath = Files.createTempFile(directory, newPrefix, null);
+ File newTmpFile = newTmpPath.toFile();
+
+ // Set default file permissions 'rw- r-- ---'
+ final Set permissions = new HashSet<>();
+ permissions.add(PosixFilePermission.OWNER_READ);
+ permissions.add(PosixFilePermission.OWNER_WRITE);
+ permissions.add(PosixFilePermission.GROUP_READ);
+ Files.setPosixFilePermissions(newTmpPath, permissions);
+ // Mark tmp file to be cleaned up if it runs into an issue
+ newTmpFile.deleteOnExit();
+
+ return newTmpFile;
}
/**
diff --git a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreInterfaceTest.java b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreInterfaceTest.java
index 303af320..7bc157fb 100644
--- a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreInterfaceTest.java
+++ b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreInterfaceTest.java
@@ -17,6 +17,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermission;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
@@ -26,6 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -163,6 +165,39 @@ public void storeObject_hexDigests() throws Exception {
}
}
+ /**
+ * Check that data object stored contains the correct permission settings 'rw- r-- ---'
+ */
+ @Test
+ public void storeObject_filePermissions() throws Exception {
+ for (String pid : testData.pidList) {
+ String pidFormatted = pid.replace("/", "_");
+ Path testDataFile = testData.getTestFile(pidFormatted);
+
+ try (InputStream dataStream = Files.newInputStream(testDataFile)) {
+ fileHashStore.storeObject(dataStream, pid, null, null, null, -1);
+
+ Path objRealPath = fileHashStore.getHashStoreDataObjectPath(pid);
+
+ Collection expectedPermissions = new HashSet<>();
+ expectedPermissions.add(PosixFilePermission.OWNER_READ);
+ expectedPermissions.add(PosixFilePermission.OWNER_WRITE);
+ expectedPermissions.add(PosixFilePermission.GROUP_READ);
+
+ Set actualPermissions =
+ Files.getPosixFilePermissions(objRealPath);
+
+ assertEquals(expectedPermissions, actualPermissions);
+ assertFalse(actualPermissions.contains(PosixFilePermission.OWNER_EXECUTE));
+ assertFalse(actualPermissions.contains(PosixFilePermission.GROUP_WRITE));
+ assertFalse(actualPermissions.contains(PosixFilePermission.GROUP_EXECUTE));
+ assertFalse(actualPermissions.contains(PosixFilePermission.OTHERS_READ));
+ assertFalse(actualPermissions.contains(PosixFilePermission.OTHERS_WRITE));
+ assertFalse(actualPermissions.contains(PosixFilePermission.OTHERS_EXECUTE));
+ }
+ }
+ }
+
/**
* Check that store object throws exception when object is null
*/
diff --git a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java
index f5a3c486..64522145 100644
--- a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java
+++ b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java
@@ -15,15 +15,18 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermission;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
+import java.util.Set;
import javax.xml.bind.DatatypeConverter;
@@ -2421,4 +2424,31 @@ public void fileHashStoreUtility_renamePathForRestoration() throws Exception {
}
}
}
+
+
+ /**
+ * Confirm that generateTemporaryFile creates tmpFile with expected permissions
+ */
+ @Test
+ public void fileHashStoreUtility_generateTmpFile_permissions() throws Exception {
+ Path directory = tempFolder.resolve("hashstore");
+ // newFile
+ File tmpFile = FileHashStoreUtility.generateTmpFile("testfile", directory);
+
+ Collection expectedPermissions = new HashSet<>();
+ expectedPermissions.add(PosixFilePermission.OWNER_READ);
+ expectedPermissions.add(PosixFilePermission.OWNER_WRITE);
+ expectedPermissions.add(PosixFilePermission.GROUP_READ);
+
+ Set actualPermissions =
+ Files.getPosixFilePermissions(tmpFile.toPath());
+
+ assertEquals(expectedPermissions, actualPermissions);
+ assertFalse(actualPermissions.contains(PosixFilePermission.OWNER_EXECUTE));
+ assertFalse(actualPermissions.contains(PosixFilePermission.GROUP_WRITE));
+ assertFalse(actualPermissions.contains(PosixFilePermission.GROUP_EXECUTE));
+ assertFalse(actualPermissions.contains(PosixFilePermission.OTHERS_READ));
+ assertFalse(actualPermissions.contains(PosixFilePermission.OTHERS_WRITE));
+ assertFalse(actualPermissions.contains(PosixFilePermission.OTHERS_EXECUTE));
+ }
}