sentry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lsk...@apache.org
Subject incubator-sentry git commit: SENTRY-826: TRUNCATE on empty partitioned table in Hive fails (Li Li via Lenni Kuff)
Date Sun, 10 Jan 2016 08:05:35 GMT
Repository: incubator-sentry
Updated Branches:
  refs/heads/master 3ee3e9320 -> 67031139f


SENTRY-826: TRUNCATE on empty partitioned table in Hive fails (Li Li via Lenni Kuff)

Change-Id: I1a1969e169ad014915473435ae62b4c1e054bac7


Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/67031139
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/67031139
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/67031139

Branch: refs/heads/master
Commit: 67031139f0db369ed4969a23e97308c941a8c953
Parents: 3ee3e93
Author: Lenni Kuff <lskuff@cloudera.com>
Authored: Sun Jan 10 00:04:40 2016 -0800
Committer: Lenni Kuff <lskuff@cloudera.com>
Committed: Sun Jan 10 00:04:40 2016 -0800

----------------------------------------------------------------------
 .../binding/hive/HiveAuthzBindingHook.java      |  14 ++
 .../e2e/hive/TestPrivilegesAtTableScope.java    | 149 +++++++++++++++----
 2 files changed, 136 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/67031139/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
index 994af8a..57e4689 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
@@ -28,6 +28,7 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.Set;
 
+import com.google.common.base.Preconditions;
 import org.apache.hadoop.hive.common.JavaUtils;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
