HADOOP-14416. Path starting with 'wasb:///' not resolved correctly while authorizing with WASB-Ranger. Contributed by Sivaguru Sankaridurg

This commit is contained in:
Mingliang Liu 2017-05-16 11:22:11 -07:00
parent 8236130b2c
commit b415c6fe74
5 changed files with 116 additions and 135 deletions

View File

@ -1433,13 +1433,19 @@ public class NativeAzureFileSystem extends FileSystem {
* @param operation - A string describing the operation being performed ("delete", "create" etc.). * @param operation - A string describing the operation being performed ("delete", "create" etc.).
* @param originalPath - The originalPath that was being accessed * @param originalPath - The originalPath that was being accessed
*/ */
private void performAuthCheck(String requestingAccessForPath, WasbAuthorizationOperations accessType, private void performAuthCheck(Path requestingAccessForPath, WasbAuthorizationOperations accessType,
String operation, String originalPath) throws WasbAuthorizationException, IOException { String operation, Path originalPath) throws WasbAuthorizationException, IOException {
if (azureAuthorization && this.authorizer != null) {
requestingAccessForPath = requestingAccessForPath.makeQualified(getUri(), getWorkingDirectory());
originalPath = originalPath.makeQualified(getUri(), getWorkingDirectory());
if (!this.authorizer.authorize(requestingAccessForPath.toString(), accessType.toString())) {
throw new WasbAuthorizationException(operation
+ " operation for Path : " + originalPath.toString() + " not allowed");
}
if (azureAuthorization && this.authorizer != null &&
!this.authorizer.authorize(requestingAccessForPath, accessType.toString())) {
throw new WasbAuthorizationException(operation
+ " operation for Path : " + originalPath + " not allowed");
} }
} }
@ -1466,7 +1472,7 @@ public class NativeAzureFileSystem extends FileSystem {
Path absolutePath = makeAbsolute(f); Path absolutePath = makeAbsolute(f);
performAuthCheck(absolutePath.toString(), WasbAuthorizationOperations.WRITE, "append", absolutePath.toString()); performAuthCheck(absolutePath, WasbAuthorizationOperations.WRITE, "append", absolutePath);
String key = pathToKey(absolutePath); String key = pathToKey(absolutePath);
FileMetadata meta = null; FileMetadata meta = null;
@ -1671,7 +1677,7 @@ public class NativeAzureFileSystem extends FileSystem {
Path absolutePath = makeAbsolute(f); Path absolutePath = makeAbsolute(f);
Path ancestor = getAncestor(absolutePath); Path ancestor = getAncestor(absolutePath);
performAuthCheck(ancestor.toString(), WasbAuthorizationOperations.WRITE, "create", absolutePath.toString()); performAuthCheck(ancestor, WasbAuthorizationOperations.WRITE, "create", absolutePath);
String key = pathToKey(absolutePath); String key = pathToKey(absolutePath);
@ -1685,7 +1691,7 @@ public class NativeAzureFileSystem extends FileSystem {
throw new FileAlreadyExistsException("File already exists:" + f); throw new FileAlreadyExistsException("File already exists:" + f);
} }
else { else {
performAuthCheck(absolutePath.toString(), WasbAuthorizationOperations.WRITE, "create", absolutePath.toString()); performAuthCheck(absolutePath, WasbAuthorizationOperations.WRITE, "create", absolutePath);
} }
} }
@ -1800,7 +1806,7 @@ public class NativeAzureFileSystem extends FileSystem {
Path absolutePath = makeAbsolute(f); Path absolutePath = makeAbsolute(f);
Path parentPath = absolutePath.getParent(); Path parentPath = absolutePath.getParent();
performAuthCheck(parentPath.toString(), WasbAuthorizationOperations.WRITE, "delete", absolutePath.toString()); performAuthCheck(parentPath, WasbAuthorizationOperations.WRITE, "delete", absolutePath);
String key = pathToKey(absolutePath); String key = pathToKey(absolutePath);
@ -2002,14 +2008,12 @@ public class NativeAzureFileSystem extends FileSystem {
// NOTE: Ideally the subtree needs read-write-execute access check. // NOTE: Ideally the subtree needs read-write-execute access check.
// But we will simplify it to write-access check. // But we will simplify it to write-access check.
if (metaFile.isDir()) { // the absolute-path if (metaFile.isDir()) { // the absolute-path
performAuthCheck(absolutePath.toString(), WasbAuthorizationOperations.WRITE, "delete", performAuthCheck(absolutePath, WasbAuthorizationOperations.WRITE, "delete", absolutePath);
absolutePath.toString());
} }
for (FileMetadata meta : contents) { for (FileMetadata meta : contents) {
if (meta.isDir()) { if (meta.isDir()) {
Path subTreeDir = keyToPath(meta.getKey()); Path subTreeDir = keyToPath(meta.getKey());
performAuthCheck(subTreeDir.toString(), WasbAuthorizationOperations.WRITE, "delete", performAuthCheck(subTreeDir, WasbAuthorizationOperations.WRITE, "delete", absolutePath);
absolutePath.toString());
} }
} }
} }
@ -2090,8 +2094,7 @@ public class NativeAzureFileSystem extends FileSystem {
// Capture the absolute path and the path to key. // Capture the absolute path and the path to key.
Path absolutePath = makeAbsolute(f); Path absolutePath = makeAbsolute(f);
performAuthCheck(absolutePath.toString(), WasbAuthorizationOperations.READ, "getFileStatus", performAuthCheck(absolutePath, WasbAuthorizationOperations.READ, "getFileStatus", absolutePath);
absolutePath.toString());
String key = pathToKey(absolutePath); String key = pathToKey(absolutePath);
if (key.length() == 0) { // root always exists if (key.length() == 0) { // root always exists
@ -2192,7 +2195,7 @@ public class NativeAzureFileSystem extends FileSystem {
Path absolutePath = makeAbsolute(f); Path absolutePath = makeAbsolute(f);
performAuthCheck(absolutePath.toString(), WasbAuthorizationOperations.READ, "liststatus", absolutePath.toString()); performAuthCheck(absolutePath, WasbAuthorizationOperations.READ, "liststatus", absolutePath);
String key = pathToKey(absolutePath); String key = pathToKey(absolutePath);
Set<FileStatus> status = new TreeSet<FileStatus>(); Set<FileStatus> status = new TreeSet<FileStatus>();
@ -2436,7 +2439,7 @@ public class NativeAzureFileSystem extends FileSystem {
Path absolutePath = makeAbsolute(f); Path absolutePath = makeAbsolute(f);
Path ancestor = getAncestor(absolutePath); Path ancestor = getAncestor(absolutePath);
performAuthCheck(ancestor.toString(), WasbAuthorizationOperations.WRITE, "mkdirs", absolutePath.toString()); performAuthCheck(ancestor, WasbAuthorizationOperations.WRITE, "mkdirs", absolutePath);
PermissionStatus permissionStatus = null; PermissionStatus permissionStatus = null;
if(noUmask) { if(noUmask) {
@ -2482,7 +2485,7 @@ public class NativeAzureFileSystem extends FileSystem {
Path absolutePath = makeAbsolute(f); Path absolutePath = makeAbsolute(f);
performAuthCheck(absolutePath.toString(), WasbAuthorizationOperations.READ, "read", absolutePath.toString()); performAuthCheck(absolutePath, WasbAuthorizationOperations.READ, "read", absolutePath);
String key = pathToKey(absolutePath); String key = pathToKey(absolutePath);
FileMetadata meta = null; FileMetadata meta = null;
@ -2548,8 +2551,7 @@ public class NativeAzureFileSystem extends FileSystem {
return false; return false;
} }
performAuthCheck(srcParentFolder.toString(), WasbAuthorizationOperations.WRITE, "rename", performAuthCheck(srcParentFolder, WasbAuthorizationOperations.WRITE, "rename", absoluteSrcPath);
absoluteSrcPath.toString());
String srcKey = pathToKey(absoluteSrcPath); String srcKey = pathToKey(absoluteSrcPath);
@ -2562,8 +2564,7 @@ public class NativeAzureFileSystem extends FileSystem {
Path absoluteDstPath = makeAbsolute(dst); Path absoluteDstPath = makeAbsolute(dst);
Path dstParentFolder = absoluteDstPath.getParent(); Path dstParentFolder = absoluteDstPath.getParent();
performAuthCheck(dstParentFolder.toString(), WasbAuthorizationOperations.WRITE, "rename", performAuthCheck(dstParentFolder, WasbAuthorizationOperations.WRITE, "rename", absoluteDstPath);
absoluteDstPath.toString());
String dstKey = pathToKey(absoluteDstPath); String dstKey = pathToKey(absoluteDstPath);
FileMetadata dstMetadata = null; FileMetadata dstMetadata = null;

View File

@ -20,11 +20,9 @@ package org.apache.hadoop.fs.azure;
import static org.junit.Assume.assumeNotNull; import static org.junit.Assume.assumeNotNull;
import org.apache.hadoop.fs.FileSystem; import com.google.common.annotations.VisibleForTesting;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -40,7 +38,8 @@ public abstract class AbstractWasbTestBase {
protected static final Logger LOG = protected static final Logger LOG =
LoggerFactory.getLogger(AbstractWasbTestBase.class); LoggerFactory.getLogger(AbstractWasbTestBase.class);
protected FileSystem fs; @VisibleForTesting
protected NativeAzureFileSystem fs;
private AzureBlobStorageTestAccount testAccount; private AzureBlobStorageTestAccount testAccount;
@Before @Before

View File

@ -23,6 +23,7 @@ import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
/** /**
* A mock wasb authorizer implementation. * A mock wasb authorizer implementation.
@ -32,6 +33,14 @@ public class MockWasbAuthorizerImpl implements WasbAuthorizerInterface {
private Map<AuthorizationComponent, Boolean> authRules; private Map<AuthorizationComponent, Boolean> authRules;
// The full qualified URL to the root directory
private String qualifiedPrefixUrl;
public MockWasbAuthorizerImpl(NativeAzureFileSystem fs) {
qualifiedPrefixUrl = new Path("/").makeQualified(fs.getUri(), fs.getWorkingDirectory())
.toString().replaceAll("/$", "");
}
@Override @Override
public void init(Configuration conf) { public void init(Configuration conf) {
authRules = new HashMap<AuthorizationComponent, Boolean>(); authRules = new HashMap<AuthorizationComponent, Boolean>();
@ -40,6 +49,8 @@ public class MockWasbAuthorizerImpl implements WasbAuthorizerInterface {
public void addAuthRule(String wasbAbsolutePath, public void addAuthRule(String wasbAbsolutePath,
String accessType, boolean access) { String accessType, boolean access) {
wasbAbsolutePath = qualifiedPrefixUrl + wasbAbsolutePath;
AuthorizationComponent component = wasbAbsolutePath.endsWith("*") AuthorizationComponent component = wasbAbsolutePath.endsWith("*")
? new AuthorizationComponent("^" + wasbAbsolutePath.replace("*", ".*"), accessType) ? new AuthorizationComponent("^" + wasbAbsolutePath.replace("*", ".*"), accessType)
: new AuthorizationComponent(wasbAbsolutePath, accessType); : new AuthorizationComponent(wasbAbsolutePath, accessType);

View File

@ -77,6 +77,15 @@ public class TestNativeAzureFileSystemAuthorization
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
} }
/**
* Setup the expected exception class, and exception message that the test is supposed to fail with
*/
private void setExpectedFailureMessage(String operation, Path path) {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage(String.format("%s operation for Path : %s not allowed",
operation, path.makeQualified(fs.getUri(), fs.getWorkingDirectory())));
}
/** /**
* Positive test to verify Create access check * Positive test to verify Create access check
* The file is created directly under an existing folder. * The file is created directly under an existing folder.
@ -86,13 +95,10 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testCreateAccessWithoutCreateIntermediateFoldersCheckPositive() throws Throwable { public void testCreateAccessWithoutCreateIntermediateFoldersCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/"); Path parentDir = new Path("/");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -117,13 +123,10 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testCreateAccessWithCreateIntermediateFoldersCheckPositive() throws Throwable { public void testCreateAccessWithCreateIntermediateFoldersCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testCreateAccessCheckPositive/1/2/3"); Path parentDir = new Path("/testCreateAccessCheckPositive/1/2/3");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -148,16 +151,12 @@ public class TestNativeAzureFileSystemAuthorization
@Test // (expected=WasbAuthorizationException.class) @Test // (expected=WasbAuthorizationException.class)
public void testCreateAccessWithOverwriteCheckNegative() throws Throwable { public void testCreateAccessWithOverwriteCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("create operation for Path : /test.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/"); Path parentDir = new Path("/");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("create", testPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -184,13 +183,10 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testCreateAccessWithOverwriteCheckPositive() throws Throwable { public void testCreateAccessWithOverwriteCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/"); Path parentDir = new Path("/");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -218,16 +214,12 @@ public class TestNativeAzureFileSystemAuthorization
@Test // (expected=WasbAuthorizationException.class) @Test // (expected=WasbAuthorizationException.class)
public void testCreateAccessCheckNegative() throws Throwable { public void testCreateAccessCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("create operation for Path : /testCreateAccessCheckNegative/test.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testCreateAccessCheckNegative"); Path parentDir = new Path("/testCreateAccessCheckNegative");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("create", testPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), false); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), false);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
@ -249,14 +241,11 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testListAccessCheckPositive() throws Throwable { public void testListAccessCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testListAccessCheckPositive"); Path parentDir = new Path("/testListAccessCheckPositive");
Path intermediateFolders = new Path(parentDir, "1/2/3/"); Path intermediateFolders = new Path(parentDir, "1/2/3/");
Path testPath = new Path(intermediateFolders, "test.dat"); Path testPath = new Path(intermediateFolders, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -280,16 +269,12 @@ public class TestNativeAzureFileSystemAuthorization
@Test //(expected=WasbAuthorizationException.class) @Test //(expected=WasbAuthorizationException.class)
public void testListAccessCheckNegative() throws Throwable { public void testListAccessCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("liststatus operation for Path : /testListAccessCheckNegative/test.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testListAccessCheckNegative"); Path parentDir = new Path("/testListAccessCheckNegative");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("liststatus", testPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), false); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), false);
@ -312,14 +297,11 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testRenameAccessCheckPositive() throws Throwable { public void testRenameAccessCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testRenameAccessCheckPositive"); Path parentDir = new Path("/testRenameAccessCheckPositive");
Path srcPath = new Path(parentDir, "test1.dat"); Path srcPath = new Path(parentDir, "test1.dat");
Path dstPath = new Path(parentDir, "test2.dat"); Path dstPath = new Path(parentDir, "test2.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); /* to create parentDir */ authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); /* to create parentDir */
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.WRITE.toString(), true); /* for rename */ authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.WRITE.toString(), true); /* for rename */
@ -347,16 +329,13 @@ public class TestNativeAzureFileSystemAuthorization
@Test //(expected=WasbAuthorizationException.class) @Test //(expected=WasbAuthorizationException.class)
public void testRenameAccessCheckNegative() throws Throwable { public void testRenameAccessCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("rename operation for Path : /testRenameAccessCheckNegative/test1.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testRenameAccessCheckNegative"); Path parentDir = new Path("/testRenameAccessCheckNegative");
Path srcPath = new Path(parentDir, "test1.dat"); Path srcPath = new Path(parentDir, "test1.dat");
Path dstPath = new Path(parentDir, "test2.dat"); Path dstPath = new Path(parentDir, "test2.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("rename", srcPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); /* to create parent dir */ authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); /* to create parent dir */
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.WRITE.toString(), false); authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.WRITE.toString(), false);
@ -384,17 +363,14 @@ public class TestNativeAzureFileSystemAuthorization
@Test //(expected=WasbAuthorizationException.class) @Test //(expected=WasbAuthorizationException.class)
public void testRenameAccessCheckNegativeOnDstFolder() throws Throwable { public void testRenameAccessCheckNegativeOnDstFolder() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("rename operation for Path : /testRenameAccessCheckNegativeDst/test2.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentSrcDir = new Path("/testRenameAccessCheckNegativeSrc"); Path parentSrcDir = new Path("/testRenameAccessCheckNegativeSrc");
Path srcPath = new Path(parentSrcDir, "test1.dat"); Path srcPath = new Path(parentSrcDir, "test1.dat");
Path parentDstDir = new Path("/testRenameAccessCheckNegativeDst"); Path parentDstDir = new Path("/testRenameAccessCheckNegativeDst");
Path dstPath = new Path(parentDstDir, "test2.dat"); Path dstPath = new Path(parentDstDir, "test2.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("rename", dstPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); /* to create parent dir */ authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); /* to create parent dir */
authorizer.addAuthRule(parentSrcDir.toString(), WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule(parentSrcDir.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
@ -419,17 +395,15 @@ public class TestNativeAzureFileSystemAuthorization
* Positive test to verify rename access check - the dstFolder allows rename * Positive test to verify rename access check - the dstFolder allows rename
* @throws Throwable * @throws Throwable
*/ */
@Test //(expected=WasbAuthorizationException.class) @Test
public void testRenameAccessCheckPositiveOnDstFolder() throws Throwable { public void testRenameAccessCheckPositiveOnDstFolder() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentSrcDir = new Path("/testRenameAccessCheckPositiveSrc"); Path parentSrcDir = new Path("/testRenameAccessCheckPositiveSrc");
Path srcPath = new Path(parentSrcDir, "test1.dat"); Path srcPath = new Path(parentSrcDir, "test1.dat");
Path parentDstDir = new Path("/testRenameAccessCheckPositiveDst"); Path parentDstDir = new Path("/testRenameAccessCheckPositiveDst");
Path dstPath = new Path(parentDstDir, "test2.dat"); Path dstPath = new Path(parentDstDir, "test2.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); /* to create parent dirs */ authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); /* to create parent dirs */
authorizer.addAuthRule(parentSrcDir.toString(), WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule(parentSrcDir.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
@ -461,12 +435,10 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testReadAccessCheckPositive() throws Throwable { public void testReadAccessCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testReadAccessCheckPositive"); Path parentDir = new Path("/testReadAccessCheckPositive");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -504,15 +476,12 @@ public class TestNativeAzureFileSystemAuthorization
@Test //(expected=WasbAuthorizationException.class) @Test //(expected=WasbAuthorizationException.class)
public void testReadAccessCheckNegative() throws Throwable { public void testReadAccessCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("read operation for Path : /testReadAccessCheckNegative/test.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testReadAccessCheckNegative"); Path parentDir = new Path("/testReadAccessCheckNegative");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("read", testPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), false); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), false);
@ -548,13 +517,10 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testFileDeleteAccessCheckPositive() throws Throwable { public void testFileDeleteAccessCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/"); Path parentDir = new Path("/");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -576,16 +542,12 @@ public class TestNativeAzureFileSystemAuthorization
@Test //(expected=WasbAuthorizationException.class) @Test //(expected=WasbAuthorizationException.class)
public void testFileDeleteAccessCheckNegative() throws Throwable { public void testFileDeleteAccessCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("delete operation for Path : /test.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/"); Path parentDir = new Path("/");
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("delete", testPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -622,13 +584,10 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testFileDeleteAccessWithIntermediateFoldersCheckPositive() throws Throwable { public void testFileDeleteAccessWithIntermediateFoldersCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testDeleteIntermediateFolder"); Path parentDir = new Path("/testDeleteIntermediateFolder");
Path testPath = new Path(parentDir, "1/2/test.dat"); Path testPath = new Path(parentDir, "1/2/test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); // for create and delete authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); // for create and delete
authorizer.addAuthRule("/testDeleteIntermediateFolder*", authorizer.addAuthRule("/testDeleteIntermediateFolder*",
@ -655,12 +614,9 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testGetFileStatusPositive() throws Throwable { public void testGetFileStatusPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path testPath = new Path("/"); Path testPath = new Path("/");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.READ.toString(), true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
@ -675,15 +631,11 @@ public class TestNativeAzureFileSystemAuthorization
@Test //(expected=WasbAuthorizationException.class) @Test //(expected=WasbAuthorizationException.class)
public void testGetFileStatusNegative() throws Throwable { public void testGetFileStatusNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("getFileStatus operation for Path : / not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path testPath = new Path("/"); Path testPath = new Path("/");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("getFileStatus", testPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.READ.toString(), false); authorizer.addAuthRule("/", WasbAuthorizationOperations.READ.toString(), false);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
@ -698,12 +650,9 @@ public class TestNativeAzureFileSystemAuthorization
@Test @Test
public void testMkdirsCheckPositive() throws Throwable { public void testMkdirsCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path testPath = new Path("/testMkdirsAccessCheckPositive/1/2/3"); Path testPath = new Path("/testMkdirsAccessCheckPositive/1/2/3");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -726,15 +675,11 @@ public class TestNativeAzureFileSystemAuthorization
@Test //(expected=WasbAuthorizationException.class) @Test //(expected=WasbAuthorizationException.class)
public void testMkdirsCheckNegative() throws Throwable { public void testMkdirsCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("mkdirs operation for Path : /testMkdirsAccessCheckNegative/1/2/3 not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path testPath = new Path("/testMkdirsAccessCheckNegative/1/2/3"); Path testPath = new Path("/testMkdirsAccessCheckNegative/1/2/3");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(); setExpectedFailureMessage("mkdirs", testPath);
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null); authorizer.init(null);
authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), false); authorizer.addAuthRule("/", WasbAuthorizationOperations.WRITE.toString(), false);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true); authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
@ -749,4 +694,23 @@ public class TestNativeAzureFileSystemAuthorization
fs.delete(new Path("/testMkdirsAccessCheckNegative"), true); fs.delete(new Path("/testMkdirsAccessCheckNegative"), true);
} }
} }
/**
* Positive test triple slash format (wasb:///) access check
* @throws Throwable
*/
@Test
public void testListStatusWithTripleSlashCheckPositive() throws Throwable {
Path testPath = new Path("/");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl(fs);
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
fs.updateWasbAuthorizer(authorizer);
Path testPathWithTripleSlash = new Path("wasb:///" + testPath);
fs.listStatus(testPathWithTripleSlash);
}
} }

View File

@ -32,6 +32,8 @@ import org.junit.rules.ExpectedException;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static org.apache.hadoop.fs.azure.AzureNativeFileSystemStore.KEY_USE_SECURE_MODE; import static org.apache.hadoop.fs.azure.AzureNativeFileSystemStore.KEY_USE_SECURE_MODE;
@ -261,16 +263,20 @@ public class TestWasbRemoteCallHelper
performop(mockHttpClient); performop(mockHttpClient);
} }
private void setupExpectations() { private void setupExpectations() throws UnsupportedEncodingException {
String path = new Path("/").makeQualified(fs.getUri(), fs.getWorkingDirectory()).toString();
String pathEncoded = URLEncoder.encode(path, "UTF-8");
String requestURI = String.format("http://localhost/CHECK_AUTHORIZATION?wasb_absolute_path=%s&operation_type=write", pathEncoded);
expectedEx.expect(WasbAuthorizationException.class); expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("org.apache.hadoop.fs.azure.WasbRemoteCallException: " expectedEx.expectMessage("org.apache.hadoop.fs.azure.WasbRemoteCallException: "
+ "http://localhost/CHECK_AUTHORIZATION?wasb_absolute_path=%2F&" + requestURI
+ "operation_type=write:Encountered IOException while making remote call"); + ":Encountered IOException while making remote call"
);
} }
private void performop(HttpClient mockHttpClient) throws Throwable { private void performop(HttpClient mockHttpClient) throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path testPath = new Path("/", "test.dat"); Path testPath = new Path("/", "test.dat");