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        return null;
564      }
565    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
566
567    // preBalance
568    verifyAllowed(new AccessTestAction() {
569      @Override
570      public Object run() throws Exception {
571        ACCESS_CONTROLLER.preBalance(ObserverContextImpl.createAndPrepare(CP_ENV));
572        return null;
573      }
574    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
575
576    // preBalanceSwitch
577    verifyAllowed(new AccessTestAction() {
578      @Override
579      public Object run() throws Exception {
580        ACCESS_CONTROLLER.preBalanceSwitch(ObserverContextImpl.createAndPrepare(CP_ENV),
581          true);
582        return null;
583      }
584    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
585
586    // preSnapshot
587    verifyAllowed(new AccessTestAction() {
588      @Override
589      public Object run() throws Exception {
590        SnapshotDescription snapshot = new SnapshotDescription("foo");
591        HTableDescriptor htd = new HTableDescriptor(testTable.getTableName());
592        ACCESS_CONTROLLER.preSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV),
593          snapshot, htd);
594        return null;
595      }
596    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
597
598    // preListSnapshot
599    verifyAllowed(new AccessTestAction() {
600      @Override
601      public Object run() throws Exception {
602        SnapshotDescription snapshot = new SnapshotDescription("foo");
603        ACCESS_CONTROLLER.preListSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV),
604          snapshot);
605        return null;
606      }
607    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
608
609    // preCloneSnapshot
610    verifyAllowed(new AccessTestAction() {
611      @Override
612      public Object run() throws Exception {
613        SnapshotDescription snapshot = new SnapshotDescription("foo");
614        HTableDescriptor htd = new HTableDescriptor(testTable.getTableName());
615        ACCESS_CONTROLLER.preCloneSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV),
616          snapshot, htd);
617        return null;
618      }
619    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
620
621    // preRestoreSnapshot
622    verifyAllowed(new AccessTestAction() {
623      @Override
624      public Object run() throws Exception {
625        SnapshotDescription snapshot = new SnapshotDescription("foo");
626        HTableDescriptor htd = new HTableDescriptor(testTable.getTableName());
627        ACCESS_CONTROLLER.preRestoreSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV),
628          snapshot, htd);
629        return null;
630      }
631    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
632
633    // preDeleteSnapshot
634    verifyAllowed(new AccessTestAction() {
635      @Override
636      public Object run() throws Exception {
637        SnapshotDescription snapshot = new SnapshotDescription("foo");
638        ACCESS_CONTROLLER.preDeleteSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV),
639          snapshot);
640        return null;
641      }
642    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
643
644    // preGetTableDescriptors
645    verifyAllowed(new AccessTestAction() {
646      @Override
647      public Object run() throws Exception {
648        List<TableName> tableNamesList = Lists.newArrayList();
649        tableNamesList.add(testTable.getTableName());
650        List<TableDescriptor> descriptors = Lists.newArrayList();
651        ACCESS_CONTROLLER.preGetTableDescriptors(ObserverContextImpl.createAndPrepare(CP_ENV),
652          tableNamesList, descriptors, ".+");
653        return null;
654      }
655    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
656
657    // preGetTableNames
658    verifyAllowed(new AccessTestAction() {
659      @Override
660      public Object run() throws Exception {
661        List<TableDescriptor> descriptors = Lists.newArrayList();
662        ACCESS_CONTROLLER.preGetTableNames(ObserverContextImpl.createAndPrepare(CP_ENV),
663          descriptors, ".+");
664        return null;
665      }
666    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
667
668    // preCreateNamespace
669    verifyAllowed(new AccessTestAction() {
670      @Override
671      public Object run() throws Exception {
672        NamespaceDescriptor ns = NamespaceDescriptor.create("test").build();
673        ACCESS_CONTROLLER.preCreateNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
674          ns);
675        return null;
676      }
677    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
678
679    // preDeleteNamespace
680    verifyAllowed(new AccessTestAction() {
681      @Override
682      public Object run() throws Exception {
683        ACCESS_CONTROLLER.preDeleteNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
684          "test");
685        return null;
686      }
687    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
688
689    // preModifyNamespace
690    verifyAllowed(new AccessTestAction() {
691      @Override
692      public Object run() throws Exception {
693        NamespaceDescriptor ns = NamespaceDescriptor.create("test").build();
694        ACCESS_CONTROLLER.preModifyNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
695          ns);
696        return null;
697      }
698    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
699
700    // preGetNamespaceDescriptor
701    verifyAllowed(new AccessTestAction() {
702      @Override
703      public Object run() throws Exception {
704        ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContextImpl.createAndPrepare(CP_ENV),
705          "test");
706        return null;
707      }
708    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
709
710    // preListNamespaceDescriptors
711    verifyAllowed(new AccessTestAction() {
712      @Override
713      public Object run() throws Exception {
714        List<NamespaceDescriptor> descriptors = Lists.newArrayList();
715        ACCESS_CONTROLLER.preListNamespaceDescriptors(ObserverContextImpl.createAndPrepare(CP_ENV),
716          descriptors);
717        return null;
718      }
719    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
720
721    // preSplit
722    verifyAllowed(new AccessTestAction() {
723      @Override
724      public Object run() throws Exception {
725        ACCESS_CONTROLLER.preSplitRegion(
726          ObserverContextImpl.createAndPrepare(CP_ENV),
727          testTable.getTableName(),
728          Bytes.toBytes("ss"));
729        return null;
730      }
731    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
732
733    // preSetUserQuota
734    verifyAllowed(new AccessTestAction() {
735      @Override
736      public Object run() throws Exception {
737        ACCESS_CONTROLLER.preSetUserQuota(ObserverContextImpl.createAndPrepare(CP_ENV),
738          "testuser", null);
739        return null;
740      }
741    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
742
743    // preSetTableQuota
744    verifyAllowed(new AccessTestAction() {
745      @Override
746      public Object run() throws Exception {
747        ACCESS_CONTROLLER.preSetTableQuota(ObserverContextImpl.createAndPrepare(CP_ENV),
748          testTable.getTableName(), null);
749        return null;
750      }
751    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
752
753    // preSetNamespaceQuota
754    verifyAllowed(new AccessTestAction() {
755      @Override
756      public Object run() throws Exception {
757        ACCESS_CONTROLLER.preSetNamespaceQuota(ObserverContextImpl.createAndPrepare(CP_ENV),
758          "test", null);
759        return null;
760      }
761    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
762
763  }
764
765  /** Test region server observer */
766  @Test
767  public void testPassiveRegionServerOperations() throws Exception {
768    // preStopRegionServer
769    verifyAllowed(new AccessTestAction() {
770      @Override
771      public Object run() throws Exception {
772        ACCESS_CONTROLLER.preStopRegionServer(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    // preRollWALWriterRequest
778    verifyAllowed(new AccessTestAction() {
779      @Override
780      public Object run() throws Exception {
781        ACCESS_CONTROLLER.preRollWALWriterRequest(ObserverContextImpl.createAndPrepare(RSCP_ENV));
782        return null;
783      }
784    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
785
786  }
787
788  /** Test region observer */
789  @Test
790  public void testPassiveRegionOperations() throws Exception {
791
792    // preOpen
793    verifyAllowed(new AccessTestAction() {
794      @Override
795      public Object run() throws Exception {
796        ACCESS_CONTROLLER.preOpen(ObserverContextImpl.createAndPrepare(RCP_ENV));
797        return null;
798      }
799    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
800
801    // preFlush
802    verifyAllowed(new AccessTestAction() {
803      @Override
804      public Object run() throws Exception {
805        ACCESS_CONTROLLER.preFlush(ObserverContextImpl.createAndPrepare(RCP_ENV),
806          FlushLifeCycleTracker.DUMMY);
807        return null;
808      }
809    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
810
811    // preGetOp
812    verifyAllowed(new AccessTestAction() {
813      @Override
814      public Object run() throws Exception {
815        List<Cell> cells = Lists.newArrayList();
816        ACCESS_CONTROLLER.preGetOp(ObserverContextImpl.createAndPrepare(RCP_ENV),
817          new Get(TEST_ROW), cells);
818        return null;
819      }
820    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
821
822    // preExists
823    verifyAllowed(new AccessTestAction() {
824      @Override
825      public Object run() throws Exception {
826        ACCESS_CONTROLLER.preExists(ObserverContextImpl.createAndPrepare(RCP_ENV),
827          new Get(TEST_ROW), true);
828        return null;
829      }
830    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
831
832    // prePut
833    verifyAllowed(new AccessTestAction() {
834      @Override
835      public Object run() throws Exception {
836        ACCESS_CONTROLLER.prePut(ObserverContextImpl.createAndPrepare(RCP_ENV),
837          new Put(TEST_ROW), new WALEdit(), Durability.USE_DEFAULT);
838        return null;
839      }
840    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
841
842    // preDelete
843    verifyAllowed(new AccessTestAction() {
844      @Override
845      public Object run() throws Exception {
846        ACCESS_CONTROLLER.preDelete(ObserverContextImpl.createAndPrepare(RCP_ENV),
847          new Delete(TEST_ROW), new WALEdit(), Durability.USE_DEFAULT);
848        return null;
849      }
850    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
851
852    // preBatchMutate
853    verifyAllowed(new AccessTestAction() {
854      @Override
855      public Object run() throws Exception {
856        ACCESS_CONTROLLER.preBatchMutate(ObserverContextImpl.createAndPrepare(RCP_ENV),
857          new MiniBatchOperationInProgress<>(null, null, null, 0, 0, 0));
858        return null;
859      }
860    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
861
862    // preCheckAndPut
863    verifyAllowed(new AccessTestAction() {
864      @Override
865      public Object run() throws Exception {
866        ACCESS_CONTROLLER.preCheckAndPut(ObserverContextImpl.createAndPrepare(RCP_ENV),
867          TEST_ROW, TEST_FAMILY, TEST_Q1, CompareOperator.EQUAL,
868          new BinaryComparator("foo".getBytes()), new Put(TEST_ROW), true);
869        return null;
870      }
871    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
872
873    // preCheckAndDelete
874    verifyAllowed(new AccessTestAction() {
875      @Override
876      public Object run() throws Exception {
877        ACCESS_CONTROLLER.preCheckAndDelete(ObserverContextImpl.createAndPrepare(RCP_ENV),
878          TEST_ROW, TEST_FAMILY, TEST_Q1, CompareOperator.EQUAL,
879          new BinaryComparator("foo".getBytes()), new Delete(TEST_ROW), true);
880        return null;
881      }
882    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
883
884    // preAppend
885    verifyAllowed(new AccessTestAction() {
886      @Override
887      public Object run() throws Exception {
888        ACCESS_CONTROLLER.preAppend(ObserverContextImpl.createAndPrepare(RCP_ENV),
889          new Append(TEST_ROW));
890        return null;
891      }
892    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
893
894    // preIncrement
895    verifyAllowed(new AccessTestAction() {
896      @Override
897      public Object run() throws Exception {
898        ACCESS_CONTROLLER.preIncrement(ObserverContextImpl.createAndPrepare(RCP_ENV),
899          new Increment(TEST_ROW));
900        return null;
901      }
902    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
903
904    // preScannerOpen
905    verifyAllowed(new AccessTestAction() {
906      @Override
907      public Object run() throws Exception {
908        ACCESS_CONTROLLER.preScannerOpen(ObserverContextImpl.createAndPrepare(RCP_ENV),
909          new Scan());
910        return null;
911      }
912    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
913
914    // preBulkLoadHFile
915    verifyAllowed(new AccessTestAction() {
916      @Override
917      public Object run() throws Exception {
918        List<Pair<byte[], String>> paths = Lists.newArrayList();
919        ACCESS_CONTROLLER.preBulkLoadHFile(ObserverContextImpl.createAndPrepare(RCP_ENV),
920          paths);
921        return null;
922      }
923    }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE);
924
925  }
926
927  @Test
928  public void testPassiveCellPermissions() throws Exception {
929    final Configuration conf = TEST_UTIL.getConfiguration();
930
931    // store two sets of values, one store with a cell level ACL, and one without
932    verifyAllowed(new AccessTestAction() {
933      @Override
934      public Object run() throws Exception {
935        try(Connection connection = ConnectionFactory.createConnection(conf);
936            Table t = connection.getTable(testTable.getTableName())) {
937          Put p;
938          // with ro ACL
939          p = new Put(TEST_ROW).addColumn(TEST_FAMILY, TEST_Q1, ZERO);
940          p.setACL(USER_NONE.getShortName(), new Permission(Action.READ));
941          t.put(p);
942          // with rw ACL
943          p = new Put(TEST_ROW).addColumn(TEST_FAMILY, TEST_Q2, ZERO);
944          p.setACL(USER_NONE.getShortName(), new Permission(Action.READ, Action.WRITE));
945          t.put(p);
946          // no ACL
947          p = new Put(TEST_ROW)
948              .addColumn(TEST_FAMILY, TEST_Q3, ZERO)
949              .addColumn(TEST_FAMILY, TEST_Q4, ZERO);
950          t.put(p);
951        }
952        return null;
953      }
954    }, USER_OWNER);
955
956    // check that a scan over the test data returns the expected number of KVs
957
958    final List<Cell> scanResults = Lists.newArrayList();
959
960    AccessTestAction scanAction = new AccessTestAction() {
961      @Override
962      public List<Cell> run() throws Exception {
963        Scan scan = new Scan();
964        scan.setStartRow(TEST_ROW);
965        scan.setStopRow(Bytes.add(TEST_ROW, new byte[]{ 0 } ));
966        scan.addFamily(TEST_FAMILY);
967        Connection connection = ConnectionFactory.createConnection(conf);
968        Table t = connection.getTable(testTable.getTableName());
969        try {
970          ResultScanner scanner = t.getScanner(scan);
971          Result result = null;
972          do {
973            result = scanner.next();
974            if (result != null) {
975              scanResults.addAll(result.listCells());
976            }
977          } while (result != null);
978        } finally {
979          t.close();
980          connection.close();
981        }
982        return scanResults;
983      }
984    };
985
986    // owner will see all values
987    scanResults.clear();
988    verifyAllowed(scanAction, USER_OWNER);
989    assertEquals(4, scanResults.size());
990
991    // other user will also see 4 values
992    // if cell filtering was active, we would only see 2 values
993    scanResults.clear();
994    verifyAllowed(scanAction, USER_NONE);
995    assertEquals(4, scanResults.size());
996  }
997
998}