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;
023import com.google.protobuf.BlockingRpcChannel;
024import java.util.Arrays;
025import java.util.List;
026import java.util.Map;
027import java.util.Objects;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.hadoop.hbase.HBaseClassTestRule;
030import org.apache.hadoop.hbase.HBaseTestingUtility;
031import org.apache.hadoop.hbase.HColumnDescriptor;
032import org.apache.hadoop.hbase.HConstants;
033import org.apache.hadoop.hbase.HTableDescriptor;
034import org.apache.hadoop.hbase.NamespaceDescriptor;
035import org.apache.hadoop.hbase.TableName;
036import org.apache.hadoop.hbase.client.Admin;
037import org.apache.hadoop.hbase.client.Connection;
038import org.apache.hadoop.hbase.client.ConnectionFactory;
039import org.apache.hadoop.hbase.client.Get;
040import org.apache.hadoop.hbase.client.Result;
041import org.apache.hadoop.hbase.client.Table;
042import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
043import org.apache.hadoop.hbase.coprocessor.ObserverContextImpl;
044import org.apache.hadoop.hbase.ipc.NettyRpcClientConfigHelper;
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;
059import org.apache.hbase.thirdparty.com.google.common.collect.ListMultimap;
060
061@Category({SecurityTests.class, MediumTests.class})
062public class TestNamespaceCommands extends SecureTestUtil {
063
064  @ClassRule
065  public static final HBaseClassTestRule CLASS_RULE =
066      HBaseClassTestRule.forClass(TestNamespaceCommands.class);
067
068  private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
069  private static final Logger LOG = LoggerFactory.getLogger(TestNamespaceCommands.class);
070  private static String TEST_NAMESPACE = "ns1";
071  private static String TEST_NAMESPACE2 = "ns2";
072  private static Configuration conf;
073  private static MasterCoprocessorEnvironment CP_ENV;
074  private static AccessController ACCESS_CONTROLLER;
075
076  // user with all permissions
077  private static User SUPERUSER;
078
079  // user with A permission on global
080  private static User USER_GLOBAL_ADMIN;
081  // user with C permission on global
082  private static User USER_GLOBAL_CREATE;
083  // user with W permission on global
084  private static User USER_GLOBAL_WRITE;
085  // user with R permission on global
086  private static User USER_GLOBAL_READ;
087  // user with X permission on global
088  private static User USER_GLOBAL_EXEC;
089
090  // user with A permission on namespace
091  private static User USER_NS_ADMIN;
092  // user with C permission on namespace
093  private static User USER_NS_CREATE;
094  // user with W permission on namespace
095  private static User USER_NS_WRITE;
096  // user with R permission on namespace.
097  private static User USER_NS_READ;
098  // user with X permission on namespace.
099  private static User USER_NS_EXEC;
100
101  // user with rw permissions
102  private static User USER_TABLE_WRITE;  // TODO: WE DO NOT GIVE ANY PERMS TO THIS USER
103  //user with create table permissions alone
104  private static User USER_TABLE_CREATE; // TODO: WE DO NOT GIVE ANY PERMS TO THIS USER
105
106  private static final String GROUP_ADMIN = "group_admin";
107  private static final String GROUP_NS_ADMIN = "group_ns_admin";
108  private static final String GROUP_CREATE = "group_create";
109  private static final String GROUP_READ = "group_read";
110  private static final String GROUP_WRITE = "group_write";
111
112  private static User USER_GROUP_ADMIN;
113  private static User USER_GROUP_NS_ADMIN;
114  private static User USER_GROUP_CREATE;
115  private static User USER_GROUP_READ;
116  private static User USER_GROUP_WRITE;
117
118  private static String TEST_TABLE = TEST_NAMESPACE + ":testtable";
119  private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
120
121  @BeforeClass
122  public static void beforeClass() throws Exception {
123    conf = UTIL.getConfiguration();
124    enableSecurity(conf);
125
126    SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
127    // Users with global permissions
128    USER_GLOBAL_ADMIN = User.createUserForTesting(conf, "global_admin", new String[0]);
129    USER_GLOBAL_CREATE = User.createUserForTesting(conf, "global_create", new String[0]);
130    USER_GLOBAL_WRITE = User.createUserForTesting(conf, "global_write", new String[0]);
131    USER_GLOBAL_READ = User.createUserForTesting(conf, "global_read", new String[0]);
132    USER_GLOBAL_EXEC = User.createUserForTesting(conf, "global_exec", new String[0]);
133
134    USER_NS_ADMIN = User.createUserForTesting(conf, "namespace_admin", new String[0]);
135    USER_NS_CREATE = User.createUserForTesting(conf, "namespace_create", new String[0]);
136    USER_NS_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]);
137    USER_NS_READ = User.createUserForTesting(conf, "namespace_read", new String[0]);
138    USER_NS_EXEC = User.createUserForTesting(conf, "namespace_exec", new String[0]);
139
140    USER_TABLE_CREATE = User.createUserForTesting(conf, "table_create", new String[0]);
141    USER_TABLE_WRITE = User.createUserForTesting(conf, "table_write", new String[0]);
142
143    USER_GROUP_ADMIN =
144        User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN });
145    USER_GROUP_NS_ADMIN =
146        User.createUserForTesting(conf, "user_group_ns_admin", new String[] { GROUP_NS_ADMIN });
147    USER_GROUP_CREATE =
148        User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE });
149    USER_GROUP_READ =
150        User.createUserForTesting(conf, "user_group_read", new String[] { GROUP_READ });
151    USER_GROUP_WRITE =
152        User.createUserForTesting(conf, "user_group_write", new String[] { GROUP_WRITE });
153    // TODO: other table perms
154
155    UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
156    UTIL.startMiniCluster();
157    // Wait for the ACL table to become available
158    UTIL.waitTableAvailable(PermissionStorage.ACL_TABLE_NAME.getName(), 30 * 1000);
159
160    // Find the Access Controller CP. Could be on master or if master is not serving regions, is
161    // on an arbitrary server.
162    for (JVMClusterUtil.RegionServerThread rst:
163        UTIL.getMiniHBaseCluster().getLiveRegionServerThreads()) {
164      ACCESS_CONTROLLER = rst.getRegionServer().getRegionServerCoprocessorHost().
165        findCoprocessor(AccessController.class);
166      if (ACCESS_CONTROLLER != null) {
167        break;
168      }
169    }
170    if (ACCESS_CONTROLLER == null) {
171      throw new NullPointerException();
172    }
173
174    UTIL.getAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE).build());
175    UTIL.getAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE2).build());
176
177    // grants on global
178    grantGlobal(UTIL, USER_GLOBAL_ADMIN.getShortName(),  Permission.Action.ADMIN);
179    grantGlobal(UTIL, USER_GLOBAL_CREATE.getShortName(), Permission.Action.CREATE);
180    grantGlobal(UTIL, USER_GLOBAL_WRITE.getShortName(),  Permission.Action.WRITE);
181    grantGlobal(UTIL, USER_GLOBAL_READ.getShortName(),   Permission.Action.READ);
182    grantGlobal(UTIL, USER_GLOBAL_EXEC.getShortName(),   Permission.Action.EXEC);
183
184    // grants on namespace
185    grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(),  TEST_NAMESPACE, Permission.Action.ADMIN);
186    grantOnNamespace(UTIL, USER_NS_CREATE.getShortName(), TEST_NAMESPACE, Permission.Action.CREATE);
187    grantOnNamespace(UTIL, USER_NS_WRITE.getShortName(),  TEST_NAMESPACE, Permission.Action.WRITE);
188    grantOnNamespace(UTIL, USER_NS_READ.getShortName(),   TEST_NAMESPACE, Permission.Action.READ);
189    grantOnNamespace(UTIL, USER_NS_EXEC.getShortName(),   TEST_NAMESPACE, Permission.Action.EXEC);
190    grantOnNamespace(UTIL, toGroupEntry(GROUP_NS_ADMIN), TEST_NAMESPACE, Permission.Action.ADMIN);
191
192    grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(), TEST_NAMESPACE2, Permission.Action.ADMIN);
193
194    grantGlobal(UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN);
195    grantGlobal(UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE);
196    grantGlobal(UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ);
197    grantGlobal(UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE);
198  }
199
200  @AfterClass
201  public static void afterClass() throws Exception {
202    UTIL.getAdmin().deleteNamespace(TEST_NAMESPACE);
203    UTIL.getAdmin().deleteNamespace(TEST_NAMESPACE2);
204    UTIL.shutdownMiniCluster();
205  }
206
207  @Test
208  public void testAclTableEntries() throws Exception {
209    String userTestNamespace = "userTestNsp";
210    Table acl = UTIL.getConnection().getTable(PermissionStorage.ACL_TABLE_NAME);
211    try {
212      ListMultimap<String, UserPermission> perms =
213          PermissionStorage.getNamespacePermissions(conf, TEST_NAMESPACE);
214      for (Map.Entry<String, UserPermission> entry : perms.entries()) {
215        LOG.debug(Objects.toString(entry));
216      }
217      assertEquals(6, perms.size());
218
219      // Grant and check state in ACL table
220      grantOnNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
221        Permission.Action.WRITE);
222
223      Result result = acl.get(new Get(Bytes.toBytes(userTestNamespace)));
224      assertTrue(result != null);
225      perms = PermissionStorage.getNamespacePermissions(conf, TEST_NAMESPACE);
226      assertEquals(7, perms.size());
227      List<UserPermission> namespacePerms = perms.get(userTestNamespace);
228      assertTrue(perms.containsKey(userTestNamespace));
229      assertEquals(1, namespacePerms.size());
230      assertEquals(TEST_NAMESPACE,
231        ((NamespacePermission) namespacePerms.get(0).getPermission()).getNamespace());
232      assertEquals(1, namespacePerms.get(0).getPermission().getActions().length);
233      assertEquals(Permission.Action.WRITE, namespacePerms.get(0).getPermission().getActions()[0]);
234
235      // Revoke and check state in ACL table
236      revokeFromNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
237        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") @Test
361  public void testGrantRevoke() throws Exception {
362    final String testUser = "testUser";
363    // Set this else in test context, with limit on the number of threads for
364    // netty eventloopgroup, we can run out of threads if one group used throughout.
365    NettyRpcClientConfigHelper.createEventLoopPerClient(conf);
366    // Test if client API actions are authorized
367    AccessTestAction grantAction = new AccessTestAction() {
368      @Override
369      public Object run() throws Exception {
370        try (Connection connection = ConnectionFactory.createConnection(conf)) {
371          connection.getAdmin().grant(new UserPermission(testUser,
372              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()),
373            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()),
384            false);
385        }
386        return null;
387      }
388    };
389
390    AccessTestAction revokeAction = new AccessTestAction() {
391      @Override
392      public Object run() throws Exception {
393        try (Connection connection = ConnectionFactory.createConnection(conf)) {
394          connection.getAdmin().revoke(new UserPermission(testUser,
395              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()));
396        }
397        return null;
398      }
399    };
400    AccessTestAction revokeNamespaceAction = new AccessTestAction() {
401      @Override
402      public Object run() throws Exception {
403        try (Connection connection = ConnectionFactory.createConnection(conf)) {
404          connection.getAdmin().revoke(new UserPermission(USER_GROUP_NS_ADMIN.getShortName(),
405              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.READ).build()));
406        }
407        return null;
408      }
409    };
410
411    AccessTestAction getPermissionsAction = new AccessTestAction() {
412      @Override
413      public Object run() throws Exception {
414        try (Connection connection = ConnectionFactory.createConnection(conf)) {
415          connection.getAdmin()
416              .getUserPermissions(GetUserPermissionsRequest.newBuilder(TEST_NAMESPACE).build());
417        }
418        return null;
419      }
420    };
421
422    AccessTestAction preGrantAction = new AccessTestAction() {
423      @Override
424      public Object run() throws Exception {
425        ACCESS_CONTROLLER.preGrant(ObserverContextImpl.createAndPrepare(CP_ENV),
426          new UserPermission(testUser,
427              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()),
428          false);
429        return null;
430      }
431    };
432    AccessTestAction preRevokeAction = new AccessTestAction() {
433      @Override
434      public Object run() throws Exception {
435        ACCESS_CONTROLLER.preRevoke(ObserverContextImpl.createAndPrepare(CP_ENV),
436          new UserPermission(testUser,
437              Permission.newBuilder(TEST_NAMESPACE).withActions(Action.WRITE).build()));
438        return null;
439      }
440    };
441
442    AccessTestAction grantCPAction = new AccessTestAction() {
443      @Override
444      public Object run() throws Exception {
445        try (Connection connection = ConnectionFactory.createConnection(conf);
446            Table acl = connection.getTable(PermissionStorage.ACL_TABLE_NAME)) {
447          BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
448          AccessControlService.BlockingInterface protocol =
449              AccessControlService.newBlockingStub(service);
450          AccessControlUtil.grant(null, protocol, testUser, TEST_NAMESPACE, false, Action.WRITE);
451        }
452        return null;
453      }
454    };
455    AccessTestAction revokeCPAction = new AccessTestAction() {
456      @Override
457      public Object run() throws Exception {
458        try (Connection connection = ConnectionFactory.createConnection(conf);
459            Table acl = connection.getTable(PermissionStorage.ACL_TABLE_NAME)) {
460          BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
461          AccessControlService.BlockingInterface protocol =
462              AccessControlService.newBlockingStub(service);
463          AccessControlUtil.revoke(null, protocol, testUser, TEST_NAMESPACE, Action.WRITE);
464        }
465        return null;
466      }
467    };
468
469    verifyAllowed(grantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
470    verifyDenied(grantAction, 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    verifyAllowed(grantNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
474      USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
475    verifyDenied(grantNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
476      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
477      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
478
479    verifyAllowed(revokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
480    verifyDenied(revokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
481      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
482      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
483    verifyAllowed(revokeNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN,
484      USER_NS_ADMIN, USER_GROUP_NS_ADMIN);
485    verifyDenied(revokeNamespaceAction, 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(getPermissionsAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN,
490      USER_GROUP_ADMIN);
491    verifyDenied(getPermissionsAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
492      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
493      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
494
495    verifyAllowed(preGrantAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
496    verifyDenied(preGrantAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
497      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
498      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
499    verifyAllowed(preRevokeAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
500    verifyDenied(preRevokeAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
501      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
502      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
503
504    verifyAllowed(grantCPAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
505    verifyDenied(grantCPAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
506      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
507      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
508    verifyAllowed(revokeCPAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN, USER_NS_ADMIN);
509    verifyDenied(revokeCPAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ,
510      USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC,
511      USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
512  }
513
514  @Test
515  public void testCreateTableWithNamespace() throws Exception {
516    AccessTestAction createTable = new AccessTestAction() {
517      @Override
518      public Object run() throws Exception {
519        HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TEST_TABLE));
520        htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
521        ACCESS_CONTROLLER.preCreateTable(ObserverContextImpl.createAndPrepare(CP_ENV), htd, null);
522        return null;
523      }
524    };
525
526    //createTable            : superuser | global(AC) | NS(AC)
527    verifyAllowed(createTable, SUPERUSER, USER_GLOBAL_CREATE, USER_NS_CREATE, USER_GROUP_CREATE,
528      USER_GLOBAL_ADMIN, USER_NS_ADMIN, USER_GROUP_ADMIN);
529    verifyDenied(createTable, USER_GLOBAL_WRITE, USER_GLOBAL_READ, USER_GLOBAL_EXEC,
530      USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC, USER_TABLE_CREATE, USER_TABLE_WRITE,
531      USER_GROUP_READ, USER_GROUP_WRITE);
532  }
533}