You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by pr...@apache.org on 2014/04/11 18:36:16 UTC

git commit: SENTRY-152: Sentry checks permissions on underlying partitioned table when accessing a view

Repository: incubator-sentry
Updated Branches:
  refs/heads/master e0e70e2cd -> 197164e06


SENTRY-152: Sentry checks permissions on underlying partitioned table when accessing a view


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

Branch: refs/heads/master
Commit: 197164e0624e3add1f1a7dd96c614d03f6df87c6
Parents: e0e70e2
Author: Prasad Mujumdar <pr...@cloudera.com>
Authored: Fri Apr 11 09:36:01 2014 -0700
Committer: Prasad Mujumdar <pr...@cloudera.com>
Committed: Fri Apr 11 09:36:01 2014 -0700

----------------------------------------------------------------------
 .../binding/hive/HiveAuthzBindingHook.java      |   2 +-
 .../tests/e2e/hive/TestViewPrivileges.java      | 180 +++++++++++++++++++
 2 files changed, 181 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/197164e0/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
index 8e5cf4e..f8c694c 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java
@@ -680,7 +680,7 @@ implements HiveDriverFilterHook {
    */
   private boolean isChildTabForView(ReadEntity readEntity) {
     // If this is a table added for view, then we need to skip that
-    if (!readEntity.getType().equals(Type.TABLE)) {
+    if (!readEntity.getType().equals(Type.TABLE) && !readEntity.getType().equals(Type.PARTITION)) {
       return false;
     }
     if ((readEntity.getParents() != null) && (readEntity.getParents().size() > 0)) {

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/197164e0/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestViewPrivileges.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestViewPrivileges.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestViewPrivileges.java
new file mode 100644
index 0000000..0595ffb
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestViewPrivileges.java
@@ -0,0 +1,180 @@
+/*
+ * 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 static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.sentry.binding.hive.SentryHiveAuthorizationTaskFactoryImpl;
+import org.apache.sentry.provider.db.SimpleDBProviderBackend;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.service.thrift.SentryService;
+import org.apache.sentry.service.thrift.SentryServiceFactory;
+import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig;
+import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+import com.google.common.io.Files;
+import com.google.common.io.Resources;
+
+public class TestViewPrivileges extends AbstractTestWithHiveServer {
+  protected static final String SERVER_HOST = "localhost";
+
+  private Context context;
+  private Map<String, String> properties;
+  private PolicyFile policyFile;
+
+  private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+
+  @Before
+  public void setUp() throws Exception {
+    properties = Maps.newHashMap();
+    policyFile = PolicyFile.setAdminOnServer1(ADMINGROUP);
+    context = createContext(properties);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if(context != null) {
+      context.close();
+    }
+  }
+
+  @Test
+  public void testPartitionedViewOnJoin() throws Exception {
+    // copy data file to test dir
+    File dataDir = context.getDataDir();
+    File 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();
+
+    String viewName = "view1";
+    String db = "db1";
+    String tabNames[] = { "tab1", "tab2" } ;
+    policyFile
+        .addPermissionsToRole("view", "server=server1->db=" + db + "->table=" + viewName)
+        .addRolesToGroup(USERGROUP1, "view")
+        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+    policyFile.write(context.getPolicyFile());
+
+    //admin creates a view
+    Connection conn = context.createConnection(ADMIN1);
+    Statement stmt = context.createStatement(conn);
+    stmt.execute("DROP DATABASE IF EXISTS " + db + " CASCADE");
+    stmt.execute("CREATE DATABASE " + db);
+
+    stmt.execute("use " + db);
+    for (String tabName : tabNames) {
+      stmt.execute("create table " + tabName + " (id int) partitioned by (part string)");
+      stmt.execute("load data local inpath '" + dataFile + "' into table " + tabName + " PARTITION (part=\"a\")");
+      stmt.execute("load data local inpath '" + dataFile + "' into table " + tabName + " PARTITION (part=\"b\")");
+      ResultSet res = stmt.executeQuery("select count(*) from " + tabName);
+      org.junit.Assert.assertThat(res, notNullValue());
+      while(res.next()) {
+        Assume.assumeTrue(res.getInt(1) == new Integer(1000));
+      }
+    }
+    stmt.execute("create view " + viewName + " as select t1.id from " +
+        tabNames[0] + " t1 JOIN " + tabNames[1] + " t2 on (t1.id = t2.id) where t1.id<100");
+    ResultSet res = stmt.executeQuery("select count(*) from " + viewName);
+    org.junit.Assert.assertThat(res, notNullValue());
+    int rowsInView = 0;
+    while(res.next()) {
+      System.out.println("Admin: Rows in view: " + res.getInt(1));
+      rowsInView = res.getInt(1);
+    }
+
+    Connection userConn = context.createConnection(USER1_1);
+    Statement userStmt = context.createStatement(userConn);
+    userStmt.execute("use " + db);
+    res = userStmt.executeQuery("select count(*) from " + viewName);
+    org.junit.Assert.assertThat(res, notNullValue());
+    while(res.next()) {
+      System.out.println("User1_1: Rows in view: " + res.getInt(1));
+      org.junit.Assert.assertThat(res.getInt(1), is(rowsInView));
+    }
+  }
+
+  @Test
+  public void testPartitioned() throws Exception {
+    // copy data file to test dir
+    File dataDir = context.getDataDir();
+    File 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();
+
+    String viewName = "view1";
+    String db = "db1";
+    String tabName = "tab1";
+    policyFile
+        .addPermissionsToRole("view", "server=server1->db=" + db + "->table=" + viewName)
+        .addRolesToGroup(USERGROUP1, "view")
+        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+    policyFile.write(context.getPolicyFile());
+
+    //admin creates a view
+    Connection conn = context.createConnection(ADMIN1);
+    Statement stmt = context.createStatement(conn);
+    stmt.execute("DROP DATABASE IF EXISTS " + db + " CASCADE");
+    stmt.execute("CREATE DATABASE " + db);
+
+    stmt.execute("use " + db);
+    stmt.execute("create table " + tabName + " (id int) partitioned by (part string)");
+    stmt.execute("load data local inpath '" + dataFile + "' into table " + tabName + " PARTITION (part=\"a\")");
+    stmt.execute("load data local inpath '" + dataFile + "' into table " + tabName + " PARTITION (part=\"b\")");
+    ResultSet res = stmt.executeQuery("select count(*) from " + tabName);
+    org.junit.Assert.assertThat(res, notNullValue());
+    while(res.next()) {
+      Assume.assumeTrue(res.getInt(1) == new Integer(1000));
+    }
+    stmt.execute("create view " + viewName + " as select * from " + tabName + " where id<100");
+    res = stmt.executeQuery("select count(*) from " + viewName);
+    org.junit.Assert.assertThat(res, notNullValue());
+    int rowsInView = 0;
+    while(res.next()) {
+      System.out.println("Admin: Rows in view: " + res.getInt(1));
+      rowsInView = res.getInt(1);
+    }
+    Connection userConn = context.createConnection(USER1_1);
+    Statement userStmt = context.createStatement(userConn);
+    userStmt.execute("use " + db);
+    res = userStmt.executeQuery("select count(*) from " + viewName);
+    org.junit.Assert.assertThat(res, notNullValue());
+    while(res.next()) {
+      System.out.println("User1_1: Rows in view: " + res.getInt(1));
+      org.junit.Assert.assertThat(res.getInt(1), is(rowsInView));
+    }
+  }
+}