/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.fs.azure;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.contract.ContractTestUtils;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import com.sun.tools.javac.util.Assert;
import org.junit.rules.ExpectedException;
import java.io.Console;
import static org.apache.hadoop.fs.azure.AzureNativeFileSystemStore.KEY_USE_SECURE_MODE;
/**
* Test class to hold all WASB authorization tests.
*/
public class TestNativeAzureFileSystemAuthorization
extends AbstractWasbTestBase {
@Override
protected AzureBlobStorageTestAccount createTestAccount() throws Exception {
Configuration conf = new Configuration();
conf.set(NativeAzureFileSystem.KEY_AZURE_AUTHORIZATION, "true");
conf.set(RemoteWasbAuthorizerImpl.KEY_REMOTE_AUTH_SERVICE_URL, "http://localhost/");
return AzureBlobStorageTestAccount.create(conf);
}
@Before
public void beforeMethod() {
boolean useSecureMode = fs.getConf().getBoolean(KEY_USE_SECURE_MODE, false);
boolean useAuthorization = fs.getConf().getBoolean(NativeAzureFileSystem.KEY_AZURE_AUTHORIZATION, false);
Assume.assumeTrue("Test valid when both SecureMode and Authorization are enabled .. skipping",
useSecureMode && useAuthorization);
Assume.assumeTrue(
useSecureMode && useAuthorization
);
}
@Rule
public ExpectedException expectedEx = ExpectedException.none();
/**
* Positive test to verify Create and delete access check
* @throws Throwable
*/
@Test
public void testCreateAccessCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testCreateAccessCheckPositive");
Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl();
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
fs.updateWasbAuthorizer(authorizer);
fs.create(testPath);
ContractTestUtils.assertPathExists(fs, "testPath was not created", testPath);
fs.delete(parentDir, true);
}
/**
* Negative test to verify Create access check
* @throws Throwable
*/
@Test // (expected=WasbAuthorizationException.class)
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 testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl();
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(),WasbAuthorizationOperations.WRITE.toString(), false);
authorizer.addAuthRule(parentDir.toString(),WasbAuthorizationOperations.EXECUTE.toString(), true);
fs.updateWasbAuthorizer(authorizer);
try {
fs.create(testPath);
}
finally {
fs.delete(parentDir, true);
}
}
/**
* Positive test to verify Create and delete access check
* @throws Throwable
*/
@Test
public void testListAccessCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testListAccessCheckPositive");
Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl();
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
fs.updateWasbAuthorizer(authorizer);
fs.create(testPath);
ContractTestUtils.assertPathExists(fs, "testPath does not exist", testPath);
try {
fs.listStatus(testPath);
}
finally {
fs.delete(parentDir, true);
}
}
/**
* Negative test to verify Create access check
* @throws Throwable
*/
@Test //(expected=WasbAuthorizationException.class)
public void testListAccessCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("getFileStatus operation for Path : /testListAccessCheckNegative/test.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testListAccessCheckNegative");
Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl();
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), false);
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
fs.updateWasbAuthorizer(authorizer);
fs.create(testPath);
ContractTestUtils.assertPathExists(fs, "testPath does not exist", testPath);
try {
fs.listStatus(testPath);
}
finally {
fs.delete(parentDir, true);
}
}
/**
* Positive test to verify rename access check.
* @throws Throwable
*/
@Test
public void testRenameAccessCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testRenameAccessCheckPositive");
Path testPath = new Path(parentDir, "test.dat");
Path renamePath = new Path(parentDir, "test2.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl();
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
authorizer.addAuthRule(renamePath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
fs.updateWasbAuthorizer(authorizer);
fs.create(testPath);
ContractTestUtils.assertPathExists(fs, "sourcePath does not exist", testPath);
try {
fs.rename(testPath, renamePath);
ContractTestUtils.assertPathExists(fs, "destPath does not exist", renamePath);
}
finally {
fs.delete(parentDir, true);
}
}
/**
* Negative test to verify rename access check.
* @throws Throwable
*/
@Test //(expected=WasbAuthorizationException.class)
public void testRenameAccessCheckNegative() throws Throwable {
expectedEx.expect(WasbAuthorizationException.class);
expectedEx.expectMessage("rename operation for Path : /testRenameAccessCheckNegative/test.dat not allowed");
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testRenameAccessCheckNegative");
Path testPath = new Path(parentDir, "test.dat");
Path renamePath = new Path(parentDir, "test2.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl();
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
// set EXECUTE to true for initial assert right after creation.
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
fs.updateWasbAuthorizer(authorizer);
fs.create(testPath);
ContractTestUtils.assertPathExists(fs, "sourcePath does not exist", testPath);
// Set EXECUTE to false for actual rename-failure test
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), false);
fs.updateWasbAuthorizer(authorizer);
try {
fs.rename(testPath, renamePath);
ContractTestUtils.assertPathExists(fs, "destPath does not exist", renamePath);
} finally {
fs.delete(parentDir, true);
}
}
/**
* Positive test for read access check.
* @throws Throwable
*/
@Test
public void testReadAccessCheckPositive() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
NativeAzureFileSystem fs = testAccount.getFileSystem();
Path parentDir = new Path("/testReadAccessCheckPositive");
Path testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl();
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), true);
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
fs.updateWasbAuthorizer(authorizer);
FSDataOutputStream fso = fs.create(testPath);
String data = "Hello World";
fso.writeBytes(data);
fso.close();
ContractTestUtils.assertPathExists(fs, "testPath does not exist", testPath);
FSDataInputStream inputStream = null;
try {
inputStream = fs.open(testPath);
ContractTestUtils.verifyRead(inputStream, data.getBytes(), 0, data.length());
}
finally {
if(inputStream != null) {
inputStream.close();
}
fs.delete(parentDir, true);
}
}
/**
* Negative test to verify read access check.
* @throws Throwable
*/
@Test //(expected=WasbAuthorizationException.class)
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 testPath = new Path(parentDir, "test.dat");
MockWasbAuthorizerImpl authorizer = new MockWasbAuthorizerImpl();
authorizer.init(null);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.WRITE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
authorizer.addAuthRule(testPath.toString(), WasbAuthorizationOperations.READ.toString(), false);
authorizer.addAuthRule(parentDir.toString(), WasbAuthorizationOperations.EXECUTE.toString(), true);
fs.updateWasbAuthorizer(authorizer);
FSDataOutputStream fso = fs.create(testPath);
String data = "Hello World";
fso.writeBytes(data);
fso.close();
ContractTestUtils.assertPathExists(fs, "testPath does not exist", testPath);
FSDataInputStream inputStream = null;
try {
inputStream = fs.open(testPath);
ContractTestUtils.verifyRead(inputStream, data.getBytes(), 0, data.length());
} finally {
if (inputStream != null) {
inputStream.close();
}
fs.delete(parentDir, true);
}
}
}