From 6e3701fcad82d3f6081cf5dd50599305ec590a72 Mon Sep 17 00:00:00 2001 From: Ashish Singhi Date: Sat, 14 Mar 2015 22:23:51 +0530 Subject: [PATCH] HBASE-13241 Add tests for group level grants --- .../access/TestAccessControllerWithGroups.java | 220 +++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessControllerWithGroups.java diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessControllerWithGroups.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessControllerWithGroups.java new file mode 100644 index 0000000..081f03f --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessControllerWithGroups.java @@ -0,0 +1,220 @@ +/* + * 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.assertEquals; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.TableNotFoundException; +import org.apache.hadoop.hbase.client.Connection; +import org.apache.hadoop.hbase.client.ConnectionFactory; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Table; +import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; +import org.apache.hadoop.hbase.protobuf.ProtobufUtil; +import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService; +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.testclassification.SecurityTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.google.protobuf.BlockingRpcChannel; + +@Category({ SecurityTests.class, LargeTests.class }) +public class TestAccessControllerWithGroups extends SecureTestUtil { + private static final Log LOG = LogFactory.getLog(TestAccessControllerWithGroups.class); + + public TableName TEST_TABLE = TableName.valueOf("testtable1"); + private static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private static Configuration conf; + private static Connection connection; + + private static byte[] TEST_FAMILY = Bytes.toBytes("f1"); + private static byte[] TEST_ROW = Bytes.toBytes("r1"); + private final static byte[] Q1 = Bytes.toBytes("q1"); + private final static byte[] value1 = Bytes.toBytes("value1"); + + private static final String SUPERGROUP = "supergroup"; + private static final String TESTGROUP_TABLE = "testgroup_table"; + private static final String TESTGROUP_FAMILY = "testgroup_family"; + private static final String TESTGROUP_QUAIFIER = "testgroup_qualifier"; + + private static User SUPERUSER; + private static User USER1_TESTGROUP_QUALIFIER; + private static User USER2_TESTGROUP_QUALIFIER; + private static User USER1_TESTGROUP_TABLE; + private static User USER2_TESTGROUP_TABLE; + private static User USER1_TESTGROUP_FAMILY; + private static User USER2_TESTGROUP_FAMILY; + + @BeforeClass + public static void setupBeforeClass() throws Exception { + // setup configuration + conf = TEST_UTIL.getConfiguration(); + // Enable security + enableSecurity(conf); + // In this particular test case, we can't use SecureBulkLoadEndpoint because its doAs will fail + // to move a file for a random user + conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, AccessController.class.getName()); + + // Enable EXEC permission checking + conf.setBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY, true); + + // Verify enableSecurity sets up what we require + verifyConfiguration(conf); + + TEST_UTIL.startMiniCluster(); + + TEST_UTIL.waitUntilAllRegionsAssigned(AccessControlLists.ACL_TABLE_NAME); + + // 'admin' has super user permission because it is part of the 'supergroup' + SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { SUPERGROUP }); + + USER1_TESTGROUP_TABLE = + User.createUserForTesting(conf, "test_table1", new String[] { TESTGROUP_TABLE }); + USER2_TESTGROUP_TABLE = + User.createUserForTesting(conf, "test_table2", new String[] { TESTGROUP_TABLE }); + + USER1_TESTGROUP_FAMILY = + User.createUserForTesting(conf, "test_family1", new String[] { TESTGROUP_FAMILY }); + USER2_TESTGROUP_FAMILY = + User.createUserForTesting(conf, "test_family2", new String[] { TESTGROUP_FAMILY }); + + USER1_TESTGROUP_QUALIFIER = + User.createUserForTesting(conf, "test_qualifier1", new String[] { TESTGROUP_QUAIFIER }); + USER2_TESTGROUP_QUALIFIER = + User.createUserForTesting(conf, "test_qualifier2", new String[] { TESTGROUP_QUAIFIER }); + + connection = ConnectionFactory.createConnection(conf); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + connection.close(); + TEST_UTIL.shutdownMiniCluster(); + } + + @Before + public void setUp() throws Exception { + try (Table table = TEST_UTIL.createTable(TEST_TABLE, TEST_FAMILY)) { + TEST_UTIL.waitTableEnabled(TEST_TABLE); + Put put = new Put(TEST_ROW); + put.addColumn(TEST_FAMILY, Q1, value1); + table.put(put); + } + // Set up initial grants + grantGlobal(TEST_UTIL, '@' + SUPERGROUP, Permission.Action.ADMIN, Permission.Action.CREATE, + Permission.Action.READ, Permission.Action.WRITE); + + assertEquals(1, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size()); + try { + assertEquals(1, AccessControlClient.getUserPermissions(connection, TEST_TABLE.toString()) + .size()); + } catch (Throwable e) { + LOG.error("Error during call of AccessControlClient.getUserPermissions. ", e); + } + } + + @After + public void tearDown() throws Exception { + // Clean the _acl_ table + try { + deleteTable(TEST_UTIL, TEST_TABLE); + } catch (TableNotFoundException ex) { + // Test deleted the table, no problem + LOG.info("Test deleted table " + TEST_TABLE); + } + // Verify all table/namespace permissions are erased + assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size()); + assertEquals(0, AccessControlLists.getNamespacePermissions(conf, TEST_TABLE.getNameAsString()) + .size()); + } + + /* + * Test group level grants at table, family and column qualifier level. + */ + @Test + public void testGrant() throws Exception { + AccessTestAction grantActionAtTableLevel = new AccessTestAction() { + @Override + public Object run() throws Exception { + // Connection connection = ConnectionFactory.createConnection(conf); + Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME); + try { + BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName()); + AccessControlService.BlockingInterface protocol = + AccessControlService.newBlockingStub(service); + ProtobufUtil.grant(protocol, '@' + TESTGROUP_TABLE, TEST_TABLE, null, null, Action.ADMIN); + } finally { + acl.close(); + } + return null; + } + }; + + AccessTestAction grantActionAtFamilyLevel = new AccessTestAction() { + @Override + public Object run() throws Exception { + Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME); + try { + BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName()); + AccessControlService.BlockingInterface protocol = + AccessControlService.newBlockingStub(service); + ProtobufUtil.grant(protocol, '@' + TESTGROUP_FAMILY, TEST_TABLE, TEST_FAMILY, null, + Action.ADMIN); + } finally { + acl.close(); + } + return null; + } + }; + + AccessTestAction grantActionAtQualifierLevel = new AccessTestAction() { + @Override + public Object run() throws Exception { + Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME); + try { + BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName()); + AccessControlService.BlockingInterface protocol = + AccessControlService.newBlockingStub(service); + ProtobufUtil.grant(protocol, '@' + TESTGROUP_QUAIFIER, TEST_TABLE, TEST_FAMILY, Q1, + Action.ADMIN); + } finally { + acl.close(); + } + return null; + } + }; + + verifyAllowed(grantActionAtTableLevel, SUPERUSER, USER1_TESTGROUP_TABLE, USER2_TESTGROUP_TABLE); + verifyDenied(grantActionAtTableLevel, USER1_TESTGROUP_FAMILY, USER2_TESTGROUP_FAMILY, + USER1_TESTGROUP_QUALIFIER, USER2_TESTGROUP_QUALIFIER); + + verifyAllowed(grantActionAtFamilyLevel, SUPERUSER, USER1_TESTGROUP_TABLE, + USER2_TESTGROUP_TABLE, USER1_TESTGROUP_FAMILY, USER2_TESTGROUP_FAMILY); + verifyDenied(grantActionAtFamilyLevel, USER1_TESTGROUP_QUALIFIER, USER2_TESTGROUP_QUALIFIER); + + verifyAllowed(grantActionAtQualifierLevel, SUPERUSER, USER1_TESTGROUP_TABLE, + USER2_TESTGROUP_TABLE, USER1_TESTGROUP_FAMILY, USER2_TESTGROUP_FAMILY, + USER1_TESTGROUP_QUALIFIER, USER2_TESTGROUP_QUALIFIER); + } +} -- 1.9.5.msysgit.0