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