You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2020/02/08 17:44:23 UTC

[impala] 01/04: IMPALA-8587: Show inherited privileges with Ranger show grant

This is an automated email from the ASF dual-hosted git repository.

tarmstrong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit c07f54b3c45c0b1ae18c458d744d154db89f5e3c
Author: Austin Nobis <an...@cloudera.com>
AuthorDate: Tue Jun 18 11:59:07 2019 -0700

    IMPALA-8587: Show inherited privileges with Ranger show grant
    
    Previously when executing a SHOW GRANT statement on a resource with
    Ranger authorization enabled, Impala would not show inherited
    privileges. For example, consider a user 'foo' with database-level
    privileges granted by:
    
    GRANT SELECT ON DATABASE db TO USER foo;
    
    If later on we would like to retrieve the table-level privileges
    associated with the user 'foo' by:
    
    SHOW GRANT USER foo ON TABLE db.table;
    
    We would not see any result before this change. After this change, the
    related privileges including the inherited privileges with regard to the
    specified resource will be shown. In our example described above, we
    will see the following result and therefore the result returned by SHOW
    GRANT statement is more informative than the case in which only the
    privileges on 'db'.'table' were shown. Notice that in the following
    returned result, we are also able to know the specified user's
    privileges on any other table under the database 'db'.
    
    +----------------+----------------+----------+-------+--------+-----+-----+-----------+--------------+---------------+
    | principal_type | principal_name | database | table | column | uri | udf | privilege | grant_option | create_time   |
    +----------------+----------------+----------+-------+--------+-----+-----+-----------+--------------+---------------+
    | USER           | foo            | db       | *     | *      |     |     | select    | false        | 1580174954746 |
    +----------------+----------------+----------+-------+--------+-----+-----+-----------+--------------+---------------+
    
    Testing
    - Ran all FE tests
    - Ran all authorization E2E tests
    - Added E2E tests in test_ranger verifying functionality
    
    Change-Id: Ia4e679dc6fcf8d0b0e4e0fc2e9b335e2d8bc0899
    Reviewed-on: http://gerrit.cloudera.org:8080/15111
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 .../ranger/RangerImpaladAuthorizationManager.java  | 106 ++++++++---
 tests/authorization/test_ranger.py                 | 201 ++++++++++++++++-----
 2 files changed, 236 insertions(+), 71 deletions(-)

diff --git a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpaladAuthorizationManager.java b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpaladAuthorizationManager.java
index 81c8643..369b232 100644
--- a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpaladAuthorizationManager.java
+++ b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpaladAuthorizationManager.java
@@ -240,24 +240,6 @@ public class RangerImpaladAuthorizationManager implements AuthorizationManager {
     Optional<String> udf = getResourceName(RangerImpalaResourceBuilder.UDF, ANY,
         accessResult);
 
-    switch (privilege.getScope()) {
-      case COLUMN:
-        if (!column.isPresent() || column.get().equals("*")) return null;
-      case TABLE:
-        if (!table.isPresent() || table.get().equals("*")) return null;
-      case DATABASE:
-        if (!database.isPresent() || database.get().equals("*")) return null;
-        break;
-      case URI:
-        if (!uri.isPresent() || uri.get().equals("*")) return null;
-        break;
-      case SERVER:
-        break;
-      default:
-        throw new IllegalArgumentException("Unsupported privilege scope " +
-            privilege.getScope());
-    }
-
     return new RangerResultRow(type, principal, database.orElse(""), table.orElse(""),
         column.orElse(""), uri.orElse(""), udf.orElse(""), level, grantOption, longTime);
   }
@@ -343,14 +325,26 @@ public class RangerImpaladAuthorizationManager implements AuthorizationManager {
               "type %s.", params.principal_type));
       }
 
-      boolean all = resultRows.stream().anyMatch(row ->
-          row.privilege_ == TPrivilegeLevel.ALL);
-
-      List<RangerResultRow> rows = all ? resultRows.stream()
-          .filter(row -> row.privilege_ == TPrivilegeLevel.ALL)
-          .collect(Collectors.toList()) : resultRows;
+      RangerResourceResult resourceResult = new RangerResourceResult();
+
+      // Categorize 'resultRows' based on their lowest non-wildcard resource in the
+      // resource hierarchy. RangerResultRow's falling into the same category correspond
+      // to the same resource.
+      // TODO: To support displaying privileges on UDF's later.
+      for (RangerResultRow row : resultRows) {
+        if (!row.column_.equals("*") && !row.column_.isEmpty()) {
+          resourceResult.addColumnResult(row);
+        } else if (!row.table_.equals("*") && !row.table_.isEmpty()) {
+          resourceResult.addTableResult(row);
+        } else if (!row.database_.equals("*") && !row.database_.isEmpty()) {
+          resourceResult.addDatabaseResult(row);
+        } else {
+          resourceResult.addServerResult(row);
+        }
+      }
 
-      rows.forEach(principal -> resultSet.add(principal.toResultRow()));
+      resourceResult.getResultRows()
+          .forEach(principal -> resultSet.add(principal.toResultRow()));
     }
     resultSet.forEach(result::addToRows);
 
@@ -375,6 +369,68 @@ public class RangerImpaladAuthorizationManager implements AuthorizationManager {
         "%s is not supported in Impalad", ClassUtil.getMethodName()));
   }
 
+  private static class RangerResourceResult {
+    private List<RangerResultRow> server = new ArrayList<>();
+    private List<RangerResultRow> database = new ArrayList<>();
+    private List<RangerResultRow> table = new ArrayList<>();
+    private List<RangerResultRow> column = new ArrayList<>();
+
+    public RangerResourceResult() { }
+
+    public RangerResourceResult addServerResult(RangerResultRow result) {
+      server.add(result);
+      return this;
+    }
+
+    public RangerResourceResult addDatabaseResult(RangerResultRow result) {
+      database.add(result);
+      return this;
+    }
+
+    public RangerResourceResult addTableResult(RangerResultRow result) {
+      table.add(result);
+      return this;
+    }
+
+    public RangerResourceResult addColumnResult(RangerResultRow result) {
+      column.add(result);
+      return this;
+    }
+
+    /**
+     * For each disjoint List corresponding to a given resource, if there exists a
+     * RangerResultRow indicating the specified principal's privilege of
+     * TPrivilegeLevel.ALL, we filter out other RangerResultRow's that could be deduced
+     * from this wildcard RangerResultRow.
+     */
+    public List<RangerResultRow> getResultRows() {
+      List<RangerResultRow> results = new ArrayList<>();
+
+      results.addAll(filterIfAll(server));
+      results.addAll(filterIfAll(database));
+      results.addAll(filterIfAll(table));
+      results.addAll(filterIfAll(column));
+      return results;
+    }
+
+    /**
+     * Given that the elements on 'resultRow' refer to the same resource, in the case
+     * when any of the granted privileges on this resource equals 'TPrivilegeLevel.ALL',
+     * we only keep this wildcard RangerResultRow since any other RangerResultRow in
+     * 'resultRow' could be inferred from this wildcard RangerResultRow.
+     */
+    private static List<RangerResultRow> filterIfAll(List<RangerResultRow> resultRows) {
+      boolean all = resultRows.stream().anyMatch(row ->
+          row.privilege_ == TPrivilegeLevel.ALL);
+
+      List<RangerResultRow> rows = all ? resultRows.stream()
+          .filter(row -> row.privilege_ == TPrivilegeLevel.ALL)
+          .collect(Collectors.toList()) : resultRows;
+
+      return rows;
+    }
+  }
+
   private static class RangerResultRow {
     private final TPrincipalType principalType_;
     private final String principalName_;
diff --git a/tests/authorization/test_ranger.py b/tests/authorization/test_ranger.py
index 3d2a7ea..2de7283 100644
--- a/tests/authorization/test_ranger.py
+++ b/tests/authorization/test_ranger.py
@@ -95,8 +95,8 @@ class TestRanger(CustomClusterTestSuite):
           result = self.execute_query("show grant {0} {1} on database {2}"
                                       .format(kw, ident, unique_database))
           TestRanger._check_privileges(result, [
-            [kw, ident, unique_database, "", "", "", "*", "select", "false"],
-            [kw, ident, unique_database, "*", "*", "", "", "select", "false"]])
+              [kw, ident, unique_database, "", "", "", "*", "select", "false"],
+              [kw, ident, unique_database, "*", "*", "", "", "select", "false"]])
           self.execute_query_expect_success(admin_client,
                                             "revoke select on database {0} from {1} "
                                             "{2}".format(unique_database, kw, ident),
@@ -141,10 +141,10 @@ class TestRanger(CustomClusterTestSuite):
       result = self.execute_query("show grant user {0} on database {1}"
                                   .format(user1, unique_database))
       TestRanger._check_privileges(result, [
-        ["USER", user1, unique_database, "", "", "", "*", "insert", "true"],
-        ["USER", user1, unique_database, "", "", "", "*", "select", "true"],
-        ["USER", user1, unique_database, "*", "*", "", "", "insert", "true"],
-        ["USER", user1, unique_database, "*", "*", "", "", "select", "true"]])
+          ["USER", user1, unique_database, "", "", "", "*", "insert", "true"],
+          ["USER", user1, unique_database, "", "", "", "*", "select", "true"],
+          ["USER", user1, unique_database, "*", "*", "", "", "insert", "true"],
+          ["USER", user1, unique_database, "*", "*", "", "", "select", "true"]])
 
       # Revoke select privilege and check grant option is still present
       self.execute_query_expect_success(admin_client,
@@ -153,8 +153,8 @@ class TestRanger(CustomClusterTestSuite):
       result = self.execute_query("show grant user {0} on database {1}"
                                   .format(user1, unique_database))
       TestRanger._check_privileges(result, [
-        ["USER", user1, unique_database, "", "", "", "*", "insert", "true"],
-        ["USER", user1, unique_database, "*", "*", "", "", "insert", "true"]])
+          ["USER", user1, unique_database, "", "", "", "*", "insert", "true"],
+          ["USER", user1, unique_database, "*", "*", "", "", "insert", "true"]])
 
       # Revoke privilege granting from user 1
       self.execute_query_expect_success(admin_client, "revoke grant option for insert "
@@ -166,8 +166,8 @@ class TestRanger(CustomClusterTestSuite):
       result = self.execute_query("show grant user {0} on database {1}"
                                   .format(user1, unique_database))
       TestRanger._check_privileges(result, [
-        ["USER", user1, unique_database, "", "", "", "*", "insert", "false"],
-        ["USER", user1, unique_database, "*", "*", "", "", "insert", "false"]])
+          ["USER", user1, unique_database, "", "", "", "*", "insert", "false"],
+          ["USER", user1, unique_database, "*", "*", "", "", "insert", "false"]])
     finally:
       admin_client.execute("revoke insert on database {0} from user {1}"
                            .format(unique_database, user1), user=ADMIN)
@@ -199,6 +199,10 @@ class TestRanger(CustomClusterTestSuite):
         # Test that omitting ON <resource> results in failure
         self._test_show_grant_without_on(data[1], data[0])
 
+        # Test inherited privileges (server privileges show for database, etc.)
+        self._test_show_grant_inherited(admin_client, data[1], data[0], unique_db,
+                                        unique_table)
+
       # Test ALL privilege hides other privileges
       self._test_show_grant_mask(admin_client, user)
 
@@ -222,8 +226,8 @@ class TestRanger(CustomClusterTestSuite):
       result = self.client.execute("show grant user {0} on database {1}"
                                    .format(user, unique_db))
       TestRanger._check_privileges(result, [
-        ["GROUP", user, unique_db, "", "", "", "*", "select", "false"],
-        ["GROUP", user, unique_db, "*", "*", "", "", "select", "false"]])
+          ["GROUP", user, unique_db, "", "", "", "*", "select", "false"],
+          ["GROUP", user, unique_db, "*", "*", "", "", "select", "false"]])
     finally:
       admin_client.execute("revoke select on database {0} from group {1}"
                            .format(unique_db, group))
@@ -235,31 +239,31 @@ class TestRanger(CustomClusterTestSuite):
         admin_client.execute("grant {0} on server to user {1}".format(privilege, user))
       result = self.client.execute("show grant user {0} on server".format(user))
       TestRanger._check_privileges(result, [
-        ["USER", user, "", "", "", "*", "", "alter", "false"],
-        ["USER", user, "", "", "", "*", "", "create", "false"],
-        ["USER", user, "", "", "", "*", "", "drop", "false"],
-        ["USER", user, "", "", "", "*", "", "insert", "false"],
-        ["USER", user, "", "", "", "*", "", "refresh", "false"],
-        ["USER", user, "", "", "", "*", "", "select", "false"],
-        ["USER", user, "*", "", "", "", "*", "alter", "false"],
-        ["USER", user, "*", "", "", "", "*", "create", "false"],
-        ["USER", user, "*", "", "", "", "*", "drop", "false"],
-        ["USER", user, "*", "", "", "", "*", "insert", "false"],
-        ["USER", user, "*", "", "", "", "*", "refresh", "false"],
-        ["USER", user, "*", "", "", "", "*", "select", "false"],
-        ["USER", user, "*", "*", "*", "", "", "alter", "false"],
-        ["USER", user, "*", "*", "*", "", "", "create", "false"],
-        ["USER", user, "*", "*", "*", "", "", "drop", "false"],
-        ["USER", user, "*", "*", "*", "", "", "insert", "false"],
-        ["USER", user, "*", "*", "*", "", "", "refresh", "false"],
-        ["USER", user, "*", "*", "*", "", "", "select", "false"]])
+          ["USER", user, "", "", "", "*", "", "alter", "false"],
+          ["USER", user, "", "", "", "*", "", "create", "false"],
+          ["USER", user, "", "", "", "*", "", "drop", "false"],
+          ["USER", user, "", "", "", "*", "", "insert", "false"],
+          ["USER", user, "", "", "", "*", "", "refresh", "false"],
+          ["USER", user, "", "", "", "*", "", "select", "false"],
+          ["USER", user, "*", "", "", "", "*", "alter", "false"],
+          ["USER", user, "*", "", "", "", "*", "create", "false"],
+          ["USER", user, "*", "", "", "", "*", "drop", "false"],
+          ["USER", user, "*", "", "", "", "*", "insert", "false"],
+          ["USER", user, "*", "", "", "", "*", "refresh", "false"],
+          ["USER", user, "*", "", "", "", "*", "select", "false"],
+          ["USER", user, "*", "*", "*", "", "", "alter", "false"],
+          ["USER", user, "*", "*", "*", "", "", "create", "false"],
+          ["USER", user, "*", "*", "*", "", "", "drop", "false"],
+          ["USER", user, "*", "*", "*", "", "", "insert", "false"],
+          ["USER", user, "*", "*", "*", "", "", "refresh", "false"],
+          ["USER", user, "*", "*", "*", "", "", "select", "false"]])
 
       admin_client.execute("grant all on server to user {0}".format(user))
       result = self.client.execute("show grant user {0} on server".format(user))
       TestRanger._check_privileges(result, [
-        ["USER", user, "", "", "", "*", "", "all", "false"],
-        ["USER", user, "*", "", "", "", "*", "all", "false"],
-        ["USER", user, "*", "*", "*", "", "", "all", "false"]])
+          ["USER", user, "", "", "", "*", "", "all", "false"],
+          ["USER", user, "*", "", "", "", "*", "all", "false"],
+          ["USER", user, "*", "*", "*", "", "", "all", "false"]])
     finally:
       admin_client.execute("revoke all on server from user {0}".format(user))
       for privilege in privileges:
