001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.security.access; 019 020import static org.apache.hadoop.hbase.AuthUtil.toGroupEntry; 021import static org.junit.Assert.assertArrayEquals; 022import static org.junit.Assert.assertEquals; 023import static org.junit.Assert.assertFalse; 024import static org.junit.Assert.assertNotNull; 025import static org.junit.Assert.assertTrue; 026import static org.junit.Assert.fail; 027 028import com.google.protobuf.BlockingRpcChannel; 029import com.google.protobuf.RpcCallback; 030import com.google.protobuf.RpcController; 031import com.google.protobuf.Service; 032import com.google.protobuf.ServiceException; 033import java.io.IOException; 034import java.security.PrivilegedAction; 035import java.util.ArrayList; 036import java.util.Arrays; 037import java.util.Collection; 038import java.util.Collections; 039import java.util.List; 040import org.apache.hadoop.conf.Configuration; 041import org.apache.hadoop.fs.CommonConfigurationKeys; 042import org.apache.hadoop.fs.FileStatus; 043import org.apache.hadoop.fs.FileSystem; 044import org.apache.hadoop.fs.Path; 045import org.apache.hadoop.fs.permission.FsPermission; 046import org.apache.hadoop.hbase.Coprocessor; 047import org.apache.hadoop.hbase.CoprocessorEnvironment; 048import org.apache.hadoop.hbase.HBaseClassTestRule; 049import org.apache.hadoop.hbase.HBaseIOException; 050import org.apache.hadoop.hbase.HBaseTestingUtility; 051import org.apache.hadoop.hbase.HColumnDescriptor; 052import org.apache.hadoop.hbase.HConstants; 053import org.apache.hadoop.hbase.HRegionInfo; 054import org.apache.hadoop.hbase.HRegionLocation; 055import org.apache.hadoop.hbase.HTableDescriptor; 056import org.apache.hadoop.hbase.KeyValue; 057import org.apache.hadoop.hbase.MiniHBaseCluster; 058import org.apache.hadoop.hbase.NamespaceDescriptor; 059import org.apache.hadoop.hbase.ServerName; 060import org.apache.hadoop.hbase.TableName; 061import org.apache.hadoop.hbase.TableNotFoundException; 062import org.apache.hadoop.hbase.client.Admin; 063import org.apache.hadoop.hbase.client.Append; 064import org.apache.hadoop.hbase.client.Connection; 065import org.apache.hadoop.hbase.client.ConnectionFactory; 066import org.apache.hadoop.hbase.client.Delete; 067import org.apache.hadoop.hbase.client.Get; 068import org.apache.hadoop.hbase.client.Increment; 069import org.apache.hadoop.hbase.client.MasterSwitchType; 070import org.apache.hadoop.hbase.client.Put; 071import org.apache.hadoop.hbase.client.RegionLocator; 072import org.apache.hadoop.hbase.client.Result; 073import org.apache.hadoop.hbase.client.ResultScanner; 074import org.apache.hadoop.hbase.client.Scan; 075import org.apache.hadoop.hbase.client.SnapshotDescription; 076import org.apache.hadoop.hbase.client.Table; 077import org.apache.hadoop.hbase.client.security.SecurityCapability; 078import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; 079import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; 080import org.apache.hadoop.hbase.coprocessor.ObserverContextImpl; 081import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor; 082import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; 083import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment; 084import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.CountRequest; 085import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.CountResponse; 086import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.HelloRequest; 087import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.HelloResponse; 088import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.IncrementCountRequest; 089import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.IncrementCountResponse; 090import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.NoopRequest; 091import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.NoopResponse; 092import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingRequest; 093import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingResponse; 094import org.apache.hadoop.hbase.coprocessor.protobuf.generated.PingProtos.PingService; 095import org.apache.hadoop.hbase.exceptions.HBaseException; 096import org.apache.hadoop.hbase.io.hfile.CacheConfig; 097import org.apache.hadoop.hbase.io.hfile.HFile; 098import org.apache.hadoop.hbase.io.hfile.HFileContext; 099import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder; 100import org.apache.hadoop.hbase.master.HMaster; 101import org.apache.hadoop.hbase.master.MasterCoprocessorHost; 102import org.apache.hadoop.hbase.master.locking.LockProcedure; 103import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; 104import org.apache.hadoop.hbase.master.procedure.TableProcedureInterface; 105import org.apache.hadoop.hbase.procedure2.LockType; 106import org.apache.hadoop.hbase.procedure2.Procedure; 107import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; 108import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; 109import org.apache.hadoop.hbase.procedure2.ProcedureYieldException; 110import org.apache.hadoop.hbase.protobuf.ProtobufUtil; 111import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos; 112import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService; 113import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.CheckPermissionsRequest; 114import org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker; 115import org.apache.hadoop.hbase.regionserver.HRegion; 116import org.apache.hadoop.hbase.regionserver.HRegionServer; 117import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost; 118import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost; 119import org.apache.hadoop.hbase.regionserver.ScanType; 120import org.apache.hadoop.hbase.replication.ReplicationPeerConfig; 121import org.apache.hadoop.hbase.security.Superusers; 122import org.apache.hadoop.hbase.security.User; 123import org.apache.hadoop.hbase.security.access.Permission.Action; 124import org.apache.hadoop.hbase.testclassification.LargeTests; 125import org.apache.hadoop.hbase.testclassification.SecurityTests; 126import org.apache.hadoop.hbase.tool.LoadIncrementalHFiles; 127import org.apache.hadoop.hbase.util.Bytes; 128import org.apache.hadoop.hbase.util.JVMClusterUtil; 129import org.apache.hadoop.hbase.util.Threads; 130import org.apache.hadoop.security.GroupMappingServiceProvider; 131import org.apache.hadoop.security.ShellBasedUnixGroupsMapping; 132import org.apache.hadoop.security.UserGroupInformation; 133import org.junit.AfterClass; 134import org.junit.BeforeClass; 135import org.junit.ClassRule; 136import org.junit.Rule; 137import org.junit.Test; 138import org.junit.experimental.categories.Category; 139import org.junit.rules.TestName; 140import org.slf4j.Logger; 141import org.slf4j.LoggerFactory; 142 143import org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProcedureProtos; 144import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState; 145 146/** 147 * Performs authorization checks for common operations, according to different 148 * levels of authorized users. 149 */ 150@Category({SecurityTests.class, LargeTests.class}) 151public class TestAccessController extends SecureTestUtil { 152 153 @ClassRule 154 public static final HBaseClassTestRule CLASS_RULE = 155 HBaseClassTestRule.forClass(TestAccessController.class); 156 157 private static final FsPermission FS_PERMISSION_ALL = FsPermission.valueOf("-rwxrwxrwx"); 158 private static final Logger LOG = LoggerFactory.getLogger(TestAccessController.class); 159 private static TableName TEST_TABLE = TableName.valueOf("testtable1"); 160 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 161 private static Configuration conf; 162 163 /** The systemUserConnection created here is tied to the system user. In case, you are planning 164 * to create AccessTestAction, DON'T use this systemUserConnection as the 'doAs' user 165 * gets eclipsed by the system user. */ 166 private static Connection systemUserConnection; 167 168 169 // user with all permissions 170 private static User SUPERUSER; 171 // user granted with all global permission 172 private static User USER_ADMIN; 173 // user with rw permissions on column family. 174 private static User USER_RW; 175 // user with read-only permissions 176 private static User USER_RO; 177 // user is table owner. will have all permissions on table 178 private static User USER_OWNER; 179 // user with create table permissions alone 180 private static User USER_CREATE; 181 // user with no permissions 182 private static User USER_NONE; 183 // user with admin rights on the column family 184 private static User USER_ADMIN_CF; 185 186 private static final String GROUP_ADMIN = "group_admin"; 187 private static final String GROUP_CREATE = "group_create"; 188 private static final String GROUP_READ = "group_read"; 189 private static final String GROUP_WRITE = "group_write"; 190 191 private static User USER_GROUP_ADMIN; 192 private static User USER_GROUP_CREATE; 193 private static User USER_GROUP_READ; 194 private static User USER_GROUP_WRITE; 195 196 // TODO: convert this test to cover the full matrix in 197 // https://hbase.apache.org/book/appendix_acl_matrix.html 198 // creating all Scope x Permission combinations 199 200 private static TableName TEST_TABLE2 = TableName.valueOf("testtable2"); 201 private static byte[] TEST_FAMILY = Bytes.toBytes("f1"); 202 private static byte[] TEST_QUALIFIER = Bytes.toBytes("q1"); 203 private static byte[] TEST_ROW = Bytes.toBytes("r1"); 204 205 private static MasterCoprocessorEnvironment CP_ENV; 206 private static AccessController ACCESS_CONTROLLER; 207 private static RegionServerCoprocessorEnvironment RSCP_ENV; 208 private static RegionCoprocessorEnvironment RCP_ENV; 209 210 @Rule 211 public TestName name = new TestName(); 212 213 @BeforeClass 214 public static void setupBeforeClass() throws Exception { 215 // setup configuration 216 conf = TEST_UTIL.getConfiguration(); 217 // Up the handlers; this test needs more than usual. 218 conf.setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10); 219 220 conf.set(CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING, 221 MyShellBasedUnixGroupsMapping.class.getName()); 222 UserGroupInformation.setConfiguration(conf); 223 224 // Enable security 225 enableSecurity(conf); 226 // In this particular test case, we can't use SecureBulkLoadEndpoint because its doAs will fail 227 // to move a file for a random user 228 conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, AccessController.class.getName()); 229 // Verify enableSecurity sets up what we require 230 verifyConfiguration(conf); 231 232 // Enable EXEC permission checking 233 conf.setBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY, true); 234 235 TEST_UTIL.startMiniCluster(); 236 MasterCoprocessorHost masterCpHost = 237 TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterCoprocessorHost(); 238 masterCpHost.load(AccessController.class, Coprocessor.PRIORITY_HIGHEST, conf); 239 ACCESS_CONTROLLER = masterCpHost.findCoprocessor(AccessController.class); 240 CP_ENV = masterCpHost.createEnvironment( 241 ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 242 RegionServerCoprocessorHost rsCpHost = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0) 243 .getRegionServerCoprocessorHost(); 244 RSCP_ENV = rsCpHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 245 246 // Wait for the ACL table to become available 247 TEST_UTIL.waitUntilAllRegionsAssigned(AccessControlLists.ACL_TABLE_NAME); 248 249 // create a set of test users 250 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" }); 251 USER_ADMIN = User.createUserForTesting(conf, "admin2", new String[0]); 252 USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]); 253 USER_RO = User.createUserForTesting(conf, "rouser", new String[0]); 254 USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]); 255 USER_CREATE = User.createUserForTesting(conf, "tbl_create", new String[0]); 256 USER_NONE = User.createUserForTesting(conf, "nouser", new String[0]); 257 USER_ADMIN_CF = User.createUserForTesting(conf, "col_family_admin", new String[0]); 258 259 USER_GROUP_ADMIN = 260 User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN }); 261 USER_GROUP_CREATE = 262 User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE }); 263 USER_GROUP_READ = 264 User.createUserForTesting(conf, "user_group_read", new String[] { GROUP_READ }); 265 USER_GROUP_WRITE = 266 User.createUserForTesting(conf, "user_group_write", new String[] { GROUP_WRITE }); 267 268 systemUserConnection = TEST_UTIL.getConnection(); 269 setUpTableAndUserPermissions(); 270 } 271 272 @AfterClass 273 public static void tearDownAfterClass() throws Exception { 274 cleanUp(); 275 TEST_UTIL.shutdownMiniCluster(); 276 int total = AuthManager.getTotalRefCount(); 277 assertTrue("Unexpected reference count: " + total, total == 0); 278 } 279 280 private static void setUpTableAndUserPermissions() throws Exception { 281 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE); 282 HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY); 283 hcd.setMaxVersions(100); 284 htd.addFamily(hcd); 285 htd.setOwner(USER_OWNER); 286 createTable(TEST_UTIL, htd, new byte[][] { Bytes.toBytes("s") }); 287 288 HRegion region = TEST_UTIL.getHBaseCluster().getRegions(TEST_TABLE).get(0); 289 RegionCoprocessorHost rcpHost = region.getCoprocessorHost(); 290 RCP_ENV = rcpHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 291 292 // Set up initial grants 293 294 grantGlobal(TEST_UTIL, USER_ADMIN.getShortName(), 295 Permission.Action.ADMIN, 296 Permission.Action.CREATE, 297 Permission.Action.READ, 298 Permission.Action.WRITE); 299 300 grantOnTable(TEST_UTIL, USER_RW.getShortName(), 301 TEST_TABLE, TEST_FAMILY, null, 302 Permission.Action.READ, 303 Permission.Action.WRITE); 304 305 // USER_CREATE is USER_RW plus CREATE permissions 306 grantOnTable(TEST_UTIL, USER_CREATE.getShortName(), 307 TEST_TABLE, null, null, 308 Permission.Action.CREATE, 309 Permission.Action.READ, 310 Permission.Action.WRITE); 311 312 grantOnTable(TEST_UTIL, USER_RO.getShortName(), 313 TEST_TABLE, TEST_FAMILY, null, 314 Permission.Action.READ); 315 316 grantOnTable(TEST_UTIL, USER_ADMIN_CF.getShortName(), 317 TEST_TABLE, TEST_FAMILY, 318 null, Permission.Action.ADMIN, Permission.Action.CREATE); 319 320 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN); 321 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE); 322 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ); 323 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE); 324 325 assertEquals(5, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size()); 326 int size = 0; 327 try { 328 size = AccessControlClient.getUserPermissions(systemUserConnection, TEST_TABLE.toString()) 329 .size(); 330 } catch (Throwable e) { 331 LOG.error("error during call of AccessControlClient.getUserPermissions. ", e); 332 fail("error during call of AccessControlClient.getUserPermissions."); 333 } 334 assertEquals(5, size); 335 } 336 337 private static void cleanUp() throws Exception { 338 // Clean the _acl_ table 339 try { 340 deleteTable(TEST_UTIL, TEST_TABLE); 341 } catch (TableNotFoundException ex) { 342 // Test deleted the table, no problem 343 LOG.info("Test deleted table " + TEST_TABLE); 344 } 345 // Verify all table/namespace permissions are erased 346 assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size()); 347 assertEquals( 348 0, 349 AccessControlLists.getNamespacePermissions(conf, 350 TEST_TABLE.getNamespaceAsString()).size()); 351 } 352 353 @Test 354 public void testUnauthorizedShutdown() throws Exception { 355 AccessTestAction action = new AccessTestAction() { 356 @Override public Object run() throws Exception { 357 HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); 358 master.shutdown(); 359 return null; 360 } 361 }; 362 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 363 USER_GROUP_WRITE, USER_GROUP_CREATE); 364 } 365 366 @Test 367 public void testUnauthorizedStopMaster() throws Exception { 368 AccessTestAction action = new AccessTestAction() { 369 @Override public Object run() throws Exception { 370 HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); 371 master.stopMaster(); 372 return null; 373 } 374 }; 375 376 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 377 USER_GROUP_WRITE, USER_GROUP_CREATE); 378 } 379 380 @Test 381 public void testSecurityCapabilities() throws Exception { 382 List<SecurityCapability> capabilities = TEST_UTIL.getConnection().getAdmin() 383 .getSecurityCapabilities(); 384 assertTrue("AUTHORIZATION capability is missing", 385 capabilities.contains(SecurityCapability.AUTHORIZATION)); 386 assertTrue("CELL_AUTHORIZATION capability is missing", 387 capabilities.contains(SecurityCapability.CELL_AUTHORIZATION)); 388 } 389 390 @Test 391 public void testTableCreate() throws Exception { 392 AccessTestAction createTable = new AccessTestAction() { 393 @Override 394 public Object run() throws Exception { 395 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName())); 396 htd.addFamily(new HColumnDescriptor(TEST_FAMILY)); 397 ACCESS_CONTROLLER.preCreateTable(ObserverContextImpl.createAndPrepare(CP_ENV), htd, null); 398 return null; 399 } 400 }; 401 402 // verify that superuser can create tables 403 verifyAllowed(createTable, SUPERUSER, USER_ADMIN, USER_GROUP_CREATE); 404 405 // all others should be denied 406 verifyDenied(createTable, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_ADMIN, 407 USER_GROUP_READ, USER_GROUP_WRITE); 408 } 409 410 @Test 411 public void testTableModify() throws Exception { 412 AccessTestAction modifyTable = new AccessTestAction() { 413 @Override 414 public Object run() throws Exception { 415 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE); 416 htd.addFamily(new HColumnDescriptor(TEST_FAMILY)); 417 htd.addFamily(new HColumnDescriptor("fam_" + User.getCurrent().getShortName())); 418 ACCESS_CONTROLLER.preModifyTable(ObserverContextImpl.createAndPrepare(CP_ENV), TEST_TABLE, 419 null, htd); 420 return null; 421 } 422 }; 423 424 verifyAllowed(modifyTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_GROUP_CREATE, 425 USER_GROUP_ADMIN); 426 verifyDenied(modifyTable, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); 427 } 428 429 @Test 430 public void testTableDelete() throws Exception { 431 AccessTestAction deleteTable = new AccessTestAction() { 432 @Override 433 public Object run() throws Exception { 434 ACCESS_CONTROLLER 435 .preDeleteTable(ObserverContextImpl.createAndPrepare(CP_ENV), TEST_TABLE); 436 return null; 437 } 438 }; 439 440 verifyAllowed(deleteTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_GROUP_CREATE, 441 USER_GROUP_ADMIN); 442 verifyDenied(deleteTable, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); 443 } 444 445 @Test 446 public void testTableTruncate() throws Exception { 447 AccessTestAction truncateTable = new AccessTestAction() { 448 @Override 449 public Object run() throws Exception { 450 ACCESS_CONTROLLER 451 .preTruncateTable(ObserverContextImpl.createAndPrepare(CP_ENV), 452 TEST_TABLE); 453 return null; 454 } 455 }; 456 457 verifyAllowed(truncateTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_GROUP_CREATE, 458 USER_GROUP_ADMIN); 459 verifyDenied(truncateTable, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); 460 } 461 462 @Test 463 public void testTableDisable() throws Exception { 464 AccessTestAction disableTable = new AccessTestAction() { 465 @Override 466 public Object run() throws Exception { 467 ACCESS_CONTROLLER.preDisableTable(ObserverContextImpl.createAndPrepare(CP_ENV), 468 TEST_TABLE); 469 return null; 470 } 471 }; 472 473 AccessTestAction disableAclTable = new AccessTestAction() { 474 @Override 475 public Object run() throws Exception { 476 ACCESS_CONTROLLER.preDisableTable(ObserverContextImpl.createAndPrepare(CP_ENV), 477 AccessControlLists.ACL_TABLE_NAME); 478 return null; 479 } 480 }; 481 482 verifyAllowed(disableTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_GROUP_CREATE, 483 USER_GROUP_ADMIN); 484 verifyDenied(disableTable, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); 485 486 // No user should be allowed to disable _acl_ table 487 verifyDenied(disableAclTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_RW, USER_RO, 488 USER_GROUP_CREATE, USER_GROUP_ADMIN, USER_GROUP_READ, USER_GROUP_WRITE); 489 } 490 491 @Test 492 public void testTableEnable() throws Exception { 493 AccessTestAction enableTable = new AccessTestAction() { 494 @Override 495 public Object run() throws Exception { 496 ACCESS_CONTROLLER 497 .preEnableTable(ObserverContextImpl.createAndPrepare(CP_ENV), TEST_TABLE); 498 return null; 499 } 500 }; 501 502 verifyAllowed(enableTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_GROUP_CREATE, 503 USER_GROUP_ADMIN); 504 verifyDenied(enableTable, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); 505 } 506 507 public static class TestTableDDLProcedure extends Procedure<MasterProcedureEnv> 508 implements TableProcedureInterface { 509 private TableName tableName; 510 511 public TestTableDDLProcedure() { 512 } 513 514 public TestTableDDLProcedure(final MasterProcedureEnv env, final TableName tableName) 515 throws IOException { 516 this.tableName = tableName; 517 this.setTimeout(180000); // Timeout in 3 minutes 518 this.setOwner(env.getRequestUser()); 519 } 520 521 @Override 522 public TableName getTableName() { 523 return tableName; 524 } 525 526 @Override 527 public TableOperationType getTableOperationType() { 528 return TableOperationType.EDIT; 529 } 530 531 @Override 532 protected boolean abort(MasterProcedureEnv env) { 533 return true; 534 } 535 536 @Override 537 protected void serializeStateData(ProcedureStateSerializer serializer) 538 throws IOException { 539 TestProcedureProtos.TestTableDDLStateData.Builder testTableDDLMsg = 540 TestProcedureProtos.TestTableDDLStateData.newBuilder() 541 .setTableName(tableName.getNameAsString()); 542 serializer.serialize(testTableDDLMsg.build()); 543 } 544 545 @Override 546 protected void deserializeStateData(ProcedureStateSerializer serializer) 547 throws IOException { 548 TestProcedureProtos.TestTableDDLStateData testTableDDLMsg = 549 serializer.deserialize(TestProcedureProtos.TestTableDDLStateData.class); 550 tableName = TableName.valueOf(testTableDDLMsg.getTableName()); 551 } 552 553 @Override 554 protected Procedure[] execute(MasterProcedureEnv env) throws ProcedureYieldException, 555 InterruptedException { 556 // Not letting the procedure to complete until timed out 557 setState(ProcedureState.WAITING_TIMEOUT); 558 return null; 559 } 560 561 @Override 562 protected void rollback(MasterProcedureEnv env) throws IOException, InterruptedException { 563 } 564 } 565 566 @Test 567 public void testAbortProcedure() throws Exception { 568 long procId = 1; 569 AccessTestAction abortProcedureAction = new AccessTestAction() { 570 @Override 571 public Object run() throws Exception { 572 ACCESS_CONTROLLER.preAbortProcedure(ObserverContextImpl.createAndPrepare(CP_ENV), procId); 573 return null; 574 } 575 }; 576 577 verifyAllowed(abortProcedureAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 578 } 579 580 @Test 581 public void testGetProcedures() throws Exception { 582 final TableName tableName = TableName.valueOf(name.getMethodName()); 583 final ProcedureExecutor<MasterProcedureEnv> procExec = 584 TEST_UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor(); 585 Procedure proc = new TestTableDDLProcedure(procExec.getEnvironment(), tableName); 586 proc.setOwner(USER_OWNER); 587 procExec.submitProcedure(proc); 588 final List<Procedure<MasterProcedureEnv>> procList = procExec.getProcedures(); 589 590 AccessTestAction getProceduresAction = new AccessTestAction() { 591 @Override 592 public Object run() throws Exception { 593 ACCESS_CONTROLLER 594 .postGetProcedures(ObserverContextImpl.createAndPrepare(CP_ENV)); 595 return null; 596 } 597 }; 598 599 verifyAllowed(getProceduresAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 600 verifyAllowed(getProceduresAction, USER_OWNER); 601 verifyIfNull( 602 getProceduresAction, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); 603 } 604 605 @Test 606 public void testGetLocks() throws Exception { 607 AccessTestAction action = new AccessTestAction() { 608 @Override 609 public Object run() throws Exception { 610 ACCESS_CONTROLLER.preGetLocks(ObserverContextImpl.createAndPrepare(CP_ENV)); 611 return null; 612 } 613 }; 614 615 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 616 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, 617 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 618 } 619 620 @Test 621 public void testMove() throws Exception { 622 List<HRegionLocation> regions; 623 try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE)) { 624 regions = locator.getAllRegionLocations(); 625 } 626 HRegionLocation location = regions.get(0); 627 final HRegionInfo hri = location.getRegionInfo(); 628 final ServerName server = location.getServerName(); 629 AccessTestAction action = new AccessTestAction() { 630 @Override 631 public Object run() throws Exception { 632 ACCESS_CONTROLLER.preMove(ObserverContextImpl.createAndPrepare(CP_ENV), 633 hri, server, server); 634 return null; 635 } 636 }; 637 638 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 639 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 640 USER_GROUP_WRITE, USER_GROUP_CREATE); 641 } 642 643 @Test 644 public void testAssign() throws Exception { 645 List<HRegionLocation> regions; 646 try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE)) { 647 regions = locator.getAllRegionLocations(); 648 } 649 HRegionLocation location = regions.get(0); 650 final HRegionInfo hri = location.getRegionInfo(); 651 AccessTestAction action = new AccessTestAction() { 652 @Override 653 public Object run() throws Exception { 654 ACCESS_CONTROLLER.preAssign(ObserverContextImpl.createAndPrepare(CP_ENV), hri); 655 return null; 656 } 657 }; 658 659 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 660 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 661 USER_GROUP_WRITE, USER_GROUP_CREATE); 662 } 663 664 @Test 665 public void testUnassign() throws Exception { 666 List<HRegionLocation> regions; 667 try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE)) { 668 regions = locator.getAllRegionLocations(); 669 } 670 HRegionLocation location = regions.get(0); 671 final HRegionInfo hri = location.getRegionInfo(); 672 AccessTestAction action = new AccessTestAction() { 673 @Override 674 public Object run() throws Exception { 675 ACCESS_CONTROLLER.preUnassign(ObserverContextImpl.createAndPrepare(CP_ENV), hri, false); 676 return null; 677 } 678 }; 679 680 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 681 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 682 USER_GROUP_WRITE, USER_GROUP_CREATE); 683 } 684 685 @Test 686 public void testRegionOffline() throws Exception { 687 List<HRegionLocation> regions; 688 try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE)) { 689 regions = locator.getAllRegionLocations(); 690 } 691 HRegionLocation location = regions.get(0); 692 final HRegionInfo hri = location.getRegionInfo(); 693 AccessTestAction action = new AccessTestAction() { 694 @Override 695 public Object run() throws Exception { 696 ACCESS_CONTROLLER.preRegionOffline(ObserverContextImpl.createAndPrepare(CP_ENV), hri); 697 return null; 698 } 699 }; 700 701 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 702 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 703 USER_GROUP_WRITE, USER_GROUP_CREATE); 704 } 705 706 @Test 707 public void testSetSplitOrMergeEnabled() throws Exception { 708 AccessTestAction action = new AccessTestAction() { 709 @Override 710 public Object run() throws Exception { 711 ACCESS_CONTROLLER.preSetSplitOrMergeEnabled(ObserverContextImpl.createAndPrepare(CP_ENV), 712 true, MasterSwitchType.MERGE); 713 return null; 714 } 715 }; 716 717 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 718 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 719 USER_GROUP_WRITE, USER_GROUP_CREATE); 720 } 721 722 @Test 723 public void testBalance() throws Exception { 724 AccessTestAction action = new AccessTestAction() { 725 @Override 726 public Object run() throws Exception { 727 ACCESS_CONTROLLER.preBalance(ObserverContextImpl.createAndPrepare(CP_ENV)); 728 return null; 729 } 730 }; 731 732 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 733 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 734 USER_GROUP_WRITE, USER_GROUP_CREATE); 735 } 736 737 @Test 738 public void testBalanceSwitch() throws Exception { 739 AccessTestAction action = new AccessTestAction() { 740 @Override 741 public Object run() throws Exception { 742 ACCESS_CONTROLLER.preBalanceSwitch(ObserverContextImpl.createAndPrepare(CP_ENV), true); 743 return null; 744 } 745 }; 746 747 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 748 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 749 USER_GROUP_WRITE, USER_GROUP_CREATE); 750 } 751 752 @Test 753 public void testShutdown() throws Exception { 754 AccessTestAction action = new AccessTestAction() { 755 @Override 756 public Object run() throws Exception { 757 ACCESS_CONTROLLER.preShutdown(ObserverContextImpl.createAndPrepare(CP_ENV)); 758 return null; 759 } 760 }; 761 762 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 763 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 764 USER_GROUP_WRITE, USER_GROUP_CREATE); 765 } 766 767 @Test 768 public void testStopMaster() throws Exception { 769 AccessTestAction action = new AccessTestAction() { 770 @Override 771 public Object run() throws Exception { 772 ACCESS_CONTROLLER.preStopMaster(ObserverContextImpl.createAndPrepare(CP_ENV)); 773 return null; 774 } 775 }; 776 777 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 778 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 779 USER_GROUP_WRITE, USER_GROUP_CREATE); 780 } 781 782 private void verifyWrite(AccessTestAction action) throws Exception { 783 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 784 USER_GROUP_WRITE); 785 verifyDenied(action, USER_NONE, USER_RO, USER_GROUP_ADMIN, USER_GROUP_READ, USER_GROUP_CREATE); 786 } 787 788 @Test 789 public void testSplitWithSplitRow() throws Exception { 790 final TableName tableName = TableName.valueOf(name.getMethodName()); 791 createTestTable(tableName); 792 AccessTestAction action = new AccessTestAction() { 793 @Override 794 public Object run() throws Exception { 795 ACCESS_CONTROLLER.preSplitRegion( 796 ObserverContextImpl.createAndPrepare(CP_ENV), 797 tableName, 798 TEST_ROW); 799 return null; 800 } 801 }; 802 803 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 804 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 805 USER_GROUP_WRITE, USER_GROUP_CREATE); 806 } 807 808 @Test 809 public void testFlush() throws Exception { 810 AccessTestAction action = new AccessTestAction() { 811 @Override 812 public Object run() throws Exception { 813 ACCESS_CONTROLLER.preFlush(ObserverContextImpl.createAndPrepare(RCP_ENV), 814 FlushLifeCycleTracker.DUMMY); 815 return null; 816 } 817 }; 818 819 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_GROUP_CREATE, 820 USER_GROUP_ADMIN); 821 verifyDenied(action, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); 822 } 823 824 @Test 825 public void testCompact() throws Exception { 826 AccessTestAction action = new AccessTestAction() { 827 @Override 828 public Object run() throws Exception { 829 ACCESS_CONTROLLER.preCompact(ObserverContextImpl.createAndPrepare(RCP_ENV), null, null, 830 ScanType.COMPACT_RETAIN_DELETES, null, null); 831 return null; 832 } 833 }; 834 835 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_GROUP_CREATE, 836 USER_GROUP_ADMIN); 837 verifyDenied(action, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); 838 } 839 840 private void verifyRead(AccessTestAction action) throws Exception { 841 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 842 USER_GROUP_READ); 843 verifyDenied(action, USER_NONE, USER_GROUP_CREATE, USER_GROUP_ADMIN, USER_GROUP_WRITE); 844 } 845 846 private void verifyReadWrite(AccessTestAction action) throws Exception { 847 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW); 848 verifyDenied(action, USER_NONE, USER_RO, USER_GROUP_ADMIN, USER_GROUP_CREATE, USER_GROUP_READ, 849 USER_GROUP_WRITE); 850 } 851 852 @Test 853 public void testRead() throws Exception { 854 // get action 855 AccessTestAction getAction = new AccessTestAction() { 856 @Override 857 public Object run() throws Exception { 858 Get g = new Get(TEST_ROW); 859 g.addFamily(TEST_FAMILY); 860 try(Connection conn = ConnectionFactory.createConnection(conf); 861 Table t = conn.getTable(TEST_TABLE)) { 862 t.get(g); 863 } 864 return null; 865 } 866 }; 867 verifyRead(getAction); 868 869 // action for scanning 870 AccessTestAction scanAction = new AccessTestAction() { 871 @Override 872 public Object run() throws Exception { 873 Scan s = new Scan(); 874 s.addFamily(TEST_FAMILY); 875 try(Connection conn = ConnectionFactory.createConnection(conf); 876 Table table = conn.getTable(TEST_TABLE)) { 877 ResultScanner scanner = table.getScanner(s); 878 try { 879 for (Result r = scanner.next(); r != null; r = scanner.next()) { 880 // do nothing 881 } 882 } finally { 883 scanner.close(); 884 } 885 } 886 return null; 887 } 888 }; 889 verifyRead(scanAction); 890 } 891 892 @Test 893 // test put, delete, increment 894 public void testWrite() throws Exception { 895 // put action 896 AccessTestAction putAction = new AccessTestAction() { 897 @Override 898 public Object run() throws Exception { 899 Put p = new Put(TEST_ROW); 900 p.addColumn(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(1)); 901 try(Connection conn = ConnectionFactory.createConnection(conf); 902 Table t = conn.getTable(TEST_TABLE)) { 903 t.put(p); 904 } 905 return null; 906 } 907 }; 908 verifyWrite(putAction); 909 910 // delete action 911 AccessTestAction deleteAction = new AccessTestAction() { 912 @Override 913 public Object run() throws Exception { 914 Delete d = new Delete(TEST_ROW); 915 d.addFamily(TEST_FAMILY); 916 try(Connection conn = ConnectionFactory.createConnection(conf); 917 Table t = conn.getTable(TEST_TABLE)) { 918 t.delete(d); 919 } 920 return null; 921 } 922 }; 923 verifyWrite(deleteAction); 924 925 // increment action 926 AccessTestAction incrementAction = new AccessTestAction() { 927 @Override 928 public Object run() throws Exception { 929 Increment inc = new Increment(TEST_ROW); 930 inc.addColumn(TEST_FAMILY, TEST_QUALIFIER, 1); 931 try(Connection conn = ConnectionFactory.createConnection(conf); 932 Table t = conn.getTable(TEST_TABLE);) { 933 t.increment(inc); 934 } 935 return null; 936 } 937 }; 938 verifyWrite(incrementAction); 939 } 940 941 @Test 942 public void testReadWrite() throws Exception { 943 // action for checkAndDelete 944 AccessTestAction checkAndDeleteAction = new AccessTestAction() { 945 @Override 946 public Object run() throws Exception { 947 Delete d = new Delete(TEST_ROW); 948 d.addFamily(TEST_FAMILY); 949 try(Connection conn = ConnectionFactory.createConnection(conf); 950 Table t = conn.getTable(TEST_TABLE);) { 951 t.checkAndMutate(TEST_ROW, TEST_FAMILY).qualifier(TEST_QUALIFIER) 952 .ifEquals(Bytes.toBytes("test_value")).thenDelete(d); 953 } 954 return null; 955 } 956 }; 957 verifyReadWrite(checkAndDeleteAction); 958 959 // action for checkAndPut() 960 AccessTestAction checkAndPut = new AccessTestAction() { 961 @Override 962 public Object run() throws Exception { 963 Put p = new Put(TEST_ROW); 964 p.addColumn(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(1)); 965 try(Connection conn = ConnectionFactory.createConnection(conf); 966 Table t = conn.getTable(TEST_TABLE)) { 967 t.checkAndMutate(TEST_ROW, TEST_FAMILY).qualifier(TEST_QUALIFIER) 968 .ifEquals(Bytes.toBytes("test_value")).thenPut(p); 969 } 970 return null; 971 } 972 }; 973 verifyReadWrite(checkAndPut); 974 } 975 976 @Test 977 public void testBulkLoad() throws Exception { 978 try { 979 FileSystem fs = TEST_UTIL.getTestFileSystem(); 980 final Path dir = TEST_UTIL.getDataTestDirOnTestFS("testBulkLoad"); 981 fs.mkdirs(dir); 982 // need to make it globally writable 983 // so users creating HFiles have write permissions 984 fs.setPermission(dir, FS_PERMISSION_ALL); 985 986 AccessTestAction bulkLoadAction = new AccessTestAction() { 987 @Override 988 public Object run() throws Exception { 989 int numRows = 3; 990 991 // Making the assumption that the test table won't split between the range 992 byte[][][] hfileRanges = { { { (byte) 0 }, { (byte) 9 } } }; 993 994 Path bulkLoadBasePath = new Path(dir, new Path(User.getCurrent().getName())); 995 new BulkLoadHelper(bulkLoadBasePath).initHFileData(TEST_FAMILY, TEST_QUALIFIER, 996 hfileRanges, numRows, FS_PERMISSION_ALL).bulkLoadHFile(TEST_TABLE); 997 return null; 998 } 999 }; 1000 1001 // User performing bulk loads must have privilege to read table metadata 1002 // (ADMIN or CREATE) 1003 verifyAllowed(bulkLoadAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, 1004 USER_GROUP_CREATE); 1005 verifyDenied(bulkLoadAction, USER_RW, USER_NONE, USER_RO, USER_GROUP_READ, USER_GROUP_WRITE, 1006 USER_GROUP_ADMIN); 1007 } finally { 1008 // Reinit after the bulk upload 1009 TEST_UTIL.getAdmin().disableTable(TEST_TABLE); 1010 TEST_UTIL.getAdmin().enableTable(TEST_TABLE); 1011 } 1012 } 1013 1014 private class BulkLoadAccessTestAction implements AccessTestAction { 1015 private FsPermission filePermission; 1016 private Path testDataDir; 1017 1018 public BulkLoadAccessTestAction(FsPermission perm, Path testDataDir) { 1019 this.filePermission = perm; 1020 this.testDataDir = testDataDir; 1021 } 1022 1023 @Override 1024 public Object run() throws Exception { 1025 FileSystem fs = TEST_UTIL.getTestFileSystem(); 1026 fs.mkdirs(testDataDir); 1027 fs.setPermission(testDataDir, FS_PERMISSION_ALL); 1028 // Making the assumption that the test table won't split between the range 1029 byte[][][] hfileRanges = { { { (byte) 0 }, { (byte) 9 } } }; 1030 Path bulkLoadBasePath = new Path(testDataDir, new Path(User.getCurrent().getName())); 1031 new BulkLoadHelper(bulkLoadBasePath) 1032 .initHFileData(TEST_FAMILY, TEST_QUALIFIER, hfileRanges, 3, filePermission) 1033 .bulkLoadHFile(TEST_TABLE); 1034 return null; 1035 } 1036 } 1037 1038 @Test 1039 public void testBulkLoadWithoutWritePermission() throws Exception { 1040 // Use the USER_CREATE to initialize the source directory. 1041 Path testDataDir0 = TEST_UTIL.getDataTestDirOnTestFS("testBulkLoadWithoutWritePermission0"); 1042 Path testDataDir1 = TEST_UTIL.getDataTestDirOnTestFS("testBulkLoadWithoutWritePermission1"); 1043 AccessTestAction bulkLoadAction1 = 1044 new BulkLoadAccessTestAction(FsPermission.valueOf("-r-xr-xr-x"), testDataDir0); 1045 AccessTestAction bulkLoadAction2 = 1046 new BulkLoadAccessTestAction(FS_PERMISSION_ALL, testDataDir1); 1047 // Test the incorrect case. 1048 BulkLoadHelper.setPermission(TEST_UTIL.getTestFileSystem(), 1049 TEST_UTIL.getTestFileSystem().getWorkingDirectory(), FS_PERMISSION_ALL); 1050 try { 1051 USER_CREATE.runAs(bulkLoadAction1); 1052 fail("Should fail because the hbase user has no write permission on hfiles."); 1053 } catch (IOException e) { 1054 } 1055 // Ensure the correct case. 1056 USER_CREATE.runAs(bulkLoadAction2); 1057 } 1058 1059 public static class BulkLoadHelper { 1060 private final FileSystem fs; 1061 private final Path loadPath; 1062 private final Configuration conf; 1063 1064 public BulkLoadHelper(Path loadPath) throws IOException { 1065 fs = TEST_UTIL.getTestFileSystem(); 1066 conf = TEST_UTIL.getConfiguration(); 1067 loadPath = loadPath.makeQualified(fs); 1068 this.loadPath = loadPath; 1069 } 1070 1071 private void createHFile(Path path, 1072 byte[] family, byte[] qualifier, 1073 byte[] startKey, byte[] endKey, int numRows) throws IOException { 1074 HFile.Writer writer = null; 1075 long now = System.currentTimeMillis(); 1076 try { 1077 HFileContext context = new HFileContextBuilder().build(); 1078 writer = HFile.getWriterFactory(conf, new CacheConfig(conf)).withPath(fs, path) 1079 .withFileContext(context).create(); 1080 // subtract 2 since numRows doesn't include boundary keys 1081 for (byte[] key : Bytes.iterateOnSplits(startKey, endKey, true, numRows - 2)) { 1082 KeyValue kv = new KeyValue(key, family, qualifier, now, key); 1083 writer.append(kv); 1084 } 1085 } finally { 1086 if (writer != null) { 1087 writer.close(); 1088 } 1089 } 1090 } 1091 1092 private BulkLoadHelper initHFileData(byte[] family, byte[] qualifier, byte[][][] hfileRanges, 1093 int numRowsPerRange, FsPermission filePermission) throws Exception { 1094 Path familyDir = new Path(loadPath, Bytes.toString(family)); 1095 fs.mkdirs(familyDir); 1096 int hfileIdx = 0; 1097 List<Path> hfiles = new ArrayList<>(); 1098 for (byte[][] range : hfileRanges) { 1099 byte[] from = range[0]; 1100 byte[] to = range[1]; 1101 Path hfile = new Path(familyDir, "hfile_" + (hfileIdx++)); 1102 hfiles.add(hfile); 1103 createHFile(hfile, family, qualifier, from, to, numRowsPerRange); 1104 } 1105 // set global read so RegionServer can move it 1106 setPermission(fs, loadPath, FS_PERMISSION_ALL); 1107 // Ensure the file permission as requested. 1108 for (Path hfile : hfiles) { 1109 setPermission(fs, hfile, filePermission); 1110 } 1111 return this; 1112 } 1113 1114 private void bulkLoadHFile(TableName tableName) throws Exception { 1115 try (Connection conn = ConnectionFactory.createConnection(conf); 1116 Admin admin = conn.getAdmin(); 1117 RegionLocator locator = conn.getRegionLocator(tableName); 1118 Table table = conn.getTable(tableName)) { 1119 TEST_UTIL.waitUntilAllRegionsAssigned(tableName); 1120 LoadIncrementalHFiles loader = new LoadIncrementalHFiles(conf); 1121 loader.doBulkLoad(loadPath, admin, table, locator); 1122 } 1123 } 1124 1125 private static void setPermission(FileSystem fs, Path dir, FsPermission perm) 1126 throws IOException { 1127 if (!fs.getFileStatus(dir).isDirectory()) { 1128 fs.setPermission(dir, perm); 1129 } else { 1130 for (FileStatus el : fs.listStatus(dir)) { 1131 fs.setPermission(el.getPath(), perm); 1132 setPermission(fs, el.getPath(), perm); 1133 } 1134 } 1135 } 1136 } 1137 1138 @Test 1139 public void testAppend() throws Exception { 1140 1141 AccessTestAction appendAction = new AccessTestAction() { 1142 @Override 1143 public Object run() throws Exception { 1144 byte[] row = TEST_ROW; 1145 byte[] qualifier = TEST_QUALIFIER; 1146 Put put = new Put(row); 1147 put.addColumn(TEST_FAMILY, qualifier, Bytes.toBytes(1)); 1148 Append append = new Append(row); 1149 append.addColumn(TEST_FAMILY, qualifier, Bytes.toBytes(2)); 1150 try(Connection conn = ConnectionFactory.createConnection(conf); 1151 Table t = conn.getTable(TEST_TABLE)) { 1152 t.put(put); 1153 t.append(append); 1154 } 1155 return null; 1156 } 1157 }; 1158 1159 verifyAllowed(appendAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 1160 USER_GROUP_WRITE); 1161 verifyDenied(appendAction, USER_RO, USER_NONE, USER_GROUP_CREATE, USER_GROUP_READ, 1162 USER_GROUP_ADMIN); 1163 } 1164 1165 @Test 1166 public void testGrantRevoke() throws Exception { 1167 AccessTestAction grantAction = new AccessTestAction() { 1168 @Override 1169 public Object run() throws Exception { 1170 try (Connection conn = ConnectionFactory.createConnection(conf)) { 1171 conn.getAdmin().grant(new UserPermission(USER_RO.getShortName(), Permission 1172 .newBuilder(TEST_TABLE).withFamily(TEST_FAMILY).withActions(Action.READ).build()), 1173 false); 1174 } 1175 return null; 1176 } 1177 }; 1178 1179 AccessTestAction revokeAction = new AccessTestAction() { 1180 @Override 1181 public Object run() throws Exception { 1182 try (Connection conn = ConnectionFactory.createConnection(conf)) { 1183 conn.getAdmin().revoke(new UserPermission(USER_RO.getShortName(), Permission 1184 .newBuilder(TEST_TABLE).withFamily(TEST_FAMILY).withActions(Action.READ).build())); 1185 } 1186 return null; 1187 } 1188 }; 1189 1190 AccessTestAction getTablePermissionsAction = new AccessTestAction() { 1191 @Override 1192 public Object run() throws Exception { 1193 try (Connection conn = ConnectionFactory.createConnection(conf)) { 1194 conn.getAdmin() 1195 .getUserPermissions(GetUserPermissionsRequest.newBuilder(TEST_TABLE).build()); 1196 } 1197 return null; 1198 } 1199 }; 1200 1201 AccessTestAction getGlobalPermissionsAction = new AccessTestAction() { 1202 @Override 1203 public Object run() throws Exception { 1204 try (Connection conn = ConnectionFactory.createConnection(conf); 1205 Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) { 1206 conn.getAdmin().getUserPermissions(GetUserPermissionsRequest.newBuilder().build()); 1207 } 1208 return null; 1209 } 1210 }; 1211 1212 AccessTestAction preGrantAction = new AccessTestAction() { 1213 @Override 1214 public Object run() throws Exception { 1215 ACCESS_CONTROLLER.preGrant(ObserverContextImpl.createAndPrepare(CP_ENV), 1216 new UserPermission(USER_RO.getShortName(), Permission.newBuilder(TEST_TABLE) 1217 .withFamily(TEST_FAMILY).withActions(Action.READ).build()), 1218 false); 1219 return null; 1220 } 1221 }; 1222 1223 AccessTestAction preRevokeAction = new AccessTestAction() { 1224 @Override 1225 public Object run() throws Exception { 1226 ACCESS_CONTROLLER.preRevoke(ObserverContextImpl.createAndPrepare(CP_ENV), 1227 new UserPermission(USER_RO.getShortName(), Permission.newBuilder(TEST_TABLE) 1228 .withFamily(TEST_FAMILY).withActions(Action.READ).build())); 1229 return null; 1230 } 1231 }; 1232 1233 AccessTestAction grantCPAction = new AccessTestAction() { 1234 @Override 1235 public Object run() throws Exception { 1236 try (Connection conn = ConnectionFactory.createConnection(conf); 1237 Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) { 1238 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName()); 1239 AccessControlService.BlockingInterface protocol = 1240 AccessControlService.newBlockingStub(service); 1241 AccessControlUtil.grant(null, protocol, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY, 1242 null, false, Action.READ); 1243 } 1244 return null; 1245 } 1246 }; 1247 1248 AccessTestAction revokeCPAction = new AccessTestAction() { 1249 @Override 1250 public Object run() throws Exception { 1251 try (Connection conn = ConnectionFactory.createConnection(conf); 1252 Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) { 1253 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName()); 1254 AccessControlService.BlockingInterface protocol = 1255 AccessControlService.newBlockingStub(service); 1256 AccessControlUtil.revoke(null, protocol, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY, 1257 null, Action.READ); 1258 } 1259 return null; 1260 } 1261 }; 1262 1263 verifyAllowed(grantAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 1264 verifyDenied(grantAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 1265 USER_GROUP_WRITE, USER_GROUP_CREATE); 1266 try { 1267 verifyAllowed(revokeAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 1268 verifyDenied(revokeAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 1269 USER_GROUP_WRITE, USER_GROUP_CREATE); 1270 1271 verifyAllowed(getTablePermissionsAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 1272 verifyDenied(getTablePermissionsAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, 1273 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 1274 1275 verifyAllowed(getGlobalPermissionsAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 1276 verifyDenied(getGlobalPermissionsAction, USER_CREATE, USER_OWNER, USER_RW, USER_RO, 1277 USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 1278 1279 verifyAllowed(preGrantAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 1280 verifyDenied(preGrantAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 1281 USER_GROUP_WRITE, USER_GROUP_CREATE); 1282 1283 verifyAllowed(preRevokeAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 1284 verifyDenied(preRevokeAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 1285 USER_GROUP_WRITE, USER_GROUP_CREATE); 1286 1287 verifyAllowed(grantCPAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 1288 verifyDenied(grantCPAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 1289 USER_GROUP_WRITE, USER_GROUP_CREATE); 1290 1291 verifyAllowed(revokeCPAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 1292 verifyDenied(revokeCPAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 1293 USER_GROUP_WRITE, USER_GROUP_CREATE); 1294 } finally { 1295 // Cleanup, Grant the revoked permission back to the user 1296 grantOnTable(TEST_UTIL, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY, null, 1297 Permission.Action.READ); 1298 } 1299 } 1300 1301 @Test 1302 public void testPostGrantRevoke() throws Exception { 1303 final TableName tableName = 1304 TableName.valueOf("TempTable"); 1305 final byte[] family1 = Bytes.toBytes("f1"); 1306 final byte[] family2 = Bytes.toBytes("f2"); 1307 final byte[] qualifier = Bytes.toBytes("q"); 1308 1309 // create table 1310 Admin admin = TEST_UTIL.getAdmin(); 1311 if (admin.tableExists(tableName)) { 1312 deleteTable(TEST_UTIL, tableName); 1313 } 1314 HTableDescriptor htd = new HTableDescriptor(tableName); 1315 htd.addFamily(new HColumnDescriptor(family1)); 1316 htd.addFamily(new HColumnDescriptor(family2)); 1317 createTable(TEST_UTIL, htd); 1318 try { 1319 // create temp users 1320 User tblUser = 1321 User.createUserForTesting(TEST_UTIL.getConfiguration(), "tbluser", new String[0]); 1322 User gblUser = 1323 User.createUserForTesting(TEST_UTIL.getConfiguration(), "gbluser", new String[0]); 1324 1325 // prepare actions: 1326 AccessTestAction putActionAll = new AccessTestAction() { 1327 @Override 1328 public Object run() throws Exception { 1329 Put p = new Put(Bytes.toBytes("a")); 1330 p.addColumn(family1, qualifier, Bytes.toBytes("v1")); 1331 p.addColumn(family2, qualifier, Bytes.toBytes("v2")); 1332 1333 try (Connection conn = ConnectionFactory.createConnection(conf); 1334 Table t = conn.getTable(tableName);) { 1335 t.put(p); 1336 } 1337 return null; 1338 } 1339 }; 1340 1341 AccessTestAction putAction1 = new AccessTestAction() { 1342 @Override 1343 public Object run() throws Exception { 1344 Put p = new Put(Bytes.toBytes("a")); 1345 p.addColumn(family1, qualifier, Bytes.toBytes("v1")); 1346 1347 try (Connection conn = ConnectionFactory.createConnection(conf); 1348 Table t = conn.getTable(tableName)) { 1349 t.put(p); 1350 } 1351 return null; 1352 } 1353 }; 1354 1355 AccessTestAction putAction2 = new AccessTestAction() { 1356 @Override 1357 public Object run() throws Exception { 1358 Put p = new Put(Bytes.toBytes("a")); 1359 p.addColumn(family2, qualifier, Bytes.toBytes("v2")); 1360 try (Connection conn = ConnectionFactory.createConnection(conf); 1361 Table t = conn.getTable(tableName);) { 1362 t.put(p); 1363 } 1364 return null; 1365 } 1366 }; 1367 1368 AccessTestAction getActionAll = new AccessTestAction() { 1369 @Override 1370 public Object run() throws Exception { 1371 Get g = new Get(TEST_ROW); 1372 g.addFamily(family1); 1373 g.addFamily(family2); 1374 try (Connection conn = ConnectionFactory.createConnection(conf); 1375 Table t = conn.getTable(tableName);) { 1376 t.get(g); 1377 } 1378 return null; 1379 } 1380 }; 1381 1382 AccessTestAction getAction1 = new AccessTestAction() { 1383 @Override 1384 public Object run() throws Exception { 1385 Get g = new Get(TEST_ROW); 1386 g.addFamily(family1); 1387 try (Connection conn = ConnectionFactory.createConnection(conf); 1388 Table t = conn.getTable(tableName)) { 1389 t.get(g); 1390 } 1391 return null; 1392 } 1393 }; 1394 1395 AccessTestAction getAction2 = new AccessTestAction() { 1396 @Override 1397 public Object run() throws Exception { 1398 Get g = new Get(TEST_ROW); 1399 g.addFamily(family2); 1400 try (Connection conn = ConnectionFactory.createConnection(conf); 1401 Table t = conn.getTable(tableName)) { 1402 t.get(g); 1403 } 1404 return null; 1405 } 1406 }; 1407 1408 AccessTestAction deleteActionAll = new AccessTestAction() { 1409 @Override 1410 public Object run() throws Exception { 1411 Delete d = new Delete(TEST_ROW); 1412 d.addFamily(family1); 1413 d.addFamily(family2); 1414 try (Connection conn = ConnectionFactory.createConnection(conf); 1415 Table t = conn.getTable(tableName)) { 1416 t.delete(d); 1417 } 1418 return null; 1419 } 1420 }; 1421 1422 AccessTestAction deleteAction1 = new AccessTestAction() { 1423 @Override 1424 public Object run() throws Exception { 1425 Delete d = new Delete(TEST_ROW); 1426 d.addFamily(family1); 1427 try (Connection conn = ConnectionFactory.createConnection(conf); 1428 Table t = conn.getTable(tableName)) { 1429 t.delete(d); 1430 } 1431 return null; 1432 } 1433 }; 1434 1435 AccessTestAction deleteAction2 = new AccessTestAction() { 1436 @Override 1437 public Object run() throws Exception { 1438 Delete d = new Delete(TEST_ROW); 1439 d.addFamily(family2); 1440 try (Connection conn = ConnectionFactory.createConnection(conf); 1441 Table t = conn.getTable(tableName)) { 1442 t.delete(d); 1443 } 1444 return null; 1445 } 1446 }; 1447 1448 // initial check: 1449 verifyDenied(tblUser, getActionAll, getAction1, getAction2); 1450 verifyDenied(tblUser, putActionAll, putAction1, putAction2); 1451 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2); 1452 1453 verifyDenied(gblUser, getActionAll, getAction1, getAction2); 1454 verifyDenied(gblUser, putActionAll, putAction1, putAction2); 1455 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2); 1456 1457 // grant table read permission 1458 grantGlobal(TEST_UTIL, gblUser.getShortName(), Permission.Action.READ); 1459 grantOnTable(TEST_UTIL, tblUser.getShortName(), tableName, null, null, Permission.Action.READ); 1460 1461 // check 1462 verifyAllowed(tblUser, getActionAll, getAction1, getAction2); 1463 verifyDenied(tblUser, putActionAll, putAction1, putAction2); 1464 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2); 1465 1466 verifyAllowed(gblUser, getActionAll, getAction1, getAction2); 1467 verifyDenied(gblUser, putActionAll, putAction1, putAction2); 1468 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2); 1469 1470 // grant table write permission while revoking read permissions 1471 grantGlobal(TEST_UTIL, gblUser.getShortName(), Permission.Action.WRITE); 1472 grantOnTable(TEST_UTIL, tblUser.getShortName(), tableName, null, null, 1473 Permission.Action.WRITE); 1474 1475 verifyDenied(tblUser, getActionAll, getAction1, getAction2); 1476 verifyAllowed(tblUser, putActionAll, putAction1, putAction2); 1477 verifyAllowed(tblUser, deleteActionAll, deleteAction1, deleteAction2); 1478 1479 verifyDenied(gblUser, getActionAll, getAction1, getAction2); 1480 verifyAllowed(gblUser, putActionAll, putAction1, putAction2); 1481 verifyAllowed(gblUser, deleteActionAll, deleteAction1, deleteAction2); 1482 1483 // revoke table permissions 1484 revokeGlobal(TEST_UTIL, gblUser.getShortName()); 1485 revokeFromTable(TEST_UTIL, tblUser.getShortName(), tableName, null, null); 1486 1487 verifyDenied(tblUser, getActionAll, getAction1, getAction2); 1488 verifyDenied(tblUser, putActionAll, putAction1, putAction2); 1489 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2); 1490 1491 verifyDenied(gblUser, getActionAll, getAction1, getAction2); 1492 verifyDenied(gblUser, putActionAll, putAction1, putAction2); 1493 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2); 1494 1495 // grant column family read permission 1496 grantGlobal(TEST_UTIL, gblUser.getShortName(), Permission.Action.READ); 1497 grantOnTable(TEST_UTIL, tblUser.getShortName(), tableName, family1, null, 1498 Permission.Action.READ); 1499 1500 // Access should be denied for family2 1501 verifyAllowed(tblUser, getActionAll, getAction1); 1502 verifyDenied(tblUser, getAction2); 1503 verifyDenied(tblUser, putActionAll, putAction1, putAction2); 1504 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2); 1505 1506 verifyAllowed(gblUser, getActionAll, getAction1, getAction2); 1507 verifyDenied(gblUser, putActionAll, putAction1, putAction2); 1508 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2); 1509 1510 // grant column family write permission 1511 grantGlobal(TEST_UTIL, gblUser.getShortName(), Permission.Action.WRITE); 1512 grantOnTable(TEST_UTIL, tblUser.getShortName(), tableName, family2, null, 1513 Permission.Action.WRITE); 1514 1515 // READ from family1, WRITE to family2 are allowed 1516 verifyAllowed(tblUser, getActionAll, getAction1); 1517 verifyAllowed(tblUser, putAction2, deleteAction2); 1518 verifyDenied(tblUser, getAction2); 1519 verifyDenied(tblUser, putActionAll, putAction1); 1520 verifyDenied(tblUser, deleteActionAll, deleteAction1); 1521 1522 verifyDenied(gblUser, getActionAll, getAction1, getAction2); 1523 verifyAllowed(gblUser, putActionAll, putAction1, putAction2); 1524 verifyAllowed(gblUser, deleteActionAll, deleteAction1, deleteAction2); 1525 1526 // revoke column family permission 1527 revokeGlobal(TEST_UTIL, gblUser.getShortName()); 1528 revokeFromTable(TEST_UTIL, tblUser.getShortName(), tableName, family2, null); 1529 1530 // Revoke on family2 should not have impact on family1 permissions 1531 verifyAllowed(tblUser, getActionAll, getAction1); 1532 verifyDenied(tblUser, getAction2); 1533 verifyDenied(tblUser, putActionAll, putAction1, putAction2); 1534 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2); 1535 1536 // Should not have access as global permissions are completely revoked 1537 verifyDenied(gblUser, getActionAll, getAction1, getAction2); 1538 verifyDenied(gblUser, putActionAll, putAction1, putAction2); 1539 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2); 1540 } finally { 1541 // delete table 1542 deleteTable(TEST_UTIL, tableName); 1543 } 1544 } 1545 1546 private boolean hasFoundUserPermission(List<UserPermission> userPermissions, 1547 List<UserPermission> perms) { 1548 return perms.containsAll(userPermissions); 1549 } 1550 1551 private boolean hasFoundUserPermission(UserPermission userPermission, List<UserPermission> perms) { 1552 return perms.contains(userPermission); 1553 } 1554 1555 @Test 1556 public void testPostGrantRevokeAtQualifierLevel() throws Exception { 1557 final TableName tableName = TableName.valueOf(name.getMethodName()); 1558 final byte[] family1 = Bytes.toBytes("f1"); 1559 final byte[] family2 = Bytes.toBytes("f2"); 1560 final byte[] qualifier = Bytes.toBytes("q"); 1561 1562 // create table 1563 Admin admin = TEST_UTIL.getAdmin(); 1564 if (admin.tableExists(tableName)) { 1565 deleteTable(TEST_UTIL, tableName); 1566 } 1567 HTableDescriptor htd = new HTableDescriptor(tableName); 1568 htd.addFamily(new HColumnDescriptor(family1)); 1569 htd.addFamily(new HColumnDescriptor(family2)); 1570 createTable(TEST_UTIL, htd); 1571 1572 try { 1573 // create temp users 1574 User user = User.createUserForTesting(TEST_UTIL.getConfiguration(), "user", new String[0]); 1575 1576 AccessTestAction getQualifierAction = new AccessTestAction() { 1577 @Override 1578 public Object run() throws Exception { 1579 Get g = new Get(TEST_ROW); 1580 g.addColumn(family1, qualifier); 1581 try (Connection conn = ConnectionFactory.createConnection(conf); 1582 Table t = conn.getTable(tableName)) { 1583 t.get(g); 1584 } 1585 return null; 1586 } 1587 }; 1588 1589 AccessTestAction putQualifierAction = new AccessTestAction() { 1590 @Override 1591 public Object run() throws Exception { 1592 Put p = new Put(TEST_ROW); 1593 p.addColumn(family1, qualifier, Bytes.toBytes("v1")); 1594 try (Connection conn = ConnectionFactory.createConnection(conf); 1595 Table t = conn.getTable(tableName)) { 1596 t.put(p); 1597 } 1598 return null; 1599 } 1600 }; 1601 1602 AccessTestAction deleteQualifierAction = new AccessTestAction() { 1603 @Override 1604 public Object run() throws Exception { 1605 Delete d = new Delete(TEST_ROW); 1606 d.addColumn(family1, qualifier); 1607 // d.deleteFamily(family1); 1608 try (Connection conn = ConnectionFactory.createConnection(conf); 1609 Table t = conn.getTable(tableName)) { 1610 t.delete(d); 1611 } 1612 return null; 1613 } 1614 }; 1615 1616 revokeFromTable(TEST_UTIL, user.getShortName(), tableName, family1, null); 1617 1618 verifyDenied(user, getQualifierAction); 1619 verifyDenied(user, putQualifierAction); 1620 verifyDenied(user, deleteQualifierAction); 1621 1622 grantOnTable(TEST_UTIL, user.getShortName(), tableName, family1, qualifier, 1623 Permission.Action.READ); 1624 1625 verifyAllowed(user, getQualifierAction); 1626 verifyDenied(user, putQualifierAction); 1627 verifyDenied(user, deleteQualifierAction); 1628 1629 // only grant write permission 1630 // TODO: comment this portion after HBASE-3583 1631 grantOnTable(TEST_UTIL, user.getShortName(), tableName, family1, qualifier, 1632 Permission.Action.WRITE); 1633 1634 verifyDenied(user, getQualifierAction); 1635 verifyAllowed(user, putQualifierAction); 1636 verifyAllowed(user, deleteQualifierAction); 1637 1638 // grant both read and write permission 1639 grantOnTable(TEST_UTIL, user.getShortName(), tableName, family1, qualifier, 1640 Permission.Action.READ, Permission.Action.WRITE); 1641 1642 verifyAllowed(user, getQualifierAction); 1643 verifyAllowed(user, putQualifierAction); 1644 verifyAllowed(user, deleteQualifierAction); 1645 1646 // revoke family level permission won't impact column level 1647 revokeFromTable(TEST_UTIL, user.getShortName(), tableName, family1, qualifier); 1648 1649 verifyDenied(user, getQualifierAction); 1650 verifyDenied(user, putQualifierAction); 1651 verifyDenied(user, deleteQualifierAction); 1652 } finally { 1653 // delete table 1654 deleteTable(TEST_UTIL, tableName); 1655 } 1656 } 1657 1658 @Test 1659 public void testPermissionList() throws Exception { 1660 final TableName tableName = TableName.valueOf(name.getMethodName()); 1661 final byte[] family1 = Bytes.toBytes("f1"); 1662 final byte[] family2 = Bytes.toBytes("f2"); 1663 final byte[] qualifier = Bytes.toBytes("q"); 1664 1665 // create table 1666 Admin admin = TEST_UTIL.getAdmin(); 1667 if (admin.tableExists(tableName)) { 1668 deleteTable(TEST_UTIL, tableName); 1669 } 1670 HTableDescriptor htd = new HTableDescriptor(tableName); 1671 htd.addFamily(new HColumnDescriptor(family1)); 1672 htd.addFamily(new HColumnDescriptor(family2)); 1673 htd.setOwner(USER_OWNER); 1674 createTable(TEST_UTIL, htd); 1675 try { 1676 List<UserPermission> perms = 1677 admin.getUserPermissions(GetUserPermissionsRequest.newBuilder(tableName).build()); 1678 UserPermission ownerperm = new UserPermission(USER_OWNER.getName(), 1679 Permission.newBuilder(tableName).withActions(Action.values()).build()); 1680 assertTrue("Owner should have all permissions on table", 1681 hasFoundUserPermission(ownerperm, perms)); 1682 1683 User user = User.createUserForTesting(TEST_UTIL.getConfiguration(), "user", new String[0]); 1684 String userName = user.getShortName(); 1685 1686 UserPermission up = 1687 new UserPermission(userName, Permission.newBuilder(tableName).withFamily(family1) 1688 .withQualifier(qualifier).withActions(Permission.Action.READ).build()); 1689 assertFalse("User should not be granted permission: " + up.toString(), 1690 hasFoundUserPermission(up, perms)); 1691 1692 // grant read permission 1693 grantOnTable(TEST_UTIL, user.getShortName(), tableName, family1, qualifier, 1694 Permission.Action.READ); 1695 1696 perms = admin.getUserPermissions(GetUserPermissionsRequest.newBuilder(tableName).build()); 1697 UserPermission upToVerify = 1698 new UserPermission(userName, Permission.newBuilder(tableName).withFamily(family1) 1699 .withQualifier(qualifier).withActions(Permission.Action.READ).build()); 1700 assertTrue("User should be granted permission: " + upToVerify.toString(), 1701 hasFoundUserPermission(upToVerify, perms)); 1702 1703 upToVerify = new UserPermission(userName, Permission.newBuilder(tableName).withFamily(family1) 1704 .withQualifier(qualifier).withActions(Permission.Action.WRITE).build()); 1705 assertFalse("User should not be granted permission: " + upToVerify.toString(), 1706 hasFoundUserPermission(upToVerify, perms)); 1707 1708 // grant read+write 1709 grantOnTable(TEST_UTIL, user.getShortName(), tableName, family1, qualifier, 1710 Permission.Action.WRITE, Permission.Action.READ); 1711 1712 perms = admin.getUserPermissions(GetUserPermissionsRequest.newBuilder(tableName).build()); 1713 upToVerify = new UserPermission(userName, 1714 Permission.newBuilder(tableName).withFamily(family1).withQualifier(qualifier) 1715 .withActions(Permission.Action.WRITE, Permission.Action.READ).build()); 1716 assertTrue("User should be granted permission: " + upToVerify.toString(), 1717 hasFoundUserPermission(upToVerify, perms)); 1718 1719 // revoke 1720 revokeFromTable(TEST_UTIL, user.getShortName(), tableName, family1, qualifier, 1721 Permission.Action.WRITE, Permission.Action.READ); 1722 1723 perms = admin.getUserPermissions(GetUserPermissionsRequest.newBuilder(tableName).build()); 1724 assertFalse("User should not be granted permission: " + upToVerify.toString(), 1725 hasFoundUserPermission(upToVerify, perms)); 1726 1727 // disable table before modification 1728 admin.disableTable(tableName); 1729 1730 User newOwner = User.createUserForTesting(conf, "new_owner", new String[] {}); 1731 htd.setOwner(newOwner); 1732 admin.modifyTable(tableName, htd); 1733 1734 perms = admin.getUserPermissions(GetUserPermissionsRequest.newBuilder(tableName).build()); 1735 UserPermission newOwnerperm = new UserPermission(newOwner.getName(), 1736 Permission.newBuilder(tableName).withActions(Action.values()).build()); 1737 assertTrue("New owner should have all permissions on table", 1738 hasFoundUserPermission(newOwnerperm, perms)); 1739 } finally { 1740 // delete table 1741 deleteTable(TEST_UTIL, tableName); 1742 } 1743 } 1744 1745 @Test 1746 public void testGlobalPermissionList() throws Exception { 1747 List<UserPermission> perms = systemUserConnection.getAdmin() 1748 .getUserPermissions(GetUserPermissionsRequest.newBuilder().build()); 1749 1750 Collection<String> superUsers = Superusers.getSuperUsers(); 1751 List<UserPermission> adminPerms = new ArrayList<>(superUsers.size() + 1); 1752 adminPerms.add(new UserPermission(USER_ADMIN.getShortName(), Permission.newBuilder() 1753 .withActions(Action.ADMIN, Action.CREATE, Action.READ, Action.WRITE).build())); 1754 for (String user : superUsers) { 1755 // Global permission 1756 adminPerms.add( 1757 new UserPermission(user, Permission.newBuilder().withActions(Action.values()).build())); 1758 } 1759 assertTrue("Only super users, global users and user admin has permission on table hbase:acl " + 1760 "per setup", perms.size() == 5 + superUsers.size() && 1761 hasFoundUserPermission(adminPerms, perms)); 1762 } 1763 1764 /** global operations */ 1765 private void verifyGlobal(AccessTestAction action) throws Exception { 1766 verifyAllowed(action, SUPERUSER); 1767 1768 verifyDenied(action, USER_CREATE, USER_RW, USER_NONE, USER_RO); 1769 } 1770 1771 @Test 1772 public void testCheckPermissions() throws Exception { 1773 // -------------------------------------- 1774 // test global permissions 1775 AccessTestAction globalAdmin = new AccessTestAction() { 1776 @Override 1777 public Void run() throws Exception { 1778 checkGlobalPerms(TEST_UTIL, Permission.Action.ADMIN); 1779 return null; 1780 } 1781 }; 1782 // verify that only superuser can admin 1783 verifyGlobal(globalAdmin); 1784 1785 // -------------------------------------- 1786 // test multiple permissions 1787 AccessTestAction globalReadWrite = new AccessTestAction() { 1788 @Override 1789 public Void run() throws Exception { 1790 checkGlobalPerms(TEST_UTIL, Permission.Action.READ, Permission.Action.WRITE); 1791 return null; 1792 } 1793 }; 1794 1795 verifyGlobal(globalReadWrite); 1796 1797 // -------------------------------------- 1798 // table/column/qualifier level permissions 1799 final byte[] TEST_Q1 = Bytes.toBytes("q1"); 1800 final byte[] TEST_Q2 = Bytes.toBytes("q2"); 1801 1802 User userTable = User.createUserForTesting(conf, "user_check_perms_table", new String[0]); 1803 User userColumn = User.createUserForTesting(conf, "user_check_perms_family", new String[0]); 1804 User userQualifier = User.createUserForTesting(conf, "user_check_perms_q", new String[0]); 1805 1806 grantOnTable(TEST_UTIL, userTable.getShortName(), 1807 TEST_TABLE, null, null, 1808 Permission.Action.READ); 1809 grantOnTable(TEST_UTIL, userColumn.getShortName(), 1810 TEST_TABLE, TEST_FAMILY, null, 1811 Permission.Action.READ); 1812 grantOnTable(TEST_UTIL, userQualifier.getShortName(), 1813 TEST_TABLE, TEST_FAMILY, TEST_Q1, 1814 Permission.Action.READ); 1815 1816 try { 1817 AccessTestAction tableRead = new AccessTestAction() { 1818 @Override 1819 public Void run() throws Exception { 1820 checkTablePerms(TEST_UTIL, TEST_TABLE, null, null, Permission.Action.READ); 1821 return null; 1822 } 1823 }; 1824 1825 AccessTestAction columnRead = new AccessTestAction() { 1826 @Override 1827 public Void run() throws Exception { 1828 checkTablePerms(TEST_UTIL, TEST_TABLE, TEST_FAMILY, null, Permission.Action.READ); 1829 return null; 1830 } 1831 }; 1832 1833 AccessTestAction qualifierRead = new AccessTestAction() { 1834 @Override 1835 public Void run() throws Exception { 1836 checkTablePerms(TEST_UTIL, TEST_TABLE, TEST_FAMILY, TEST_Q1, Permission.Action.READ); 1837 return null; 1838 } 1839 }; 1840 1841 AccessTestAction multiQualifierRead = new AccessTestAction() { 1842 @Override 1843 public Void run() throws Exception { 1844 checkTablePerms(TEST_UTIL, 1845 new Permission[] { 1846 Permission.newBuilder(TEST_TABLE).withFamily(TEST_FAMILY).withQualifier(TEST_Q1) 1847 .withActions(Permission.Action.READ).build(), 1848 Permission.newBuilder(TEST_TABLE).withFamily(TEST_FAMILY).withQualifier(TEST_Q2) 1849 .withActions(Permission.Action.READ).build(), }); 1850 return null; 1851 } 1852 }; 1853 1854 AccessTestAction globalAndTableRead = new AccessTestAction() { 1855 @Override 1856 public Void run() throws Exception { 1857 checkTablePerms(TEST_UTIL, new Permission[] { new Permission(Permission.Action.READ), 1858 Permission.newBuilder(TEST_TABLE).withActions(Permission.Action.READ).build() }); 1859 return null; 1860 } 1861 }; 1862 1863 AccessTestAction noCheck = new AccessTestAction() { 1864 @Override 1865 public Void run() throws Exception { 1866 checkTablePerms(TEST_UTIL, new Permission[0]); 1867 return null; 1868 } 1869 }; 1870 1871 verifyAllowed(tableRead, SUPERUSER, userTable); 1872 verifyDenied(tableRead, userColumn, userQualifier); 1873 1874 verifyAllowed(columnRead, SUPERUSER, userTable, userColumn); 1875 verifyDenied(columnRead, userQualifier); 1876 1877 verifyAllowed(qualifierRead, SUPERUSER, userTable, userColumn, userQualifier); 1878 1879 verifyAllowed(multiQualifierRead, SUPERUSER, userTable, userColumn); 1880 verifyDenied(multiQualifierRead, userQualifier); 1881 1882 verifyAllowed(globalAndTableRead, SUPERUSER); 1883 verifyDenied(globalAndTableRead, userTable, userColumn, userQualifier); 1884 1885 verifyAllowed(noCheck, SUPERUSER, userTable, userColumn, userQualifier); 1886 1887 // -------------------------------------- 1888 // test family level multiple permissions 1889 AccessTestAction familyReadWrite = new AccessTestAction() { 1890 @Override 1891 public Void run() throws Exception { 1892 checkTablePerms(TEST_UTIL, TEST_TABLE, TEST_FAMILY, null, Permission.Action.READ, 1893 Permission.Action.WRITE); 1894 return null; 1895 } 1896 }; 1897 1898 verifyAllowed(familyReadWrite, SUPERUSER, USER_OWNER, USER_CREATE, USER_RW); 1899 verifyDenied(familyReadWrite, USER_NONE, USER_RO); 1900 1901 // -------------------------------------- 1902 // check for wrong table region 1903 CheckPermissionsRequest checkRequest = 1904 CheckPermissionsRequest 1905 .newBuilder() 1906 .addPermission( 1907 AccessControlProtos.Permission 1908 .newBuilder() 1909 .setType(AccessControlProtos.Permission.Type.Table) 1910 .setTablePermission( 1911 AccessControlProtos.TablePermission.newBuilder() 1912 .setTableName(ProtobufUtil.toProtoTableName(TEST_TABLE)) 1913 .addAction(AccessControlProtos.Permission.Action.CREATE))).build(); 1914 Table acl = systemUserConnection.getTable(AccessControlLists.ACL_TABLE_NAME); 1915 try { 1916 BlockingRpcChannel channel = acl.coprocessorService(new byte[0]); 1917 AccessControlService.BlockingInterface protocol = 1918 AccessControlService.newBlockingStub(channel); 1919 try { 1920 // but ask for TablePermissions for TEST_TABLE 1921 protocol.checkPermissions(null, checkRequest); 1922 fail("this should have thrown CoprocessorException"); 1923 } catch (ServiceException ex) { 1924 // expected 1925 } 1926 } finally { 1927 acl.close(); 1928 } 1929 1930 } finally { 1931 revokeFromTable(TEST_UTIL, userTable.getShortName(), TEST_TABLE, null, null, 1932 Permission.Action.READ); 1933 revokeFromTable(TEST_UTIL, userColumn.getShortName(), TEST_TABLE, TEST_FAMILY, null, 1934 Permission.Action.READ); 1935 revokeFromTable(TEST_UTIL, userQualifier.getShortName(), TEST_TABLE, TEST_FAMILY, TEST_Q1, 1936 Permission.Action.READ); 1937 } 1938 } 1939 1940 @Test 1941 public void testStopRegionServer() throws Exception { 1942 AccessTestAction action = new AccessTestAction() { 1943 @Override 1944 public Object run() throws Exception { 1945 ACCESS_CONTROLLER.preStopRegionServer(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 1946 return null; 1947 } 1948 }; 1949 1950 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 1951 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 1952 USER_GROUP_WRITE, USER_GROUP_CREATE); 1953 } 1954 1955 @Test 1956 public void testRollWALWriterRequest() throws Exception { 1957 AccessTestAction action = new AccessTestAction() { 1958 @Override 1959 public Object run() throws Exception { 1960 ACCESS_CONTROLLER.preRollWALWriterRequest(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 1961 return null; 1962 } 1963 }; 1964 1965 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 1966 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 1967 USER_GROUP_WRITE, USER_GROUP_CREATE); 1968 } 1969 1970 @Test 1971 public void testOpenRegion() throws Exception { 1972 AccessTestAction action = new AccessTestAction() { 1973 @Override 1974 public Object run() throws Exception { 1975 ACCESS_CONTROLLER.preOpen(ObserverContextImpl.createAndPrepare(RCP_ENV)); 1976 return null; 1977 } 1978 }; 1979 1980 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 1981 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, USER_GROUP_CREATE, 1982 USER_GROUP_READ, USER_GROUP_WRITE); 1983 } 1984 1985 @Test 1986 public void testCloseRegion() throws Exception { 1987 AccessTestAction action = new AccessTestAction() { 1988 @Override 1989 public Object run() throws Exception { 1990 ACCESS_CONTROLLER.preClose(ObserverContextImpl.createAndPrepare(RCP_ENV), false); 1991 return null; 1992 } 1993 }; 1994 1995 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 1996 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, USER_GROUP_CREATE, 1997 USER_GROUP_READ, USER_GROUP_WRITE); 1998 } 1999 2000 @Test 2001 public void testSnapshot() throws Exception { 2002 Admin admin = TEST_UTIL.getAdmin(); 2003 final HTableDescriptor htd = admin.getTableDescriptor(TEST_TABLE); 2004 final SnapshotDescription snapshot = new SnapshotDescription( 2005 TEST_TABLE.getNameAsString() + "-snapshot", TEST_TABLE); 2006 AccessTestAction snapshotAction = new AccessTestAction() { 2007 @Override 2008 public Object run() throws Exception { 2009 ACCESS_CONTROLLER.preSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), 2010 snapshot, htd); 2011 return null; 2012 } 2013 }; 2014 2015 AccessTestAction deleteAction = new AccessTestAction() { 2016 @Override 2017 public Object run() throws Exception { 2018 ACCESS_CONTROLLER.preDeleteSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), 2019 snapshot); 2020 return null; 2021 } 2022 }; 2023 2024 AccessTestAction restoreAction = new AccessTestAction() { 2025 @Override 2026 public Object run() throws Exception { 2027 ACCESS_CONTROLLER.preRestoreSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), 2028 snapshot, htd); 2029 return null; 2030 } 2031 }; 2032 2033 AccessTestAction cloneAction = new AccessTestAction() { 2034 @Override 2035 public Object run() throws Exception { 2036 ACCESS_CONTROLLER.preCloneSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), 2037 snapshot, null); 2038 return null; 2039 } 2040 }; 2041 2042 verifyAllowed(snapshotAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 2043 verifyDenied(snapshotAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 2044 USER_GROUP_WRITE, USER_GROUP_CREATE); 2045 2046 verifyAllowed(cloneAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 2047 verifyDenied(deleteAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, 2048 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 2049 2050 verifyAllowed(restoreAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 2051 verifyDenied(restoreAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, 2052 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 2053 2054 verifyAllowed(deleteAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 2055 verifyDenied(cloneAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, 2056 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 2057 } 2058 2059 @Test 2060 public void testSnapshotWithOwner() throws Exception { 2061 Admin admin = TEST_UTIL.getAdmin(); 2062 final HTableDescriptor htd = admin.getTableDescriptor(TEST_TABLE); 2063 final SnapshotDescription snapshot = new SnapshotDescription( 2064 TEST_TABLE.getNameAsString() + "-snapshot", TEST_TABLE, null, USER_OWNER.getName()); 2065 2066 AccessTestAction snapshotAction = new AccessTestAction() { 2067 @Override 2068 public Object run() throws Exception { 2069 ACCESS_CONTROLLER.preSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), 2070 snapshot, htd); 2071 return null; 2072 } 2073 }; 2074 verifyAllowed(snapshotAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 2075 verifyDenied(snapshotAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 2076 USER_GROUP_WRITE, USER_GROUP_CREATE); 2077 2078 AccessTestAction deleteAction = new AccessTestAction() { 2079 @Override 2080 public Object run() throws Exception { 2081 ACCESS_CONTROLLER.preDeleteSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), 2082 snapshot); 2083 return null; 2084 } 2085 }; 2086 verifyAllowed(deleteAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 2087 verifyDenied(deleteAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 2088 USER_GROUP_WRITE, USER_GROUP_CREATE); 2089 2090 AccessTestAction restoreAction = new AccessTestAction() { 2091 @Override 2092 public Object run() throws Exception { 2093 ACCESS_CONTROLLER.preRestoreSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), 2094 snapshot, htd); 2095 return null; 2096 } 2097 }; 2098 verifyAllowed(restoreAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 2099 verifyDenied(restoreAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 2100 USER_GROUP_WRITE, USER_GROUP_CREATE); 2101 2102 AccessTestAction cloneAction = new AccessTestAction() { 2103 @Override 2104 public Object run() throws Exception { 2105 ACCESS_CONTROLLER.preCloneSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), 2106 snapshot, htd); 2107 return null; 2108 } 2109 }; 2110 verifyAllowed(cloneAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN, USER_OWNER); 2111 verifyDenied(cloneAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 2112 USER_GROUP_WRITE, USER_GROUP_CREATE); 2113 } 2114 2115 @Test 2116 public void testGlobalAuthorizationForNewRegisteredRS() throws Exception { 2117 LOG.debug("Test for global authorization for a new registered RegionServer."); 2118 MiniHBaseCluster hbaseCluster = TEST_UTIL.getHBaseCluster(); 2119 2120 final Admin admin = TEST_UTIL.getAdmin(); 2121 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE2); 2122 htd.addFamily(new HColumnDescriptor(TEST_FAMILY)); 2123 createTable(TEST_UTIL, htd); 2124 2125 // Starting a new RegionServer. 2126 JVMClusterUtil.RegionServerThread newRsThread = hbaseCluster 2127 .startRegionServer(); 2128 final HRegionServer newRs = newRsThread.getRegionServer(); 2129 2130 // Move region to the new RegionServer. 2131 List<HRegionLocation> regions; 2132 try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE2)) { 2133 regions = locator.getAllRegionLocations(); 2134 } 2135 HRegionLocation location = regions.get(0); 2136 final HRegionInfo hri = location.getRegionInfo(); 2137 final ServerName server = location.getServerName(); 2138 try (Table table = systemUserConnection.getTable(TEST_TABLE2)) { 2139 AccessTestAction moveAction = new AccessTestAction() { 2140 @Override 2141 public Object run() throws Exception { 2142 admin.move(hri.getEncodedNameAsBytes(), newRs.getServerName()); 2143 return null; 2144 } 2145 }; 2146 SUPERUSER.runAs(moveAction); 2147 2148 final int RETRIES_LIMIT = 10; 2149 int retries = 0; 2150 while (newRs.getRegions(TEST_TABLE2).size() < 1 && retries < RETRIES_LIMIT) { 2151 LOG.debug("Waiting for region to be opened. Already retried " + retries 2152 + " times."); 2153 try { 2154 Thread.sleep(1000); 2155 } catch (InterruptedException e) { 2156 } 2157 retries++; 2158 if (retries == RETRIES_LIMIT - 1) { 2159 fail("Retry exhaust for waiting region to be opened."); 2160 } 2161 } 2162 // Verify write permission for user "admin2" who has the global 2163 // permissions. 2164 AccessTestAction putAction = new AccessTestAction() { 2165 @Override 2166 public Object run() throws Exception { 2167 Put put = new Put(Bytes.toBytes("test")); 2168 put.addColumn(TEST_FAMILY, Bytes.toBytes("qual"), Bytes.toBytes("value")); 2169 table.put(put); 2170 return null; 2171 } 2172 }; 2173 USER_ADMIN.runAs(putAction); 2174 } 2175 } 2176 2177 @Test 2178 public void testTableDescriptorsEnumeration() throws Exception { 2179 User TABLE_ADMIN = User.createUserForTesting(conf, "UserA", new String[0]); 2180 2181 // Grant TABLE ADMIN privs 2182 grantOnTable(TEST_UTIL, TABLE_ADMIN.getShortName(), TEST_TABLE, null, null, 2183 Permission.Action.ADMIN); 2184 try { 2185 AccessTestAction listTablesAction = new AccessTestAction() { 2186 @Override 2187 public Object run() throws Exception { 2188 try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); 2189 Admin admin = conn.getAdmin()) { 2190 return Arrays.asList(admin.listTables()); 2191 } 2192 } 2193 }; 2194 2195 AccessTestAction getTableDescAction = new AccessTestAction() { 2196 @Override 2197 public Object run() throws Exception { 2198 try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); 2199 Admin admin = conn.getAdmin();) { 2200 return admin.getTableDescriptor(TEST_TABLE); 2201 } 2202 } 2203 }; 2204 2205 verifyAllowed(listTablesAction, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, TABLE_ADMIN, 2206 USER_GROUP_CREATE, USER_GROUP_ADMIN); 2207 verifyIfEmptyList(listTablesAction, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 2208 USER_GROUP_WRITE); 2209 2210 verifyAllowed(getTableDescAction, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, 2211 TABLE_ADMIN, USER_GROUP_CREATE, USER_GROUP_ADMIN); 2212 verifyDenied(getTableDescAction, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 2213 USER_GROUP_WRITE); 2214 } finally { 2215 // Cleanup, revoke TABLE ADMIN privs 2216 revokeFromTable(TEST_UTIL, TABLE_ADMIN.getShortName(), TEST_TABLE, null, null, 2217 Permission.Action.ADMIN); 2218 } 2219 } 2220 2221 @Test 2222 public void testTableNameEnumeration() throws Exception { 2223 AccessTestAction listTablesAction = new AccessTestAction() { 2224 @Override 2225 public Object run() throws Exception { 2226 Connection unmanagedConnection = 2227 ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); 2228 Admin admin = unmanagedConnection.getAdmin(); 2229 try { 2230 return Arrays.asList(admin.listTableNames()); 2231 } finally { 2232 admin.close(); 2233 unmanagedConnection.close(); 2234 } 2235 } 2236 }; 2237 2238 verifyAllowed(listTablesAction, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_RW, 2239 USER_RO, USER_GROUP_CREATE, USER_GROUP_ADMIN, USER_GROUP_READ, USER_GROUP_WRITE); 2240 verifyIfEmptyList(listTablesAction, USER_NONE); 2241 } 2242 2243 @Test 2244 public void testTableDeletion() throws Exception { 2245 User TABLE_ADMIN = User.createUserForTesting(conf, "TestUser", new String[0]); 2246 final TableName tableName = TableName.valueOf(name.getMethodName()); 2247 createTestTable(tableName); 2248 2249 // Grant TABLE ADMIN privs 2250 grantOnTable(TEST_UTIL, TABLE_ADMIN.getShortName(), tableName, null, null, Permission.Action.ADMIN); 2251 2252 AccessTestAction deleteTableAction = new AccessTestAction() { 2253 @Override 2254 public Object run() throws Exception { 2255 Connection unmanagedConnection = 2256 ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); 2257 Admin admin = unmanagedConnection.getAdmin(); 2258 try { 2259 deleteTable(TEST_UTIL, admin, tableName); 2260 } finally { 2261 admin.close(); 2262 unmanagedConnection.close(); 2263 } 2264 return null; 2265 } 2266 }; 2267 2268 verifyDenied(deleteTableAction, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, 2269 USER_GROUP_WRITE); 2270 verifyAllowed(deleteTableAction, TABLE_ADMIN); 2271 } 2272 2273 private void createTestTable(TableName tname) throws Exception { 2274 createTestTable(tname, TEST_FAMILY); 2275 } 2276 2277 private void createTestTable(TableName tname, byte[] cf) throws Exception { 2278 HTableDescriptor htd = new HTableDescriptor(tname); 2279 HColumnDescriptor hcd = new HColumnDescriptor(cf); 2280 hcd.setMaxVersions(100); 2281 htd.addFamily(hcd); 2282 htd.setOwner(USER_OWNER); 2283 createTable(TEST_UTIL, htd, new byte[][] { Bytes.toBytes("s") }); 2284 } 2285 2286 @Test 2287 public void testNamespaceUserGrant() throws Exception { 2288 AccessTestAction getAction = new AccessTestAction() { 2289 @Override 2290 public Object run() throws Exception { 2291 try(Connection conn = ConnectionFactory.createConnection(conf); 2292 Table t = conn.getTable(TEST_TABLE);) { 2293 return t.get(new Get(TEST_ROW)); 2294 } 2295 } 2296 }; 2297 2298 String namespace = TEST_TABLE.getNamespaceAsString(); 2299 2300 // Grant namespace READ to USER_NONE, this should supersede any table permissions 2301 grantOnNamespace(TEST_UTIL, USER_NONE.getShortName(), namespace, Permission.Action.READ); 2302 // Now USER_NONE should be able to read 2303 verifyAllowed(getAction, USER_NONE); 2304 2305 // Revoke namespace READ to USER_NONE 2306 revokeFromNamespace(TEST_UTIL, USER_NONE.getShortName(), namespace, Permission.Action.READ); 2307 verifyDenied(getAction, USER_NONE); 2308 } 2309 2310 @Test 2311 public void testAccessControlClientGrantRevoke() throws Exception { 2312 // Create user for testing, who has no READ privileges by default. 2313 User testGrantRevoke = User.createUserForTesting(conf, "testGrantRevoke", new String[0]); 2314 AccessTestAction getAction = new AccessTestAction() { 2315 @Override 2316 public Object run() throws Exception { 2317 try(Connection conn = ConnectionFactory.createConnection(conf); 2318 Table t = conn.getTable(TEST_TABLE);) { 2319 return t.get(new Get(TEST_ROW)); 2320 } 2321 } 2322 }; 2323 2324 verifyDenied(getAction, testGrantRevoke); 2325 2326 // Grant table READ permissions to testGrantRevoke. 2327 try { 2328 grantOnTableUsingAccessControlClient(TEST_UTIL, systemUserConnection, 2329 testGrantRevoke.getShortName(), TEST_TABLE, null, null, Permission.Action.READ); 2330 } catch (Throwable e) { 2331 LOG.error("error during call of AccessControlClient.grant. ", e); 2332 } 2333 2334 // Now testGrantRevoke should be able to read also 2335 verifyAllowed(getAction, testGrantRevoke); 2336 2337 // Revoke table READ permission to testGrantRevoke. 2338 try { 2339 revokeFromTableUsingAccessControlClient(TEST_UTIL, systemUserConnection, 2340 testGrantRevoke.getShortName(), TEST_TABLE, null, null, Permission.Action.READ); 2341 } catch (Throwable e) { 2342 LOG.error("error during call of AccessControlClient.revoke ", e); 2343 } 2344 2345 // Now testGrantRevoke shouldn't be able read 2346 verifyDenied(getAction, testGrantRevoke); 2347 } 2348 2349 @Test 2350 public void testAccessControlClientGlobalGrantRevoke() throws Exception { 2351 // Create user for testing, who has no READ privileges by default. 2352 User testGlobalGrantRevoke = User.createUserForTesting(conf, 2353 "testGlobalGrantRevoke", new String[0]); 2354 AccessTestAction getAction = new AccessTestAction() { 2355 @Override 2356 public Object run() throws Exception { 2357 try(Connection conn = ConnectionFactory.createConnection(conf); 2358 Table t = conn.getTable(TEST_TABLE)) { 2359 return t.get(new Get(TEST_ROW)); 2360 } 2361 } 2362 }; 2363 2364 verifyDenied(getAction, testGlobalGrantRevoke); 2365 2366 // Grant table READ permissions to testGlobalGrantRevoke. 2367 String userName = testGlobalGrantRevoke.getShortName(); 2368 try { 2369 grantGlobalUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2370 Permission.Action.READ); 2371 } catch (Throwable e) { 2372 LOG.error("error during call of AccessControlClient.grant. ", e); 2373 } 2374 try { 2375 // Now testGlobalGrantRevoke should be able to read also 2376 verifyAllowed(getAction, testGlobalGrantRevoke); 2377 } catch (Exception e) { 2378 revokeGlobal(TEST_UTIL, userName, Permission.Action.READ); 2379 throw e; 2380 } 2381 2382 // Revoke table READ permission to testGlobalGrantRevoke. 2383 try { 2384 revokeGlobalUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2385 Permission.Action.READ); 2386 } catch (Throwable e) { 2387 LOG.error("error during call of AccessControlClient.revoke ", e); 2388 } 2389 2390 // Now testGlobalGrantRevoke shouldn't be able read 2391 verifyDenied(getAction, testGlobalGrantRevoke); 2392 2393 } 2394 2395 @Test 2396 public void testAccessControlClientMultiGrantRevoke() throws Exception { 2397 User testGrantRevoke = 2398 User.createUserForTesting(conf, "testGrantRevoke", new String[0]); 2399 AccessTestAction getAction = new AccessTestAction() { 2400 @Override 2401 public Object run() throws Exception { 2402 try(Connection conn = ConnectionFactory.createConnection(conf); 2403 Table t = conn.getTable(TEST_TABLE)) { 2404 return t.get(new Get(TEST_ROW)); 2405 } 2406 } 2407 }; 2408 2409 AccessTestAction putAction = new AccessTestAction() { 2410 @Override 2411 public Object run() throws Exception { 2412 Put p = new Put(TEST_ROW); 2413 p.addColumn(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(1)); 2414 try(Connection conn = ConnectionFactory.createConnection(conf); 2415 Table t = conn.getTable(TEST_TABLE)) { 2416 t.put(p); 2417 return null; 2418 } 2419 } 2420 }; 2421 2422 verifyDenied(getAction, testGrantRevoke); 2423 verifyDenied(putAction, testGrantRevoke); 2424 2425 // Grant global READ permissions to testGrantRevoke. 2426 String userName = testGrantRevoke.getShortName(); 2427 try { 2428 grantGlobalUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2429 Permission.Action.READ); 2430 } catch (Throwable e) { 2431 LOG.error("error during call of AccessControlClient.grant. ", e); 2432 } 2433 verifyAllowed(getAction, testGrantRevoke); 2434 verifyDenied(putAction, testGrantRevoke); 2435 2436 // Grant global WRITE permissions to testGrantRevoke. 2437 try { 2438 grantGlobalUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2439 Permission.Action.WRITE); 2440 } catch (Throwable e) { 2441 LOG.error("error during call of AccessControlClient.grant. ", e); 2442 } 2443 verifyAllowed(getAction, testGrantRevoke); 2444 verifyAllowed(putAction, testGrantRevoke); 2445 2446 // Revoke global READ permission to testGrantRevoke. 2447 try { 2448 revokeGlobalUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2449 Permission.Action.READ, Permission.Action.WRITE); 2450 } catch (Throwable e) { 2451 LOG.error("error during call of AccessControlClient.revoke ", e); 2452 } 2453 verifyDenied(getAction, testGrantRevoke); 2454 verifyDenied(putAction, testGrantRevoke); 2455 2456 // Grant table READ & WRITE permissions to testGrantRevoke 2457 try { 2458 grantOnTableUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, TEST_TABLE, 2459 null, null, Permission.Action.READ); 2460 } catch (Throwable e) { 2461 LOG.error("error during call of AccessControlClient.grant. ", e); 2462 } 2463 verifyAllowed(getAction, testGrantRevoke); 2464 verifyDenied(putAction, testGrantRevoke); 2465 2466 // Grant table WRITE permissions to testGrantRevoke 2467 try { 2468 grantOnTableUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, TEST_TABLE, 2469 null, null, Action.WRITE); 2470 } catch (Throwable e) { 2471 LOG.error("error during call of AccessControlClient.grant. ", e); 2472 } 2473 verifyAllowed(getAction, testGrantRevoke); 2474 verifyAllowed(putAction, testGrantRevoke); 2475 2476 // Revoke table READ & WRITE permission to testGrantRevoke. 2477 try { 2478 revokeFromTableUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, TEST_TABLE, null, null, 2479 Permission.Action.READ, Permission.Action.WRITE); 2480 } catch (Throwable e) { 2481 LOG.error("error during call of AccessControlClient.revoke ", e); 2482 } 2483 verifyDenied(getAction, testGrantRevoke); 2484 verifyDenied(putAction, testGrantRevoke); 2485 2486 // Grant Namespace READ permissions to testGrantRevoke 2487 String namespace = TEST_TABLE.getNamespaceAsString(); 2488 try { 2489 grantOnNamespaceUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2490 namespace, Permission.Action.READ); 2491 } catch (Throwable e) { 2492 LOG.error("error during call of AccessControlClient.grant. ", e); 2493 } 2494 verifyAllowed(getAction, testGrantRevoke); 2495 verifyDenied(putAction, testGrantRevoke); 2496 2497 // Grant Namespace WRITE permissions to testGrantRevoke 2498 try { 2499 grantOnNamespaceUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2500 namespace, Permission.Action.WRITE); 2501 } catch (Throwable e) { 2502 LOG.error("error during call of AccessControlClient.grant. ", e); 2503 } 2504 verifyAllowed(getAction, testGrantRevoke); 2505 verifyAllowed(putAction, testGrantRevoke); 2506 2507 // Revoke table READ & WRITE permission to testGrantRevoke. 2508 try { 2509 revokeFromNamespaceUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2510 TEST_TABLE.getNamespaceAsString(), Permission.Action.READ, Permission.Action.WRITE); 2511 } catch (Throwable e) { 2512 LOG.error("error during call of AccessControlClient.revoke ", e); 2513 } 2514 verifyDenied(getAction, testGrantRevoke); 2515 verifyDenied(putAction, testGrantRevoke); 2516 } 2517 2518 @Test 2519 public void testAccessControlClientGrantRevokeOnNamespace() throws Exception { 2520 // Create user for testing, who has no READ privileges by default. 2521 User testNS = User.createUserForTesting(conf, "testNS", new String[0]); 2522 AccessTestAction getAction = new AccessTestAction() { 2523 @Override 2524 public Object run() throws Exception { 2525 try(Connection conn = ConnectionFactory.createConnection(conf); 2526 Table t = conn.getTable(TEST_TABLE);) { 2527 return t.get(new Get(TEST_ROW)); 2528 } 2529 } 2530 }; 2531 2532 verifyDenied(getAction, testNS); 2533 2534 String userName = testNS.getShortName(); 2535 String namespace = TEST_TABLE.getNamespaceAsString(); 2536 // Grant namespace READ to testNS, this should supersede any table permissions 2537 try { 2538 grantOnNamespaceUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, namespace, 2539 Permission.Action.READ); 2540 } catch (Throwable e) { 2541 LOG.error("error during call of AccessControlClient.grant. ", e); 2542 } 2543 try { 2544 // Now testNS should be able to read also 2545 verifyAllowed(getAction, testNS); 2546 } catch (Exception e) { 2547 revokeFromNamespace(TEST_UTIL, userName, namespace, Permission.Action.READ); 2548 throw e; 2549 } 2550 2551 // Revoke namespace READ to testNS, this should supersede any table permissions 2552 try { 2553 revokeFromNamespaceUsingAccessControlClient(TEST_UTIL, systemUserConnection, userName, 2554 namespace, Permission.Action.READ); 2555 } catch (Throwable e) { 2556 LOG.error("error during call of AccessControlClient.revoke ", e); 2557 } 2558 2559 // Now testNS shouldn't be able read 2560 verifyDenied(getAction, testNS); 2561 } 2562 2563 2564 public static class PingCoprocessor extends PingService implements RegionCoprocessor { 2565 2566 @Override 2567 public void start(CoprocessorEnvironment env) throws IOException { } 2568 2569 @Override 2570 public void stop(CoprocessorEnvironment env) throws IOException { } 2571 2572 @Override 2573 public Iterable<Service> getServices() { 2574 return Collections.singleton(this); 2575 } 2576 2577 @Override 2578 public void ping(RpcController controller, PingRequest request, 2579 RpcCallback<PingResponse> callback) { 2580 callback.run(PingResponse.newBuilder().setPong("Pong!").build()); 2581 } 2582 2583 @Override 2584 public void count(RpcController controller, CountRequest request, 2585 RpcCallback<CountResponse> callback) { 2586 callback.run(CountResponse.newBuilder().build()); 2587 } 2588 2589 @Override 2590 public void increment(RpcController controller, IncrementCountRequest requet, 2591 RpcCallback<IncrementCountResponse> callback) { 2592 callback.run(IncrementCountResponse.newBuilder().build()); 2593 } 2594 2595 @Override 2596 public void hello(RpcController controller, HelloRequest request, 2597 RpcCallback<HelloResponse> callback) { 2598 callback.run(HelloResponse.newBuilder().setResponse("Hello!").build()); 2599 } 2600 2601 @Override 2602 public void noop(RpcController controller, NoopRequest request, 2603 RpcCallback<NoopResponse> callback) { 2604 callback.run(NoopResponse.newBuilder().build()); 2605 } 2606 } 2607 2608 @Test 2609 public void testCoprocessorExec() throws Exception { 2610 // Set up our ping endpoint service on all regions of our test table 2611 for (JVMClusterUtil.RegionServerThread thread: 2612 TEST_UTIL.getMiniHBaseCluster().getRegionServerThreads()) { 2613 HRegionServer rs = thread.getRegionServer(); 2614 for (HRegion region: rs.getRegions(TEST_TABLE)) { 2615 region.getCoprocessorHost().load(PingCoprocessor.class, 2616 Coprocessor.PRIORITY_USER, conf); 2617 } 2618 } 2619 2620 // Create users for testing, and grant EXEC privileges on our test table 2621 // only to user A 2622 User userA = User.createUserForTesting(conf, "UserA", new String[0]); 2623 User userB = User.createUserForTesting(conf, "UserB", new String[0]); 2624 2625 grantOnTable(TEST_UTIL, userA.getShortName(), 2626 TEST_TABLE, null, null, 2627 Permission.Action.EXEC); 2628 try { 2629 // Create an action for invoking our test endpoint 2630 AccessTestAction execEndpointAction = new AccessTestAction() { 2631 @Override 2632 public Object run() throws Exception { 2633 try (Connection conn = ConnectionFactory.createConnection(conf); 2634 Table t = conn.getTable(TEST_TABLE);) { 2635 BlockingRpcChannel service = t.coprocessorService(HConstants.EMPTY_BYTE_ARRAY); 2636 PingCoprocessor.newBlockingStub(service).noop(null, NoopRequest.newBuilder().build()); 2637 } 2638 return null; 2639 } 2640 }; 2641 2642 String namespace = TEST_TABLE.getNamespaceAsString(); 2643 // Now grant EXEC to the entire namespace to user B 2644 grantOnNamespace(TEST_UTIL, userB.getShortName(), namespace, Permission.Action.EXEC); 2645 // User B should now be allowed also 2646 verifyAllowed(execEndpointAction, userA, userB); 2647 2648 revokeFromNamespace(TEST_UTIL, userB.getShortName(), namespace, Permission.Action.EXEC); 2649 // Verify that EXEC permission is checked correctly 2650 verifyDenied(execEndpointAction, userB); 2651 verifyAllowed(execEndpointAction, userA); 2652 } finally { 2653 // Cleanup, revoke the userA privileges 2654 revokeFromTable(TEST_UTIL, userA.getShortName(), TEST_TABLE, null, null, 2655 Permission.Action.EXEC); 2656 } 2657 } 2658 2659 @Test 2660 public void testSetQuota() throws Exception { 2661 AccessTestAction setUserQuotaAction = new AccessTestAction() { 2662 @Override 2663 public Object run() throws Exception { 2664 ACCESS_CONTROLLER.preSetUserQuota(ObserverContextImpl.createAndPrepare(CP_ENV), 2665 null, null); 2666 return null; 2667 } 2668 }; 2669 2670 AccessTestAction setUserTableQuotaAction = new AccessTestAction() { 2671 @Override 2672 public Object run() throws Exception { 2673 ACCESS_CONTROLLER.preSetUserQuota(ObserverContextImpl.createAndPrepare(CP_ENV), null, 2674 TEST_TABLE, null); 2675 return null; 2676 } 2677 }; 2678 2679 AccessTestAction setUserNamespaceQuotaAction = new AccessTestAction() { 2680 @Override 2681 public Object run() throws Exception { 2682 ACCESS_CONTROLLER.preSetUserQuota(ObserverContextImpl.createAndPrepare(CP_ENV), 2683 null, (String)null, null); 2684 return null; 2685 } 2686 }; 2687 2688 AccessTestAction setTableQuotaAction = new AccessTestAction() { 2689 @Override 2690 public Object run() throws Exception { 2691 ACCESS_CONTROLLER.preSetTableQuota(ObserverContextImpl.createAndPrepare(CP_ENV), 2692 TEST_TABLE, null); 2693 return null; 2694 } 2695 }; 2696 2697 AccessTestAction setNamespaceQuotaAction = new AccessTestAction() { 2698 @Override 2699 public Object run() throws Exception { 2700 ACCESS_CONTROLLER.preSetNamespaceQuota(ObserverContextImpl.createAndPrepare(CP_ENV), 2701 null, null); 2702 return null; 2703 } 2704 }; 2705 2706 AccessTestAction setRegionServerQuotaAction = new AccessTestAction() { 2707 @Override 2708 public Object run() throws Exception { 2709 ACCESS_CONTROLLER.preSetRegionServerQuota(ObserverContextImpl.createAndPrepare(CP_ENV), 2710 null, null); 2711 return null; 2712 } 2713 }; 2714 2715 verifyAllowed(setUserQuotaAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 2716 verifyDenied(setUserQuotaAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, 2717 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 2718 2719 verifyAllowed(setUserTableQuotaAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 2720 verifyDenied(setUserTableQuotaAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, 2721 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 2722 2723 verifyAllowed(setUserNamespaceQuotaAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 2724 verifyDenied(setUserNamespaceQuotaAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, 2725 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 2726 2727 verifyAllowed(setTableQuotaAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); 2728 verifyDenied(setTableQuotaAction, USER_CREATE, USER_RW, USER_RO, USER_NONE); 2729 2730 verifyAllowed(setNamespaceQuotaAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 2731 verifyDenied(setNamespaceQuotaAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, 2732 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 2733 2734 verifyAllowed(setRegionServerQuotaAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 2735 verifyDenied(setRegionServerQuotaAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, 2736 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); 2737 } 2738 2739 @Test 2740 public void testGetNamespacePermission() throws Exception { 2741 String namespace = "testGetNamespacePermission"; 2742 NamespaceDescriptor desc = NamespaceDescriptor.create(namespace).build(); 2743 createNamespace(TEST_UTIL, desc); 2744 grantOnNamespace(TEST_UTIL, USER_NONE.getShortName(), namespace, Permission.Action.READ); 2745 2746 // Test 1: A specific namespace 2747 getNamespacePermissionsAndVerify(namespace, 1, namespace); 2748 2749 // Test 2: '@.*' 2750 getNamespacePermissionsAndVerify(".*", 1, namespace); 2751 2752 // Test 3: A more complex regex 2753 getNamespacePermissionsAndVerify("^test[a-zA-Z]*", 1, namespace); 2754 2755 deleteNamespace(TEST_UTIL, namespace); 2756 } 2757 2758 /** 2759 * List all user permissions match the given regular expression for namespace 2760 * and verify each of them. 2761 * @param namespaceRegexWithoutPrefix the regualar expression for namespace, without NAMESPACE_PREFIX 2762 * @param expectedAmount the expected amount of user permissions returned 2763 * @param expectedNamespace the expected namespace of each user permission returned 2764 * @throws HBaseException in the case of any HBase exception when accessing hbase:acl table 2765 */ 2766 private void getNamespacePermissionsAndVerify(String namespaceRegexWithoutPrefix, 2767 int expectedAmount, String expectedNamespace) throws HBaseException { 2768 try { 2769 List<UserPermission> namespacePermissions = AccessControlClient.getUserPermissions( 2770 systemUserConnection, AccessControlLists.toNamespaceEntry(namespaceRegexWithoutPrefix)); 2771 assertTrue(namespacePermissions != null); 2772 assertEquals(expectedAmount, namespacePermissions.size()); 2773 for (UserPermission namespacePermission : namespacePermissions) { 2774 // Verify it is not a global user permission 2775 assertFalse(namespacePermission.getAccessScope() == Permission.Scope.GLOBAL); 2776 // Verify namespace is set 2777 NamespacePermission nsPerm = (NamespacePermission) namespacePermission.getPermission(); 2778 assertEquals(expectedNamespace, nsPerm.getNamespace()); 2779 } 2780 } catch (Throwable thw) { 2781 throw new HBaseException(thw); 2782 } 2783 } 2784 2785 @Test 2786 public void testTruncatePerms() throws Exception { 2787 try { 2788 List<UserPermission> existingPerms = AccessControlClient.getUserPermissions( 2789 systemUserConnection, TEST_TABLE.getNameAsString()); 2790 assertTrue(existingPerms != null); 2791 assertTrue(existingPerms.size() > 1); 2792 TEST_UTIL.getAdmin().disableTable(TEST_TABLE); 2793 TEST_UTIL.truncateTable(TEST_TABLE); 2794 TEST_UTIL.waitTableAvailable(TEST_TABLE); 2795 List<UserPermission> perms = AccessControlClient.getUserPermissions( 2796 systemUserConnection, TEST_TABLE.getNameAsString()); 2797 assertTrue(perms != null); 2798 assertEquals(existingPerms.size(), perms.size()); 2799 } catch (Throwable e) { 2800 throw new HBaseIOException(e); 2801 } 2802 } 2803 2804 private PrivilegedAction<List<UserPermission>> getPrivilegedAction(final String regex) { 2805 return new PrivilegedAction<List<UserPermission>>() { 2806 @Override 2807 public List<UserPermission> run() { 2808 try(Connection conn = ConnectionFactory.createConnection(conf);) { 2809 return AccessControlClient.getUserPermissions(conn, regex); 2810 } catch (Throwable e) { 2811 LOG.error("error during call of AccessControlClient.getUserPermissions.", e); 2812 return null; 2813 } 2814 } 2815 }; 2816 } 2817 2818 @Test 2819 public void testAccessControlClientUserPerms() throws Exception { 2820 final TableName tableName = TableName.valueOf(name.getMethodName()); 2821 createTestTable(tableName); 2822 try { 2823 final String regex = tableName.getNameWithNamespaceInclAsString(); 2824 User testUserPerms = User.createUserForTesting(conf, "testUserPerms", new String[0]); 2825 assertEquals(0, testUserPerms.runAs(getPrivilegedAction(regex)).size()); 2826 // Grant TABLE ADMIN privs to testUserPerms 2827 grantOnTable(TEST_UTIL, testUserPerms.getShortName(), tableName, null, null, Action.ADMIN); 2828 List<UserPermission> perms = testUserPerms.runAs(getPrivilegedAction(regex)); 2829 assertNotNull(perms); 2830 // Superuser, testUserPerms 2831 assertEquals(2, perms.size()); 2832 } finally { 2833 deleteTable(TEST_UTIL, tableName); 2834 } 2835 } 2836 2837 @Test 2838 public void testAccessControllerUserPermsRegexHandling() throws Exception { 2839 User testRegexHandler = User.createUserForTesting(conf, "testRegexHandling", new String[0]); 2840 2841 final String REGEX_ALL_TABLES = ".*"; 2842 final String tableName = name.getMethodName(); 2843 final TableName table1 = TableName.valueOf(tableName); 2844 final byte[] family = Bytes.toBytes("f1"); 2845 2846 // create table in default ns 2847 Admin admin = TEST_UTIL.getAdmin(); 2848 HTableDescriptor htd = new HTableDescriptor(table1); 2849 htd.addFamily(new HColumnDescriptor(family)); 2850 createTable(TEST_UTIL, htd); 2851 2852 // creating the ns and table in it 2853 String ns = "testNamespace"; 2854 NamespaceDescriptor desc = NamespaceDescriptor.create(ns).build(); 2855 final TableName table2 = TableName.valueOf(ns, tableName); 2856 createNamespace(TEST_UTIL, desc); 2857 htd = new HTableDescriptor(table2); 2858 htd.addFamily(new HColumnDescriptor(family)); 2859 createTable(TEST_UTIL, htd); 2860 2861 // Verify that we can read sys-tables 2862 String aclTableName = AccessControlLists.ACL_TABLE_NAME.getNameAsString(); 2863 assertEquals(5, SUPERUSER.runAs(getPrivilegedAction(aclTableName)).size()); 2864 assertEquals(0, testRegexHandler.runAs(getPrivilegedAction(aclTableName)).size()); 2865 2866 // Grant TABLE ADMIN privs to testUserPerms 2867 assertEquals(0, testRegexHandler.runAs(getPrivilegedAction(REGEX_ALL_TABLES)).size()); 2868 grantOnTable(TEST_UTIL, testRegexHandler.getShortName(), table1, null, null, Action.ADMIN); 2869 assertEquals(2, testRegexHandler.runAs(getPrivilegedAction(REGEX_ALL_TABLES)).size()); 2870 grantOnTable(TEST_UTIL, testRegexHandler.getShortName(), table2, null, null, Action.ADMIN); 2871 assertEquals(4, testRegexHandler.runAs(getPrivilegedAction(REGEX_ALL_TABLES)).size()); 2872 2873 // USER_ADMIN, testUserPerms must have a row each. 2874 assertEquals(2, testRegexHandler.runAs(getPrivilegedAction(tableName)).size()); 2875 assertEquals(2, testRegexHandler.runAs(getPrivilegedAction( 2876 NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR + TableName.NAMESPACE_DELIM + tableName) 2877 ).size()); 2878 assertEquals(2, testRegexHandler.runAs(getPrivilegedAction( 2879 ns + TableName.NAMESPACE_DELIM + tableName)).size()); 2880 assertEquals(0, testRegexHandler.runAs(getPrivilegedAction("notMatchingAny")).size()); 2881 2882 deleteTable(TEST_UTIL, table1); 2883 deleteTable(TEST_UTIL, table2); 2884 deleteNamespace(TEST_UTIL, ns); 2885 } 2886 2887 private void verifyAnyCreate(AccessTestAction action) throws Exception { 2888 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_ADMIN_CF, 2889 USER_GROUP_CREATE); 2890 verifyDenied(action, USER_NONE, USER_RO, USER_RW, USER_GROUP_READ, USER_GROUP_WRITE, 2891 USER_GROUP_ADMIN); 2892 } 2893 2894 @Test 2895 public void testPrepareAndCleanBulkLoad() throws Exception { 2896 AccessTestAction prepareBulkLoadAction = new AccessTestAction() { 2897 @Override 2898 public Object run() throws Exception { 2899 ACCESS_CONTROLLER.prePrepareBulkLoad(ObserverContextImpl.createAndPrepare(RCP_ENV)); 2900 return null; 2901 } 2902 }; 2903 AccessTestAction cleanupBulkLoadAction = new AccessTestAction() { 2904 @Override 2905 public Object run() throws Exception { 2906 ACCESS_CONTROLLER.preCleanupBulkLoad(ObserverContextImpl.createAndPrepare(RCP_ENV)); 2907 return null; 2908 } 2909 }; 2910 verifyAnyCreate(prepareBulkLoadAction); 2911 verifyAnyCreate(cleanupBulkLoadAction); 2912 } 2913 2914 @Test 2915 public void testReplicateLogEntries() throws Exception { 2916 AccessTestAction replicateLogEntriesAction = new AccessTestAction() { 2917 @Override 2918 public Object run() throws Exception { 2919 ACCESS_CONTROLLER.preReplicateLogEntries(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 2920 ACCESS_CONTROLLER.postReplicateLogEntries(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 2921 return null; 2922 } 2923 }; 2924 2925 verifyAllowed(replicateLogEntriesAction, SUPERUSER, USER_ADMIN, USER_GROUP_WRITE); 2926 verifyDenied(replicateLogEntriesAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, 2927 USER_GROUP_READ, USER_GROUP_ADMIN, USER_GROUP_CREATE); 2928 } 2929 2930 @Test 2931 public void testAddReplicationPeer() throws Exception { 2932 AccessTestAction action = new AccessTestAction() { 2933 @Override 2934 public Object run() throws Exception { 2935 ACCESS_CONTROLLER.preAddReplicationPeer(ObserverContextImpl.createAndPrepare(CP_ENV), 2936 "test", null); 2937 return null; 2938 } 2939 }; 2940 2941 verifyAllowed(action, SUPERUSER, USER_ADMIN); 2942 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 2943 } 2944 2945 @Test 2946 public void testRemoveReplicationPeer() throws Exception { 2947 AccessTestAction action = new AccessTestAction() { 2948 @Override 2949 public Object run() throws Exception { 2950 ACCESS_CONTROLLER.preRemoveReplicationPeer(ObserverContextImpl.createAndPrepare(CP_ENV), 2951 "test"); 2952 return null; 2953 } 2954 }; 2955 2956 verifyAllowed(action, SUPERUSER, USER_ADMIN); 2957 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 2958 } 2959 2960 @Test 2961 public void testEnableReplicationPeer() throws Exception { 2962 AccessTestAction action = new AccessTestAction() { 2963 @Override 2964 public Object run() throws Exception { 2965 ACCESS_CONTROLLER.preEnableReplicationPeer(ObserverContextImpl.createAndPrepare(CP_ENV), 2966 "test"); 2967 return null; 2968 } 2969 }; 2970 2971 verifyAllowed(action, SUPERUSER, USER_ADMIN); 2972 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 2973 } 2974 2975 @Test 2976 public void testDisableReplicationPeer() throws Exception { 2977 AccessTestAction action = new AccessTestAction() { 2978 @Override 2979 public Object run() throws Exception { 2980 ACCESS_CONTROLLER.preDisableReplicationPeer(ObserverContextImpl.createAndPrepare(CP_ENV), 2981 "test"); 2982 return null; 2983 } 2984 }; 2985 2986 verifyAllowed(action, SUPERUSER, USER_ADMIN); 2987 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 2988 } 2989 2990 @Test 2991 public void testGetReplicationPeerConfig() throws Exception { 2992 AccessTestAction action = new AccessTestAction() { 2993 @Override 2994 public Object run() throws Exception { 2995 ACCESS_CONTROLLER.preGetReplicationPeerConfig( 2996 ObserverContextImpl.createAndPrepare(CP_ENV), "test"); 2997 return null; 2998 } 2999 }; 3000 3001 verifyAllowed(action, SUPERUSER, USER_ADMIN); 3002 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 3003 } 3004 3005 @Test 3006 public void testUpdateReplicationPeerConfig() throws Exception { 3007 AccessTestAction action = new AccessTestAction() { 3008 @Override 3009 public Object run() throws Exception { 3010 ACCESS_CONTROLLER.preUpdateReplicationPeerConfig( 3011 ObserverContextImpl.createAndPrepare(CP_ENV), "test", new ReplicationPeerConfig()); 3012 return null; 3013 } 3014 }; 3015 3016 verifyAllowed(action, SUPERUSER, USER_ADMIN); 3017 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 3018 } 3019 3020 @Test 3021 public void testListReplicationPeers() throws Exception { 3022 AccessTestAction action = new AccessTestAction() { 3023 @Override 3024 public Object run() throws Exception { 3025 ACCESS_CONTROLLER.preListReplicationPeers(ObserverContextImpl.createAndPrepare(CP_ENV), 3026 "test"); 3027 return null; 3028 } 3029 }; 3030 3031 verifyAllowed(action, SUPERUSER, USER_ADMIN); 3032 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 3033 } 3034 3035 @Test 3036 public void testRemoteLocks() throws Exception { 3037 String namespace = "preQueueNs"; 3038 final TableName tableName = TableName.valueOf(namespace, name.getMethodName()); 3039 HRegionInfo[] regionInfos = new HRegionInfo[] {new HRegionInfo(tableName)}; 3040 3041 // Setup Users 3042 // User will be granted ADMIN and CREATE on namespace. Should be denied before grant. 3043 User namespaceUser = User.createUserForTesting(conf, "qLNSUser", new String[0]); 3044 // User will be granted ADMIN and CREATE on table. Should be denied before grant. 3045 User tableACUser = User.createUserForTesting(conf, "qLTableACUser", new String[0]); 3046 // User will be granted READ, WRITE, EXECUTE on table. Should be denied. 3047 User tableRWXUser = User.createUserForTesting(conf, "qLTableRWXUser", new String[0]); 3048 grantOnTable(TEST_UTIL, tableRWXUser.getShortName(), tableName, null, null, 3049 Action.READ, Action.WRITE, Action.EXEC); 3050 // User with global READ, WRITE, EXECUTE should be denied lock access. 3051 User globalRWXUser = User.createUserForTesting(conf, "qLGlobalRWXUser", new String[0]); 3052 grantGlobal(TEST_UTIL, globalRWXUser.getShortName(), Action.READ, Action.WRITE, Action.EXEC); 3053 3054 AccessTestAction namespaceLockAction = new AccessTestAction() { 3055 @Override public Object run() throws Exception { 3056 ACCESS_CONTROLLER.preRequestLock(ObserverContextImpl.createAndPrepare(CP_ENV), namespace, 3057 null, null, null); 3058 return null; 3059 } 3060 }; 3061 verifyAllowed(namespaceLockAction, SUPERUSER, USER_ADMIN); 3062 verifyDenied(namespaceLockAction, globalRWXUser, tableACUser, namespaceUser, tableRWXUser); 3063 grantOnNamespace(TEST_UTIL, namespaceUser.getShortName(), namespace, Action.ADMIN); 3064 // Why I need this pause? I don't need it elsewhere. 3065 Threads.sleep(1000); 3066 verifyAllowed(namespaceLockAction, namespaceUser); 3067 3068 AccessTestAction tableLockAction = new AccessTestAction() { 3069 @Override public Object run() throws Exception { 3070 ACCESS_CONTROLLER.preRequestLock(ObserverContextImpl.createAndPrepare(CP_ENV), 3071 null, tableName, null, null); 3072 return null; 3073 } 3074 }; 3075 verifyAllowed(tableLockAction, SUPERUSER, USER_ADMIN, namespaceUser); 3076 verifyDenied(tableLockAction, globalRWXUser, tableACUser, tableRWXUser); 3077 grantOnTable(TEST_UTIL, tableACUser.getShortName(), tableName, null, null, 3078 Action.ADMIN, Action.CREATE); 3079 verifyAllowed(tableLockAction, tableACUser); 3080 3081 AccessTestAction regionsLockAction = new AccessTestAction() { 3082 @Override public Object run() throws Exception { 3083 ACCESS_CONTROLLER.preRequestLock(ObserverContextImpl.createAndPrepare(CP_ENV), 3084 null, null, regionInfos, null); 3085 return null; 3086 } 3087 }; 3088 verifyAllowed(regionsLockAction, SUPERUSER, USER_ADMIN, namespaceUser, tableACUser); 3089 verifyDenied(regionsLockAction, globalRWXUser, tableRWXUser); 3090 3091 // Test heartbeats 3092 // Create a lock procedure and try sending heartbeat to it. It doesn't matter how the lock 3093 // was created, we just need namespace from the lock's tablename. 3094 LockProcedure proc = new LockProcedure(conf, tableName, LockType.EXCLUSIVE, "test", null); 3095 AccessTestAction regionLockHeartbeatAction = new AccessTestAction() { 3096 @Override public Object run() throws Exception { 3097 ACCESS_CONTROLLER.preLockHeartbeat(ObserverContextImpl.createAndPrepare(CP_ENV), 3098 proc.getTableName(), proc.getDescription()); 3099 return null; 3100 } 3101 }; 3102 verifyAllowed(regionLockHeartbeatAction, SUPERUSER, USER_ADMIN, namespaceUser, tableACUser); 3103 verifyDenied(regionLockHeartbeatAction, globalRWXUser, tableRWXUser); 3104 } 3105 3106 @Test 3107 public void testAccessControlRevokeOnlyFewPermission() throws Throwable { 3108 TableName tname = TableName.valueOf("revoke"); 3109 try { 3110 TEST_UTIL.createTable(tname, TEST_FAMILY); 3111 User testUserPerms = User.createUserForTesting(conf, "revokePerms", new String[0]); 3112 Permission.Action[] actions = { Action.READ, Action.WRITE }; 3113 AccessControlClient.grant(TEST_UTIL.getConnection(), tname, testUserPerms.getShortName(), 3114 null, null, actions); 3115 3116 List<UserPermission> userPermissions = AccessControlClient 3117 .getUserPermissions(TEST_UTIL.getConnection(), tname.getNameAsString()); 3118 assertEquals(2, userPermissions.size()); 3119 3120 AccessControlClient.revoke(TEST_UTIL.getConnection(), tname, testUserPerms.getShortName(), 3121 null, null, Action.WRITE); 3122 3123 userPermissions = AccessControlClient.getUserPermissions(TEST_UTIL.getConnection(), 3124 tname.getNameAsString()); 3125 assertEquals(2, userPermissions.size()); 3126 3127 Permission.Action[] expectedAction = { Action.READ }; 3128 boolean userFound = false; 3129 for (UserPermission p : userPermissions) { 3130 if (testUserPerms.getShortName().equals(p.getUser())) { 3131 assertArrayEquals(expectedAction, p.getPermission().getActions()); 3132 userFound = true; 3133 break; 3134 } 3135 } 3136 assertTrue(userFound); 3137 } finally { 3138 TEST_UTIL.deleteTable(tname); 3139 } 3140 } 3141 3142 @Test 3143 public void testGetClusterStatus() throws Exception { 3144 AccessTestAction action = new AccessTestAction() { 3145 @Override 3146 public Object run() throws Exception { 3147 ACCESS_CONTROLLER.preGetClusterMetrics(ObserverContextImpl.createAndPrepare(CP_ENV)); 3148 return null; 3149 } 3150 }; 3151 3152 verifyAllowed( 3153 action, SUPERUSER, USER_ADMIN, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 3154 } 3155 3156 @Test 3157 public void testExecuteProcedures() throws Exception { 3158 AccessTestAction action = new AccessTestAction() { 3159 @Override 3160 public Object run() throws Exception { 3161 ACCESS_CONTROLLER.preExecuteProcedures(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 3162 return null; 3163 } 3164 }; 3165 3166 verifyAllowed(action, SUPERUSER); 3167 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, USER_ADMIN); 3168 } 3169 3170 @Test 3171 public void testGetUserPermissions() throws Throwable { 3172 Connection conn = null; 3173 try { 3174 conn = ConnectionFactory.createConnection(conf); 3175 User nSUser1 = User.createUserForTesting(conf, "nsuser1", new String[0]); 3176 User nSUser2 = User.createUserForTesting(conf, "nsuser2", new String[0]); 3177 User nSUser3 = User.createUserForTesting(conf, "nsuser3", new String[0]); 3178 3179 // Global access groups 3180 User globalGroupUser1 = 3181 User.createUserForTesting(conf, "globalGroupUser1", new String[] { "group_admin" }); 3182 User globalGroupUser2 = User.createUserForTesting(conf, "globalGroupUser2", 3183 new String[] { "group_admin", "group_create" }); 3184 // Namespace access groups 3185 User nsGroupUser1 = 3186 User.createUserForTesting(conf, "nsGroupUser1", new String[] { "ns_group1" }); 3187 User nsGroupUser2 = 3188 User.createUserForTesting(conf, "nsGroupUser2", new String[] { "ns_group2" }); 3189 // table Access groups 3190 User tableGroupUser1 = 3191 User.createUserForTesting(conf, "tableGroupUser1", new String[] { "table_group1" }); 3192 User tableGroupUser2 = 3193 User.createUserForTesting(conf, "tableGroupUser2", new String[] { "table_group2" }); 3194 3195 // Create namespaces 3196 String nsPrefix = "testNS"; 3197 final String namespace1 = nsPrefix + "1"; 3198 NamespaceDescriptor desc1 = NamespaceDescriptor.create(namespace1).build(); 3199 createNamespace(TEST_UTIL, desc1); 3200 String namespace2 = nsPrefix + "2"; 3201 NamespaceDescriptor desc2 = NamespaceDescriptor.create(namespace2).build(); 3202 createNamespace(TEST_UTIL, desc2); 3203 3204 // Grant namespace permission 3205 grantOnNamespace(TEST_UTIL, nSUser1.getShortName(), namespace1, Permission.Action.ADMIN); 3206 grantOnNamespace(TEST_UTIL, nSUser3.getShortName(), namespace1, Permission.Action.READ); 3207 grantOnNamespace(TEST_UTIL, toGroupEntry("ns_group1"), namespace1, Permission.Action.ADMIN); 3208 grantOnNamespace(TEST_UTIL, nSUser2.getShortName(), namespace2, Permission.Action.ADMIN); 3209 grantOnNamespace(TEST_UTIL, nSUser3.getShortName(), namespace2, Permission.Action.ADMIN); 3210 grantOnNamespace(TEST_UTIL, toGroupEntry("ns_group2"), namespace2, Permission.Action.READ, 3211 Permission.Action.WRITE); 3212 3213 // Create tables 3214 TableName table1 = TableName.valueOf(namespace1 + TableName.NAMESPACE_DELIM + "t1"); 3215 TableName table2 = TableName.valueOf(namespace2 + TableName.NAMESPACE_DELIM + "t2"); 3216 byte[] TEST_FAMILY2 = Bytes.toBytes("f2"); 3217 byte[] TEST_QUALIFIER2 = Bytes.toBytes("q2"); 3218 createTestTable(table1, TEST_FAMILY); 3219 createTestTable(table2, TEST_FAMILY2); 3220 3221 // Grant table permissions 3222 grantOnTable(TEST_UTIL, toGroupEntry("table_group1"), table1, null, null, 3223 Permission.Action.ADMIN); 3224 grantOnTable(TEST_UTIL, USER_ADMIN.getShortName(), table1, null, null, 3225 Permission.Action.ADMIN); 3226 grantOnTable(TEST_UTIL, USER_ADMIN_CF.getShortName(), table1, TEST_FAMILY, null, 3227 Permission.Action.ADMIN); 3228 grantOnTable(TEST_UTIL, USER_RW.getShortName(), table1, TEST_FAMILY, TEST_QUALIFIER, 3229 Permission.Action.READ); 3230 grantOnTable(TEST_UTIL, USER_RW.getShortName(), table1, TEST_FAMILY, TEST_QUALIFIER2, 3231 Permission.Action.WRITE); 3232 3233 grantOnTable(TEST_UTIL, toGroupEntry("table_group2"), table2, null, null, 3234 Permission.Action.ADMIN); 3235 grantOnTable(TEST_UTIL, USER_ADMIN.getShortName(), table2, null, null, 3236 Permission.Action.ADMIN); 3237 grantOnTable(TEST_UTIL, USER_ADMIN_CF.getShortName(), table2, TEST_FAMILY2, null, 3238 Permission.Action.ADMIN); 3239 grantOnTable(TEST_UTIL, USER_RW.getShortName(), table2, TEST_FAMILY2, TEST_QUALIFIER, 3240 Permission.Action.READ); 3241 grantOnTable(TEST_UTIL, USER_RW.getShortName(), table2, TEST_FAMILY2, TEST_QUALIFIER2, 3242 Permission.Action.WRITE); 3243 3244 List<UserPermission> userPermissions = null; 3245 Collection<String> superUsers = Superusers.getSuperUsers(); 3246 int superUserCount = superUsers.size(); 3247 3248 // Global User ACL 3249 validateGlobalUserACLForGetUserPermissions(conn, nSUser1, globalGroupUser1, globalGroupUser2, 3250 superUsers, superUserCount); 3251 3252 // Namespace ACL 3253 validateNamespaceUserACLForGetUserPermissions(conn, nSUser1, nSUser3, nsGroupUser1, 3254 nsGroupUser2, nsPrefix, namespace1, namespace2); 3255 3256 // Table + Users 3257 validateTableACLForGetUserPermissions(conn, nSUser1, tableGroupUser1, tableGroupUser2, 3258 nsPrefix, table1, table2, TEST_QUALIFIER2, superUsers); 3259 3260 // exception scenarios 3261 3262 try { 3263 // test case with table name as null 3264 assertEquals(3, AccessControlClient.getUserPermissions(conn, null, TEST_FAMILY).size()); 3265 fail("this should have thrown IllegalArgumentException"); 3266 } catch (IllegalArgumentException ex) { 3267 // expected 3268 } 3269 try { 3270 // test case with table name as emplty 3271 assertEquals(3, AccessControlClient 3272 .getUserPermissions(conn, HConstants.EMPTY_STRING, TEST_FAMILY).size()); 3273 fail("this should have thrown IllegalArgumentException"); 3274 } catch (IllegalArgumentException ex) { 3275 // expected 3276 } 3277 try { 3278 // test case with table name as namespace name 3279 assertEquals(3, 3280 AccessControlClient.getUserPermissions(conn, "@" + namespace2, TEST_FAMILY).size()); 3281 fail("this should have thrown IllegalArgumentException"); 3282 } catch (IllegalArgumentException ex) { 3283 // expected 3284 } 3285 3286 // Clean the table and namespace 3287 deleteTable(TEST_UTIL, table1); 3288 deleteTable(TEST_UTIL, table2); 3289 deleteNamespace(TEST_UTIL, namespace1); 3290 deleteNamespace(TEST_UTIL, namespace2); 3291 } finally { 3292 if (conn != null) { 3293 conn.close(); 3294 } 3295 } 3296 } 3297 3298 @Test 3299 public void testHasPermission() throws Throwable { 3300 Connection conn = null; 3301 try { 3302 conn = ConnectionFactory.createConnection(conf); 3303 // Create user and set namespace ACL 3304 User user1 = User.createUserForTesting(conf, "testHasPermissionUser1", new String[0]); 3305 // Grant namespace permission 3306 grantOnNamespaceUsingAccessControlClient(TEST_UTIL, conn, user1.getShortName(), 3307 NamespaceDescriptor.DEFAULT_NAMESPACE.getName(), Permission.Action.ADMIN, 3308 Permission.Action.CREATE, Permission.Action.READ); 3309 3310 // Create user and set table ACL 3311 User user2 = User.createUserForTesting(conf, "testHasPermissionUser2", new String[0]); 3312 // Grant namespace permission 3313 grantOnTableUsingAccessControlClient(TEST_UTIL, conn, user2.getShortName(), TEST_TABLE, 3314 TEST_FAMILY, TEST_QUALIFIER, Permission.Action.READ, Permission.Action.WRITE); 3315 3316 // Verify action privilege 3317 AccessTestAction hasPermissionActionCP = new AccessTestAction() { 3318 @Override 3319 public Object run() throws Exception { 3320 try (Connection conn = ConnectionFactory.createConnection(conf); 3321 Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) { 3322 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName()); 3323 AccessControlService.BlockingInterface protocol = 3324 AccessControlService.newBlockingStub(service); 3325 Permission.Action[] actions = { Permission.Action.READ, Permission.Action.WRITE }; 3326 AccessControlUtil.hasPermission(null, protocol, TEST_TABLE, TEST_FAMILY, 3327 HConstants.EMPTY_BYTE_ARRAY, "dummy", actions); 3328 } 3329 return null; 3330 } 3331 }; 3332 AccessTestAction hasPermissionAction = new AccessTestAction() { 3333 @Override 3334 public Object run() throws Exception { 3335 try (Connection conn = ConnectionFactory.createConnection(conf)) { 3336 Permission.Action[] actions = { Permission.Action.READ, Permission.Action.WRITE }; 3337 conn.getAdmin().hasUserPermissions("dummy", 3338 Arrays.asList(Permission.newBuilder(TEST_TABLE).withFamily(TEST_FAMILY) 3339 .withQualifier(HConstants.EMPTY_BYTE_ARRAY).withActions(actions).build())); 3340 } 3341 return null; 3342 } 3343 }; 3344 verifyAllowed(hasPermissionActionCP, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN, USER_OWNER, 3345 USER_ADMIN_CF, user1); 3346 verifyDenied(hasPermissionActionCP, USER_CREATE, USER_RW, USER_RO, USER_NONE, user2); 3347 verifyAllowed(hasPermissionAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN, USER_OWNER, 3348 USER_ADMIN_CF, user1); 3349 verifyDenied(hasPermissionAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, user2); 3350 3351 // Check for global user 3352 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3353 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN.getShortName(), 3354 Permission.Action.READ, Permission.Action.WRITE, Permission.Action.CREATE, 3355 Permission.Action.ADMIN)); 3356 assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3357 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN.getShortName(), 3358 Permission.Action.READ, Permission.Action.WRITE, Permission.Action.CREATE, 3359 Permission.Action.ADMIN, Permission.Action.EXEC)); 3360 3361 // Check for namespace access user 3362 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3363 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, user1.getShortName(), 3364 Permission.Action.ADMIN, Permission.Action.CREATE)); 3365 assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3366 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, user1.getShortName(), 3367 Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.EXEC)); 3368 3369 // Check for table owner 3370 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3371 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_OWNER.getShortName(), 3372 Permission.Action.READ, Permission.Action.WRITE, Permission.Action.EXEC, 3373 Permission.Action.CREATE, Permission.Action.ADMIN)); 3374 3375 // Check for table user 3376 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3377 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_CREATE.getShortName(), 3378 Permission.Action.READ, Permission.Action.WRITE)); 3379 assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3380 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_RO.getShortName(), 3381 Permission.Action.READ, Permission.Action.WRITE)); 3382 3383 // Check for family access user 3384 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY, 3385 HConstants.EMPTY_BYTE_ARRAY, USER_RO.getShortName(), Permission.Action.READ)); 3386 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY, 3387 HConstants.EMPTY_BYTE_ARRAY, USER_RW.getShortName(), Permission.Action.READ, 3388 Permission.Action.WRITE)); 3389 assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3390 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN_CF.getShortName(), 3391 Permission.Action.ADMIN, Permission.Action.CREATE)); 3392 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY, 3393 HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN_CF.getShortName(), Permission.Action.ADMIN, 3394 Permission.Action.CREATE)); 3395 assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY, 3396 HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN_CF.getShortName(), Permission.Action.READ)); 3397 3398 // Check for qualifier access user 3399 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY, 3400 TEST_QUALIFIER, user2.getShortName(), Permission.Action.READ, Permission.Action.WRITE)); 3401 assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY, 3402 TEST_QUALIFIER, user2.getShortName(), Permission.Action.EXEC, Permission.Action.READ)); 3403 assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3404 HConstants.EMPTY_BYTE_ARRAY, TEST_QUALIFIER, USER_RW.getShortName(), 3405 Permission.Action.WRITE, Permission.Action.READ)); 3406 3407 // exception scenarios 3408 try { 3409 // test case with table name as null 3410 assertTrue(AccessControlClient.hasPermission(conn, null, HConstants.EMPTY_BYTE_ARRAY, 3411 HConstants.EMPTY_BYTE_ARRAY, null, Permission.Action.READ)); 3412 fail("this should have thrown IllegalArgumentException"); 3413 } catch (IllegalArgumentException ex) { 3414 // expected 3415 } 3416 try { 3417 // test case with username as null 3418 assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), 3419 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, null, Permission.Action.READ)); 3420 fail("this should have thrown IllegalArgumentException"); 3421 } catch (IllegalArgumentException ex) { 3422 // expected 3423 } 3424 3425 revokeFromNamespaceUsingAccessControlClient(TEST_UTIL, conn, user1.getShortName(), 3426 NamespaceDescriptor.DEFAULT_NAMESPACE.getName(), Permission.Action.ADMIN, 3427 Permission.Action.CREATE, Permission.Action.READ); 3428 revokeFromTableUsingAccessControlClient(TEST_UTIL, conn, user2.getShortName(), TEST_TABLE, 3429 TEST_FAMILY, TEST_QUALIFIER, Permission.Action.READ, Permission.Action.WRITE); 3430 } finally { 3431 if (conn != null) { 3432 conn.close(); 3433 } 3434 } 3435 } 3436 3437 @Test 3438 public void testSwitchRpcThrottle() throws Exception { 3439 AccessTestAction action = new AccessTestAction() { 3440 @Override 3441 public Object run() throws Exception { 3442 ACCESS_CONTROLLER.preSwitchRpcThrottle(ObserverContextImpl.createAndPrepare(CP_ENV), true); 3443 return null; 3444 } 3445 }; 3446 verifyAllowed(action, SUPERUSER, USER_ADMIN); 3447 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 3448 } 3449 3450 @Test 3451 public void testIsRpcThrottleEnabled() throws Exception { 3452 AccessTestAction action = new AccessTestAction() { 3453 @Override 3454 public Object run() throws Exception { 3455 ACCESS_CONTROLLER.preIsRpcThrottleEnabled(ObserverContextImpl.createAndPrepare(CP_ENV)); 3456 return null; 3457 } 3458 }; 3459 verifyAllowed(action, SUPERUSER, USER_ADMIN); 3460 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 3461 } 3462 3463 @Test 3464 public void testSwitchExceedThrottleQuota() throws Exception { 3465 AccessTestAction action = new AccessTestAction() { 3466 @Override 3467 public Object run() throws Exception { 3468 ACCESS_CONTROLLER.preSwitchExceedThrottleQuota(ObserverContextImpl.createAndPrepare(CP_ENV), 3469 true); 3470 return null; 3471 } 3472 }; 3473 verifyAllowed(action, SUPERUSER, USER_ADMIN); 3474 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER); 3475 } 3476 3477 /* 3478 * Validate Global User ACL 3479 */ 3480 private void validateGlobalUserACLForGetUserPermissions(final Connection conn, User nSUser1, 3481 User globalGroupUser1, User globalGroupUser2, Collection<String> superUsers, 3482 int superUserCount) throws Throwable { 3483 // Verify action privilege 3484 AccessTestAction globalUserPermissionAction = new AccessTestAction() { 3485 @Override 3486 public Object run() throws Exception { 3487 try (Connection conn = ConnectionFactory.createConnection(conf)) { 3488 conn.getAdmin().getUserPermissions( 3489 GetUserPermissionsRequest.newBuilder().withUserName("dummy").build()); 3490 } 3491 return null; 3492 } 3493 }; 3494 verifyAllowed(globalUserPermissionAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN); 3495 verifyDenied(globalUserPermissionAction, USER_GROUP_CREATE, USER_GROUP_READ, USER_GROUP_WRITE); 3496 3497 // Validate global user permission 3498 List<UserPermission> userPermissions; 3499 assertEquals(5 + superUserCount, AccessControlClient.getUserPermissions(conn, null).size()); 3500 assertEquals(5 + superUserCount, 3501 AccessControlClient.getUserPermissions(conn, HConstants.EMPTY_STRING).size()); 3502 assertEquals(5 + superUserCount, 3503 AccessControlClient.getUserPermissions(conn, null, HConstants.EMPTY_STRING).size()); 3504 userPermissions = AccessControlClient.getUserPermissions(conn, null, USER_ADMIN.getName()); 3505 verifyGetUserPermissionResult(userPermissions, 1, null, null, USER_ADMIN.getName(), superUsers); 3506 assertEquals(0, AccessControlClient.getUserPermissions(conn, null, nSUser1.getName()).size()); 3507 // Global group user ACL 3508 assertEquals(1, 3509 AccessControlClient.getUserPermissions(conn, null, globalGroupUser1.getName()).size()); 3510 assertEquals(2, 3511 AccessControlClient.getUserPermissions(conn, null, globalGroupUser2.getName()).size()); 3512 } 3513 3514 /* 3515 * Validate Namespace User ACL 3516 */ 3517 private void validateNamespaceUserACLForGetUserPermissions(final Connection conn, User nSUser1, 3518 User nSUser3, User nsGroupUser1, User nsGroupUser2, String nsPrefix, final String namespace1, 3519 String namespace2) throws Throwable { 3520 AccessTestAction namespaceUserPermissionAction = new AccessTestAction() { 3521 @Override 3522 public Object run() throws Exception { 3523 try (Connection conn = ConnectionFactory.createConnection(conf)) { 3524 conn.getAdmin().getUserPermissions( 3525 GetUserPermissionsRequest.newBuilder(namespace1).withUserName("dummy").build()); 3526 } 3527 return null; 3528 } 3529 }; 3530 verifyAllowed(namespaceUserPermissionAction, SUPERUSER, USER_GROUP_ADMIN, USER_ADMIN, nSUser1, 3531 nsGroupUser1); 3532 verifyDenied(namespaceUserPermissionAction, USER_GROUP_CREATE, USER_GROUP_READ, 3533 USER_GROUP_WRITE, nSUser3, nsGroupUser2); 3534 3535 List<UserPermission> userPermissions; 3536 assertEquals(6, AccessControlClient.getUserPermissions(conn, "@" + nsPrefix + ".*").size()); 3537 assertEquals(3, AccessControlClient.getUserPermissions(conn, "@" + namespace1).size()); 3538 assertEquals(3, AccessControlClient 3539 .getUserPermissions(conn, "@" + namespace1, HConstants.EMPTY_STRING).size()); 3540 userPermissions = 3541 AccessControlClient.getUserPermissions(conn, "@" + namespace1, nSUser1.getName()); 3542 verifyGetUserPermissionResult(userPermissions, 1, null, null, nSUser1.getName(), null); 3543 userPermissions = 3544 AccessControlClient.getUserPermissions(conn, "@" + namespace1, nSUser3.getName()); 3545 verifyGetUserPermissionResult(userPermissions, 1, null, null, nSUser3.getName(), null); 3546 assertEquals(0, 3547 AccessControlClient.getUserPermissions(conn, "@" + namespace1, USER_ADMIN.getName()).size()); 3548 // Namespace group user ACL 3549 assertEquals(1, AccessControlClient 3550 .getUserPermissions(conn, "@" + namespace1, nsGroupUser1.getName()).size()); 3551 assertEquals(1, AccessControlClient 3552 .getUserPermissions(conn, "@" + namespace2, nsGroupUser2.getName()).size()); 3553 } 3554 3555 /* 3556 * Validate Table User ACL 3557 */ 3558 private void validateTableACLForGetUserPermissions(final Connection conn, User nSUser1, 3559 User tableGroupUser1, User tableGroupUser2, String nsPrefix, TableName table1, 3560 TableName table2, byte[] TEST_QUALIFIER2, Collection<String> superUsers) throws Throwable { 3561 AccessTestAction tableUserPermissionAction = new AccessTestAction() { 3562 @Override 3563 public Object run() throws Exception { 3564 try (Connection conn = ConnectionFactory.createConnection(conf)) { 3565 conn.getAdmin().getUserPermissions(GetUserPermissionsRequest.newBuilder(TEST_TABLE) 3566 .withFamily(TEST_FAMILY).withQualifier(TEST_QUALIFIER).withUserName("dummy").build()); 3567 } 3568 return null; 3569 } 3570 }; 3571 verifyAllowed(tableUserPermissionAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_ADMIN_CF); 3572 verifyDenied(tableUserPermissionAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_CREATE); 3573 3574 List<UserPermission> userPermissions; 3575 assertEquals(12, AccessControlClient.getUserPermissions(conn, nsPrefix + ".*").size()); 3576 assertEquals(6, AccessControlClient.getUserPermissions(conn, table1.getNameAsString()).size()); 3577 assertEquals(6, AccessControlClient 3578 .getUserPermissions(conn, table1.getNameAsString(), HConstants.EMPTY_STRING).size()); 3579 userPermissions = AccessControlClient.getUserPermissions(conn, table1.getNameAsString(), 3580 USER_ADMIN_CF.getName()); 3581 verifyGetUserPermissionResult(userPermissions, 1, null, null, USER_ADMIN_CF.getName(), null); 3582 assertEquals(0, AccessControlClient 3583 .getUserPermissions(conn, table1.getNameAsString(), nSUser1.getName()).size()); 3584 // Table group user ACL 3585 assertEquals(1, AccessControlClient 3586 .getUserPermissions(conn, table1.getNameAsString(), tableGroupUser1.getName()).size()); 3587 assertEquals(1, AccessControlClient 3588 .getUserPermissions(conn, table2.getNameAsString(), tableGroupUser2.getName()).size()); 3589 3590 // Table Users + CF 3591 assertEquals(12, AccessControlClient 3592 .getUserPermissions(conn, nsPrefix + ".*", HConstants.EMPTY_BYTE_ARRAY).size()); 3593 userPermissions = AccessControlClient.getUserPermissions(conn, nsPrefix + ".*", TEST_FAMILY); 3594 verifyGetUserPermissionResult(userPermissions, 3, TEST_FAMILY, null, null, null); 3595 assertEquals(0, AccessControlClient 3596 .getUserPermissions(conn, table1.getNameAsString(), Bytes.toBytes("dummmyCF")).size()); 3597 3598 // Table Users + CF + User 3599 assertEquals(3, 3600 AccessControlClient 3601 .getUserPermissions(conn, table1.getNameAsString(), TEST_FAMILY, HConstants.EMPTY_STRING) 3602 .size()); 3603 userPermissions = AccessControlClient.getUserPermissions(conn, table1.getNameAsString(), 3604 TEST_FAMILY, USER_ADMIN_CF.getName()); 3605 verifyGetUserPermissionResult(userPermissions, 1, null, null, USER_ADMIN_CF.getName(), 3606 superUsers); 3607 assertEquals(0, AccessControlClient 3608 .getUserPermissions(conn, table1.getNameAsString(), TEST_FAMILY, nSUser1.getName()).size()); 3609 3610 // Table Users + CF + CQ 3611 assertEquals(3, AccessControlClient.getUserPermissions(conn, table1.getNameAsString(), 3612 TEST_FAMILY, HConstants.EMPTY_BYTE_ARRAY).size()); 3613 assertEquals(1, AccessControlClient 3614 .getUserPermissions(conn, table1.getNameAsString(), TEST_FAMILY, TEST_QUALIFIER).size()); 3615 assertEquals(1, AccessControlClient 3616 .getUserPermissions(conn, table1.getNameAsString(), TEST_FAMILY, TEST_QUALIFIER2).size()); 3617 assertEquals(2, AccessControlClient.getUserPermissions(conn, table1.getNameAsString(), 3618 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_RW.getName()).size()); 3619 assertEquals(0, AccessControlClient 3620 .getUserPermissions(conn, table1.getNameAsString(), TEST_FAMILY, Bytes.toBytes("dummmyCQ")) 3621 .size()); 3622 3623 // Table Users + CF + CQ + User 3624 assertEquals(3, AccessControlClient.getUserPermissions(conn, table1.getNameAsString(), 3625 TEST_FAMILY, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_STRING).size()); 3626 assertEquals(1, AccessControlClient.getUserPermissions(conn, table1.getNameAsString(), 3627 TEST_FAMILY, TEST_QUALIFIER, USER_RW.getName()).size()); 3628 assertEquals(1, AccessControlClient.getUserPermissions(conn, table1.getNameAsString(), 3629 TEST_FAMILY, TEST_QUALIFIER2, USER_RW.getName()).size()); 3630 assertEquals(0, AccessControlClient.getUserPermissions(conn, table1.getNameAsString(), 3631 TEST_FAMILY, TEST_QUALIFIER2, nSUser1.getName()).size()); 3632 } 3633 3634 /* 3635 * Validate the user permission against the specified column family, column qualifier and user 3636 * name. 3637 */ 3638 private void verifyGetUserPermissionResult(List<UserPermission> userPermissions, int resultCount, 3639 byte[] cf, byte[] cq, String userName, Collection<String> superUsers) { 3640 assertEquals(resultCount, userPermissions.size()); 3641 3642 for (UserPermission perm : userPermissions) { 3643 if (perm.getPermission() instanceof TablePermission) { 3644 TablePermission tablePerm = (TablePermission) perm.getPermission(); 3645 if (cf != null) { 3646 assertTrue(Bytes.equals(cf, tablePerm.getFamily())); 3647 } 3648 if (cq != null) { 3649 assertTrue(Bytes.equals(cq, tablePerm.getQualifier())); 3650 } 3651 if (userName != null 3652 && (superUsers == null || !superUsers.contains(perm.getUser()))) { 3653 assertTrue(userName.equals(perm.getUser())); 3654 } 3655 } else if (perm.getPermission() instanceof NamespacePermission || 3656 perm.getPermission() instanceof GlobalPermission) { 3657 if (userName != null && 3658 (superUsers == null || !superUsers.contains(perm.getUser()))) { 3659 assertTrue(userName.equals(perm.getUser())); 3660 } 3661 } 3662 } 3663 } 3664 3665 /* 3666 * Dummy ShellBasedUnixGroupsMapping class to retrieve the groups for the test users. 3667 */ 3668 public static class MyShellBasedUnixGroupsMapping extends ShellBasedUnixGroupsMapping 3669 implements GroupMappingServiceProvider { 3670 @Override 3671 public List<String> getGroups(String user) throws IOException { 3672 if (user.equals("globalGroupUser1")) { 3673 return Arrays.asList(new String[] { "group_admin" }); 3674 } else if (user.equals("globalGroupUser2")) { 3675 return Arrays.asList(new String[] { "group_admin", "group_create" }); 3676 } else if (user.equals("nsGroupUser1")) { 3677 return Arrays.asList(new String[] { "ns_group1" }); 3678 } else if (user.equals("nsGroupUser2")) { 3679 return Arrays.asList(new String[] { "ns_group2" }); 3680 } else if (user.equals("tableGroupUser1")) { 3681 return Arrays.asList(new String[] { "table_group1" }); 3682 } else if (user.equals("tableGroupUser2")) { 3683 return Arrays.asList(new String[] { "table_group2" }); 3684 } else { 3685 return super.getGroups(user); 3686 } 3687 } 3688 } 3689}