You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ap...@apache.org on 2015/04/10 00:56:08 UTC
[5/8] hbase git commit: HBASE-13275 Setting
hbase.security.authorization to false does not disable authorization
http://git-wip-us.apache.org/repos/asf/hbase/blob/356422e1/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestWithDisabledAuthorization.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestWithDisabledAuthorization.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestWithDisabledAuthorization.java
new file mode 100644
index 0000000..385d11c
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestWithDisabledAuthorization.java
@@ -0,0 +1,1031 @@
+/*
+ * 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.hbase.security.access;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.Coprocessor;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.TableNotFoundException;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.Append;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Durability;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Increment;
+import org.apache.hadoop.hbase.client.Mutation;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
+import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
+import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
+import org.apache.hadoop.hbase.filter.BinaryComparator;
+import org.apache.hadoop.hbase.filter.CompareFilter;
+import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
+import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
+import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
+import org.apache.hadoop.hbase.regionserver.Region;
+import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost;
+import org.apache.hadoop.hbase.regionserver.RegionScanner;
+import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost;
+import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
+import org.apache.hadoop.hbase.security.User;
+import org.apache.hadoop.hbase.security.access.Permission.Action;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.hbase.util.TestTableName;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Lists;
+
+@Category(LargeTests.class)
+public class TestWithDisabledAuthorization extends SecureTestUtil {
+ private static final Log LOG = LogFactory.getLog(TestWithDisabledAuthorization.class);
+
+ static {
+ Logger.getLogger(AccessController.class).setLevel(Level.TRACE);
+ Logger.getLogger(AccessControlFilter.class).setLevel(Level.TRACE);
+ Logger.getLogger(TableAuthManager.class).setLevel(Level.TRACE);
+ }
+
+ private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+
+ private static final byte[] TEST_FAMILY = Bytes.toBytes("f1");
+ private static final byte[] TEST_FAMILY2 = Bytes.toBytes("f2");
+ private static final byte[] TEST_ROW = Bytes.toBytes("testrow");
+ private static final byte[] TEST_Q1 = Bytes.toBytes("q1");
+ private static final byte[] TEST_Q2 = Bytes.toBytes("q2");
+ private static final byte[] TEST_Q3 = Bytes.toBytes("q3");
+ private static final byte[] TEST_Q4 = Bytes.toBytes("q4");
+ private static final byte[] ZERO = Bytes.toBytes(0L);
+
+ private static MasterCoprocessorEnvironment CP_ENV;
+ private static AccessController ACCESS_CONTROLLER;
+ private static RegionServerCoprocessorEnvironment RSCP_ENV;
+ private RegionCoprocessorEnvironment RCP_ENV;
+
+ @Rule public TestTableName TEST_TABLE = new TestTableName();
+
+ // default users
+
+ // superuser
+ private static User SUPERUSER;
+ // user granted with all global permission
+ private static User USER_ADMIN;
+ // user with rw permissions on column family.
+ private static User USER_RW;
+ // user with read-only permissions
+ private static User USER_RO;
+ // user is table owner. will have all permissions on table
+ private static User USER_OWNER;
+ // user with create table permissions alone
+ private static User USER_CREATE;
+ // user with no permissions
+ private static User USER_NONE;
+ // user with only partial read-write perms (on family:q1 only)
+ private static User USER_QUAL;
+
+ @BeforeClass
+ public static void setupBeforeClass() throws Exception {
+ Configuration conf = TEST_UTIL.getConfiguration();
+ // Enable security
+ enableSecurity(conf);
+ // We expect 0.98 cell ACL semantics
+ conf.setBoolean(AccessControlConstants.CF_ATTRIBUTE_EARLY_OUT, false);
+ // Enable EXEC permission checking
+ conf.setBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY, true);
+ // Verify enableSecurity sets up what we require
+ verifyConfiguration(conf);
+
+ // Now, DISABLE only active authorization
+ conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false);
+
+ // Start the minicluster
+ TEST_UTIL.startMiniCluster();
+ MasterCoprocessorHost cpHost =
+ TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterCoprocessorHost();
+ cpHost.load(AccessController.class, Coprocessor.PRIORITY_HIGHEST, conf);
+ ACCESS_CONTROLLER = (AccessController) cpHost.findCoprocessor(AccessController.class.getName());
+ CP_ENV = cpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
+ Coprocessor.PRIORITY_HIGHEST, 1, conf);
+ RegionServerCoprocessorHost rsHost = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0)
+ .getRegionServerCoprocessorHost();
+ RSCP_ENV = rsHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
+ Coprocessor.PRIORITY_HIGHEST, 1, conf);
+
+ // Wait for the ACL table to become available
+ TEST_UTIL.waitUntilAllRegionsAssigned(AccessControlLists.ACL_TABLE_NAME);
+
+ // create a set of test users
+ SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
+ USER_ADMIN = User.createUserForTesting(conf, "admin2", new String[0]);
+ USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]);
+ USER_CREATE = User.createUserForTesting(conf, "tbl_create", new String[0]);
+ USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]);
+ USER_RO = User.createUserForTesting(conf, "rouser", new String[0]);
+ USER_QUAL = User.createUserForTesting(conf, "rwpartial", new String[0]);
+ USER_NONE = User.createUserForTesting(conf, "nouser", new String[0]);
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ TEST_UTIL.shutdownMiniCluster();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ // Create the test table (owner added to the _acl_ table)
+ Admin admin = TEST_UTIL.getHBaseAdmin();
+ HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
+ HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY);
+ hcd.setMaxVersions(100);
+ htd.addFamily(hcd);
+ htd.setOwner(USER_OWNER);
+ admin.createTable(htd, new byte[][] { Bytes.toBytes("s") });
+ TEST_UTIL.waitUntilAllRegionsAssigned(TEST_TABLE.getTableName());
+
+ Region region = TEST_UTIL.getHBaseCluster().getRegions(TEST_TABLE.getTableName()).get(0);
+ RegionCoprocessorHost rcpHost = region.getCoprocessorHost();
+ RCP_ENV = rcpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
+ Coprocessor.PRIORITY_HIGHEST, 1, TEST_UTIL.getConfiguration());
+
+ // Set up initial grants
+
+ grantGlobal(TEST_UTIL, USER_ADMIN.getShortName(),
+ Permission.Action.ADMIN,
+ Permission.Action.CREATE,
+ Permission.Action.READ,
+ Permission.Action.WRITE);
+
+ grantOnTable(TEST_UTIL, USER_RW.getShortName(),
+ TEST_TABLE.getTableName(), TEST_FAMILY, null,
+ Permission.Action.READ,
+ Permission.Action.WRITE);
+
+ // USER_CREATE is USER_RW plus CREATE permissions
+ grantOnTable(TEST_UTIL, USER_CREATE.getShortName(),
+ TEST_TABLE.getTableName(), null, null,
+ Permission.Action.CREATE,
+ Permission.Action.READ,
+ Permission.Action.WRITE);
+
+ grantOnTable(TEST_UTIL, USER_RO.getShortName(),
+ TEST_TABLE.getTableName(), TEST_FAMILY, null,
+ Permission.Action.READ);
+
+ grantOnTable(TEST_UTIL, USER_QUAL.getShortName(),
+ TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1,
+ Permission.Action.READ,
+ Permission.Action.WRITE);
+
+ assertEquals(5, AccessControlLists.getTablePermissions(TEST_UTIL.getConfiguration(),
+ TEST_TABLE.getTableName()).size());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ // Clean the _acl_ table
+ try {
+ deleteTable(TEST_UTIL, TEST_TABLE.getTableName());
+ } catch (TableNotFoundException ex) {
+ // Test deleted the table, no problem
+ LOG.info("Test deleted table " + TEST_TABLE.getTableName());
+ }
+ // Verify all table/namespace permissions are erased
+ assertEquals(0, AccessControlLists.getTablePermissions(TEST_UTIL.getConfiguration(),
+ TEST_TABLE.getTableName()).size());
+ assertEquals(0, AccessControlLists.getNamespacePermissions(TEST_UTIL.getConfiguration(),
+ TEST_TABLE.getTableName().getNamespaceAsString()).size());
+ }
+
+ @Test
+ public void testCheckPermissions() throws Exception {
+
+ AccessTestAction checkGlobalAdmin = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkGlobalPerms(TEST_UTIL, Permission.Action.ADMIN);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkGlobalAdmin, SUPERUSER, USER_ADMIN);
+ verifyDenied(checkGlobalAdmin, USER_OWNER, USER_CREATE, USER_RW, USER_RO, USER_QUAL,
+ USER_NONE);
+
+ AccessTestAction checkGlobalRead = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkGlobalPerms(TEST_UTIL, Permission.Action.READ);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkGlobalRead, SUPERUSER, USER_ADMIN);
+ verifyDenied(checkGlobalRead, USER_OWNER, USER_CREATE, USER_RW, USER_RO, USER_QUAL,
+ USER_NONE);
+
+ AccessTestAction checkGlobalReadWrite = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkGlobalPerms(TEST_UTIL, Permission.Action.READ, Permission.Action.WRITE);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkGlobalReadWrite, SUPERUSER, USER_ADMIN);
+ verifyDenied(checkGlobalReadWrite, USER_OWNER, USER_CREATE, USER_RW, USER_RO, USER_QUAL,
+ USER_NONE);
+
+ AccessTestAction checkTableAdmin = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), null, null,
+ Permission.Action.ADMIN);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkTableAdmin, SUPERUSER, USER_ADMIN, USER_OWNER);
+ verifyDenied(checkTableAdmin, USER_CREATE, USER_RW, USER_RO, USER_QUAL, USER_NONE);
+
+ AccessTestAction checkTableCreate = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), null, null,
+ Permission.Action.CREATE);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkTableCreate, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE);
+ verifyDenied(checkTableCreate, USER_RW, USER_RO, USER_QUAL, USER_NONE);
+
+ AccessTestAction checkTableRead = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), null, null,
+ Permission.Action.READ);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkTableRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE);
+ verifyDenied(checkTableRead, USER_RW, USER_RO, USER_QUAL, USER_NONE);
+
+ AccessTestAction checkTableReadWrite = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), null, null,
+ Permission.Action.READ, Permission.Action.WRITE);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkTableReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE);
+ verifyDenied(checkTableReadWrite, USER_RW, USER_RO, USER_QUAL, USER_NONE);
+
+ AccessTestAction checkColumnRead = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), TEST_FAMILY, null,
+ Permission.Action.READ);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkColumnRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW,
+ USER_RO);
+ verifyDenied(checkColumnRead, USER_QUAL, USER_NONE);
+
+ AccessTestAction checkColumnReadWrite = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), TEST_FAMILY, null,
+ Permission.Action.READ, Permission.Action.WRITE);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkColumnReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE,
+ USER_RW);
+ verifyDenied(checkColumnReadWrite, USER_RO, USER_QUAL, USER_NONE);
+
+ AccessTestAction checkQualifierRead = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1,
+ Permission.Action.READ);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkQualifierRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW,
+ USER_RO, USER_QUAL);
+ verifyDenied(checkQualifierRead, USER_NONE);
+
+ AccessTestAction checkQualifierReadWrite = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1,
+ Permission.Action.READ, Permission.Action.WRITE);
+ return null;
+ }
+ };
+
+ verifyAllowed(checkQualifierReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE,
+ USER_RW, USER_QUAL);
+ verifyDenied(checkQualifierReadWrite, USER_RO, USER_NONE);
+
+ AccessTestAction checkMultiQualifierRead = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), new Permission[] {
+ new TablePermission(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1,
+ Permission.Action.READ),
+ new TablePermission(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q2,
+ Permission.Action.READ), });
+ return null;
+ }
+ };
+
+ verifyAllowed(checkMultiQualifierRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE,
+ USER_RW, USER_RO);
+ verifyDenied(checkMultiQualifierRead, USER_QUAL, USER_NONE);
+
+ AccessTestAction checkMultiQualifierReadWrite = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), new Permission[] {
+ new TablePermission(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1,
+ Permission.Action.READ, Permission.Action.WRITE),
+ new TablePermission(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q2,
+ Permission.Action.READ, Permission.Action.WRITE), });
+ return null;
+ }
+ };
+
+ verifyAllowed(checkMultiQualifierReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE,
+ USER_RW);
+ verifyDenied(checkMultiQualifierReadWrite, USER_RO, USER_QUAL, USER_NONE);
+ }
+
+ /** Test grants and revocations with authorization disabled */
+ @Test
+ public void testPassiveGrantRevoke() throws Exception {
+
+ // Add a test user
+
+ User tblUser = User.createUserForTesting(TEST_UTIL.getConfiguration(), "tbluser",
+ new String[0]);
+
+ // If we check now, the test user won't have permissions
+
+ AccessTestAction checkTableRead = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ checkTablePerms(TEST_UTIL, TEST_TABLE.getTableName(), TEST_FAMILY, null,
+ Permission.Action.READ);
+ return null;
+ }
+ };
+
+ verifyDenied(tblUser, checkTableRead);
+
+ // An actual read won't be denied
+
+ AccessTestAction tableRead = new AccessTestAction() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
+ Table t = conn.getTable(TEST_TABLE.getTableName())) {
+ t.get(new Get(TEST_ROW).addFamily(TEST_FAMILY));
+ }
+ return null;
+ }
+ };
+
+ verifyAllowed(tblUser, tableRead);
+
+ // Grant read perms to the test user
+
+ grantOnTable(TEST_UTIL, tblUser.getShortName(), TEST_TABLE.getTableName(), TEST_FAMILY,
+ null, Permission.Action.READ);
+
+ // Now both the permission check and actual op will succeed
+
+ verifyAllowed(tblUser, checkTableRead);
+ verifyAllowed(tblUser, tableRead);
+
+ // Revoke read perms from the test user
+
+ revokeFromTable(TEST_UTIL, tblUser.getShortName(), TEST_TABLE.getTableName(), TEST_FAMILY,
+ null, Permission.Action.READ);
+
+ // Now the permission check will indicate revocation but the actual op will still succeed
+
+ verifyDenied(tblUser, checkTableRead);
+ verifyAllowed(tblUser, tableRead);
+ }
+
+ /** Test master observer */
+ @Test
+ public void testPassiveMasterOperations() throws Exception {
+
+ // preCreateTable
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
+ htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
+ ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd,
+ null);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preModifyTable
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
+ htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
+ htd.addFamily(new HColumnDescriptor(TEST_FAMILY2));
+ ACCESS_CONTROLLER.preModifyTable(ObserverContext.createAndPrepare(CP_ENV, null),
+ TEST_TABLE.getTableName(), htd);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preDeleteTable
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preDeleteTable(ObserverContext.createAndPrepare(CP_ENV, null),
+ TEST_TABLE.getTableName());
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preTruncateTable
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preTruncateTable(ObserverContext.createAndPrepare(CP_ENV, null),
+ TEST_TABLE.getTableName());
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preAddColumn
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY2);
+ ACCESS_CONTROLLER.preAddColumn(ObserverContext.createAndPrepare(CP_ENV, null),
+ TEST_TABLE.getTableName(), hcd);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preModifyColumn
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY2);
+ ACCESS_CONTROLLER.preModifyColumn(ObserverContext.createAndPrepare(CP_ENV, null),
+ TEST_TABLE.getTableName(), hcd);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preDeleteColumn
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preDeleteColumn(ObserverContext.createAndPrepare(CP_ENV, null),
+ TEST_TABLE.getTableName(), TEST_FAMILY2);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preEnableTable
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preEnableTable(ObserverContext.createAndPrepare(CP_ENV, null),
+ TEST_TABLE.getTableName());
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preDisableTable
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preDisableTable(ObserverContext.createAndPrepare(CP_ENV, null),
+ TEST_TABLE.getTableName());
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preMove
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ HRegionInfo region = new HRegionInfo(TEST_TABLE.getTableName());
+ ServerName srcServer = ServerName.valueOf("1.1.1.1", 1, 0);
+ ServerName destServer = ServerName.valueOf("2.2.2.2", 2, 0);
+ ACCESS_CONTROLLER.preMove(ObserverContext.createAndPrepare(CP_ENV, null), region,
+ srcServer, destServer);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preAssign
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ HRegionInfo region = new HRegionInfo(TEST_TABLE.getTableName());
+ ACCESS_CONTROLLER.preAssign(ObserverContext.createAndPrepare(CP_ENV, null), region);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preUnassign
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ HRegionInfo region = new HRegionInfo(TEST_TABLE.getTableName());
+ ACCESS_CONTROLLER.preUnassign(ObserverContext.createAndPrepare(CP_ENV, null), region,
+ true);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preBalance
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preBalance(ObserverContext.createAndPrepare(CP_ENV, null));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preBalanceSwitch
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preBalanceSwitch(ObserverContext.createAndPrepare(CP_ENV, null),
+ true);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preSnapshot
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ SnapshotDescription snapshot = SnapshotDescription.newBuilder()
+ .setName("foo")
+ .build();
+ HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
+ ACCESS_CONTROLLER.preSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
+ snapshot, htd);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preCloneSnapshot
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ SnapshotDescription snapshot = SnapshotDescription.newBuilder()
+ .setName("foo")
+ .build();
+ HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
+ ACCESS_CONTROLLER.preCloneSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
+ snapshot, htd);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preRestoreSnapshot
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ SnapshotDescription snapshot = SnapshotDescription.newBuilder()
+ .setName("foo")
+ .build();
+ HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
+ ACCESS_CONTROLLER.preRestoreSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
+ snapshot, htd);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preDeleteSnapshot
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ SnapshotDescription snapshot = SnapshotDescription.newBuilder()
+ .setName("foo")
+ .build();
+ ACCESS_CONTROLLER.preDeleteSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
+ snapshot);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preGetTableDescriptors
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ List<TableName> tableNamesList = Lists.newArrayList();
+ tableNamesList.add(TEST_TABLE.getTableName());
+ List<HTableDescriptor> descriptors = Lists.newArrayList();
+ ACCESS_CONTROLLER.preGetTableDescriptors(ObserverContext.createAndPrepare(CP_ENV, null),
+ tableNamesList, descriptors, ".+");
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preGetTableNames
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ List<HTableDescriptor> descriptors = Lists.newArrayList();
+ ACCESS_CONTROLLER.preGetTableNames(ObserverContext.createAndPrepare(CP_ENV, null),
+ descriptors, ".+");
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preCreateNamespace
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ NamespaceDescriptor ns = NamespaceDescriptor.create("test").build();
+ ACCESS_CONTROLLER.preCreateNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
+ ns);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preDeleteNamespace
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preDeleteNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
+ "test");
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preModifyNamespace
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ NamespaceDescriptor ns = NamespaceDescriptor.create("test").build();
+ ACCESS_CONTROLLER.preModifyNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
+ ns);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preGetNamespaceDescriptor
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContext.createAndPrepare(CP_ENV,
+ null),
+ "test");
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preListNamespaceDescriptors
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ List<NamespaceDescriptor> descriptors = Lists.newArrayList();
+ ACCESS_CONTROLLER.preListNamespaceDescriptors(ObserverContext.createAndPrepare(CP_ENV,
+ null),
+ descriptors);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ }
+
+ /** Test region server observer */
+ @Test
+ public void testPassiveRegionServerOperations() throws Exception {
+ // preStopRegionServer
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preStopRegionServer(ObserverContext.createAndPrepare(RSCP_ENV, null));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preMerge
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
+ Region region_a = mock(Region.class);
+ when(region_a.getTableDesc()).thenReturn(htd);
+ Region region_b = mock(Region.class);
+ when(region_b.getTableDesc()).thenReturn(htd);
+ ACCESS_CONTROLLER.preMerge(ObserverContext.createAndPrepare(RSCP_ENV, null), region_a,
+ region_b);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preRollWALWriterRequest
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preRollWALWriterRequest(ObserverContext.createAndPrepare(RSCP_ENV,
+ null));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ }
+
+ /** Test region observer */
+ @Test
+ public void testPassiveRegionOperations() throws Exception {
+
+ // preOpen
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preOpen(ObserverContext.createAndPrepare(RCP_ENV, null));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preFlush
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preFlush(ObserverContext.createAndPrepare(RCP_ENV, null));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preSplit
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preSplit(ObserverContext.createAndPrepare(RCP_ENV, null));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preGetClosestRowBefore
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preGetClosestRowBefore(ObserverContext.createAndPrepare(RCP_ENV, null),
+ TEST_ROW, TEST_FAMILY, new Result());
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preGetOp
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ List<Cell> cells = Lists.newArrayList();
+ ACCESS_CONTROLLER.preGetOp(ObserverContext.createAndPrepare(RCP_ENV, null),
+ new Get(TEST_ROW), cells);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preExists
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preExists(ObserverContext.createAndPrepare(RCP_ENV, null),
+ new Get(TEST_ROW), true);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // prePut
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.prePut(ObserverContext.createAndPrepare(RCP_ENV, null),
+ new Put(TEST_ROW), new WALEdit(), Durability.USE_DEFAULT);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preDelete
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preDelete(ObserverContext.createAndPrepare(RCP_ENV, null),
+ new Delete(TEST_ROW), new WALEdit(), Durability.USE_DEFAULT);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preBatchMutate
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preBatchMutate(ObserverContext.createAndPrepare(RCP_ENV, null),
+ new MiniBatchOperationInProgress<Mutation>(null, null, null, 0, 0));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preCheckAndPut
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preCheckAndPut(ObserverContext.createAndPrepare(RCP_ENV, null),
+ TEST_ROW, TEST_FAMILY, TEST_Q1, CompareFilter.CompareOp.EQUAL,
+ new BinaryComparator("foo".getBytes()), new Put(TEST_ROW), true);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preCheckAndDelete
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preCheckAndDelete(ObserverContext.createAndPrepare(RCP_ENV, null),
+ TEST_ROW, TEST_FAMILY, TEST_Q1, CompareFilter.CompareOp.EQUAL,
+ new BinaryComparator("foo".getBytes()), new Delete(TEST_ROW), true);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preAppend
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preAppend(ObserverContext.createAndPrepare(RCP_ENV, null),
+ new Append(TEST_ROW));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preIncrement
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preIncrement(ObserverContext.createAndPrepare(RCP_ENV, null),
+ new Increment(TEST_ROW));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preScannerOpen
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ ACCESS_CONTROLLER.preScannerOpen(ObserverContext.createAndPrepare(RCP_ENV, null),
+ new Scan(), mock(RegionScanner.class));
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ // preBulkLoadHFile
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ List<Pair<byte[], String>> paths = Lists.newArrayList();
+ ACCESS_CONTROLLER.preBulkLoadHFile(ObserverContext.createAndPrepare(RCP_ENV, null),
+ paths);
+ return null;
+ }
+ }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
+
+ }
+
+ @Test
+ public void testPassiveCellPermissions() throws Exception {
+ final Configuration conf = TEST_UTIL.getConfiguration();
+
+ // store two sets of values, one store with a cell level ACL, and one without
+ verifyAllowed(new AccessTestAction() {
+ @Override
+ public Object run() throws Exception {
+ try(Connection connection = ConnectionFactory.createConnection(conf);
+ Table t = connection.getTable(TEST_TABLE.getTableName())) {
+ Put p;
+ // with ro ACL
+ p = new Put(TEST_ROW).add(TEST_FAMILY, TEST_Q1, ZERO);
+ p.setACL(USER_NONE.getShortName(), new Permission(Action.READ));
+ t.put(p);
+ // with rw ACL
+ p = new Put(TEST_ROW).add(TEST_FAMILY, TEST_Q2, ZERO);
+ p.setACL(USER_NONE.getShortName(), new Permission(Action.READ, Action.WRITE));
+ t.put(p);
+ // no ACL
+ p = new Put(TEST_ROW)
+ .add(TEST_FAMILY, TEST_Q3, ZERO)
+ .add(TEST_FAMILY, TEST_Q4, ZERO);
+ t.put(p);
+ }
+ return null;
+ }
+ }, USER_OWNER);
+
+ // check that a scan over the test data returns the expected number of KVs
+
+ final List<Cell> scanResults = Lists.newArrayList();
+
+ AccessTestAction scanAction = new AccessTestAction() {
+ @Override
+ public List<Cell> run() throws Exception {
+ Scan scan = new Scan();
+ scan.setStartRow(TEST_ROW);
+ scan.setStopRow(Bytes.add(TEST_ROW, new byte[]{ 0 } ));
+ scan.addFamily(TEST_FAMILY);
+ Connection connection = ConnectionFactory.createConnection(conf);
+ Table t = connection.getTable(TEST_TABLE.getTableName());
+ try {
+ ResultScanner scanner = t.getScanner(scan);
+ Result result = null;
+ do {
+ result = scanner.next();
+ if (result != null) {
+ scanResults.addAll(result.listCells());
+ }
+ } while (result != null);
+ } finally {
+ t.close();
+ connection.close();
+ }
+ return scanResults;
+ }
+ };
+
+ // owner will see all values
+ scanResults.clear();
+ verifyAllowed(scanAction, USER_OWNER);
+ assertEquals(4, scanResults.size());
+
+ // other user will also see 4 values
+ // if cell filtering was active, we would only see 2 values
+ scanResults.clear();
+ verifyAllowed(scanAction, USER_NONE);
+ assertEquals(4, scanResults.size());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/356422e1/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestWithDisabledAuthorization.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestWithDisabledAuthorization.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestWithDisabledAuthorization.java
new file mode 100644
index 0000000..aef6088
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestWithDisabledAuthorization.java
@@ -0,0 +1,236 @@
+/**
+ * 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.hbase.security.visibility;
+
+import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_NAME;
+import static org.junit.Assert.*;
+
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
+import org.apache.hadoop.hbase.security.User;
+import org.apache.hadoop.hbase.security.access.SecureTestUtil;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+import com.google.protobuf.ByteString;
+
+@Category(LargeTests.class)
+public class TestWithDisabledAuthorization {
+
+ private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+
+ private static final String CONFIDENTIAL = "confidential";
+ private static final String SECRET = "secret";
+ private static final String PRIVATE = "private";
+ private static final byte[] TEST_FAMILY = Bytes.toBytes("test");
+ private static final byte[] TEST_QUALIFIER = Bytes.toBytes("q");
+ private static final byte[] ZERO = Bytes.toBytes(0L);
+
+
+ @Rule
+ public final TestName TEST_NAME = new TestName();
+
+ private static User SUPERUSER;
+ private static User USER_RW;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ Configuration conf = TEST_UTIL.getConfiguration();
+
+ // Set up superuser
+ SecureTestUtil.configureSuperuser(conf);
+
+ // Install the VisibilityController as a system processor
+ VisibilityTestUtil.enableVisiblityLabels(conf);
+
+ // Now, DISABLE active authorization
+ conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false);
+
+ TEST_UTIL.startMiniCluster();
+
+ // Wait for the labels table to become available
+ TEST_UTIL.waitUntilAllRegionsAssigned(LABELS_TABLE_NAME);
+
+ // create a set of test users
+ SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
+ USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]);
+
+ // Define test labels
+ SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws Exception {
+ try {
+ VisibilityClient.addLabels(TEST_UTIL.getConfiguration(),
+ new String[] { SECRET, CONFIDENTIAL, PRIVATE });
+ VisibilityClient.setAuths(TEST_UTIL.getConfiguration(),
+ new String[] { SECRET, CONFIDENTIAL },
+ USER_RW.getShortName());
+ } catch (Throwable t) {
+ fail("Should not have failed");
+ }
+ return null;
+ }
+ });
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ TEST_UTIL.shutdownMiniCluster();
+ }
+
+ @Test
+ public void testManageUserAuths() throws Throwable {
+ // Even though authorization is disabled, we should be able to manage user auths
+
+ SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws Exception {
+ try {
+ VisibilityClient.setAuths(TEST_UTIL.getConfiguration(),
+ new String[] { SECRET, CONFIDENTIAL },
+ USER_RW.getShortName());
+ } catch (Throwable t) {
+ fail("Should not have failed");
+ }
+ return null;
+ }
+ });
+
+ PrivilegedExceptionAction<List<String>> getAuths =
+ new PrivilegedExceptionAction<List<String>>() {
+ public List<String> run() throws Exception {
+ GetAuthsResponse authsResponse = null;
+ try {
+ authsResponse = VisibilityClient.getAuths(TEST_UTIL.getConfiguration(),
+ USER_RW.getShortName());
+ } catch (Throwable t) {
+ fail("Should not have failed");
+ }
+ List<String> authsList = new ArrayList<String>();
+ for (ByteString authBS : authsResponse.getAuthList()) {
+ authsList.add(Bytes.toString(authBS.toByteArray()));
+ }
+ return authsList;
+ }
+ };
+
+ List<String> authsList = SUPERUSER.runAs(getAuths);
+ assertEquals(2, authsList.size());
+ assertTrue(authsList.contains(SECRET));
+ assertTrue(authsList.contains(CONFIDENTIAL));
+
+ SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws Exception {
+ try {
+ VisibilityClient.clearAuths(TEST_UTIL.getConfiguration(),
+ new String[] { SECRET },
+ USER_RW.getShortName());
+ } catch (Throwable t) {
+ fail("Should not have failed");
+ }
+ return null;
+ }
+ });
+
+ authsList = SUPERUSER.runAs(getAuths);
+ assertEquals(1, authsList.size());
+ assertTrue(authsList.contains(CONFIDENTIAL));
+
+ SUPERUSER.runAs(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws Exception {
+ try {
+ VisibilityClient.clearAuths(TEST_UTIL.getConfiguration(),
+ new String[] { CONFIDENTIAL },
+ USER_RW.getShortName());
+ } catch (Throwable t) {
+ fail("Should not have failed");
+ }
+ return null;
+ }
+ });
+
+ authsList = SUPERUSER.runAs(getAuths);
+ assertEquals(0, authsList.size());
+ }
+
+ @Test
+ public void testPassiveVisibility() throws Exception {
+ // No values should be filtered regardless of authorization if we are passive
+ try (Table t = createTableAndWriteDataWithLabels(
+ TableName.valueOf(TEST_NAME.getMethodName()),
+ SECRET,
+ PRIVATE,
+ SECRET + "|" + CONFIDENTIAL,
+ PRIVATE + "|" + CONFIDENTIAL)) {
+ Scan s = new Scan();
+ s.setAuthorizations(new Authorizations());
+ try (ResultScanner scanner = t.getScanner(s)) {
+ Result[] next = scanner.next(10);
+ assertEquals(next.length, 4);
+ }
+ s = new Scan();
+ s.setAuthorizations(new Authorizations(SECRET));
+ try (ResultScanner scanner = t.getScanner(s)) {
+ Result[] next = scanner.next(10);
+ assertEquals(next.length, 4);
+ }
+ s = new Scan();
+ s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL));
+ try (ResultScanner scanner = t.getScanner(s)) {
+ Result[] next = scanner.next(10);
+ assertEquals(next.length, 4);
+ }
+ s = new Scan();
+ s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL, PRIVATE));
+ try (ResultScanner scanner = t.getScanner(s)) {
+ Result[] next = scanner.next(10);
+ assertEquals(next.length, 4);
+ }
+ }
+ }
+
+ static Table createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)
+ throws Exception {
+ List<Put> puts = new ArrayList<Put>();
+ for (int i = 0; i < labelExps.length; i++) {
+ Put put = new Put(Bytes.toBytes("row" + (i+1)));
+ put.addColumn(TEST_FAMILY, TEST_QUALIFIER, HConstants.LATEST_TIMESTAMP, ZERO);
+ put.setCellVisibility(new CellVisibility(labelExps[i]));
+ puts.add(put);
+ }
+ Table table = TEST_UTIL.createTable(tableName, TEST_FAMILY);
+ table.put(puts);
+ return table;
+ }
+}