@@ -272,9 +276,9 @@ class TestRanger(CustomClusterTestSuite):
       admin_client.execute("grant all on server to {0} {1}".format(kw, id), user=ADMIN)
       result = self.client.execute("show grant {0} {1} on server".format(kw, id))
       TestRanger._check_privileges(result, [
-        [kw, id, "", "", "", "*", "", "all", "false"],
-        [kw, id, "*", "", "", "", "*", "all", "false"],
-        [kw, id, "*", "*", "*", "", "", "all", "false"]])
+          [kw, id, "", "", "", "*", "", "all", "false"],
+          [kw, id, "*", "", "", "", "*", "all", "false"],
+          [kw, id, "*", "*", "*", "", "", "all", "false"]])
 
       # Revoke server privileges and verify
       admin_client.execute("revoke all on server from {0} {1}".format(kw, id))
@@ -287,7 +291,7 @@ class TestRanger(CustomClusterTestSuite):
       result = self.client.execute("show grant {0} {1} on uri '{2}'"
                                    .format(kw, id, uri))
       TestRanger._check_privileges(result, [
-        [kw, id, "", "", "", "{0}{1}".format(NAMENODE, uri), "", "all", "false"]])
+          [kw, id, "", "", "", "{0}{1}".format(NAMENODE, uri), "", "all", "false"]])
 
       # Revoke uri privileges and verify
       admin_client.execute("revoke all on uri '{0}' from {1} {2}"
@@ -302,8 +306,8 @@ class TestRanger(CustomClusterTestSuite):
       result = self.client.execute("show grant {0} {1} on database {2}"
                                    .format(kw, id, unique_database))
       TestRanger._check_privileges(result, [
-        [kw, id, unique_database, "", "", "", "*", "select", "false"],
-        [kw, id, unique_database, "*", "*", "", "", "select", "false"]])
+          [kw, id, unique_database, "", "", "", "*", "select", "false"],
+          [kw, id, unique_database, "*", "*", "", "", "select", "false"]])
 
       # Revoke database privileges and verify
       admin_client.execute("revoke select on database {0} from {1} {2}"
@@ -318,7 +322,7 @@ class TestRanger(CustomClusterTestSuite):
       result = self.client.execute("show grant {0} {1} on table {2}.{3}"
                                    .format(kw, id, unique_database, unique_table))
       TestRanger._check_privileges(result, [
-        [kw, id, unique_database, unique_table, "*", "", "", "select", "false"]])
+          [kw, id, unique_database, unique_table, "*", "", "", "select", "false"]])
 
       # Revoke table privileges and verify
       admin_client.execute("revoke select on table {0}.{1} from {2} {3}"
@@ -333,7 +337,7 @@ class TestRanger(CustomClusterTestSuite):
       result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
                                    .format(kw, id, unique_database, unique_table))
       TestRanger._check_privileges(result, [
-        [kw, id, unique_database, unique_table, "x", "", "", "select", "false"]])
+          [kw, id, unique_database, unique_table, "x", "", "", "select", "false"]])
 
       # Revoke column privileges and verify
       admin_client.execute("revoke select(x) on table {0}.{1} from {2} {3}"
@@ -352,6 +356,111 @@ class TestRanger(CustomClusterTestSuite):
       admin_client.execute("revoke select(x) on table {0}.{1} from {2} {3}"
                            .format(unique_database, unique_table, kw, id))
 
+  def _test_show_grant_inherited(self, admin_client, kw, id, unique_database,
+                                 unique_table):
+    try:
+      # Grant the select privilege on server
+      admin_client.execute("grant select on server to {0} {1}".format(kw, id), user=ADMIN)
+
+      # Verify the privileges are correctly added
+      result = self.client.execute("show grant {0} {1} on server".format(kw, id))
+      TestRanger._check_privileges(result, [
+          [kw, id, "", "", "", "*", "", "select", "false"],
+          [kw, id, "*", "", "", "", "*", "select", "false"],
+          [kw, id, "*", "*", "*", "", "", "select", "false"]])
+
+      # Verify the highest level of resource that contains the specified resource could
+      # be computed when the specified resource is a database
+      result = self.client.execute("show grant {0} {1} on database {2}"
+          .format(kw, id, unique_database))
+      TestRanger._check_privileges(result, [
+          [kw, id, "*", "", "", "", "*", "select", "false"],
+          [kw, id, "*", "*", "*", "", "", "select", "false"]])
+
+      # Verify the highest level of resource that contains the specified resource could
+      # be computed when the specified resource is a table
+      result = self.client.execute("show grant {0} {1} on table {2}.{3}"
+                                   .format(kw, id, unique_database, unique_table))
+      TestRanger._check_privileges(result, [
+          [kw, id, "*", "*", "*", "", "", "select", "false"]])
+
+      # Verify the highest level of resource that contains the specified resource could
+      # be computed when the specified resource is a column
+      result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
+                                   .format(kw, id, unique_database, unique_table))
+      TestRanger._check_privileges(result, [
+          [kw, id, "*", "*", "*", "", "", "select", "false"]])
+
+      # Grant the create privilege on database and verify
+      admin_client.execute("grant create on database {0} to {1} {2}"
+                           .format(unique_database, kw, id), user=ADMIN)
+      result = self.client.execute("show grant {0} {1} on database {2}"
+                                   .format(kw, id, unique_database))
+      TestRanger._check_privileges(result, [
+          [kw, id, "*", "", "", "", "*", "select", "false"],
+          [kw, id, "*", "*", "*", "", "", "select", "false"],
+          [kw, id, unique_database, "", "", "", "*", "create", "false"],
+          [kw, id, unique_database, "*", "*", "", "", "create", "false"]
+      ])
+
+      # Grant the insert privilege on table and verify
+      admin_client.execute("grant insert on table {0}.{1} to {2} {3}"
+                           .format(unique_database, unique_table, kw, id), user=ADMIN)
+      result = self.client.execute("show grant {0} {1} on table {2}.{3}"
+                                   .format(kw, id, unique_database, unique_table))
+      TestRanger._check_privileges(result, [
+          [kw, id, "*", "*", "*", "", "", "select", "false"],
+          [kw, id, unique_database, "*", "*", "", "", "create", "false"],
+          [kw, id, unique_database, unique_table, "*", "", "", "insert", "false"]
+      ])
+
+      # Grant the select privilege on column and verify
+      admin_client.execute("grant select(x) on table {0}.{1} to {2} {3}"
+                           .format(unique_database, unique_table, kw, id), user=ADMIN)
+      result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
+                                   .format(kw, id, unique_database, unique_table))
+      TestRanger._check_privileges(result, [
+          [kw, id, unique_database, "*", "*", "", "", "create", "false"],
+          [kw, id, unique_database, unique_table, "*", "", "", "insert", "false"],
+          [kw, id, unique_database, unique_table, "x", "", "", "select", "false"]
+      ])
+
+      # The insert privilege on table masks the select privilege just added
+      admin_client.execute("grant select on table {0}.{1} to {2} {3}"
+                           .format(unique_database, unique_table, kw, id), user=ADMIN)
+      result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
+                                   .format(kw, id, unique_database, unique_table))
+      TestRanger._check_privileges(result, [
+          [kw, id, unique_database, "*", "*", "", "", "create", "false"],
+          [kw, id, unique_database, unique_table, "*", "", "", "insert", "false"],
+          [kw, id, unique_database, unique_table, "x", "", "", "select", "false"]
+      ])
+
+      # The all privilege on table masks the privileges of insert and select, but not the
+      # select privilege on column.
+      admin_client.execute("grant all on table {0}.{1} to {2} {3}"
+                           .format(unique_database, unique_table, kw, id), user=ADMIN)
+      result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
+                                   .format(kw, id, unique_database, unique_table))
+      TestRanger._check_privileges(result, [
+          [kw, id, unique_database, unique_table, "*", "", "", "all", "false"],
+          [kw, id, unique_database, unique_table, "x", "", "", "select", "false"]
+      ])
+
+    finally:
+      admin_client.execute("revoke select on server from {0} {1}".format(kw, id))
+      admin_client.execute("revoke create on database {0} from {1} {2}"
+                           .format(unique_database, kw, id))
+      admin_client.execute("revoke insert on table {0}.{1} from {2} {3}"
+                           .format(unique_database, unique_table, kw, id))
+      admin_client.execute("revoke select(x) on table {0}.{1} from {2} {3}"
+                           .format(unique_database, unique_table, kw, id))
+      admin_client.execute("revoke select on table {0}.{1} from {2} {3}"
+                           .format(unique_database, unique_table, kw, id))
+      admin_client.execute("revoke all on table {0}.{1} from {2} {3}"
+                           .format(unique_database, unique_table, kw, id))
+
+
   @CustomClusterTestSuite.with_args(
     impalad_args=IMPALAD_ARGS, catalogd_args=CATALOGD_ARGS)
   def test_grant_revoke_ranger_api(self, unique_name):
@@ -385,8 +494,8 @@ class TestRanger(CustomClusterTestSuite):
                                    .format(user, unique_db))
 
       TestRanger._check_privileges(result, [
-        ["USER", user, unique_db, "*", "*", "", "", "create", "false"],
-        ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
+          ["USER", user, unique_db, "*", "*", "", "", "create", "false"],
+          ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
       ])
 
       # Revoke privileges via Ranger REST API
@@ -396,8 +505,8 @@ class TestRanger(CustomClusterTestSuite):
       result = self.client.execute("show grant user {0} on database {1}"
                                    .format(user, unique_db))
       TestRanger._check_privileges(result, [
-        ["USER", user, unique_db, "*", "*", "", "", "create", "false"],
-        ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
+          ["USER", user, unique_db, "*", "*", "", "", "create", "false"],
+          ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
       ])
 
       # Refresh and check updated privileges
@@ -436,7 +545,7 @@ class TestRanger(CustomClusterTestSuite):
                                    .format(user, unique_db))
 
       TestRanger._check_privileges(result, [
-        ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
+          ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
       ])
 
       # Assert that lock, select privilege exists in Ranger server