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