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(AccessControlLists.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(AccessControlLists.ACL_TABLE_NAME);
208    try {
209      ListMultimap<String, UserPermission> perms =
210        AccessControlLists.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 = AccessControlLists.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 = AccessControlLists.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          NamespaceDescriptor.create(TEST_NAMESPACE).addConfiguration("abc", "156").build());
250        return null;
251      }
252    };
253
254    // modifyNamespace: superuser | global(A) | NS(A)
255    verifyAllowed(modifyNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
256    verifyDenied(modifyNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
257      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
258      USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
259  }
260
261  @Test
262  public void testCreateAndDeleteNamespace() throws Exception {
263    AccessTestAction createNamespace = new AccessTestAction() {
264      @Override
265      public Object run() throws Exception {
266        ACCESS_CONTROLLER.preCreateNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
267          NamespaceDescriptor.create(TEST_NAMESPACE2).build());
268        return null;
269      }
270    };
271
272    AccessTestAction deleteNamespace = new AccessTestAction() {
273      @Override
274      public Object run() throws Exception {
275        ACCESS_CONTROLLER.preDeleteNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
276          TEST_NAMESPACE2);
277        return null;
278      }
279    };
280
281    // createNamespace: superuser | global(A)
282    verifyAllowed(createNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
283    // all others should be denied
284    verifyDenied(createNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
285      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
286      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
287
288    // deleteNamespace: superuser | global(A) | NS(A)
289    verifyAllowed(deleteNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
290    verifyDenied(deleteNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
291      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
292      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
293  }
294
295  @Test
296  public void testGetNamespaceDescriptor() throws Exception {
297    AccessTestAction getNamespaceAction = new AccessTestAction() {
298      @Override
299      public Object run() throws Exception {
300        ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContextImpl.createAndPrepare(CP_ENV),
301          TEST_NAMESPACE);
302        return null;
303      }
304    };
305    // getNamespaceDescriptor : superuser | global(A) | NS(A)
306    verifyAllowed(getNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
307      USER_GROUP_ADMIN);
308    verifyDenied(getNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
309      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
310      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
311  }
312
313  @Test
314  public void testListNamespaces() throws Exception {
315    AccessTestAction listAction = new AccessTestAction() {
316      @Override
317      public Object run() throws Exception {
318        Connection unmanagedConnection =
319            ConnectionFactory.createConnection(UTIL.getConfiguration());
320        Admin admin = unmanagedConnection.getAdmin();
321        try {
322          return Arrays.asList(admin.listNamespaceDescriptors());
323        } finally {
324          admin.close();
325          unmanagedConnection.close();
326        }
327      }
328    };
329
330    // listNamespaces         : All access*
331    // * Returned list will only show what you can call getNamespaceDescriptor()
332
333    verifyAllowed(listAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN, USER_GROUP_ADMIN);
334
335    // we have 3 namespaces: [default, hbase, TEST_NAMESPACE, TEST_NAMESPACE2]
336    assertEquals(4, ((List)SUPERUSER.runAs(listAction)).size());
337    assertEquals(4, ((List)USER_GLOBAL_ADMIN.runAs(listAction)).size());
338    assertEquals(4, ((List)USER_GROUP_ADMIN.runAs(listAction)).size());
339
340    assertEquals(2, ((List)USER_NS_ADMIN.runAs(listAction)).size());
341
342    assertEquals(0, ((List)USER_GLOBAL_CREATE.runAs(listAction)).size());
343    assertEquals(0, ((List)USER_GLOBAL_WRITE.runAs(listAction)).size());
344    assertEquals(0, ((List)USER_GLOBAL_READ.runAs(listAction)).size());
345    assertEquals(0, ((List)USER_GLOBAL_EXEC.runAs(listAction)).size());
346    assertEquals(0, ((List)USER_NS_CREATE.runAs(listAction)).size());
347    assertEquals(0, ((List)USER_NS_WRITE.runAs(listAction)).size());
348    assertEquals(0, ((List)USER_NS_READ.runAs(listAction)).size());
349    assertEquals(0, ((List)USER_NS_EXEC.runAs(listAction)).size());
350    assertEquals(0, ((List)USER_TABLE_CREATE.runAs(listAction)).size());
351    assertEquals(0, ((List)USER_TABLE_WRITE.runAs(listAction)).size());
352    assertEquals(0, ((List)USER_GROUP_CREATE.runAs(listAction)).size());
353    assertEquals(0, ((List)USER_GROUP_READ.runAs(listAction)).size());
354    assertEquals(0, ((List)USER_GROUP_WRITE.runAs(listAction)).size());
355  }
356
357  @Test
358  public void testGrantRevoke() throws Exception {
359    final String testUser = "testUser";
360    // Test if client API actions are authorized
361    AccessTestAction grantAction = new AccessTestAction() {
362      @Override
363      public Object run() throws Exception {
364        try (Connection connection = ConnectionFactory.createConnection(conf)) {
365          connection.getAdmin().grant(new UserPermission(testUser,
366              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()),
367            false);
368        }
369        return null;
370      }
371    };
372    AccessTestAction grantNamespaceAction = new AccessTestAction() {
373      @Override
374      public Object run() throws Exception {
375        try (Connection conn = ConnectionFactory.createConnection(conf)) {
376          conn.getAdmin().grant(new UserPermission(USER_GROUP_NS_ADMIN.getShortName(),
377              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.READ).build()),
378            false);
379        }
380        return null;
381      }
382    };
383
384    AccessTestAction revokeAction = new AccessTestAction() {
385      @Override
386      public Object run() throws Exception {
387        try (Connection connection = ConnectionFactory.createConnection(conf)) {
388          connection.getAdmin().revoke(new UserPermission(testUser,
389              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()));
390        }
391        return null;
392      }
393    };
394    AccessTestAction revokeNamespaceAction = new AccessTestAction() {
395      @Override
396      public Object run() throws Exception {
397        try (Connection connection = ConnectionFactory.createConnection(conf)) {
398          connection.getAdmin().revoke(new UserPermission(USER_GROUP_NS_ADMIN.getShortName(),
399              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.READ).build()));
400        }
401        return null;
402      }
403    };
404
405    AccessTestAction getPermissionsAction = new AccessTestAction() {
406      @Override
407      public Object run() throws Exception {
408        try (Connection connection = ConnectionFactory.createConnection(conf)) {
409          connection.getAdmin()
410              .getUserPermissions(GetUserPermissionsRequest.newBuilder(TEST_NAMESPACE).build());
411        }
412        return null;
413      }
414    };
415
416    AccessTestAction preGrantAction = new AccessTestAction() {
417      @Override
418      public Object run() throws Exception {
419        ACCESS_CONTROLLER.preGrant(ObserverContextImpl.createAndPrepare(CP_ENV),
420          new UserPermission(testUser,
421              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()),
422          false);
423        return null;
424      }
425    };
426    AccessTestAction preRevokeAction = new AccessTestAction() {
427      @Override
428      public Object run() throws Exception {
429        ACCESS_CONTROLLER.preRevoke(ObserverContextImpl.createAndPrepare(CP_ENV),
430          new UserPermission(testUser,
431              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()));
432        return null;
433      }
434    };
435
436    AccessTestAction grantCPAction = new AccessTestAction() {
437      @Override
438      public Object run() throws Exception {
439        try (Connection connection = ConnectionFactory.createConnection(conf);
440            Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
441          BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
442          AccessControlService.BlockingInterface protocol =
443              AccessControlService.newBlockingStub(service);
444          AccessControlUtil.grant(null, protocol, testUser, TEST_NAMESPACE, false, Action.WRITE);
445        }
446        return null;
447      }
448    };
449    AccessTestAction revokeCPAction = new AccessTestAction() {
450      @Override
451      public Object run() throws Exception {
452        try (Connection connection = ConnectionFactory.createConnection(conf);
453            Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
454          BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
455          AccessControlService.BlockingInterface protocol =
456              AccessControlService.newBlockingStub(service);
457          AccessControlUtil.revoke(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
458        }
459        return null;
460      }
461    };
462
463    verifyAllowed(grantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
464    verifyDenied(grantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
465      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
466      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
467    verifyAllowed(grantNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
468      USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
469    verifyDenied(grantNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
470      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
471      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
472
473    verifyAllowed(revokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
474    verifyDenied(revokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
475      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
476      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
477    verifyAllowed(revokeNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
478      USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
479    verifyDenied(revokeNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
480      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
481      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
482
483    verifyAllowed(getPermissionsAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
484      USER_GROUP_ADMIN);
485    verifyDenied(getPermissionsAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
486      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
487      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
488
489    verifyAllowed(preGrantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
490    verifyDenied(preGrantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
491      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
492      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
493    verifyAllowed(preRevokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
494    verifyDenied(preRevokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
495      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
496      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
497
498    verifyAllowed(grantCPAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
499    verifyDenied(grantCPAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
500      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
501      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
502    verifyAllowed(revokeCPAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
503    verifyDenied(revokeCPAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
504      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
505      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
506  }
507
508  @Test
509  public void testCreateTableWithNamespace() throws Exception {
510    AccessTestAction createTable = new AccessTestAction() {
511      @Override
512      public Object run() throws Exception {
513        HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TEST_TABLE));
514        htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
515        ACCESS_CONTROLLER.preCreateTable(ObserverContextImpl.createAndPrepare(CP_ENV), htd, null);
516        return null;
517      }
518    };
519
520    //createTable            : superuser | global(C) | NS(C)
521    verifyAllowed(createTable, SUPERUSER, USER_GLOBAL_CREATE, USER_NS_CREATE, USER_GROUP_CREATE);
522    verifyDenied(createTable, USER_GLOBAL_ADMIN, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
523      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
524      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_ADMIN);
525  }
526}