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