From d0779c4f2cfbff2dfff9cac87d3d66f89b4c9d5b Mon Sep 17 00:00:00 2001 From: Jeff Ching Date: Wed, 2 Jan 2019 16:43:47 -0800 Subject: [PATCH 1/4] Use NIO to set file permissions --- .../util/store/FileDataStoreFactory.java | 93 +++++++++++++------ 1 file changed, 65 insertions(+), 28 deletions(-) diff --git a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java index 229ac95e3..1a63ea2bf 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java +++ b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java @@ -16,15 +16,26 @@ import com.google.api.client.util.IOUtils; import com.google.api.client.util.Maps; -import com.google.api.client.util.Throwables; +import com.google.common.base.StandardSystemProperty; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.AclEntry; +import java.nio.file.attribute.AclEntryPermission; +import java.nio.file.attribute.AclEntryType; +import java.nio.file.attribute.AclFileAttributeView; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; +import java.util.HashSet; +import java.util.Set; import java.util.logging.Logger; /** @@ -43,6 +54,8 @@ public class FileDataStoreFactory extends AbstractDataStoreFactory { private static final Logger LOGGER = Logger.getLogger(FileDataStoreFactory.class.getName()); + private static final boolean IS_WINDOWS = StandardSystemProperty.OS_NAME.value().startsWith("WINDOWS"); + /** Directory to store data. */ private final File dataDirectory; @@ -60,7 +73,12 @@ public FileDataStoreFactory(File dataDirectory) throws IOException { if (!dataDirectory.exists() && !dataDirectory.mkdirs()) { throw new IOException("unable to create directory: " + dataDirectory); } - setPermissionsToOwnerOnly(dataDirectory); + + if (IS_WINDOWS) { + setPermissionsToOwnerOnlyWindows(dataDirectory); + } else { + setPermissionsToOwnerOnly(dataDirectory); + } } /** Returns the data directory. */ @@ -122,36 +140,55 @@ public FileDataStoreFactory getDataStoreFactory() { * @throws IOException */ static void setPermissionsToOwnerOnly(File file) throws IOException { - // Disable access by other users if O/S allows it and set file permissions to readable and - // writable by user. Use reflection since JDK 1.5 will not have these methods + Set permissions = new HashSet<>(); + permissions.add(PosixFilePermission.OWNER_READ); + permissions.add(PosixFilePermission.OWNER_WRITE); + permissions.add(PosixFilePermission.OWNER_EXECUTE); try { - Method setReadable = File.class.getMethod("setReadable", boolean.class, boolean.class); - Method setWritable = File.class.getMethod("setWritable", boolean.class, boolean.class); - Method setExecutable = File.class.getMethod("setExecutable", boolean.class, boolean.class); - if (!(Boolean) setReadable.invoke(file, false, false) - || !(Boolean) setWritable.invoke(file, false, false) - || !(Boolean) setExecutable.invoke(file, false, false)) { - LOGGER.warning("unable to change permissions for everybody: " + file); - } - if (!(Boolean) setReadable.invoke(file, true, true) - || !(Boolean) setWritable.invoke(file, true, true) - || !(Boolean) setExecutable.invoke(file, true, true)) { - LOGGER.warning("unable to change permissions for owner: " + file); - } - } catch (InvocationTargetException exception) { - Throwable cause = exception.getCause(); - Throwables.propagateIfPossible(cause, IOException.class); - // shouldn't reach this point, but just in case... - throw new RuntimeException(cause); - } catch (NoSuchMethodException exception) { + Files.setPosixFilePermissions(Paths.get(file.getAbsolutePath()), permissions); + } catch (UnsupportedOperationException exception) { LOGGER.warning("Unable to set permissions for " + file - + ", likely because you are running a version of Java prior to 1.6"); + + ", because you are running on a non-POSIX file system."); } catch (SecurityException exception) { // ignored - } catch (IllegalAccessException exception) { - // ignored } catch (IllegalArgumentException exception) { // ignored } } + + static void setPermissionsToOwnerOnlyWindows(File file) throws IOException { + Path path = Paths.get(file.getAbsolutePath()); + UserPrincipal owner = path.getFileSystem().getUserPrincipalLookupService() + .lookupPrincipalByName("OWNER@"); + + // get view + AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class); + + // All available entries + Set permissions = ImmutableSet.of( + AclEntryPermission.APPEND_DATA, + AclEntryPermission.DELETE, + AclEntryPermission.DELETE_CHILD, + AclEntryPermission.READ_ACL, + AclEntryPermission.READ_ATTRIBUTES, + AclEntryPermission.READ_DATA, + AclEntryPermission.READ_NAMED_ATTRS, + AclEntryPermission.SYNCHRONIZE, + AclEntryPermission.WRITE_ACL, + AclEntryPermission.WRITE_ATTRIBUTES, + AclEntryPermission.WRITE_DATA, + AclEntryPermission.WRITE_NAMED_ATTRS, + AclEntryPermission.WRITE_OWNER + ); + + // create ACL to give owner everything + AclEntry entry = AclEntry.newBuilder() + .setType(AclEntryType.ALLOW) + .setPrincipal(owner) + .setPermissions(permissions) + .build(); + + // Overwrite the ACL with only this permission + view.setAcl(ImmutableList.of(entry)); + } } From cafa90a3cab3db53915d9f91ab1954201f197db8 Mon Sep 17 00:00:00 2001 From: Jeff Ching Date: Thu, 3 Jan 2019 09:21:50 -0800 Subject: [PATCH 2/4] Fix checkstyle --- .../google/api/client/util/store/FileDataStoreFactory.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java index 1a63ea2bf..96e3204a3 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java +++ b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java @@ -54,7 +54,8 @@ public class FileDataStoreFactory extends AbstractDataStoreFactory { private static final Logger LOGGER = Logger.getLogger(FileDataStoreFactory.class.getName()); - private static final boolean IS_WINDOWS = StandardSystemProperty.OS_NAME.value().startsWith("WINDOWS"); + private static final boolean IS_WINDOWS = StandardSystemProperty.OS_NAME.value() + .startsWith("WINDOWS"); /** Directory to store data. */ private final File dataDirectory; @@ -140,7 +141,7 @@ public FileDataStoreFactory getDataStoreFactory() { * @throws IOException */ static void setPermissionsToOwnerOnly(File file) throws IOException { - Set permissions = new HashSet<>(); + Set permissions = new HashSet(); permissions.add(PosixFilePermission.OWNER_READ); permissions.add(PosixFilePermission.OWNER_WRITE); permissions.add(PosixFilePermission.OWNER_EXECUTE); From 5b7e9ccc492e65595743df95790e2cb320d0786a Mon Sep 17 00:00:00 2001 From: Jeff Ching Date: Thu, 13 Jun 2019 15:02:50 -0700 Subject: [PATCH 3/4] Fix merge conflict --- .../com/google/api/client/util/store/FileDataStoreFactory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java index be3c16adf..65fe65a3a 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java +++ b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java @@ -98,7 +98,6 @@ protected DataStore createDataStore(String id) throw * * @param serializable type of the mapped value */ - static class FileDataStore extends AbstractMemoryDataStore { static class FileDataStore extends AbstractMemoryDataStore { /** File to store data. */ From f5959c75ec1e8aac84ef21dd38af3d44bfa7176e Mon Sep 17 00:00:00 2001 From: Jeff Ching Date: Thu, 13 Jun 2019 15:10:42 -0700 Subject: [PATCH 4/4] Fix merge conflict --- .../google/api/client/util/store/FileDataStoreFactory.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java index 65fe65a3a..230af26e2 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java +++ b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java @@ -16,14 +16,10 @@ import com.google.api.client.util.IOUtils; import com.google.api.client.util.Maps; -<<<<<<< HEAD import com.google.common.base.StandardSystemProperty; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -======= -import com.google.api.client.util.Throwables; ->>>>>>> master import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream;