| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.sentry.tests.e2e.hive; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.sql.Connection; |
| import java.sql.ResultSet; |
| import java.sql.Statement; |
| |
| import com.google.common.io.Resources; |
| import org.junit.Assert; |
| |
| import org.apache.sentry.core.common.utils.PolicyFile; |
| import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| public class TestUriPermissions extends AbstractTestWithStaticConfiguration { |
| private PolicyFile policyFile; |
| private File dataFile; |
| private String loadData; |
| |
| @BeforeClass |
| public static void setupTestStaticConfiguration () throws Exception { |
| AbstractTestWithStaticConfiguration.setupTestStaticConfiguration(); |
| } |
| |
| @Before |
| public void setup() throws Exception { |
| policyFile = super.setupPolicy(); |
| super.setup(); |
| } |
| |
| // test load data into table |
| @Test |
| public void testLoadPrivileges() throws Exception { |
| dataFile = new File(dataDir, SINGLE_TYPE_DATA_FILE_NAME); |
| FileOutputStream to = new FileOutputStream(dataFile); |
| Resources.copy(Resources.getResource(SINGLE_TYPE_DATA_FILE_NAME), to); |
| to.close(); |
| loadData = "server=server1->uri=file://" + dataFile.getPath(); |
| |
| String tabName = "tab1"; |
| Connection userConn = null; |
| Statement userStmt = null; |
| |
| // create dbs |
| Connection adminCon = context.createConnection(ADMIN1); |
| Statement adminStmt = context.createStatement(adminCon); |
| adminStmt.execute("use default"); |
| adminStmt.execute("CREATE DATABASE " + DB1); |
| adminStmt.execute("use " + DB1); |
| adminStmt.execute("CREATE TABLE " + tabName + "(id int)"); |
| context.close(); |
| |
| policyFile |
| .addRolesToGroup(USERGROUP1, "db1_read", "db1_write", "data_read") |
| .addRolesToGroup(USERGROUP2, "db1_write") |
| .addPermissionsToRole("db1_write", "server=server1->db=" + DB1 + "->table=" + tabName + "->action=INSERT") |
| .addPermissionsToRole("db1_read", "server=server1->db=" + DB1 + "->table=" + tabName + "->action=SELECT") |
| .addPermissionsToRole("data_read", loadData); |
| writePolicyFile(policyFile); |
| |
| // positive test, user1 has access to file being loaded |
| userConn = context.createConnection(USER1_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| userStmt.execute("load data local inpath 'file://" + dataFile.getPath() + |
| "' into table " + tabName); |
| userStmt.execute("select * from " + tabName + " limit 1"); |
| ResultSet res = userStmt.getResultSet(); |
| Assert.assertTrue("Table should have data after load", res.next()); |
| res.close(); |
| context.close(); |
| |
| // Negative test, user2 doesn't have access to the file being loaded |
| userConn = context.createConnection(USER2_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| context.assertAuthzException(userStmt, "load data local inpath 'file://" + dataFile.getPath() + |
| "' into table " + tabName); |
| userStmt.close(); |
| userConn.close(); |
| } |
| |
| // Test alter partition location |
| @Test |
| public void testAlterPartitionLocationPrivileges() throws Exception { |
| String tabName = "tab1"; |
| String newPartitionDir = "foo"; |
| String tabDir = hiveServer.getProperty(HiveServerFactory.WAREHOUSE_DIR) + |
| "/" + tabName + "/" + newPartitionDir; |
| Connection userConn = null; |
| Statement userStmt = null; |
| |
| // create dbs |
| Connection adminCon = context.createConnection(ADMIN1); |
| Statement adminStmt = context.createStatement(adminCon); |
| adminStmt.execute("use default"); |
| adminStmt.execute("CREATE DATABASE " + DB1); |
| adminStmt.execute("use " + DB1); |
| adminStmt.execute("CREATE TABLE " + tabName + " (id int) PARTITIONED BY (dt string)"); |
| adminCon.close(); |
| |
| policyFile |
| .addRolesToGroup(USERGROUP1, "db1_all", "data_read") |
| .addRolesToGroup(USERGROUP2, "db1_all") |
| .addRolesToGroup(USERGROUP3, "db1_tab1_all", "data_read") |
| .addPermissionsToRole("db1_all", "server=server1->db=" + DB1) |
| .addPermissionsToRole("db1_tab1_all", "server=server1->db=" + DB1 + "->table=" + tabName) |
| .addPermissionsToRole("data_read", "server=server1->uri=" + tabDir); |
| writePolicyFile(policyFile); |
| |
| |
| // positive test: user1 has privilege to alter table add partition but not set location |
| userConn = context.createConnection(USER1_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| userStmt.execute("ALTER TABLE " + tabName + " ADD IF NOT EXISTS PARTITION (dt = '21-Dec-2012') " + |
| " LOCATION '" + tabDir + "'"); |
| userStmt.execute("ALTER TABLE " + tabName + " DROP PARTITION (dt = '21-Dec-2012')"); |
| userStmt.execute("ALTER TABLE " + tabName + " ADD PARTITION (dt = '21-Dec-2012') " + |
| " LOCATION '" + tabDir + "'"); |
| userStmt.execute( |
| "ALTER TABLE " + tabName + " PARTITION (dt = '21-Dec-2012') " + " SET LOCATION '" + tabDir + "'"); |
| userConn.close(); |
| |
| // negative test: user2 doesn't have privilege to alter table add partition |
| userConn = context.createConnection(USER2_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| context.assertAuthzException(userStmt, |
| "ALTER TABLE " + tabName + " ADD PARTITION (dt = '22-Dec-2012') " + |
| " LOCATION '" + tabDir + "/foo'"); |
| // positive test, user2 can alter managed partitions |
| userStmt.execute("ALTER TABLE " + tabName + " ADD PARTITION (dt = '22-Dec-2012')"); |
| userStmt.execute("ALTER TABLE " + tabName + " DROP PARTITION (dt = '22-Dec-2012')"); |
| userStmt.execute("ALTER TABLE " + tabName + " ADD IF NOT EXISTS PARTITION (dt = '22-Dec-2012')"); |
| userStmt.execute("ALTER TABLE " + tabName + " DROP PARTITION (dt = '22-Dec-2012')"); |
| userConn.close(); |
| |
| // positive test: user3 has privilege to add/drop partitions |
| userConn = context.createConnection(USER3_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| userStmt.execute( |
| "ALTER TABLE " + tabName + " ADD PARTITION (dt = '22-Dec-2012') " + |
| " LOCATION '" + tabDir + "/foo'"); |
| userStmt.execute( |
| "ALTER TABLE " + tabName + " DROP PARTITION (dt = '21-Dec-2012')"); |
| |
| userStmt.close(); |
| userConn.close(); |
| } |
| |
| // test alter table set location |
| @Test |
| public void testAlterTableLocationPrivileges() throws Exception { |
| String tabName = "tab1"; |
| String tabDir = hiveServer.getProperty(HiveServerFactory.WAREHOUSE_DIR) + "/" + tabName; |
| Connection userConn = null; |
| Statement userStmt = null; |
| |
| // create dbs |
| Connection adminCon = context.createConnection(ADMIN1); |
| Statement adminStmt = context.createStatement(adminCon); |
| adminStmt.execute("use default"); |
| adminStmt.execute("CREATE DATABASE " + DB1); |
| adminStmt.execute("use " + DB1); |
| adminStmt.execute("CREATE TABLE " + tabName + " (id int) PARTITIONED BY (dt string)"); |
| adminCon.close(); |
| |
| policyFile |
| .addRolesToGroup(USERGROUP1, "server1_all") |
| .addRolesToGroup(USERGROUP2, "db1_all, data_read") |
| .addPermissionsToRole("db1_all", "server=server1->db=" + DB1) |
| .addPermissionsToRole("data_read", "server=server1->URI=" + tabDir) |
| .addPermissionsToRole("server1_all", "server=server1"); |
| writePolicyFile(policyFile); |
| |
| // positive test: user2 has privilege to alter table set partition |
| userConn = context.createConnection(USER2_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| userStmt.execute( |
| "ALTER TABLE " + tabName + " SET LOCATION '" + tabDir + "'"); |
| userConn.close(); |
| |
| // positive test: user1 has privilege to alter table set partition |
| userConn = context.createConnection(USER1_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| userStmt.execute("ALTER TABLE " + tabName + " SET LOCATION '" + tabDir + "'"); |
| userConn.close(); |
| } |
| |
| // Test external table |
| @Test |
| public void testExternalTablePrivileges() throws Exception { |
| Connection userConn = null; |
| Statement userStmt = null; |
| |
| String dataDirPath = "file://" + dataDir; |
| String tableDir = dataDirPath + "/" + Math.random(); |
| |
| //Hive needs write permissions on this local directory |
| baseDir.setWritable(true, false); |
| dataDir.setWritable(true, false); |
| |
| // create dbs |
| Connection adminCon = context.createConnection(ADMIN1); |
| Statement adminStmt = context.createStatement(adminCon); |
| adminStmt.execute("use default"); |
| adminStmt.execute("CREATE DATABASE " + DB1); |
| adminStmt.close(); |
| adminCon.close(); |
| |
| policyFile |
| .addRolesToGroup(USERGROUP1, "db1_all", "data_read") |
| .addRolesToGroup(USERGROUP2, "db1_all") |
| .addPermissionsToRole("db1_all", "server=server1->db=" + DB1) |
| .addPermissionsToRole("data_read", "server=server1->URI=" + dataDirPath); |
| writePolicyFile(policyFile); |
| |
| // negative test: user2 doesn't have privilege to create external table in given path |
| userConn = context.createConnection(USER2_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| context.assertAuthzException(userStmt, |
| "CREATE EXTERNAL TABLE extab1(id INT) LOCATION '" + tableDir + "'"); |
| context.assertAuthzException(userStmt, "CREATE TABLE extab1(id INT) LOCATION '" + tableDir + "'"); |
| userStmt.close(); |
| userConn.close(); |
| |
| // positive test: user1 has privilege to create external table in given path |
| userConn = context.createConnection(USER1_1); |
| userStmt = context.createStatement(userConn); |
| userStmt.execute("use " + DB1); |
| userStmt.execute("CREATE EXTERNAL TABLE extab1(id INT) LOCATION '" + tableDir + "'"); |
| userStmt.execute("DROP TABLE extab1"); |
| userStmt.execute("CREATE TABLE extab1(id INT) LOCATION '" + tableDir + "'"); |
| userStmt.close(); |
| userConn.close(); |
| } |
| |
| } |