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, TablePermission> perms =
210          AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
211
212      perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
213      for (Map.Entry<String, TablePermission> entry : perms.entries()) {
214        LOG.debug(Objects.toString(entry));
215      }
216      assertEquals(6, perms.size());
217
218      // Grant and check state in ACL table
219      grantOnNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
220        Permission.Action.WRITE);
221
222      Result result = acl.get(new Get(Bytes.toBytes(userTestNamespace)));
223      assertTrue(result != null);
224      perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
225      assertEquals(7, perms.size());
226      List<TablePermission> namespacePerms = perms.get(userTestNamespace);
227      assertTrue(perms.containsKey(userTestNamespace));
228      assertEquals(1, namespacePerms.size());
229      assertEquals(TEST_NAMESPACE,
230        namespacePerms.get(0).getNamespace());
231      assertEquals(null, namespacePerms.get(0).getFamily());
232      assertEquals(null, namespacePerms.get(0).getQualifier());
233      assertEquals(1, namespacePerms.get(0).getActions().length);
234      assertEquals(Permission.Action.WRITE, namespacePerms.get(0).getActions()[0]);
235
236      // Revoke and check state in ACL table
237      revokeFromNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
238        Permission.Action.WRITE);
239
240      perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
241      assertEquals(6, perms.size());
242    } finally {
243      acl.close();
244    }
245  }
246
247  @Test
248  public void testModifyNamespace() throws Exception {
249    AccessTestAction modifyNamespace = new AccessTestAction() {
250      @Override
251      public Object run() throws Exception {
252        ACCESS_CONTROLLER.preModifyNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
253          NamespaceDescriptor.create(TEST_NAMESPACE).addConfiguration("abc", "156").build());
254        return null;
255      }
256    };
257
258    // modifyNamespace: superuser | global(A) | NS(A)
259    verifyAllowed(modifyNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
260    verifyDenied(modifyNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
261      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
262      USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
263  }
264
265  @Test
266  public void testCreateAndDeleteNamespace() throws Exception {
267    AccessTestAction createNamespace = new AccessTestAction() {
268      @Override
269      public Object run() throws Exception {
270        ACCESS_CONTROLLER.preCreateNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
271          NamespaceDescriptor.create(TEST_NAMESPACE2).build());
272        return null;
273      }
274    };
275
276    AccessTestAction deleteNamespace = new AccessTestAction() {
277      @Override
278      public Object run() throws Exception {
279        ACCESS_CONTROLLER.preDeleteNamespace(ObserverContextImpl.createAndPrepare(CP_ENV),
280          TEST_NAMESPACE2);
281        return null;
282      }
283    };
284
285    // createNamespace: superuser | global(A)
286    verifyAllowed(createNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
287    // all others should be denied
288    verifyDenied(createNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
289      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
290      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
291
292    // deleteNamespace: superuser | global(A) | NS(A)
293    verifyAllowed(deleteNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN);
294    verifyDenied(deleteNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
295      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
296      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
297  }
298
299  @Test
300  public void testGetNamespaceDescriptor() throws Exception {
301    AccessTestAction getNamespaceAction = new AccessTestAction() {
302      @Override
303      public Object run() throws Exception {
304        ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContextImpl.createAndPrepare(CP_ENV),
305          TEST_NAMESPACE);
306        return null;
307      }
308    };
309    // getNamespaceDescriptor : superuser | global(A) | NS(A)
310    verifyAllowed(getNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
311      USER_GROUP_ADMIN);
312    verifyDenied(getNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
313      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
314      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
315  }
316
317  @Test
318  public void testListNamespaces() throws Exception {
319    AccessTestAction listAction = new AccessTestAction() {
320      @Override
321      public Object run() throws Exception {
322        Connection unmanagedConnection =
323            ConnectionFactory.createConnection(UTIL.getConfiguration());
324        Admin admin = unmanagedConnection.getAdmin();
325        try {
326          return Arrays.asList(admin.listNamespaceDescriptors());
327        } finally {
328          admin.close();
329          unmanagedConnection.close();
330        }
331      }
332    };
333
334    // listNamespaces         : All access*
335    // * Returned list will only show what you can call getNamespaceDescriptor()
336
337    verifyAllowed(listAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN, USER_GROUP_ADMIN);
338
339    // we have 3 namespaces: [default, hbase, TEST_NAMESPACE, TEST_NAMESPACE2]
340    assertEquals(4, ((List)SUPERUSER.runAs(listAction)).size());
341    assertEquals(4, ((List)USER_GLOBAL_ADMIN.runAs(listAction)).size());
342    assertEquals(4, ((List)USER_GROUP_ADMIN.runAs(listAction)).size());
343
344    assertEquals(2, ((List)USER_NS_ADMIN.runAs(listAction)).size());
345
346    assertEquals(0, ((List)USER_GLOBAL_CREATE.runAs(listAction)).size());
347    assertEquals(0, ((List)USER_GLOBAL_WRITE.runAs(listAction)).size());
348    assertEquals(0, ((List)USER_GLOBAL_READ.runAs(listAction)).size());
349    assertEquals(0, ((List)USER_GLOBAL_EXEC.runAs(listAction)).size());
350    assertEquals(0, ((List)USER_NS_CREATE.runAs(listAction)).size());
351    assertEquals(0, ((List)USER_NS_WRITE.runAs(listAction)).size());
352    assertEquals(0, ((List)USER_NS_READ.runAs(listAction)).size());
353    assertEquals(0, ((List)USER_NS_EXEC.runAs(listAction)).size());
354    assertEquals(0, ((List)USER_TABLE_CREATE.runAs(listAction)).size());
355    assertEquals(0, ((List)USER_TABLE_WRITE.runAs(listAction)).size());
356    assertEquals(0, ((List)USER_GROUP_CREATE.runAs(listAction)).size());
357    assertEquals(0, ((List)USER_GROUP_READ.runAs(listAction)).size());
358    assertEquals(0, ((List)USER_GROUP_WRITE.runAs(listAction)).size());
359  }
360
361  @Test
362  public void testGrantRevoke() throws Exception{
363    final String testUser = "testUser";
364
365    // Test if client API actions are authorized
366
367    AccessTestAction grantAction = new AccessTestAction() {
368      @Override
369      public Object run() throws Exception {
370        Connection connection = ConnectionFactory.createConnection(conf);
371        Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
372        try {
373          BlockingRpcChannel service =
374              acl.coprocessorService(HConstants.EMPTY_START_ROW);
375          AccessControlService.BlockingInterface protocol =
376            AccessControlService.newBlockingStub(service);
377          AccessControlUtil.grant(null, protocol, testUser, TEST_NAMESPACE, false, Action.WRITE);
378        } finally {
379          acl.close();
380          connection.close();
381        }
382        return null;
383      }
384    };
385
386    AccessTestAction grantNamespaceAction = new AccessTestAction() {
387      @Override
388      public Object run() throws Exception {
389        try(Connection conn = ConnectionFactory.createConnection(conf);
390            Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
391          BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
392          AccessControlService.BlockingInterface protocol =
393            AccessControlService.newBlockingStub(service);
394          AccessControlUtil.grant(null, protocol, USER_GROUP_NS_ADMIN.getShortName(),
395            TEST_NAMESPACE, false, Action.READ);
396        }
397        return null;
398      }
399    };
400
401    AccessTestAction revokeAction = new AccessTestAction() {
402      @Override
403      public Object run() throws Exception {
404        Connection connection = ConnectionFactory.createConnection(conf);
405        Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
406        try {
407          BlockingRpcChannel service =
408              acl.coprocessorService(HConstants.EMPTY_START_ROW);
409          AccessControlService.BlockingInterface protocol =
410            AccessControlService.newBlockingStub(service);
411          AccessControlUtil.revoke(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
412        } finally {
413          acl.close();
414          connection.close();
415        }
416        return null;
417      }
418    };
419
420    AccessTestAction revokeNamespaceAction = new AccessTestAction() {
421      @Override
422      public Object run() throws Exception {
423        Connection connection = ConnectionFactory.createConnection(conf);
424        Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
425        try {
426          BlockingRpcChannel service =
427              acl.coprocessorService(HConstants.EMPTY_START_ROW);
428          AccessControlService.BlockingInterface protocol =
429            AccessControlService.newBlockingStub(service);
430          AccessControlUtil.revoke(null, protocol, USER_GROUP_NS_ADMIN.getShortName(),
431            TEST_NAMESPACE, Action.READ);
432        } finally {
433          acl.close();
434          connection.close();
435        }
436        return null;
437      }
438    };
439
440    AccessTestAction getPermissionsAction = new AccessTestAction() {
441      @Override
442      public Object run() throws Exception {
443        Connection connection = ConnectionFactory.createConnection(conf);
444        Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME);
445        try {
446          BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
447          AccessControlService.BlockingInterface protocol =
448            AccessControlService.newBlockingStub(service);
449          AccessControlUtil.getUserPermissions(null, protocol, Bytes.toBytes(TEST_NAMESPACE));
450        } finally {
451          acl.close();
452          connection.close();
453        }
454        return null;
455      }
456    };
457
458    verifyAllowed(grantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
459    verifyDenied(grantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
460      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
461      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
462
463    verifyAllowed(grantNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
464      USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
465    verifyDenied(grantNamespaceAction, 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
469    verifyAllowed(revokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
470    verifyDenied(revokeAction, 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(revokeNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
475      USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
476    verifyDenied(revokeNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
477      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
478      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
479
480    verifyAllowed(getPermissionsAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
481      USER_GROUP_ADMIN);
482    verifyDenied(getPermissionsAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
483      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
484      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
485  }
486
487  @Test
488  public void testCreateTableWithNamespace() throws Exception {
489    AccessTestAction createTable = new AccessTestAction() {
490      @Override
491      public Object run() throws Exception {
492        HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TEST_TABLE));
493        htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
494        ACCESS_CONTROLLER.preCreateTable(ObserverContextImpl.createAndPrepare(CP_ENV), htd, null);
495        return null;
496      }
497    };
498
499    //createTable            : superuser | global(C) | NS(C)
500    verifyAllowed(createTable, SUPERUSER, USER_GLOBAL_CREATE, USER_NS_CREATE, USER_GROUP_CREATE);
501    verifyDenied(createTable, USER_GLOBAL_ADMIN, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
502      USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
503      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_ADMIN);
504  }
505}