16
16
17
17
import com .google .api .client .util .IOUtils ;
18
18
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 ;
20
23
import java .io .File ;
21
24
import java .io .FileInputStream ;
22
25
import java .io .FileOutputStream ;
23
26
import java .io .IOException ;
24
27
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 ;
27
39
import java .util .logging .Logger ;
28
40
29
41
/**
@@ -40,6 +52,9 @@ public class FileDataStoreFactory extends AbstractDataStoreFactory {
40
52
41
53
private static final Logger LOGGER = Logger .getLogger (FileDataStoreFactory .class .getName ());
42
54
55
+ private static final boolean IS_WINDOWS = StandardSystemProperty .OS_NAME .value ()
56
+ .startsWith ("WINDOWS" );
57
+
43
58
/** Directory to store data. */
44
59
private final File dataDirectory ;
45
60
@@ -55,7 +70,12 @@ public FileDataStoreFactory(File dataDirectory) throws IOException {
55
70
if (!dataDirectory .exists () && !dataDirectory .mkdirs ()) {
56
71
throw new IOException ("unable to create directory: " + dataDirectory );
57
72
}
58
- setPermissionsToOwnerOnly (dataDirectory );
73
+
74
+ if (IS_WINDOWS ) {
75
+ setPermissionsToOwnerOnlyWindows (dataDirectory );
76
+ } else {
77
+ setPermissionsToOwnerOnly (dataDirectory );
78
+ }
59
79
}
60
80
61
81
/** Returns the data directory. */
@@ -117,38 +137,55 @@ public FileDataStoreFactory getDataStoreFactory() {
117
137
* @throws IOException
118
138
*/
119
139
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 );
122
144
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." );
146
149
} catch (SecurityException exception ) {
147
150
// ignored
148
- } catch (IllegalAccessException exception ) {
149
- // ignored
150
151
} catch (IllegalArgumentException exception ) {
151
152
// ignored
152
153
}
153
154
}
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
+ }
154
191
}
0 commit comments