Adds windows ACL code for file permissions, fixes build.

This commit is contained in:
Zack Shoylev 2015-04-22 18:55:30 -05:00
parent d29424304e
commit 10e5d69d64
2 changed files with 164 additions and 40 deletions

View File

@ -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<PosixFilePermission> 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<PosixFilePermission> 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<PosixFilePermission> 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<PosixFilePermission> 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);
}
}
@ -481,30 +510,55 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
@Override
public BlobAccess getBlobAccess(String containerName, String blobName) {
Path path = new File(buildPathStartingFromBaseDir(containerName, blobName)).toPath();
Set<PosixFilePermission> 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<PosixFilePermission> 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<PosixFilePermission> 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<PosixFilePermission> 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);
}
}

View File

@ -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<AclEntry> 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<AclEntry> 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);
}
}