@Test
  public void testHasPermission() throws Throwable {
    Connection conn = null;
    try {
      conn = ConnectionFactory.createConnection(conf);
      // Create user and set namespace ACL
      User user1 = User.createUserForTesting(conf, "testHasPermissionUser1", new String[0]);
      // Grant namespace permission
      grantOnNamespaceUsingAccessControlClient(TEST_UTIL, conn, user1.getShortName(),
        NamespaceDescriptor.DEFAULT_NAMESPACE.getName(), Permission.Action.ADMIN,
        Permission.Action.CREATE, Permission.Action.READ);

      // Create user and set table ACL
      User user2 = User.createUserForTesting(conf, "testHasPermissionUser2", new String[0]);
      // Grant namespace permission
      grantOnTableUsingAccessControlClient(TEST_UTIL, conn, user2.getShortName(), TEST_TABLE,
        TEST_FAMILY, TEST_QUALIFIER, Permission.Action.READ, Permission.Action.WRITE);

      // Verify action privilege
      AccessTestAction hasPermissionActionCP = new AccessTestAction() {
        @Override
        public Object run() throws Exception {
          try (Connection conn = ConnectionFactory.createConnection(conf);
            Table acl = conn.getTable(PermissionStorage.ACL_TABLE_NAME)) {
            BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName());
            AccessControlService.BlockingInterface protocol =
              AccessControlService.newBlockingStub(service);
            Permission.Action[] actions = { Permission.Action.READ, Permission.Action.WRITE };
            AccessControlUtil.hasPermission(null, protocol, TEST_TABLE, TEST_FAMILY,
              HConstants.EMPTY_BYTE_ARRAY, "dummy", actions);
          }
          return null;
        }
      };
      AccessTestAction hasPermissionAction = new AccessTestAction() {
        @Override
        public Object run() throws Exception {
          try (Connection conn = ConnectionFactory.createConnection(conf)) {
            Permission.Action[] actions = { Permission.Action.READ, Permission.Action.WRITE };
            conn.getAdmin().hasUserPermissions("dummy",
              Arrays.asList(Permission.newBuilder(TEST_TABLE).withFamily(TEST_FAMILY)
                .withQualifier(HConstants.EMPTY_BYTE_ARRAY).withActions(actions).build()));
          }
          return null;
        }
      };
      verifyAllowed(hasPermissionActionCP, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN, USER_OWNER,
        USER_ADMIN_CF, user1);
      verifyDenied(hasPermissionActionCP, USER_CREATE, USER_RW, USER_RO, USER_NONE, user2);
      verifyAllowed(hasPermissionAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN, USER_OWNER,
        USER_ADMIN_CF, user1);
      verifyDenied(hasPermissionAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, user2);

      // Check for global user
      assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN.getShortName(),
        Permission.Action.READ, Permission.Action.WRITE, Permission.Action.CREATE,
        Permission.Action.ADMIN));
      assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN.getShortName(),
        Permission.Action.READ, Permission.Action.WRITE, Permission.Action.CREATE,
        Permission.Action.ADMIN, Permission.Action.EXEC));

      // Check for namespace access user
      assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, user1.getShortName(),
        Permission.Action.ADMIN, Permission.Action.CREATE));
      assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, user1.getShortName(),
        Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.EXEC));

      // Check for table owner
      assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_OWNER.getShortName(),
        Permission.Action.READ, Permission.Action.WRITE, Permission.Action.EXEC,
        Permission.Action.CREATE, Permission.Action.ADMIN));

      // Check for table user
      assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_CREATE.getShortName(),
        Permission.Action.READ, Permission.Action.WRITE));
      assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_RO.getShortName(),
        Permission.Action.READ, Permission.Action.WRITE));

      // Check for family access user
      assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY,
        HConstants.EMPTY_BYTE_ARRAY, USER_RO.getShortName(), Permission.Action.READ));
      assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY,
        HConstants.EMPTY_BYTE_ARRAY, USER_RW.getShortName(), Permission.Action.READ,
        Permission.Action.WRITE));
      assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN_CF.getShortName(),
        Permission.Action.ADMIN, Permission.Action.CREATE));
      assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY,
        HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN_CF.getShortName(), Permission.Action.ADMIN,
        Permission.Action.CREATE));
      assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY,
        HConstants.EMPTY_BYTE_ARRAY, USER_ADMIN_CF.getShortName(), Permission.Action.READ));

      // Check for qualifier access user
      assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY,
        TEST_QUALIFIER, user2.getShortName(), Permission.Action.READ, Permission.Action.WRITE));
      assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(), TEST_FAMILY,
        TEST_QUALIFIER, user2.getShortName(), Permission.Action.EXEC, Permission.Action.READ));
      assertFalse(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
        HConstants.EMPTY_BYTE_ARRAY, TEST_QUALIFIER, USER_RW.getShortName(),
        Permission.Action.WRITE, Permission.Action.READ));

      // exception scenarios
      try {
        // test case with table name as null
        assertTrue(AccessControlClient.hasPermission(conn, null, HConstants.EMPTY_BYTE_ARRAY,
          HConstants.EMPTY_BYTE_ARRAY, null, Permission.Action.READ));
        fail("this should have thrown IllegalArgumentException");
      } catch (IllegalArgumentException ex) {
        // expected
      }
      try {
        // test case with username as null
        assertTrue(AccessControlClient.hasPermission(conn, TEST_TABLE.getNameAsString(),
          HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, null, Permission.Action.READ));
        fail("this should have thrown IllegalArgumentException");
      } catch (IllegalArgumentException ex) {
        // expected
      }

      revokeFromNamespaceUsingAccessControlClient(TEST_UTIL, conn, user1.getShortName(),
        NamespaceDescriptor.DEFAULT_NAMESPACE.getName(), Permission.Action.ADMIN,
        Permission.Action.CREATE, Permission.Action.READ);
      revokeFromTableUsingAccessControlClient(TEST_UTIL, conn, user2.getShortName(), TEST_TABLE,
        TEST_FAMILY, TEST_QUALIFIER, Permission.Action.READ, Permission.Action.WRITE);
    } finally {
      if (conn != null) {
        conn.close();
      }
    }
  }
List all user permissions match the given regular expression for namespace and verify each of
them.
@param namespaceRegexWithoutPrefix the regualar expression for namespace, without
                                   NAMESPACE_PREFIX
@param expectedAmount              the expected amount of user permissions returned
@param expectedNamespace           the expected namespace of each user permission returned
@throws HBaseException in the case of any HBase exception when accessing hbase:acl table
hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java