This is an automated email from the ASF dual-hosted git repository. arodoni pushed a commit to branch 2.x in repository https://gitbox.apache.org/repos/asf/impala.git
commit 139f3b7351bf6a45689b670fa3d388d56cf4cc72 Author: Fredy Wijaya <fwij...@cloudera.com> AuthorDate: Wed Jun 27 12:59:20 2018 -0700 IMPALA-6802 (part 6): Clean up authorization tests This is the last part of the authorization test clean up. This patch rewrites the following tests: - alter database - explain - comment on - function - alter table/view This patch also adds the following authorization tests: - update - upsert - delete The tests in AuthorizationTest.java that have been rewritten into AuthorizationStmtTest.java are removed. Cherry-picks: not for 2.x Change-Id: Id594ce09a821aef4a1debfdd61569a11defd1c55 Reviewed-on: http://gerrit.cloudera.org:8080/10841 Reviewed-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com> Tested-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com> Reviewed-on: http://gerrit.cloudera.org:8080/12722 Reviewed-by: Fredy Wijaya <fwij...@cloudera.com> --- .../impala/analysis/AuthorizationStmtTest.java | 595 +++++- .../apache/impala/analysis/AuthorizationTest.java | 2004 -------------------- 2 files changed, 554 insertions(+), 2045 deletions(-) diff --git a/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java b/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java index 1d4c593..0a32fc9 100644 --- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java +++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java @@ -297,6 +297,45 @@ public class AuthorizationStmtTest extends FrontendTestBase { verifyPrivilegeReqs("drop view functional.alltypes_view", expectedAuthorizables); verifyPrivilegeReqs(createAnalysisCtx("functional"), "drop view alltypes_view", expectedAuthorizables); + + // Update table. + expectedAuthorizables = Sets.newHashSet( + "functional_kudu.alltypes", + "functional_kudu.alltypes.id", + "functional_kudu.alltypes.int_col"); + verifyPrivilegeReqs("update functional_kudu.alltypes set int_col = 1", + expectedAuthorizables); + verifyPrivilegeReqs(createAnalysisCtx("functional_kudu"), + "update alltypes set int_col = 1", expectedAuthorizables); + + // Upsert table. + expectedAuthorizables = Sets.newHashSet("functional_kudu.alltypes"); + verifyPrivilegeReqs("upsert into table functional_kudu.alltypes(id, int_col) " + + "values(1, 1)", expectedAuthorizables); + verifyPrivilegeReqs(createAnalysisCtx("functional_kudu"), + "upsert into table alltypes(id, int_col) values(1, 1)", expectedAuthorizables); + + // Delete table. + expectedAuthorizables = Sets.newHashSet( + "functional_kudu.alltypes", + "functional_kudu.alltypes.id"); + verifyPrivilegeReqs("delete from functional_kudu.alltypes", expectedAuthorizables); + verifyPrivilegeReqs(createAnalysisCtx("functional_kudu"), "delete from alltypes", + expectedAuthorizables); + + // Alter table. + expectedAuthorizables = Sets.newHashSet("functional.alltypes"); + verifyPrivilegeReqs("alter table functional.alltypes add columns(c1 int)", + expectedAuthorizables); + verifyPrivilegeReqs(createAnalysisCtx("functional"), "alter table alltypes " + + "add columns(c1 int)", expectedAuthorizables); + + // Alter view. + expectedAuthorizables = Sets.newHashSet("functional.alltypes_view"); + verifyPrivilegeReqs("alter view functional.alltypes_view as select 1", + expectedAuthorizables); + verifyPrivilegeReqs(createAnalysisCtx("functional"), "alter view alltypes_view as " + + "select 1", expectedAuthorizables); } @Test @@ -403,6 +442,23 @@ public class AuthorizationStmtTest extends FrontendTestBase { onTable("functional_seq_snap", "subquery_view", allExcept( TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))); + // Select a UDF. + ScalarFunction fn = addFunction("functional", "f"); + try { + authorize("select functional.f()") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(viewMetadataPrivileges())) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", viewMetadataPrivileges())) + .error(accessError("functional")) + .error(accessError("functional"), onServer(allExcept( + viewMetadataPrivileges()))) + .error(accessError("functional"), onDatabase("functional", allExcept( + viewMetadataPrivileges()))); + } finally { + removeFunction(fn); + } + // Select from non-existent database. authorize("select 1 from nodb.alltypes") .error(selectError("nodb.alltypes")); @@ -557,20 +613,24 @@ public class AuthorizationStmtTest extends FrontendTestBase { @Test public void testInsert() throws ImpalaException { // Basic insert into a table. - authorize("insert into functional.zipcode_incomes(id) values('123')") - .ok(onServer(TPrivilegeLevel.ALL)) - .ok(onServer(TPrivilegeLevel.INSERT)) - .ok(onDatabase("functional", TPrivilegeLevel.ALL)) - .ok(onDatabase("functional", TPrivilegeLevel.INSERT)) - .ok(onTable("functional", "zipcode_incomes", TPrivilegeLevel.ALL)) - .ok(onTable("functional", "zipcode_incomes", TPrivilegeLevel.INSERT)) - .error(insertError("functional.zipcode_incomes")) - .error(insertError("functional.zipcode_incomes"), onServer(allExcept( - TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT))) - .error(insertError("functional.zipcode_incomes"), onDatabase("functional", - allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT))) - .error(insertError("functional.zipcode_incomes"), onTable("functional", - "zipcode_incomes", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT))); + for (AuthzTest test: new AuthzTest[]{ + authorize("insert into functional.zipcode_incomes(id) values('123')"), + // Explain insert. + authorize("explain insert into functional.zipcode_incomes(id) values('123')")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.INSERT)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.INSERT)) + .ok(onTable("functional", "zipcode_incomes", TPrivilegeLevel.ALL)) + .ok(onTable("functional", "zipcode_incomes", TPrivilegeLevel.INSERT)) + .error(insertError("functional.zipcode_incomes")) + .error(insertError("functional.zipcode_incomes"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT))) + .error(insertError("functional.zipcode_incomes"), onDatabase("functional", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT))) + .error(insertError("functional.zipcode_incomes"), onTable("functional", + "zipcode_incomes", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.INSERT))); + } for (AuthzTest test: new AuthzTest[]{ // With clause with insert. @@ -1218,33 +1278,38 @@ public class AuthorizationStmtTest extends FrontendTestBase { } // CTAS. - authorize("create table functional.new_table as " + - "select int_col from functional.alltypes") - .ok(onServer(TPrivilegeLevel.ALL)) - .ok(onServer(TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT, - TPrivilegeLevel.SELECT)) - .ok(onDatabase("functional", TPrivilegeLevel.ALL)) - .ok(onDatabase("functional", TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT, - TPrivilegeLevel.SELECT)) - .ok(onDatabase("functional"), onDatabase("functional", TPrivilegeLevel.CREATE, - TPrivilegeLevel.INSERT), onTable("functional", "alltypes", - TPrivilegeLevel.SELECT)) - .ok(onDatabase("functional"), onDatabase("functional", TPrivilegeLevel.CREATE, - TPrivilegeLevel.INSERT), onColumn("functional", "alltypes", "int_col", - TPrivilegeLevel.ALL)) - .error(createError("functional.new_table")) - .error(createError("functional.new_table"), onServer(allExcept( - TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT, - TPrivilegeLevel.SELECT))) - .error(createError("functional.new_table"), onDatabase("functional", allExcept( - TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT, - TPrivilegeLevel.SELECT))) - .error(createError("functional.new_table"), onDatabase("functional", allExcept( - TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT)), - onTable("functional", "alltypes", TPrivilegeLevel.SELECT)) - .error(selectError("functional.alltypes"), onDatabase("functional", - TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT), onTable("functional", - "alltypes", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))); + for (AuthzTest test: new AuthzTest[]{ + authorize("create table functional.new_table as " + + "select int_col from functional.alltypes"), + // Explain CTAS. + authorize("explain create table functional.new_table as " + + "select int_col from functional.alltypes")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT, + TPrivilegeLevel.SELECT)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT, + TPrivilegeLevel.SELECT)) + .ok(onDatabase("functional"), onDatabase("functional", TPrivilegeLevel.CREATE, + TPrivilegeLevel.INSERT), onTable("functional", "alltypes", + TPrivilegeLevel.SELECT)) + .ok(onDatabase("functional"), onDatabase("functional", TPrivilegeLevel.CREATE, + TPrivilegeLevel.INSERT), onColumn("functional", "alltypes", "int_col", + TPrivilegeLevel.ALL)) + .error(createError("functional.new_table")) + .error(createError("functional.new_table"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT, + TPrivilegeLevel.SELECT))) + .error(createError("functional.new_table"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT, + TPrivilegeLevel.SELECT))) + .error(createError("functional.new_table"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT)), + onTable("functional", "alltypes", TPrivilegeLevel.SELECT)) + .error(selectError("functional.alltypes"), onDatabase("functional", + TPrivilegeLevel.CREATE, TPrivilegeLevel.INSERT), onTable("functional", + "alltypes", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))); + } // Table with a specific location. authorize("create table functional.new_table(i int) location " + @@ -1562,6 +1627,446 @@ public class AuthorizationStmtTest extends FrontendTestBase { .error(systemDbError(), onServer(TPrivilegeLevel.ALL)); } + @Test + public void testAlterTable() throws ImpalaException { + for (AuthzTest test: new AuthzTest[]{ + authorize("alter table functional.alltypes add columns(c1 int)"), + authorize("alter table functional.alltypes replace columns(c1 int)"), + authorize("alter table functional.alltypes change int_col c1 int"), + authorize("alter table functional.alltypes drop int_col"), + authorize("alter table functional.alltypes set fileformat parquet"), + authorize("alter table functional.alltypes set tblproperties('a'='b')"), + authorize("alter table functional.alltypes partition(year=2009) " + + "set tblproperties('a'='b')"), + authorize("alter table functional.alltypes set cached in 'testPool'"), + authorize("alter table functional.alltypes partition(year=2009) set cached " + + "in 'testPool'"), + authorize("alter table functional.alltypes sort by (id)"), + authorize("alter table functional.alltypes set column stats int_col " + + "('numNulls'='1')"), + authorize("alter table functional.alltypes recover partitions"), + authorize("alter table functional.alltypes set row format delimited fields " + + "terminated by ' '"), + authorize("alter table functional.alltypes partition(year=2009) set row format " + + "delimited fields terminated by ' '"), + authorize("alter table functional.alltypes add partition(year=1, month=1)"), + authorize("alter table functional.alltypes drop partition(" + + "year=2009, month=1)")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER)) + .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALTER)) + .error(alterError("functional.alltypes")) + .error(alterError("functional.alltypes"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.alltypes"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.alltypes"), onTable("functional", "alltypes", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + } + + // Alter table rename. + authorize("alter table functional.alltypes rename to functional.new_table") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE)) + .ok(onDatabase("functional", TPrivilegeLevel.CREATE), onTable("functional", + "alltypes", TPrivilegeLevel.ALTER)) + .error(alterError("functional.alltypes")) + .error(alterError("functional.alltypes"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE))) + .error(alterError("functional.alltypes"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE))) + .error(alterError("functional.alltypes"), onDatabase("functional", + TPrivilegeLevel.CREATE), onTable("functional", "alltypes", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(createError("functional.new_table"), onDatabase("functional", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE)), + onTable("functional", "alltypes", TPrivilegeLevel.ALTER)); + + // Only for Kudu tables. + for (AuthzTest test: new AuthzTest[]{ + authorize("alter table functional_kudu.testtbl alter column " + + "name drop default"), + authorize("alter table functional_kudu.testtbl alter column name " + + "set default null"), + authorize("alter table functional_kudu.testtbl add range partition " + + "1 < values < 2"), + authorize("alter table functional_kudu.testtbl drop range partition " + + "1 < values < 2")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER)) + .ok(onDatabase("functional_kudu", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional_kudu", TPrivilegeLevel.ALTER)) + .ok(onTable("functional_kudu", "testtbl", TPrivilegeLevel.ALL)) + .ok(onTable("functional_kudu", "testtbl", TPrivilegeLevel.ALTER)) + .error(alterError("functional_kudu.testtbl")) + .error(alterError("functional_kudu.testtbl"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional_kudu.testtbl"), onDatabase("functional_kudu", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional_kudu.testtbl"), onTable("functional_kudu", + "testtbl", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + } + + // Alter table set location. + for (AuthzTest test: new AuthzTest[] { + authorize("alter table functional.alltypes set location " + + "'hdfs://localhost:20500/test-warehouse/new_table'"), + authorize("alter table functional.alltypes partition(year=2009, month=1) " + + "set location 'hdfs://localhost:20500/test-warehouse/new_table'")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER), onUri( + "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL), onUri( + "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER), onUri( + "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL)) + .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALL), onUri( + "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL)) + .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALTER), onUri( + "hdfs://localhost:20500/test-warehouse/new_table", TPrivilegeLevel.ALL)) + .error(alterError("functional.alltypes")) + .error(alterError("functional.alltypes"), + onServer(allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)), + onUri("hdfs://localhost:20500/test-warehouse/new_table")) + .error(alterError("functional.alltypes"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)), + onUri("hdfs://localhost:20500/test-warehouse/new_table")) + .error(alterError("functional.alltypes"), onTable("functional", "alltypes", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER)), + onUri("hdfs://localhost:20500/test-warehouse/new_table")) + .error(accessError("hdfs://localhost:20500/test-warehouse/new_table"), + onDatabase("functional", TPrivilegeLevel.ALTER)) + .error(accessError("hdfs://localhost:20500/test-warehouse/new_table"), + onTable("functional", "alltypes", TPrivilegeLevel.ALTER)); + } + + // Database does not exist. + authorize("alter table nodb.alltypes add columns(c1 int)") + .error(alterError("nodb")) + .error(alterError("nodb"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + + // Table does not exist. + authorize("alter table functional.notbl add columns(c1 int)") + .error(alterError("functional.notbl")) + .error(alterError("functional.notbl"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.notbl"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + } + + @Test + public void testAlterView() throws ImpalaException { + for (AuthzTest test: new AuthzTest[] { + authorize("alter view functional.alltypes_view as " + + "select int_col from functional.alltypes"), + authorize("alter view functional.alltypes_view(a) as " + + "select int_col from functional.alltypes")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER), onTable("functional", "alltypes", + TPrivilegeLevel.SELECT)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, + TPrivilegeLevel.SELECT)) + .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER), + onTable("functional", "alltypes", TPrivilegeLevel.SELECT)) + .error(selectError("functional.alltypes")) + .error(selectError("functional.alltypes"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.SELECT))) + .error(selectError("functional.alltypes"), onDatabase("functional", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, + TPrivilegeLevel.SELECT))) + .error(alterError("functional.alltypes_view"), onTable("functional", "alltypes", + TPrivilegeLevel.SELECT), onTable("functional", "alltypes_view", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(selectError("functional.alltypes"), onTable("functional", "alltypes", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT)), + onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER)); + } + + // Alter view rename. + authorize("alter view functional.alltypes_view rename to functional.new_view") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE)) + .ok(onDatabase("functional", TPrivilegeLevel.CREATE), onTable("functional", + "alltypes_view", TPrivilegeLevel.ALTER)) + .error(alterError("functional.alltypes_view")) + .error(alterError("functional.alltypes_view"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE))) + .error(alterError("functional.alltypes_view"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER, TPrivilegeLevel.CREATE))) + .error(alterError("functional.alltypes_view"), onDatabase("functional", + TPrivilegeLevel.CREATE), onTable("functional", "alltypes_view", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(createError("functional.new_view"), onDatabase("functional", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.CREATE)), + onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER)); + + // Alter view with constant select. + authorize("alter view functional.alltypes_view as select 1") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER)) + .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALL)) + .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER)) + .error(alterError("functional.alltypes_view")) + .error(alterError("functional.alltypes_view"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.alltypes_view"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.alltypes_view"), onTable("functional", + "alltypes_view", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + + // Database does not exist. + authorize("alter view nodb.alltypes_view as select 1") + .error(alterError("nodb")) + .error(alterError("nodb"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + + // View does not exist. + authorize("alter view functional.noview as select 1") + .error(alterError("functional.noview")) + .error(alterError("functional.noview"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.noview"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + } + + @Test + public void testAlterDatabase() throws ImpalaException { + for (String ownerType: new String[]{"user", "role"}) { + authorize(String.format("alter database functional set owner %s foo", ownerType)) + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER)) + .error(alterError("functional")) + .error(alterError("functional"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + + // Database does not exist. + authorize(String.format("alter database nodb set owner %s foo", ownerType)) + .error(alterError("nodb")) + .error(alterError("nodb"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + } + } + + @Test + public void testUpdate() throws ImpalaException { + // Update is only supported on Kudu tables. + for (AuthzTest test: new AuthzTest[]{ + authorize("update functional_kudu.alltypes set int_col = 1"), + // Explain update. + authorize("explain update functional_kudu.alltypes set int_col = 1")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .error(accessError("functional_kudu.alltypes")) + .error(accessError("functional_kudu.alltypes"), onServer(allExcept( + TPrivilegeLevel.ALL))); + } + + // Database does not exist. + authorize("update nodb.alltypes set int_col = 1") + .error(selectError("nodb")) + .error(selectError("nodb"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))); + + // Table does not exist. + authorize("update functional_kudu.notbl set int_col = 1") + .error(selectError("functional_kudu.notbl")) + .error(selectError("functional_kudu.notbl"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))) + .error(selectError("functional_kudu.notbl"), onDatabase("functional_kudu", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))); + } + + @Test + public void testUpsert() throws ImpalaException { + // Upsert is only supported on Kudu tables. + for (AuthzTest test: new AuthzTest[]{ + authorize("upsert into table functional_kudu.testtbl(id, name) values(1, 'a')"), + // Upsert with clause. + authorize("with t1 as (select 1, 'a', 2) upsert into functional_kudu.testtbl " + + "select * from t1"), + // Explain upsert. + authorize("explain upsert into table functional_kudu.testtbl(id, name) " + + "values(1, 'a')")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .error(accessError("functional_kudu.testtbl")) + .error(accessError("functional_kudu.testtbl"), onServer(allExcept( + TPrivilegeLevel.ALL))); + } + + // Upsert select. + authorize("upsert into table functional_kudu.testtbl(id) " + + "select int_col from functional.alltypes") + .ok(onServer(TPrivilegeLevel.ALL)) + .error(selectError("functional.alltypes")) + .error(accessError("functional_kudu.testtbl"), onServer(allExcept( + TPrivilegeLevel.ALL))); + + // Database does not exist. + authorize("upsert into table nodb.testtbl(id, name) values(1, 'a')") + .error(accessError("nodb.testtbl")) + .error(accessError("nodb.testtbl"), onServer(allExcept(TPrivilegeLevel.ALL))); + + // Table does not exist. + authorize("upsert into table functional_kudu.notbl(id, name) values(1, 'a')") + .error(accessError("functional_kudu.notbl")) + .error(accessError("functional_kudu.notbl"), onServer(allExcept( + TPrivilegeLevel.ALL))) + .error(accessError("functional_kudu.notbl"), onDatabase("functional_kudu", + allExcept(TPrivilegeLevel.ALL))); + } + + @Test + public void testDelete() throws ImpalaException { + // Delete is only supported on Kudu tables. + for (AuthzTest test: new AuthzTest[]{ + authorize("delete from functional_kudu.alltypes"), + authorize("explain delete from functional_kudu.alltypes")}) { + test.ok(onServer(TPrivilegeLevel.ALL)) + .error(accessError("functional_kudu.alltypes")) + .error(accessError("functional_kudu.alltypes"), onServer(allExcept( + TPrivilegeLevel.ALL))); + } + + // Database does not exist. + authorize("delete from nodb.alltypes") + .error(selectError("nodb")) + .error(selectError("nodb"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))); + + // Table does not exist. + authorize("delete from functional_kudu.notbl") + .error(selectError("functional_kudu.notbl")) + .error(selectError("functional_kudu.notbl"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))) + .error(selectError("functional_kudu.notbl"), onDatabase("functional_kudu", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.SELECT))); + } + + @Test + public void testCommentOn() throws ImpalaException { + // Comment on database. + authorize("comment on database functional is 'comment'") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER)) + .error(alterError("functional")) + .error(alterError("functional"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + + // Comment on table. + authorize("comment on table functional.alltypes is 'comment'") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER)) + .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALL)) + .ok(onTable("functional", "alltypes", TPrivilegeLevel.ALTER)) + .error(alterError("functional.alltypes")) + .error(alterError("functional.alltypes"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.alltypes"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.alltypes"), onTable("functional", "alltypes", + allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + + // Comment on view. + authorize("comment on view functional.alltypes_view is 'comment'") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.ALTER)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALTER)) + .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALL)) + .ok(onTable("functional", "alltypes_view", TPrivilegeLevel.ALTER)) + .error(alterError("functional.alltypes_view")) + .error(alterError("functional.alltypes_view"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.alltypes_view"), onDatabase("functional", allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))) + .error(alterError("functional.alltypes_view"), onTable("functional", + "alltypes_view", allExcept(TPrivilegeLevel.ALL, TPrivilegeLevel.ALTER))); + } + + @Test + public void testFunction() throws ImpalaException { + // Create function. + authorize("create function functional.f() returns int location " + + "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.CREATE), onUri("/test-warehouse/libTestUdfs.so", + TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL), + onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.CREATE), + onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL)) + .error(createFunctionError("functional.f()")) + .error(accessError("hdfs://localhost:20500/test-warehouse/libTestUdfs.so"), + onServer(allExcept(TPrivilegeLevel.ALL))) + .error(createFunctionError("functional.f()"), + onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL)); + + // Create a function name that has the same name as built-in function is OK. + authorize("create function functional.sin() returns int location " + + "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.CREATE), onUri("/test-warehouse/libTestUdfs.so", + TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL), + onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.CREATE), + onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL)) + .error(createFunctionError("functional.sin()")) + .error(accessError("hdfs://localhost:20500/test-warehouse/libTestUdfs.so"), + onServer(allExcept(TPrivilegeLevel.ALL))) + .error(createFunctionError("functional.sin()"), + onUri("/test-warehouse/libTestUdfs.so", TPrivilegeLevel.ALL)); + + // Creating a function in the system database even with ALL privilege on SERVER is + // not allowed. + for (AuthzTest test: new AuthzTest[] { + authorize("create function _impala_builtins.sin() returns int location " + + "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'"), + authorize("create function _impala_builtins.f() returns int location " + + "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'")}) { + test.error(systemDbError(), onServer(TPrivilegeLevel.ALL)); + } + + ScalarFunction fn = addFunction("functional", "f"); + try { + authorize("drop function functional.f()") + .ok(onServer(TPrivilegeLevel.ALL)) + .ok(onServer(TPrivilegeLevel.DROP)) + .ok(onDatabase("functional", TPrivilegeLevel.ALL)) + .ok(onDatabase("functional", TPrivilegeLevel.DROP)) + .error(dropFunctionError("functional.f()")) + .error(dropFunctionError("functional.f()"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.DROP))); + + // Function does not exist but with if exists clause. + authorize("drop function if exists functional.g()") + .error(dropFunctionError("functional.g()")) + .error(dropFunctionError("functional.g()"), onServer(allExcept( + TPrivilegeLevel.ALL, TPrivilegeLevel.DROP))); + } finally { + removeFunction(fn); + } + } + // Convert TDescribeResult to list of strings. private static List<String> resultToStringList(TDescribeResult result) { List<String> list = new ArrayList<>(); @@ -1606,6 +2111,14 @@ public class AuthorizationStmtTest extends FrontendTestBase { return "Cannot modify system database."; } + private static String createFunctionError(String object) { + return "User '%s' does not have privileges to CREATE functions in: " + object; + } + + private static String dropFunctionError(String object) { + return "User '%s' does not have privileges to DROP functions in: " + object; + } + private ScalarFunction addFunction(String db, String fnName) { ScalarFunction fn = ScalarFunction.createForTesting(db, fnName, new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, diff --git a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java index a684847..106a59d 100644 --- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java +++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java @@ -21,13 +21,11 @@ import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.UUID; import org.apache.hadoop.conf.Configuration; @@ -38,11 +36,8 @@ import org.apache.impala.authorization.AuthorizationConfig; import org.apache.impala.authorization.AuthorizeableTable; import org.apache.impala.authorization.User; import org.apache.impala.catalog.AuthorizationException; -import org.apache.impala.catalog.Db; import org.apache.impala.catalog.FeDb; import org.apache.impala.catalog.ImpaladCatalog; -import org.apache.impala.catalog.ScalarFunction; -import org.apache.impala.catalog.Type; import org.apache.impala.common.AnalysisException; import org.apache.impala.common.FrontendTestBase; import org.apache.impala.common.ImpalaException; @@ -50,20 +45,14 @@ import org.apache.impala.common.InternalException; import org.apache.impala.common.RuntimeEnv; import org.apache.impala.service.Frontend; import org.apache.impala.testutil.ImpaladTestCatalog; -import org.apache.impala.thrift.TColumnValue; -import org.apache.impala.thrift.TDescribeOutputStyle; -import org.apache.impala.thrift.TDescribeResult; -import org.apache.impala.thrift.TFunctionBinaryType; import org.apache.impala.thrift.TMetadataOpRequest; import org.apache.impala.thrift.TMetadataOpcode; import org.apache.impala.thrift.TNetworkAddress; import org.apache.impala.thrift.TPrivilege; import org.apache.impala.thrift.TPrivilegeLevel; import org.apache.impala.thrift.TPrivilegeScope; -import org.apache.impala.thrift.TResultRow; import org.apache.impala.thrift.TResultSet; import org.apache.impala.thrift.TSessionState; -import org.apache.impala.thrift.TTableName; import org.apache.impala.util.PatternMatcher; import org.apache.impala.util.SentryPolicyService; import org.apache.sentry.provider.common.ResourceAuthorizationProvider; @@ -596,1545 +585,6 @@ public class AuthorizationTest extends FrontendTestBase { } @Test - public void TestSelect() throws ImpalaException { - // Can select from table that user has privileges on. - AuthzOk("select * from functional.alltypesagg"); - - AuthzOk("select * from functional_seq_snap.alltypes"); - - // Can select from view that user has privileges on even though he/she doesn't - // have privileges on underlying tables. - AuthzOk("select * from functional.complex_view"); - - // User has permission to select the view but not on the view (alltypes_view) - // referenced in its view definition. - AuthzOk("select * from functional.view_view"); - - // User does not have SELECT privileges on this view. - AuthzError("select * from functional.alltypes_view", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes_view"); - - // User has SELECT privileges on the view and the join table. - AuthzOk("select a.id from functional.view_view a " - + "join functional.alltypesagg b ON (a.id = b.id)"); - - // User has SELECT privileges on the view, but does not have privileges - // to select join table. - AuthzError("select a.id from functional.view_view a " - + "join functional.alltypes b ON (a.id = b.id)", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // Tests authorization after a statement has been rewritten (IMPALA-3915). - // User has SELECT privileges on the view which contains a subquery. - AuthzOk("select * from functional_seq_snap.subquery_view"); - - // User does not have SELECT privileges on the view which contains a subquery. - AuthzError("select * from functional_rc.subquery_view", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional_rc.subquery_view"); - - // Constant select. - AuthzOk("select 1"); - - // Unqualified table name. - AuthzError("select * from alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: default.alltypes"); - - // Select with no privileges on table. - AuthzError("select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // Select without referencing a column. - AuthzError("select 1 from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // Select from non-existent table. - AuthzError("select 1 from functional.notbl", - "User '%s' does not have privileges to execute 'SELECT' on: functional.notbl"); - - // Select from non-existent db. - AuthzError("select 1 from nodb.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: nodb.alltypes"); - - // Table within inline view is authorized properly. - AuthzError("select a.* from (select * from functional.alltypes) a", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - // Table within inline view is authorized properly (user has permission). - AuthzOk("select a.* from (select * from functional.alltypesagg) a"); - - // User has SELECT privileges on all the columns of 'alltypestiny' - AuthzOk("select * from functional.alltypestiny"); - - // No SELECT privileges on all the columns of 'alltypessmall' - AuthzError("select * from functional.alltypessmall", "User '%s' does " + - "not have privileges to execute 'SELECT' on: functional.alltypessmall"); - - // No SELECT privileges on table 'alltypessmall' - AuthzError("select count(*) from functional.alltypessmall", "User '%s' does " + - "not have privileges to execute 'SELECT' on: functional.alltypessmall"); - AuthzError("select 1 from functional.alltypessmall", "User '%s' does not " + - "have privileges to execute 'SELECT' on: functional.alltypessmall"); - AuthzOk("select 1, id from functional.alltypessmall"); - - // No SELECT privileges on column 'month' - AuthzError("select id, int_col, year, month from functional.alltypessmall", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypessmall"); - - // User has column-level privileges on all referenced columns - AuthzOk("select id, count(int_col) from functional.alltypessmall where " + - "year = 2010 group by id"); - - // No SELECT privileges on 'int_array_col' - AuthzError("select a.id, b.item from functional.allcomplextypes a, " + - "a.int_array_col b", "User '%s' does not have privileges to execute " + - "'SELECT' on: functional.allcomplextypes"); - - // Sufficient column-level privileges on both scalar and nested columns - AuthzOk("select a.int_struct_col.f1 from functional.allcomplextypes a " + - "where a.id = 1"); - AuthzOk("select pos, item.f1, f2 from functional.allcomplextypes t, " + - "t.struct_array_col"); - AuthzOk("select * from functional.allcomplextypes.struct_array_col"); - AuthzOk("select key from functional.allcomplextypes.int_map_col"); - AuthzOk("select id, b.key from functional.allcomplextypes a, a.int_map_col b"); - - // No SELECT privileges on 'alltypessmall' - AuthzError("select a.* from functional.alltypesagg a cross join " + - "functional.alltypessmall b", "User '%s' does not have privileges to execute " + - "'SELECT' on: functional.alltypessmall"); - - // User has SELECT privileges on all columns referenced in the inline view - AuthzOk("select * from (select id, int_col from functional.alltypessmall) v"); - } - - @Test - public void TestUnion() throws ImpalaException { - AuthzOk("select * from functional.alltypesagg union all " + - "select * from functional.alltypesagg"); - - AuthzError("select * from functional.alltypesagg union all " + - "select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - AuthzOk("select id, int_col, year from functional.alltypessmall union all " + - "select id, int_col, year from functional.alltypestiny"); - - AuthzError("select * from functional.alltypessmall union all " + - "select * from functional.alltypestiny", "User '%s' does not have privileges " + - "to execute 'SELECT' on: functional.alltypessmall"); - } - - @Test - public void TestInsert() throws ImpalaException { - AuthzOk("insert into functional_parquet.alltypes " + - "partition(month,year) select * from functional_seq_snap.alltypes"); - - // Insert + inline view (user has permissions). - AuthzOk("insert into functional.alltypes partition(month,year) " + - "select b.* from functional.alltypesagg a join (select * from " + - "functional_seq_snap.alltypes) b on (a.int_col = b.int_col)"); - - // User doesn't have INSERT permissions in the target table. - AuthzError("insert into functional.alltypesagg select 1", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypesagg"); - - // User doesn't have INSERT permissions in the target view. - // Inserting into a view is not allowed. - AuthzError("insert into functional.alltypes_view select 1", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypes_view"); - - // User doesn't have SELECT permissions on source table. - AuthzError("insert into functional.alltypes " + - "select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // User doesn't have permissions on source table within inline view. - AuthzError("insert into functional.alltypes partition (month, year) " + - "select id, bool_col, tinyint_col, smallint_col, a.int_col, bigint_col, " + - "float_col, a.double_col, a.date_string_col, a.string_col, a.timestamp_col, " + - "a.year, a.month " + - "from functional_rc.alltypesagg a " + - "join (select int_col, double_col, date_string_col, string_col, timestamp_col, " + - "year, month from functional_seq.alltypes) b " + - "on (a.int_col = b.int_col)", "User '%s' does " + - "not have privileges to execute 'SELECT' on: functional_rc.alltypesagg"); - - // User doesn't have INSERT permissions on the target table but has sufficient SELECT - // permissions on all the referenced columns of the source table - AuthzError("insert into functional.alltypestiny partition (month, year) " + - "select * from functional.alltypestiny", "User '%s' does not have " + - "privileges to execute 'INSERT' on: functional.alltypestiny"); - - // User has INSERT permissions on target table but insufficient column-level - // permissions on the source table - AuthzError("insert into functional.alltypes partition (month, year) " + - "select * from functional.alltypessmall", "User '%s' does not have " + - "privileges to execute 'SELECT' on: functional.alltypessmall"); - - // User has INSERT permissions on the target table and SELECT permissions on - // all the columns of the source table - AuthzOk("insert into functional.alltypes partition (month, year) " + - "select * from functional.alltypestiny where id < 100"); - - // Same as above with a column permutation - AuthzOk("insert into table functional.alltypes" + - "(id, bool_col, string_col, smallint_col, int_col, bigint_col, " + - "float_col, double_col, date_string_col, tinyint_col, timestamp_col) " + - "partition (month, year) select id, bool_col, string_col, smallint_col, " + - "int_col, bigint_col, float_col, double_col, date_string_col, tinyint_col, " + - "timestamp_col, month, year from functional.alltypestiny"); - } - - @Test - public void TestWithClause() throws ImpalaException { - // User has SELECT privileges on table in WITH-clause view. - AuthzOk("with t as (select * from functional.alltypesagg) select * from t"); - // User doesn't have SELECT privileges on table in WITH-clause view. - AuthzError("with t as (select * from functional.alltypes) select * from t", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - // User has SELECT privileges on view in WITH-clause view. - AuthzOk("with t as (select * from functional.complex_view) select * from t"); - - // User has SELECT privileges on table in WITH-clause view in INSERT. - AuthzOk("with t as (select * from functional_seq_snap.alltypes) " + - "insert into functional_parquet.alltypes partition(month,year) select * from t"); - // User doesn't have SELECT privileges on table in WITH-clause view in INSERT. - AuthzError("with t as (select * from functional_parquet.alltypes) " + - "insert into functional_parquet.alltypes partition(month,year) select * from t", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional_parquet.alltypes"); - // User doesn't have SELECT privileges on view in WITH-clause view in INSERT. - AuthzError("with t as (select * from functional.alltypes_view) " + - "insert into functional_parquet.alltypes partition(month,year) select * from t", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes_view"); - - // User has SELECT privileges on columns referenced in the WITH-clause view. - AuthzOk("with t as (select id, int_col from functional.alltypessmall) " + - "select * from t"); - - // User does not have SELECT privileges on 'month' - AuthzError("with t as (select id, int_col from functional.alltypessmall " + - "where month = 10) select count(*) from t", "User '%s' does not have " + - "privileges to execute 'SELECT' on: functional.alltypessmall"); - } - - @Test - public void TestExplain() throws ImpalaException { - AuthzOk("explain select * from functional.alltypesagg"); - AuthzOk("explain insert into functional_parquet.alltypes " + - "partition(month,year) select * from functional_seq_snap.alltypes"); - - // Select without permissions. - AuthzError("explain select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // Insert with no select permissions on source table. - AuthzError("explain insert into functional_parquet.alltypes " + - "partition(month,year) select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - // Insert, user doesn't have permissions on source table. - AuthzError("explain insert into functional.alltypes " + - "select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // Test explain on views. User has permissions on all the underlying tables. - AuthzOk("explain select * from functional_seq_snap.alltypes_view"); - AuthzOk("explain insert into functional_parquet.alltypes " + - "partition(month,year) select * from functional_seq_snap.alltypes_view"); - - // Select on view without permissions on view. - AuthzError("explain select * from functional.alltypes_view", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes_view"); - // Insert into view without permissions on view. - AuthzError("explain insert into functional.alltypes_view " + - "select * from functional_seq_snap.alltypes ", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypes_view"); - - // User has permission on view, but not on underlying tables. - AuthzError("explain select * from functional.complex_view", - "User '%s' does not have privileges to EXPLAIN this statement."); - // User has permission on view in WITH clause, but not on underlying tables. - AuthzError("explain with t as (select * from functional.complex_view) " + - "select * from t", - "User '%s' does not have privileges to EXPLAIN this statement."); - - // User has permission on view in WITH clause, but not on underlying tables. - AuthzError("explain with t as (select * from functional.complex_view) " + - "select * from t", - "User '%s' does not have privileges to EXPLAIN this statement."); - // User has permission on view and on view inside view, - // but not on tables in view inside view. - AuthzError("explain select * from functional.view_view", - "User '%s' does not have privileges to EXPLAIN this statement."); - // User doesn't have permission on tables in view inside view. - AuthzError("explain insert into functional_seq_snap.alltypes " + - "partition(month,year) select * from functional.view_view", - "User '%s' does not have privileges to EXPLAIN this statement."); - - // User has SELECT privileges on the view, but does not have privileges - // to select join table. Should get standard auth message back. - AuthzError("explain select a.id from functional.view_view a " - + "join functional.alltypes b ON (a.id = b.id)", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // User has privileges on tables inside the first view, but not the second - // view. Should get masked auth error back. - AuthzError("explain select a.id from functional.view_view a " - + "join functional.complex_view b ON (a.id = b.id)", - "User '%s' does not have privileges to EXPLAIN this statement."); - - // User has SELECT privileges on all referenced columns - AuthzOk("explain select * from functional.alltypestiny"); - - // User doesn't have SELECT privileges on all referenced columns - AuthzError("explain select * from functional.alltypessmall", "User '%s' " + - "does not have privileges to execute 'SELECT' on: functional.alltypessmall"); - } - - @Test - public void TestUseDb() throws ImpalaException { - // Positive cases (user has privileges on these tables). - AuthzOk("use functional"); - AuthzOk("use functional_avro"); // Database with only column privileges. - AuthzOk("use tpcds"); - AuthzOk("use tpch"); - - // Should always be able to use default, even if privilege was not explicitly - // granted. - AuthzOk("use default"); - - AuthzError("use functional_seq", - "User '%s' does not have privileges to access: functional_seq.*"); - - // Database does not exist, user does not have access. - AuthzError("use nodb", - "User '%s' does not have privileges to access: nodb.*"); - - // Database does not exist, user has access: - try { - AuthzOk("use newdb"); - fail("Expected AnalysisException"); - } catch (AnalysisException e) { - Assert.assertEquals(e.getMessage(), "Database does not exist: newdb"); - } - - // All users should be able to use the system db. - AuthzOk("use _impala_builtins"); - } - - @Test - public void TestResetMetadata() throws ImpalaException { - // Positive cases (user has REFRESH privilege on these tables/views). - AuthzOk("invalidate metadata functional.alltypesagg"); - AuthzOk("refresh functional.alltypesagg"); - AuthzOk("invalidate metadata functional.view_view"); - AuthzOk("refresh functional.view_view"); - // Positive cases for checking refresh partition - AuthzOk("refresh functional.alltypesagg partition (year=2010, month=1, day=1)"); - AuthzOk("refresh functional_seq_snap.alltypes partition (year=2009, month=1)"); - // User has REFRESH privilege on functional_text_lzo database, = - // but no privilege at the table level. - AuthzOk("invalidate metadata functional_text_lzo.alltypes"); - AuthzOk("refresh functional_text_lzo.alltypes"); - AuthzOk("refresh functions functional_text_lzo"); - - AuthzError("invalidate metadata unknown_db.alltypessmall", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: unknown_db.alltypessmall"); - AuthzError("invalidate metadata functional_seq.alltypessmall", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional_seq.alltypessmall"); - AuthzError("invalidate metadata functional.alltypes_view", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional.alltypes_view"); - AuthzError("invalidate metadata functional.unknown_table", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional.unknown_table"); - AuthzError("invalidate metadata functional.alltypessmall", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional.alltypessmall"); - AuthzError("refresh functional.alltypessmall", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional.alltypessmall"); - AuthzError("refresh functional.alltypes_view", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional.alltypes_view"); - // Only column-level privileges on the table - AuthzError("invalidate metadata functional.alltypestiny", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional.alltypestiny"); - // Only column-level privileges on the table - AuthzError("refresh functional.alltypestiny", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional.alltypestiny"); - - AuthzError("invalidate metadata", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: server"); - AuthzError( - "refresh functional_rc.alltypesagg partition (year=2010, month=1, day=1)", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional_rc.alltypesagg"); - AuthzError( - "refresh functional_rc.alltypesagg partition (year=2010, month=1, day=9999)", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional_rc.alltypesagg"); - AuthzError("refresh functions functional_rc", - "User '%s' does not have privileges to execute 'INVALIDATE METADATA/REFRESH' " + - "on: functional_rc"); - - // TODO: Add test support for dynamically changing privileges for - // file-based policy. - if (ctx_.authzConfig.isFileBasedPolicy()) return; - SentryPolicyService sentryService = createSentryService(); - - try { - sentryService.grantRoleToGroup(USER, "admin", USER.getName()); - ctx_.catalog.reset(); - AuthzOk("invalidate metadata"); - AuthzOk("invalidate metadata functional.testtbl"); - AuthzOk("refresh functional.testtbl"); - AuthzOk("refresh functional.alltypesagg partition (year=2010, month=1, day=1)"); - AuthzOk("refresh functions functional"); - } finally { - sentryService.revokeRoleFromGroup(USER, "admin", USER.getName()); - ctx_.catalog.reset(); - } - - // User has REFRESH privilege on server. - String roleName = "refresh_role"; - try { - sentryService.createRole(USER, roleName, true); - TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.REFRESH, - TPrivilegeScope.SERVER, false); - privilege.setServer_name("server1"); - sentryService.grantRolePrivilege(USER, roleName, privilege); - sentryService.grantRoleToGroup(USER, roleName, USER.getName()); - ctx_.catalog.reset(); - AuthzOk("invalidate metadata"); - AuthzOk("invalidate metadata functional.testtbl"); - AuthzOk("refresh functional.testtbl"); - AuthzOk("refresh functional.alltypesagg partition (year=2010, month=1, day=1)"); - AuthzOk("refresh functions functional"); - } finally { - sentryService.dropRole(USER, roleName, true); - ctx_.catalog.reset(); - } - } - - @Test - public void TestCreateTable() throws ImpalaException { - AuthzOk("create table tpch.new_table (i int)"); - AuthzOk("create table tpch.new_lineitem like tpch.lineitem"); - // Create table IF NOT EXISTS, user has permission and table exists. - AuthzOk("create table if not exists tpch.lineitem (i int)"); - try { - AuthzOk("create table tpch.lineitem (i int)"); - fail("Expected analysis error."); - } catch (AnalysisException e) { - Assert.assertEquals(e.getMessage(), "Table already exists: tpch.lineitem"); - } - // User has CREATE privilege on functional_text_lzo database. - AuthzOk("create table functional_text_lzo.new_table (i int)"); - - // Create table AS SELECT positive and negative cases for SELECT privilege. - AuthzOk("create table tpch.new_table as select * from functional.alltypesagg"); - // User has CREATE and INSERT privileges on functional_text_lzo database and SELECT - // privilege on functional.alltypesagg table. - AuthzOk("create table functional_text_lzo.new_table as " + - "select * from functional.alltypesagg"); - AuthzError("create table tpch.new_table as select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - // User has CREATE privilege on functional_text_lzo database, SELECT privilege on - // functional.alltypes table but no INSERT privilege on functional_text_lzo database. - AuthzError("create table functional_text_lzo.new_table as " + - "select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // CTAS with a subquery. - AuthzOk("create table tpch.new_table as select * from functional.alltypesagg " + - "where id < (select max(year) from functional.alltypesagg)"); - - AuthzError("create table functional.tbl tblproperties('a'='b')" + - " as select 1", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional.tbl"); - - // Create table IF NOT EXISTS, user does not have permission and table exists. - AuthzError("create table if not exists functional_seq.alltypes (i int)", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional_seq.alltypes"); - - // User has permission to create at given location. - AuthzOk("create table tpch.new_table (i int) location " + - "'hdfs://localhost:20500/test-warehouse/new_table'"); - - // No permissions on source table. - AuthzError("create table tpch.new_lineitem like tpch_seq.lineitem", - "User '%s' does not have privileges to access: tpch_seq.lineitem"); - - // No permissions on target table. - AuthzError("create table tpch_rc.new like tpch.lineitem", - "User '%s' does not have privileges to execute 'CREATE' on: tpch_rc.new"); - - // Unqualified table name. - AuthzError("create table new_table (i int)", - "User '%s' does not have privileges to execute 'CREATE' on: default.new_table"); - - // Table already exists (user does not have permission). - AuthzError("create table functional.alltypes (i int)", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional.alltypes"); - - // Database does not exist, user does not have access. - AuthzError("create table nodb.alltypes (i int)", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "nodb.alltypes"); - - // IMPALA-4000: Only users with ALL privileges on SERVER may create external Kudu - // tables. - AuthzError("create external table tpch.kudu_tbl stored as kudu " + - "TBLPROPERTIES ('kudu.master_addresses'='127.0.0.1', 'kudu.table_name'='tbl')", - "User '%s' does not have privileges to access: server1"); - AuthzError("create table tpch.kudu_tbl (i int, j int, primary key (i))" + - " PARTITION BY HASH (i) PARTITIONS 9 stored as kudu TBLPROPERTIES " + - "('kudu.master_addresses'='127.0.0.1')", - "User '%s' does not have privileges to access: server1"); - - // IMPALA-4000: ALL privileges on SERVER are not required to create managed tables. - AuthzOk("create table tpch.kudu_tbl (i int, j int, primary key (i))" + - " PARTITION BY HASH (i) PARTITIONS 9 stored as kudu"); - - // IMPALA-6451: CTAS for Kudu tables on non-external tables and without - // TBLPROPERTIES ('kudu.master_addresses') should not require ALL privileges - // on SERVER. - // User has ALL privilege on tpch database and SELECT privilege on - // functional.alltypesagg table. - // The statement below causes the SQL statement to be rewritten. - AuthzOk("create table tpch.kudu_tbl primary key (bigint_col) stored as kudu as " + - "select bigint_col, string_col, current_timestamp() as ins_date " + - "from functional.alltypesagg " + - "where exists (select 1 from functional.alltypesagg)"); - - // User does not have permission to create table at the specified location.. - AuthzError("create table tpch.new_table (i int) location " + - "'hdfs://localhost:20500/test-warehouse/alltypes'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/alltypes"); - - AuthzError("create table _impala_builtins.tbl(i int)", - "Cannot modify system database."); - - // Check that create like file follows authorization rules for HDFS files - AuthzError("create table tpch.table_DNE like parquet " - + "'hdfs://localhost:20500/test-warehouse/alltypes'", - "User '%s' does not have privileges to access: " - + "hdfs://localhost:20500/test-warehouse/alltypes"); - - // Sufficient column-level privileges in the source table - AuthzOk("create table tpch.new_table as select id, int_col from " + - "functional.alltypessmall where year = 2010"); - - // Insufficient column-level privileges in the source table - AuthzError("create table tpch.new as select * from functional.alltypessmall", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypessmall"); - - // No permissions on target table but sufficient column-level privileges in the - // source table - AuthzError("create table tpch_rc.new_tbl as select * from functional.alltypestiny", - "User '%s' does not have privileges to execute 'CREATE' on: tpch_rc.new_tbl"); - - // Try creating an external table on a URI with upper case letters - AuthzOk("create external table tpch.upper_case (a int) location " + - "'hdfs://localhost:20500/test-warehouse/UPPER_CASE/test'"); - - // Try creating table on the same URI in lower case. It should fail - AuthzError("create external table tpch.upper_case (a int) location " + - "'hdfs://localhost:20500/test-warehouse/upper_case/test'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/upper_case/test"); - } - - @Test - public void TestCreateView() throws ImpalaException { - AuthzOk("create view tpch.new_view as select * from functional.alltypesagg"); - AuthzOk("create view tpch.new_view (a, b, c) as " + - "select int_col, string_col, timestamp_col from functional.alltypesagg"); - // User has CREATE and INSERT privileges on functional_text_lzo database and - // SELECT privilege on functional.alltypesagg table. - AuthzOk("create view functional_text_lzo.new_view as " + - "select * from functional.alltypesagg"); - // Create view IF NOT EXISTS, user has permission and table exists. - AuthzOk("create view if not exists tpch.lineitem as " + - "select * from functional.alltypesagg"); - // Create view IF NOT EXISTS, user has permission and table/view exists. - try { - AuthzOk("create view tpch.lineitem as select * from functional.alltypesagg"); - fail("Expected analysis error."); - } catch (AnalysisException e) { - Assert.assertEquals(e.getMessage(), "Table already exists: tpch.lineitem"); - } - - // Create view IF NOT EXISTS, user does not have permission and table/view exists. - AuthzError("create view if not exists functional_seq.alltypes as " + - "select * from functional.alltypesagg", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional_seq.alltypes"); - - // No permissions on source table. - AuthzError("create view tpch.new_view as select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes"); - - // No permissions on target table. - AuthzError("create view tpch_rc.new as select * from functional.alltypesagg", - "User '%s' does not have privileges to execute 'CREATE' on: tpch_rc.new"); - - // Unqualified view name. - AuthzError("create view new_view as select * from functional.alltypesagg", - "User '%s' does not have privileges to execute 'CREATE' on: default.new_view"); - - // Table already exists (user does not have permission). - AuthzError("create view functional.alltypes_view as " + - "select * from functional.alltypesagg", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional.alltypes_view"); - - // Database does not exist, user does not have access. - AuthzError("create view nodb.alltypes as select * from functional.alltypesagg", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "nodb.alltypes"); - - AuthzError("create view _impala_builtins.new_view as " - + "select * from functional.alltypesagg", - "Cannot modify system database."); - - // User has SELECT privileges on the referenced columns of the source table - AuthzOk("create view tpch.new_view as select * from functional.alltypestiny"); - AuthzOk("create view tpch.new_view as select count(id) from " + - "functional.alltypessmall"); - - // No SELECT permissions on all the referenced columns - AuthzError("create view tpch.new as select id, count(month) from " + - "functional.alltypessmall where int_col = 1 group by id", "User '%s' does " + - "not have privileges to execute 'SELECT' on: functional.alltypessmall"); - } - - @Test - public void TestCreateDatabase() throws ImpalaException { - // Database already exists (no permissions). - AuthzError("create database functional", - "User '%s' does not have privileges to execute 'CREATE' on: functional"); - - // Non existent db (no permissions). - AuthzError("create database nodb", - "User '%s' does not have privileges to execute 'CREATE' on: nodb"); - - // Non existent db (no permissions). - AuthzError("create database if not exists _impala_builtins", - "Cannot modify system database."); - - // TODO: Add test support for dynamically changing privileges for - // file-based policy. - if (ctx_.authzConfig.isFileBasedPolicy()) return; - - SentryPolicyService sentryService = - new SentryPolicyService(ctx_.authzConfig.getSentryConfig()); - try { - sentryService.grantRoleToGroup(USER, "admin", USER.getName()); - ctx_.catalog.reset(); - - // User has permissions to create database. - AuthzOk("create database newdb"); - - // Create database with location specified explicitly (user has permission). - // Since create database requires server-level privileges there should never - // be a case where the user has privileges to create a database does not have - // privileges on the URI. - AuthzOk("create database newdb location " + - "'hdfs://localhost:20500/test-warehouse/new_table'"); - } finally { - sentryService.revokeRoleFromGroup(USER, "admin", USER.getName()); - ctx_.catalog.reset(); - } - } - - @Test - public void TestDropDatabase() throws ImpalaException { - // User has permissions. - AuthzOk("drop database tpch"); - AuthzOk("drop database tpch cascade"); - AuthzOk("drop database tpch restrict"); - // User has permissions, database does not exists and IF EXISTS specified. - AuthzOk("drop database if exists newdb"); - AuthzOk("drop database if exists newdb cascade"); - AuthzOk("drop database if exists newdb restrict"); - - // User has DROP privilege on functional_text_lzo database. - AuthzOk("drop database functional_text_lzo"); - AuthzOk("drop database functional_text_lzo cascade"); - AuthzOk("drop database functional_text_lzo restrict"); - AuthzOk("drop database if exists functional_text_lzo"); - AuthzOk("drop database if exists functional_text_lzo cascade"); - AuthzOk("drop database if exists functional_text_lzo restrict"); - - // User has permission, database does not exists, IF EXISTS not specified. - try { - AuthzOk("drop database newdb"); - fail("Expected analysis error"); - } catch (AnalysisException e) { - Assert.assertEquals(e.getMessage(), "Database does not exist: newdb"); - } - try { - AuthzOk("drop database newdb cascade"); - fail("Expected analysis error"); - } catch (AnalysisException e) { - Assert.assertEquals(e.getMessage(), "Database does not exist: newdb"); - } - try { - AuthzOk("drop database newdb restrict"); - fail("Expected analysis error"); - } catch (AnalysisException e) { - Assert.assertEquals(e.getMessage(), "Database does not exist: newdb"); - } - - // Database exists, user doesn't have permission to drop. - AuthzError("drop database functional", - "User '%s' does not have privileges to execute 'DROP' on: functional"); - AuthzError("drop database if exists functional", - "User '%s' does not have privileges to execute 'DROP' on: functional"); - AuthzError("drop database if exists functional cascade", - "User '%s' does not have privileges to execute 'DROP' on: functional"); - AuthzError("drop database if exists functional restrict", - "User '%s' does not have privileges to execute 'DROP' on: functional"); - - // Database does not exist, user doesn't have permission to drop. - AuthzError("drop database nodb", - "User '%s' does not have privileges to execute 'DROP' on: nodb"); - AuthzError("drop database if exists nodb", - "User '%s' does not have privileges to execute 'DROP' on: nodb"); - AuthzError("drop database if exists nodb cascade", - "User '%s' does not have privileges to execute 'DROP' on: nodb"); - AuthzError("drop database if exists nodb restrict", - "User '%s' does not have privileges to execute 'DROP' on: nodb"); - - AuthzError("drop database _impala_builtins", - "Cannot modify system database."); - } - - @Test - public void TestDropTable() throws ImpalaException { - // Drop table (user has permission). - AuthzOk("drop table tpch.lineitem"); - AuthzOk("drop table if exists tpch.lineitem"); - - // User has DROP privilege on functional.alltypesagg table. - AuthzOk("drop table functional.alltypesagg"); - - // Drop table (user does not have permission). - AuthzError("drop table functional.alltypes", - "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes"); - AuthzError("drop table if exists functional.alltypes", - "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes"); - // Drop table when user only has column-level privileges - AuthzError("drop table if exists functional.alltypestiny", "User '%s' does not " + - "have privileges to execute 'DROP' on: functional.alltypestiny"); - - // Drop table with unqualified table name. - AuthzError("drop table alltypes", - "User '%s' does not have privileges to execute 'DROP' on: default.alltypes"); - - // Drop table with non-existent database. - AuthzError("drop table nodb.alltypes", - "User '%s' does not have privileges to execute 'DROP' on: nodb.alltypes"); - - // Drop table with non-existent table. - AuthzError("drop table functional.notbl", - "User '%s' does not have privileges to execute 'DROP' on: functional.notbl"); - - // Using DROP TABLE on a view does not reveal privileged information. - AuthzError("drop table functional.view_view", - "User '%s' does not have privileges to execute 'DROP' on: functional.view_view"); - - // Using DROP TABLE on a view does not reveal privileged information. - AuthzError("drop table if exists _impala_builtins.tbl", - "Cannot modify system database."); - } - - @Test - public void TestDropView() throws ImpalaException { - // Drop view (user has permission). - AuthzOk("drop view functional_seq_snap.alltypes_view"); - AuthzOk("drop view if exists functional_seq_snap.alltypes_view"); - - // User has DROP privilege on functional.alltypes_view view. - AuthzOk("drop view functional.alltypes_view"); - - // User does not have DROP privilege on functional.alltypes_view_sub view. - AuthzError("drop view functional.alltypes_view_sub", - "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes"); - AuthzError("drop view if exists functional.alltypes_view_sub", - "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes"); - - // Drop view with unqualified table name. - AuthzError("drop view alltypes", - "User '%s' does not have privileges to execute 'DROP' on: default.alltypes"); - - // Drop view with non-existent database. - AuthzError("drop view nodb.alltypes", - "User '%s' does not have privileges to execute 'DROP' on: nodb.alltypes"); - - // Drop view with non-existent table. - AuthzError("drop view functional.notbl", - "User '%s' does not have privileges to execute 'DROP' on: functional.notbl"); - - // Using DROP VIEW on a table does not reveal privileged information. - AuthzError("drop view functional.alltypes", - "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes"); - - // Using DROP VIEW on a table does not reveal privileged information. - AuthzError("drop view _impala_builtins.my_view", - "Cannot modify system database."); - } - - @Test - public void TestTruncate() throws ImpalaException { - AuthzOk("truncate table functional_parquet.alltypes"); - - // User doesn't have INSERT permissions in the target table. - AuthzError("truncate table functional.alltypesagg", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypesagg"); - - // User doesn't have INSERT permissions in the target view. - // Truncating a view is not allowed. - AuthzError("truncate table functional.alltypes_view", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypes_view"); - - // User doesn't have INSERT permissions on the target table but has SELECT permissions - // on all the columns. - AuthzError("truncate table functional.alltypestiny", "User '%s' does not have " + - "privileges to execute 'INSERT' on: functional.alltypestiny"); - } - - @Test - public void TestAlterTable() throws ImpalaException { - // User has permissions to modify tables. - AuthzOk("ALTER TABLE functional_seq_snap.alltypes ADD COLUMNS (c1 int)"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes REPLACE COLUMNS (c1 int)"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes CHANGE int_col c1 int"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes DROP int_col"); - // Note: ALTER ... RENAME requires ALTER privileges at the TABLE level and - // CREATE privileges at the DATABASE level. - AuthzOk("ALTER TABLE functional_seq_snap.alltypes RENAME TO functional_seq_snap.t1"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET FILEFORMAT PARQUET"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " + - "'/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET TBLPROPERTIES " + - "('a'='b', 'c'='d')"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " + - "'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes PARTITION(year=2009, month=1) " + - "SET LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes SET CACHED IN 'testPool'"); - AuthzOk("ALTER TABLE functional_seq_snap.alltypes RECOVER PARTITIONS"); - - // User has ALTER privilege only to modify tables. - AuthzOk("ALTER TABLE functional.alltypeserror ADD COLUMNS (c1 int)"); - AuthzOk("ALTER TABLE functional.alltypeserror REPLACE COLUMNS (c1 int)"); - AuthzOk("ALTER TABLE functional.alltypeserror CHANGE id c1 int"); - AuthzOk("ALTER TABLE functional.alltypeserror DROP id"); - AuthzOk("ALTER TABLE functional.alltypeserror RENAME TO functional_seq_snap.t1"); - AuthzOk("ALTER TABLE functional.alltypeserror SET FILEFORMAT PARQUET"); - AuthzOk("ALTER TABLE functional.alltypeserror SET LOCATION " + - "'/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional.alltypeserror SET TBLPROPERTIES ('a'='b', 'c'='d')"); - AuthzOk("ALTER TABLE functional.alltypeserror SET LOCATION " + - "'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional.alltypeserror PARTITION(year=2009, month=1) " + - "SET LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional.alltypeserror SET CACHED IN 'testPool'"); - AuthzOk("ALTER TABLE functional.alltypeserror RECOVER PARTITIONS"); - - // User has ALTER privilege on functional_text_lzo database. - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror ADD COLUMNS (c1 int)"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror REPLACE COLUMNS (c1 int)"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror CHANGE id c1 int"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror DROP id"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror RENAME TO " + - "functional_seq_snap.t1"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET FILEFORMAT PARQUET"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET LOCATION " + - "'/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET TBLPROPERTIES " + - "('a'='b', 'c'='d')"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET LOCATION " + - "'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror " + - "PARTITION(year=2009, month=1) SET LOCATION " + - "'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror SET CACHED IN 'testPool'"); - AuthzOk("ALTER TABLE functional_text_lzo.alltypeserror RECOVER PARTITIONS"); - - // Alter table and set location to a path the user does not have access to. - // User needs ALTER on table and ALL on URI. - AuthzError("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " + - "'hdfs://localhost:20500/test-warehouse/no_access'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/no_access"); - AuthzError("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " + - "'/test-warehouse/no_access'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/no_access"); - AuthzError("ALTER TABLE functional_seq_snap.alltypes PARTITION(year=2009, month=1) " + - "SET LOCATION '/test-warehouse/no_access'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/no_access"); - - AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " + - "'hdfs://localhost:20500/test-warehouse/no_access'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/no_access"); - AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " + - "'/test-warehouse/no_access'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/no_access"); - AuthzError("ALTER TABLE functional.alltypeserror " + - "PARTITION(year=2009, month=1) SET LOCATION '/test-warehouse/no_access'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/no_access"); - - // Add multiple partitions. User has access to location path. - AuthzOk("ALTER TABLE functional_seq_snap.alltypes ADD " + - "PARTITION(year=2011, month=1) " + - "PARTITION(year=2011, month=2) " + - "LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'"); - // For one new partition location is set to a path the user does not have access to. - AuthzError("ALTER TABLE functional_seq_snap.alltypes ADD " + - "PARTITION(year=2011, month=3) " + - "PARTITION(year=2011, month=4) LOCATION '/test-warehouse/no_access'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/no_access"); - - // Different filesystem, user has permission to base path. - AuthzError("ALTER TABLE functional_seq_snap.alltypes SET LOCATION " + - "'hdfs://localhost:20510/test-warehouse/new_table'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20510/test-warehouse/new_table"); - - // ALTER privilege only. Add multiple partitions. User has access to location path. - AuthzOk("ALTER TABLE functional.alltypeserror ADD " + - "PARTITION(year=2011, month=1) PARTITION(year=2011, month=2) " + - "LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'"); - // ALTER privilege only. For one new partition location is set to a path the user - // does not have access to. - AuthzError("ALTER TABLE functional.alltypeserror ADD " + - "PARTITION(year=2011, month=3) PARTITION(year=2011, month=4) " + - "LOCATION '/test-warehouse/no_access'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/no_access"); - // ALTER privilege only. Different filesystem, user has permission to base path. - AuthzError("ALTER TABLE functional.alltypeserror SET LOCATION " + - "'hdfs://localhost:20510/test-warehouse/new_table'", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20510/test-warehouse/new_table"); - - // User does not have ALTER privilege. - AuthzError("ALTER TABLE functional.alltypes SET FILEFORMAT PARQUET", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes ADD COLUMNS (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes REPLACE COLUMNS (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes CHANGE int_col c1 int", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes DROP int_col", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes rename to functional_seq_snap.t1", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes add partition (year=1, month=1)", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes set cached in 'testPool'", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes set uncached", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("ALTER TABLE functional.alltypes recover partitions", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - - // Trying to ALTER TABLE a view does not reveal any privileged information. - AuthzError("ALTER TABLE functional.view_view SET FILEFORMAT PARQUET", - "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view"); - AuthzError("ALTER TABLE functional.view_view ADD COLUMNS (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view"); - AuthzError("ALTER TABLE functional.view_view REPLACE COLUMNS (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view"); - AuthzError("ALTER TABLE functional.view_view CHANGE int_col c1 int", - "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view"); - AuthzError("ALTER TABLE functional.view_view DROP int_col", - "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view"); - AuthzError("ALTER TABLE functional.view_views rename to functional_seq_snap.t1", - "User '%s' does not have privileges to execute 'ALTER' on: functional.view_view"); - - // No privileges on target (existing table). - AuthzError("ALTER TABLE functional_seq_snap.alltypes rename to functional.alltypes", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional.alltypes"); - - // No privileges on target (new table). - AuthzError("ALTER TABLE functional_seq_snap.alltypes rename to functional.newtbl", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional"); - - // No privileges on target (existing view). - AuthzError("ALTER TABLE functional_seq_snap.alltypes rename to " + - "functional.alltypes_view", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional.alltypes"); - - // ALTER TABLE on a view does not reveal privileged information. - AuthzError("ALTER TABLE functional.alltypes_view_sub rename to " + - "functional_seq_snap.new_view", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypes_view"); - - // Rename table that does not exist (no permissions). - AuthzError("ALTER TABLE functional.notbl rename to functional_seq_snap.newtbl", - "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl"); - - // Rename table in db that does not exist (no permissions). - AuthzError("ALTER TABLE nodb.alltypes rename to functional_seq_snap.newtbl", - "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes"); - - // Alter table that does not exist (no permissions). - AuthzError("ALTER TABLE functional.notbl ADD COLUMNS (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl"); - - // Alter table in db that does not exist (no permissions). - AuthzError("ALTER TABLE nodb.alltypes ADD COLUMNS (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes"); - - // Unqualified table name. - AuthzError("ALTER TABLE alltypes ADD COLUMNS (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes"); - - AuthzError("ALTER TABLE alltypes SET TBLPROPERTIES ('a'='b', 'c'='d')", - "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes"); - - // Alter table, user only has column-level privileges. - AuthzError("ALTER TABLE functional.alltypestiny ADD COLUMNS (c1 int)", "User " + - "'%s' does not have privileges to execute 'ALTER' on: functional.alltypestiny"); - - // User has column-level privileges on the column being dropped but no table-level - // privileges - AuthzError("ALTER TABLE functional.alltypestinyt DROP id", "User '%s' does not " + - "have privileges to execute 'ALTER' on: functional.alltypestiny"); - } - - @Test - public void TestAlterView() throws ImpalaException { - AuthzOk("ALTER VIEW functional_seq_snap.alltypes_view rename to " + - "functional_seq_snap.v1"); - AuthzOk("ALTER VIEW functional.alltypes_view (a, b, c) as " + - "select int_col, string_col, timestamp_col from functional.alltypesagg"); - - // ALTER privilege on view only. RENAME also requires CREATE privileges on the DB. - AuthzOk("ALTER VIEW functional.alltypes_view rename to functional_seq_snap.view_view_1"); - - // No create privileges on target db - AuthzError("ALTER VIEW functional.alltypes_view rename to functional.newview", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional"); - - // No privileges on target (existing table). - AuthzError("ALTER VIEW functional_seq_snap.alltypes_view rename to " + - "functional.alltypes", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional.alltypes"); - - // No privileges on target (existing view). - AuthzError("ALTER VIEW functional_seq_snap.alltypes_view rename to " + - "functional.alltypes_view", - "User '%s' does not have privileges to execute 'CREATE' on: " + - "functional.alltypes_view"); - - // ALTER VIEW on a table does not reveal privileged information. - AuthzError("ALTER VIEW functional.alltypes rename to " + - "functional_seq_snap.new_view", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypes"); - AuthzError("ALTER VIEW functional.alltypes (a, b, c) as " + - "select int_col, string_col, timestamp_col from functional.alltypesagg", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypes"); - - // Rename view that does not exist (no permissions). - AuthzError("ALTER VIEW functional.notbl rename to functional_seq_snap.newtbl", - "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl"); - - // Rename view in db that does not exist (no permissions). - AuthzError("ALTER VIEW nodb.alltypes rename to functional_seq_snap.newtbl", - "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes"); - - // Alter view that does not exist (no permissions). - AuthzError("ALTER VIEW functional.notbl rename to functional_seq_snap.new_view", - "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl"); - AuthzError("ALTER VIEW functional.notbl (a, b, c) as " + - "select int_col, string_col, timestamp_col from functional.alltypesagg", - "User '%s' does not have privileges to execute 'ALTER' on: functional.notbl"); - - // Alter view in db that does not exist (no permissions). - AuthzError("ALTER VIEW nodb.alltypes rename to functional_seq_snap.new_view", - "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes"); - AuthzError("ALTER VIEW nodb.alltypes (a, b, c) as " + - "select int_col, string_col, timestamp_col from functional.alltypesagg", - "User '%s' does not have privileges to execute 'ALTER' on: nodb.alltypes"); - - // Unqualified view name. - AuthzError("ALTER VIEW alltypes rename to functional_seq_snap.new_view", - "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes"); - AuthzError("ALTER VIEW alltypes (a, b, c) as " + - "select int_col, string_col, timestamp_col from functional.alltypesagg", - "User '%s' does not have privileges to execute 'ALTER' on: default.alltypes"); - - // No permissions on target view. - AuthzError("alter view functional.alltypes_view_sub as " + - "select * from functional.alltypesagg", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypes_view"); - AuthzError("alter view functional.alltypes_view_sub (a, b, c) as " + - "select int_col, string_col, timestamp_col from functional.alltypesagg", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypes_view"); - - // No permissions on source view. - AuthzError("alter view functional_seq_snap.alltypes_view " + - "as select * from functional.alltypes_view", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes_view"); - AuthzError("alter view functional_seq_snap.alltypes_view (a, b, c) " + - "as select int_col, string_col, timestamp_col from functional.alltypes_view", - "User '%s' does not have privileges to execute 'SELECT' on: " + - "functional.alltypes_view"); - } - - @Test - public void TestComputeStatsTable() throws ImpalaException { - AuthzOk("compute stats functional_seq_snap.alltypes"); - // User has ALTER privilege on functional.alltypeserror table. - AuthzOk("compute stats functional.alltypeserror"); - - AuthzError("compute stats functional.alltypes", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("compute stats functional.alltypesagg", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypesagg"); - // User has column-level privileges on the target table - AuthzError("compute stats functional.alltypestiny", "User '%s' does not have " + - "privileges to execute 'ALTER' on: functional.alltypestiny"); - } - - @Test - public void TestDropStats() throws ImpalaException { - AuthzOk("drop stats functional_seq_snap.alltypes"); - // User has ALTER privilege on functional.alltypeserror table. - AuthzOk("drop stats functional.alltypeserror"); - - AuthzError("drop stats functional.alltypes", - "User '%s' does not have privileges to execute 'ALTER' on: functional.alltypes"); - AuthzError("drop stats functional.alltypesagg", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypesagg"); - // User has column-level privileges on the target table - AuthzError("drop stats functional.alltypestiny", "User '%s' does not have " + - "privileges to execute 'ALTER' on: functional.alltypestiny"); - } - - @Test - public void TestDescribeDb() throws ImpalaException { - AuthzOk("describe database functional_seq_snap"); - // User has REFRESH privilege on functional_text_lzo database. - AuthzOk("describe database functional_text_lzo"); - - // Database doesn't exist. - AuthzError("describe database nodb", - "User '%s' does not have privileges to access: nodb"); - // Insufficient privileges on db. - AuthzError("describe database functional_rc", - "User '%s' does not have privileges to access: functional_rc"); - } - - @Test - public void TestDescribe() throws ImpalaException { - // User has SELECT and REFRESH privileges on functional.alltypesagg table. - AuthzOk("describe functional.alltypesagg"); - AuthzOk("describe functional.alltypes"); - AuthzOk("describe functional.complex_view"); - - // Unqualified table name. - AuthzError("describe alltypes", - "User '%s' does not have privileges to access: default.alltypes"); - // Database doesn't exist. - AuthzError("describe nodb.alltypes", - "User '%s' does not have privileges to access: nodb.alltypes"); - // User has column level privileges - AuthzOk("describe functional.alltypestiny"); - // User has column level privileges on a subset of table columns - AuthzOk("describe functional.alltypessmall"); - // User has column level privileges on described column. - AuthzOk("describe functional.allcomplextypes.int_struct_col"); - // User has column level privileges on another column in table but not this one. - AuthzError("describe functional.allcomplextypes.complex_struct_col", - "User '%s' does not have privileges to access: functional.allcomplextypes"); - // User has table level privileges without column level. - AuthzOk("describe functional_parquet.allcomplextypes.complex_struct_col"); - // Column level privileges will allow describe but with reduced data. - AuthzOk("describe formatted functional.alltypestiny"); - // Column level privileges will allow describe but with reduced data. - AuthzOk("describe formatted functional.alltypessmall"); - // Insufficient privileges on table for nested column. - AuthzError("describe functional.complextypestbl.nested_struct", - "User '%s' does not have privileges to access: functional.complextypestbl"); - // Insufficient privileges on view. - AuthzError("describe functional.alltypes_view_sub", - "User '%s' does not have privileges to access: functional.alltypes_view_sub"); - // Insufficient privileges on db. - AuthzError("describe functional_rc.alltypes", - "User '%s' does not have privileges to access: functional_rc.alltypes"); - // Insufficient privileges on column that is a complex type, trying to access member. - AuthzError("describe functional.allcomplextypes.complex_struct_col.f2", - "User '%s' does not have privileges to access: functional.allcomplextypes"); - // Insufficient privileges on column that is not a complex type, trying to access - // member. - AuthzError("describe functional.allcomplextypes.nested_struct_col.f1", - "User '%s' does not have privileges to access: functional.allcomplextypes"); - } - - private static class DescribeResult { - // List of column names. - private final List<String> columns_; - // The value of the describe result's location field. - private final String location_; - - public DescribeResult(List<String> columns, String location) { - this.columns_ = columns; - this.location_ = location; - } - - public DescribeResult(List<String> columns) { - this(columns, null); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - DescribeResult that = (DescribeResult) o; - return Objects.equals(columns_, that.columns_) && - Objects.equals(location_, that.location_); - } - - @Override - public int hashCode() { - return Objects.hash(columns_, location_); - } - - @Override - public String toString() { - return "DescribeResult{" + - "columns=" + columns_ + - ", location='" + location_ + '\'' + - '}'; - } - } - - // Expected output of DESCRIBE for functional.alltypessmall. - private static final DescribeResult EXPECTED_DESCRIBE_ALLTYPESSMALL = - new DescribeResult(Lists.newArrayList( - "id", - "int_col", - "year" - )); - - // Expected output of DESCRIBE for functional.alltypesagg. - private static final DescribeResult EXPECTED_DESCRIBE_ALLTYPESAGG = - new DescribeResult(Lists.newArrayList( - "id", - "bool_col", - "tinyint_col", - "smallint_col", - "int_col", - "bigint_col", - "float_col", - "double_col", - "date_string_col", - "string_col", - "timestamp_col", - "year", - "month", - "day" - )); - - // Expected output of DESCRIBE for functional.alltypesagg. - private static final DescribeResult EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG = - new DescribeResult(Lists.newArrayList( - "id", - "bool_col", - "tinyint_col", - "smallint_col", - "int_col", - "bigint_col", - "float_col", - "double_col", - "date_string_col", - "string_col", - "timestamp_col", - "year", - "month", - "day"), - "hdfs://localhost:20500/test-warehouse/alltypesagg" - ); - - // Expected output of DESCRIBE for functional.alltypessmall. - private static final DescribeResult EXPECTED_DESCRIBE_EXTENDED_ALLTYPESSMALL = - new DescribeResult(Lists.newArrayList( - "id", - "int_col", - "year" - )); - - @Test - public void TestDescribeTableResults() throws ImpalaException { - // Running these statements force the tables to be loaded into the catalog, which - // allows running this test independently of other tests. - AuthzOk("describe functional.alltypesagg"); - AuthzOk("describe functional.alltypessmall"); - - // Verify MINIMAL describe contains all columns. - TDescribeOutputStyle style = TDescribeOutputStyle.MINIMAL; - TDescribeResult result = fe_.describeTable(new TTableName("functional", - "alltypesagg"), style, USER); - assertEquals(EXPECTED_DESCRIBE_ALLTYPESAGG, toDescribeResult(result, style)); - - // Verify MINIMAL describe on restricted table shows limited columns. - style = TDescribeOutputStyle.MINIMAL; - result = fe_.describeTable(new TTableName("functional", "alltypessmall"), style, - USER); - assertEquals(EXPECTED_DESCRIBE_ALLTYPESSMALL, toDescribeResult(result, style)); - - for (TDescribeOutputStyle s : new TDescribeOutputStyle[]{ - TDescribeOutputStyle.EXTENDED, TDescribeOutputStyle.FORMATTED}) { - // Verify FORMATTED/EXTENDED output contains all columns and metadata. - result = fe_.describeTable(new TTableName("functional", "alltypesagg"), s, USER); - assertEquals(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG, toDescribeResult(result, s)); - - // Verify FORMATTED output contains all columns and metadata. - result = fe_.describeTable(new TTableName("functional", "alltypessmall"), s, USER); - assertEquals(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESSMALL, toDescribeResult(result, s)); - } - } - - private static DescribeResult toDescribeResult(TDescribeResult result, - TDescribeOutputStyle style) { - List<String> columns = new ArrayList<>(); - String location = null; - List<TResultRow> rows = result.getResults(); - switch (style) { - case MINIMAL: - // Example output: - // [[bool_col,boolean,] - // [month,int,]] - for (TResultRow row : rows) { - columns.add(row.getColVals().get(0).getString_val().trim()); - } - break; - case EXTENDED: - case FORMATTED: - // Example output: - // [[name,type,comment], - // [#col_name,data_type,comment], - // [,,], - // [bool_col,boolean,], - // [tinyint_col,tinyint,], - // [,,], - // [#PartitionInformation,,], - // [#col_name,data_type,comment], - // [,,], - // [year,int,], - // [month,int,], - // [,,], - // [#DetailedTableInformation,,], - // [Database:,functional,], - // [Location:,hdfs://localhost:20500/test-warehouse/alltypes,], - // [,,] - // [#StorageInformation,,] - // [SerDeLibrary:,org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe,] - // [InputFormat:,org.apache.hadoop.mapred.TextInputFormat,]] - int rowIdx = 0; - while (rowIdx < rows.size()) { - List<TColumnValue> cols = rows.get(rowIdx).getColVals(); - if (cols.get(0).getString_val().startsWith("Location")) { - Preconditions.checkState(location == null); - location = cols.get(1).getString_val().trim(); - } else if (cols.get(0).getString_val().startsWith("# col_name")) { - // To get the column names, we need to ignore the first empty line and stop - // until we see another empty line. - rowIdx += 2; // Skips over the first empty line. - Preconditions.checkElementIndex(rowIdx, rows.size()); - cols = rows.get(rowIdx).getColVals(); - // Stop when we see the next empty line. - while (!cols.get(0).getString_val().trim().isEmpty()) { - columns.add(cols.get(0).getString_val().trim()); - rowIdx++; - Preconditions.checkElementIndex(rowIdx, rows.size()); - cols = rows.get(rowIdx).getColVals(); - } - } - rowIdx++; - } - break; - default: - throw new IllegalArgumentException("Invalid describe output style: " + style); - } - return new DescribeResult(columns, location); - } - - @Test - public void TestLoad() throws ImpalaException { - // User has permission on table and URI. - AuthzOk("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" + - " into table functional.alltypes partition(month=10, year=2009)"); - - // User does not have permission on table. - AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" + - " into table functional.alltypesagg", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypesagg"); - - // User only has column-level privileges on the table - AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" + - " into table functional.alltypestiny", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypestiny"); - - // User does not have permission on URI. - AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.part'" + - " into table functional.alltypes partition(month=10, year=2009)", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/tpch.part"); - - // URI does not exist and user does not have permission. - AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/nope'" + - " into table functional.alltypes partition(month=10, year=2009)", - "User '%s' does not have privileges to access: " + - "hdfs://localhost:20500/test-warehouse/nope"); - - // Table/Db does not exist, user does not have permission. - AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" + - " into table functional.notable", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.notable"); - AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" + - " into table nodb.alltypes", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "nodb.alltypes"); - - // Trying to LOAD a view does not reveal privileged information. - AuthzError("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" + - " into table functional.alltypes_view", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypes_view"); - } - - @Test - public void TestShowPermissions() throws ImpalaException { - AuthzOk("show tables in functional"); - AuthzOk("show tables in functional_avro"); // Database with only column privileges. - AuthzOk("show databases"); - AuthzOk("show tables in _impala_builtins"); - AuthzOk("show functions in _impala_builtins"); - // User has REFRESH privilege on functional_text_lzo database. - AuthzOk("show tables in functional_text_lzo"); - AuthzOk("show functions in functional_text_lzo"); - - // Database exists, user does not have access. - AuthzError("show tables in functional_rc", - "User '%s' does not have privileges to access: functional_rc.*"); - - // Database does not exist, user does not have access. - AuthzError("show tables in nodb", - "User '%s' does not have privileges to access: nodb.*"); - - AuthzError("show tables", - "User '%s' does not have privileges to access: default.*"); - - // Database does not exist, user has access. - try { - AuthzOk("show tables in newdb"); - fail("Expected AnalysisException"); - } catch (AnalysisException e) { - Assert.assertEquals(e.getMessage(), "Database does not exist: newdb"); - } - - // Show partitions and show table/column stats. - String[] statsQuals = new String[] { "partitions", "table stats", "column stats" }; - for (String qual: statsQuals) { - // User has SELECT and REFRESH privileges on functional.alltypesagg table. - AuthzOk(String.format("show %s functional.alltypesagg", qual)); - AuthzOk(String.format("show %s functional.alltypes", qual)); - // User does not have access to db/table. - AuthzError(String.format("show %s nodb.tbl", qual), - "User '%s' does not have privileges to access: nodb.tbl"); - AuthzError(String.format("show %s functional.badtbl", qual), - "User '%s' does not have privileges to access: functional.badtbl"); - AuthzError(String.format("show %s functional_rc.alltypes", qual), - "User '%s' does not have privileges to access: functional_rc.alltypes"); - // User only has column-level privileges - AuthzError(String.format("show %s functional.alltypestiny", qual), - "User '%s' does not have privileges to access: functional.alltypestiny"); - } - - // Show files - String[] partitions = new String[] { "", "partition(month=10, year=2010)" }; - for (String partition: partitions) { - // User has SELECT and REFRESH privileges on functional.alltypesagg table. - AuthzOk(String.format("show files in functional.alltypesagg %s", partition)); - AuthzOk(String.format("show files in functional.alltypes %s", partition)); - // User does not have access to db/table. - AuthzError(String.format("show files in nodb.tbl %s", partition), - "User '%s' does not have privileges to access: nodb.tbl"); - AuthzError(String.format("show files in functional.badtbl %s", partition), - "User '%s' does not have privileges to access: functional.badtbl"); - AuthzError(String.format("show files in functional_rc.alltypes %s", partition), - "User '%s' does not have privileges to access: functional_rc.alltypes"); - // User only has column-level privileges. - AuthzError(String.format("show files in functional.alltypestiny %s", partition), - "User '%s' does not have privileges to access: functional.alltypestiny"); - } - } - - @Test public void TestShowDbResultsFiltered() throws ImpalaException { // These are the only dbs that should show up because they are the only // dbs the user has any permissions on. @@ -2203,35 +653,6 @@ public class AuthorizationTest extends FrontendTestBase { } @Test - public void TestShowCreateTable() throws ImpalaException { - // User has SELECT and REFRESH privileges functional.alltypesagg table. - AuthzOk("show create table functional.alltypesagg"); - AuthzOk("show create table functional.alltypes"); - // Have permissions on view and underlying table. - AuthzOk("show create table functional_seq_snap.alltypes_view"); - // Unqualified table name. - AuthzError("show create table alltypes", - "User '%s' does not have privileges to access: default.alltypes"); - // Database doesn't exist. - AuthzError("show create table nodb.alltypes", - "User '%s' does not have privileges to access: nodb.alltypes"); - // Insufficient privileges on table. - AuthzError("show create table functional.alltypestiny", - "User '%s' does not have privileges to access: functional.alltypestiny"); - // Insufficient privileges on db. - AuthzError("show create table functional_rc.alltypes", - "User '%s' does not have privileges to access: functional_rc.alltypes"); - // User has column-level privileges on table - AuthzError("show create table functional.alltypestiny", - "User '%s' does not have privileges to access: functional.alltypestiny"); - - // Cannot show SQL if user doesn't have permissions on underlying table. - AuthzError("show create table functional.complex_view", - "User '%s' does not have privileges to see the definition of view " + - "'functional.complex_view'."); - } - - @Test public void TestHs2GetTables() throws ImpalaException { TMetadataOpRequest req = new TMetadataOpRequest(); req.setSession(createSessionState("default", USER)); @@ -2491,108 +912,6 @@ public class AuthorizationTest extends FrontendTestBase { } @Test - public void TestFunction() throws Exception { - // First try with the less privileged user. - AnalysisContext ctx = createAnalysisCtx(ctx_.authzConfig, USER.getName()); - - // User has CREATE privilege on functional_text_lzo database and ALL privilege - // on /test-warehouse/libTestUdfs.so URI. - AuthzOk(ctx, "create function functional_text_lzo.f() returns int location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'"); - - AuthzError(ctx, "show functions", - "User '%s' does not have privileges to access: default"); - AuthzOk(ctx, "show functions in tpch"); - - AuthzError(ctx, "create function f() returns int location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'", - "User '%s' does not have privileges to CREATE functions in: default.f()"); - - // User has ALL privilege on tpch database and ALL privilege on - // /test-warehouse/libTestUdfs.so URI. - AuthzOk(ctx, "create function tpch.f() returns int location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'"); - - AuthzError(ctx, "create function notdb.f() returns int location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'", - "User '%s' does not have privileges to CREATE functions in: notdb.f()"); - - // User has DROP privilege on functional_text_lzo database. - try { - ctx_.catalog.addFunction(ScalarFunction.createForTesting("functional_text_lzo", - "f", new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, - null, TFunctionBinaryType.NATIVE)); - AuthzOk("drop function functional_text_lzo.f()"); - } finally { - ctx_.catalog.removeFunction(ScalarFunction.createForTesting("functional_text_lzo", - "f", new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, - null, TFunctionBinaryType.NATIVE)); - } - - AuthzError(ctx, "drop function if exists f()", - "User '%s' does not have privileges to DROP functions in: default.f()"); - - AuthzError(ctx, "drop function notdb.f()", - "User '%s' does not have privileges to DROP functions in: notdb.f()"); - - // User does not have ALL privilege on SERVER and tries to create a function with - // the same name as the built-in function. - AuthzError(ctx, "create function sin(double) returns double location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'", - "Cannot modify system database."); - - // TODO: Add test support for dynamically changing privileges for - // file-based policy. - if (ctx_.authzConfig.isFileBasedPolicy()) return; - - // Admin should be able to do everything - SentryPolicyService sentryService = - new SentryPolicyService(ctx_.authzConfig.getSentryConfig()); - try { - sentryService.grantRoleToGroup(USER, "admin", USER.getName()); - ctx_.catalog.reset(); - - AuthzOk("show functions"); - AuthzOk("show functions in tpch"); - - AuthzOk("create function f() returns int location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'"); - AuthzOk("create function tpch.f() returns int location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'"); - AuthzOk("drop function if exists f()"); - - // Can't add function to system db - AuthzError("create function _impala_builtins.f() returns int location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'", - "Cannot modify system database."); - AuthzError("drop function if exists pi()", - "Cannot modify system database."); - - // Add default.f(), tpch.f() - ctx_.catalog.addFunction(ScalarFunction.createForTesting("default", "f", - new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, - null, TFunctionBinaryType.NATIVE)); - ctx_.catalog.addFunction(ScalarFunction.createForTesting("tpch", "f", - new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, - null, TFunctionBinaryType.NATIVE)); - - AuthzOk("drop function tpch.f()"); - } finally { - sentryService.revokeRoleFromGroup(USER, "admin", USER.getName()); - ctx_.catalog.reset(); - - //Other tests don't expect tpch to contain functions - //Specifically, if these functions are not cleaned up, TestDropDatabase() will fail - ctx_.catalog.removeFunction(ScalarFunction.createForTesting("default", "f", - new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, - null, TFunctionBinaryType.NATIVE)); - ctx_.catalog.removeFunction(ScalarFunction.createForTesting("tpch", "f", - new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, - null, TFunctionBinaryType.NATIVE)); - } - } - - @Test public void TestServerNameAuthorized() throws ImpalaException { if (ctx_.authzConfig.isFileBasedPolicy()) { // Authorization config that has a different server name from policy file. @@ -2749,329 +1068,6 @@ public class AuthorizationTest extends FrontendTestBase { "TBLPROPERTIES ('kudu.master_addresses'='127.0.0.1', 'kudu.table_name'='tbl')"); } - @Test - public void TestServerLevelInsert() throws ImpalaException { - // TODO: Add test support for dynamically changing privileges for - // file-based policy. - if (ctx_.authzConfig.isFileBasedPolicy()) return; - - SentryPolicyService sentryService = - new SentryPolicyService(ctx_.authzConfig.getSentryConfig()); - - // User has INSERT privilege on server. - String roleName = "insert_role"; - try { - sentryService.createRole(USER, roleName, true); - TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.INSERT, - TPrivilegeScope.SERVER, false); - privilege.setServer_name("server1"); - sentryService.grantRolePrivilege(USER, roleName, privilege); - sentryService.grantRoleToGroup(USER, roleName, USER.getName()); - - privilege = new TPrivilege ("", TPrivilegeLevel.SELECT, TPrivilegeScope.DATABASE, - false); - privilege.setServer_name("server1"); - privilege.setDb_name("functional_rc"); - sentryService.grantRolePrivilege(USER, roleName, privilege); - sentryService.grantRoleToGroup(USER, roleName, USER.getName()); - - privilege = new TPrivilege ("", TPrivilegeLevel.SELECT, TPrivilegeScope.DATABASE, - false); - privilege.setServer_name("server1"); - privilege.setDb_name("functional_seq"); - sentryService.grantRolePrivilege(USER, roleName, privilege); - sentryService.grantRoleToGroup(USER, roleName, USER.getName()); - ctx_.catalog.reset(); - - // Copied majority of INSERT tests that should fail from authorization and - // ensure they succeed here. Some tests that fail will fail here with - // AnalysisException and are covered elsewhere. - - // User has SELECT permissions on source table. - AuthzOk("insert into functional.alltypes partition (month, year) " + - "select * from functional_rc.alltypes"); - - // Ensure INSERT at server does not allow other privileges - AuthzError("select * from functional.alltypes", - "User '%s' does not have privileges to execute 'SELECT' on: functional"); - AuthzError("create table functional.new_table (i int)", - "User '%s' does not have privileges to execute 'CREATE' on: functional"); - AuthzError("alter table functional.alltypes add columns (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypes"); - AuthzError("drop table functional.alltypes", - "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes"); - - // User has permissions on source table within inline view. - AuthzOk("insert into functional.alltypes partition (month, year) " + - "select id, bool_col, tinyint_col, smallint_col, a.int_col, bigint_col, " + - "float_col, a.double_col, a.date_string_col, a.string_col, a.timestamp_col, " + - "a.year, a.month from functional_rc.alltypesagg a " + - "join (select int_col, double_col, date_string_col, string_col, " + - "timestamp_col, year, month from functional_seq.alltypes) b " + - "on (a.int_col = b.int_col)"); - - // User has INSERT permissions on the target table and has sufficient SELECT - // permissions on all the referenced columns of the source table - AuthzOk("insert into functional.alltypestiny partition (month, year) " + - "select * from functional_rc.alltypestiny"); - - // User has INSERT permissions on target table and column-level - // permissions on the source table - AuthzOk("insert into functional.alltypes partition (month, year) " + - "select * from functional_rc.alltypessmall"); - - // Insert and Select allow view_metadata - AuthzOk("describe database functional_rc"); - AuthzOk("describe functional.complextypes_fileformat.s"); - AuthzOk("describe functional.alltypes_view_sub"); - AuthzOk("describe functional_rc.alltypes"); - } finally { - sentryService.dropRole(USER, roleName, true); - ctx_.catalog.reset(); - } - } - - @Test - public void TestServerLevelSelect() throws ImpalaException { - // TODO: Add test support for dynamically changing privileges for - // file-based policy. - if (ctx_.authzConfig.isFileBasedPolicy()) return; - - SentryPolicyService sentryService = - new SentryPolicyService(ctx_.authzConfig.getSentryConfig()); - - // User has SELECT privilege on server. - String roleName = "select_role"; - try { - sentryService.createRole(USER, roleName, true); - TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.SELECT, - TPrivilegeScope.SERVER, false); - privilege.setServer_name("server1"); - sentryService.grantRolePrivilege(USER, roleName, privilege); - sentryService.grantRoleToGroup(USER, roleName, USER.getName()); - ctx_.catalog.reset(); - - // Copied majority of SELECT tests that should fail from authorization and - // ensure they succeed here. - AuthzOk("select * from functional.alltypes_view_sub"); - AuthzOk("select * from functional.alltypes"); - - // Ensure SELECT at server does not allow other privileges - AuthzError("insert into functional.alltypesagg select 1", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional.alltypesagg"); - AuthzError("create table functional.new_table (i int)", - "User '%s' does not have privileges to execute 'CREATE' on: functional"); - AuthzError("alter table functional.alltypes add columns (c1 int)", - "User '%s' does not have privileges to execute 'ALTER' on: " + - "functional.alltypes"); - AuthzError("drop table functional.alltypes", - "User '%s' does not have privileges to execute 'DROP' on: functional.alltypes"); - - // User has SELECT privileges on the view, and has privileges - // to select join table. - AuthzOk("select a.id from functional.view_view a " + - "join functional.alltypes b ON (a.id = b.id)"); - - // User has SELECT privileges on the view which contains a subquery. - AuthzOk("select * from functional_rc.subquery_view"); - - // Constant select. - AuthzOk("select 1"); - - // Table within inline view is authorized properly. - AuthzOk("select a.* from (select * from functional.alltypes) a"); - - // SELECT privileges on all the columns of 'alltypessmall' - AuthzOk("select * from functional.alltypessmall"); - - // SELECT privileges on table 'alltypessmall' - AuthzOk("select count(*) from functional.alltypessmall"); - AuthzOk("select 1 from functional.alltypessmall"); - - // SELECT privileges on column 'month' - AuthzOk("select id, int_col, year, month from functional.alltypessmall"); - - // SELECT privileges on 'int_array_col' - AuthzOk("select a.id, b.item from functional.allcomplextypes a, " + - "a.int_array_col b"); - - // SELECT privileges on 'alltypessmall' - AuthzOk("select a.* from functional.alltypesagg a cross join " + - "functional.alltypessmall b"); - - // Insert allows view_metadata - AuthzOk("describe database functional_rc"); - AuthzOk("describe functional.complextypes_fileformat.s"); - AuthzOk("describe functional.alltypes_view_sub"); - AuthzOk("describe functional_rc.alltypes"); - } finally { - sentryService.dropRole(USER, roleName, true); - ctx_.catalog.reset(); - } - } - - @Test - public void TestServerLevelCreate() throws ImpalaException { - // TODO: Add test support for dynamically changing privileges for - // file-based policy. - if (ctx_.authzConfig.isFileBasedPolicy()) return; - - SentryPolicyService sentryService = - new SentryPolicyService(ctx_.authzConfig.getSentryConfig()); - - // User has CREATE privilege on server. - String roleName = "create_role"; - try { - sentryService.createRole(USER, roleName, true); - TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.CREATE, - TPrivilegeScope.SERVER, false); - privilege.setServer_name("server1"); - sentryService.grantRolePrivilege(USER, roleName, privilege); - sentryService.grantRoleToGroup(USER, roleName, USER.getName()); - ctx_.catalog.reset(); - - AuthzOk("create database newdb"); - AuthzOk("create database newdb location " + - "'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("create table functional_avro.newtable (i int)"); - AuthzOk("create view functional_avro.newview as " + - "select * from functional.alltypesagg"); - AuthzOk("create function functional_avro.f() returns int location " + - "'/test-warehouse/libTestUdfs.so' symbol='NoArgs'"); - // User does not have INSERT privilege on functional_avro database. - AuthzError("create table functional_avro.newtable as " + - "select * from functional.alltypesagg", - "User '%s' does not have privileges to execute 'INSERT' on: " + - "functional_avro.newtable"); - } finally { - sentryService.dropRole(USER, roleName, true); - ctx_.catalog.reset(); - } - } - - @Test - public void TestServerLevelAlter() throws ImpalaException { - // TODO: Add test support for dynamically changing privileges for - // file-based policy. - if (ctx_.authzConfig.isFileBasedPolicy()) return; - - SentryPolicyService sentryService = - new SentryPolicyService(ctx_.authzConfig.getSentryConfig()); - - // User has ALTER privilege on server. - String roleName = "alter_role"; - try { - sentryService.createRole(USER, roleName, true); - TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.ALTER, - TPrivilegeScope.SERVER, false); - privilege.setServer_name("server1"); - sentryService.grantRolePrivilege(USER, roleName, privilege); - sentryService.grantRoleToGroup(USER, roleName, USER.getName()); - ctx_.catalog.reset(); - - AuthzOk("ALTER TABLE functional_rc.alltypes ADD COLUMNS (c1 int)"); - AuthzOk("ALTER TABLE functional_rc.alltypes REPLACE COLUMNS (c1 int)"); - AuthzOk("ALTER TABLE functional_rc.alltypes CHANGE int_col c1 int"); - AuthzOk("ALTER TABLE functional_rc.alltypes DROP int_col"); - AuthzOk("ALTER TABLE functional_rc.alltypes RENAME TO functional_seq_snap.t1"); - AuthzOk("ALTER TABLE functional_rc.alltypes SET FILEFORMAT PARQUET"); - AuthzOk("ALTER TABLE functional_rc.alltypes SET LOCATION " + - "'/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_rc.alltypes SET TBLPROPERTIES " + - "('a'='b', 'c'='d')"); - AuthzOk("ALTER TABLE functional_rc.alltypes SET LOCATION " + - "'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_rc.alltypes PARTITION(year=2009, month=1) " + - "SET LOCATION 'hdfs://localhost:20500/test-warehouse/new_table'"); - AuthzOk("ALTER TABLE functional_rc.alltypes SET CACHED IN 'testPool'"); - AuthzOk("ALTER TABLE functional_rc.alltypes RECOVER PARTITIONS"); - } finally { - sentryService.dropRole(USER, roleName, true); - ctx_.catalog.reset(); - } - } - - @Test - public void TestServerLevelDrop() throws ImpalaException { - // TODO: Add test support for dynamically changing privileges for - // file-based policy. - if (ctx_.authzConfig.isFileBasedPolicy()) return; - - SentryPolicyService sentryService = - new SentryPolicyService(ctx_.authzConfig.getSentryConfig()); - - // User has DROP privilege on server. - String roleName = "drop_role"; - try { - sentryService.createRole(USER, roleName, true); - TPrivilege privilege = new TPrivilege("", TPrivilegeLevel.DROP, - TPrivilegeScope.SERVER, false); - privilege.setServer_name("server1"); - sentryService.grantRolePrivilege(USER, roleName, privilege); - sentryService.grantRoleToGroup(USER, roleName, USER.getName()); - ctx_.catalog.reset(); - - AuthzOk("drop database functional"); - AuthzOk("drop table functional.alltypes"); - AuthzOk("drop view functional.alltypes_view_sub"); - ctx_.catalog.addFunction(ScalarFunction.createForTesting("functional", - "f", new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, - null, TFunctionBinaryType.NATIVE)); - AuthzOk("drop function functional.f()"); - } finally { - sentryService.dropRole(USER, roleName, true); - ctx_.catalog.reset(); - ctx_.catalog.addFunction(ScalarFunction.createForTesting("functional", - "f", new ArrayList<Type>(), Type.INT, "/dummy", "dummy.class", null, - null, TFunctionBinaryType.NATIVE)); - } - } - - @Test - public void TestCommentOn() throws ImpalaException { - // User has ALTER privilege on functional_text_lzo database. - AuthzOk("comment on database functional_text_lzo is 'comment'"); - // User does not have ALTER privilege on functional database. - AuthzError("comment on database functional is 'comment'", - "User '%s' does not have privileges to execute 'ALTER' on: functional"); - AuthzError("comment on database doesntexist is 'comment'", - "User '%s' does not have privileges to execute 'ALTER' on: doesntexist"); - - // User has ALTER privilege on functional_text_lzo.alltypes table. - AuthzOk("comment on table functional_text_lzo.alltypes is 'comment'"); - // User does not have ALTER privilege on functional.alltypes table. - AuthzError("comment on table functional.alltypes is 'comment'", - "User '%s' does not have privileges to execute 'ALTER' on: functional"); - AuthzError("comment on table doesntexist is 'comment'", - "User '%s' does not have privileges to execute 'ALTER' on: default.doesntexist"); - - // User has ALTER privilege on functional.alltypes_view view. - AuthzOk("comment on view functional.alltypes_view is 'comment'"); - // User does not have ALTER privilege on functional.view_view table. - AuthzError("comment on view functional.view_view is 'comment'", - "User '%s' does not have privileges to execute 'ALTER' on: functional"); - AuthzError("comment on view doesntexist is 'comment'", - "User '%s' does not have privileges to execute 'ALTER' on: default.doesntexist"); - } - - @Test - public void TestAlterDatabaseSetOwner() throws ImpalaException { - // User has ALTER privilege on functional_text_lzo database. - AuthzOk("alter database functional_text_lzo set owner user foo_user"); - AuthzOk("alter database functional_text_lzo set owner role foo_role"); - // User does not have ALTER privilege on functional database. - AuthzError("alter database functional set owner user foo_user", - "User '%s' does not have privileges to execute 'ALTER' on: functional"); - AuthzError("alter database functional set owner role foo_role", - "User '%s' does not have privileges to execute 'ALTER' on: functional"); - AuthzError("alter database doesntexist set owner user foo_user", - "User '%s' does not have privileges to execute 'ALTER' on: doesntexist"); - AuthzError("alter database doesntexist set owner role foo_role", - "User '%s' does not have privileges to execute 'ALTER' on: doesntexist"); - } - private void TestWithIncorrectConfig(AuthorizationConfig authzConfig, User user) throws ImpalaException { Frontend fe = new Frontend(authzConfig, ctx_.catalog);