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.junit.Assert.assertEquals; 021 022import java.util.List; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.hbase.Cell; 025import org.apache.hadoop.hbase.CompareOperator; 026import org.apache.hadoop.hbase.Coprocessor; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.HBaseTestingUtil; 029import org.apache.hadoop.hbase.HConstants; 030import org.apache.hadoop.hbase.NamespaceDescriptor; 031import org.apache.hadoop.hbase.ServerName; 032import org.apache.hadoop.hbase.TableName; 033import org.apache.hadoop.hbase.TableNameTestRule; 034import org.apache.hadoop.hbase.TableNotFoundException; 035import org.apache.hadoop.hbase.client.Append; 036import org.apache.hadoop.hbase.client.BalanceRequest; 037import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 038import org.apache.hadoop.hbase.client.Connection; 039import org.apache.hadoop.hbase.client.ConnectionFactory; 040import org.apache.hadoop.hbase.client.Delete; 041import org.apache.hadoop.hbase.client.Durability; 042import org.apache.hadoop.hbase.client.Get; 043import org.apache.hadoop.hbase.client.Increment; 044import org.apache.hadoop.hbase.client.Put; 045import org.apache.hadoop.hbase.client.RegionInfo; 046import org.apache.hadoop.hbase.client.RegionInfoBuilder; 047import org.apache.hadoop.hbase.client.Result; 048import org.apache.hadoop.hbase.client.ResultScanner; 049import org.apache.hadoop.hbase.client.Scan; 050import org.apache.hadoop.hbase.client.SnapshotDescription; 051import org.apache.hadoop.hbase.client.Table; 052import org.apache.hadoop.hbase.client.TableDescriptor; 053import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 054import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; 055import org.apache.hadoop.hbase.coprocessor.ObserverContextImpl; 056import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; 057import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment; 058import org.apache.hadoop.hbase.filter.BinaryComparator; 059import org.apache.hadoop.hbase.master.MasterCoprocessorHost; 060import org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker; 061import org.apache.hadoop.hbase.regionserver.HRegion; 062import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress; 063import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost; 064import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost; 065import org.apache.hadoop.hbase.security.User; 066import org.apache.hadoop.hbase.security.access.Permission.Action; 067import org.apache.hadoop.hbase.testclassification.LargeTests; 068import org.apache.hadoop.hbase.testclassification.SecurityTests; 069import org.apache.hadoop.hbase.util.Bytes; 070import org.apache.hadoop.hbase.util.Pair; 071import org.apache.hadoop.hbase.wal.WALEdit; 072import org.junit.After; 073import org.junit.AfterClass; 074import org.junit.Before; 075import org.junit.BeforeClass; 076import org.junit.ClassRule; 077import org.junit.Rule; 078import org.junit.Test; 079import org.junit.experimental.categories.Category; 080import org.slf4j.Logger; 081import org.slf4j.LoggerFactory; 082 083import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 084 085@Category({ SecurityTests.class, LargeTests.class }) 086public class TestWithDisabledAuthorization extends SecureTestUtil { 087 088 @ClassRule 089 public static final HBaseClassTestRule CLASS_RULE = 090 HBaseClassTestRule.forClass(TestWithDisabledAuthorization.class); 091 092 private static final Logger LOG = LoggerFactory.getLogger(TestWithDisabledAuthorization.class); 093 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 094 095 private static final byte[] TEST_FAMILY = Bytes.toBytes("f1"); 096 private static final byte[] TEST_FAMILY2 = Bytes.toBytes("f2"); 097 private static final byte[] TEST_ROW = Bytes.toBytes("testrow"); 098 private static final byte[] TEST_Q1 = Bytes.toBytes("q1"); 099 private static final byte[] TEST_Q2 = Bytes.toBytes("q2"); 100 private static final byte[] TEST_Q3 = Bytes.toBytes("q3"); 101 private static final byte[] TEST_Q4 = Bytes.toBytes("q4"); 102 private static final byte[] ZERO = Bytes.toBytes(0L); 103 104 private static MasterCoprocessorEnvironment CP_ENV; 105 private static AccessController ACCESS_CONTROLLER; 106 private static RegionServerCoprocessorEnvironment RSCP_ENV; 107 private RegionCoprocessorEnvironment RCP_ENV; 108 109 @Rule 110 public TableNameTestRule testTable = new TableNameTestRule(); 111 112 // default users 113 114 // superuser 115 private static User SUPERUSER; 116 // user granted with all global permission 117 private static User USER_ADMIN; 118 // user with rw permissions on column family. 119 private static User USER_RW; 120 // user with read-only permissions 121 private static User USER_RO; 122 // user is table owner. will have all permissions on table 123 private static User USER_OWNER; 124 // user with create table permissions alone 125 private static User USER_CREATE; 126 // user with no permissions 127 private static User USER_NONE; 128 // user with only partial read-write perms (on family:q1 only) 129 private static User USER_QUAL; 130 131 @BeforeClass 132 public static void setupBeforeClass() throws Exception { 133 Configuration conf = TEST_UTIL.getConfiguration(); 134 // Up the handlers; this test needs more than usual. 135 TEST_UTIL.getConfiguration().setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10); 136 // Enable security 137 enableSecurity(conf); 138 // We expect 0.98 cell ACL semantics 139 conf.setBoolean(AccessControlConstants.CF_ATTRIBUTE_EARLY_OUT, false); 140 // Enable EXEC permission checking 141 conf.setBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY, true); 142 // Verify enableSecurity sets up what we require 143 verifyConfiguration(conf); 144 145 // Now, DISABLE only active authorization 146 conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false); 147 148 // Start the minicluster 149 TEST_UTIL.startMiniCluster(); 150 MasterCoprocessorHost cpHost = 151 TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterCoprocessorHost(); 152 cpHost.load(AccessController.class, Coprocessor.PRIORITY_HIGHEST, conf); 153 ACCESS_CONTROLLER = (AccessController) cpHost.findCoprocessor(AccessController.class.getName()); 154 CP_ENV = cpHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 155 RegionServerCoprocessorHost rsHost = 156 TEST_UTIL.getMiniHBaseCluster().getRegionServer(0).getRegionServerCoprocessorHost(); 157 RSCP_ENV = rsHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 158 159 // Wait for the ACL table to become available 160 TEST_UTIL.waitUntilAllRegionsAssigned(PermissionStorage.ACL_TABLE_NAME); 161 162 // create a set of test users 163 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" }); 164 USER_ADMIN = User.createUserForTesting(conf, "admin2", new String[0]); 165 USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]); 166 USER_CREATE = User.createUserForTesting(conf, "tbl_create", new String[0]); 167 USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]); 168 USER_RO = User.createUserForTesting(conf, "rouser", new String[0]); 169 USER_QUAL = User.createUserForTesting(conf, "rwpartial", new String[0]); 170 USER_NONE = User.createUserForTesting(conf, "nouser", new String[0]); 171 172 // Grant table creation permission to USER_OWNER 173 grantGlobal(TEST_UTIL, USER_OWNER.getShortName(), Action.CREATE); 174 } 175 176 @AfterClass 177 public static void tearDownAfterClass() throws Exception { 178 TEST_UTIL.shutdownMiniCluster(); 179 } 180 181 @Before 182 public void setUp() throws Exception { 183 // Create the test table (owner added to the _acl_ table) 184 TableDescriptor tableDescriptor = 185 TableDescriptorBuilder.newBuilder(testTable.getTableName()) 186 .setColumnFamily( 187 ColumnFamilyDescriptorBuilder.newBuilder(TEST_FAMILY).setMaxVersions(100).build()) 188 .build(); 189 createTable(TEST_UTIL, USER_OWNER, tableDescriptor, new byte[][] { Bytes.toBytes("s") }); 190 TEST_UTIL.waitUntilAllRegionsAssigned(testTable.getTableName()); 191 192 HRegion region = TEST_UTIL.getHBaseCluster().getRegions(testTable.getTableName()).get(0); 193 RegionCoprocessorHost rcpHost = region.getCoprocessorHost(); 194 RCP_ENV = rcpHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, 195 TEST_UTIL.getConfiguration()); 196 197 // Set up initial grants 198 199 grantGlobal(TEST_UTIL, USER_ADMIN.getShortName(), Permission.Action.ADMIN, 200 Permission.Action.CREATE, Permission.Action.READ, Permission.Action.WRITE); 201 202 grantOnTable(TEST_UTIL, USER_RW.getShortName(), testTable.getTableName(), TEST_FAMILY, null, 203 Permission.Action.READ, Permission.Action.WRITE); 204 205 // USER_CREATE is USER_RW plus CREATE permissions 206 grantOnTable(TEST_UTIL, USER_CREATE.getShortName(), testTable.getTableName(), null, null, 207 Permission.Action.CREATE, Permission.Action.READ, Permission.Action.WRITE); 208 209 grantOnTable(TEST_UTIL, USER_RO.getShortName(), testTable.getTableName(), TEST_FAMILY, null, 210 Permission.Action.READ); 211 212 grantOnTable(TEST_UTIL, USER_QUAL.getShortName(), testTable.getTableName(), TEST_FAMILY, 213 TEST_Q1, Permission.Action.READ, Permission.Action.WRITE); 214 215 assertEquals(5, PermissionStorage 216 .getTablePermissions(TEST_UTIL.getConfiguration(), testTable.getTableName()).size()); 217 } 218 219 @After 220 public void tearDown() throws Exception { 221 // Clean the _acl_ table 222 try { 223 deleteTable(TEST_UTIL, testTable.getTableName()); 224 } catch (TableNotFoundException ex) { 225 // Test deleted the table, no problem 226 LOG.info("Test deleted table " + testTable.getTableName()); 227 } 228 // Verify all table/namespace permissions are erased 229 assertEquals(0, PermissionStorage 230 .getTablePermissions(TEST_UTIL.getConfiguration(), testTable.getTableName()).size()); 231 assertEquals(0, PermissionStorage.getNamespacePermissions(TEST_UTIL.getConfiguration(), 232 testTable.getTableName().getNamespaceAsString()).size()); 233 } 234 235 @Test 236 public void testCheckPermissions() throws Exception { 237 238 AccessTestAction checkGlobalAdmin = new AccessTestAction() { 239 @Override 240 public Void run() throws Exception { 241 checkGlobalPerms(TEST_UTIL, Permission.Action.ADMIN); 242 return null; 243 } 244 }; 245 246 verifyAllowed(checkGlobalAdmin, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 247 USER_RO, USER_QUAL, USER_NONE); 248 249 AccessTestAction checkGlobalRead = new AccessTestAction() { 250 @Override 251 public Void run() throws Exception { 252 checkGlobalPerms(TEST_UTIL, Permission.Action.READ); 253 return null; 254 } 255 }; 256 257 verifyAllowed(checkGlobalRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 258 USER_QUAL, USER_NONE); 259 260 AccessTestAction checkGlobalReadWrite = new AccessTestAction() { 261 @Override 262 public Void run() throws Exception { 263 checkGlobalPerms(TEST_UTIL, Permission.Action.READ, Permission.Action.WRITE); 264 return null; 265 } 266 }; 267 268 verifyAllowed(checkGlobalReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 269 USER_RO, USER_QUAL, USER_NONE); 270 271 AccessTestAction checkTableAdmin = new AccessTestAction() { 272 @Override 273 public Void run() throws Exception { 274 checkTablePerms(TEST_UTIL, testTable.getTableName(), null, null, Permission.Action.ADMIN); 275 return null; 276 } 277 }; 278 279 verifyAllowed(checkTableAdmin, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 280 USER_QUAL, USER_NONE); 281 282 AccessTestAction checkTableCreate = new AccessTestAction() { 283 @Override 284 public Void run() throws Exception { 285 checkTablePerms(TEST_UTIL, testTable.getTableName(), null, null, Permission.Action.CREATE); 286 return null; 287 } 288 }; 289 290 verifyAllowed(checkTableCreate, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 291 USER_RO, USER_QUAL, USER_NONE); 292 293 AccessTestAction checkTableRead = new AccessTestAction() { 294 @Override 295 public Void run() throws Exception { 296 checkTablePerms(TEST_UTIL, testTable.getTableName(), null, null, Permission.Action.READ); 297 return null; 298 } 299 }; 300 301 verifyAllowed(checkTableRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 302 USER_QUAL, USER_NONE); 303 304 AccessTestAction checkTableReadWrite = new AccessTestAction() { 305 @Override 306 public Void run() throws Exception { 307 checkTablePerms(TEST_UTIL, testTable.getTableName(), null, null, Permission.Action.READ, 308 Permission.Action.WRITE); 309 return null; 310 } 311 }; 312 313 verifyAllowed(checkTableReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 314 USER_RO, USER_QUAL, USER_NONE); 315 316 AccessTestAction checkColumnRead = new AccessTestAction() { 317 @Override 318 public Void run() throws Exception { 319 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, null, 320 Permission.Action.READ); 321 return null; 322 } 323 }; 324 325 verifyAllowed(checkColumnRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 326 USER_QUAL, USER_NONE); 327 328 AccessTestAction checkColumnReadWrite = new AccessTestAction() { 329 @Override 330 public Void run() throws Exception { 331 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, null, 332 Permission.Action.READ, Permission.Action.WRITE); 333 return null; 334 } 335 }; 336 337 verifyAllowed(checkColumnReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 338 USER_RO, USER_QUAL, USER_NONE); 339 340 AccessTestAction checkQualifierRead = new AccessTestAction() { 341 @Override 342 public Void run() throws Exception { 343 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, TEST_Q1, 344 Permission.Action.READ); 345 return null; 346 } 347 }; 348 349 verifyAllowed(checkQualifierRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 350 USER_RO, USER_QUAL, USER_NONE); 351 352 AccessTestAction checkQualifierReadWrite = new AccessTestAction() { 353 @Override 354 public Void run() throws Exception { 355 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, TEST_Q1, 356 Permission.Action.READ, Permission.Action.WRITE); 357 return null; 358 } 359 }; 360 361 verifyAllowed(checkQualifierReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 362 USER_QUAL, USER_RO, USER_NONE); 363 364 AccessTestAction checkMultiQualifierRead = new AccessTestAction() { 365 @Override 366 public Void run() throws Exception { 367 checkTablePerms(TEST_UTIL, 368 new Permission[] { 369 Permission.newBuilder(testTable.getTableName()).withFamily(TEST_FAMILY) 370 .withQualifier(TEST_Q1).withActions(Action.READ).build(), 371 Permission.newBuilder(testTable.getTableName()).withFamily(TEST_FAMILY) 372 .withQualifier(TEST_Q2).withActions(Action.READ).build() }); 373 return null; 374 } 375 }; 376 377 verifyAllowed(checkMultiQualifierRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 378 USER_RO, USER_QUAL, USER_NONE); 379 380 AccessTestAction checkMultiQualifierReadWrite = new AccessTestAction() { 381 @Override 382 public Void run() throws Exception { 383 checkTablePerms(TEST_UTIL, 384 new Permission[] { 385 Permission.newBuilder(testTable.getTableName()).withFamily(TEST_FAMILY) 386 .withQualifier(TEST_Q1).withActions(Permission.Action.READ, Permission.Action.WRITE) 387 .build(), 388 Permission.newBuilder(testTable.getTableName()).withFamily(TEST_FAMILY) 389 .withQualifier(TEST_Q2).withActions(Permission.Action.READ, Permission.Action.WRITE) 390 .build() }); 391 return null; 392 } 393 }; 394 395 verifyAllowed(checkMultiQualifierReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, 396 USER_RW, USER_RO, USER_QUAL, USER_NONE); 397 } 398 399 /** Test grants and revocations with authorization disabled */ 400 @Test 401 public void testPassiveGrantRevoke() throws Exception { 402 403 // Add a test user 404 405 User tblUser = 406 User.createUserForTesting(TEST_UTIL.getConfiguration(), "tbluser", new String[0]); 407 408 // If we check now, the test user have permissions because authorization is disabled 409 410 AccessTestAction checkTableRead = new AccessTestAction() { 411 @Override 412 public Void run() throws Exception { 413 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, null, 414 Permission.Action.READ); 415 return null; 416 } 417 }; 418 419 verifyAllowed(tblUser, checkTableRead); 420 421 // An actual read won't be denied 422 423 AccessTestAction tableRead = new AccessTestAction() { 424 @Override 425 public Void run() throws Exception { 426 try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); 427 Table t = conn.getTable(testTable.getTableName())) { 428 t.get(new Get(TEST_ROW).addFamily(TEST_FAMILY)); 429 } 430 return null; 431 } 432 }; 433 434 verifyAllowed(tblUser, tableRead); 435 436 // Grant read perms to the test user 437 438 grantOnTable(TEST_UTIL, tblUser.getShortName(), testTable.getTableName(), TEST_FAMILY, null, 439 Permission.Action.READ); 440 441 // Now both the permission check and actual op will succeed 442 443 verifyAllowed(tblUser, checkTableRead); 444 verifyAllowed(tblUser, tableRead); 445 446 // Revoke read perms from the test user 447 448 revokeFromTable(TEST_UTIL, tblUser.getShortName(), testTable.getTableName(), TEST_FAMILY, null, 449 Permission.Action.READ); 450 451 // Now the permission check will indicate revocation but the actual op will still succeed 452 453 verifyAllowed(tblUser, checkTableRead); 454 verifyAllowed(tblUser, tableRead); 455 } 456 457 /** Test master observer */ 458 @Test 459 public void testPassiveMasterOperations() throws Exception { 460 461 // preCreateTable 462 verifyAllowed(new AccessTestAction() { 463 @Override 464 public Object run() throws Exception { 465 TableDescriptor tableDescriptor = 466 TableDescriptorBuilder.newBuilder(testTable.getTableName()) 467 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(TEST_FAMILY)).build(); 468 ACCESS_CONTROLLER.preCreateTable(ObserverContextImpl.createAndPrepare(CP_ENV), 469 tableDescriptor, null); 470 return null; 471 } 472 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 473 474 // preModifyTable 475 verifyAllowed(new AccessTestAction() { 476 @Override 477 public Object run() throws Exception { 478 TableDescriptor tableDescriptor = 479 TableDescriptorBuilder.newBuilder(testTable.getTableName()) 480 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(TEST_FAMILY)) 481 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(TEST_FAMILY2)).build(); 482 ACCESS_CONTROLLER.preModifyTable(ObserverContextImpl.createAndPrepare(CP_ENV), 483 testTable.getTableName(), null, // not needed by AccessController 484 tableDescriptor); 485 return null; 486 } 487 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 488 489 // preDeleteTable 490 verifyAllowed(new AccessTestAction() { 491 @Override 492 public Object run() throws Exception { 493 ACCESS_CONTROLLER.preDeleteTable(ObserverContextImpl.createAndPrepare(CP_ENV), 494 testTable.getTableName()); 495 return null; 496 } 497 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 498 499 // preTruncateTable 500 verifyAllowed(new AccessTestAction() { 501 @Override 502 public Object run() throws Exception { 503 ACCESS_CONTROLLER.preTruncateTable(ObserverContextImpl.createAndPrepare(CP_ENV), 504 testTable.getTableName()); 505 return null; 506 } 507 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 508 509 // preEnableTable 510 verifyAllowed(new AccessTestAction() { 511 @Override 512 public Object run() throws Exception { 513 ACCESS_CONTROLLER.preEnableTable(ObserverContextImpl.createAndPrepare(CP_ENV), 514 testTable.getTableName()); 515 return null; 516 } 517 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 518 519 // preDisableTable 520 verifyAllowed(new AccessTestAction() { 521 @Override 522 public Object run() throws Exception { 523 ACCESS_CONTROLLER.preDisableTable(ObserverContextImpl.createAndPrepare(CP_ENV), 524 testTable.getTableName()); 525 return null; 526 } 527 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 528 529 // preMove 530 verifyAllowed(new AccessTestAction() { 531 @Override 532 public Object run() throws Exception { 533 RegionInfo region = RegionInfoBuilder.newBuilder(testTable.getTableName()).build(); 534 ServerName srcServer = ServerName.valueOf("1.1.1.1", 1, 0); 535 ServerName destServer = ServerName.valueOf("2.2.2.2", 2, 0); 536 ACCESS_CONTROLLER.preMove(ObserverContextImpl.createAndPrepare(CP_ENV), region, srcServer, 537 destServer); 538 return null; 539 } 540 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 541 542 // preAssign 543 verifyAllowed(new AccessTestAction() { 544 @Override 545 public Object run() throws Exception { 546 RegionInfo region = RegionInfoBuilder.newBuilder(testTable.getTableName()).build(); 547 ACCESS_CONTROLLER.preAssign(ObserverContextImpl.createAndPrepare(CP_ENV), region); 548 return null; 549 } 550 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 551 552 // preUnassign 553 verifyAllowed(new AccessTestAction() { 554 @Override 555 public Object run() throws Exception { 556 RegionInfo region = RegionInfoBuilder.newBuilder(testTable.getTableName()).build(); 557 ACCESS_CONTROLLER.preUnassign(ObserverContextImpl.createAndPrepare(CP_ENV), region); 558 return null; 559 } 560 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 561 562 // preBalance 563 verifyAllowed(new AccessTestAction() { 564 @Override 565 public Object run() throws Exception { 566 ACCESS_CONTROLLER.preBalance(ObserverContextImpl.createAndPrepare(CP_ENV), 567 BalanceRequest.defaultInstance()); 568 return null; 569 } 570 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 571 572 // preBalanceSwitch 573 verifyAllowed(new AccessTestAction() { 574 @Override 575 public Object run() throws Exception { 576 ACCESS_CONTROLLER.preBalanceSwitch(ObserverContextImpl.createAndPrepare(CP_ENV), true); 577 return null; 578 } 579 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 580 581 // preSnapshot 582 verifyAllowed(new AccessTestAction() { 583 @Override 584 public Object run() throws Exception { 585 SnapshotDescription snapshot = new SnapshotDescription("foo"); 586 TableDescriptor htd = TableDescriptorBuilder.newBuilder(testTable.getTableName()).build(); 587 ACCESS_CONTROLLER.preSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot, htd); 588 return null; 589 } 590 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 591 592 // preListSnapshot 593 verifyAllowed(new AccessTestAction() { 594 @Override 595 public Object run() throws Exception { 596 SnapshotDescription snapshot = new SnapshotDescription("foo"); 597 ACCESS_CONTROLLER.preListSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot); 598 return null; 599 } 600 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 601 602 // preCloneSnapshot 603 verifyAllowed(new AccessTestAction() { 604 @Override 605 public Object run() throws Exception { 606 SnapshotDescription snapshot = new SnapshotDescription("foo"); 607 TableDescriptor htd = TableDescriptorBuilder.newBuilder(testTable.getTableName()).build(); 608 ACCESS_CONTROLLER.preCloneSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot, 609 htd); 610 return null; 611 } 612 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 613 614 // preRestoreSnapshot 615 verifyAllowed(new AccessTestAction() { 616 @Override 617 public Object run() throws Exception { 618 SnapshotDescription snapshot = new SnapshotDescription("foo"); 619 TableDescriptor htd = TableDescriptorBuilder.newBuilder(testTable.getTableName()).build(); 620 ACCESS_CONTROLLER.preRestoreSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot, 621 htd); 622 return null; 623 } 624 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 625 626 // preDeleteSnapshot 627 verifyAllowed(new AccessTestAction() { 628 @Override 629 public Object run() throws Exception { 630 SnapshotDescription snapshot = new SnapshotDescription("foo"); 631 ACCESS_CONTROLLER.preDeleteSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot); 632 return null; 633 } 634 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 635 636 // preGetTableDescriptors 637 verifyAllowed(new AccessTestAction() { 638 @Override 639 public Object run() throws Exception { 640 List<TableName> tableNamesList = Lists.newArrayList(); 641 tableNamesList.add(testTable.getTableName()); 642 List<TableDescriptor> descriptors = Lists.newArrayList(); 643 ACCESS_CONTROLLER.preGetTableDescriptors(ObserverContextImpl.createAndPrepare(CP_ENV), 644 tableNamesList, descriptors, ".+"); 645 return null; 646 } 647 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 648 649 // preGetTableNames 650 verifyAllowed(new AccessTestAction() { 651 @Override 652 public Object run() throws Exception { 653 List<TableDescriptor> descriptors = Lists.newArrayList(); 654 ACCESS_CONTROLLER.preGetTableNames(ObserverContextImpl.createAndPrepare(CP_ENV), 655 descriptors, ".+"); 656 return null; 657 } 658 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 659 660 // preCreateNamespace 661 verifyAllowed(new AccessTestAction() { 662 @Override 663 public Object run() throws Exception { 664 NamespaceDescriptor ns = NamespaceDescriptor.create("test").build(); 665 ACCESS_CONTROLLER.preCreateNamespace(ObserverContextImpl.createAndPrepare(CP_ENV), ns); 666 return null; 667 } 668 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 669 670 // preDeleteNamespace 671 verifyAllowed(new AccessTestAction() { 672 @Override 673 public Object run() throws Exception { 674 ACCESS_CONTROLLER.preDeleteNamespace(ObserverContextImpl.createAndPrepare(CP_ENV), "test"); 675 return null; 676 } 677 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 678 679 // preModifyNamespace 680 verifyAllowed(new AccessTestAction() { 681 @Override 682 public Object run() throws Exception { 683 NamespaceDescriptor ns = NamespaceDescriptor.create("test").build(); 684 ACCESS_CONTROLLER.preModifyNamespace(ObserverContextImpl.createAndPrepare(CP_ENV), null, // not 685 // needed 686 // by 687 // AccessController 688 ns); 689 return null; 690 } 691 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 692 693 // preGetNamespaceDescriptor 694 verifyAllowed(new AccessTestAction() { 695 @Override 696 public Object run() throws Exception { 697 ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContextImpl.createAndPrepare(CP_ENV), 698 "test"); 699 return null; 700 } 701 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 702 703 // preListNamespaceDescriptors 704 verifyAllowed(new AccessTestAction() { 705 @Override 706 public Object run() throws Exception { 707 List<NamespaceDescriptor> descriptors = Lists.newArrayList(); 708 ACCESS_CONTROLLER.preListNamespaceDescriptors(ObserverContextImpl.createAndPrepare(CP_ENV), 709 descriptors); 710 return null; 711 } 712 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 713 714 // preSplit 715 verifyAllowed(new AccessTestAction() { 716 @Override 717 public Object run() throws Exception { 718 ACCESS_CONTROLLER.preSplitRegion(ObserverContextImpl.createAndPrepare(CP_ENV), 719 testTable.getTableName(), Bytes.toBytes("ss")); 720 return null; 721 } 722 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 723 724 // preSetUserQuota 725 verifyAllowed(new AccessTestAction() { 726 @Override 727 public Object run() throws Exception { 728 ACCESS_CONTROLLER.preSetUserQuota(ObserverContextImpl.createAndPrepare(CP_ENV), "testuser", 729 null); 730 return null; 731 } 732 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 733 734 // preSetTableQuota 735 verifyAllowed(new AccessTestAction() { 736 @Override 737 public Object run() throws Exception { 738 ACCESS_CONTROLLER.preSetTableQuota(ObserverContextImpl.createAndPrepare(CP_ENV), 739 testTable.getTableName(), null); 740 return null; 741 } 742 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 743 744 // preSetNamespaceQuota 745 verifyAllowed(new AccessTestAction() { 746 @Override 747 public Object run() throws Exception { 748 ACCESS_CONTROLLER.preSetNamespaceQuota(ObserverContextImpl.createAndPrepare(CP_ENV), "test", 749 null); 750 return null; 751 } 752 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 753 754 } 755 756 /** Test region server observer */ 757 @Test 758 public void testPassiveRegionServerOperations() throws Exception { 759 // preStopRegionServer 760 verifyAllowed(new AccessTestAction() { 761 @Override 762 public Object run() throws Exception { 763 ACCESS_CONTROLLER.preStopRegionServer(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 764 return null; 765 } 766 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 767 768 // preRollWALWriterRequest 769 verifyAllowed(new AccessTestAction() { 770 @Override 771 public Object run() throws Exception { 772 ACCESS_CONTROLLER.preRollWALWriterRequest(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 773 return null; 774 } 775 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 776 777 } 778 779 /** Test region observer */ 780 @Test 781 public void testPassiveRegionOperations() throws Exception { 782 783 // preOpen 784 verifyAllowed(new AccessTestAction() { 785 @Override 786 public Object run() throws Exception { 787 ACCESS_CONTROLLER.preOpen(ObserverContextImpl.createAndPrepare(RCP_ENV)); 788 return null; 789 } 790 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 791 792 // preFlush 793 verifyAllowed(new AccessTestAction() { 794 @Override 795 public Object run() throws Exception { 796 ACCESS_CONTROLLER.preFlush(ObserverContextImpl.createAndPrepare(RCP_ENV), 797 FlushLifeCycleTracker.DUMMY); 798 return null; 799 } 800 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 801 802 // preGetOp 803 verifyAllowed(new AccessTestAction() { 804 @Override 805 public Object run() throws Exception { 806 List<Cell> cells = Lists.newArrayList(); 807 ACCESS_CONTROLLER.preGetOp(ObserverContextImpl.createAndPrepare(RCP_ENV), new Get(TEST_ROW), 808 cells); 809 return null; 810 } 811 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 812 813 // preExists 814 verifyAllowed(new AccessTestAction() { 815 @Override 816 public Object run() throws Exception { 817 ACCESS_CONTROLLER.preExists(ObserverContextImpl.createAndPrepare(RCP_ENV), 818 new Get(TEST_ROW), true); 819 return null; 820 } 821 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 822 823 // prePut 824 verifyAllowed(new AccessTestAction() { 825 @Override 826 public Object run() throws Exception { 827 ACCESS_CONTROLLER.prePut(ObserverContextImpl.createAndPrepare(RCP_ENV), new Put(TEST_ROW), 828 new WALEdit(), Durability.USE_DEFAULT); 829 return null; 830 } 831 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 832 833 // preDelete 834 verifyAllowed(new AccessTestAction() { 835 @Override 836 public Object run() throws Exception { 837 ACCESS_CONTROLLER.preDelete(ObserverContextImpl.createAndPrepare(RCP_ENV), 838 new Delete(TEST_ROW), new WALEdit(), Durability.USE_DEFAULT); 839 return null; 840 } 841 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 842 843 // preBatchMutate 844 verifyAllowed(new AccessTestAction() { 845 @Override 846 public Object run() throws Exception { 847 ACCESS_CONTROLLER.preBatchMutate(ObserverContextImpl.createAndPrepare(RCP_ENV), 848 new MiniBatchOperationInProgress<>(null, null, null, 0, 0, 0)); 849 return null; 850 } 851 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 852 853 // preCheckAndPut 854 verifyAllowed(new AccessTestAction() { 855 @Override 856 public Object run() throws Exception { 857 ACCESS_CONTROLLER.preCheckAndPut(ObserverContextImpl.createAndPrepare(RCP_ENV), TEST_ROW, 858 TEST_FAMILY, TEST_Q1, CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("foo")), 859 new Put(TEST_ROW), true); 860 return null; 861 } 862 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 863 864 // preCheckAndDelete 865 verifyAllowed(new AccessTestAction() { 866 @Override 867 public Object run() throws Exception { 868 ACCESS_CONTROLLER.preCheckAndDelete(ObserverContextImpl.createAndPrepare(RCP_ENV), TEST_ROW, 869 TEST_FAMILY, TEST_Q1, CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("foo")), 870 new Delete(TEST_ROW), true); 871 return null; 872 } 873 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 874 875 // preAppend 876 verifyAllowed(new AccessTestAction() { 877 @Override 878 public Object run() throws Exception { 879 ACCESS_CONTROLLER.preAppend(ObserverContextImpl.createAndPrepare(RCP_ENV), 880 new Append(TEST_ROW)); 881 return null; 882 } 883 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 884 885 // preIncrement 886 verifyAllowed(new AccessTestAction() { 887 @Override 888 public Object run() throws Exception { 889 ACCESS_CONTROLLER.preIncrement(ObserverContextImpl.createAndPrepare(RCP_ENV), 890 new Increment(TEST_ROW)); 891 return null; 892 } 893 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 894 895 // preScannerOpen 896 verifyAllowed(new AccessTestAction() { 897 @Override 898 public Object run() throws Exception { 899 ACCESS_CONTROLLER.preScannerOpen(ObserverContextImpl.createAndPrepare(RCP_ENV), new Scan()); 900 return null; 901 } 902 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 903 904 // preBulkLoadHFile 905 verifyAllowed(new AccessTestAction() { 906 @Override 907 public Object run() throws Exception { 908 List<Pair<byte[], String>> paths = Lists.newArrayList(); 909 ACCESS_CONTROLLER.preBulkLoadHFile(ObserverContextImpl.createAndPrepare(RCP_ENV), paths); 910 return null; 911 } 912 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 913 914 } 915 916 @Test 917 public void testPassiveCellPermissions() throws Exception { 918 final Configuration conf = TEST_UTIL.getConfiguration(); 919 920 // store two sets of values, one store with a cell level ACL, and one without 921 verifyAllowed(new AccessTestAction() { 922 @Override 923 public Object run() throws Exception { 924 try (Connection connection = ConnectionFactory.createConnection(conf); 925 Table t = connection.getTable(testTable.getTableName())) { 926 Put p; 927 // with ro ACL 928 p = new Put(TEST_ROW).addColumn(TEST_FAMILY, TEST_Q1, ZERO); 929 p.setACL(USER_NONE.getShortName(), new Permission(Action.READ)); 930 t.put(p); 931 // with rw ACL 932 p = new Put(TEST_ROW).addColumn(TEST_FAMILY, TEST_Q2, ZERO); 933 p.setACL(USER_NONE.getShortName(), new Permission(Action.READ, Action.WRITE)); 934 t.put(p); 935 // no ACL 936 p = new Put(TEST_ROW).addColumn(TEST_FAMILY, TEST_Q3, ZERO).addColumn(TEST_FAMILY, 937 TEST_Q4, ZERO); 938 t.put(p); 939 } 940 return null; 941 } 942 }, USER_OWNER); 943 944 // check that a scan over the test data returns the expected number of KVs 945 946 final List<Cell> scanResults = Lists.newArrayList(); 947 948 AccessTestAction scanAction = new AccessTestAction() { 949 @Override 950 public List<Cell> run() throws Exception { 951 Scan scan = new Scan(); 952 scan.withStartRow(TEST_ROW); 953 scan.withStopRow(Bytes.add(TEST_ROW, new byte[] { 0 })); 954 scan.addFamily(TEST_FAMILY); 955 Connection connection = ConnectionFactory.createConnection(conf); 956 Table t = connection.getTable(testTable.getTableName()); 957 try { 958 ResultScanner scanner = t.getScanner(scan); 959 Result result = null; 960 do { 961 result = scanner.next(); 962 if (result != null) { 963 scanResults.addAll(result.listCells()); 964 } 965 } while (result != null); 966 } finally { 967 t.close(); 968 connection.close(); 969 } 970 return scanResults; 971 } 972 }; 973 974 // owner will see all values 975 scanResults.clear(); 976 verifyAllowed(scanAction, USER_OWNER); 977 assertEquals(4, scanResults.size()); 978 979 // other user will also see 4 values 980 // if cell filtering was active, we would only see 2 values 981 scanResults.clear(); 982 verifyAllowed(scanAction, USER_NONE); 983 assertEquals(4, scanResults.size()); 984 } 985 986}