You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by sh...@apache.org on 2013/09/07 00:36:19 UTC
git commit: SENTRY-1: use default on HiveServer2 fails with invalid
privileges exception (Prasad Mujumdar via Shreepadma Venugopalan)
Updated Branches:
refs/heads/master c98ac0c37 -> ecc85161f
SENTRY-1: use default on HiveServer2 fails with invalid privileges exception (Prasad Mujumdar via Shreepadma Venugopalan)
Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/ecc85161
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/ecc85161
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/ecc85161
Branch: refs/heads/master
Commit: ecc85161f73e11da54dba35822f284083a1c57de
Parents: c98ac0c
Author: Shreepadma Venugopalan <sh...@apache.org>
Authored: Fri Sep 6 15:35:42 2013 -0700
Committer: Shreepadma Venugopalan <sh...@apache.org>
Committed: Fri Sep 6 15:35:42 2013 -0700
----------------------------------------------------------------------
.../org/apache/sentry/provider/file/Roles.java | 16 +-
.../file/AbstractTestSimplePolicyEngine.java | 22 ++-
.../tests/e2e/TestPerDBConfiguration.java | 173 +++++++++++++++++++
3 files changed, 207 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ecc85161/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/Roles.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/Roles.java b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/Roles.java
index 556be01..924c2cc 100644
--- a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/Roles.java
+++ b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/Roles.java
@@ -16,15 +16,17 @@
*/
package org.apache.sentry.provider.file;
+import java.util.Map.Entry;
+
import javax.annotation.Nullable;
+import org.apache.sentry.core.Database;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.io.Resources;
public class Roles {
private static final Logger LOGGER = LoggerFactory
@@ -44,16 +46,24 @@ public class Roles {
}
public ImmutableSet<String> getRoles(@Nullable String database, String group, Boolean isURI) {
ImmutableSet.Builder<String> resultBuilder = ImmutableSet.builder();
- String allowURIPerDbFile =
+ String allowURIPerDbFile =
System.getProperty(SimplePolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE);
Boolean consultPerDbRolesForURI = isURI && ("true".equalsIgnoreCase(allowURIPerDbFile));
- if(database != null) {
+ // handle Database.ALL
+ if (Database.ALL.getName().equals(database)) {
+ for(Entry<String, ImmutableSetMultimap<String, String>> dbListEntry : perDatabaseRoles.entrySet()) {
+ if (dbListEntry.getValue().containsKey(group)) {
+ resultBuilder.addAll(dbListEntry.getValue().get(group));
+ }
+ }
+ } else if(database != null) {
ImmutableSetMultimap<String, String> dbPolicies = perDatabaseRoles.get(database);
if(dbPolicies != null && dbPolicies.containsKey(group)) {
resultBuilder.addAll(dbPolicies.get(group));
}
}
+
if (consultPerDbRolesForURI) {
for(String db:perDatabaseRoles.keySet()) {
ImmutableSetMultimap<String, String> dbPolicies = perDatabaseRoles.get(db);
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ecc85161/sentry-provider/sentry-provider-file/src/test/java/org/apache/sentry/provider/file/AbstractTestSimplePolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-file/src/test/java/org/apache/sentry/provider/file/AbstractTestSimplePolicyEngine.java b/sentry-provider/sentry-provider-file/src/test/java/org/apache/sentry/provider/file/AbstractTestSimplePolicyEngine.java
index bfa2d68..5388b0f 100644
--- a/sentry-provider/sentry-provider-file/src/test/java/org/apache/sentry/provider/file/AbstractTestSimplePolicyEngine.java
+++ b/sentry-provider/sentry-provider-file/src/test/java/org/apache/sentry/provider/file/AbstractTestSimplePolicyEngine.java
@@ -27,7 +27,6 @@ import junit.framework.Assert;
import org.apache.commons.io.FileUtils;
import org.apache.sentry.core.Authorizable;
import org.apache.sentry.core.Database;
-import org.apache.sentry.provider.file.PolicyEngine;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -136,6 +135,27 @@ public abstract class AbstractTestSimplePolicyEngine {
.toString());
}
+ @Test
+ public void testDbAll() throws Exception {
+ authorizables.add(new Database(Database.ALL.getName()));
+ Set<String> expected = Sets.newTreeSet(Sets
+ .newHashSet(PERM_SERVER1_JUNIOR_ANALYST_ALL,
+ PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT));
+ Assert.assertEquals(expected.toString(),
+ new TreeSet<String>(policy.getPermissions(authorizables, list("jranalyst")).values())
+ .toString());
+ }
+
+ @Test
+ public void testDbAllforOtherGroup() throws Exception {
+ authorizables.add(new Database(Database.ALL.getName()));
+ Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
+ PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT));
+ Assert.assertEquals(expected.toString(),
+ new TreeSet<String>(policy.getPermissions(authorizables, list("other_group")).values())
+ .toString());
+ }
+
private static List<String> list(String... values) {
return Lists.newArrayList(values);
}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ecc85161/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDBConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDBConfiguration.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDBConfiguration.java
index b0523ab..7fb7f6c 100644
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDBConfiguration.java
+++ b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDBConfiguration.java
@@ -408,6 +408,179 @@ public class TestPerDBConfiguration extends AbstractTestWithStaticLocalFS {
System.setProperty(SimplePolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "false");
}
+ /**
+ * Test 'use default' statement. It should work as long as the user as privilege to assess any object in system
+ * @throws Exception
+ */
+ @Test
+ public void testDefaultDb() throws Exception {
+ context = createContext();
+ File policyFile = context.getPolicyFile();
+ File dataDir = context.getDataDir();
+ //copy data file to test dir
+ File dataFile = new File(dataDir, MULTI_TYPE_DATA_FILE_NAME);
+ FileOutputStream to = new FileOutputStream(dataFile);
+ Resources.copy(Resources.getResource(MULTI_TYPE_DATA_FILE_NAME), to);
+ to.close();
+ //delete existing policy file; create new policy file
+ assertTrue("Could not delete " + policyFile, context.deletePolicyFile());
+
+ String[] policyFileContents = {
+ // groups : role -> group
+ "[groups]",
+ "admin = all_server",
+ "user_group1 = select_tbl1",
+ // roles: privileges -> role
+ "[roles]",
+ "all_server = server=server1",
+ "select_tbl1 = server=server1->db=db1->table=tbl1->action=select",
+ // users: users -> groups
+ "[users]",
+ "hive = admin",
+ "user_1 = user_group1",
+ "user_2 = user_group2",
+ };
+ context.makeNewPolicy(policyFileContents);
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("hive", "hive");
+ Statement statement = context.createStatement(connection);
+
+ statement.execute("USE default");
+
+ statement.execute("DROP DATABASE IF EXISTS db1 CASCADE");
+ statement.execute("CREATE DATABASE db1");
+ statement.execute("USE db1");
+ statement.execute("CREATE TABLE tbl1(B INT, A STRING) " +
+ " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("DROP DATABASE IF EXISTS db2 CASCADE");
+ statement.close();
+ connection.close();
+
+ // user_1 should be able to access default
+ connection = context.createConnection("user_1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE default");
+ statement.close();
+ connection.close();
+
+ // user_2 should NOT be able to access default since it does have access to any other object
+ connection = context.createConnection("user_2", "password");
+ statement = context.createStatement(connection);
+ context.assertAuthzException(statement, "USE default");
+ statement.close();
+ connection.close();
+
+ }
+
+ @Test
+ public void testDefaultDBwithDbPolicy() throws Exception {
+ context = createContext();
+ File policyFile = context.getPolicyFile();
+ File db2PolicyFile = new File(policyFile.getParent(), DB2_POLICY_FILE);
+ File defaultPolicyFile = new File(policyFile.getParent(), "default-policy-file.ini");
+ File dataDir = context.getDataDir();
+ //copy data file to test dir
+ File dataFile = new File(dataDir, MULTI_TYPE_DATA_FILE_NAME);
+ FileOutputStream to = new FileOutputStream(dataFile);
+ Resources.copy(Resources.getResource(MULTI_TYPE_DATA_FILE_NAME), to);
+ to.close();
+ //delete existing policy file; create new policy file
+ assertTrue("Could not delete " + policyFile, context.deletePolicyFile());
+ assertTrue("Could not delete " + db2PolicyFile,!db2PolicyFile.exists() || db2PolicyFile.delete());
+ assertTrue("Could not delete " + defaultPolicyFile,!defaultPolicyFile.exists() || defaultPolicyFile.delete());
+
+ String[] policyFileContents = {
+ // groups : role -> group
+ "[groups]",
+ "admin = all_server",
+ "user_group1 = select_tbl1",
+ "user_group2 = select_tbl2",
+ // roles: privileges -> role
+ "[roles]",
+ "all_server = server=server1",
+ "select_tbl1 = server=server1->db=db1->table=tbl1->action=select",
+ // users: users -> groups
+ "[users]",
+ "hive = admin",
+ "user_1 = user_group1",
+ "user_2 = user_group2",
+ "user_3 = user_group3",
+ "[databases]",
+ "db2 = " + db2PolicyFile.getPath(),
+ "default = " + defaultPolicyFile.getPath()
+ };
+ context.makeNewPolicy(policyFileContents);
+
+ String[] db2PolicyFileContents = {
+ "[groups]",
+ "user_group2 = select_tbl2",
+ "[roles]",
+ "select_tbl2 = server=server1->db=db2->table=tbl2->action=select"
+ };
+ Files.write(Joiner.on("\n").join(db2PolicyFileContents), db2PolicyFile, Charsets.UTF_8);
+
+ String[] defautlPolicyFileContents = {
+ "[groups]",
+ "user_group2 = select_def",
+ "[roles]",
+ "select_def = server=server1->db=default->table=dtab->action=select"
+ };
+ Files.write(Joiner.on("\n").join(defautlPolicyFileContents), defaultPolicyFile, Charsets.UTF_8);
+
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("hive", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE default");
+ statement.execute("CREATE TABLE dtab(B INT, A STRING) " +
+ " row format delimited fields terminated by '|' stored as textfile");
+
+ statement.execute("DROP DATABASE IF EXISTS db1 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS db2 CASCADE");
+ statement.execute("CREATE DATABASE db1");
+ statement.execute("USE db1");
+ statement.execute("CREATE TABLE tbl1(B INT, A STRING) " +
+ " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("DROP DATABASE IF EXISTS db2 CASCADE");
+ statement.execute("CREATE DATABASE db2");
+ statement.execute("USE db2");
+ statement.execute("CREATE TABLE tbl2(B INT, A STRING) " +
+ " row format delimited fields terminated by '|' stored as textfile");
+ statement.close();
+ connection.close();
+
+ // user_1 should be able to switch to default, but not the tables from default
+ connection = context.createConnection("user_1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db1");
+ statement.execute("USE default");
+ context.assertAuthzException(statement, "SELECT * FROM dtab");
+ statement.execute("USE db1");
+ context.assertAuthzException(statement, "SELECT * FROM default.dtab");
+
+ statement.close();
+ connection.close();
+
+ // user_2 should be able to access default and select from default's tables
+ connection = context.createConnection("user_2", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db2");
+ statement.execute("USE default");
+ statement.execute("SELECT * FROM dtab");
+ statement.execute("USE db2");
+ statement.execute("SELECT * FROM default.dtab");
+ statement.close();
+ connection.close();
+
+ // user_3 should NOT be able to switch to default since it doesn't have access to any objects
+ connection = context.createConnection("user_3", "password");
+ statement = context.createStatement(connection);
+ context.assertAuthzException(statement, "USE default");
+ statement.close();
+ connection.close();
+ }
+
private void verifyCount(Statement statement, String query) throws SQLException {
ResultSet resultSet = statement.executeQuery(query);
int count = 0;