Repository: incubator-sentry
Updated Branches:
  refs/heads/master afe8cd8df -> 540424d50


SENTRY-217: Add Insert and URI tests for Sentry DB provider (Prasad Mujumdar 
via Sravya Tirukkovalur)


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

Branch: refs/heads/master
Commit: 540424d50f84c3ad0bd65370374e3d70c352bb72
Parents: afe8cd8
Author: Sravya Tirukkovalur <[email protected]>
Authored: Wed May 21 13:25:31 2014 -0700
Committer: Sravya Tirukkovalur <[email protected]>
Committed: Wed May 21 13:27:59 2014 -0700

----------------------------------------------------------------------
 .../apache/hadoop/hive/SentryHiveConstants.java |   4 +-
 .../hive/ql/exec/SentryGrantRevokeTask.java     |  53 +++--
 .../ql/exec/SentryHivePrivilegeObjectDesc.java  |  42 ++++
 .../SentryHiveAuthorizationTaskFactoryImpl.java |  20 +-
 .../db/service/persistent/SentryStore.java      |   4 +-
 .../db/service/persistent/TestSentryStore.java  |   6 +-
 .../TestSentryStoreToAuthorizable.java          |   8 +-
 sentry-tests/sentry-tests-hive/pom.xml          |  85 +++++---
 .../dbprovider/AbstractTestWithDbProvider.java  | 155 +++++++++++++
 .../tests/e2e/dbprovider/TestDbEndToEnd.java    | 218 +++++++++++++++++++
 10 files changed, 532 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/SentryHiveConstants.java
----------------------------------------------------------------------
diff --git 
a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/SentryHiveConstants.java
 
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/SentryHiveConstants.java
index db14b6c..26eea91 100644
--- 
a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/SentryHiveConstants.java
+++ 
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/SentryHiveConstants.java
@@ -22,8 +22,8 @@ import java.util.EnumSet;
 import 
