diff --git a/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java b/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java index 2f9f14b259..5a7524532f 100644 --- a/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java +++ b/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java @@ -16,24 +16,27 @@ */ package org.jclouds.filesystem.strategy.internal; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Strings.isNullOrEmpty; +import static com.google.common.io.BaseEncoding.base16; import static java.nio.file.Files.getFileAttributeView; import static java.nio.file.Files.getPosixFilePermissions; import static java.nio.file.Files.readAttributes; import static java.nio.file.Files.setPosixFilePermissions; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Strings.isNullOrEmpty; -import static com.google.common.io.BaseEncoding.base16; +import static org.jclouds.filesystem.util.Utils.isPrivate; +import static org.jclouds.filesystem.util.Utils.isWindows; +import static org.jclouds.filesystem.util.Utils.setPrivate; +import static org.jclouds.filesystem.util.Utils.setPublic; import static org.jclouds.util.Closeables2.closeQuietly; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.UserDefinedFileAttributeView; -import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Map; import java.util.Set; @@ -156,30 +159,56 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy { @Override public ContainerAccess getContainerAccess(String container) { Path path = new File(buildPathStartingFromBaseDir(container)).toPath(); - Set permissions; - try { - permissions = getPosixFilePermissions(path); - } catch (IOException ioe) { - throw Throwables.propagate(ioe); + + if ( isWindows() ) { + try { + if (isPrivate(path)) { + return ContainerAccess.PRIVATE; + } else { + return ContainerAccess.PUBLIC_READ; + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + Set permissions; + try { + permissions = getPosixFilePermissions(path); + } catch (IOException ioe) { + throw Throwables.propagate(ioe); + } + return permissions.contains(PosixFilePermission.OTHERS_READ) + ? ContainerAccess.PUBLIC_READ : ContainerAccess.PRIVATE; } - return permissions.contains(PosixFilePermission.OTHERS_READ) - ? ContainerAccess.PUBLIC_READ : ContainerAccess.PRIVATE; } @Override public void setContainerAccess(String container, ContainerAccess access) { Path path = new File(buildPathStartingFromBaseDir(container)).toPath(); - Set permissions; - try { - permissions = getPosixFilePermissions(path); - if (access == ContainerAccess.PRIVATE) { - permissions.remove(PosixFilePermission.OTHERS_READ); - } else if (access == ContainerAccess.PUBLIC_READ) { - permissions.add(PosixFilePermission.OTHERS_READ); + + if ( isWindows() ) { + try { + if (access == ContainerAccess.PRIVATE) { + setPrivate(path); + } else { + setPublic(path); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + Set permissions; + try { + permissions = getPosixFilePermissions(path); + if (access == ContainerAccess.PRIVATE) { + permissions.remove(PosixFilePermission.OTHERS_READ); + } else if (access == ContainerAccess.PUBLIC_READ) { + permissions.add(PosixFilePermission.OTHERS_READ); + } + setPosixFilePermissions(path, permissions); + } catch (IOException ioe) { + throw Throwables.propagate(ioe); } - setPosixFilePermissions(path, permissions); - } catch (IOException ioe) { - throw Throwables.propagate(ioe); } } @@ -243,7 +272,7 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy { return buildPathAndChecksIfBlobExists(container, key); } catch (IOException e) { logger.error(e, "An error occurred while checking key %s in container %s", - container, key); + container, key); throw Throwables.propagate(e); } } @@ -480,30 +509,55 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy { @Override public BlobAccess getBlobAccess(String containerName, String blobName) { Path path = new File(buildPathStartingFromBaseDir(containerName, blobName)).toPath(); - Set permissions; - try { - permissions = getPosixFilePermissions(path); - } catch (IOException ioe) { - throw Throwables.propagate(ioe); + + if ( isWindows() ) { + try { + if (isPrivate(path)) { + return BlobAccess.PRIVATE; + } else { + return BlobAccess.PUBLIC_READ; + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + Set permissions; + try { + permissions = getPosixFilePermissions(path); + } catch (IOException ioe) { + throw Throwables.propagate(ioe); + } + return permissions.contains(PosixFilePermission.OTHERS_READ) + ? BlobAccess.PUBLIC_READ : BlobAccess.PRIVATE; } - return permissions.contains(PosixFilePermission.OTHERS_READ) - ? BlobAccess.PUBLIC_READ : BlobAccess.PRIVATE; } @Override public void setBlobAccess(String container, String name, BlobAccess access) { Path path = new File(buildPathStartingFromBaseDir(container, name)).toPath(); - Set permissions; - try { - permissions = getPosixFilePermissions(path); - if (access == BlobAccess.PRIVATE) { - permissions.remove(PosixFilePermission.OTHERS_READ); - } else if (access == BlobAccess.PUBLIC_READ) { - permissions.add(PosixFilePermission.OTHERS_READ); + if ( isWindows() ) { + try { + if (access == BlobAccess.PRIVATE) { + setPrivate(path); + } else { + setPublic(path); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + Set permissions; + try { + permissions = getPosixFilePermissions(path); + if (access == BlobAccess.PRIVATE) { + permissions.remove(PosixFilePermission.OTHERS_READ); + } else if (access == BlobAccess.PUBLIC_READ) { + permissions.add(PosixFilePermission.OTHERS_READ); + } + setPosixFilePermissions(path, permissions); + } catch (IOException ioe) { + throw Throwables.propagate(ioe); } - setPosixFilePermissions(path, permissions); - } catch (IOException ioe) { - throw Throwables.propagate(ioe); } } diff --git a/apis/filesystem/src/main/java/org/jclouds/filesystem/util/Utils.java b/apis/filesystem/src/main/java/org/jclouds/filesystem/util/Utils.java index 95f5f57527..cc258510aa 100644 --- a/apis/filesystem/src/main/java/org/jclouds/filesystem/util/Utils.java +++ b/apis/filesystem/src/main/java/org/jclouds/filesystem/util/Utils.java @@ -16,9 +16,19 @@ */ package org.jclouds.filesystem.util; +import static java.nio.file.FileSystems.getDefault; + import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; +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.UserPrincipal; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; /** * Utilities for the filesystem blobstore. @@ -41,4 +51,64 @@ public class Utils { } Files.delete(file.toPath()); } + + /** + * Determine if Java is running on a windows OS + */ + public static boolean isWindows() { + return System.getProperty("os.name", "").toLowerCase().contains("windows"); + } + + /** + * @param path The path to a Windows file or directory. + * @return true if path has permissions set to Everyone on windows. The exact permissions are not checked. + */ + public static boolean isPrivate(Path path) throws IOException { + UserPrincipal everyone = getDefault().getUserPrincipalLookupService() + .lookupPrincipalByName("Everyone"); + AclFileAttributeView aclFileAttributes = java.nio.file.Files.getFileAttributeView( + path, AclFileAttributeView.class); + for (AclEntry aclEntry : aclFileAttributes.getAcl()) { + if (aclEntry.principal().equals(everyone)) { + return false; + } + } + return true; + } + + /** + * @param path Remove "Everyone" from this path's Windows ACL permissions. + */ + public static void setPrivate(Path path) throws IOException { + UserPrincipal everyone = getDefault().getUserPrincipalLookupService() + .lookupPrincipalByName("Everyone"); + AclFileAttributeView aclFileAttributes = java.nio.file.Files.getFileAttributeView( + path, AclFileAttributeView.class); + CopyOnWriteArrayList aclList = new CopyOnWriteArrayList(aclFileAttributes.getAcl()); + for (AclEntry aclEntry : aclList) { + if (aclEntry.principal().equals(everyone) && aclEntry.type().equals(AclEntryType.ALLOW)) { + aclList.remove(aclEntry); + } + } + aclFileAttributes.setAcl(aclList); + } + + /** + * @param path Add "Everyone" with read enabled to this path's Windows ACL permissions. + */ + public static void setPublic(Path path) throws IOException { + UserPrincipal everyone = getDefault().getUserPrincipalLookupService() + .lookupPrincipalByName("Everyone"); + AclFileAttributeView aclFileAttributes = java.nio.file.Files.getFileAttributeView( + path, AclFileAttributeView.class); + List list = aclFileAttributes.getAcl(); + list.add(AclEntry.newBuilder().setPrincipal(everyone).setPermissions( + AclEntryPermission.READ_DATA, + AclEntryPermission.READ_ACL, + AclEntryPermission.READ_ATTRIBUTES, + AclEntryPermission.READ_NAMED_ATTRS) + .setType(AclEntryType.ALLOW) + .build()); + aclFileAttributes.setAcl(list); + } }