Skip to content

Commit 4e77793

Browse files
authored
Use NIO to set file permissions (#557)
* Use NIO to set file permissions * Fix checkstyle * Fix merge conflict * Fix merge conflict
1 parent e63e009 commit 4e77793

File tree

1 file changed

+68
-31
lines changed

1 file changed

+68
-31
lines changed

google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,26 @@
1616

1717
import com.google.api.client.util.IOUtils;
1818
import com.google.api.client.util.Maps;
19-
import com.google.api.client.util.Throwables;
19+
20+
import com.google.common.base.StandardSystemProperty;
21+
import com.google.common.collect.ImmutableList;
22+
import com.google.common.collect.ImmutableSet;
2023
import java.io.File;
2124
import java.io.FileInputStream;
2225
import java.io.FileOutputStream;
2326
import java.io.IOException;
2427
import java.io.Serializable;
25-
import java.lang.reflect.InvocationTargetException;
26-
import java.lang.reflect.Method;
28+
import java.nio.file.Files;
29+
import java.nio.file.Path;
30+
import java.nio.file.Paths;
31+
import java.nio.file.attribute.AclEntry;
32+
import java.nio.file.attribute.AclEntryPermission;
33+
import java.nio.file.attribute.AclEntryType;
34+
import java.nio.file.attribute.AclFileAttributeView;
35+
import java.nio.file.attribute.PosixFilePermission;
36+
import java.nio.file.attribute.UserPrincipal;
37+
import java.util.HashSet;
38+
import java.util.Set;
2739
import java.util.logging.Logger;
2840

2941
/**
@@ -40,6 +52,9 @@ public class FileDataStoreFactory extends AbstractDataStoreFactory {
4052

4153
private static final Logger LOGGER = Logger.getLogger(FileDataStoreFactory.class.getName());
4254

55+
private static final boolean IS_WINDOWS = StandardSystemProperty.OS_NAME.value()
56+
.startsWith("WINDOWS");
57+
4358
/** Directory to store data. */
4459
private final File dataDirectory;
4560

@@ -55,7 +70,12 @@ public FileDataStoreFactory(File dataDirectory) throws IOException {
5570
if (!dataDirectory.exists() && !dataDirectory.mkdirs()) {
5671
throw new IOException("unable to create directory: " + dataDirectory);
5772
}
58-
setPermissionsToOwnerOnly(dataDirectory);
73+
74+
if (IS_WINDOWS) {
75+
setPermissionsToOwnerOnlyWindows(dataDirectory);
76+
} else {
77+
setPermissionsToOwnerOnly(dataDirectory);
78+
}
5979
}
6080

6181
/** Returns the data directory. */
@@ -117,38 +137,55 @@ public FileDataStoreFactory getDataStoreFactory() {
117137
* @throws IOException
118138
*/
119139
static void setPermissionsToOwnerOnly(File file) throws IOException {
120-
// Disable access by other users if O/S allows it and set file permissions to readable and
121-
// writable by user. Use reflection since JDK 1.5 will not have these methods
140+
Set permissions = new HashSet<PosixFilePermission>();
141+
permissions.add(PosixFilePermission.OWNER_READ);
142+
permissions.add(PosixFilePermission.OWNER_WRITE);
143+
permissions.add(PosixFilePermission.OWNER_EXECUTE);
122144
try {
123-
Method setReadable = File.class.getMethod("setReadable", boolean.class, boolean.class);
124-
Method setWritable = File.class.getMethod("setWritable", boolean.class, boolean.class);
125-
Method setExecutable = File.class.getMethod("setExecutable", boolean.class, boolean.class);
126-
if (!(Boolean) setReadable.invoke(file, false, false)
127-
|| !(Boolean) setWritable.invoke(file, false, false)
128-
|| !(Boolean) setExecutable.invoke(file, false, false)) {
129-
LOGGER.warning("unable to change permissions for everybody: " + file);
130-
}
131-
if (!(Boolean) setReadable.invoke(file, true, true)
132-
|| !(Boolean) setWritable.invoke(file, true, true)
133-
|| !(Boolean) setExecutable.invoke(file, true, true)) {
134-
LOGGER.warning("unable to change permissions for owner: " + file);
135-
}
136-
} catch (InvocationTargetException exception) {
137-
Throwable cause = exception.getCause();
138-
Throwables.propagateIfPossible(cause, IOException.class);
139-
// shouldn't reach this point, but just in case...
140-
throw new RuntimeException(cause);
141-
} catch (NoSuchMethodException exception) {
142-
LOGGER.warning(
143-
"Unable to set permissions for "
144-
+ file
145-
+ ", likely because you are running a version of Java prior to 1.6");
145+
Files.setPosixFilePermissions(Paths.get(file.getAbsolutePath()), permissions);
146+
} catch (UnsupportedOperationException exception) {
147+
LOGGER.warning("Unable to set permissions for " + file
148+
+ ", because you are running on a non-POSIX file system.");
146149
} catch (SecurityException exception) {
147150
// ignored
148-
} catch (IllegalAccessException exception) {
149-
// ignored
150151
} catch (IllegalArgumentException exception) {
151152
// ignored
152153
}
153154
}
155+
156+
static void setPermissionsToOwnerOnlyWindows(File file) throws IOException {
157+
Path path = Paths.get(file.getAbsolutePath());
158+
UserPrincipal owner = path.getFileSystem().getUserPrincipalLookupService()
159+
.lookupPrincipalByName("OWNER@");
160+
161+
// get view
162+
AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
163+
164+
// All available entries
165+
Set<AclEntryPermission> permissions = ImmutableSet.of(
166+
AclEntryPermission.APPEND_DATA,
167+
AclEntryPermission.DELETE,
168+
AclEntryPermission.DELETE_CHILD,
169+
AclEntryPermission.READ_ACL,
170+
AclEntryPermission.READ_ATTRIBUTES,
171+
AclEntryPermission.READ_DATA,
172+
AclEntryPermission.READ_NAMED_ATTRS,
173+
AclEntryPermission.SYNCHRONIZE,
174+
AclEntryPermission.WRITE_ACL,
175+
AclEntryPermission.WRITE_ATTRIBUTES,
176+
AclEntryPermission.WRITE_DATA,
177+
AclEntryPermission.WRITE_NAMED_ATTRS,
178+
AclEntryPermission.WRITE_OWNER
179+
);
180+
181+
// create ACL to give owner everything
182+
AclEntry entry = AclEntry.newBuilder()
183+
.setType(AclEntryType.ALLOW)
184+
.setPrincipal(owner)
185+
.setPermissions(permissions)
186+
.build();
187+
188+
// Overwrite the ACL with only this permission
189+
view.setAcl(ImmutableList.of(entry));
190+
}
154191
}

0 commit comments

Comments
 (0)