org.apache.hadoop.hive.ql.security.authorization.Privilege.PrivilegeType;
 
 public class SentryHiveConstants {
-  // TODO add INSERT
-  public static final EnumSet<PrivilegeType> ALLOWED_PRIVS = 
EnumSet.of(PrivilegeType.ALL, PrivilegeType.SELECT);
+  public static final EnumSet<PrivilegeType> ALLOWED_PRIVS = EnumSet.of(
+      PrivilegeType.ALL, PrivilegeType.SELECT, PrivilegeType.INSERT);
 
   public static final String PRIVILEGE_NOT_SUPPORTED = "Sentry does not 
support privilege: ";
   public static final String COLUMN_PRIVS_NOT_SUPPORTED = "Sentry users should 
use views to grant privileges on columns";

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
----------------------------------------------------------------------
diff --git 
a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
 
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
index b6f39ad..ec0b658 100644
--- 
a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
+++ 
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
@@ -17,9 +17,13 @@ package org.apache.hadoop.hive.ql.exec;
  * limitations under the License.
  */
 
-import com.google.common.base.Preconditions;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Set;
+
 import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -50,15 +54,13 @@ import 
org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
 import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
 import org.apache.sentry.provider.db.service.thrift.TSentryRole;
 import org.apache.sentry.service.thrift.SentryServiceClientFactory;
+import org.apache.sentry.service.thrift.ServiceConstants.PrivilegeScope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Set;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
 
 public class SentryGrantRevokeTask extends Task<DDLWork> implements 
Serializable {
   private static final Logger LOG = LoggerFactory
@@ -313,7 +315,12 @@ public class SentryGrantRevokeTask extends Task<DDLWork> 
implements Serializable
 
     for (TSentryPrivilege privilege : privileges) {
 
-      appendNonNull(builder, privilege.getDbName(), true);
+      if (PrivilegeScope.URI.name().equalsIgnoreCase(
+          privilege.getPrivilegeScope())) {
+        appendNonNull(builder, privilege.getURI(), true);
+      } else {
+        appendNonNull(builder, privilege.getDbName(), true);
+      }
       appendNonNull(builder, privilege.getTableName());
       appendNonNull(builder, null);//getPartValues()
       appendNonNull(builder, null);//getColumnName()
@@ -373,14 +380,24 @@ public class SentryGrantRevokeTask extends Task<DDLWork> 
implements Serializable
       SentryPolicyServiceClient sentryClient, String subject,
       Set<String> subjectGroups, String server,
       boolean isGrant, List<PrincipalDesc> principals,
-      List<PrivilegeDesc> privileges, PrivilegeObjectDesc privSubjectDesc) 
throws SentryUserException {
+ List<PrivilegeDesc> privileges,
+      PrivilegeObjectDesc privSubjectObjDesc) throws SentryUserException {
     if (privileges == null || privileges.size() == 0) {
       console.printError("No privilege found.");
       return RETURN_CODE_FAILURE;
     }
+
     String dbName = null;
     String tableName = null;
+    String uriPath = null;
+    String serverName = null;
     try {
+      if (!(privSubjectObjDesc instanceof SentryHivePrivilegeObjectDesc)) {
+        throw new HiveException(
+            "Privilege subject not parsed correctly by Sentry");
+      }
+      SentryHivePrivilegeObjectDesc privSubjectDesc = 
(SentryHivePrivilegeObjectDesc) privSubjectObjDesc;
+
       if (privSubjectDesc == null) {
         throw new HiveException("Privilege subject cannot be null");
       }
@@ -393,6 +410,10 @@ public class SentryGrantRevokeTask extends Task<DDLWork> 
implements Serializable
         DatabaseTable dbTable = parseDBTable(obj);
         dbName = dbTable.getDatabase();
         tableName = dbTable.getTable();
+      } else if (privSubjectDesc.getUri()) {
+        uriPath = privSubjectDesc.getObject();
+      } else if (privSubjectDesc.getServer()) {
+        serverName = privSubjectDesc.getObject();
       } else {
         dbName = privSubjectDesc.getObject();
       }
@@ -413,7 +434,13 @@ public class SentryGrantRevokeTask extends Task<DDLWork> 
implements Serializable
         }
         for (PrivilegeDesc privDesc : privileges) {
           if (isGrant) {
-            if (tableName == null) {
+            if (serverName != null) {
+              sentryClient.grantServerPrivilege(subject, subjectGroups,
+                  princ.getName(), serverName);
+            } else if (uriPath != null) {
+              sentryClient.grantURIPrivilege(subject, subjectGroups,
+                  princ.getName(), server, uriPath);
+            } else if (tableName == null) {
               sentryClient.grantDatabasePrivilege(subject, subjectGroups, 
princ.getName(), server, dbName);
             } else {
               sentryClient.grantTablePrivilege(subject, subjectGroups, 
princ.getName(), server, dbName,
@@ -503,4 +530,4 @@ public class SentryGrantRevokeTask extends Task<DDLWork> 
implements Serializable
   public String getName() {
     return "SENTRY";
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryHivePrivilegeObjectDesc.java
----------------------------------------------------------------------
diff --git 
a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryHivePrivilegeObjectDesc.java
 
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryHivePrivilegeObjectDesc.java
new file mode 100644
index 0000000..0447e26
--- /dev/null
+++ 
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryHivePrivilegeObjectDesc.java
@@ -0,0 +1,42 @@
+/*
+ * 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.hadoop.hive.ql.exec;
+
+import org.apache.hadoop.hive.ql.plan.PrivilegeObjectDesc;
+
+public class SentryHivePrivilegeObjectDesc extends PrivilegeObjectDesc {
+  private boolean isUri;
+  private boolean isServer;
+
+  public boolean getUri() {
+    return isUri;
+  }
+
+  public void setUri(boolean isUri) {
+    this.isUri = isUri;
+  }
+
+  public boolean getServer() {
+    return isServer;
+  }
+
+  public void setServer(boolean isServer) {
+    this.isServer = isServer;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
----------------------------------------------------------------------
diff --git 
a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
 
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
index 9ca11ae..6d89041 100644
--- 
a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
+++ 
b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
@@ -22,6 +22,7 @@ import org.apache.hadoop.hive.SentryHiveConstants;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.metastore.api.PrincipalType;
 import org.apache.hadoop.hive.ql.exec.SentryGrantRevokeTask;
+import org.apache.hadoop.hive.ql.exec.SentryHivePrivilegeObjectDesc;
 import org.apache.hadoop.hive.ql.exec.Task;
 import org.apache.hadoop.hive.ql.exec.TaskFactory;
 import org.apache.hadoop.hive.ql.hooks.ReadEntity;
@@ -114,7 +115,7 @@ public class SentryHiveAuthorizationTaskFactoryImpl 
implements HiveAuthorization
         (ASTNode) ast.getChild(0));
     List<PrincipalDesc> principalDesc = analyzePrincipalListDef(
         (ASTNode) ast.getChild(1));
-    PrivilegeObjectDesc privilegeObj = null;
+    SentryHivePrivilegeObjectDesc privilegeObj = null;
 
     if (ast.getChildCount() > 2) {
       for (int i = 2; i < ast.getChildCount(); i++) {
@@ -291,20 +292,27 @@ public class SentryHiveAuthorizationTaskFactoryImpl 
implements HiveAuthorization
     return createTask(new DDLWork(inputs, outputs, showRolesDesc));
   }
 
-  private PrivilegeObjectDesc analyzePrivilegeObject(ASTNode ast)
+  private SentryHivePrivilegeObjectDesc analyzePrivilegeObject(ASTNode ast)
       throws SemanticException {
-    PrivilegeObjectDesc subject = new PrivilegeObjectDesc();
-    
subject.setObject(BaseSemanticAnalyzer.unescapeIdentifier(ast.getChild(0).getText()));
+    SentryHivePrivilegeObjectDesc subject = new 
SentryHivePrivilegeObjectDesc();
+    String privilegeObject = BaseSemanticAnalyzer.unescapeIdentifier(ast
+        .getChild(0).getText());
     if (ast.getChildCount() > 1) {
-      for (int i = 0; i < ast.getChildCount(); i++) {
+      for (int i = 1; i < ast.getChildCount(); i++) {
         ASTNode astChild = (ASTNode) ast.getChild(i);
         if (astChild.getToken().getType() == HiveParser.TOK_PARTSPEC) {
           throw new 
SemanticException(SentryHiveConstants.PARTITION_PRIVS_NOT_SUPPORTED);
+        } else if (astChild.getToken().getType() == HiveParser.TOK_URI) {
+          privilegeObject = privilegeObject.replaceAll("'", "");
+          subject.setUri(true);
+        } else if (astChild.getToken().getType() == HiveParser.TOK_SERVER) {
+          subject.setServer(true);
         } else {
-          subject.setTable(ast.getChild(0) != null);
+          subject.setTable(true);
         }
       }
     }
+    subject.setObject(privilegeObject);
     return subject;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
index 7971ea3..8f0ecfd 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
@@ -724,7 +724,8 @@ public class SentryStore {
       
authorizable.add(KV_JOINER.join(AuthorizableType.URI.name().toLowerCase(),
           privilege.getURI()));
     }
-    if (!Strings.nullToEmpty(privilege.getAction()).isEmpty()) {
+    if (!Strings.nullToEmpty(privilege.getAction()).isEmpty()
+        && !privilege.getAction().equalsIgnoreCase(AccessConstants.ALL)) {
       
authorizable.add(KV_JOINER.join(ProviderConstants.PRIVILEGE_NAME.toLowerCase(),
           privilege.getAction()));
     }
@@ -897,4 +898,3 @@ public class SentryStore {
 
   }
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
index 0d8e24f..67b05e6 100644
--- 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
+++ 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
@@ -258,7 +258,8 @@ public class TestSentryStore {
     
assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
         
SentryStore.toTrimedLower(sentryStore.listSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
             new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
-    assertEquals(Sets.newHashSet("server=server1"),
+    assertEquals(Sets.newHashSet(
+        "server=server1->db=db1->table=tbl1->action=select", "server=server1"),
         
SentryStore.toTrimedLower(sentryStore.listSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
             new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
     // unknown active role
@@ -280,7 +281,8 @@ public class TestSentryStore {
         
SentryStore.toTrimedLower(sentryStore.listSentryPrivilegesForProvider(Sets.
             newHashSet(groupName1, groupName2),
             new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
-    assertEquals(Sets.newHashSet("server=server1"),
+    assertEquals(Sets.newHashSet(
+        "server=server1->db=db1->table=tbl1->action=select", "server=server1"),
         
SentryStore.toTrimedLower(sentryStore.listSentryPrivilegesForProvider(Sets.
             newHashSet(groupName1, groupName2),
             new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java
 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java
index 9c851eb..d77786a 100644
--- 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java
+++ 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java
@@ -35,7 +35,7 @@ public class TestSentryStoreToAuthorizable {
         SentryStore.toAuthorizable(privilege));
     privilege = new MSentryPrivilege(null, null, "server1", null, null, null,
         AccessConstants.ALL);
-    assertEquals("server=server1->action=*",
+    assertEquals("server=server1",
         SentryStore.toAuthorizable(privilege));
   }
 
@@ -54,7 +54,7 @@ public class TestSentryStoreToAuthorizable {
         SentryStore.toAuthorizable(privilege));
     privilege = new MSentryPrivilege(null, null, "server1", "db1", "tbl1", 
null,
         AccessConstants.ALL);
-    assertEquals("server=server1->db=db1->table=tbl1->action=*",
+    assertEquals("server=server1->db=db1->table=tbl1",
         SentryStore.toAuthorizable(privilege));
   }
 
@@ -65,7 +65,7 @@ public class TestSentryStoreToAuthorizable {
         SentryStore.toAuthorizable(privilege));
     privilege = new MSentryPrivilege(null, null, "server1", "db1", null, null,
         AccessConstants.ALL);
-    assertEquals("server=server1->db=db1->action=*",
+    assertEquals("server=server1->db=db1",
         SentryStore.toAuthorizable(privilege));
   }
 
@@ -80,7 +80,7 @@ public class TestSentryStoreToAuthorizable {
         SentryStore.toAuthorizable(privilege));
     privilege = new MSentryPrivilege(null, null, "server1", null, null, 
"file:///",
         AccessConstants.ALL);
-    assertEquals("server=server1->uri=file:///->action=*",
+    assertEquals("server=server1->uri=file:///",
         SentryStore.toAuthorizable(privilege));
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-tests/sentry-tests-hive/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/pom.xml 
b/sentry-tests/sentry-tests-hive/pom.xml
index 1d0e169..03802a3 100644
--- a/sentry-tests/sentry-tests-hive/pom.xml
+++ b/sentry-tests/sentry-tests-hive/pom.xml
@@ -27,8 +27,10 @@ limitations under the License.
   <name>Sentry Hive Tests</name>
   <description>end to end tests for sentry-hive integration</description>
   <properties>
-    <hadoop-dist></hadoop-dist>
+  <!--
+    <hadoop-dist>.</hadoop-dist>
     <hive-dist>${hadoop-dist}</hive-dist>
+  -->
     <HADOOP_CONF_DIR>${env.HADOOP_CONF_DIR}</HADOOP_CONF_DIR>
     <HIVE_CONF_DIR>${env.HIVE_CONF_DIR}</HIVE_CONF_DIR>
   </properties>
@@ -237,11 +239,51 @@ limitations under the License.
           </systemPropertyVariables>
         </configuration>
       </plugin>
+    </plugins>
+    <pluginManagement>
+      <plugins>
+        <!--This plugin's configuration is used to store Eclipse m2e settings 
only. It has no influence on the Maven build itself.-->
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-antrun-plugin</artifactId>
+                    <versionRange>[1.7,)</versionRange>
+                    <goals>
+                      <goal>run</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+  <profiles>
+   <profile>
+     <id>download-hadoop</id>
+     <activation>
+       <activeByDefault>false</activeByDefault>
+       <property><name>!skipTests</name></property>
+     </activation>
+     <build>
+     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-antrun-plugin</artifactId>
         <configuration>
-          <skipTests>false</skipTests>
+          <skipTests>true</skipTests>
         </configuration>
         <executions>
           <execution>
@@ -282,40 +324,15 @@ limitations under the License.
           </execution>
         </executions>
       </plugin>
-    </plugins>
-    <pluginManagement>
-      <plugins>
-        <!--This plugin's configuration is used to store Eclipse m2e settings 
only. It has no influence on the Maven build itself.-->
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-antrun-plugin</artifactId>
-                    <versionRange>[1.7,)</versionRange>
-                    <goals>
-                      <goal>run</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore></ignore>
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-  </build>
-  <profiles>
+     </plugins>
+    </build>
+   </profile>
    <profile>
      <id>link-hadoop</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+        <property><name>hadoop-dist</name></property>
+      </activation>
      <build>
       <plugins>
         <plugin>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/AbstractTestWithDbProvider.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/AbstractTestWithDbProvider.java
 
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/AbstractTestWithDbProvider.java
new file mode 100644
index 0000000..5b655f3
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/AbstractTestWithDbProvider.java
@@ -0,0 +1,155 @@
+/*
+ * 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.dbprovider;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+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.AbstractTestWithHiveServer;
+import org.apache.sentry.tests.e2e.hive.Context;
+import org.apache.sentry.tests.e2e.hive.StaticUserGroup;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.After;
+import org.junit.BeforeClass;
+
+import com.google.common.collect.Maps;
+import com.google.common.io.Files;
+
+public abstract class AbstractTestWithDbProvider extends 
AbstractTestWithHiveServer {
+
+  protected static final String SERVER_HOST = "localhost";
+
+  private Map<String, String> properties;
+  private File dbDir;
+  private SentryService sentryServer;
+  private Configuration conf;
+  protected PolicyFile policyFile;
+
+  @BeforeClass
+  public static void setupTest() throws Exception {
+  }
+
+  public void setupSentryService() throws Exception {
+    properties = Maps.newHashMap();
+    conf = new Configuration(false);
+    policyFile = new PolicyFile();
+
+    properties.put(HiveServerFactory.AUTHZ_PROVIDER_BACKEND, 
SimpleDBProviderBackend.class.getName());
+    properties.put(ConfVars.HIVE_AUTHORIZATION_TASK_FACTORY.varname,
+        SentryHiveAuthorizationTaskFactoryImpl.class.getName());
+    properties.put(ServerConfig.SECURITY_MODE, 
ServerConfig.SECURITY_MODE_NONE);
+    properties.put(ServerConfig.ADMIN_GROUPS, ADMINGROUP);
+    properties.put(ServerConfig.RPC_ADDRESS, SERVER_HOST);
+    properties.put(ServerConfig.RPC_PORT, String.valueOf(0));
+    properties.put(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false");
+    dbDir = new File(Files.createTempDir(), "sentry_policy_db");
+    properties.put(ServerConfig.SENTRY_STORE_JDBC_URL,
+        "jdbc:derby:;databaseName=" + dbDir.getPath() + ";create=true");
+    for (Map.Entry<String, String> entry : properties.entrySet()) {
+      conf.set(entry.getKey(), entry.getValue());
+    }
+    sentryServer = new SentryServiceFactory().create(conf);
+    properties.put(ClientConfig.SERVER_RPC_ADDRESS, 
sentryServer.getAddress().getHostString());
+    properties.put(ClientConfig.SERVER_RPC_PORT,
+        String.valueOf(sentryServer.getAddress().getPort()));
+    startSentryService();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (sentryServer != null) {
+      sentryServer.stop();
+    }
+    if (dbDir != null) {
+      FileUtils.deleteQuietly(dbDir);
+    }
+  }
+
+  public Context createContext() throws Exception {
+    setupSentryService();
+    Context context = createContext(properties);
+    policyFile
+    .setUserGroupMapping(StaticUserGroup.getStaticMapping())
+    .write(context.getPolicyFile());
+    return context;
+  }
+
+  protected void setupAdmin(Context context) throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = connection.createStatement();
+    statement.execute("CREATE ROLE admin_role");
+    statement.execute("GRANT ALL ON SERVER "
+        + HiveServerFactory.DEFAULT_AUTHZ_SERVER_NAME + " TO ROLE admin_role");
+    statement.execute("GRANT ROLE admin_role TO GROUP " + ADMINGROUP);
+    statement.close();
+    connection.close();
+  }
+
+  protected void createDb(Connection connection, String...dbs) throws 
Exception {
+    Statement statement = connection.createStatement();
+    for(String db : dbs) {
+      statement.execute("CREATE DATABASE " + db);
+    }
+    statement.close();
+  }
+
+  protected void createTable(Connection connection , String db, File dataFile, 
String...tables)
+      throws Exception {
+    Statement statement = connection.createStatement();
+    statement.execute("USE " + db);
+    for(String table : tables) {
+      statement.execute("DROP TABLE IF EXISTS " + table);
+      statement.execute("create table " + table
+          + " (under_col int comment 'the under column', value string)");
+      statement.execute("load data local inpath '" + dataFile.getPath()
+          + "' into table " + table);
+      ResultSet res = statement.executeQuery("select * from " + table);
+      Assert.assertTrue("Table should have data after load", res.next());
+      res.close();
+    }
+    statement.close();
+  }
+
+  private void startSentryService() throws Exception {
+    sentryServer.start();
+    final long start = System.currentTimeMillis();
+    while(!sentryServer.isRunning()) {
+      Thread.sleep(1000);
+      if(System.currentTimeMillis() - start > 60000L) {
+        throw new TimeoutException("Server did not start after 60 seconds");
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/540424d5/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbEndToEnd.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbEndToEnd.java
 
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbEndToEnd.java
new file mode 100644
index 0000000..eb9f91b
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbEndToEnd.java
@@ -0,0 +1,218 @@
+/*
+ * 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.dbprovider;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import org.apache.sentry.tests.e2e.hive.Context;
+import org.apache.sentry.tests.e2e.hive.StaticUserGroup;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestDbEndToEnd extends AbstractTestWithDbProvider {
+  private Context context;
+  private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+  private File dataFile;
+
+  @Before
+  public void setup() throws Exception {
+    context = createContext();
+    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();
+    setupAdmin(context);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (context != null) {
+      context.close();
+    }
+  }
+
+  @Test
+  public void testBasic() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE TABLE t1 (c1 string)");
+    statement.execute("CREATE ROLE user_role");
+    statement.execute("GRANT SELECT ON TABLE t1 TO ROLE user_role");
+    statement.execute("GRANT ROLE user_role TO GROUP " + USERGROUP1);
+    statement.close();
+    connection.close();
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    context.assertSentryServiceAccessDenied(statement, "CREATE ROLE r2");
+    // test default of ALL
+    statement.execute("SELECT * FROM t1");
+    // test a specific role
+    statement.execute("SET ROLE user_role");
+    statement.execute("SELECT * FROM t1");
+    // test NONE
+    statement.execute("SET ROLE NONE");
+    context.assertAuthzException(statement, "SELECT * FROM t1");
+    // test ALL
+    statement.execute("SET ROLE ALL");
+    statement.execute("SELECT * FROM t1");
+    statement.close();
+    connection.close();
+  }
+
+  @Test
+  public void testUPrivileges() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE TABLE t1 (c1 string)");
+    statement.execute("CREATE ROLE user_role");
+    statement.execute("CREATE ROLE uri_role");
+    statement.execute("GRANT SELECT ON URI 'file://" + dataDir.getPath()
+        + "' TO ROLE uri_role");
+    statement.execute("GRANT INSERT ON TABLE t1 TO ROLE user_role");
+
+    statement.execute("GRANT ROLE user_role TO GROUP " + USERGROUP1);
+    statement.execute("GRANT ROLE uri_role TO GROUP " + USERGROUP1);
+
+    ResultSet resultSet = statement.executeQuery("SHOW GRANT ROLE uri_role");
+    assertTrue(resultSet.next());
+    assertEquals("file://" + dataDir.getPath(), resultSet.getString(1));
+    resultSet.close();
+
+    resultSet = statement.executeQuery("SHOW GRANT ROLE user_role");
+    assertTrue(resultSet.next());
+    assertEquals("default", resultSet.getString(1));
+    assertEquals("t1", resultSet.getString(2));
+    resultSet.close();
+
+    statement.close();
+    connection.close();
+
+  }
+
+  /**
+   * Steps:
+   * 1. admin create a new experimental database
+   * 2. admin create a new production database, create table, load data
+   * 3. admin grant privilege all@'experimental database' to usergroup1
+   * 4. user create table, load data in experimental DB
+   * 5. user create view based on table in experimental DB
+   * 6. admin create table (same name) in production DB
+   * 7. admin grant [email protected] to group
+   *    admin grant [email protected] to group
+   * 8. user load data from experimental table to production table
+   */
+  @Test
+  public void testEndToEnd1() throws Exception {
+    policyFile
+      .setUserGroupMapping(StaticUserGroup.getStaticMapping())
+      .write(context.getPolicyFile());
+
+    String dbName1 = "db_1";
+    String dbName2 = "productionDB";
+    String tableName1 = "tb_1";
+    String tableName2 = "tb_2";
+    String viewName1 = "view_1";
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    // 1
+    statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+    statement.execute("CREATE DATABASE " + dbName1);
+    // 2
+    statement.execute("DROP DATABASE IF EXISTS " + dbName2 + " CASCADE");
+    statement.execute("CREATE DATABASE " + dbName2);
+    statement.execute("USE " + dbName2);
+    statement.execute("DROP TABLE IF EXISTS " + dbName2 + "." + tableName2);
+    statement.execute("create table " + dbName2 + "." + tableName2
+        + " (under_col int comment 'the under column', value string)");
+    statement.execute("load data local inpath '" + dataFile.getPath()
+            + "' into table " + tableName2);
+
+    // 3
+    statement.execute("CREATE ROLE all_db1");
+    statement.execute("GRANT ALL ON DATABASE " + dbName1 + " TO ROLE all_db1");
+
+    statement.execute("CREATE ROLE select_tb1");
+    statement.execute("CREATE ROLE insert_tb1");
+    statement.execute("CREATE ROLE insert_tb2");
+    statement.execute("CREATE ROLE data_uri");
+
+    statement.execute("USE " + dbName2);
+    statement.execute("GRANT INSERT ON TABLE " + tableName1
+        + " TO ROLE insert_tb1");
+    statement.execute("GRANT INSERT ON TABLE " + tableName2
+        + " TO ROLE insert_tb2");
+    statement.execute("GRANT ALL ON URI 'file://" + dataDir.getPath()
+        + "' TO ROLE data_uri");
+
+    statement.execute("USE " + dbName1);
+    statement.execute("GRANT SELECT ON TABLE " + tableName1
+        + " TO ROLE select_tb1");
+
+    statement
+        .execute("GRANT ROLE all_db1, select_tb1, insert_tb1, insert_tb2, 
data_uri TO GROUP "
+            + USERGROUP1);
+
+    statement.close();
+    connection.close();
+
+    // 4
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    statement.execute("USE " + dbName1);
+    statement.execute("DROP TABLE IF EXISTS " + dbName1 + "." + tableName1);
+    statement.execute("create table " + dbName1 + "." + tableName1
+        + " (under_col int comment 'the under column', value string)");
+    statement.execute("load data local inpath '" + dataFile.getPath()
+            + "' into table " + tableName1);
+
+    // 5
+    statement.execute("CREATE VIEW " + viewName1 + " (value) AS SELECT value 
from " + tableName1 + " LIMIT 10");
+    statement.close();
+    connection.close();
+
+    // 7
+    connection = context.createConnection(ADMIN1);
+    statement = context.createStatement(connection);
+    statement.execute("USE " + dbName2);
+    statement.execute("DROP TABLE IF EXISTS " + dbName1 + "." + tableName1);
+    statement.execute("create table " + dbName1 + "." + tableName1
+        + " (under_col int comment 'the under column', value string)");
+    statement.close();
+    connection.close();
+
+    // 8
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    statement.execute("USE " + dbName2);
+    statement.execute("INSERT OVERWRITE TABLE " +
+        dbName2 + "." + tableName2 + " SELECT * FROM " + dbName1
+        + "." + tableName1);
+    statement.close();
+    connection.close();
+  }
+}

Reply via email to