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