SENTRY-758: Add test cases for partition columns with column level privileges
- Also added tests for select *, select col(*) and select col(1) Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/a9c8d904 Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/a9c8d904 Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/a9c8d904 Branch: refs/heads/hive_plugin_v2 Commit: a9c8d904d795826d43000f81523fe1966aa775b6 Parents: 2265ab8 Author: Sravya Tirukkovalur <[email protected]> Authored: Thu Aug 13 12:02:14 2015 -0700 Committer: Sravya Tirukkovalur <[email protected]> Committed: Thu Aug 13 12:06:48 2015 -0700 ---------------------------------------------------------------------- .../e2e/dbprovider/TestColumnEndToEnd.java | 60 +++++++++++++------- .../e2e/dbprovider/TestDatabaseProvider.java | 26 +++++++++ .../e2e/hive/TestPrivilegesAtColumnScope.java | 49 ++++++++++++++++ 3 files changed, 116 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/a9c8d904/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestColumnEndToEnd.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestColumnEndToEnd.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestColumnEndToEnd.java index 742c74f..9ed38ae 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestColumnEndToEnd.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestColumnEndToEnd.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileOutputStream; import java.sql.Connection; +import java.sql.SQLException; import java.sql.Statement; import org.apache.sentry.provider.db.SentryAccessDeniedException; @@ -82,11 +83,13 @@ public class TestColumnEndToEnd extends AbstractTestWithStaticConfiguration { public void testNegative() throws Exception { Connection connection = context.createConnection(ADMIN1); Statement statement = context.createStatement(connection); - statement.execute("CREATE TABLE t1 (c1 string, c2 string, c3 string)"); + statement.execute("CREATE TABLE t1 (c1 string, c2 string)"); statement.execute("CREATE ROLE user_role1"); statement.execute("CREATE ROLE user_role2"); statement.execute("GRANT SELECT (c1) ON TABLE t1 TO ROLE user_role1"); statement.execute("GRANT SELECT (c1,c2) ON TABLE t1 TO ROLE user_role2"); + + //Make sure insert/all are not supported try { statement.execute("GRANT INSERT (c2) ON TABLE t1 TO ROLE user_role2"); assertTrue("Sentry should not support privilege: Insert on Column", false); @@ -106,50 +109,69 @@ public class TestColumnEndToEnd extends AbstractTestWithStaticConfiguration { statement.close(); connection.close(); + /* + Behavior of select col, select count(col), select *, and select count(*), count(1) + */ // 1.1 user_role1 select c1,c2 from t1, will throw exception connection = context.createConnection(USER1_1); statement = context.createStatement(connection); try { statement.execute("SELECT c1,c2 FROM t1"); - assertTrue("only SELECT allowed on t1.c1!!", false); - } catch (Exception e) { - // Ignore + assertTrue("User with privilege on one column is able to access other column!!", false); + } catch (SQLException e) { + context.verifyAuthzException(e); } - // 1.2 user_role1 select * from t1, will throw exception + // 1.2 user_role1 count(col) works, *, count(*) and count(1) fails + statement.execute("SELECT count(c1) FROM t1"); try { statement.execute("SELECT * FROM t1"); - assertTrue("only SELECT allowed on t1.c1!!", false); - } catch (Exception e) { - // Ignore + assertTrue("Select * should fail - only SELECT allowed on t1.c1!!", false); + } catch (SQLException e) { + context.verifyAuthzException(e); + } + try { + statement.execute("SELECT count(*) FROM t1"); + assertTrue("Select count(*) should fail - only SELECT allowed on t1.c1!!", false); + } catch (SQLException e) { + context.verifyAuthzException(e); + } + try { + statement.execute("SELECT count(1) FROM t1"); + assertTrue("Select count(1) should fail - only SELECT allowed on t1.c1!!", false); + } catch (SQLException e) { + context.verifyAuthzException(e); } - // 2.1 user_role2 select c1,c2,c3 from t1, will throw exception + statement.close(); + connection.close(); + + + // 2.1 user_role2 can do *, count(col), but count(*) and count(1) fails connection = context.createConnection(USER2_1); statement = context.createStatement(connection); + statement.execute("SELECT count(c1) FROM t1"); + statement.execute("SELECT * FROM t1"); + + //SENTRY-838 try { - statement.execute("SELECT c1,c2,c3 FROM t1"); - assertTrue("no permission on table t1!!", false); + statement.execute("SELECT count(*) FROM t1"); + assertTrue("Select count(*) works only with table level privileges - User has select on all columns!!", false); } catch (Exception e) { // Ignore } - - // 2.2 user_role2 select * from t1, will throw exception - connection = context.createConnection(USER2_1); - statement = context.createStatement(connection); try { - statement.execute("SELECT * FROM t1"); - assertTrue("no permission on table t1!!", false); + statement.execute("SELECT count(1) FROM t1"); + assertTrue("Select count(1) works only with table level privileges - User has select on all columns!!", false); } catch (Exception e) { // Ignore } - statement.close(); connection.close(); } @Test - public void testPostive() throws Exception { + public void testPositive() throws Exception { Connection connection = context.createConnection(ADMIN1); Statement statement = context.createStatement(connection); statement.execute("CREATE database " + DB1); http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/a9c8d904/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java index 87b281b..9c0958f 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java @@ -1013,6 +1013,8 @@ public class TestDatabaseProvider extends AbstractTestWithStaticConfiguration { //Grant/Revoke All on server by admin statement.execute("GRANT ALL ON SERVER server1 to role role1"); + statement.execute("GRANT Role role1 to group " + ADMINGROUP); + statement.execute("Create table tab1(col1 int)"); resultSet = statement.executeQuery("SHOW GRANT ROLE role1"); assertResultSize(resultSet, 1); while(resultSet.next()) { @@ -1142,6 +1144,29 @@ public class TestDatabaseProvider extends AbstractTestWithStaticConfiguration { resultSet = statement.executeQuery("SHOW GRANT ROLE role1"); assertResultSize(resultSet, 0); + + //Grant/Revoke SELECT on column by admin + statement.execute("GRANT SELECT(col1) ON TABLE tab1 to role role1"); + resultSet = statement.executeQuery("SHOW GRANT ROLE role1"); + assertResultSize(resultSet, 1); + while(resultSet.next()) { + assertThat(resultSet.getString(1), equalToIgnoringCase("default")); + assertThat(resultSet.getString(2), equalToIgnoringCase("tab1")); + assertThat(resultSet.getString(3), equalToIgnoringCase(""));//partition + assertThat(resultSet.getString(4), equalToIgnoringCase("col1"));//column + assertThat(resultSet.getString(5), equalToIgnoringCase("role1"));//principalName + assertThat(resultSet.getString(6), equalToIgnoringCase("role"));//principalType + assertThat(resultSet.getString(7), equalToIgnoringCase("select")); + assertThat(resultSet.getBoolean(8), is(new Boolean("False")));//grantOption + //Create time is not tested + //assertThat(resultSet.getLong(9), is(new Long(0))); + assertThat(resultSet.getString(10), equalToIgnoringCase("--"));//grantor + } + + statement.execute("REVOKE SELECT(col1) ON TABLE tab1 from role role1"); + resultSet = statement.executeQuery("SHOW GRANT ROLE role1"); + assertResultSize(resultSet, 0); + //Revoke Partial privilege on table by admin statement.execute("GRANT ALL ON TABLE tab1 to role role1"); resultSet = statement.executeQuery("SHOW GRANT ROLE role1"); @@ -1184,6 +1209,7 @@ public class TestDatabaseProvider extends AbstractTestWithStaticConfiguration { assertThat(resultSet.getString(10), equalToIgnoringCase("--"));//grantor } + statement.close(); connection.close(); } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/a9c8d904/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtColumnScope.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtColumnScope.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtColumnScope.java index 9eeed60..8adc5bb 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtColumnScope.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtColumnScope.java @@ -20,11 +20,16 @@ package org.apache.sentry.tests.e2e.hive; import java.io.File; import java.io.FileOutputStream; import java.sql.Connection; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; import junit.framework.Assert; +import org.apache.hadoop.fs.FSDataOutputStream; +import org.apache.hadoop.fs.Path; import org.apache.sentry.provider.file.PolicyFile; import org.junit.Before; import org.junit.BeforeClass; @@ -82,6 +87,12 @@ public class TestPrivilegesAtColumnScope extends AbstractTestWithStaticConfigura statement.execute("CREATE TABLE TAB_2(A STRING, B STRING)"); statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_2"); statement.execute("CREATE VIEW VIEW_2(A,B) AS SELECT A,B FROM TAB_2"); + //create table with partitions + statement.execute("CREATE TABLE TAB_3 (A STRING, B STRING) partitioned by (C STRING)"); + statement.execute("ALTER TABLE TAB_3 ADD PARTITION (C=1)"); + statement.execute("ALTER TABLE TAB_3 ADD PARTITION (C=2)"); + statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_3 PARTITION (C=1)"); + statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_3 PARTITION (C=2)"); statement.close(); connection.close(); } @@ -460,4 +471,42 @@ public class TestPrivilegesAtColumnScope extends AbstractTestWithStaticConfigura statement.close(); connection.close(); } + + @Test + public void testPartition() throws Exception{ + policyFile + .addRolesToGroup(USERGROUP1, "select_tab3_A", "select_tab3_C") + .addRolesToGroup(USERGROUP2, "select_tab3_A") + .addRolesToGroup(USERGROUP3, "select_tab3_C") + .addPermissionsToRole("select_tab3_A", "server=server1->db=DB_1->table=TAB_3->column=A->action=select") + .addPermissionsToRole("select_tab3_C", "server=server1->db=DB_1->table=TAB_3->column=C->action=select") + .setUserGroupMapping(StaticUserGroup.getStaticMapping()); + writePolicyFile(policyFile); + + // Users with privileges on partition column can access it + String [] positiveUsers = {USER1_1, USER3_1}; + for(String user:positiveUsers) { + Connection connection = context.createConnection(user); + Statement statement = context.createStatement(connection); + statement.execute("USE DB_1"); + statement.execute("SELECT C FROM TAB_3"); + statement.close(); + connection.close(); + } + + // Users with out privileges on partition column can not access it + String [] negativeUsers = {USER2_1}; + for(String user:negativeUsers) { + Connection connection = context.createConnection(USER1_1); + Statement statement = context.createStatement(connection); + statement.execute("USE DB_1"); + try { + statement.execute("SELECT C FROM TAB_3"); + } catch (SQLException e) { + context.verifyAuthzException(e); + } + statement.close(); + connection.close(); + } + } }