@@ -266,6 +267,19 @@ public class HiveAuthzBindingHook extends AbstractSemanticAnalyzerHook
{
         // "FORMATTED/EXTENDED".
         isDescTableBasic = (ast.getChildCount() == 1);
         break;
+      case HiveParser.TOK_TRUNCATETABLE:
+        // SENTRY-826:
+        // Truncate empty partitioned table should throw SemanticException only if the
+        // user does not have permission.
+        // In postAnalyze, currOutDB and currOutTbl will be added into outputHierarchy
+        // which will be validated in the hiveAuthzBinding.authorize method.
+        Preconditions.checkArgument(ast.getChildCount() == 1);
+        // childcount is 1 for table without partition, 2 for table with partitions
+        Preconditions.checkArgument(ast.getChild(0).getChildCount() >= 1);
+        Preconditions.checkArgument(ast.getChild(0).getChild(0).getChildCount() == 1);
+        currOutDB = extractDatabase((ASTNode) ast.getChild(0));
+        currOutTab = extractTable((ASTNode) ast.getChild(0).getChild(0).getChild(0));
+        break;
       default:
         currDB = getCanonicalDb();
         break;

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/67031139/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java
index 56776db..b5240ea 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java
@@ -450,44 +450,70 @@ public class TestPrivilegesAtTableScope extends AbstractTestWithStaticConfigurat
     statement.close();
     connection.close();
 
-    policyFile
-        .addRolesToGroup(USERGROUP1, "all_tab1")
-        .addPermissionsToRole("all_tab1",
-            "server=server1->db=" + DB1 + "->table=" + TBL2)
-        .addRolesToGroup(USERGROUP2, "drop_tab1")
-        .addPermissionsToRole("drop_tab1",
-            "server=server1->db=" + DB1 + "->table=" + TBL3 + "->action=drop",
-            "server=server1->db=" + DB1 + "->table=" + TBL3 + "->action=select")
-        .addRolesToGroup(USERGROUP3, "select_tab1")
-        .addPermissionsToRole("select_tab1",
-            "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=select");
+    // add roles and grant permissions
+    updatePolicyFile();
+
+    // test truncate table without partitions
+    truncateTableTests(false);
+  }
+
+  /***
+   * Verify truncate partitioned permissions for different users with different
+   * privileges
+   * @throws Exception
+   */
+  @Test
+  public void testTruncatePartitionedTable() throws Exception {
+    File dataDir = context.getDataDir();
+    // copy data file to test dir
+    File dataFile = new File(dataDir, MULTI_TYPE_DATA_FILE_NAME);
+    FileOutputStream to = new FileOutputStream(dataFile);
+    Resources.copy(Resources.getResource(MULTI_TYPE_DATA_FILE_NAME), to);
+    to.close();
+
+    policyFile.setUserGroupMapping(StaticUserGroup.getStaticMapping());
     writePolicyFile(policyFile);
 
-    connection = context.createConnection(USER1_1);
-    statement = context.createStatement(connection);
+    // create partitioned tables
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
     statement.execute("USE " + DB1);
-    // verify all on tab can truncate table
-    statement.execute("TRUNCATE TABLE " + TBL2);
-    assertFalse(hasData(statement, TBL2));
-    statement.close();
-    connection.close();
+    statement.execute("DROP TABLE if exists " + TBL1);
+    statement.execute("CREATE TABLE " + TBL1 + " (i int) PARTITIONED BY (j int)");
+    statement.execute("DROP TABLE if exists " + TBL2);
+    statement.execute("CREATE TABLE " + TBL2 + " (i int) PARTITIONED BY (j int)");
+    statement.execute("DROP TABLE if exists " + TBL3);
+    statement.execute("CREATE TABLE " + TBL3 + " (i int) PARTITIONED BY (j int)");
 
-    connection = context.createConnection(USER2_1);
-    statement = context.createStatement(connection);
-    statement.execute("USE " + DB1);
-    // verify drop on tab can truncate table
-    statement.execute("TRUNCATE TABLE " + TBL3);
-    assertFalse(hasData(statement, TBL3));
+    // verify admin can execute truncate empty partitioned table
+    statement.execute("TRUNCATE TABLE " + TBL1);
+    assertFalse(hasData(statement, TBL1));
     statement.close();
     connection.close();
 
-    connection = context.createConnection(USER3_1);
+    // add roles and grant permissions
+    updatePolicyFile();
+
+    // test truncate empty partitioned tables
+    truncateTableTests(false);
+
+    // add partitions to tables
+    connection = context.createConnection(ADMIN1);
     statement = context.createStatement(connection);
     statement.execute("USE " + DB1);
-    // verify select on tab can NOT truncate table
-    context.assertAuthzException(statement, "TRUNCATE TABLE " + TBL3);
+    statement.execute("ALTER TABLE " + TBL1 + " ADD PARTITION (j=1) PARTITION (j=2)");
+    statement.execute("ALTER TABLE " + TBL2 + " ADD PARTITION (j=1) PARTITION (j=2)");
+    statement.execute("ALTER TABLE " + TBL3 + " ADD PARTITION (j=1) PARTITION (j=2)");
+
+    // verify admin can execute truncate NOT empty partitioned table
+    statement.execute("TRUNCATE TABLE " + TBL1 + " partition (j=1)");
+    statement.execute("TRUNCATE TABLE " + TBL1);
+    assertFalse(hasData(statement, TBL1));
     statement.close();
     connection.close();
+
+    // test truncate NOT empty partitioned tables
+    truncateTableTests(true);
   }
 
   /**
@@ -564,4 +590,73 @@ public class TestPrivilegesAtTableScope extends AbstractTestWithStaticConfigurat
     connection.close();
 
   }
+
+  /**
+   * update policy file for truncate table tests
+   */
+  private void updatePolicyFile() throws Exception{
+    policyFile
+        .addRolesToGroup(USERGROUP1, "all_tab1")
+        .addPermissionsToRole("all_tab1",
+            "server=server1->db=" + DB1 + "->table=" + TBL2)
+        .addRolesToGroup(USERGROUP2, "drop_tab1")
+        .addPermissionsToRole("drop_tab1",
+            "server=server1->db=" + DB1 + "->table=" + TBL3 + "->action=drop",
+            "server=server1->db=" + DB1 + "->table=" + TBL3 + "->action=select")
+        .addRolesToGroup(USERGROUP3, "select_tab1")
+        .addPermissionsToRole("select_tab1",
+            "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=select");
+    writePolicyFile(policyFile);
+  }
+
+  /**
+   * Test truncate table with or without partitions for users with different privileges.
+   * Only test truncate table partition if truncPartition is true.
+   */
+  private void truncateTableTests(boolean truncPartition) throws Exception{
+    Connection connection = null;
+    Statement statement = null;
+    try {
+      connection = context.createConnection(USER1_1);
+      statement = context.createStatement(connection);
+      statement.execute("USE " + DB1);
+      // verify all privileges on table can truncate table
+      if (truncPartition) {
+        statement.execute("TRUNCATE TABLE " + TBL2 + " PARTITION (j=1)");
+      }
+      statement.execute("TRUNCATE TABLE " + TBL2);
+      assertFalse(hasData(statement, TBL2));
+      statement.close();
+      connection.close();
+
+      connection = context.createConnection(USER2_1);
+      statement = context.createStatement(connection);
+      statement.execute("USE " + DB1);
+      // verify drop privilege on table can truncate table
+      if (truncPartition) {
+        statement.execute("TRUNCATE TABLE " + TBL3 + " partition (j=1)");
+      }
+      statement.execute("TRUNCATE TABLE " + TBL3);
+      assertFalse(hasData(statement, TBL3));
+      statement.close();
+      connection.close();
+
+      connection = context.createConnection(USER3_1);
+      statement = context.createStatement(connection);
+      statement.execute("USE " + DB1);
+      // verify select privilege on table can NOT truncate table
+      if (truncPartition) {
+        context.assertAuthzException(
+            statement, "TRUNCATE TABLE " + TBL1 + " PARTITION (j=1)");
+      }
+      context.assertAuthzException(statement, "TRUNCATE TABLE " + TBL1);
+    } finally {
+      if (statement != null) {
+        statement.close();
+      }
+      if (connection != null) {
+        connection.close();
+      }
+    }
+  }
 }


Mime
View raw message