001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.security.access;
019
020import static org.apache.hadoop.hbase.AuthUtil.toGroupEntry;
021import static org.junit.Assert.assertEquals;
022import static org.junit.Assert.assertTrue;
023
024import com.google.protobuf.BlockingRpcChannel;
025import java.util.Arrays;
026import java.util.List;
027import java.util.Map;
028import java.util.Objects;
029import org.apache.hadoop.conf.Configuration;
030import org.apache.hadoop.hbase.HBaseClassTestRule;
031import org.apache.hadoop.hbase.HBaseTestingUtility;
032import org.apache.hadoop.hbase.HColumnDescriptor;
033import org.apache.hadoop.hbase.HConstants;
034import org.apache.hadoop.hbase.HTableDescriptor;
035import org.apache.hadoop.hbase.NamespaceDescriptor;
036import org.apache.hadoop.hbase.TableName;
037import org.apache.hadoop.hbase.client.Admin;
038import org.apache.hadoop.hbase.client.Connection;
039import org.apache.hadoop.hbase.client.ConnectionFactory;
040import org.apache.hadoop.hbase.client.Get;
041import org.apache.hadoop.hbase.client.Result;
042import org.apache.hadoop.hbase.client.Table;
043import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
044import org.apache.hadoop.hbase.coprocessor.ObserverContextImpl;
045import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
046import org.apache.hadoop.hbase.security.User;
047import org.apache.hadoop.hbase.security.access.Permission.Action;
048import org.apache.hadoop.hbase.testclassification.MediumTests;
049import org.apache.hadoop.hbase.testclassification.SecurityTests;
050import org.apache.hadoop.hbase.util.Bytes;
051import org.apache.hadoop.hbase.util.JVMClusterUtil;
052import org.junit.AfterClass;
053import org.junit.BeforeClass;
054import org.junit.ClassRule;
055import org.junit.Test;
056import org.junit.experimental.categories.Category;
057import org.slf4j.Logger;
058import org.slf4j.LoggerFactory;
059
060import org.apache.hbase.thirdparty.com.google.common.collect.ListMultimap;
061
062@Category({SecurityTests.class, MediumTests.class})
063public class TestNamespaceCommands extends SecureTestUtil {
064
065  @ClassRule
066  public static final HBaseClassTestRule CLASS_RULE =
067      HBaseClassTestRule.forClass(TestNamespaceCommands.class);
068
069  private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
070  private static final Logger LOG = LoggerFactory.getLogger(TestNamespaceCommands.class);
071  private static String TEST_NAMESPACE = "ns1";
072  private static String TEST_NAMESPACE2 = "ns2";
073  private static Configuration conf;
074  private static MasterCoprocessorEnvironment CP_ENV;
075  private static AccessController ACCESS_CONTROLLER;
076
077  // user with all permissions
078  private static User SUPERUSER;
079
080  // user with A permission on global
081  private static User USER_GLOBAL_ADMIN;
082  // user with C permission on global
083  private static User USER_GLOBAL_CREATE;
084  // user with W permission on global
085  private static User USER_GLOBAL_WRITE;
086  // user with R permission on global
087  private static User USER_GLOBAL_READ;
088  // user with X permission on global
089  private static User USER_GLOBAL_EXEC;
090
091  // user with A permission on namespace
092  private static User USER_NS_ADMIN;
093  // user with C permission on namespace
094  private static User USER_NS_CREATE;
095  // user with W permission on namespace
096  private static User USER_NS_WRITE;
097  // user with R permission on namespace.
098  private static User USER_NS_READ;
099  // user with X permission on namespace.
100  private static User USER_NS_EXEC;
101
102  // user with rw permissions
103  private static User USER_TABLE_WRITE;  // TODO: WE DO NOT GIVE ANY PERMS TO THIS USER
104  //user with create table permissions alone
105  private static User USER_TABLE_CREATE; // TODO: WE DO NOT GIVE ANY PERMS TO THIS USER
106
107  private static final String GROUP_ADMIN = "group_admin";
108  private static final String GROUP_NS_ADMIN = "group_ns_admin";
109  private static final String GROUP_CREATE = "group_create";
110  private static final String GROUP_READ = "group_read";
111  private static final String GROUP_WRITE = "group_write";
112
113  private static User USER_GROUP_ADMIN;
114  private static User USER_GROUP_NS_ADMIN;
115  private static User USER_GROUP_CREATE;
116  private static User USER_GROUP_READ;
117  private static User USER_GROUP_WRITE;
118
119  private static String TEST_TABLE = TEST_NAMESPACE + ":testtable";
120  private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
121
122  @BeforeClass
123  public static void beforeClass() throws Exception {
124    conf = UTIL.getConfiguration();
125    enableSecurity(conf);
126
127    SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
128    // Users with global permissions
129    USER_GLOBAL_ADMIN = User.createUserForTesting(conf, "global_admin", new String[0]);
130    USER_GLOBAL_CREATE = User.createUserForTesting(conf, "global_create", new String[0]);
131    USER_GLOBAL_WRITE = User.createUserForTesting(conf, "global_write", new String[0]);
132    USER_GLOBAL_READ = User.createUserForTesting(conf, "global_read", new String[0]);
133    USER_GLOBAL_EXEC = User.createUserForTesting(conf, "global_exec", new String[0]);
134
135    USER_NS_ADMIN = User.createUserForTesting(conf, "namespace_admin", new String[0]);
136    USER_NS_CREATE = User.createUserForTesting(conf, "namespace_create", new String[0]);
137    USER_NS_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]);
138    USER_NS_READ = User.createUserForTesting(conf, "namespace_read", new String[0]);
139    USER_NS_EXEC = User.createUserForTesting(conf, "namespace_exec", new String[0]);
140
141    USER_TABLE_CREATE = User.createUserForTesting(conf, "table_create", new String[0]);
142    USER_TABLE_WRITE = User.createUserForTesting(conf, "table_write", new String[0]);
143
144    USER_GROUP_ADMIN =
145        User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN });
146    USER_GROUP_NS_ADMIN =
147        User.createUserForTesting(conf, "user_group_ns_admin", new String[] { GROUP_NS_ADMIN });
148    USER_GROUP_CREATE =
149        User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE });
150    USER_GROUP_READ =
151        User.createUserForTesting(conf, "user_group_read", new String[] { GROUP_READ });
152    USER_GROUP_WRITE =
153        User.createUserForTesting(conf, "user_group_write", new String[] { GROUP_WRITE });
154    // TODO: other table perms
155
156    UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
157    UTIL.startMiniCluster();
158    // Wait for the ACL table to become available
159    UTIL.waitTableAvailable(PermissionStorage.ACL_TABLE_NAME.getName(), 30 * 1000);
160
161    // Find the Access Controller CP. Could be on master or if master is not serving regions, is
162    // on an arbitrary server.
163    for (JVMClusterUtil.RegionServerThread rst:
164        UTIL.getMiniHBaseCluster().getLiveRegionServerThreads()) {
165      ACCESS_CONTROLLER = rst.getRegionServer().getRegionServerCoprocessorHost().
166        findCoprocessor(AccessController.class);
167      if (ACCESS_CONTROLLER != null) break;
168    }
169    if (ACCESS_CONTROLLER == null) throw new NullPointerException();
170
171    UTIL.getAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE).build());
172    UTIL.getAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE2).build());
173
174    // grants on global
175    grantGlobal(UTIL, USER_GLOBAL_ADMIN.getShortName(),  Permission.Action.ADMIN);
176    grantGlobal(UTIL, USER_GLOBAL_CREATE.getShortName(), Permission.Action.CREATE);
177    grantGlobal(UTIL, USER_GLOBAL_WRITE.getShortName(),  Permission.Action.WRITE);
178    grantGlobal(UTIL, USER_GLOBAL_READ.getShortName(),   Permission.Action.READ);
179    grantGlobal(UTIL, USER_GLOBAL_EXEC.getShortName(),   Permission.Action.EXEC);
180
181    // grants on namespace
182    grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(),  TEST_NAMESPACE, Permission.Action.ADMIN);
183    grantOnNamespace(UTIL, USER_NS_CREATE.getShortName(), TEST_NAMESPACE, Permission.Action.CREATE);
184    grantOnNamespace(UTIL, USER_NS_WRITE.getShortName(),  TEST_NAMESPACE, Permission.Action.WRITE);
185    grantOnNamespace(UTIL, USER_NS_READ.getShortName(),   TEST_NAMESPACE, Permission.Action.READ);
186    grantOnNamespace(UTIL, USER_NS_EXEC.getShortName(),   TEST_NAMESPACE, Permission.Action.EXEC);
187    grantOnNamespace(UTIL, toGroupEntry(GROUP_NS_ADMIN), TEST_NAMESPACE, Permission.Action.ADMIN);
188
189    grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(), TEST_NAMESPACE2, Permission.Action.ADMIN);
190
191    grantGlobal(UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN);
192    grantGlobal(UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE);
193    grantGlobal(UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ);
194    grantGlobal(UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE);
195  }
196
197  @AfterClass
198  public static void afterClass() throws Exception {
199    UTIL.getAdmin().deleteNamespace(TEST_NAMESPACE);
200    UTIL.getAdmin().deleteNamespace(TEST_NAMESPACE2);
201    UTIL.shutdownMiniCluster();
202  }
203
204  @Test
205  public void testAclTableEntries() throws Exception {
206    String userTestNamespace = "userTestNsp";
207    Table acl = UTIL.getConnection().getTable(PermissionStorage.ACL_TABLE_NAME);
208    try {
209      ListMultimap<String, UserPermission> perms =
210          PermissionStorage.getNamespacePermissions(conf, TEST_NAMESPACE);
211      for (Map.Entry<String, UserPermission> entry : perms.entries()) {
212        LOG.debug(Objects.toString(entry));
213      }
214      assertEquals(6, perms.size());
215
216      // Grant and check state in ACL table
217      grantOnNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
218        Permission.Action.WRITE);
219
220      Result result = acl.get(new Get(Bytes.toBytes(userTestNamespace)));
221      assertTrue(result != null);
222      perms = PermissionStorage.getNamespacePermissions(conf, TEST_NAMESPACE);
223      assertEquals(7, perms.size());
224      List<UserPermission> namespacePerms = perms.get(userTestNamespace);
225      assertTrue(perms.containsKey(userTestNamespace));
226      assertEquals(1, namespacePerms.size());
227      assertEquals(TEST_NAMESPACE,
228        ((NamespacePermission) namespacePerms.get(0).getPermission()).getNamespace());
229      assertEquals(1, namespacePerms.get(0).getPermission().getActions().length);
230      assertEquals(Permission.Action.WRITE, namespacePerms.get(0).getPermission().getActions()[0]);
231
232      // Revoke and check state in ACL table
233      revokeFromNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
234        Permission.Action.WRITE);
235
236      perms = PermissionStorage.getNamespacePermissions(conf, TEST_NAMESPACE);
237      assertEquals(6, perms.size());
238    } finally {
239      acl.close();
240    }
241  }
242
243  @Test
244  public void testModifyNamespace() throws Exception {
245    AccessTestAction modifyNamespace = new AccessTestAction() {
246      @Override
247      public Object run() throws Exception {
248        ACCESS_CONTROLLER.preModifyNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
249          null, // not needed by AccessController
250          NamespaceDescriptor.create(TEST_NAMESPACE).addConfiguration("abc", "156").build());
251        return null;
252      }
253    };
254
255    // modifyNamespace: superuser | global(A) | NS(A)
256    verifyAllowed(modifyNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
257    verifyDenied(modifyNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
258      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
259      USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
260  }
261
262  @Test
263  public void testCreateAndDeleteNamespace() throws Exception {
264    AccessTestAction createNamespace = new AccessTestAction() {
265      @Override
266      public Object run() throws Exception {
267        ACCESS_CONTROLLER.preCreateNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
268          NamespaceDescriptor.create(TEST_NAMESPACE2).build());
269        return null;
270      }
271    };
272
273    AccessTestAction deleteNamespace = new AccessTestAction() {
274      @Override
275      public Object run() throws Exception {
276        ACCESS_CONTROLLER.preDeleteNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
277          TEST_NAMESPACE2);
278        return null;
279      }
280    };
281
282    // createNamespace: superuser | global(A)
283    verifyAllowed(createNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
284    // all others should be denied
285    verifyDenied(createNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
286      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
287      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
288
289    // deleteNamespace: superuser | global(A) | NS(A)
290    verifyAllowed(deleteNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
291    verifyDenied(deleteNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
292      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
293      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
294  }
295
296  @Test
297  public void testGetNamespaceDescriptor() throws Exception {
298    AccessTestAction getNamespaceAction = new AccessTestAction() {
299      @Override
300      public Object run() throws Exception {
301        ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContextImpl.createAndPrepare(CP_ENV),
302          TEST_NAMESPACE);
303        return null;
304      }
305    };
306    // getNamespaceDescriptor : superuser | global(A) | NS(A)
307    verifyAllowed(getNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
308      USER_GROUP_ADMIN);
309    verifyDenied(getNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
310      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
311      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
312  }
313
314  @Test
315  public void testListNamespaces() throws Exception {
316    AccessTestAction listAction = new AccessTestAction() {
317      @Override
318      public Object run() throws Exception {
319        Connection unmanagedConnection =
320            ConnectionFactory.createConnection(UTIL.getConfiguration());
321        Admin admin = unmanagedConnection.getAdmin();
322        try {
323          return Arrays.asList(admin.listNamespaceDescriptors());
324        } finally {
325          admin.close();
326          unmanagedConnection.close();
327        }
328      }
329    };
330
331    // listNamespaces         : All access*
332    // * Returned list will only show what you can call getNamespaceDescriptor()
333
334    verifyAllowed(listAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN, USER_GROUP_ADMIN);
335
336    // we have 3 namespaces: [default, hbase, TEST_NAMESPACE, TEST_NAMESPACE2]
337    assertEquals(4, ((List)SUPERUSER.runAs(listAction)).size());
338    assertEquals(4, ((List)USER_GLOBAL_ADMIN.runAs(listAction)).size());
339    assertEquals(4, ((List)USER_GROUP_ADMIN.runAs(listAction)).size());
340
341    assertEquals(2, ((List)USER_NS_ADMIN.runAs(listAction)).size());
342
343    assertEquals(0, ((List)USER_GLOBAL_CREATE.runAs(listAction)).size());
344    assertEquals(0, ((List)USER_GLOBAL_WRITE.runAs(listAction)).size());
345    assertEquals(0, ((List)USER_GLOBAL_READ.runAs(listAction)).size());
346    assertEquals(0, ((List)USER_GLOBAL_EXEC.runAs(listAction)).size());
347    assertEquals(0, ((List)USER_NS_CREATE.runAs(listAction)).size());
348    assertEquals(0, ((List)USER_NS_WRITE.runAs(listAction)).size());
349    assertEquals(0, ((List)USER_NS_READ.runAs(listAction)).size());
350    assertEquals(0, ((List)USER_NS_EXEC.runAs(listAction)).size());
351    assertEquals(0, ((List)USER_TABLE_CREATE.runAs(listAction)).size());
352    assertEquals(0, ((List)USER_TABLE_WRITE.runAs(listAction)).size());
353    assertEquals(0, ((List)USER_GROUP_CREATE.runAs(listAction)).size());
354    assertEquals(0, ((List)USER_GROUP_READ.runAs(listAction)).size());
355    assertEquals(0, ((List)USER_GROUP_WRITE.runAs(listAction)).size());
356  }
357
358  @Test
359  public void testGrantRevoke() throws Exception {
360    final String testUser = "testUser";
361    // Test if client API actions are authorized
362    AccessTestAction grantAction = new AccessTestAction() {
363      @Override
364      public Object run() throws Exception {
365        try (Connection connection = ConnectionFactory.createConnection(conf)) {
366          connection.getAdmin().grant(new UserPermission(testUser,
367              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()),
368            false);
369        }
370        return null;
371      }
372    };
373    AccessTestAction grantNamespaceAction = new AccessTestAction() {
374      @Override
375      public Object run() throws Exception {
376        try (Connection conn = ConnectionFactory.createConnection(conf)) {
377          conn.getAdmin().grant(new UserPermission(USER_GROUP_NS_ADMIN.getShortName(),
378              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.READ).build()),
379            false);
380        }
381        return null;
382      }
383    };
384
385    AccessTestAction revokeAction = new AccessTestAction() {
386      @Override
387      public Object run() throws Exception {
388        try (Connection connection = ConnectionFactory.createConnection(conf)) {
389          connection.getAdmin().revoke(new UserPermission(testUser,
390              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()));
391        }
392        return null;
393      }
394    };
395    AccessTestAction revokeNamespaceAction = new AccessTestAction() {
396      @Override
397      public Object run() throws Exception {
398        try (Connection connection = ConnectionFactory.createConnection(conf)) {
399          connection.getAdmin().revoke(new UserPermission(USER_GROUP_NS_ADMIN.getShortName(),
400              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.READ).build()));
401        }
402        return null;
403      }
404    };
405
406    AccessTestAction getPermissionsAction = new AccessTestAction() {
407      @Override
408      public Object run() throws Exception {
409        try (Connection connection = ConnectionFactory.createConnection(conf)) {
410          connection.getAdmin()
411              .getUserPermissions(GetUserPermissionsRequest.newBuilder(TEST_NAMESPACE).build());
412        }
413        return null;
414      }
415    };
416
417    AccessTestAction preGrantAction = new AccessTestAction() {
418      @Override
419      public Object run() throws Exception {
420        ACCESS_CONTROLLER.preGrant(ObserverContextImpl.createAndPrepare(CP_ENV),
421          new UserPermission(testUser,
422              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()),
423          false);
424        return null;
425      }
426    };
427    AccessTestAction preRevokeAction = new AccessTestAction() {
428      @Override
429      public Object run() throws Exception {
430        ACCESS_CONTROLLER.preRevoke(ObserverContextImpl.createAndPrepare(CP_ENV),
431          new UserPermission(testUser,
432              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()));
433        return null;
434      }
435    };
436
437    AccessTestAction grantCPAction = new AccessTestAction() {
438      @Override
439      public Object run() throws Exception {
440        try (Connection connection = ConnectionFactory.createConnection(conf);
441            Table acl = connection.getTable(PermissionStorage.ACL_TABLE_NAME)) {
442          BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
443          AccessControlService.BlockingInterface protocol =
444              AccessControlService.newBlockingStub(service);
445          AccessControlUtil.grant(null, protocol, testUser, TEST_NAMESPACE, false, Action.WRITE);
446        }
447        return null;
448      }
449    };
450    AccessTestAction revokeCPAction = new AccessTestAction() {
451      @Override
452      public Object run() throws Exception {
453        try (Connection connection = ConnectionFactory.createConnection(conf);
454            Table acl = connection.getTable(PermissionStorage.ACL_TABLE_NAME)) {
455          BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
456          AccessControlService.BlockingInterface protocol =
457              AccessControlService.newBlockingStub(service);
458          AccessControlUtil.revoke(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
459        }
460        return null;
461      }
462    };
463
464    verifyAllowed(grantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
465    verifyDenied(grantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
466      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
467      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
468    verifyAllowed(grantNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
469      USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
470    verifyDenied(grantNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
471      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
472      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
473
474    verifyAllowed(revokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
475    verifyDenied(revokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
476      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
477      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
478    verifyAllowed(revokeNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
479      USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
480    verifyDenied(revokeNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
481      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
482      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
483
484    verifyAllowed(getPermissionsAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
485      USER_GROUP_ADMIN);
486    verifyDenied(getPermissionsAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
487      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
488      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
489
490    verifyAllowed(preGrantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
491    verifyDenied(preGrantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
492      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
493      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
494    verifyAllowed(preRevokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
495    verifyDenied(preRevokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
496      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
497      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
498
499    verifyAllowed(grantCPAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
500    verifyDenied(grantCPAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
501      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
502      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
503    verifyAllowed(revokeCPAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
504    verifyDenied(revokeCPAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
505      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
506      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
507  }
508
509  @Test
510  public void testCreateTableWithNamespace() throws Exception {
511    AccessTestAction createTable = new AccessTestAction() {
512      @Override
513      public Object run() throws Exception {
514        HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TEST_TABLE));
515        htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
516        ACCESS_CONTROLLER.preCreateTable(ObserverContextImpl.createAndPrepare(CP_ENV), htd, null);
517        return null;
518      }
519    };
520
521    //createTable            : superuser | global(C) | NS(C)
522    verifyAllowed(createTable, SUPERUSER, USER_GLOBAL_CREATE, USER_NS_CREATE, USER_GROUP_CREATE);
523    verifyDenied(createTable, USER_GLOBAL_ADMIN, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
524      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
525      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_ADMIN);
526  }
527}