View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.security.access;
19  
20  import static org.apache.hadoop.hbase.AuthUtil.toGroupEntry;
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.util.List;
25  import java.util.Arrays;
26  import java.util.Map;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hadoop.conf.Configuration;
31  import org.apache.hadoop.hbase.HBaseTestingUtility;
32  import org.apache.hadoop.hbase.HColumnDescriptor;
33  import org.apache.hadoop.hbase.HConstants;
34  import org.apache.hadoop.hbase.HTableDescriptor;
35  import org.apache.hadoop.hbase.NamespaceDescriptor;
36  import org.apache.hadoop.hbase.testclassification.MediumTests;
37  import org.apache.hadoop.hbase.TableName;
38  import org.apache.hadoop.hbase.client.Admin;
39  import org.apache.hadoop.hbase.client.Connection;
40  import org.apache.hadoop.hbase.client.ConnectionFactory;
41  import org.apache.hadoop.hbase.client.Get;
42  import org.apache.hadoop.hbase.client.Result;
43  import org.apache.hadoop.hbase.client.Table;
44  import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
45  import org.apache.hadoop.hbase.coprocessor.ObserverContext;
46  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
47  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
48  import org.apache.hadoop.hbase.security.User;
49  import org.apache.hadoop.hbase.security.access.Permission.Action;
50  import org.apache.hadoop.hbase.util.Bytes;
51  import org.junit.AfterClass;
52  import org.junit.BeforeClass;
53  import org.junit.Test;
54  import org.junit.experimental.categories.Category;
55  
56  import com.google.common.collect.ListMultimap;
57  import com.google.protobuf.BlockingRpcChannel;
58  
59  @Category(MediumTests.class)
60  public class TestNamespaceCommands extends SecureTestUtil {
61    private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
62    private static final Log LOG = LogFactory.getLog(TestNamespaceCommands.class);
63    private static String TEST_NAMESPACE = "ns1";
64    private static String TEST_NAMESPACE2 = "ns2";
65    private static Configuration conf;
66    private static MasterCoprocessorEnvironment CP_ENV;
67    private static AccessController ACCESS_CONTROLLER;
68  
69    // user with all permissions
70    private static User SUPERUSER;
71  
72    // user with A permission on global
73    private static User USER_GLOBAL_ADMIN;
74    // user with C permission on global
75    private static User USER_GLOBAL_CREATE;
76    // user with W permission on global
77    private static User USER_GLOBAL_WRITE;
78    // user with R permission on global
79    private static User USER_GLOBAL_READ;
80    // user with X permission on global
81    private static User USER_GLOBAL_EXEC;
82  
83    // user with A permission on namespace
84    private static User USER_NS_ADMIN;
85    // user with C permission on namespace
86    private static User USER_NS_CREATE;
87    // user with W permission on namespace
88    private static User USER_NS_WRITE;
89    // user with R permission on namespace.
90    private static User USER_NS_READ;
91    // user with X permission on namespace.
92    private static User USER_NS_EXEC;
93  
94    // user with rw permissions
95    private static User USER_TABLE_WRITE;  // TODO: WE DO NOT GIVE ANY PERMS TO THIS USER
96    //user with create table permissions alone
97    private static User USER_TABLE_CREATE; // TODO: WE DO NOT GIVE ANY PERMS TO THIS USER
98  
99    private static final String GROUP_ADMIN = "group_admin";
100   private static final String GROUP_NS_ADMIN = "group_ns_admin";
101   private static final String GROUP_CREATE = "group_create";
102   private static final String GROUP_READ = "group_read";
103   private static final String GROUP_WRITE = "group_write";
104 
105   private static User USER_GROUP_ADMIN;
106   private static User USER_GROUP_NS_ADMIN;
107   private static User USER_GROUP_CREATE;
108   private static User USER_GROUP_READ;
109   private static User USER_GROUP_WRITE;
110 
111   private static String TEST_TABLE = TEST_NAMESPACE + ":testtable";
112   private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
113 
114   @BeforeClass
115   public static void beforeClass() throws Exception {
116     conf = UTIL.getConfiguration();
117     conf.setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10);
118     enableSecurity(conf);
119 
120     SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
121     // Users with global permissions
122     USER_GLOBAL_ADMIN = User.createUserForTesting(conf, "global_admin", new String[0]);
123     USER_GLOBAL_CREATE = User.createUserForTesting(conf, "global_create", new String[0]);
124     USER_GLOBAL_WRITE = User.createUserForTesting(conf, "global_write", new String[0]);
125     USER_GLOBAL_READ = User.createUserForTesting(conf, "global_read", new String[0]);
126     USER_GLOBAL_EXEC = User.createUserForTesting(conf, "global_exec", new String[0]);
127 
128     USER_NS_ADMIN = User.createUserForTesting(conf, "namespace_admin", new String[0]);
129     USER_NS_CREATE = User.createUserForTesting(conf, "namespace_create", new String[0]);
130     USER_NS_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]);
131     USER_NS_READ = User.createUserForTesting(conf, "namespace_read", new String[0]);
132     USER_NS_EXEC = User.createUserForTesting(conf, "namespace_exec", new String[0]);
133 
134     USER_TABLE_CREATE = User.createUserForTesting(conf, "table_create", new String[0]);
135     USER_TABLE_WRITE = User.createUserForTesting(conf, "table_write", new String[0]);
136 
137     USER_GROUP_ADMIN =
138         User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN });
139     USER_GROUP_NS_ADMIN =
140         User.createUserForTesting(conf, "user_group_ns_admin", new String[] { GROUP_NS_ADMIN });
141     USER_GROUP_CREATE =
142         User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE });
143     USER_GROUP_READ =
144         User.createUserForTesting(conf, "user_group_read", new String[] { GROUP_READ });
145     USER_GROUP_WRITE =
146         User.createUserForTesting(conf, "user_group_write", new String[] { GROUP_WRITE });
147     // TODO: other table perms
148 
149     UTIL.startMiniCluster();
150     // Wait for the ACL table to become available
151     UTIL.waitTableAvailable(AccessControlLists.ACL_TABLE_NAME.getName(), 30 * 1000);
152 
153     ACCESS_CONTROLLER = (AccessController) UTIL.getMiniHBaseCluster().getMaster()
154       .getMasterCoprocessorHost()
155         .findCoprocessor(AccessController.class.getName());
156 
157     UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE).build());
158     UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE2).build());
159 
160     // grants on global
161     grantGlobal(UTIL, USER_GLOBAL_ADMIN.getShortName(),  Permission.Action.ADMIN);
162     grantGlobal(UTIL, USER_GLOBAL_CREATE.getShortName(), Permission.Action.CREATE);
163     grantGlobal(UTIL, USER_GLOBAL_WRITE.getShortName(),  Permission.Action.WRITE);
164     grantGlobal(UTIL, USER_GLOBAL_READ.getShortName(),   Permission.Action.READ);
165     grantGlobal(UTIL, USER_GLOBAL_EXEC.getShortName(),   Permission.Action.EXEC);
166 
167     // grants on namespace
168     grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(),  TEST_NAMESPACE, Permission.Action.ADMIN);
169     grantOnNamespace(UTIL, USER_NS_CREATE.getShortName(), TEST_NAMESPACE, Permission.Action.CREATE);
170     grantOnNamespace(UTIL, USER_NS_WRITE.getShortName(),  TEST_NAMESPACE, Permission.Action.WRITE);
171     grantOnNamespace(UTIL, USER_NS_READ.getShortName(),   TEST_NAMESPACE, Permission.Action.READ);
172     grantOnNamespace(UTIL, USER_NS_EXEC.getShortName(),   TEST_NAMESPACE, Permission.Action.EXEC);
173     grantOnNamespace(UTIL, toGroupEntry(GROUP_NS_ADMIN), TEST_NAMESPACE, Permission.Action.ADMIN);
174 
175     grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(), TEST_NAMESPACE2, Permission.Action.ADMIN);
176 
177     grantGlobal(UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN);
178     grantGlobal(UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE);
179     grantGlobal(UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ);
180     grantGlobal(UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE);
181   }
182 
183   @AfterClass
184   public static void afterClass() throws Exception {
185     UTIL.getHBaseAdmin().deleteNamespace(TEST_NAMESPACE);
186     UTIL.getHBaseAdmin().deleteNamespace(TEST_NAMESPACE2);
187     UTIL.shutdownMiniCluster();
188   }
189 
190   @Test
191   public void testAclTableEntries() throws Exception {
192     String userTestNamespace = "userTestNsp";
193     try(Connection conn = ConnectionFactory.createConnection(conf);
194         Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
195       ListMultimap<String, TablePermission> perms =
196           AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
197 
198       perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
199       for (Map.Entry<String, TablePermission> entry : perms.entries()) {
200         LOG.debug(entry);
201       }
202       assertEquals(6, perms.size());
203 
204       // Grant and check state in ACL table
205       grantOnNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
206         Permission.Action.WRITE);
207 
208       Result result = acl.get(new Get(Bytes.toBytes(userTestNamespace)));
209       assertTrue(result != null);
210       perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
211       assertEquals(7, perms.size());
212       List<TablePermission> namespacePerms = perms.get(userTestNamespace);
213       assertTrue(perms.containsKey(userTestNamespace));
214       assertEquals(1, namespacePerms.size());
215       assertEquals(TEST_NAMESPACE,
216         namespacePerms.get(0).getNamespace());
217       assertEquals(null, namespacePerms.get(0).getFamily());
218       assertEquals(null, namespacePerms.get(0).getQualifier());
219       assertEquals(1, namespacePerms.get(0).getActions().length);
220       assertEquals(Permission.Action.WRITE, namespacePerms.get(0).getActions()[0]);
221 
222       // Revoke and check state in ACL table
223       revokeFromNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
224         Permission.Action.WRITE);
225 
226       perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
227       assertEquals(6, perms.size());
228     }
229   }
230 
231   @Test
232   public void testModifyNamespace() throws Exception {
233     AccessTestAction modifyNamespace = new AccessTestAction() {
234       @Override
235       public Object run() throws Exception {
236         ACCESS_CONTROLLER.preModifyNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
237           NamespaceDescriptor.create(TEST_NAMESPACE).addConfiguration("abc", "156").build());
238         return null;
239       }
240     };
241 
242     // modifyNamespace: superuser | global(A) | NS(A)
243     verifyAllowed(modifyNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
244     verifyDenied(modifyNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
245       USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
246       USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
247   }
248 
249   @Test
250   public void testCreateAndDeleteNamespace() throws Exception {
251     AccessTestAction createNamespace = new AccessTestAction() {
252       @Override
253       public Object run() throws Exception {
254         ACCESS_CONTROLLER.preCreateNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
255           NamespaceDescriptor.create(TEST_NAMESPACE2).build());
256         return null;
257       }
258     };
259 
260     AccessTestAction deleteNamespace = new AccessTestAction() {
261       @Override
262       public Object run() throws Exception {
263         ACCESS_CONTROLLER.preDeleteNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
264           TEST_NAMESPACE2);
265         return null;
266       }
267     };
268 
269     // createNamespace: superuser | global(A)
270     verifyAllowed(createNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
271     // all others should be denied
272     verifyDenied(createNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
273       USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
274       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
275 
276     // deleteNamespace: superuser | global(A) | NS(A)
277     verifyAllowed(deleteNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
278     verifyDenied(deleteNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
279       USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
280       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
281   }
282 
283   @Test
284   public void testGetNamespaceDescriptor() throws Exception {
285     AccessTestAction getNamespaceAction = new AccessTestAction() {
286       @Override
287       public Object run() throws Exception {
288         ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContext.createAndPrepare(CP_ENV, null),
289           TEST_NAMESPACE);
290         return null;
291       }
292     };
293     // getNamespaceDescriptor : superuser | global(A) | NS(A)
294     verifyAllowed(getNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
295       USER_GROUP_ADMIN);
296     verifyDenied(getNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
297       USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
298       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
299   }
300 
301   @Test
302   public void testListNamespaces() throws Exception {
303     AccessTestAction listAction = new AccessTestAction() {
304       @Override
305       public Object run() throws Exception {
306         Connection unmanagedConnection =
307             ConnectionFactory.createConnection(UTIL.getConfiguration());
308         Admin admin = unmanagedConnection.getAdmin();
309         try {
310           return Arrays.asList(admin.listNamespaceDescriptors());
311         } finally {
312           admin.close();
313           unmanagedConnection.close();
314         }
315       }
316     };
317 
318     // listNamespaces         : All access*
319     // * Returned list will only show what you can call getNamespaceDescriptor()
320 
321     verifyAllowed(listAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN, USER_GROUP_ADMIN);
322 
323     // we have 3 namespaces: [default, hbase, TEST_NAMESPACE, TEST_NAMESPACE2]
324     assertEquals(4, ((List)SUPERUSER.runAs(listAction)).size());
325     assertEquals(4, ((List)USER_GLOBAL_ADMIN.runAs(listAction)).size());
326     assertEquals(4, ((List)USER_GROUP_ADMIN.runAs(listAction)).size());
327 
328     assertEquals(2, ((List)USER_NS_ADMIN.runAs(listAction)).size());
329 
330     assertEquals(0, ((List)USER_GLOBAL_CREATE.runAs(listAction)).size());
331     assertEquals(0, ((List)USER_GLOBAL_WRITE.runAs(listAction)).size());
332     assertEquals(0, ((List)USER_GLOBAL_READ.runAs(listAction)).size());
333     assertEquals(0, ((List)USER_GLOBAL_EXEC.runAs(listAction)).size());
334     assertEquals(0, ((List)USER_NS_CREATE.runAs(listAction)).size());
335     assertEquals(0, ((List)USER_NS_WRITE.runAs(listAction)).size());
336     assertEquals(0, ((List)USER_NS_READ.runAs(listAction)).size());
337     assertEquals(0, ((List)USER_NS_EXEC.runAs(listAction)).size());
338     assertEquals(0, ((List)USER_TABLE_CREATE.runAs(listAction)).size());
339     assertEquals(0, ((List)USER_TABLE_WRITE.runAs(listAction)).size());
340     assertEquals(0, ((List)USER_GROUP_CREATE.runAs(listAction)).size());
341     assertEquals(0, ((List)USER_GROUP_READ.runAs(listAction)).size());
342     assertEquals(0, ((List)USER_GROUP_WRITE.runAs(listAction)).size());
343   }
344 
345   @Test
346   public void testGrantRevoke() throws Exception{
347     final String testUser = "testUser";
348 
349     // Test if client API actions are authorized
350 
351     AccessTestAction grantAction = new AccessTestAction() {
352       @Override
353       public Object run() throws Exception {
354         try(Connection conn = ConnectionFactory.createConnection(conf);
355             Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
356           BlockingRpcChannel service =
357               acl.coprocessorService(HConstants.EMPTY_START_ROW);
358           AccessControlService.BlockingInterface protocol =
359             AccessControlService.newBlockingStub(service);
360           ProtobufUtil.grant(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
361         }
362         return null;
363       }
364     };
365 
366     AccessTestAction grantNamespaceAction = new AccessTestAction() {
367       @Override
368       public Object run() throws Exception {
369         try(Connection conn = ConnectionFactory.createConnection(conf);
370             Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
371           BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
372           AccessControlService.BlockingInterface protocol =
373             AccessControlService.newBlockingStub(service);
374           ProtobufUtil.grant(null, protocol, USER_GROUP_NS_ADMIN.getShortName(),
375             TEST_NAMESPACE, Action.READ);
376         }
377         return null;
378       }
379     };
380 
381     AccessTestAction revokeAction = new AccessTestAction() {
382       @Override
383       public Object run() throws Exception {
384         try(Connection conn = ConnectionFactory.createConnection(conf);
385             Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
386           BlockingRpcChannel service =
387               acl.coprocessorService(HConstants.EMPTY_START_ROW);
388           AccessControlService.BlockingInterface protocol =
389             AccessControlService.newBlockingStub(service);
390           ProtobufUtil.revoke(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
391         }
392         return null;
393       }
394     };
395 
396     AccessTestAction revokeNamespaceAction = new AccessTestAction() {
397       @Override
398       public Object run() throws Exception {
399         Connection connection = ConnectionFactory.createConnection(conf);
400         Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
401         try {
402           BlockingRpcChannel service =
403               acl.coprocessorService(HConstants.EMPTY_START_ROW);
404           AccessControlService.BlockingInterface protocol =
405             AccessControlService.newBlockingStub(service);
406           ProtobufUtil.revoke(null, protocol, USER_GROUP_NS_ADMIN.getShortName(),
407             TEST_NAMESPACE, Action.READ);
408         } finally {
409           acl.close();
410           connection.close();
411         }
412         return null;
413       }
414     };
415 
416     AccessTestAction getPermissionsAction = new AccessTestAction() {
417       @Override
418       public Object run() throws Exception {
419         try(Connection conn = ConnectionFactory.createConnection(conf);
420             Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
421           BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
422           AccessControlService.BlockingInterface protocol =
423             AccessControlService.newBlockingStub(service);
424           ProtobufUtil.getUserPermissions(null, protocol, Bytes.toBytes(TEST_NAMESPACE));
425         }
426         return null;
427       }
428     };
429 
430     verifyAllowed(grantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
431     verifyDenied(grantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
432       USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
433       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
434 
435     verifyAllowed(grantNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
436       USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
437     verifyDenied(grantNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
438       USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
439       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
440 
441     verifyAllowed(revokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
442     verifyDenied(revokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
443       USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
444       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
445 
446     verifyAllowed(revokeNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
447       USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
448     verifyDenied(revokeNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
449       USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
450       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
451 
452     verifyAllowed(getPermissionsAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
453       USER_GROUP_ADMIN);
454     verifyDenied(getPermissionsAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
455       USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
456       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
457   }
458 
459   @Test
460   public void testCreateTableWithNamespace() throws Exception {
461     AccessTestAction createTable = new AccessTestAction() {
462       @Override
463       public Object run() throws Exception {
464         HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TEST_TABLE));
465         htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
466         ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null);
467         return null;
468       }
469     };
470 
471     //createTable            : superuser | global(C) | NS(C)
472     verifyAllowed(createTable, SUPERUSER, USER_GLOBAL_CREATE, USER_NS_CREATE, USER_GROUP_CREATE);
473     verifyDenied(createTable, USER_GLOBAL_ADMIN, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
474       USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
475       USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_ADMIN);
476   }
477 }