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/21 01:38:50 UTC
[1/9] SENTRY-16: Move sentry-tests to sentry-tests-hive package
(Gregory Chanan via Shreepadma Venugopalan)
Updated Branches:
refs/heads/master 3c232e191 -> aef404c60
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/HiveServerFactory.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/HiveServerFactory.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/HiveServerFactory.java
deleted file mode 100644
index 628b247..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/HiveServerFactory.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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.hiveserver;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.ServerSocket;
-import java.net.URL;
-import java.util.Map;
-
-import com.google.common.annotations.VisibleForTesting;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.hdfs.DistributedFileSystem;
-import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
-import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
-import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
-import org.fest.reflect.core.Reflection;
-import org.junit.Assert;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.io.Resources;
-
-public class HiveServerFactory {
- private static final Logger LOGGER = LoggerFactory
- .getLogger(HiveServerFactory.class);
- private static final String HIVE_DRIVER_NAME = "org.apache.hive.jdbc.HiveDriver";
- private static final String DERBY_DRIVER_NAME = "org.apache.derby.jdbc.EmbeddedDriver";
- public static final String HIVESERVER2_TYPE = "sentry.e2etest.hiveServer2Type";
- public static final String KEEP_BASEDIR = "sentry.e2etest.keepBaseDir";
- public static final String METASTORE_CONNECTION_URL = HiveConf.ConfVars.METASTORECONNECTURLKEY.varname;
- public static final String WAREHOUSE_DIR = HiveConf.ConfVars.METASTOREWAREHOUSE.varname;
- public static final String AUTHZ_PROVIDER = HiveAuthzConf.AuthzConfVars.AUTHZ_PROVIDER.getVar();
- public static final String AUTHZ_PROVIDER_RESOURCE = HiveAuthzConf.AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar();
- public static final String AUTHZ_PROVIDER_FILENAME = "test-authz-provider.ini";
- public static final String AUTHZ_SERVER_NAME = HiveAuthzConf.AuthzConfVars.AUTHZ_SERVER_NAME.getVar();
- public static final String ACCESS_TESTING_MODE = HiveAuthzConf.AuthzConfVars.ACCESS_TESTING_MODE.getVar();
- public static final String HS2_PORT = ConfVars.HIVE_SERVER2_THRIFT_PORT.toString();
- public static final String SUPPORT_CONCURRENCY = HiveConf.ConfVars.HIVE_SUPPORT_CONCURRENCY.varname;
- public static final String HADOOPBIN = ConfVars.HADOOPBIN.toString();
- public static final String DEFAULT_AUTHZ_SERVER_NAME = "server1";
- public static final String HIVESERVER2_IMPERSONATION = "hive.server2.enable.doAs";
-
-
- static {
- try {
- Assert.assertNotNull(DERBY_DRIVER_NAME + " is null", Class.forName(DERBY_DRIVER_NAME));
- Assert.assertNotNull(HIVE_DRIVER_NAME + " is null", Class.forName(HIVE_DRIVER_NAME));
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static HiveServer create(Map<String, String> properties,
- File baseDir, File confDir, File logDir, File policyFile,
- FileSystem fileSystem)
- throws Exception {
- String type = properties.get(HIVESERVER2_TYPE);
- if(type == null) {
- type = System.getProperty(HIVESERVER2_TYPE);
- }
- if(type == null) {
- type = HiveServer2Type.InternalHiveServer2.name();
- }
- return create(HiveServer2Type.valueOf(type.trim()), properties,
- baseDir, confDir, logDir, policyFile, fileSystem);
- }
-
- private static HiveServer create(HiveServer2Type type,
- Map<String, String> properties, File baseDir, File confDir,
- File logDir, File policyFile, FileSystem fileSystem) throws Exception {
- if(!properties.containsKey(WAREHOUSE_DIR)) {
- LOGGER.error("fileSystem " + fileSystem.getClass().getSimpleName());
- if (fileSystem instanceof DistributedFileSystem) {
- @SuppressWarnings("static-access")
- String dfsUri = fileSystem.getDefaultUri(fileSystem.getConf()).toString();
- LOGGER.error("dfsUri " + dfsUri);
- properties.put(WAREHOUSE_DIR, dfsUri + "/data");
- } else {
- properties.put(WAREHOUSE_DIR, new File(baseDir, "warehouse").getPath());
- }
- }
- if(!properties.containsKey(METASTORE_CONNECTION_URL)) {
- properties.put(METASTORE_CONNECTION_URL,
- String.format("jdbc:derby:;databaseName=%s;create=true",
- new File(baseDir, "metastore").getPath()));
- }
- if(policyFile.exists()) {
- LOGGER.info("Policy file " + policyFile + " exists");
- } else {
- LOGGER.info("Creating policy file " + policyFile);
- FileOutputStream to = new FileOutputStream(policyFile);
- Resources.copy(Resources.getResource(AUTHZ_PROVIDER_FILENAME), to);
- to.close();
- }
- if(!properties.containsKey(ACCESS_TESTING_MODE)) {
- properties.put(ACCESS_TESTING_MODE, "true");
- }
- if(!properties.containsKey(AUTHZ_PROVIDER_RESOURCE)) {
- properties.put(AUTHZ_PROVIDER_RESOURCE, policyFile.getPath());
- }
- if(!properties.containsKey(AUTHZ_PROVIDER)) {
- properties.put(AUTHZ_PROVIDER, LocalGroupResourceAuthorizationProvider.class.getName());
- }
- if(!properties.containsKey(AUTHZ_SERVER_NAME)) {
- properties.put(AUTHZ_SERVER_NAME, DEFAULT_AUTHZ_SERVER_NAME);
- }
- if(!properties.containsKey(HS2_PORT)) {
- properties.put(HS2_PORT, String.valueOf(findPort()));
- }
- if(!properties.containsKey(SUPPORT_CONCURRENCY)) {
- properties.put(SUPPORT_CONCURRENCY, "false");
- }
- if(!properties.containsKey(HADOOPBIN)) {
- properties.put(HADOOPBIN, "./target/hadoop/bin/hadoop");
- }
- String hadoopBinPath = properties.get(HADOOPBIN);
- Assert.assertNotNull(hadoopBinPath, "Hadoop Bin");
- File hadoopBin = new File(hadoopBinPath);
- if(!hadoopBin.isFile()) {
- Assert.fail("Path to hadoop bin " + hadoopBin.getPath() + "is invalid. "
- + "Perhaps you missed the download-hadoop profile.");
- }
- /*
- * This hack, setting the hiveSiteURL field removes a previous hack involving
- * setting of system properties for each property. Although both are hacks,
- * I prefer this hack because once the system properties are set they can
- * affect later tests unless those tests clear them. This hack allows for
- * a clean switch to a new set of defaults when a new HiveConf object is created.
- */
- Reflection.staticField("hiveSiteURL")
- .ofType(URL.class)
- .in(HiveConf.class)
- .set(null);
- HiveConf hiveConf = new HiveConf();
- HiveAuthzConf authzConf = new HiveAuthzConf(Resources.getResource("sentry-site.xml"));
- for(Map.Entry<String, String> entry : properties.entrySet()) {
- LOGGER.info(entry.getKey() + " => " + entry.getValue());
- hiveConf.set(entry.getKey(), entry.getValue());
- authzConf.set(entry.getKey(), entry.getValue());
- }
- File hiveSite = new File(confDir, "hive-site.xml");
- File accessSite = new File(confDir, HiveAuthzConf.AUTHZ_SITE_FILE);
- OutputStream out = new FileOutputStream(accessSite);
- authzConf.writeXml(out);
- out.close();
- // points hive-site.xml at access-site.xml
- hiveConf.set(HiveAuthzConf.HIVE_ACCESS_CONF_URL, accessSite.toURI().toURL().toExternalForm());
- if(!properties.containsKey(HiveConf.ConfVars.HIVE_SERVER2_SESSION_HOOK.varname)) {
- hiveConf.set(HiveConf.ConfVars.HIVE_SERVER2_SESSION_HOOK.varname,
- "org.apache.sentry.binding.hive.HiveAuthzBindingSessionHook");
- }
- hiveConf.set(HIVESERVER2_IMPERSONATION, "false");
- out = new FileOutputStream(hiveSite);
- hiveConf.writeXml(out);
- out.close();
-
- Reflection.staticField("hiveSiteURL")
- .ofType(URL.class)
- .in(HiveConf.class)
- .set(hiveSite.toURI().toURL());
-
- switch (type) {
- case EmbeddedHiveServer2:
- LOGGER.info("Creating EmbeddedHiveServer");
- return new EmbeddedHiveServer();
- case InternalHiveServer2:
- LOGGER.info("Creating InternalHiveServer");
- return new InternalHiveServer(hiveConf);
- case ExternalHiveServer2:
- LOGGER.info("Creating ExternalHiveServer");
- return new ExternalHiveServer(hiveConf, confDir, logDir);
- case UnmanagedHiveServer2:
- LOGGER.info("Creating UnmanagedHiveServer");
- return new UnmanagedHiveServer();
- default:
- throw new UnsupportedOperationException(type.name());
- }
- }
- private static int findPort() throws IOException {
- ServerSocket socket = new ServerSocket(0);
- int port = socket.getLocalPort();
- socket.close();
- return port;
- }
-
- @VisibleForTesting
- public static enum HiveServer2Type {
- EmbeddedHiveServer2, // Embedded HS2, directly executed by JDBC, without thrift
- InternalHiveServer2, // Start a thrift HS2 in the same process
- ExternalHiveServer2, // start a remote thrift HS2
- UnmanagedHiveServer2 // Use a remote thrift HS2 already running
- ;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/InternalHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/InternalHiveServer.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/InternalHiveServer.java
deleted file mode 100644
index 7e0fed7..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/InternalHiveServer.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.hiveserver;
-
-import java.io.IOException;
-import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.metastore.HiveMetaStore;
-import org.apache.hive.service.server.HiveServer2;
-import org.fest.reflect.core.Reflection;
-
-public class InternalHiveServer extends AbstractHiveServer {
-
- private final HiveServer2 hiveServer2;
- private final HiveConf conf;
-
- public InternalHiveServer(HiveConf conf) throws IOException {
- super(conf, getHostname(conf), getPort(conf));
- // Fix for ACCESS-148. Resets a static field
- // so the default database is created even
- // though is has been created before in this JVM
- Reflection.staticField("createDefaultDB")
- .ofType(boolean.class)
- .in(HiveMetaStore.HMSHandler.class)
- .set(false);
- hiveServer2 = new HiveServer2();
- this.conf = conf;
- }
-
- @Override
- public synchronized void start() throws Exception {
- hiveServer2.init(conf);
- hiveServer2.start();
- waitForStartup(this);
- }
-
- @Override
- public synchronized void shutdown() {
- hiveServer2.stop();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/UnmanagedHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/UnmanagedHiveServer.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/UnmanagedHiveServer.java
deleted file mode 100644
index 7a92ba1..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/UnmanagedHiveServer.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.hiveserver;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import org.apache.hadoop.hive.conf.HiveConf;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.util.Properties;
-
-public class UnmanagedHiveServer implements HiveServer {
- private static final Logger LOGGER = LoggerFactory.getLogger(UnmanagedHiveServer.class);
- public static String hostname;
- public static int port;
- public static final String hs2Host = System.getProperty("hs2Host");
- public static final int hs2Port = Integer.parseInt(System.getProperty("hivePort", "10000"));
- public static final String auth = System.getProperty("auth", "kerberos");
- public static final String hivePrincipal = System.getProperty("hivePrincipal");
- public static final String kerbRealm = System.getProperty("kerberosRealm");
- private HiveConf hiveConf;
-
- public UnmanagedHiveServer() {
- Preconditions.checkNotNull(hs2Host);
- if(auth.equalsIgnoreCase("kerberos")){
- Preconditions.checkNotNull(kerbRealm);
- Preconditions.checkNotNull(hivePrincipal);
- }
- this.hostname = hs2Host;
- this.port = hs2Port;
- hiveConf = new HiveConf();
- }
-
- @Override
- public void start() throws Exception {
- //For Unmanaged HiveServer, service need not be started within the test
- }
-
- @Override
- public void shutdown() throws Exception {
- //For Unmanaged HiveServer, service need not be stopped within the test
- }
-
- @Override
- public String getURL() {
- return "jdbc:hive2://" + hostname + ":" + port + "/default;";
- }
-
- @Override
- public String getProperty(String key) {
- return hiveConf.get(key);
- }
-
- @Override
- public Connection createConnection(String user, String password) throws Exception{
- String url = getURL();
- Properties oProps = new Properties();
-
- if(auth.equalsIgnoreCase("kerberos")){
- String commandFormat = "kinit -kt /cdep/keytabs/%s.keytab %s@" + kerbRealm;
- String command = String.format(commandFormat, user, user, user);
- Process proc = Runtime.getRuntime().exec(command);
- String status = (proc.waitFor()==0)?"passed":"failed";
- LOGGER.info(command + ": " + status);
-
- command = "kinit -R";
- proc = Runtime.getRuntime().exec(command);
- status = (proc.waitFor()==0)?"passed":"failed";
- LOGGER.info(command + ": " + status);
-
- url += "principal=" + hivePrincipal;
- }else{
- oProps.setProperty("user",user);
- oProps.setProperty("password",password);
- }
- LOGGER.info("url: " + url);
- return DriverManager.getConnection(url, oProps);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/resources/access-site.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/resources/access-site.xml b/sentry-tests/src/test/resources/access-site.xml
deleted file mode 100644
index e4de05a..0000000
--- a/sentry-tests/src/test/resources/access-site.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
-<!--
- 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.
--->
-
-<configuration>
- <property>
- <name>hive.access.provider</name>
- <value>invalid</value>
- </property>
- <property>
- <name>hive.access.provider.resource</name>
- <value>invalid</value>
- </property>
- <property>
- <name>hive.access.server</name>
- <value>myHS2</value>
- </property>
-</configuration>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/resources/emp.dat
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/resources/emp.dat b/sentry-tests/src/test/resources/emp.dat
deleted file mode 100644
index 5922b20..0000000
--- a/sentry-tests/src/test/resources/emp.dat
+++ /dev/null
@@ -1,12 +0,0 @@
-16|john
-17|robert
-18|andrew
-19|katty
-21|tom
-22|tim
-23|james
-24|paul
-27|edward
-29|alan
-31|kerry
-34|terri
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/resources/hive-site.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/resources/hive-site.xml b/sentry-tests/src/test/resources/hive-site.xml
deleted file mode 100644
index 237c408..0000000
--- a/sentry-tests/src/test/resources/hive-site.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
-<!--
- 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.
--->
-
-<configuration>
-<property>
- <name>hive.metastore.warehouse.dir</name>
- <value>invalid</value>
-</property>
-
-<property>
- <name>mapreduce.framework.name</name>
- <value>local</value>
-</property>
-
-<property>
- <name>javax.jdo.option.ConnectionURL</name>
- <value>invalid</value>
-</property>
-
-<property>
- <name>hadoop.bin.path</name>
- <value>./target/hadoop/bin/hadoop</value>
-</property>
-
-<property>
- <name>hive.support.concurrency</name>
- <value>false</value>
-</property>
-</configuration>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/resources/kv1.dat
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/resources/kv1.dat b/sentry-tests/src/test/resources/kv1.dat
deleted file mode 100644
index 20fb0dc..0000000
--- a/sentry-tests/src/test/resources/kv1.dat
+++ /dev/null
@@ -1,500 +0,0 @@
-238
-86
-311
-27
-165
-409
-255
-278
-98
-484
-265
-193
-401
-150
-273
-224
-369
-66
-128
-213
-146
-406
-429
-374
-152
-469
-145
-495
-37
-327
-281
-277
-209
-15
-82
-403
-166
-417
-430
-252
-292
-219
-287
-153
-193
-338
-446
-459
-394
-237
-482
-174
-413
-494
-207
-199
-466
-208
-174
-399
-396
-247
-417
-489
-162
-377
-397
-309
-365
-266
-439
-342
-367
-325
-167
-195
-475
-17
-113
-155
-203
-339
-0
-455
-128
-311
-316
-57
-302
-205
-149
-438
-345
-129
-170
-20
-489
-157
-378
-221
-92
-111
-47
-72
-4
-280
-35
-427
-277
-208
-356
-399
-169
-382
-498
-125
-386
-437
-469
-192
-286
-187
-176
-54
-459
-51
-138
-103
-239
-213
-216
-430
-278
-176
-289
-221
-65
-318
-332
-311
-275
-137
-241
-83
-333
-180
-284
-12
-230
-181
-67
-260
-404
-384
-489
-353
-373
-272
-138
-217
-84
-348
-466
-58
-8
-411
-230
-208
-348
-24
-463
-431
-179
-172
-42
-129
-158
-119
-496
-0
-322
-197
-468
-393
-454
-100
-298
-199
-191
-418
-96
-26
-165
-327
-230
-205
-120
-131
-51
-404
-43
-436
-156
-469
-468
-308
-95
-196
-288
-481
-457
-98
-282
-197
-187
-318
-318
-409
-470
-137
-369
-316
-169
-413
-85
-77
-0
-490
-87
-364
-179
-118
-134
-395
-282
-138
-238
-419
-15
-118
-72
-90
-307
-19
-435
-10
-277
-273
-306
-224
-309
-389
-327
-242
-369
-392
-272
-331
-401
-242
-452
-177
-226
-5
-497
-402
-396
-317
-395
-58
-35
-336
-95
-11
-168
-34
-229
-233
-143
-472
-322
-498
-160
-195
-42
-321
-430
-119
-489
-458
-78
-76
-41
-223
-492
-149
-449
-218
-228
-138
-453
-30
-209
-64
-468
-76
-74
-342
-69
-230
-33
-368
-103
-296
-113
-216
-367
-344
-167
-274
-219
-239
-485
-116
-223
-256
-263
-70
-487
-480
-401
-288
-191
-5
-244
-438
-128
-467
-432
-202
-316
-229
-469
-463
-280
-2
-35
-283
-331
-235
-80
-44
-193
-321
-335
-104
-466
-366
-175
-403
-483
-53
-105
-257
-406
-409
-190
-406
-401
-114
-258
-90
-203
-262
-348
-424
-12
-396
-201
-217
-164
-431
-454
-478
-298
-125
-431
-164
-424
-187
-382
-5
-70
-397
-480
-291
-24
-351
-255
-104
-70
-163
-438
-119
-414
-200
-491
-237
-439
-360
-248
-479
-305
-417
-199
-444
-120
-429
-169
-443
-323
-325
-277
-230
-478
-178
-468
-310
-317
-333
-493
-460
-207
-249
-265
-480
-83
-136
-353
-172
-214
-462
-233
-406
-133
-175
-189
-454
-375
-401
-421
-407
-384
-256
-26
-134
-67
-384
-379
-18
-462
-492
-100
-298
-9
-341
-498
-146
-458
-362
-186
-285
-348
-167
-18
-273
-183
-281
-344
-97
-469
-315
-84
-28
-37
-448
-152
-348
-307
-194
-414
-477
-222
-126
-90
-169
-403
-400
-200
-97
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/resources/log4j.properties b/sentry-tests/src/test/resources/log4j.properties
deleted file mode 100644
index d941816..0000000
--- a/sentry-tests/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# 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.
-#
-
-# Define some default values that can be overridden by system properties.
-#
-# For testing, it may also be convenient to specify
-
-sentry.root.logger=INFO,console
-log4j.rootLogger=${sentry.root.logger}
-
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.target=System.err
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d (%t) [%p - %l] %m%n
-
-log4j.logger.org.apache.hadoop.conf.Configuration=ERROR
-log4j.logger.org.apache.sentry=DEBUG
-
-log4j.category.DataNucleus=ERROR
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/resources/sentry-site.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/resources/sentry-site.xml b/sentry-tests/src/test/resources/sentry-site.xml
deleted file mode 100644
index de0c9cf..0000000
--- a/sentry-tests/src/test/resources/sentry-site.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
-<!--
- 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.
--->
-
-<configuration>
- <property>
- <name>hive.sentry.provider</name>
- <value>invalid</value>
- </property>
- <property>
- <name>hive.sentry.provider.resource</name>
- <value>invalid</value>
- </property>
- <property>
- <name>hive.sentry.server</name>
- <value>myHS2</value>
- </property>
-</configuration>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/resources/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/resources/test-authz-provider.ini b/sentry-tests/src/test/resources/test-authz-provider.ini
deleted file mode 100644
index 014d827..0000000
--- a/sentry-tests/src/test/resources/test-authz-provider.ini
+++ /dev/null
@@ -1,25 +0,0 @@
-# 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.
-
-[groups]
-foo = all_default
-
-[roles]
-all_default = server=server1->db=default
-
-[users]
-foo = foo
[4/9] SENTRY-16: Move sentry-tests to sentry-tests-hive package
(Gregory Chanan via Shreepadma Venugopalan)
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestEndToEnd.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestEndToEnd.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestEndToEnd.java
deleted file mode 100644
index c45dfbc..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestEndToEnd.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.sql.Connection;
-import java.sql.Statement;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-public class TestEndToEnd extends AbstractTestWithStaticLocalFS {
- private Context context;
- private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- private File dataFile;
- private PolicyFile policyFile;
-
-
- @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();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
-
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /**
- * Steps:
- * 1. admin create a new experimental database
- * 2. admin create a new production database, create table, load data
- * 3. admin create new user group, and add user into it
- * 4. admin grant privilege all@'experimental database' to group
- * 5. user create table, load data in experimental DB
- * 6. user create view based on table in experimental DB
- * 7. admin create table (same name) in production DB
- * 8. admin grant read@productionDB.table to group
- * admin grant select@productionDB.table to group
- * 9. user load data from experimental table to production table
- */
- @Test
- public void testEndToEnd1() throws Exception {
- policyFile.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", "foo");
- 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);
- statement.close();
- connection.close();
-
- // 3
- policyFile.addGroupsToUser("user1", "group1");
-
- // 4
- policyFile
- .addRolesToGroup("group1", "all_db1", "data_uri", "select_tb1", "insert_tb1")
- .addPermissionsToRole("all_db1", "server=server1->db=db_1")
- .addPermissionsToRole("select_tb1", "server=server1->db=productionDB->table=tb_1->action=select")
- .addPermissionsToRole("insert_tb2", "server=server1->db=productionDB->table=tb_2->action=insert")
- .addPermissionsToRole("insert_tb1", "server=server1->db=productionDB->table=tb_2->action=insert")
- .addPermissionsToRole("data_uri", "server=server1->uri=file://" + dataDir.getPath());
- policyFile.write(context.getPolicyFile());
-
- // 5
- connection = context.createConnection("user1", "foo");
- 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);
- // 6
- statement.execute("CREATE VIEW " + viewName1 + " (value) AS SELECT value from " + tableName1 + " LIMIT 10");
- statement.close();
- connection.close();
-
- // 7
- connection = context.createConnection("admin1", "foo");
- 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();
-
- // 9
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName2);
- statement.execute("INSERT OVERWRITE TABLE " +
- dbName2 + "." + tableName2 + " SELECT * FROM " + dbName1
- + "." + tableName1);
- statement.close();
- connection.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestExportImportPrivileges.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestExportImportPrivileges.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestExportImportPrivileges.java
deleted file mode 100644
index 22fe430..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestExportImportPrivileges.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.sql.Connection;
-import java.sql.Statement;
-
-import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-public class TestExportImportPrivileges extends AbstractTestWithStaticDFS {
- private File dataFile;
- private PolicyFile policyFile;
-
- @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();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- @Test
- public void testInsertToDirPrivileges() throws Exception {
- Connection connection = null;
- Statement statement = null;
- String dumpDir = context.getDFSUri().toString() + "/hive_data_dump";
-
- policyFile
- .addRolesToGroup("user_group1", "db1_read", "db1_write", "data_dump")
- .addRolesToGroup("user_group2", "db1_read", "db1_write")
- .addPermissionsToRole("db1_write", "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=INSERT")
- .addPermissionsToRole("db1_read", "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=SELECT")
- .addPermissionsToRole("data_dump", "server=server1->URI=" + dumpDir)
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2");
- policyFile.write(context.getPolicyFile());
-
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
-
- // Negative test, user2 doesn't have access to write to dir
- connection = context.createConnection(USER2, "password");
- statement = context.createStatement(connection);
- statement.execute("use " + DB1);
- context.assertAuthzException(statement, "INSERT OVERWRITE DIRECTORY '" + dumpDir + "' SELECT * FROM " + TBL1);
- statement.close();
- connection.close();
-
- // Negative test, user2 doesn't have access to dir that's similar to scratch dir
- String scratchDumpDir = context.getProperty(HiveConf.ConfVars.SCRATCHDIR.varname) + "_foo" + "/bar";
- connection = context.createConnection(USER2, "password");
- statement = context.createStatement(connection);
- statement.execute("use " + DB1);
- context.assertAuthzException(statement, "INSERT OVERWRITE DIRECTORY '" + scratchDumpDir + "' SELECT * FROM " + TBL1);
- statement.close();
- connection.close();
-
- // positive test, user1 has access to write to dir
- connection = context.createConnection(USER1, "password");
- statement = context.createStatement(connection);
- statement.execute("use " + DB1);
- assertTrue(statement.executeQuery("SELECT * FROM " + TBL1).next());
- statement.execute("INSERT OVERWRITE DIRECTORY '" + dumpDir + "' SELECT * FROM " + TBL1);
- }
-
- @Test
- public void testExportImportPrivileges() throws Exception {
- Connection connection = null;
- Statement statement = null;
- String exportDir = context.getDFSUri().toString() + "/hive_export1";
-
- policyFile
- .addRolesToGroup("user_group1", "tab1_read", "tab1_write", "db1_all", "data_read", "data_export")
- .addRolesToGroup("user_group2", "tab1_write", "tab1_read")
- .addPermissionsToRole("tab1_write", "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=INSERT")
- .addPermissionsToRole("tab1_read", "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=SELECT")
- .addPermissionsToRole("db1_all", "server=server1->db=" + DB1)
- .addPermissionsToRole("data_read", "server=server1->URI=file://" + dataFile.getPath())
- .addPermissionsToRole("data_export", "server=server1->URI=" + exportDir)
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2");
- policyFile.write(context.getPolicyFile());
-
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
-
- // Negative test, user2 doesn't have access to the file being loaded
- connection = context.createConnection(USER2, "password");
- statement = context.createStatement(connection);
- statement.execute("use " + DB1);
- context.assertAuthzException(statement, "EXPORT TABLE " + TBL1 + " TO '" + exportDir + "'");
- statement.close();
- connection.close();
-
- // Positive test, user1 have access to the target directory
- connection = context.createConnection(USER1, "password");
- statement = context.createStatement(connection);
- statement.execute("use " + DB1);
- statement.execute("EXPORT TABLE " + TBL1 + " TO '" + exportDir + "'");
- statement.close();
- connection.close();
-
- // Negative test, user2 doesn't have access to the directory loading from
- connection = context.createConnection(USER2, "password");
- statement = context.createStatement(connection);
- statement.execute("use " + DB1);
- context.assertAuthzException(statement, "IMPORT TABLE " + TBL2 + " FROM '" + exportDir + "'");
- statement.close();
- connection.close();
-
- // Positive test, user1 have access to the target directory
- connection = context.createConnection(USER1, "password");
- statement = context.createStatement(connection);
- statement.execute("use " + DB1);
- statement.execute("IMPORT TABLE " + TBL2 + " FROM '" + exportDir + "'");
- statement.close();
- connection.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMetadataObjectRetrieval.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMetadataObjectRetrieval.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMetadataObjectRetrieval.java
deleted file mode 100644
index 24684f2..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMetadataObjectRetrieval.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * 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;
-
-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.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-public class TestMetadataObjectRetrieval extends
-AbstractTestWithStaticLocalFS {
- private PolicyFile policyFile;
- private File dataFile;
-
- @Before
- public void setup() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- 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();
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /**
- * Method called to run positive tests:
- * describe table
- * describe table column
- * show columns from table
- * show create table table
- * show tblproperties table
- *
- * The table is assumed to have two colums under_col int and value string.
- */
- private void positiveDescribeShowTests(String user, String db, String table) throws Exception {
- Connection connection = context.createConnection(user, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + db);
- ResultSet rs = statement.executeQuery("DESCRIBE " + table);
- assertTrue(rs.next());
-
- assertTrue("describe table fail", rs.getString(1).trim().equals("under_col"));
- assertTrue("describe table fail", rs.getString(2).trim().equals("int"));
- assertTrue(rs.next());
- assertTrue("describe table fail", rs.getString(1).trim().equals("value"));
- assertTrue("describe table fail", rs.getString(2).trim().equals("string"));
-
- rs = statement.executeQuery("DESCRIBE " + table + " under_col");
- assertTrue(rs.next());
- assertTrue("describe table fail", rs.getString(1).trim().equals("under_col"));
- assertTrue("describe table fail", rs.getString(2).trim().equals("int"));
-
- rs = statement.executeQuery("DESCRIBE " + table + " value");
- assertTrue(rs.next());
- assertTrue("describe table fail", rs.getString(1).trim().equals("value"));
- assertTrue("describe table fail", rs.getString(2).trim().equals("string"));
-
- rs = statement.executeQuery("SHOW COLUMNS FROM " + table);
- assertTrue(rs.next());
- assertTrue("show columns from fail", rs.getString(1).trim().equals("under_col"));
- assertTrue(rs.next());
- assertTrue("show columns from fail", rs.getString(1).trim().equals("value"));
-
- rs = statement.executeQuery("SHOW CREATE TABLE " + table);
- assertTrue("SHOW CREATE TABLE fail", rs.next());
-
- rs = statement.executeQuery("SHOW TBLPROPERTIES " + table);
- assertTrue("SHOW TBLPROPERTIES fail", rs.next());
-
- statement.close();
- connection.close();
- }
- /**
- * Method called to run negative tests:
- * describe table
- * describe table column
- * show columns from table
- * show create table table
- * show tblproperties table
- *
- * The table is assumed to have two columns under_col int and value string.
- */
- private void negativeDescribeShowTests(String user, String db, String table) throws Exception {
- Connection connection = context.createConnection(user, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + db);
- context.assertAuthzException(statement, "DESCRIBE " + table);
- context.assertAuthzException(statement, "DESCRIBE " + table + " under_col");
- context.assertAuthzException(statement, "DESCRIBE " + table + " value");
- context.assertAuthzException(statement, "SHOW COLUMNS FROM " + table);
- context.assertAuthzException(statement, "SHOW CREATE TABLE " + table);
- context.assertAuthzException(statement, "SHOW TBLPROPERTIES " + table);
- statement.close();
- connection.close();
- }
-
-
- /**
- * Tests to ensure a user with all on server,
- * insert|select on table can view metadata while
- * a user with all on a different table cannot
- * view the metadata.
-
- * Test both positive and negative of:
- * describe table
- * describe table column
- * show columns from table
- * show create table table
- * show tblproperties table
- *
- * Positive tests are run with:
- * all@server
- * select@table
- * insert@table
- * Negative tests are run three times:
- * none
- * insert@different table
- */
- @Test
- public void testAllOnServerSelectInsertNegativeNoneAllOnDifferentTable()
- throws Exception {
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1 + "->table=" + TBL2)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1)
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
- positiveDescribeShowTests(ADMIN1, DB1, TBL1);
- negativeDescribeShowTests(USER1, DB1, TBL1);
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL1)
- .write(context.getPolicyFile());
- positiveDescribeShowTests(USER1, DB1, TBL1);
- policyFile.removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_TBL1);
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, INSERT_DB1_TBL1)
- .write(context.getPolicyFile());
- positiveDescribeShowTests(USER1, DB1, TBL1);
- }
-
- /**
- * Tests to ensure that a user is able to view metadata
- * with all on db
- *
- * Test positive:
- * describe table
- * describe table column
- * show columns from table
- * show create table table
- * show tblproperties table
- *
- * Positive tests are run twice:
- * all@server
- * all@db
- */
- @Test
- public void testAllOnServerAndAllOnDb() throws Exception {
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1)
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
- positiveDescribeShowTests(ADMIN1, DB1, TBL1);
- positiveDescribeShowTests(USER1, DB1, TBL1);
- }
-
- /**
- * Test to ensure that all on view do not result in
- * metadata privileges on the underlying table
- *
- * Test both positive and negative of:
- * describe table
- * describe table column
- * show columns from table
- * show create table table
- * show tblproperties table
- *
- * Positive tests are run with all@server
- * Negative tests are run three times:
- * none
- * all@view
- */
- @Test
- public void testAllOnServerNegativeAllOnView() throws Exception {
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1 + "->table=" + VIEW1)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1)
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
- Connection connection = context.createConnection(ADMIN1, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- statement.execute("DROP VIEW IF EXISTS " + VIEW1);
- statement.execute("CREATE VIEW " + VIEW1 + " (value) AS SELECT value from " + TBL1 + " LIMIT 10");
- positiveDescribeShowTests(ADMIN1, DB1, TBL1);
- statement.close();
- connection.close();
- negativeDescribeShowTests(USER1, DB1, TBL1);
- }
-
- /**
- * Tests to ensure that a user is able to view metadata
- * with all on table
- *
- * Test positive:
- * describe table
- * describe table column
- * show columns from table
- * show create table table
- * show tblproperties table
- *
- * Positive tests are run twice:
- * all@server
- * all@table
- */
- @Test
- public void testAllOnServerAndAllOnTable() throws Exception {
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1 + "->table=" + TBL1)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1)
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
- positiveDescribeShowTests(ADMIN1, DB1, TBL1);
- positiveDescribeShowTests(USER1, DB1, TBL1);
- }
-
-
- /**
- * Tests that admin and all@db can describe database
- * and describe database extended. Also tests that a user
- * with no privileges on a db cannot describe database.
- */
- @Test
- public void testDescribeDatabasesWithAllOnServerAndAllOnDb()
- throws Exception {
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1)
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1, DB2);
- createDb(ADMIN1, DB1, DB2);
- createTable(ADMIN1, DB1, dataFile, TBL1);
-
- Connection connection = context.createConnection(ADMIN1, "password");
- Statement statement = context.createStatement(connection);
- assertTrue(statement.executeQuery("DESCRIBE DATABASE " + DB1).next());
- assertTrue(statement.executeQuery("DESCRIBE DATABASE EXTENDED " + DB1).next());
- statement.close();
- connection.close();
-
- connection = context.createConnection(USER1, "password");
- statement = context.createStatement(connection);
- assertTrue(statement.executeQuery("DESCRIBE DATABASE " + DB1).next());
- assertTrue(statement.executeQuery("DESCRIBE DATABASE EXTENDED " + DB1).next());
- context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB2);
- context.assertAuthzException(statement, "DESCRIBE DATABASE EXTENDED " + DB2);
- policyFile.addPermissionsToRole(GROUP1_ROLE, INSERT_DB2_TBL1)
- .write(context.getPolicyFile());
- context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB2);
- context.assertAuthzException(statement, "DESCRIBE DATABASE EXTENDED " + DB2);
- statement.close();
- connection.close();
- }
-
- /**
- * Tests that a user without db level privileges cannot describe default
- */
- @Test
- public void testDescribeDefaultDatabase() throws Exception {
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=default->table=" + TBL1 + "->action=select",
- "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=select")
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1)
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1, DB2);
- createDb(ADMIN1, DB1, DB2);
- Connection connection = context.createConnection(ADMIN1, "password");
- Statement statement = context.createStatement(connection);
- assertTrue(statement.executeQuery("DESCRIBE DATABASE default").next());
- statement.execute("USE " + DB1);
- assertTrue(statement.executeQuery("DESCRIBE DATABASE default").next());
- assertTrue(statement.executeQuery("DESCRIBE DATABASE " + DB1).next());
- assertTrue(statement.executeQuery("DESCRIBE DATABASE " + DB2).next());
- statement.close();
- connection.close();
-
- connection = context.createConnection(USER1, "password");
- statement = context.createStatement(connection);
- context.assertAuthzException(statement, "DESCRIBE DATABASE default");
- context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB1);
- statement.execute("USE " + DB1);
- context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB1);
- context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB2);
- statement.close();
- connection.close();
- }
-
- /**
- * Tests that users without privileges cannot execute show indexes
- * and that users with all on table can execute show indexes
- */
- @Test
- public void testShowIndexes1() throws Exception {
- // grant privilege to non-existent table to allow use db1
- policyFile.addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_NONTABLE)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1)
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
- Connection connection = context.createConnection(ADMIN1, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- statement.execute("DROP INDEX IF EXISTS " + INDEX1 + " ON " + TBL1);
- statement
- .execute("CREATE INDEX "
- + INDEX1
- + " ON TABLE "
- + TBL1
- + "(value) AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' WITH DEFERRED REBUILD");
- statement.execute("DROP VIEW IF EXISTS " + VIEW1);
- statement.execute("CREATE VIEW " + VIEW1 + " (value) AS SELECT value from " + TBL1 + " LIMIT 10");
- statement.close();
- connection.close();
- connection = context.createConnection(USER1, "password");
- statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- context.assertAuthzException(statement, "SHOW INDEX ON " + TBL1);
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_VIEW1)
- .write(context.getPolicyFile());
- context.assertAuthzException(statement, "SHOW INDEX ON " + TBL1);
- policyFile.removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_VIEW1)
- .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL1)
- .write(context.getPolicyFile());
- verifyIndex(statement, TBL1, INDEX1);
- policyFile.removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_TBL1)
- .addPermissionsToRole(GROUP1_ROLE, INSERT_DB1_TBL1)
- .write(context.getPolicyFile());
- verifyIndex(statement, TBL1, INDEX1);
- statement.close();
- connection.close();
- }
-
- private void verifyIndex(Statement statement, String table, String index) throws Exception {
- ResultSet rs = statement.executeQuery("SHOW INDEX ON " + table);
- assertTrue(rs.next());
- assertEquals(index, rs.getString(1).trim());
- assertEquals(table, rs.getString(2).trim());
- assertEquals("value", rs.getString(3).trim());
- assertEquals("db_1__tb_1_index_1__", rs.getString(4).trim());
- assertEquals("compact", rs.getString(5).trim());
- }
-
- /**
- * Tests that users without privileges cannot execute show partitions
- * and that users with select on table can execute show partitions
- */
- @Test
- public void testShowPartitions1() throws Exception {
- // grant privilege to non-existent table to allow use db1
- policyFile.addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_NONTABLE)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1)
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- Connection connection = context.createConnection(ADMIN1, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- statement.execute("DROP TABLE IF EXISTS " + TBL1);
- statement.execute("create table " + TBL1
- + " (under_col int, value string) PARTITIONED BY (dt INT)");
- statement.execute("load data local inpath '" + dataFile.getPath()
- + "' into table " + TBL1 + " PARTITION (dt=3)");
- statement.execute("DROP VIEW IF EXISTS " + VIEW1);
- statement.execute("CREATE VIEW " + VIEW1 + " (value) AS SELECT value from " + TBL1 + " LIMIT 10");
- statement.close();
- connection.close();
- connection = context.createConnection(USER1, "password");
- statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- context.assertAuthzException(statement, "SHOW PARTITIONS " + TBL1);
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_VIEW1)
- .write(context.getPolicyFile());
- context.assertAuthzException(statement, "SHOW PARTITIONS " + TBL1);
- policyFile
- .removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_VIEW1)
- .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL1)
- .write(context.getPolicyFile());
- verifyParition(statement, TBL1);
- policyFile.removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_TBL1)
- .addPermissionsToRole(GROUP1_ROLE, INSERT_DB1_TBL1)
- .write(context.getPolicyFile());
- verifyParition(statement, TBL1);
- statement.close();
- connection.close();
- }
-
- private void verifyParition(Statement statement, String table) throws Exception {
- ResultSet rs = statement.executeQuery("SHOW PARTITIONS " + TBL1);
- assertTrue(rs.next());
- assertEquals("dt=3", rs.getString(1).trim());
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMetadataPermissions.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMetadataPermissions.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMetadataPermissions.java
deleted file mode 100644
index f3d493f..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMetadataPermissions.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import junit.framework.Assert;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-
-public class TestMetadataPermissions extends AbstractTestWithStaticLocalFS {
- private Context context;
- private PolicyFile policyFile;
-
- @Before
- public void setup() throws Exception {
- context = createContext();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
-
-/*
- String testPolicies[] = {
- "[groups]",
- "admin_group = admin_role",
- "user_group1 = db1_all,db2_all",
- "user_group2 = db1_all",
- "[roles]",
- "db1_all = server=server1->db=db1",
- "db2_all = server=server1->db=db2",
- "admin_role = server=server1",
- "[users]",
- "user1 = user_group1",
- "user2 = user_group2",
- "admin = admin_group"
- };
- context.makeNewPolicy(testPolicies);
-*/
- policyFile
- .addRolesToGroup("user_group1", "db1_all", "db2_all")
- .addRolesToGroup("user_group2", "db1_all")
- .addPermissionsToRole("db1_all", "server=server1->db=db1")
- .addPermissionsToRole("db2_all", "server=server1->db=db2")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .write(context.getPolicyFile());
-
- Connection adminCon = context.createConnection(ADMIN1, "foo");
- Statement adminStmt = context.createStatement(adminCon);
- for (String dbName : new String[] { "db1", "db2" }) {
- adminStmt.execute("USE default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.execute("USE " + dbName);
- for (String tabName : new String[] { "tab1", "tab2" }) {
- adminStmt.execute("CREATE TABLE " + tabName + " (id int)");
- }
- }
- context.close();
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /**
- * Ensure that a user with no privileges on a database cannot
- * query that databases metadata.
- */
- @Test
- public void testDescPrivilegesNegative() throws Exception {
- String dbName = "db2";
- Connection connection = context.createConnection("user2", "password");
- Statement statement = context.createStatement(connection);
- context.assertAuthzException(statement, "USE " + dbName);
-// TODO when DESCRIBE db.table is supported tests should be uncommented
-// for (String tabName : new String[] { "tab1", "tab2" }) {
-// context.assertAuthzException(statement, "DESCRIBE " + dbName + "." + tabName);
-// context.assertAuthzException(statement, "DESCRIBE EXTENDED " + dbName + "." + tabName);
-// }
- statement.close();
- connection.close();
- }
-
- /**
- * Ensure that a user cannot describe databases to which the user
- * has no privilege.
- */
- @Test
- public void testDescDbPrivilegesNegative() throws Exception {
- String dbName = "db2";
- Connection connection = context.createConnection("user2", "password");
- Statement statement = context.createStatement(connection);
- context.assertAuthzException(statement, "DESCRIBE DATABASE " + dbName);
- context.assertAuthzException(statement, "DESCRIBE DATABASE EXTENDED " + dbName);
- statement.close();
- connection.close();
- }
-
- /**
- * Ensure that a user with privileges on a database can describe
- * the database.
- */
- @Test
- public void testDescDbPrivilegesPositive() throws Exception {
- Connection connection = context.createConnection("user1", "password");
- Statement statement = context.createStatement(connection);
- for (String dbName : new String[] { "db1", "db2" }) {
- statement.execute("USE " + dbName);
- Assert.assertTrue(statement.executeQuery("DESCRIBE DATABASE " + dbName).next());
- Assert.assertTrue(statement.executeQuery("DESCRIBE DATABASE EXTENDED " + dbName).next());
- }
- statement.close();
- connection.close();
- }
-
- /**
- * Ensure that a user with privileges on a table can describe the table.
- */
- @Test
- public void testDescPrivilegesPositive() throws Exception {
- Connection connection = context.createConnection("user1", "password");
- Statement statement = context.createStatement(connection);
- for (String dbName : new String[] { "db1", "db2" }) {
- statement.execute("USE " + dbName);
- Assert.assertTrue(statement.executeQuery("DESCRIBE DATABASE " + dbName).next());
- for (String tabName : new String[] { "tab1", "tab2" }) {
- Assert.assertTrue(statement.executeQuery("DESCRIBE " + tabName).next());
- Assert.assertTrue(statement.executeQuery("DESCRIBE EXTENDED " + tabName).next());
-
- }
- }
- statement.close();
- connection.close();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMovingToProduction.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMovingToProduction.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMovingToProduction.java
deleted file mode 100644
index c7b5e31..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestMovingToProduction.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * 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;
-
-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 junit.framework.Assert;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-public class TestMovingToProduction extends AbstractTestWithStaticLocalFS {
- private Context context;
- private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- private PolicyFile policyFile;
-
-
- @Before
- public void setUp() throws Exception {
- context = createContext();
- 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();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /**
- * Steps:
- * 1. admin create DB_1, admin create GROUP_1, GROUP_2
- * 2. admin grant all to GROUP_1 on DB_1
- * 3. user in GROUP_1 create table tb_1 and load data into
- * 4. admin create table production.tb_1.
- * 5. admin grant all to GROUP_1 on production.tb_1.
- * positive test cases:
- * a)verify user in GROUP_1 can load data from DB_1.tb_1 to production.tb_1
- * b)verify user in GROUP_1 has proper privilege on production.tb_1
- * (read and insert)
- * negative test cases:
- * c)verify user in GROUP_2 cannot load data from DB_1.tb_1
- * to production.tb_1
- * d)verify user in GROUP_1 cannot drop production.tb_1
- */
- @Test
- public void testMovingTable1() throws Exception {
- policyFile
- .addRolesToGroup("group1", "all_db1", "load_data", "select_proddb_tbl1", "insert_proddb_tbl1")
- .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataDir.getPath())
- .addPermissionsToRole("all_db1", "server=server1->db=db_1")
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group2")
- .write(context.getPolicyFile());
-
- String dbName1 = "db_1";
- String dbName2 = "proddb";
- String tableName1 = "tb_1";
-
- Connection connection = context.createConnection(ADMIN1, "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("DROP DATABASE IF EXISTS " + dbName2 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- statement.execute("CREATE DATABASE " + dbName2);
- statement.execute("DROP TABLE IF EXISTS " + dbName2 + "." + tableName1);
- statement.execute("create table " + dbName2 + "." + tableName1
- + " (under_col int comment 'the under column', value string)");
- statement.close();
- connection.close();
-
- // a
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName1);
- statement.execute("DROP TABLE IF EXISTS " + tableName1);
- statement.execute("create table " + tableName1
- + " (under_col int comment 'the under column', value string)");
- statement.execute("LOAD DATA INPATH 'file://" + dataDir.getPath()
- + "' INTO TABLE " + tableName1);
-
- policyFile
- .addPermissionsToRole("insert_proddb_tbl1", "server=server1->db=proddb->table=tb_1->action=insert")
- .write(context.getPolicyFile());
- statement.execute("USE " + dbName2);
- statement.execute("INSERT OVERWRITE TABLE "
- + tableName1 + " SELECT * FROM " + dbName1
- + "." + tableName1);
-
- // b
- policyFile
- .addPermissionsToRole("select_proddb_tbl1", "server=server1->db=proddb->table=tb_1->action=select")
- .write(context.getPolicyFile());
- ResultSet resultSet = statement.executeQuery("SELECT * FROM " + tableName1 + " LIMIT 10");
- int count = 0;
- while(resultSet.next()) {
- count++;
- }
- assertEquals(10, count);
- statement.execute("DESCRIBE " + tableName1);
-
- // c
- connection = context.createConnection("user2", "foo");
- statement = context.createStatement(connection);
- context.assertAuthzException(statement, "USE " + dbName2);
- context.assertAuthzException(statement, "INSERT OVERWRITE TABLE "
- + dbName2 + "." + tableName1 + " SELECT * FROM " + dbName1
- + "." + tableName1);
- context.assertAuthzException(statement, "SELECT * FROM " + dbName2 + "." + tableName1 + " LIMIT 10");
- statement.close();
- connection.close();
-
- // d
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName2);
- context.assertAuthzException(statement, "DROP TABLE " + tableName1);
- statement.close();
- connection.close();
- }
-
- /**
- * repeat above tests, only difference is don't do 'USE <database>'
- * in this test. Instead, access table objects across database by
- * database.table
- * @throws Exception
- */
- @Test
- public void testMovingTable2() throws Exception {
- policyFile
- .addRolesToGroup("group1", "all_db1", "load_data", "select_proddb_tbl1", "insert_proddb_tbl1")
- .addPermissionsToRole("all_db1", "server=server1->db=db_1")
- .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataDir.getPath())
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group2")
- .write(context.getPolicyFile());
-
- String dbName1 = "db_1";
- String dbName2 = "proddb";
- String tableName1 = "tb_1";
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("DROP DATABASE IF EXISTS " + dbName2 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- statement.execute("CREATE DATABASE " + dbName2);
- statement.execute("DROP TABLE IF EXISTS " + dbName2 + "." + tableName1);
- statement.execute("create table " + dbName2 + "." + tableName1
- + " (under_col int comment 'the under column', value string)");
- statement.close();
- connection.close();
-
- // a
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- 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 INPATH 'file://" + dataDir.getPath()
- + "' INTO TABLE " + dbName1 + "." + tableName1);
-
- policyFile
- .addPermissionsToRole("insert_proddb_tbl1", "server=server1->db=proddb->table=tb_1->action=insert")
- .write(context.getPolicyFile());
- statement.execute("INSERT OVERWRITE TABLE "
- + dbName2 + "." + tableName1 + " SELECT * FROM " + dbName1
- + "." + tableName1);
-
- // b
- policyFile
- .addPermissionsToRole("select_proddb_tbl1", "server=server1->db=proddb->table=tb_1->action=select")
- .write(context.getPolicyFile());
- assertTrue("user1 should be able to select data from "
- + dbName2 + "." + dbName2 + "." + tableName1, statement.execute("SELECT * FROM "
- + dbName2 + "." + tableName1 + " LIMIT 10"));
- assertTrue("user1 should be able to describe table " + dbName2 + "." + tableName1,
- statement.execute("DESCRIBE " + dbName2 + "." + tableName1));
-
- // c
- connection = context.createConnection("user2", "foo");
- statement = context.createStatement(connection);
-
- context.assertAuthzException(statement, "INSERT OVERWRITE TABLE "
- + dbName2 + "." + tableName1 + " SELECT * FROM " + dbName1
- + "." + tableName1);
-
- context.assertAuthzException(statement, "SELECT * FROM "
- + dbName2 + "." + tableName1 + " LIMIT 10");
- statement.close();
- connection.close();
-
- // d
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName2);
- context.assertAuthzException(statement, "DROP TABLE " + tableName1);
- statement.close();
- connection.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/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
deleted file mode 100644
index 8d520fc..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDBConfiguration.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * 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;
-
-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.SQLException;
-import java.sql.Statement;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.apache.sentry.provider.file.SimplePolicyEngine;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
-import com.google.common.io.Files;
-import com.google.common.io.Resources;
-
-/**
- * Test privileges per database policy files
- */
-public class TestPerDBConfiguration extends AbstractTestWithStaticLocalFS {
- private static final String MULTI_TYPE_DATA_FILE_NAME = "emp.dat";
- private static final String DB2_POLICY_FILE = "db2-policy-file.ini";
-
- private Context context;
- private File dataFile;
- private PolicyFile policyFile;
-
- @Before
- public void setup() throws Exception {
- context = createContext();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
-
- File dataDir = context.getDataDir();
- //copy data file to test dir
- 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();
-
- }
-
- @After
- public void teardown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- @Test
- public void testPerDB() throws Exception {
- PolicyFile db2PolicyFile = new PolicyFile();
- File db2PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB2_POLICY_FILE);
- db2PolicyFile
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
- .write(db2PolicyFileHandle);
-
- policyFile
- .addRolesToGroup("user_group1", "select_tbl1")
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .addDatabase("db2", db2PolicyFileHandle.getPath())
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection(ADMIN1, "hive");
- Statement statement = context.createStatement(connection);
-
- 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("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl1");
- 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.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE db1");
- // test user1 can execute query on tbl1
- verifyCount(statement, "SELECT COUNT(*) FROM tbl1");
-
- // user1 cannot query db2.tbl2
- context.assertAuthzException(statement, "USE db2");
- context.assertAuthzException(statement, "SELECT COUNT(*) FROM db2.tbl2");
- statement.close();
- connection.close();
-
- // test per-db file for db2
-
- connection = context.createConnection("user2", "password");
- statement = context.createStatement(connection);
- statement.execute("USE db2");
- // test user2 can execute query on tbl2
- verifyCount(statement, "SELECT COUNT(*) FROM tbl2");
-
- // user2 cannot query db1.tbl1
- context.assertAuthzException(statement, "SELECT COUNT(*) FROM db1.tbl1");
- context.assertAuthzException(statement, "USE db1");
-
- statement.close();
- connection.close();
-
- //test cleanup
- connection = context.createConnection(ADMIN1, "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE db1 CASCADE");
- statement.execute("DROP DATABASE db2 CASCADE");
- statement.close();
- connection.close();
- }
-
- /**
- * Multiple DB files with some containing badly formatted rules
- * The privileges should work for good files
- * No access for bad formatted ones
- * @throws Exception
- */
- @Test
- public void testMultiPerDBwithErrors() throws Exception {
- String DB3_POLICY_FILE = "db3-policy-file.ini";
- String DB4_POLICY_FILE = "db4-policy-file.ini";
-
- File db2PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB2_POLICY_FILE);
- File db3PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB3_POLICY_FILE);
- File db4PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB4_POLICY_FILE);
-
- PolicyFile db2PolicyFile = new PolicyFile();
- PolicyFile db3PolicyFile = new PolicyFile();
- PolicyFile db4PolicyFile = new PolicyFile();
- db2PolicyFile
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
- .write(db2PolicyFileHandle);
- db3PolicyFile
- .addRolesToGroup("user_group3", "select_tbl3_BAD")
- .addPermissionsToRole("select_tbl3_BAD", "server=server1->db=db3------>table->action=select")
- .write(db3PolicyFileHandle);
- db4PolicyFile
- .addRolesToGroup("user_group4", "select_tbl4")
- .addPermissionsToRole("select_tbl4", "server=server1->db=db4->table=tbl4->action=select")
- .write(db4PolicyFileHandle);
- policyFile
- .addRolesToGroup("user_group1", "select_tbl1")
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .addGroupsToUser("user3", "user_group3")
- .addGroupsToUser("user4", "user_group4")
- .addDatabase("db2", db2PolicyFileHandle.getPath())
- .addDatabase("db3", db3PolicyFileHandle.getPath())
- .addDatabase("db4", db4PolicyFileHandle.getPath())
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection(ADMIN1, "hive");
- Statement statement = context.createStatement(connection);
-
- 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("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl1");
-
- 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.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
-
- statement.execute("DROP DATABASE IF EXISTS db3 CASCADE");
- statement.execute("CREATE DATABASE db3");
- statement.execute("USE db3");
- statement.execute("CREATE TABLE tbl3(B INT, A STRING) " +
- " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl3");
-
- statement.execute("DROP DATABASE IF EXISTS db4 CASCADE");
- statement.execute("CREATE DATABASE db4");
- statement.execute("USE db4");
- statement.execute("CREATE TABLE tbl4(B INT, A STRING) " +
- " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl4");
-
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE db1");
- // test user1 can execute query on tbl1
- verifyCount(statement, "SELECT COUNT(*) FROM tbl1");
- connection.close();
-
- connection = context.createConnection("user2", "password");
- statement = context.createStatement(connection);
- statement.execute("USE db2");
- // test user1 can execute query on tbl1
- verifyCount(statement, "SELECT COUNT(*) FROM tbl2");
- connection.close();
-
- // verify no access to db3 due to badly formatted rule in db3 policy file
- connection = context.createConnection("user3", "password");
- statement = context.createStatement(connection);
- context.assertAuthzException(statement, "USE db3");
- // test user1 can execute query on tbl1
- context.assertAuthzException(statement, "SELECT COUNT(*) FROM db3.tbl3");
- connection.close();
-
- connection = context.createConnection("user4", "password");
- statement = context.createStatement(connection);
- statement.execute("USE db4");
- // test user1 can execute query on tbl1
- verifyCount(statement, "SELECT COUNT(*) FROM tbl4");
- connection.close();
-
- //test cleanup
- connection = context.createConnection(ADMIN1, "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE db1 CASCADE");
- statement.execute("DROP DATABASE db2 CASCADE");
- statement.execute("DROP DATABASE db3 CASCADE");
- statement.execute("DROP DATABASE db4 CASCADE");
- statement.close();
- connection.close();
- }
-
- @Test
- public void testPerDBPolicyFileWithURI() throws Exception {
- File db2PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB2_POLICY_FILE);
-
- policyFile
- .addRolesToGroup("user_group1", "select_tbl1")
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .addDatabase("db2", db2PolicyFileHandle.getPath())
- .write(context.getPolicyFile());
-
- PolicyFile db2PolicyFile = new PolicyFile();
- db2PolicyFile
- .addRolesToGroup("user_group2", "select_tbl2", "data_read", "insert_tbl2")
- .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
- .addPermissionsToRole("insert_tbl2", "server=server1->db=db2->table=tbl2->action=insert")
- .addPermissionsToRole("data_read", "server=server1->URI=file://" + dataFile)
- .write(db2PolicyFileHandle);
- // ugly hack: needs to go away once this becomes a config property. Note that this property
- // will not be set with external HS and this test will fail. Hope is this fix will go away
- // by then.
- System.setProperty(SimplePolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "true");
- // setup db objects needed by the test
- Connection connection = context.createConnection(ADMIN1, "hive");
- Statement statement = context.createStatement(connection);
-
- 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("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl1");
- 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.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE db1");
- // test user1 can execute query on tbl1
- verifyCount(statement, "SELECT COUNT(*) FROM tbl1");
-
- // user1 cannot query db2.tbl2
- context.assertAuthzException(statement, "USE db2");
- context.assertAuthzException(statement, "SELECT COUNT(*) FROM db2.tbl2");
- statement.close();
- connection.close();
-
- // test per-db file for db2
- connection = context.createConnection("user2", "password");
- statement = context.createStatement(connection);
- statement.execute("USE db2");
- // test user2 can execute query on tbl2
- verifyCount(statement, "SELECT COUNT(*) FROM tbl2");
-
- // verify user2 can execute LOAD
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
-
- // user2 cannot query db1.tbl1
- context.assertAuthzException(statement, "SELECT COUNT(*) FROM db1.tbl1");
- context.assertAuthzException(statement, "USE db1");
-
- statement.close();
- connection.close();
-
- //test cleanup
- connection = context.createConnection(ADMIN1, "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE db1 CASCADE");
- statement.execute("DROP DATABASE db2 CASCADE");
- statement.close();
- connection.close();
- 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 {
- policyFile
- .addRolesToGroup("user_group1", "select_tbl1")
- .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
- .addGroupsToUser("user_1", "user_group1")
- .addGroupsToUser("user_2", "user_group2")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection(ADMIN1, "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 {
- File db2PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB2_POLICY_FILE);
- File defaultPolicyFileHandle = new File(context.getPolicyFile().getParent(), "default.ini");
-
- policyFile
- .addRolesToGroup("user_group1", "select_tbl1")
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
- .addGroupsToUser("user_1", "user_group1")
- .addGroupsToUser("user_2", "user_group2")
- .addGroupsToUser("user_3", "user_group3")
- .addDatabase("db2", db2PolicyFileHandle.getPath())
- .addDatabase("default", defaultPolicyFileHandle.getPath())
- .write(context.getPolicyFile());
-
- PolicyFile db2PolicyFile = new PolicyFile();
- db2PolicyFile
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
- .write(db2PolicyFileHandle);
-
- PolicyFile defaultPolicyFile = new PolicyFile();
- defaultPolicyFile
- .addRolesToGroup("user_group2", "select_def")
- .addPermissionsToRole("select_def", "server=server1->db=default->table=dtab->action=select")
- .write(defaultPolicyFileHandle);
-
- // setup db objects needed by the test
- Connection connection = context.createConnection(ADMIN1, "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;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 12);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDatabasePolicyFile.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDatabasePolicyFile.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDatabasePolicyFile.java
deleted file mode 100644
index 8c0fb71..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPerDatabasePolicyFile.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.sql.Connection;
-import java.sql.Statement;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-public class TestPerDatabasePolicyFile extends AbstractTestWithStaticLocalFS {
- private static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- private static final String ADMIN1 = "admin1";
- private Context context;
- private PolicyFile policyFile;
- private File globalPolicyFile;
- private File dataDir;
- private File dataFile;
-
- @Before
- public void setup() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- context = createContext();
- globalPolicyFile = context.getPolicyFile();
- dataDir = context.getDataDir();
- assertTrue("Could not delete " + globalPolicyFile, context.deletePolicyFile());
- 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();
- }
-
- @After
- public void teardown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- private void createSampleDbTable(Statement statement, String db, String table)
- throws Exception {
- statement.execute("DROP DATABASE IF EXISTS " + db + " CASCADE");
- statement.execute("CREATE DATABASE " + db);
- statement.execute("USE " + db);
- statement.execute("CREATE TABLE " + table + "(a STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE " + table);
-
- }
-
- /**
- * Ensure that db specific file cannot grant to other db
- */
- @Test
- public void testDbSpecificFileGrantsToOtherDb() throws Exception {
- doTestDbSpecificFileGrants("server=server1->db=db1");
- }
- /**
- * Ensure that db specific file cannot grant to all db
- */
- @Test
- public void testDbSpecificFileGrantsToAllDb() throws Exception {
- doTestDbSpecificFileGrants("server=server1");
- }
- /**
- * Ensure that db specific file cannot grant to all servers
- */
- @Test
- public void testDbSpecificFileGrantsToAllServers() throws Exception {
- doTestDbSpecificFileGrants("server=*");
- }
- /**
- * Ensure that db specific file cannot grant to all
- */
- @Test
- public void testDbSpecificFileGrantsToAll() throws Exception {
- doTestDbSpecificFileGrants("*");
- }
-
- public void doTestDbSpecificFileGrants(String grant) throws Exception {
-
- policyFile.write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection(ADMIN1, "password");
- Statement statement = context.createStatement(connection);
- createSampleDbTable(statement, "db1", "tbl1");
- createSampleDbTable(statement, "db2", "tbl1");
- statement.close();
- connection.close();
-
- File specificPolicyFileFile = new File(context.getBaseDir(), "db2-policy.ini");
-
- PolicyFile specificPolicyFile = new PolicyFile()
- .addPermissionsToRole("db1_role", grant)
- .addRolesToGroup("group1", "db1_role")
- .addGroupsToUser("user1", "group1");
- specificPolicyFile.write(specificPolicyFileFile);
-
- policyFile.addDatabase("db2", specificPolicyFileFile.getPath());
- policyFile.write(context.getPolicyFile());
-
-
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- // test user can query table
- context.assertAuthzException(statement, "USE db1");
- context.assertAuthzException(statement, "SELECT COUNT(a) FROM db1.tbl1");
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegeAtTransform.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegeAtTransform.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegeAtTransform.java
deleted file mode 100644
index 53f295d..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegeAtTransform.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.sql.Connection;
-import java.sql.Statement;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-public class TestPrivilegeAtTransform extends AbstractTestWithStaticLocalFS {
- private Context context;
- private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- private File dataDir;
- private File dataFile;
- private PolicyFile policyFile;
-
- @Before
- public void setup() throws Exception {
- context = createContext();
- dataDir = context.getDataDir();
- 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();
- policyFile = PolicyFile.createAdminOnServer1("admin1");
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /**
- * Steps:
- * 1. admin create database, create table, load data into it
- * 2. all@server can issue transforms command
- * 3. all@database cannot issue transform command
- * 4. insert@table select@table cannot issue transform command
- * 5. select@view cannot issue transform command
- * 6. transform@server can issue the transform command
- */
- @Test
- public void testTransform1() throws Exception {
- policyFile
- .addGroupsToUser("user1", "group1")
- .addPermissionsToRole("all_db1", "server=server1->db=db_1")
- .addRolesToGroup("group1", "all_db1");
- policyFile.write(context.getPolicyFile());
-
- // verify by SQL
- // 1, 2
- String dbName1 = "db_1";
- String tableName1 = "tb_1";
- String query = "select TRANSFORM(a.under_col, a.value) USING 'cat' AS (tunder_col, tvalue) FROM " + dbName1 + "." + tableName1 + " a";
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- statement.execute("DROP TABLE IF EXISTS " + dbName1 + "." + tableName1);
- statement.execute("create table " + dbName1 + "." + tableName1
- + " (under_col int, value string)");
- statement.execute("load data local inpath '" + dataFile.getPath()
- + "' into table " + dbName1 + "." + tableName1);
- assertTrue(query, statement.execute(query));
-
- statement.close();
- connection.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
-
- // 3
- context.assertAuthzExecHookException(statement, query);
-
- // 4
- policyFile
- .addPermissionsToRole("select_tb1", "server=server1->db=db_1->table=tb_1->action=select")
- .addPermissionsToRole("insert_tb1", "server=server1->db=db_1->table=tb_1->action=insert")
- .addRolesToGroup("group1", "select_tb1", "insert_tb1");
- policyFile.write(context.getPolicyFile());
- context.assertAuthzExecHookException(statement, query);
-
- // 5
- policyFile
- .addPermissionsToRole("all_server1", "server=server1")
- .addRolesToGroup("group1", "all_server1");
- policyFile.write(context.getPolicyFile());
- assertTrue(query, statement.execute(query));
- statement.close();
- connection.close();
- }
-}
[7/9] SENTRY-16: Move sentry-tests to sentry-tests-hive package
(Gregory Chanan via Shreepadma Venugopalan)
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtDatabaseScope.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtDatabaseScope.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtDatabaseScope.java
new file mode 100644
index 0000000..f7d701c
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtDatabaseScope.java
@@ -0,0 +1,464 @@
+/*
+ * 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.junit.Assert.assertFalse;
+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.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+/* Tests privileges at table scope within a single database.
+ */
+
+public class TestPrivilegesAtDatabaseScope extends AbstractTestWithHiveServer {
+
+ private Context context;
+ private File dataFile;
+ private PolicyFile policyFile;
+
+ Map <String, String >testProperties;
+ private static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+
+ @Before
+ public void setup() throws Exception {
+ testProperties = new HashMap<String, String>();
+ policyFile = PolicyFile.createAdminOnServer1("admin1");
+ }
+
+ @After
+ public void teardown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /* Admin creates database DB_1
+ * Admin grants ALL to USER_GROUP of which user1 is a member.
+ */
+ @Test
+ public void testAllPrivilege() throws Exception {
+ context = createContext(testProperties);
+
+ //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();
+
+ policyFile
+ .addRolesToGroup("user_group1", "all_db1", "load_data")
+ .addRolesToGroup("user_group2", "all_db2")
+ .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
+ .addPermissionsToRole("all_db2", "server=server1->db=DB_2")
+ .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataFile.getPath())
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("CREATE DATABASE DB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ // test user can create table
+ statement.execute("CREATE TABLE DB_1.TAB_1(A STRING)");
+ // test user can execute load
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE DB_1.TAB_1");
+ statement.execute("CREATE TABLE DB_1.TAB_2(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE DB_1.TAB_2");
+
+ // test user can switch db
+ statement.execute("USE DB_1");
+ //test user can create view
+ statement.execute("CREATE VIEW VIEW_1(A) AS SELECT A FROM TAB_1");
+
+ // test user can insert
+ statement.execute("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
+ // test user can query table
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
+ int count = 0;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 1000);
+
+ // test user can execute alter table rename
+ statement.execute("ALTER TABLE TAB_1 RENAME TO TAB_3");
+
+ // test user can execute create as select
+ statement.execute("CREATE TABLE TAB_4 AS SELECT * FROM TAB_2");
+
+ // test user can execute alter table rename cols
+ statement.execute("ALTER TABLE TAB_3 ADD COLUMNS (B INT)");
+
+ // test user can drop table
+ statement.execute("DROP TABLE TAB_3");
+
+ //negative test case: user can't drop another user's database
+ try {
+ statement.execute("DROP DATABASE DB_2 CASCADE");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ //negative test case: user can't switch into another user's database
+ try {
+ statement.execute("USE DB_2");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ //negative test case: user can't drop own database
+ try {
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ statement.close();
+ connection.close();
+
+ //test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.execute("DROP DATABASE DB_2 CASCADE");
+ statement.close();
+ connection.close();
+ context.close();
+ }
+
+ /* Admin creates database DB_1, creates table TAB_1, loads data into it
+ * Admin grants ALL to USER_GROUP of which user1 is a member.
+ */
+ @Test
+ public void testAllPrivilegeOnObjectOwnedByAdmin() throws Exception {
+ context = createContext(testProperties);
+
+ //copy data file to test dir
+ File dataDir = context.getDataDir();
+ File dataFile = new File(dataDir, SINGLE_TYPE_DATA_FILE_NAME);
+ File externalTblDir = new File(dataDir, "exttab");
+ FileOutputStream to = new FileOutputStream(dataFile);
+ Resources.copy(Resources.getResource(SINGLE_TYPE_DATA_FILE_NAME), to);
+ to.close();
+
+ policyFile
+ .addRolesToGroup("user_group1", "all_db1", "load_data", "exttab")
+ .addRolesToGroup("user_group2", "all_db2")
+ .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
+ .addPermissionsToRole("all_db2", "server=server1->db=DB_2")
+ .addPermissionsToRole("exttab", "server=server1->uri=file://" + dataDir.getPath())
+ .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataFile.getPath())
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("CREATE DATABASE DB_2");
+ statement.execute("USE DB_1");
+ statement.execute("CREATE TABLE TAB_1(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_1");
+ statement.execute("CREATE TABLE PART_TAB_1(A STRING) partitioned by (B INT) STORED AS TEXTFILE");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE PART_TAB_1 PARTITION(B=1)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE PART_TAB_1 PARTITION(B=2)");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ // test user can switch db
+ statement.execute("USE DB_1");
+ // test user can execute load
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_1");
+ statement.execute("CREATE TABLE TAB_2(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_2");
+
+ //test user can create view
+ statement.execute("CREATE VIEW VIEW_1(A) AS SELECT A FROM TAB_1");
+
+ // test user can insert
+ statement.execute("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
+ // test user can query table
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
+ int count = 0;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 1500);
+
+ // test user can execute alter table rename
+ statement.execute("ALTER TABLE TAB_1 RENAME TO TAB_3");
+
+ // test user can drop table
+ statement.execute("DROP TABLE TAB_3");
+
+ //negative test case: user can't drop db
+ try {
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ //negative test case: user can't create external tables
+ assertTrue("Unable to create directory for external table test" , externalTblDir.mkdir());
+ statement.execute("CREATE EXTERNAL TABLE EXT_TAB_1(A STRING) STORED AS TEXTFILE LOCATION 'file:"+
+ externalTblDir.getAbsolutePath() + "'");
+
+ //negative test case: user can't execute alter table set location
+ try {
+ statement.execute("ALTER TABLE TAB_2 SET LOCATION 'hdfs://nn1.example.com/hive/warehouse'");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection("user2", "password");
+ statement = context.createStatement(connection);
+ try {
+ statement.execute("CREATE EXTERNAL TABLE EXT_TAB_1(A STRING) STORED AS TEXTFILE LOCATION 'file:"+
+ externalTblDir.getAbsolutePath() + "'");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ statement.close();
+ connection.close();
+
+ //test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.execute("DROP DATABASE DB_2 CASCADE");
+ statement.close();
+ connection.close();
+ context.close();
+ }
+
+ /**
+ * Test privileges for 'use <db>'
+ * Admin should be able to run use <db> with server level access
+ * User with db level access should be able to run use <db>
+ * User with table level access should be able to run use <db>
+ * User with no access to that db objects, should NOT be able run use <db>
+ * @throws Exception
+ */
+ @Test
+ public void testUseDbPrivilege() throws Exception {
+ context = createContext(testProperties);
+
+ policyFile
+ .addRolesToGroup("user_group1", "all_db1")
+ .addRolesToGroup("user_group2", "select_db2")
+ .addRolesToGroup("user_group3", "all_db3")
+ .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
+ .addPermissionsToRole("select_db2", "server=server1->db=DB_2->table=tab_2->action=select")
+ .addPermissionsToRole("all_db3", "server=server1->db=DB_3")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .addGroupsToUser("user3", "user_group3")
+ .write(context.getPolicyFile());
+
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("use DB_1");
+ statement.execute("CREATE TABLE TAB_1(A STRING)");
+ statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
+ statement.execute("CREATE DATABASE DB_2");
+ statement.execute("use DB_1");
+ statement.execute("CREATE TABLE TAB_2(A STRING)");
+ context.close();
+
+ // user1 should be able to connect db_1
+ connection = context.createConnection("user1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("use DB_1");
+ context.close();
+
+ // user2 should not be able to connect db_1
+ connection = context.createConnection("user2", "hive");
+ statement = context.createStatement(connection);
+ try {
+ statement.execute("use DB_1");
+ assertFalse("user2 shouldn't be able switch to db_1", true);
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ statement.execute("use DB_2");
+ context.close();
+
+ // user3 who is not listed in policy file should not be able to connect db_2
+ connection = context.createConnection("user3", "hive");
+ statement = context.createStatement(connection);
+ try {
+ statement.execute("use DB_2");
+ assertFalse("user3 shouldn't be able switch to db_2", true);
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ context.close();
+ }
+
+ /**
+ * Test access to default DB with out of box authz config
+ * All users should be able to switch to default, including the users that don't have any
+ * privilege on default db objects via policy file
+ * @throws Exception
+ */
+ @Test
+ public void testDefaultDbPrivilege() throws Exception {
+ context = createContext(testProperties);
+
+ policyFile
+ .addRolesToGroup("user_group1", "all_db1")
+ .addRolesToGroup("user_group2", "select_db2")
+ .addRolesToGroup("user_group3", "all_default")
+ .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
+ .addPermissionsToRole("select_db2", "server=server1->db=DB_2->table=tab_2->action=select")
+ .addPermissionsToRole("all_default", "server=server1->db=default")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .addGroupsToUser("user3", "user_group3")
+ .write(context.getPolicyFile());
+
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("use default");
+ context.close();
+
+ connection = context.createConnection("user1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("use default");
+ context.close();
+
+ connection = context.createConnection("user2", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("use default");
+ context.close();
+
+ connection = context.createConnection("user3", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("use default");
+ context.close();
+ }
+
+ /**
+ * Test access to default DB with explicit privilege requirement
+ * Admin should be able to run use default with server level access
+ * User with db level access should be able to run use default
+ * User with table level access should be able to run use default
+ * User with no access to default db objects, should NOT be able run use default
+ * @throws Exception
+ */
+ @Test
+ public void testDefaultDbRestrictivePrivilege() throws Exception {
+ testProperties.put(AuthzConfVars.AUTHZ_RESTRICT_DEFAULT_DB.getVar(), "true");
+ context = createContext(testProperties);
+
+ policyFile
+ .addRolesToGroup("user_group1", "all_default")
+ .addRolesToGroup("user_group2", "select_default")
+ .addRolesToGroup("user_group3", "all_db1")
+ .addPermissionsToRole("all_default", "server=server1->db=default")
+ .addPermissionsToRole("select_default", "server=server1->db=default->table=tab_2->action=select")
+ .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .addGroupsToUser("user3", "user_group3")
+ .write(context.getPolicyFile());
+
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("use default");
+ context.close();
+
+ connection = context.createConnection("user1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("use default");
+ context.close();
+
+ connection = context.createConnection("user2", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("use default");
+ context.close();
+
+ connection = context.createConnection("user3", "hive");
+ statement = context.createStatement(connection);
+ try {
+ // user3 doesn't have any implicit permission for default
+ statement.execute("use default");
+ assertFalse("user3 shouldn't be able switch to default", true);
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ context.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtFunctionScope.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtFunctionScope.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtFunctionScope.java
new file mode 100644
index 0000000..9bc0dcd
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtFunctionScope.java
@@ -0,0 +1,177 @@
+/*
+printf_test_3 * 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.junit.Assert.assertFalse;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestPrivilegesAtFunctionScope extends AbstractTestWithStaticLocalFS {
+ private Context context;
+ private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ private File dataDir;
+ private File dataFile;
+ private PolicyFile policyFile;
+
+ @Before
+ public void setup() throws Exception {
+ context = createContext();
+ dataDir = context.getDataDir();
+ 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();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /**
+ * admin should be able to create/drop temp functions
+ * user with db level access should be able to create/drop temp functions
+ * user with table level access should be able to create/drop temp functions
+ * user with no privilege should NOT be able to create/drop temp functions
+ */
+ @Test
+ public void testFuncPrivileges1() throws Exception {
+ String dbName1 = "db_1";
+ String tableName1 = "tb_1";
+
+ policyFile
+ .addRolesToGroup("group1", "db1_all", "UDF_JAR")
+ .addRolesToGroup("group2", "db1_tab1", "UDF_JAR")
+ .addRolesToGroup("group3", "db1_tab1")
+ .addPermissionsToRole("db1_all", "server=server1->db=" + dbName1)
+ .addPermissionsToRole("db1_tab1", "server=server1->db=" + dbName1 + "->table=" + tableName1)
+ .addPermissionsToRole("UDF_JAR", "server=server1->uri=file://${user.home}/.m2")
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group2")
+ .addGroupsToUser("user3", "group3")
+ .write(context.getPolicyFile());
+
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ 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 INPATH '" + dataFile.getPath() + "' INTO TABLE "
+ + dbName1 + "." + tableName1);
+ statement.execute("DROP TEMPORARY FUNCTION IF EXISTS printf_test");
+ statement.execute("DROP TEMPORARY FUNCTION IF EXISTS printf_test_2");
+ context.close();
+
+ // user1 should be able create/drop temp functions
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName1);
+ statement.execute(
+ "CREATE TEMPORARY FUNCTION printf_test AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
+ statement.execute("DROP TEMPORARY FUNCTION printf_test");
+ context.close();
+
+ // user2 has select privilege on one of the tables in db2, should be able create/drop temp functions
+ connection = context.createConnection("user2", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName1);
+ statement.execute(
+ "CREATE TEMPORARY FUNCTION printf_test_2 AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
+ statement.execute("DROP TEMPORARY FUNCTION printf_test");
+ context.close();
+
+ // user3 shouldn't be able to create/drop temp functions since it doesn't have permission for jar
+ connection = context.createConnection("user3", "foo");
+ statement = context.createStatement(connection);
+ try {
+ statement.execute("USE " + dbName1);
+ statement.execute(
+ "CREATE TEMPORARY FUNCTION printf_test_bad AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
+ assertFalse("CREATE TEMPORARY FUNCTION should fail for user3", true);
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ context.close();
+
+ // user4 (not part of any group ) shouldn't be able to create/drop temp functions
+ connection = context.createConnection("user4", "foo");
+ statement = context.createStatement(connection);
+ try {
+ statement.execute("USE default");
+ statement.execute(
+ "CREATE TEMPORARY FUNCTION printf_test_bad AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
+ assertFalse("CREATE TEMPORARY FUNCTION should fail for user4", true);
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ context.close();
+
+ }
+
+ @Test
+ public void testUdfWhiteList () throws Exception {
+ String dbName1 = "db1";
+ String tableName1 = "tab1";
+
+ policyFile
+ .addRolesToGroup("group1", "db1_all", "UDF_JAR")
+ .addRolesToGroup("group2", "db1_tab1", "UDF_JAR")
+ .addRolesToGroup("group3", "db1_tab1")
+ .addPermissionsToRole("db1_all", "server=server1->db=" + dbName1)
+ .addPermissionsToRole("db1_tab1", "server=server1->db=" + dbName1 + "->table=" + tableName1)
+ .addPermissionsToRole("UDF_JAR", "server=server1->uri=file://${user.home}/.m2")
+ .addGroupsToUser("user1", "group1")
+ .write(context.getPolicyFile());
+
+ Connection connection = context.createConnection("admin1", "password");
+ Statement statement = connection.createStatement();
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ statement.execute("USE " + dbName1);
+ statement.execute("create table " + tableName1
+ + " (under_col int comment 'the under column', value string)");
+ statement.execute("LOAD DATA INPATH '" + dataFile.getPath() + "' INTO TABLE "
+ + dbName1 + "." + tableName1);
+ statement.execute("SELECT rand(), concat(value, '_foo') FROM " + tableName1);
+
+ context.assertAuthzException(statement,
+ "SELECT reflect('java.net.URLDecoder', 'decode', 'http://www.apache.org', 'utf-8'), value FROM " + tableName1);
+ context.assertAuthzException(statement,
+ "SELECT java_method('java.net.URLDecoder', 'decode', 'http://www.apache.org', 'utf-8'), value FROM " + tableName1);
+ statement.close();
+ connection.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java
new file mode 100644
index 0000000..bf30abf
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegesAtTableScope.java
@@ -0,0 +1,678 @@
+/*
+ * 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.junit.Assert.*;
+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.SQLException;
+import java.sql.Statement;
+
+import junit.framework.Assert;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+/* Tests privileges at table scope within a single database.
+ */
+
+public class TestPrivilegesAtTableScope extends AbstractTestWithStaticLocalFS {
+
+ private Context context;
+ private PolicyFile policyFile;
+
+ private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ private final String MULTI_TYPE_DATA_FILE_NAME = "emp.dat";
+
+ @Before
+ public void setup() throws Exception {
+ context = createContext();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ }
+
+ @After
+ public void teardown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /*
+ * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, loads data into
+ * TAB_1, TAB_2 Admin grants SELECT on TAB_1, TAB_2, INSERT on TAB_1 to
+ * USER_GROUP of which user1 is a member.
+ */
+ @Test
+ public void testInsertAndSelect() throws Exception {
+ File dataDir = context.getDataDir();
+ // copy data file to test dir
+ 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();
+
+ policyFile
+ .addRolesToGroup("user_group", "select_tab1", "insert_tab1", "select_tab2")
+ .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
+ .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=TAB_1->action=insert")
+ .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("USE DB_1");
+ statement.execute("CREATE TABLE TAB_1(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_1");
+ statement.execute("CREATE TABLE TAB_2(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+ // test user can insert
+ statement.execute("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
+ // test user can query table
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
+ int count = 0;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 1000);
+
+ // negative test: test user can't drop
+ try {
+ statement.execute("DROP TABLE TAB_1");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ statement.close();
+ connection.close();
+
+ // connect as admin and drop tab_1
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+ statement.execute("DROP TABLE TAB_1");
+ statement.close();
+ connection.close();
+
+ // negative test: connect as user1 and try to recreate tab_1
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+ try {
+ statement.execute("CREATE TABLE TAB_1(A STRING)");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ statement.close();
+ connection.close();
+
+ // test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.close();
+ connection.close();
+
+ }
+
+ /*
+ * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, loads data into
+ * TAB_1, TAB_2. Admin grants INSERT on TAB_1, SELECT on TAB_2 to USER_GROUP
+ * of which user1 is a member.
+ */
+ @Test
+ public void testInsert() throws Exception {
+ File dataDir = context.getDataDir();
+ // copy data file to test dir
+ 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();
+
+ policyFile
+ .addRolesToGroup("user_group", "insert_tab1", "select_tab2")
+ .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=TAB_1->action=insert")
+ .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("USE DB_1");
+ statement.execute("CREATE TABLE TAB_1(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_1");
+ statement.execute("CREATE VIEW VIEW_1(A) AS SELECT A FROM TAB_1");
+ statement.execute("CREATE TABLE TAB_2(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+ // test user can execute insert on table
+ statement.executeQuery("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
+
+ // negative test: user can't query table
+ try {
+ statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ // negative test: test user can't query view
+ try {
+ statement.executeQuery("SELECT COUNT(A) FROM VIEW_1");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ // negative test case: show tables shouldn't list VIEW_1
+ ResultSet resultSet = statement.executeQuery("SHOW TABLES");
+ while (resultSet.next()) {
+ String tableName = resultSet.getString(1);
+ assertNotNull("table name is null in result set", tableName);
+ assertFalse("Found VIEW_1 in the result set",
+ "VIEW_1".equalsIgnoreCase(tableName));
+ }
+
+ // negative test: test user can't create a new view
+ try {
+ statement.executeQuery("CREATE VIEW VIEW_2(A) AS SELECT A FROM TAB_1");
+ Assert.fail("Expected SQL Exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ statement.close();
+ connection.close();
+
+ // test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.close();
+ connection.close();
+ }
+
+ /*
+ * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, loads data into
+ * TAB_1, TAB_2. Admin grants SELECT on TAB_1, TAB_2 to USER_GROUP of which
+ * user1 is a member.
+ */
+ @Test
+ public void testSelect() 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();
+
+ policyFile
+ .addRolesToGroup("user_group", "select_tab1", "select_tab2")
+ .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
+ .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=TAB_1->action=insert")
+ .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("USE DB_1");
+ statement.execute("CREATE TABLE TAB_1(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_1");
+ statement.execute("CREATE VIEW VIEW_1(A) AS SELECT A FROM TAB_1");
+ statement.execute("CREATE TABLE TAB_2(A STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+ // test user can execute query on table
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
+ int count = 0;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 500);
+
+ // negative test: test insert into table
+ try {
+ statement.executeQuery("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ // negative test: test user can't query view
+ try {
+ statement.executeQuery("SELECT COUNT(A) FROM VIEW_1");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ // negative test: test user can't create a new view
+ try {
+ statement.executeQuery("CREATE VIEW VIEW_2(A) AS SELECT A FROM TAB_1");
+ Assert.fail("Expected SQL Exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ statement.close();
+ connection.close();
+
+ // test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.close();
+ connection.close();
+ }
+
+ /*
+ * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, VIEW_1 on TAB_1
+ * loads data into TAB_1, TAB_2. Admin grants SELECT on TAB_1,TAB_2 to
+ * USER_GROUP of which user1 is a member.
+ */
+ @Test
+ public void testTableViewJoin() throws Exception {
+ // copy data file to test dir
+ File dataDir = context.getDataDir();
+ 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();
+
+ policyFile
+ .addRolesToGroup("user_group", "select_tab1", "select_tab2")
+ .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
+ .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("USE DB_1");
+ statement.execute("CREATE TABLE TAB_1(B INT, A STRING) "
+ + " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_1");
+ statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM TAB_1");
+ statement.execute("CREATE TABLE TAB_2(B INT, A STRING) "
+ + " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+ // test user can execute query TAB_1 JOIN TAB_2
+ ResultSet resultSet = statement
+ .executeQuery("SELECT COUNT(*) FROM TAB_1 T1 JOIN TAB_2 T2 ON (T1.B = T2.B)");
+ int count = 0;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 12);
+
+ // negative test: test user can't execute query VIEW_1 JOIN TAB_2
+ try {
+ statement
+ .executeQuery("SELECT COUNT(*) FROM VIEW_1 V1 JOIN TAB_2 T2 ON (V1.B = T2.B)");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ statement.close();
+ connection.close();
+
+ // test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.close();
+ connection.close();
+ }
+
+ /*
+ * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, VIEW_1 on TAB_1
+ * loads data into TAB_1, TAB_2. Admin grants SELECT on TAB_2 to USER_GROUP of
+ * which user1 is a member.
+ */
+ @Test
+ public void testTableViewJoin2() throws Exception {
+
+ 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();
+
+ policyFile
+ .addRolesToGroup("user_group", "select_tab2")
+ .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
+ .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("USE DB_1");
+ statement.execute("CREATE TABLE TAB_1(B INT, A STRING) "
+ + " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_1");
+ statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM TAB_1");
+ statement.execute("CREATE TABLE TAB_2(B INT, A STRING) "
+ + " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+ // test user can execute query on TAB_2
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) FROM TAB_2");
+ int count = 0;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 12);
+
+ // negative test: test user can't execute query VIEW_1 JOIN TAB_2
+ try {
+ statement
+ .executeQuery("SELECT COUNT(*) FROM VIEW_1 JOIN TAB_2 ON (VIEW_1.B = TAB_2.B)");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ // negative test: test user can't execute query TAB_1 JOIN TAB_2
+ try {
+ statement
+ .executeQuery("SELECT COUNT(*) FROM TAB_1 JOIN TAB_2 ON (TAB_1.B = TAB_2.B)");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ statement.close();
+ connection.close();
+
+ // test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.close();
+ connection.close();
+ }
+
+ /*
+ * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, VIEW_1 on TAB_1
+ * loads data into TAB_1, TAB_2. Admin grants SELECT on TAB_2, VIEW_1 to
+ * USER_GROUP of which user1 is a member.
+ */
+ @Test
+ public void testTableViewJoin3() throws Exception {
+ 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();
+
+ policyFile
+ .addRolesToGroup("user_group", "select_tab2", "select_view1")
+ .addPermissionsToRole("select_view1", "server=server1->db=DB_1->table=VIEW_1->action=select")
+ .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("USE DB_1");
+ statement.execute("CREATE TABLE TAB_1(B INT, A STRING) "
+ + " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_1");
+ statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM TAB_1");
+ statement.execute("CREATE TABLE TAB_2(B INT, A STRING) "
+ + " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+ // test user can execute query on TAB_2
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) FROM TAB_2");
+ int count = 0;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 12);
+
+ // test user can execute query VIEW_1 JOIN TAB_2
+ resultSet = statement
+ .executeQuery("SELECT COUNT(*) FROM VIEW_1 V1 JOIN TAB_2 T2 ON (V1.B = T2.B)");
+ count = 0;
+ countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 12);
+
+ // test user can execute query on VIEW_1
+ resultSet = statement.executeQuery("SELECT COUNT(*) FROM VIEW_1");
+ count = 0;
+ countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 12);
+
+ // negative test: test user can't execute query TAB_1 JOIN TAB_2
+ try {
+ statement
+ .executeQuery("SELECT COUNT(*) FROM TAB_1 T1 JOIN TAB_2 T2 ON (T1.B = T2.B)");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ statement.close();
+ connection.close();
+
+ // test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.close();
+ connection.close();
+ }
+
+ /*
+ * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, VIEW_1 on TAB_1
+ * loads data into TAB_1, TAB_2. Admin grants SELECT on TAB_1, VIEW_1 to
+ * USER_GROUP of which user1 is a member.
+ */
+ @Test
+ public void testTableViewJoin4() throws Exception {
+ 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();
+
+ policyFile
+ .addRolesToGroup("user_group", "select_tab1", "select_view1")
+ .addPermissionsToRole("select_view1", "server=server1->db=DB_1->table=VIEW_1->action=select")
+ .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("USE DB_1");
+ statement.execute("CREATE TABLE TAB_1(B INT, A STRING) "
+ + " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_1");
+ statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM TAB_1");
+ statement.execute("CREATE TABLE TAB_2(B INT, A STRING) "
+ + " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE TAB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE DB_1");
+
+ // test user can execute query VIEW_1 JOIN TAB_1
+ ResultSet resultSet = statement
+ .executeQuery("SELECT COUNT(*) FROM VIEW_1 JOIN TAB_1 ON (VIEW_1.B = TAB_1.B)");
+ int count = 0;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 12);
+
+ // negative test: test user can't execute query TAB_1 JOIN TAB_2
+ try {
+ statement
+ .executeQuery("SELECT COUNT(*) FROM TAB_1 JOIN TAB_2 ON (TAB_1.B = TAB_2.B)");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+
+ statement.close();
+ connection.close();
+
+ // test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.close();
+ connection.close();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestRuntimeMetadataRetrieval.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestRuntimeMetadataRetrieval.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestRuntimeMetadataRetrieval.java
new file mode 100644
index 0000000..4b0fe8e
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestRuntimeMetadataRetrieval.java
@@ -0,0 +1,401 @@
+/*
+ * 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.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+/**
+ * Metadata tests for show tables and show databases. * Unlike rest of the
+ * access privilege validation which is handled in semantic hooks, these
+ * statements are validaed via a runtime fetch hook
+ */
+public class TestRuntimeMetadataRetrieval
+ extends
+ AbstractTestWithStaticLocalFS {
+ private Context context;
+ private PolicyFile policyFile;
+ private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ private File dataDir;
+ private File dataFile;
+
+ @Before
+ public void setup() throws Exception {
+ context = createContext();
+ dataDir = context.getDataDir();
+ 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();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /**
+ * Steps: 1. admin create db_1 and db_1.tb_1
+ * 2. admin should see all tables
+ * 3. user1 should only see the tables it has any level of privilege
+ */
+ @Test
+ public void testShowTables1() throws Exception {
+ String dbName1 = "db_1";
+ // tables visible to user1 (not access to tb_4
+ String tableNames[] = {"tb_1", "tb_2", "tb_3", "tb_4"};
+ List<String> tableNamesValidation = new ArrayList<String>();
+
+ policyFile
+ .addRolesToGroup("user_group", "tab1_priv,tab2_priv,tab3_priv")
+ .addPermissionsToRole("tab1_priv", "server=server1->db=" + dbName1 + "->table="
+ + tableNames[0] + "->action=select")
+ .addPermissionsToRole("tab2_priv", "server=server1->db=" + dbName1 + "->table="
+ + tableNames[1] + "->action=insert")
+ .addPermissionsToRole("tab3_priv", "server=server1->db=" + dbName1 + "->table="
+ + tableNames[2] + "->action=select")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ String user1TableNames[] = {"tb_1", "tb_2", "tb_3"};
+
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ statement.execute("USE " + dbName1);
+ createTabs(statement, dbName1, tableNames);
+ // Admin should see all tables
+ ResultSet rs = statement.executeQuery("SHOW TABLES");
+ tableNamesValidation.addAll(Arrays.asList(tableNames));
+
+ validateTables(rs, dbName1, tableNamesValidation);
+ statement.close();
+ context.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName1);
+ // User1 should see tables with any level of access
+ rs = statement.executeQuery("SHOW TABLES");
+ tableNamesValidation.addAll(Arrays.asList(user1TableNames));
+ validateTables(rs, dbName1, tableNamesValidation);
+ statement.close();
+ context.close();
+ }
+
+ /**
+ * Steps: 1. admin create db_1 and tables
+ * 2. admin should see all tables
+ * 3. user1 should only see the all tables with db level privilege
+ */
+ @Test
+ public void testShowTables2() throws Exception {
+ String dbName1 = "db_1";
+ // tables visible to user1 (not access to tb_4
+ String tableNames[] = {"tb_1", "tb_2", "tb_3", "tb_4"};
+ List<String> tableNamesValidation = new ArrayList<String>();
+
+ policyFile
+ .addRolesToGroup("user_group", "db_priv")
+ .addPermissionsToRole("db_priv", "server=server1->db=" + dbName1)
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ String user1TableNames[] = {"tb_1", "tb_2", "tb_3", "tb_4"};
+
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ statement.execute("USE " + dbName1);
+ createTabs(statement, dbName1, tableNames);
+ // Admin should see all tables
+ ResultSet rs = statement.executeQuery("SHOW TABLES");
+ tableNamesValidation.addAll(Arrays.asList(tableNames));
+ validateTables(rs, dbName1, tableNamesValidation);
+ statement.close();
+ context.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName1);
+ // User1 should see tables with any level of access
+ rs = statement.executeQuery("SHOW TABLES");
+ tableNamesValidation.addAll(Arrays.asList(user1TableNames));
+ validateTables(rs, dbName1, tableNamesValidation);
+ statement.close();
+ context.close();
+ }
+
+ /**
+ * Steps: 1. admin create db_1 and db_1.tb_1
+ * 2. admin should see all tables
+ * 3. user1 should only see the tables he/she has any level of privilege
+ */
+ @Test
+ public void testShowTables3() throws Exception {
+ String dbName1 = "db_1";
+ // tables visible to user1 (not access to tb_4
+ String tableNames[] = {"tb_1", "tb_2", "tb_3", "newtab_3"};
+ List<String> tableNamesValidation = new ArrayList<String>();
+
+ policyFile
+ .addRolesToGroup("user_group", "tab_priv")
+ .addPermissionsToRole("tab_priv", "server=server1->db=" + dbName1 + "->table="
+ + tableNames[3] + "->action=insert")
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ String adminTableNames[] = {"tb_3", "newtab_3", "tb_2", "tb_1"};
+ String user1TableNames[] = {"newtab_3"};
+
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ statement.execute("USE " + dbName1);
+ createTabs(statement, dbName1, tableNames);
+ // Admin should see all tables
+ ResultSet rs = statement.executeQuery("SHOW TABLES");
+ tableNamesValidation.addAll(Arrays.asList(adminTableNames));
+ validateTables(rs, dbName1, tableNamesValidation);
+ statement.close();
+ context.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName1);
+ // User1 should see tables with any level of access
+ rs = statement.executeQuery("SHOW TABLES");
+ tableNamesValidation.addAll(Arrays.asList(user1TableNames));
+ validateTables(rs, dbName1, tableNamesValidation);
+ statement.close();
+ context.close();
+ }
+
+ /**
+ * Steps: 1. admin create db_1 and db_1.tb_1
+ * 2. admin should see all tables
+ * 3. user1 should only see the tables with db level privilege
+ */
+ @Test
+ public void testShowTables4() throws Exception {
+ String dbName1 = "db_1";
+ String tableNames[] = {"tb_1", "tb_2", "tb_3", "newtab_3"};
+ List<String> tableNamesValidation = new ArrayList<String>();
+
+ policyFile
+ .addRolesToGroup("user_group", "tab_priv")
+ .addPermissionsToRole("tab_priv", "server=server1->db=" + dbName1)
+ .addGroupsToUser("user1", "user_group")
+ .write(context.getPolicyFile());
+
+ String adminTableNames[] = {"tb_3", "newtab_3", "tb_1", "tb_2"};
+ String user1TableNames[] = {"tb_3", "newtab_3", "tb_1", "tb_2"};
+
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ statement.execute("USE " + dbName1);
+ createTabs(statement, dbName1, tableNames);
+ // Admin should be able to see all tables
+ ResultSet rs = statement.executeQuery("SHOW TABLES");
+ tableNamesValidation.addAll(Arrays.asList(adminTableNames));
+ validateTables(rs, dbName1, tableNamesValidation);
+ statement.close();
+ context.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName1);
+ // User1 should see tables with any level of access
+ rs = statement.executeQuery("SHOW TABLES");
+ tableNamesValidation.addAll(Arrays.asList(user1TableNames));
+ validateTables(rs, dbName1, tableNamesValidation);
+ statement.close();
+ context.close();
+ }
+
+ /**
+ * Steps: 1. admin creates tables in default db
+ * 2. user1 shouldn't see any table when he/she doesn't have any privilege on default
+ */
+ @Test
+ public void testShowTables5() throws Exception {
+ String tableNames[] = {"tb_1", "tb_2", "tb_3", "tb_4"};
+
+ policyFile
+ .addRolesToGroup("user_group", "db_priv")
+ .write(context.getPolicyFile());
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ createTabs(statement, "default", tableNames);
+ context.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ // User1 should see tables with any level of access
+ ResultSet rs = statement.executeQuery("SHOW TABLES");
+ // user1 doesn't have access to any tables in default db
+ Assert.assertFalse(rs.next());
+ statement.close();
+ context.close();
+ }
+
+ /**
+ * Steps: 1. admin create few dbs
+ * 2. admin can do show databases
+ * 3. users with db level permissions should only those dbs on 'show database'
+ */
+ @Test
+ public void testShowDatabases1() throws Exception {
+ List<String> dbNamesValidation = new ArrayList<String>();
+ String[] dbNames = {"db_1", "db_2", "db_3"};
+ String[] user1DbNames = {"db_1"};
+
+ policyFile
+ .addRolesToGroup("group1", "db1_all")
+ .addPermissionsToRole("db1_all", "server=server1->db=db_1")
+ .addGroupsToUser("user1", "group1")
+ .write(context.getPolicyFile());
+
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ // create all dbs
+ createDBs(statement, dbNames);
+ ResultSet rs = statement.executeQuery("SHOW DATABASES");
+ dbNamesValidation.addAll(Arrays.asList(dbNames));
+ dbNamesValidation.add("default");
+ // admin should see all dbs
+ validateDBs(rs, dbNamesValidation);
+ rs.close();
+ context.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ rs = statement.executeQuery("SHOW DATABASES");
+ dbNamesValidation.addAll(Arrays.asList(user1DbNames));
+ dbNamesValidation.add("default");
+ // user should see only dbs with access
+ validateDBs(rs, dbNamesValidation);
+ rs.close();
+ context.close();
+ }
+
+ /**
+ * Steps: 1. admin create few dbs
+ * 2. admin can do show databases
+ * 3. users with table level permissions should should only those parent dbs on 'show
+ * database'
+ */
+ @Test
+ public void testShowDatabases2() throws Exception {
+ String[] dbNames = {"db_1", "db_2", "db_3"};
+ List<String> dbNamesValidation = new ArrayList<String>();
+ String[] user1DbNames = {"db_1", "db_2"};
+
+ policyFile
+ .addRolesToGroup("group1", "db1_tab,db2_tab")
+ .addPermissionsToRole("db1_tab", "server=server1->db=db_1->table=tb_1->action=select")
+ .addPermissionsToRole("db2_tab", "server=server1->db=db_2->table=tb_1->action=insert")
+ .addGroupsToUser("user1", "group1")
+ .write(context.getPolicyFile());
+
+ // verify by SQL
+ // 1, 2
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ createDBs(statement, dbNames); // create all dbs
+ ResultSet rs = statement.executeQuery("SHOW DATABASES");
+ dbNamesValidation.addAll(Arrays.asList(dbNames));
+ dbNamesValidation.add("default");
+ validateDBs(rs, dbNamesValidation); // admin should see all dbs
+ rs.close();
+ context.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ rs = statement.executeQuery("SHOW DATABASES");
+ dbNamesValidation.addAll(Arrays.asList(user1DbNames));
+ dbNamesValidation.add("default");
+ // user should see only dbs with access
+ validateDBs(rs, dbNamesValidation);
+ rs.close();
+ context.close();
+ }
+
+ // create given dbs
+ private void createDBs(Statement statement, String dbNames[])
+ throws SQLException {
+ for (String dbName : dbNames) {
+ statement.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName);
+ }
+ }
+
+ // compare the table resultset with given array of table names
+ private void validateDBs(ResultSet rs, List<String> dbNames)
+ throws SQLException {
+ while (rs.next()) {
+ String dbName = rs.getString(1);
+ Assert.assertTrue(dbName, dbNames.remove(dbName.toLowerCase()));
+ }
+ Assert.assertTrue(dbNames.toString(), dbNames.isEmpty());
+ rs.close();
+ }
+
+ // Create the give tables
+ private void createTabs(Statement statement, String dbName,
+ String tableNames[]) throws SQLException {
+ for (String tabName : tableNames) {
+ statement.execute("DROP TABLE IF EXISTS " + dbName + "." + tabName);
+ statement.execute("create table " + dbName + "." + tabName
+ + " (under_col int comment 'the under column', value string)");
+ }
+ }
+
+ // compare the table resultset with given array of table names
+ private void validateTables(ResultSet rs, String dbName,
+ List<String> tableNames) throws SQLException {
+ while (rs.next()) {
+ String tableName = rs.getString(1);
+ Assert.assertTrue(tableName, tableNames.remove(tableName.toLowerCase()));
+ }
+ Assert.assertTrue(tableNames.toString(), tableNames.isEmpty());
+ rs.close();
+ }
+}
[2/9] SENTRY-16: Move sentry-tests to sentry-tests-hive package
(Gregory Chanan via Shreepadma Venugopalan)
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestSandboxOps.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestSandboxOps.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestSandboxOps.java
deleted file mode 100644
index 70c460e..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestSandboxOps.java
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * 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;
-
-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.hadoop.fs.Path;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
-import com.google.common.io.Files;
-import com.google.common.io.Resources;
-
-public class TestSandboxOps extends AbstractTestWithStaticDFS {
- private PolicyFile policyFile;
- private File dataFile;
- private String loadData;
- private static final String DB2_POLICY_FILE = "db2-policy-file.ini";
-
-
- @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();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- loadData = "server=server1->uri=file://" + dataFile.getPath();
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
- private PolicyFile addTwoUsersWithAllDb() {
- policyFile
- .addGroupsToUser("user1", "user_group")
- .addGroupsToUser("user2", "user_group")
- .addPermissionsToRole("db1_all", "server=server1->db=db1")
- .addPermissionsToRole("db2_all", "server=server1->db=db2")
- .addRolesToGroup("user_group", "db1_all", "db2_all");
- return policyFile;
- }
- /**
- * Tests to ensure that users with all@db can create tables
- * and that they cannot create databases or load data
- */
- @Test
- public void testDbPrivileges() throws Exception {
- addTwoUsersWithAllDb().write(context.getPolicyFile());
- String[] dbs = new String[] { "db1", "db2" };
- for (String dbName : dbs) {
- dropDb(ADMIN1, dbName);
- createDb(ADMIN1, dbName);
- }
- for (String user : new String[] { "user1", "user2" }) {
- for (String dbName : new String[] { "db1", "db2" }) {
- Connection userConn = context.createConnection(user, "foo");
- String tabName = user + "_tab1";
- Statement userStmt = context.createStatement(userConn);
- // Positive case: test user1 and user2 has
- // permissions to access db1 and db2
- userStmt.execute("use " + dbName);
- userStmt.execute("create table " + tabName + " (id int)");
- context.assertAuthzException(userStmt, "load data local inpath '" + dataFile + "' into table " + tabName);
- assertTrue(userStmt.execute("select * from " + tabName));
- // negative users cannot create databases
- context.assertAuthzException(userStmt, "CREATE DATABASE " + user + "_db");
- userStmt.close();
- userConn.close();
- }
- }
-
- for (String dbName : dbs) {
- dropDb(ADMIN1, dbName);
- }
-
- }
- /**
- * Test Case 2.11 admin user create a new database DB_1 and grant ALL to
- * himself on DB_1 should work
- */
- @Test
- public void testAdminDbPrivileges() throws Exception {
- policyFile.write(context.getPolicyFile());
- Connection adminCon = context.createConnection(ADMIN1, "password");
- Statement adminStmt = context.createStatement(adminCon);
- String dbName = "db1";
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
-
- // access the new databases
- adminStmt.execute("use " + dbName);
- String tabName = "admin_tab1";
- adminStmt.execute("create table " + tabName + "(c1 string)");
- adminStmt.execute("load data local inpath '" + dataFile.getPath() + "' into table "
- + tabName);
- adminStmt.execute("select * from " + tabName);
-
- // cleanup
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE " + dbName + " CASCADE");
- adminStmt.close();
- adminCon.close();
- }
-
- /**
- * Test Case 2.16 admin user create a new database DB_1 create TABLE_1 and
- * TABLE_2 (same schema) in DB_1 admin user grant SELECT, INSERT to user1's
- * group on TABLE_2 negative test case: user1 try to do following on TABLE_1
- * will fail: --insert overwrite TABLE_2 select * from TABLE_1
- */
- @Test
- public void testNegativeUserDMLPrivileges() throws Exception {
- policyFile
- .addPermissionsToRole("db1_tab2_all", "server=server1->db=db1->table=table_2")
- .addRolesToGroup("group1", "db1_tab2_all")
- .addGroupsToUser("user3", "group1");
- policyFile.write(context.getPolicyFile());
- Connection adminCon = context.createConnection(ADMIN1, "password");
- Statement adminStmt = context.createStatement(adminCon);
- String dbName = "db1";
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.execute("use " + dbName);
- adminStmt.execute("create table table_1 (id int)");
- adminStmt.execute("create table table_2 (id int)");
- adminStmt.close();
- adminCon.close();
- Connection userConn = context.createConnection("user3", "password");
- Statement userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- // user3 doesn't have select privilege on table_1, so insert/select should fail
- context.assertAuthzException(userStmt, "insert overwrite table table_2 select * from table_1");
- context.assertAuthzException(userStmt, "insert overwrite directory '" + baseDir.getPath() + "' select * from table_1");
- userConn.close();
- userStmt.close();
- }
-
- /**
- * Test Case 2.17 Execution steps a) Admin user creates a new database DB_1,
- * b) Admin user grants ALL on DB_1 to group GROUP_1 c) User from GROUP_1
- * creates table TAB_1, TAB_2 in DB_1 d) Admin user grants SELECT on TAB_1 to
- * group GROUP_2
- *
- * 1) verify users from GROUP_2 have only SELECT privileges on TAB_1. They
- * shouldn't be able to perform any operation other than those listed as
- * requiring SELECT in the privilege model.
- *
- * 2) verify users from GROUP_2 can't perform queries involving join between
- * TAB_1 and TAB_2.
- *
- * 3) verify users from GROUP_1 can't perform operations requiring ALL @
- * SERVER scope. Refer to list
- */
- @Test
- public void testNegUserPrivilegesAll() throws Exception {
- policyFile
- .addRolesToGroup("user_group1", "db1_all")
- .addRolesToGroup("user_group2", "db1_tab1_select")
- .addPermissionsToRole("db1_tab1_select", "server=server1->db=db1->table=table_1->action=select")
- .addPermissionsToRole("db1_all", "server=server1->db=db1")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .write(context.getPolicyFile());
- // create dbs
- Connection adminCon = context.createConnection("admin1", "foo");
- Statement adminStmt = context.createStatement(adminCon);
- String dbName = "db1";
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.execute("use " + dbName);
- adminStmt.execute("create table table_1 (name string)");
- adminStmt.execute("load data local inpath '" + dataFile.getPath() + "' into table table_1");
- adminStmt.execute("create table table_2 (name string)");
- adminStmt.execute("load data local inpath '" + dataFile.getPath() + "' into table table_2");
- adminStmt.execute("create view v1 AS select * from table_1");
- adminStmt.execute("create table table_part_1 (name string) PARTITIONED BY (year INT)");
- adminStmt.execute("ALTER TABLE table_part_1 ADD PARTITION (year = 2012)");
- adminStmt.execute("ALTER TABLE table_1 SET TBLPROPERTIES (\"createTime\"=\"1375824555\")");
- adminStmt.close();
- adminCon.close();
-
- Connection userConn = context.createConnection("user2", "foo");
- Statement userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
-
- context.assertAuthzException(userStmt, "alter table table_2 add columns (id int)");
- context.assertAuthzException(userStmt, "drop database " + dbName);
- context.assertAuthzException(userStmt, "CREATE INDEX x ON TABLE table_1(name) AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'");
- context.assertAuthzException(userStmt, "CREATE TEMPORARY FUNCTION strip AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
- context.assertAuthzException(userStmt, "create table foo(id int)");
- context.assertAuthzException(userStmt, "create table c_tab_2 as select * from table_2"); // no select or create privilege
- context.assertAuthzException(userStmt, "create table c_tab_1 as select * from table_1"); // no create privilege
- context.assertAuthzException(userStmt, "ALTER DATABASE " + dbName + " SET DBPROPERTIES ('foo' = 'bar')");
- context.assertAuthzException(userStmt, "ALTER VIEW v1 SET TBLPROPERTIES ('foo' = 'bar')");
- context.assertAuthzException(userStmt, "DROP VIEW IF EXISTS v1");
- context.assertAuthzException(userStmt, "create table table_5 (name string)");
- context.assertAuthzException(userStmt, "ALTER TABLE table_1 RENAME TO table_99");
- context.assertAuthzException(userStmt, "insert overwrite table table_2 select * from table_1");
- context.assertAuthzException(userStmt, "ALTER TABLE table_part_1 ADD IF NOT EXISTS PARTITION (year = 2012)");
- context.assertAuthzException(userStmt, "ALTER TABLE table_part_1 PARTITION (year = 2012) SET LOCATION '" + baseDir.getPath() + "'");
- context.assertAuthzException(userStmt, "ALTER TABLE table_1 SET TBLPROPERTIES (\"createTime\"=\"1375824555\")");
- }
-
- /**
- * Steps:
- * 1. admin user create databases, DB_1 and DB_2, no table or other
- * object in database
- * 2. admin grant all to user1's group on DB_1 and DB_2
- * positive test case:
- * a)user1 has the privilege to create table, load data,
- * drop table, create view, insert more data on both databases
- * b) user1 can switch between DB_1 and DB_2 without
- * exception negative test case:
- * c) user1 cannot drop database
- * 3. admin remove all to group1 on DB_2
- * positive test case:
- * d) user1 has the privilege to create view on tables in DB_1
- * negative test case:
- * e) user1 cannot create view on tables in DB_1 that select
- * from tables in DB_2
- * 4. admin grant select to group1 on DB_2.ta_2
- * positive test case:
- * f) user1 has the privilege to create view to select from
- * DB_1.tb_1 and DB_2.tb_2
- * negative test case:
- * g) user1 cannot create view to select from DB_1.tb_1
- * and DB_2.tb_3
- * @throws Exception
- */
- @Test
- public void testSandboxOpt9() throws Exception {
-
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, ALL_DB1, ALL_DB2, loadData)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1);
- policyFile.write(context.getPolicyFile());
-
- dropDb(ADMIN1, DB1, DB2);
- createDb(ADMIN1, DB1, DB2);
-
- Connection connection = context.createConnection(USER1, "password");
- Statement statement = context.createStatement(connection);
-
- // a
- statement.execute("USE " + DB1);
- createTable(USER1, DB1, dataFile, TBL1);
- statement.execute("DROP VIEW IF EXISTS " + VIEW1);
- statement.execute("CREATE VIEW " + VIEW1 + " (value) AS SELECT value from " + TBL1 + " LIMIT 10");
-
- createTable(USER1, DB2, dataFile, TBL2, TBL3);
- // c
- context.assertAuthzException(statement, "DROP DATABASE IF EXISTS " + DB1 + " CASCADE");
- context.assertAuthzException(statement, "DROP DATABASE IF EXISTS " + DB2 + " CASCADE");
- // d
- statement.execute("USE " + DB1);
- policyFile.removePermissionsFromRole(GROUP1_ROLE, ALL_DB2);
- policyFile.write(context.getPolicyFile());
- // e
- // create db1.view1 as select from db2.tbl2
- statement.execute("DROP VIEW IF EXISTS " + VIEW2);
- context.assertAuthzException(statement, "CREATE VIEW " + VIEW2 +
- " (value) AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
- // create db1.tbl2 as select from db2.tbl2
- statement.execute("DROP TABLE IF EXISTS " + TBL2);
- context.assertAuthzException(statement, "CREATE TABLE " + TBL2 +
- " AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
- context.assertAuthzException(statement, "CREATE TABLE " + DB2 + "." + TBL2 +
- " AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
-
- // f
- policyFile.addPermissionsToRole(GROUP1_ROLE, SELECT_DB2_TBL2);
- policyFile.write(context.getPolicyFile());
- statement.execute("DROP VIEW IF EXISTS " + VIEW2);
- statement.execute("CREATE VIEW " + VIEW2
- + " (value) AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
-
- // g
- statement.execute("DROP VIEW IF EXISTS " + VIEW3);
- context.assertAuthzException(statement, "CREATE VIEW " + VIEW3
- + " (value) AS SELECT value from " + DB2 + "." + TBL3 + " LIMIT 10");
- statement.close();
- connection.close();
- dropDb(ADMIN1, DB1, DB2);
- }
-
- /**
- * Tests select on table with index.
- *
- * Steps:
- * 1. admin user create a new database DB_1
- * 2. admin create TABLE_1 in DB_1
- * 3. admin create INDEX_1 for COLUMN_1 in TABLE_1 in DB_1
- * 4. admin user grant INSERT and SELECT to user1's group on TABLE_1
- *
- * negative test case:
- * a) user1 try to SELECT * FROM TABLE_1 WHERE COLUMN_1 == ...
- * should NOT work
- * b) user1 should not be able to check the list of view or
- * index in DB_1
- * @throws Exception
- */
- @Test
- public void testSandboxOpt13() throws Exception {
- // unrelated permission to allow user1 to connect to db1
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL2)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1);
- policyFile.write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
- Connection connection = context.createConnection(ADMIN1, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- statement.execute("DROP INDEX IF EXISTS " + INDEX1 + " ON " + TBL1);
- statement.execute("CREATE INDEX " + INDEX1 + " ON TABLE " + TBL1
- + " (under_col) as 'COMPACT' WITH DEFERRED REBUILD");
- statement.close();
- connection.close();
- connection = context.createConnection(USER1, "password");
- statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- context.assertAuthzException(statement, "SELECT * FROM " + TBL1 + " WHERE under_col == 5");
- context.assertAuthzException(statement, "SHOW INDEXES ON " + TBL1);
- policyFile.addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL1, INSERT_DB1_TBL1, loadData);
- policyFile.write(context.getPolicyFile());
- statement.execute("USE " + DB1);
- assertTrue(statement.execute("SELECT * FROM " + TBL1 + " WHERE under_col == 5"));
- assertTrue(statement.execute("SHOW INDEXES ON " + TBL1));
- policyFile.write(context.getPolicyFile());
- dropDb(ADMIN1, DB1, DB2);
- }
-
- /**
- * Steps:
- * 1. Admin user creates a new database DB_1
- * 2. Admin user grants ALL on DB_1 to group GROUP_1
- * 3. User from GROUP_1 creates table TAB_1, TAB_2 in DB_1
- * 4. Admin user grants SELECT/INSERT on TAB_1 to group GROUP_2
- * a) verify users from GROUP_2 have only SELECT/INSERT
- * privileges on TAB_1. They shouldn't be able to perform
- * any operation other than those listed as
- * requiring SELECT in the privilege model.
- * b) verify users from GROUP_2 can't perform queries
- * involving join between TAB_1 and TAB_2.
- * c) verify users from GROUP_1 can't perform operations
- * requiring ALL @SERVER scope:
- * *) create database
- * *) drop database
- * *) show databases
- * *) show locks
- * *) execute ALTER TABLE .. SET LOCATION on a table in DB_1
- * *) execute ALTER PARTITION ... SET LOCATION on a table in DB_1
- * *) execute CREATE EXTERNAL TABLE ... in DB_1
- * *) execute ADD JAR
- * *) execute a query with TRANSOFORM
- * @throws Exception
- */
- @Test
- public void testSandboxOpt17() throws Exception {
-
- policyFile
- .addRolesToGroup("group1", "all_db1", "load_data")
- .addRolesToGroup("group2", "select_tb1")
- .addPermissionsToRole("select_tb1", "server=server1->db=db_1->table=tbl_1->action=select")
- .addPermissionsToRole("all_db1", "server=server1->db=db_1")
- .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataFile.toString())
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group2")
- .write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
-
- createTable(USER1, DB1, dataFile, TBL1, TBL2);
- Connection connection = context.createConnection(USER1, "password");
- Statement statement = context.createStatement(connection);
- // c
- statement.execute("USE " + DB1);
- context.assertAuthzException(statement, "CREATE DATABASE " + DB3);
- context.assertAuthzException(statement, "DROP DATABASE " + DB1);
- ResultSet rs = statement.executeQuery("SHOW DATABASES");
- assertTrue(rs.next());
- assertEquals(DB1, rs.getString(1));
- context.assertAuthzException(statement, "ALTER TABLE " + TBL1 +
- " ADD PARTITION (value = 10) LOCATION '" + dataDir.getPath() + "'");
- context.assertAuthzException(statement, "ALTER TABLE " + TBL1
- + " PARTITION (value = 10) SET LOCATION '" + dataDir.getPath() + "'");
- context.assertAuthzException(statement, "CREATE EXTERNAL TABLE " + TBL3
- + " (under_col int, value string) LOCATION '" + dataDir.getPath() + "'");
- statement.close();
- connection.close();
-
- connection = context.createConnection(USER2, "password");
- statement = context.createStatement(connection);
-
- // a
- statement.execute("USE " + DB1);
- context.assertAuthzException(statement, "SELECT * FROM TABLE " + TBL2 + " LIMIT 10");
- context.assertAuthzException(statement, "EXPLAIN SELECT * FROM TABLE " + TBL2 + " WHERE under_col > 5 LIMIT 10");
- context.assertAuthzException(statement, "DESCRIBE " + TBL2);
- context.assertAuthzException(statement, "LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE " + TBL2);
- context.assertAuthzException(statement, "analyze table " + TBL2 + " compute statistics for columns under_col, value");
- // b
- context.assertAuthzException(statement, "SELECT " + TBL1 + ".* FROM " + TBL1 + " JOIN " + TBL2 +
- " ON (" + TBL1 + ".value = " + TBL2 + ".value)");
- statement.close();
- connection.close();
- }
-
- /**
- * Positive and negative tests for INSERT OVERWRITE [LOCAL] DIRECTORY and
- * LOAD DATA [LOCAL] INPATH. EXPORT/IMPORT are handled in separate junit class.
- * Formerly testSandboxOpt18
- */
- @Test
- public void testInsertOverwriteAndLoadData() throws Exception {
- long counter = System.currentTimeMillis();
- File allowedDir = assertCreateDir(new File(baseDir,
- "test-" + (counter++)));
- File restrictedDir = assertCreateDir(new File(baseDir,
- "test-" + (counter++)));
- Path allowedDfsDir = assertCreateDfsDir(new Path(dfsBaseDir, "test-" + (counter++)));
- Path restrictedDfsDir = assertCreateDfsDir(new Path(dfsBaseDir, "test-" + (counter++)));
-
- policyFile
- .addRolesToGroup("group1", "all_db1", "load_data")
- .addPermissionsToRole("all_db1", "server=server1->db=db_1")
- .addPermissionsToRole("load_data", "server=server1->uri=file://" + allowedDir.getPath() +
- ", server=server1->uri=file://" + allowedDir.getPath() +
- ", server=server1->uri=" + allowedDfsDir.toString())
- .addGroupsToUser("user1", "group1")
- .write(context.getPolicyFile());
-
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- createTable(ADMIN1, DB1, dataFile, TBL1);
- Connection connection = context.createConnection(USER1, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- statement.execute("INSERT OVERWRITE LOCAL DIRECTORY 'file://" + allowedDir.getPath() + "' SELECT * FROM " + TBL1);
- statement.execute("INSERT OVERWRITE DIRECTORY '" + allowedDfsDir + "' SELECT * FROM " + TBL1);
- statement.execute("LOAD DATA LOCAL INPATH 'file://" + allowedDir.getPath() + "' INTO TABLE " + TBL1);
- statement.execute("LOAD DATA INPATH '" + allowedDfsDir + "' INTO TABLE " + TBL1);
- context.assertAuthzException(statement, "INSERT OVERWRITE LOCAL DIRECTORY 'file://" + restrictedDir.getPath() + "' SELECT * FROM " + TBL1);
- context.assertAuthzException(statement, "INSERT OVERWRITE DIRECTORY '" + restrictedDfsDir + "' SELECT * FROM " + TBL1);
- context.assertAuthzException(statement, "LOAD DATA INPATH 'file://" + restrictedDir.getPath() + "' INTO TABLE " + TBL1);
- context.assertAuthzException(statement, "LOAD DATA LOCAL INPATH 'file://" + restrictedDir.getPath() + "' INTO TABLE " + TBL1);
- statement.close();
- connection.close();
- }
-
- /**
- * test create table as with cross database ref
- * @throws Exception
- */
- @Test
- public void testSandboxOpt10() throws Exception {
-
- String rTab1 = "rtab_1";
- String rTab2 = "rtab_2";
-
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, ALL_DB1, SELECT_DB2_TBL2, loadData)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1);
- policyFile.write(context.getPolicyFile());
-
- dropDb(ADMIN1, DB1, DB2);
- createDb(ADMIN1, DB1, DB2);
- createTable(ADMIN1, DB1, dataFile, TBL1);
- createTable(ADMIN1, DB2, dataFile, TBL2, TBL3);
-
- // a
- Connection connection = context.createConnection(USER1, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + DB1);
- statement.execute("CREATE TABLE " + rTab1 + " AS SELECT * FROM " + DB2 + "." + TBL2);
- // user1 doesn't have access to db2, so following create table as should fail
- context.assertAuthzException(statement, "CREATE TABLE " + rTab2 + " AS SELECT * FROM " + DB2 + "." + TBL3);
-
- statement.close();
- connection.close();
- dropDb(ADMIN1, DB1, DB2);
- }
-
- // Create per-db policy file on hdfs and global policy on local.
- @Test
- public void testPerDbPolicyOnDFS() throws Exception {
-
- policyFile
- .addRolesToGroup("user_group1", "select_tbl1")
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .addDatabase("db2", dfsBaseDir.toUri().toString() + "/" + DB2_POLICY_FILE)
- .write(context.getPolicyFile());
-
- File db2PolicyFileHandle = new File(baseDir.getPath(), DB2_POLICY_FILE);
-
- PolicyFile db2PolicyFile = new PolicyFile();
- db2PolicyFile
- .addRolesToGroup("user_group2", "select_tbl2")
- .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
- .write(db2PolicyFileHandle);
- PolicyFiles.copyFilesToDir(dfsCluster.getFileSystem(), dfsBaseDir, db2PolicyFileHandle);
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
-
- 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("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl1");
- 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.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
- statement.close();
- connection.close();
-
- // test per-db file for db2
-
- connection = context.createConnection("user2", "password");
- statement = context.createStatement(connection);
- // test user2 can use db2
- statement.execute("USE db2");
- statement.execute("select * from tbl2");
-
- statement.close();
- connection.close();
-
- //test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE db1 CASCADE");
- statement.execute("DROP DATABASE db2 CASCADE");
- statement.close();
- connection.close();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestSentryOnFailureHookLoading.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestSentryOnFailureHookLoading.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestSentryOnFailureHookLoading.java
deleted file mode 100644
index 43469c5..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestSentryOnFailureHookLoading.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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;
-
-import com.google.common.io.Resources;
-import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServerFactory;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashMap;
-import java.util.Map;
-import junit.framework.Assert;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-
-public class TestSentryOnFailureHookLoading extends AbstractTestWithHiveServer {
-
- private Context context;
- private PolicyFile policyFile;
-
- Map<String, String > testProperties;
- private static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
-
- @Before
- public void setup() throws Exception {
- testProperties = new HashMap<String, String>();
- testProperties.put(HiveAuthzConf.AuthzConfVars.AUTHZ_ONFAILURE_HOOKS.getVar(),
- DummySentryOnFailureHook.class.getName());
- policyFile = PolicyFile.createAdminOnServer1("admin1");
- }
-
- @After
- public void teardown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /* Admin creates database DB_2
- * user1 tries to drop DB_2, but it has permissions for DB_1.
- */
- @Test
- public void testOnFailureHookLoading() throws Exception {
-
- // Do not run this test if run with external HiveServer2
- // This test checks for a static member, which will not
- // be set if HiveServer2 and the test run in different JVMs
- String hiveServer2Type = System.getProperty(
- HiveServerFactory.HIVESERVER2_TYPE);
- if (hiveServer2Type != null &&
- HiveServerFactory.HiveServer2Type.valueOf(hiveServer2Type.trim()) !=
- HiveServerFactory.HiveServer2Type.InternalHiveServer2) {
- return;
- }
-
- context = createContext(testProperties);
-
- File dataDir = context.getDataDir();
- //copy data file to test dir
- 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();
-
- policyFile
- .addRolesToGroup("user_group1", "all_db1", "load_data")
- .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
- .addGroupsToUser("user1", "user_group1")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("CREATE DATABASE DB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
-
- //negative test case: user can't drop another user's database
- assertFalse(DummySentryOnFailureHook.invoked);
- try {
- statement.execute("DROP DATABASE DB_2 CASCADE");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- assertTrue(DummySentryOnFailureHook.invoked);
- }
-
- statement.close();
- connection.close();
-
- //test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.execute("DROP DATABASE DB_2 CASCADE");
- statement.close();
- connection.close();
- context.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestServerConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestServerConfiguration.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestServerConfiguration.java
deleted file mode 100644
index 2c7ed7e..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestServerConfiguration.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-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.SQLException;
-import java.sql.Statement;
-import java.util.Map;
-
-import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
-import org.apache.sentry.binding.hive.HiveAuthzBindingSessionHook;
-import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServerFactory;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.Maps;
-import com.google.common.io.Files;
-
-public class TestServerConfiguration extends AbstractTestWithHiveServer {
-
- private Context context;
- private Map<String, String> properties;
- private PolicyFile policyFile;
-
- @Before
- public void setup() throws Exception {
- properties = Maps.newHashMap();
- policyFile = PolicyFile.createAdminOnServer1("admin1");
-
- }
-
- @After
- public void tearDown() throws Exception {
- if(context != null) {
- context.close();
- }
- }
-
- /**
- * hive.server2.enable.impersonation must be disabled
- */
- @Test
- public void testImpersonationIsDisabled() throws Exception {
- properties.put(HiveServerFactory.ACCESS_TESTING_MODE, "false");
- properties.put("hive.server2.enable.impersonation", "true");
- context = createContext(properties);
- policyFile.write(context.getPolicyFile());
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- try {
- statement.execute("create table test (a string)");
- Assert.fail("Expected SQLException");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- }
-
- /**
- * hive.server2.authentication must be set to LDAP or KERBEROS
- */
- @Test
- public void testAuthenticationIsStrong() throws Exception {
- properties.put(HiveServerFactory.ACCESS_TESTING_MODE, "false");
- properties.put("hive.server2.authentication", "NONE");
- context = createContext(properties);
- policyFile.write(context.getPolicyFile());
- System.out.println(Files.toString(context.getPolicyFile(), Charsets.UTF_8));
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- try {
- statement.execute("create table test (a string)");
- Assert.fail("Expected SQLException");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- }
-
- /**
- * Test removal of policy file
- */
- @Test
- public void testRemovalOfPolicyFile() throws Exception {
- context = createContext(properties);
- File policyFile = context.getPolicyFile();
- assertTrue("Could not delete " + policyFile, policyFile.delete());
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- try {
- statement.execute("create table test (a string)");
- Assert.fail("Expected SQLException");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- }
-
- /**
- * Test corruption of policy file
- */
- @Test
- public void testCorruptionOfPolicyFile() throws Exception {
- context = createContext(properties);
- File policyFile = context.getPolicyFile();
- assertTrue("Could not delete " + policyFile, policyFile.delete());
- FileOutputStream out = new FileOutputStream(policyFile);
- out.write("this is not valid".getBytes(Charsets.UTF_8));
- out.close();
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- try {
- statement.execute("create table test (a string)");
- Assert.fail("Expected SQLException");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- }
-
- @Test
- public void testAddDeleteDFSRestriction() throws Exception {
- context = createContext(properties);
-
- policyFile
- .addRolesToGroup("group1", "all_db1")
- .addRolesToGroup("group2", "select_tb1")
- .addPermissionsToRole("select_tb1", "server=server1->db=db_1->table=tbl_1->action=select")
- .addPermissionsToRole("all_db1", "server=server1->db=db_1")
- .addGroupsToUser("user1", "group1")
- .write(context.getPolicyFile());
-
- Connection connection = context.createConnection("user1", "password");
- Statement statement = context.createStatement(connection);
-
- // disallow external executables. The external.exec is set to false by session hooks
- context.assertAuthzException(statement, "ADD JAR /usr/lib/hive/lib/hbase.jar");
- context.assertAuthzException(statement, "ADD FILE /tmp/tt.py");
- context.assertAuthzException(statement, "DFS -ls");
- context.assertAuthzException(statement, "DELETE JAR /usr/lib/hive/lib/hbase.jar");
- context.assertAuthzException(statement, "DELETE FILE /tmp/tt.py");
- statement.close();
- connection.close();
- }
-
- /**
- * Test that the required access configs are set by session hook
- */
- @Test
- public void testAccessConfigRestrictions() throws Exception {
- context = createContext(properties);
- policyFile.write(context.getPolicyFile());
-
- String testUser = "user1";
- // verify the config is set correctly by session hook
- verifyConfig(testUser, ConfVars.SEMANTIC_ANALYZER_HOOK.varname,
- HiveAuthzBindingSessionHook.SEMANTIC_HOOK);
- verifyConfig(testUser, ConfVars.PREEXECHOOKS.varname,
- HiveAuthzBindingSessionHook.PRE_EXEC_HOOK);
- verifyConfig(testUser, ConfVars.HIVE_EXEC_FILTER_HOOK.varname,
- HiveAuthzBindingSessionHook.FILTER_HOOK);
- verifyConfig(testUser, ConfVars.HIVE_EXTENDED_ENITITY_CAPTURE.varname, "true");
- verifyConfig(testUser, ConfVars.HIVE_SERVER2_AUTHZ_EXTERNAL_EXEC.varname, "false");
- verifyConfig(testUser, ConfVars.SCRATCHDIRPERMISSION.varname, HiveAuthzBindingSessionHook.SCRATCH_DIR_PERMISSIONS);
- verifyConfig(testUser, HiveConf.ConfVars.HIVE_CONF_RESTRICTED_LIST.varname,
- HiveAuthzBindingSessionHook.ACCESS_RESTRICT_LIST);
- verifyConfig(testUser, HiveAuthzConf.HIVE_ACCESS_SUBJECT_NAME, testUser);
- }
-
- private void verifyConfig(String userName, String confVar, String expectedValue) throws Exception {
- Connection connection = context.createConnection(userName, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("set " + confVar);
- ResultSet res = statement.getResultSet();
- assertTrue(res.next());
- String configValue = res.getString(1);
- assertNotNull(configValue);
- String restrictListValues = (configValue.split("="))[1];
- assertFalse(restrictListValues.isEmpty());
- for (String restrictConfig: expectedValue.split(",")) {
- assertTrue(restrictListValues.toLowerCase().contains(restrictConfig.toLowerCase()));
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestUriPermissions.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestUriPermissions.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestUriPermissions.java
deleted file mode 100644
index 51ced04..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestUriPermissions.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * 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;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.Statement;
-
-import junit.framework.Assert;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServerFactory;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestUriPermissions extends AbstractTestWithStaticLocalFS {
- private Context context;
- private PolicyFile policyFile;
-
- private static final String dataFile = "/kv1.dat";
- private String dataFilePath = this.getClass().getResource(dataFile).getFile();
-
- @Before
- public void setup() throws Exception {
- context = createContext();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- // test load data into table
- @Test
- public void testLoadPrivileges() throws Exception {
- String dbName = "db1";
- String tabName = "tab1";
- Connection userConn = null;
- Statement userStmt = null;
-
- policyFile
- .addRolesToGroup("user_group1", "db1_read", "db1_write", "data_read")
- .addRolesToGroup("user_group2", "db1_write")
- .addPermissionsToRole("db1_write", "server=server1->db=" + dbName + "->table=" + tabName + "->action=INSERT")
- .addPermissionsToRole("db1_read", "server=server1->db=" + dbName + "->table=" + tabName + "->action=SELECT")
- .addPermissionsToRole("data_read", "server=server1->URI=file://" + dataFilePath
- + ", server=server1->URI=file://" + dataFilePath)
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .write(context.getPolicyFile());
-
- // create dbs
- Connection adminCon = context.createConnection("admin1", "foo");
- Statement adminStmt = context.createStatement(adminCon);
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.execute("use " + dbName);
- adminStmt.execute("CREATE TABLE " + tabName + "(id int)");
- context.close();
-
- // positive test, user1 has access to file being loaded
- userConn = context.createConnection("user1", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- userStmt.execute("load data local inpath '" + dataFilePath +
- "' 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", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- context.assertAuthzException(userStmt, "load data local inpath '" + dataFilePath +
- "' into table " + tabName);
- userStmt.close();
- userConn.close();
- }
-
- // Test alter partition location
- @Test
- public void testAlterPartitionLocationPrivileges() throws Exception {
- String dbName = "db1";
- String tabName = "tab1";
- String newPartitionDir = "foo";
- String tabDir = "file://" + hiveServer.getProperty(HiveServerFactory.WAREHOUSE_DIR) +
- "/" + tabName + "/" + newPartitionDir;
- Connection userConn = null;
- Statement userStmt = null;
-
- policyFile
- .addRolesToGroup("user_group1", "db1_all", "data_read")
- .addRolesToGroup("user_group2", "db1_all")
- .addRolesToGroup("user_group3", "db1_tab1_all", "data_read")
- .addPermissionsToRole("db1_all", "server=server1->db=" + dbName)
- .addPermissionsToRole("db1_tab1_all", "server=server1->db=" + dbName + "->table=" + tabName)
- .addPermissionsToRole("data_read", "server=server1->URI=" + tabDir)
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .addGroupsToUser("user3", "user_group3")
- .write(context.getPolicyFile());
-
- // create dbs
- Connection adminCon = context.createConnection("admin1", "foo");
- Statement adminStmt = context.createStatement(adminCon);
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.execute("use " + dbName);
- adminStmt.execute("CREATE TABLE " + tabName + " (id int) PARTITIONED BY (dt string)");
- adminCon.close();
-
- // positive test: user1 has privilege to alter table add partition but not set location
- userConn = context.createConnection("user1", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- userStmt.execute("ALTER TABLE " + tabName + " ADD PARTITION (dt = '21-Dec-2012') " +
- " LOCATION '" + tabDir + "'");
- // negative test user1 cannot alter partition location
- context.assertAuthzException(userStmt,
- "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", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- 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')");
- userConn.close();
-
- // negative test: user3 doesn't have privilege to add/drop partitions
- userConn = context.createConnection("user3", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- context.assertAuthzException(userStmt,
- "ALTER TABLE " + tabName + " ADD PARTITION (dt = '22-Dec-2012') " +
- " LOCATION '" + tabDir + "/foo'");
- context.assertAuthzException(userStmt,
- "ALTER TABLE " + tabName + " DROP PARTITION (dt = '21-Dec-2012')");
- userConn.close();
-
- // positive test: user1 has privilege to alter drop partition
- userConn = context.createConnection("user1", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- 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 dbName = "db1";
- String tabName = "tab1";
- String tabDir = "file://" + hiveServer.getProperty(HiveServerFactory.WAREHOUSE_DIR) + "/" + tabName;
- Connection userConn = null;
- Statement userStmt = null;
-
- policyFile
- .addRolesToGroup("user_group1", "server1_all")
- .addRolesToGroup("user_group2", "db1_all, data_read")
- .addPermissionsToRole("db1_all", "server=server1->db=" + dbName)
- .addPermissionsToRole("data_read", "server=server1->URI=" + tabDir)
- .addPermissionsToRole("server1_all", "server=server1")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .write(context.getPolicyFile());
-
- // create dbs
- Connection adminCon = context.createConnection("admin1", "foo");
- Statement adminStmt = context.createStatement(adminCon);
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.execute("use " + dbName);
- adminStmt.execute("CREATE TABLE " + tabName + " (id int) PARTITIONED BY (dt string)");
- adminCon.close();
-
- // negative test: user2 doesn't have privilege to alter table set partition
- userConn = context.createConnection("user2", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- context.assertAuthzException(userStmt,
- "ALTER TABLE " + tabName + " SET LOCATION '" + tabDir + "'");
- userConn.close();
-
- // positive test: user1 has privilege to alter table set partition
- userConn = context.createConnection("user1", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- userStmt.execute("ALTER TABLE " + tabName + " SET LOCATION '" + tabDir + "'");
- userConn.close();
- }
-
- // Test external table
- @Test
- public void testExternalTablePrivileges() throws Exception {
- String dbName = "db1";
- Connection userConn = null;
- Statement userStmt = null;
- String tableDir = "file://" + context.getDataDir();
-
- policyFile
- .addRolesToGroup("user_group1", "db1_all", "data_read")
- .addRolesToGroup("user_group2", "db1_all")
- .addPermissionsToRole("db1_all", "server=server1->db=" + dbName)
- .addPermissionsToRole("data_read", "server=server1->URI=" + tableDir)
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .write(context.getPolicyFile());
-
- // create dbs
- Connection adminCon = context.createConnection("admin1", "foo");
- Statement adminStmt = context.createStatement(adminCon);
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.close();
- adminCon.close();
-
- // negative test: user2 doesn't have privilege to create external table in given path
- userConn = context.createConnection("user2", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- 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", "foo");
- userStmt = context.createStatement(userConn);
- userStmt.execute("use " + dbName);
- 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();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestUserManagement.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestUserManagement.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestUserManagement.java
deleted file mode 100644
index ed9fe36..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestUserManagement.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertFalse;
-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.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-public class TestUserManagement extends AbstractTestWithStaticLocalFS {
- private static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- private static final String dbName = "db1";
- private static final String tableName = "t1";
- private static final String tableComment = "Test table";
- private File dataFile;
- private Context context;
- private PolicyFile policyFile;
-
- @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();
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
- private void doCreateDbLoadDataDropDb(String admin, String...users) throws Exception {
- doDropDb(admin);
- for (String user : users) {
- doCreateDb(user);
- Connection connection = context.createConnection(user, "password");
- Statement statement = context.createStatement(connection);
- ResultSet res = statement.executeQuery("SHOW DATABASES");
- boolean created = false;
- while (res.next()) {
- if (res.getString(1).equals(dbName)) {
- created = true;
- }
- }
- assertTrue("database " + dbName + " is not created", created);
- doCreateTableLoadData(user);
- doDropDb(user);
- statement.close();
- connection.close();
- }
- }
- private void doDropDb(String user) throws Exception {
- Connection connection = context.createConnection(user, "password");
- Statement statement = connection.createStatement();
- statement.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- statement.close();
- connection.close();
- }
- private void doCreateDb(String user) throws Exception {
- Connection connection = context.createConnection(user, "password");
- Statement statement = connection.createStatement();
- statement.execute("CREATE DATABASE " + dbName);
- statement.close();
- connection.close();
- }
- private void doCreateTableLoadData(String user) throws Exception {
- Connection connection = context.createConnection(user, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + dbName);
- statement.execute("CREATE TABLE " + tableName +
- " (under_col int comment 'the under column', value string) comment '"
- + tableComment + "'");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' into table " + tableName);
- assertTrue(statement.execute("SELECT * FROM " + tableName));
- statement.close();
- connection.close();
- }
- /**
- * Basic sanity test
- */
- @Test
- public void testSanity() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- policyFile.write(context.getPolicyFile());
- doCreateDbLoadDataDropDb("admin1", "admin1");
- }
-
- /**
- * Tests admin privileges allow admins to create/drop dbs
- **/
- @Test
- public void testAdmin1() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- policyFile
- .addGroupsToUser("admin2", "admin")
- .addGroupsToUser("admin3", "admin")
- .write(context.getPolicyFile());
-
- doCreateDbLoadDataDropDb("admin1", "admin1", "admin2", "admin3");
- }
-
- /**
- * Negative case: Tests that when a user is removed
- * from the policy file their permissions have no effect
- **/
- @Test
- public void testAdmin3() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- policyFile
- .addGroupsToUser("admin2", "admin")
- .addGroupsToUser("admin3", "admin")
- .write(context.getPolicyFile());
- doCreateDbLoadDataDropDb("admin1", "admin1", "admin2", "admin3");
-
- // remove admin1 from admin group
- policyFile
- .removeGroupsFromUser("admin1", "admin")
- .write(context.getPolicyFile());
- // verify admin1 doesn't have admin privilege
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = connection.createStatement();
- context.assertAuthzException(statement, "CREATE DATABASE somedb");
- statement.close();
- connection.close();
- }
-
- /**
- * Tests that users in two groups work correctly
- **/
- @Test
- public void testAdmin5() throws Exception {
- policyFile = new PolicyFile();
- policyFile
- .addRolesToGroup("admin_group1", "admin")
- .addRolesToGroup("admin_group2", "admin")
- .addPermissionsToRole("admin", "server=server1")
- .addGroupsToUser("admin1", "admin_group1", "admin_group2")
- .addGroupsToUser("admin2", "admin_group1", "admin_group2")
- .addGroupsToUser("admin3", "admin_group1", "admin_group2")
- .write(context.getPolicyFile());
- doCreateDbLoadDataDropDb("admin1", "admin1", "admin2", "admin3");
- }
-
- /**
- * Tests admin group does not infect non-admin group
- **/
- @Test
- public void testAdmin6() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- policyFile
- .addRolesToGroup("group1", "non_admin_role")
- .addPermissionsToRole("non_admin_role", "server=server1->db=" + dbName)
- .addGroupsToUser("user1", "group1")
- .write(context.getPolicyFile());
-
- doCreateDbLoadDataDropDb("admin1", "admin1");
- Connection connection = context.createConnection("user1", "password");
- Statement statement = connection.createStatement();
- context.assertAuthzException(statement, "CREATE DATABASE " + dbName);
- statement.close();
- connection.close();
- }
-
- /**
- * Tests that user with two roles the most powerful role takes effect
- **/
- @Test
- public void testGroup2() throws Exception {
- policyFile = new PolicyFile();
- policyFile
- .addRolesToGroup("group1", "admin", "analytics")
- .addPermissionsToRole("admin", "server=server1")
- .addPermissionsToRole("analytics", "server=server1->db=" + dbName)
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group1")
- .addGroupsToUser("user3", "group1")
- .write(context.getPolicyFile());
- doCreateDbLoadDataDropDb("user1", "user1", "user2", "user3");
- }
- /**
- * Tests that user without uri privilege can create table but not load data
- **/
- @Test
- public void testGroup4() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- policyFile
- .addRolesToGroup("group1", "non_admin_role", "load_data")
- .addPermissionsToRole("non_admin_role", "server=server1->db=" + dbName)
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group1")
- .addGroupsToUser("user3", "group1")
- .write(context.getPolicyFile());
-
- doDropDb("admin1");
- for(String user : new String[]{"user1", "user2", "user3"}) {
- doCreateDb("admin1");
- Connection connection = context.createConnection(user, "password");
- Statement statement = context.createStatement(connection);
- statement.execute("USE " + dbName);
- statement.execute("CREATE TABLE " + tableName +
- " (under_col int comment 'the under column', value string) comment '"
- + tableComment + "'");
- context.assertAuthzException(statement,
- "LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' into table " + tableName);
- assertTrue(statement.execute("SELECT * FROM " + tableName));
- statement.close();
- connection.close();
- doDropDb("admin1");
- }
- }
- /**
- * Tests users can have same name as groups
- **/
- @Test
- public void testGroup5() throws Exception {
-
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- policyFile
- .addRolesToGroup("group1", "non_admin_role", "load_data")
- .addPermissionsToRole("non_admin_role", "server=server1->db=" + dbName)
- .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
- .addGroupsToUser("group1", "group1")
- .addGroupsToUser("user2", "group1")
- .addGroupsToUser("user3", "group1")
- .write(context.getPolicyFile());
-
- doDropDb("admin1");
- for(String user : new String[]{"group1", "user2", "user3"}) {
- doCreateDb("admin1");
- doCreateTableLoadData(user);
- doDropDb("admin1");
- }
- }
-
- /**
- * Tests that group names with special characters are handled correctly
- **/
- @Test
- public void testGroup6() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- policyFile
- .addRolesToGroup("group1~!@#$%^&*()+-", "analytics", "load_data")
- .addPermissionsToRole("analytics", "server=server1->db=" + dbName)
- .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
- .addGroupsToUser("user1", "group1~!@#$%^&*()+-")
- .addGroupsToUser("user2", "group1~!@#$%^&*()+-")
- .addGroupsToUser("user3", "group1~!@#$%^&*()+-")
- .write(context.getPolicyFile());
-
- doDropDb("admin1");
- for(String user : new String[]{"user1", "user2", "user3"}) {
- doCreateDb("admin1");
- doCreateTableLoadData(user);
- doDropDb("admin1");
- }
- }
-
- /**
- * Tests that user names with special characters are handled correctly
- **/
- @Test
- public void testGroup7() throws Exception {
- policyFile = new PolicyFile();
- policyFile
- .addRolesToGroup("group1", "admin")
- .addPermissionsToRole("admin", "server=server1")
- .addGroupsToUser("user1~!@#$%^&*()+-", "group1")
- .addGroupsToUser("user2", "group1")
- .addGroupsToUser("user3", "group1")
- .write(context.getPolicyFile());
- doCreateDbLoadDataDropDb("user1~!@#$%^&*()+-", "user1~!@#$%^&*()+-", "user2", "user3");
- }
-
- /**
- * Tests that users with no privileges cannot list any tables
- **/
- @Test
- public void testGroup8() throws Exception {
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- policyFile
- .addRolesToGroup("group1", "analytics")
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group1")
- .addGroupsToUser("user3", "group1")
- .write(context.getPolicyFile());
-
- Connection connection = context.createConnection("admin1", "password");
- Statement statement = connection.createStatement();
- statement.execute("DROP DATABASE IF EXISTS db1 CASCADE");
- statement.execute("CREATE DATABASE db1");
- statement.execute("USE db1");
- statement.execute("CREATE TABLE t1 (under_col int, value string)");
- statement.close();
- connection.close();
- String[] users = { "user1", "user2", "user3" };
- for (String user : users) {
- connection = context.createConnection(user, "foo");
- statement = context.createStatement(connection);
- assertFalse("No results should be returned",
- statement.executeQuery("SHOW TABLES").next());
- statement.close();
- connection.close();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/AbstractHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/AbstractHiveServer.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/AbstractHiveServer.java
deleted file mode 100644
index 413ef52..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/AbstractHiveServer.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.hiveserver;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
-
-import com.google.common.base.Strings;
-
-public abstract class AbstractHiveServer implements HiveServer {
-
- private static final String LINK_FAILURE_SQL_STATE = "08S01";
-
- private final Configuration configuration;
- private final String hostname;
- private final int port;
-
- public AbstractHiveServer(Configuration configuration, String hostname,
- int port) {
- this.configuration = configuration;
- this.hostname = hostname;
- this.port = port;
- }
-
- @Override
- public String getProperty(String key) {
- return configuration.get(key);
- }
-
- @Override
- public String getURL() {
- return "jdbc:hive2://" + hostname + ":" + port + "/default";
- }
-
- public Connection createConnection(String user, String password) throws Exception{
- String url = getURL();
- Connection connection = DriverManager.getConnection(url, user, password);
- return connection;
- }
-
- protected static String getHostname(HiveConf hiveConf) {
- return hiveConf.get(ConfVars.HIVE_SERVER2_THRIFT_BIND_HOST.toString(), "localhost").trim();
- }
- protected static int getPort(HiveConf hiveConf) {
- return Integer.parseInt(hiveConf.get(ConfVars.HIVE_SERVER2_THRIFT_PORT.toString(), "10000").trim());
- }
- protected static void waitForStartup(HiveServer hiveServer) throws Exception {
- int waitTime = 0;
- long startupTimeout = 1000L * 10L;
- do {
- Thread.sleep(500L);
- waitTime += 500L;
- if (waitTime > startupTimeout) {
- throw new TimeoutException("Couldn't access new HiveServer: " + hiveServer.getURL());
- }
- try {
- Connection connection = DriverManager.getConnection(hiveServer.getURL(), "hive", "bar");
- connection.close();
- break;
- } catch (SQLException e) {
- String state = Strings.nullToEmpty(e.getSQLState()).trim();
- if (!state.equalsIgnoreCase(LINK_FAILURE_SQL_STATE)) {
- throw e;
- }
- }
- } while (true);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/EmbeddedHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/EmbeddedHiveServer.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/EmbeddedHiveServer.java
deleted file mode 100644
index ba9a913..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/EmbeddedHiveServer.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.hiveserver;
-
-import org.apache.hadoop.hive.metastore.HiveMetaStore;
-import org.fest.reflect.core.Reflection;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-
-public class EmbeddedHiveServer implements HiveServer {
-
- @Override
- public void start() {
- // Fix for ACCESS-148. Resets a static field
- // so the default database is created even
- // though is has been created before in this JVM
- Reflection.staticField("createDefaultDB")
- .ofType(boolean.class)
- .in(HiveMetaStore.HMSHandler.class)
- .set(false);
- }
-
- public Connection createConnection(String user, String password) throws Exception{
- String url = getURL();
- Connection connection = DriverManager.getConnection(url, user, password);
- return connection;
- }
-
- @Override
- public void shutdown() {
-
- }
-
- @Override
- public String getURL() {
- return "jdbc:hive2://";
- }
-
- @Override
- public String getProperty(String key) {
- throw new UnsupportedOperationException();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/ExternalHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/ExternalHiveServer.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/ExternalHiveServer.java
deleted file mode 100644
index 6065002..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/ExternalHiveServer.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.hiveserver;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.List;
-
-import org.apache.hadoop.hive.conf.HiveConf;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-
-
-public class ExternalHiveServer extends AbstractHiveServer {
- private static final Logger LOGGER = LoggerFactory
- .getLogger(ExternalHiveServer.class);
- private final File confDir;
- private final File logDir;
- private Process process;
-
- public ExternalHiveServer(HiveConf hiveConf, File confDir, File logDir) throws Exception {
- super(hiveConf, getHostname(hiveConf), getPort(hiveConf));
- this.confDir = confDir;
- this.logDir = logDir;
- }
-
-
- @Override
- public synchronized void start() throws Exception {
- String hiveCommand = System.getProperty("hive.bin.path", "./target/hive/bin/hive");
- String hadoopHome = System.getProperty("hadoop.home", "./target/hadoop");
- String hadoopClasspath = getHadoopClasspath();
- String command = "export ";
- command += String.format("HIVE_CONF_DIR=\"%s\" HADOOP_HOME=\"%s\" ", confDir.getPath(), hadoopHome);
- command += String.format("HADOOP_CLASSPATH=\"%s:%s\" ", confDir.getPath(), hadoopClasspath);
- command += "HADOOP_CLIENT_OPTS=\"-Dhive.log.dir=./target/\"";
- command += "; ";
- command += String.format("%s --service hiveserver2 >%s/hs2.out 2>&1 & echo $! > %s/hs2.pid",
- hiveCommand, logDir.getPath(), logDir.getPath());
- LOGGER.info("Executing " + command);
- process = Runtime.getRuntime().
- exec(new String[]{"/bin/sh", "-c", command});
- waitForStartup(this);
- }
-
- @Override
- public synchronized void shutdown() throws Exception {
- if(process != null) {
- process.destroy();
- process = null;
- String pid = Strings.nullToEmpty(Files.readFirstLine(new File(logDir, "hs2.pid"), Charsets.UTF_8)).trim();
- if(!pid.isEmpty()) {
- LOGGER.info("Killing " + pid);
- Process killCommand = Runtime.getRuntime().
- exec(new String[]{"/bin/sh", "-c", "kill " + pid});
- // TODO this isn't strictly correct but kill won't output much data
- String error = read(killCommand.getErrorStream());
- String output = read(killCommand.getInputStream());
- LOGGER.info("Kill exit code " + killCommand.waitFor() +
- ", output = '" + output + "', error = '" + error + "'");
- }
- }
- }
-
- private String read(InputStream is) throws IOException {
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
- StringBuffer buffer = new StringBuffer();
- try {
- String line;
- while((line = reader.readLine()) != null) {
- buffer.append(line);
- }
- return buffer.toString();
- } finally {
- reader.close();
- }
-
- }
-
- private String getHadoopClasspath() {
- List<String> result = Lists.newArrayList();
- String clazzPath = Preconditions.checkNotNull(System.getProperty("java.class.path"), "java.class.path");
- String sep = Preconditions.checkNotNull(System.getProperty("path.separator"), "path.separator");
- for(String item : Splitter.on(sep).omitEmptyStrings().trimResults().split(clazzPath)) {
- if(item.endsWith("/sentry-tests/target/classes") ||
- item.endsWith("/sentry-tests/target/test-classes")) {
- result.add(item);
- } else {
- File clazzPathItem = new File(item);
- String fileName = clazzPathItem.getName();
- if(clazzPathItem.isFile() && fileName.startsWith("sentry-") && fileName.endsWith(".jar")) {
- result.add(item);
- }
- }
- }
- return Joiner.on(sep).join(result);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/HiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/HiveServer.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/HiveServer.java
deleted file mode 100644
index 8f519a4..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/hiveserver/HiveServer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.hiveserver;
-
-import java.sql.Connection;
-
-public interface HiveServer {
-
- public void start() throws Exception;
-
- public void shutdown() throws Exception;
-
- public String getURL();
-
- public String getProperty(String key);
-
- public Connection createConnection(String user, String password) throws Exception;
-
-}
[8/9] SENTRY-16: Move sentry-tests to sentry-tests-hive package
(Gregory Chanan via Shreepadma Venugopalan)
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestEndToEnd.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestEndToEnd.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestEndToEnd.java
new file mode 100644
index 0000000..8a32e5f
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestEndToEnd.java
@@ -0,0 +1,143 @@
+/*
+ * 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.Statement;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestEndToEnd extends AbstractTestWithStaticLocalFS {
+ private Context context;
+ private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ private File dataFile;
+ private PolicyFile policyFile;
+
+
+ @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();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /**
+ * Steps:
+ * 1. admin create a new experimental database
+ * 2. admin create a new production database, create table, load data
+ * 3. admin create new user group, and add user into it
+ * 4. admin grant privilege all@'experimental database' to group
+ * 5. user create table, load data in experimental DB
+ * 6. user create view based on table in experimental DB
+ * 7. admin create table (same name) in production DB
+ * 8. admin grant read@productionDB.table to group
+ * admin grant select@productionDB.table to group
+ * 9. user load data from experimental table to production table
+ */
+ @Test
+ public void testEndToEnd1() throws Exception {
+ policyFile.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", "foo");
+ 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);
+ statement.close();
+ connection.close();
+
+ // 3
+ policyFile.addGroupsToUser("user1", "group1");
+
+ // 4
+ policyFile
+ .addRolesToGroup("group1", "all_db1", "data_uri", "select_tb1", "insert_tb1")
+ .addPermissionsToRole("all_db1", "server=server1->db=db_1")
+ .addPermissionsToRole("select_tb1", "server=server1->db=productionDB->table=tb_1->action=select")
+ .addPermissionsToRole("insert_tb2", "server=server1->db=productionDB->table=tb_2->action=insert")
+ .addPermissionsToRole("insert_tb1", "server=server1->db=productionDB->table=tb_2->action=insert")
+ .addPermissionsToRole("data_uri", "server=server1->uri=file://" + dataDir.getPath());
+ policyFile.write(context.getPolicyFile());
+
+ // 5
+ connection = context.createConnection("user1", "foo");
+ 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);
+ // 6
+ statement.execute("CREATE VIEW " + viewName1 + " (value) AS SELECT value from " + tableName1 + " LIMIT 10");
+ statement.close();
+ connection.close();
+
+ // 7
+ connection = context.createConnection("admin1", "foo");
+ 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();
+
+ // 9
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName2);
+ statement.execute("INSERT OVERWRITE TABLE " +
+ dbName2 + "." + tableName2 + " SELECT * FROM " + dbName1
+ + "." + tableName1);
+ statement.close();
+ connection.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestExportImportPrivileges.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestExportImportPrivileges.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestExportImportPrivileges.java
new file mode 100644
index 0000000..c2403f8
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestExportImportPrivileges.java
@@ -0,0 +1,154 @@
+/*
+ * 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.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.Statement;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestExportImportPrivileges extends AbstractTestWithStaticDFS {
+ private File dataFile;
+ private PolicyFile policyFile;
+
+ @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();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ @Test
+ public void testInsertToDirPrivileges() throws Exception {
+ Connection connection = null;
+ Statement statement = null;
+ String dumpDir = context.getDFSUri().toString() + "/hive_data_dump";
+
+ policyFile
+ .addRolesToGroup("user_group1", "db1_read", "db1_write", "data_dump")
+ .addRolesToGroup("user_group2", "db1_read", "db1_write")
+ .addPermissionsToRole("db1_write", "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=INSERT")
+ .addPermissionsToRole("db1_read", "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=SELECT")
+ .addPermissionsToRole("data_dump", "server=server1->URI=" + dumpDir)
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2");
+ policyFile.write(context.getPolicyFile());
+
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+
+ // Negative test, user2 doesn't have access to write to dir
+ connection = context.createConnection(USER2, "password");
+ statement = context.createStatement(connection);
+ statement.execute("use " + DB1);
+ context.assertAuthzException(statement, "INSERT OVERWRITE DIRECTORY '" + dumpDir + "' SELECT * FROM " + TBL1);
+ statement.close();
+ connection.close();
+
+ // Negative test, user2 doesn't have access to dir that's similar to scratch dir
+ String scratchDumpDir = context.getProperty(HiveConf.ConfVars.SCRATCHDIR.varname) + "_foo" + "/bar";
+ connection = context.createConnection(USER2, "password");
+ statement = context.createStatement(connection);
+ statement.execute("use " + DB1);
+ context.assertAuthzException(statement, "INSERT OVERWRITE DIRECTORY '" + scratchDumpDir + "' SELECT * FROM " + TBL1);
+ statement.close();
+ connection.close();
+
+ // positive test, user1 has access to write to dir
+ connection = context.createConnection(USER1, "password");
+ statement = context.createStatement(connection);
+ statement.execute("use " + DB1);
+ assertTrue(statement.executeQuery("SELECT * FROM " + TBL1).next());
+ statement.execute("INSERT OVERWRITE DIRECTORY '" + dumpDir + "' SELECT * FROM " + TBL1);
+ }
+
+ @Test
+ public void testExportImportPrivileges() throws Exception {
+ Connection connection = null;
+ Statement statement = null;
+ String exportDir = context.getDFSUri().toString() + "/hive_export1";
+
+ policyFile
+ .addRolesToGroup("user_group1", "tab1_read", "tab1_write", "db1_all", "data_read", "data_export")
+ .addRolesToGroup("user_group2", "tab1_write", "tab1_read")
+ .addPermissionsToRole("tab1_write", "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=INSERT")
+ .addPermissionsToRole("tab1_read", "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=SELECT")
+ .addPermissionsToRole("db1_all", "server=server1->db=" + DB1)
+ .addPermissionsToRole("data_read", "server=server1->URI=file://" + dataFile.getPath())
+ .addPermissionsToRole("data_export", "server=server1->URI=" + exportDir)
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2");
+ policyFile.write(context.getPolicyFile());
+
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+
+ // Negative test, user2 doesn't have access to the file being loaded
+ connection = context.createConnection(USER2, "password");
+ statement = context.createStatement(connection);
+ statement.execute("use " + DB1);
+ context.assertAuthzException(statement, "EXPORT TABLE " + TBL1 + " TO '" + exportDir + "'");
+ statement.close();
+ connection.close();
+
+ // Positive test, user1 have access to the target directory
+ connection = context.createConnection(USER1, "password");
+ statement = context.createStatement(connection);
+ statement.execute("use " + DB1);
+ statement.execute("EXPORT TABLE " + TBL1 + " TO '" + exportDir + "'");
+ statement.close();
+ connection.close();
+
+ // Negative test, user2 doesn't have access to the directory loading from
+ connection = context.createConnection(USER2, "password");
+ statement = context.createStatement(connection);
+ statement.execute("use " + DB1);
+ context.assertAuthzException(statement, "IMPORT TABLE " + TBL2 + " FROM '" + exportDir + "'");
+ statement.close();
+ connection.close();
+
+ // Positive test, user1 have access to the target directory
+ connection = context.createConnection(USER1, "password");
+ statement = context.createStatement(connection);
+ statement.execute("use " + DB1);
+ statement.execute("IMPORT TABLE " + TBL2 + " FROM '" + exportDir + "'");
+ statement.close();
+ connection.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMetadataObjectRetrieval.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMetadataObjectRetrieval.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMetadataObjectRetrieval.java
new file mode 100644
index 0000000..a16db9b
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMetadataObjectRetrieval.java
@@ -0,0 +1,453 @@
+/*
+ * 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.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.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestMetadataObjectRetrieval extends
+AbstractTestWithStaticLocalFS {
+ private PolicyFile policyFile;
+ private File dataFile;
+
+ @Before
+ public void setup() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ 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();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /**
+ * Method called to run positive tests:
+ * describe table
+ * describe table column
+ * show columns from table
+ * show create table table
+ * show tblproperties table
+ *
+ * The table is assumed to have two colums under_col int and value string.
+ */
+ private void positiveDescribeShowTests(String user, String db, String table) throws Exception {
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + db);
+ ResultSet rs = statement.executeQuery("DESCRIBE " + table);
+ assertTrue(rs.next());
+
+ assertTrue("describe table fail", rs.getString(1).trim().equals("under_col"));
+ assertTrue("describe table fail", rs.getString(2).trim().equals("int"));
+ assertTrue(rs.next());
+ assertTrue("describe table fail", rs.getString(1).trim().equals("value"));
+ assertTrue("describe table fail", rs.getString(2).trim().equals("string"));
+
+ rs = statement.executeQuery("DESCRIBE " + table + " under_col");
+ assertTrue(rs.next());
+ assertTrue("describe table fail", rs.getString(1).trim().equals("under_col"));
+ assertTrue("describe table fail", rs.getString(2).trim().equals("int"));
+
+ rs = statement.executeQuery("DESCRIBE " + table + " value");
+ assertTrue(rs.next());
+ assertTrue("describe table fail", rs.getString(1).trim().equals("value"));
+ assertTrue("describe table fail", rs.getString(2).trim().equals("string"));
+
+ rs = statement.executeQuery("SHOW COLUMNS FROM " + table);
+ assertTrue(rs.next());
+ assertTrue("show columns from fail", rs.getString(1).trim().equals("under_col"));
+ assertTrue(rs.next());
+ assertTrue("show columns from fail", rs.getString(1).trim().equals("value"));
+
+ rs = statement.executeQuery("SHOW CREATE TABLE " + table);
+ assertTrue("SHOW CREATE TABLE fail", rs.next());
+
+ rs = statement.executeQuery("SHOW TBLPROPERTIES " + table);
+ assertTrue("SHOW TBLPROPERTIES fail", rs.next());
+
+ statement.close();
+ connection.close();
+ }
+ /**
+ * Method called to run negative tests:
+ * describe table
+ * describe table column
+ * show columns from table
+ * show create table table
+ * show tblproperties table
+ *
+ * The table is assumed to have two columns under_col int and value string.
+ */
+ private void negativeDescribeShowTests(String user, String db, String table) throws Exception {
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + db);
+ context.assertAuthzException(statement, "DESCRIBE " + table);
+ context.assertAuthzException(statement, "DESCRIBE " + table + " under_col");
+ context.assertAuthzException(statement, "DESCRIBE " + table + " value");
+ context.assertAuthzException(statement, "SHOW COLUMNS FROM " + table);
+ context.assertAuthzException(statement, "SHOW CREATE TABLE " + table);
+ context.assertAuthzException(statement, "SHOW TBLPROPERTIES " + table);
+ statement.close();
+ connection.close();
+ }
+
+
+ /**
+ * Tests to ensure a user with all on server,
+ * insert|select on table can view metadata while
+ * a user with all on a different table cannot
+ * view the metadata.
+
+ * Test both positive and negative of:
+ * describe table
+ * describe table column
+ * show columns from table
+ * show create table table
+ * show tblproperties table
+ *
+ * Positive tests are run with:
+ * all@server
+ * select@table
+ * insert@table
+ * Negative tests are run three times:
+ * none
+ * insert@different table
+ */
+ @Test
+ public void testAllOnServerSelectInsertNegativeNoneAllOnDifferentTable()
+ throws Exception {
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1 + "->table=" + TBL2)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1)
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+ positiveDescribeShowTests(ADMIN1, DB1, TBL1);
+ negativeDescribeShowTests(USER1, DB1, TBL1);
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL1)
+ .write(context.getPolicyFile());
+ positiveDescribeShowTests(USER1, DB1, TBL1);
+ policyFile.removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_TBL1);
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, INSERT_DB1_TBL1)
+ .write(context.getPolicyFile());
+ positiveDescribeShowTests(USER1, DB1, TBL1);
+ }
+
+ /**
+ * Tests to ensure that a user is able to view metadata
+ * with all on db
+ *
+ * Test positive:
+ * describe table
+ * describe table column
+ * show columns from table
+ * show create table table
+ * show tblproperties table
+ *
+ * Positive tests are run twice:
+ * all@server
+ * all@db
+ */
+ @Test
+ public void testAllOnServerAndAllOnDb() throws Exception {
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1)
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+ positiveDescribeShowTests(ADMIN1, DB1, TBL1);
+ positiveDescribeShowTests(USER1, DB1, TBL1);
+ }
+
+ /**
+ * Test to ensure that all on view do not result in
+ * metadata privileges on the underlying table
+ *
+ * Test both positive and negative of:
+ * describe table
+ * describe table column
+ * show columns from table
+ * show create table table
+ * show tblproperties table
+ *
+ * Positive tests are run with all@server
+ * Negative tests are run three times:
+ * none
+ * all@view
+ */
+ @Test
+ public void testAllOnServerNegativeAllOnView() throws Exception {
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1 + "->table=" + VIEW1)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1)
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+ Connection connection = context.createConnection(ADMIN1, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.execute("DROP VIEW IF EXISTS " + VIEW1);
+ statement.execute("CREATE VIEW " + VIEW1 + " (value) AS SELECT value from " + TBL1 + " LIMIT 10");
+ positiveDescribeShowTests(ADMIN1, DB1, TBL1);
+ statement.close();
+ connection.close();
+ negativeDescribeShowTests(USER1, DB1, TBL1);
+ }
+
+ /**
+ * Tests to ensure that a user is able to view metadata
+ * with all on table
+ *
+ * Test positive:
+ * describe table
+ * describe table column
+ * show columns from table
+ * show create table table
+ * show tblproperties table
+ *
+ * Positive tests are run twice:
+ * all@server
+ * all@table
+ */
+ @Test
+ public void testAllOnServerAndAllOnTable() throws Exception {
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1 + "->table=" + TBL1)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1)
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+ positiveDescribeShowTests(ADMIN1, DB1, TBL1);
+ positiveDescribeShowTests(USER1, DB1, TBL1);
+ }
+
+
+ /**
+ * Tests that admin and all@db can describe database
+ * and describe database extended. Also tests that a user
+ * with no privileges on a db cannot describe database.
+ */
+ @Test
+ public void testDescribeDatabasesWithAllOnServerAndAllOnDb()
+ throws Exception {
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=" + DB1)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1)
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1, DB2);
+ createDb(ADMIN1, DB1, DB2);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+
+ Connection connection = context.createConnection(ADMIN1, "password");
+ Statement statement = context.createStatement(connection);
+ assertTrue(statement.executeQuery("DESCRIBE DATABASE " + DB1).next());
+ assertTrue(statement.executeQuery("DESCRIBE DATABASE EXTENDED " + DB1).next());
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection(USER1, "password");
+ statement = context.createStatement(connection);
+ assertTrue(statement.executeQuery("DESCRIBE DATABASE " + DB1).next());
+ assertTrue(statement.executeQuery("DESCRIBE DATABASE EXTENDED " + DB1).next());
+ context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB2);
+ context.assertAuthzException(statement, "DESCRIBE DATABASE EXTENDED " + DB2);
+ policyFile.addPermissionsToRole(GROUP1_ROLE, INSERT_DB2_TBL1)
+ .write(context.getPolicyFile());
+ context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB2);
+ context.assertAuthzException(statement, "DESCRIBE DATABASE EXTENDED " + DB2);
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Tests that a user without db level privileges cannot describe default
+ */
+ @Test
+ public void testDescribeDefaultDatabase() throws Exception {
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, "server=server1->db=default->table=" + TBL1 + "->action=select",
+ "server=server1->db=" + DB1 + "->table=" + TBL1 + "->action=select")
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1)
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1, DB2);
+ createDb(ADMIN1, DB1, DB2);
+ Connection connection = context.createConnection(ADMIN1, "password");
+ Statement statement = context.createStatement(connection);
+ assertTrue(statement.executeQuery("DESCRIBE DATABASE default").next());
+ statement.execute("USE " + DB1);
+ assertTrue(statement.executeQuery("DESCRIBE DATABASE default").next());
+ assertTrue(statement.executeQuery("DESCRIBE DATABASE " + DB1).next());
+ assertTrue(statement.executeQuery("DESCRIBE DATABASE " + DB2).next());
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection(USER1, "password");
+ statement = context.createStatement(connection);
+ context.assertAuthzException(statement, "DESCRIBE DATABASE default");
+ context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB1);
+ statement.execute("USE " + DB1);
+ context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB1);
+ context.assertAuthzException(statement, "DESCRIBE DATABASE " + DB2);
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Tests that users without privileges cannot execute show indexes
+ * and that users with all on table can execute show indexes
+ */
+ @Test
+ public void testShowIndexes1() throws Exception {
+ // grant privilege to non-existent table to allow use db1
+ policyFile.addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_NONTABLE)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1)
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+ Connection connection = context.createConnection(ADMIN1, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.execute("DROP INDEX IF EXISTS " + INDEX1 + " ON " + TBL1);
+ statement
+ .execute("CREATE INDEX "
+ + INDEX1
+ + " ON TABLE "
+ + TBL1
+ + "(value) AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' WITH DEFERRED REBUILD");
+ statement.execute("DROP VIEW IF EXISTS " + VIEW1);
+ statement.execute("CREATE VIEW " + VIEW1 + " (value) AS SELECT value from " + TBL1 + " LIMIT 10");
+ statement.close();
+ connection.close();
+ connection = context.createConnection(USER1, "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ context.assertAuthzException(statement, "SHOW INDEX ON " + TBL1);
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_VIEW1)
+ .write(context.getPolicyFile());
+ context.assertAuthzException(statement, "SHOW INDEX ON " + TBL1);
+ policyFile.removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_VIEW1)
+ .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL1)
+ .write(context.getPolicyFile());
+ verifyIndex(statement, TBL1, INDEX1);
+ policyFile.removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_TBL1)
+ .addPermissionsToRole(GROUP1_ROLE, INSERT_DB1_TBL1)
+ .write(context.getPolicyFile());
+ verifyIndex(statement, TBL1, INDEX1);
+ statement.close();
+ connection.close();
+ }
+
+ private void verifyIndex(Statement statement, String table, String index) throws Exception {
+ ResultSet rs = statement.executeQuery("SHOW INDEX ON " + table);
+ assertTrue(rs.next());
+ assertEquals(index, rs.getString(1).trim());
+ assertEquals(table, rs.getString(2).trim());
+ assertEquals("value", rs.getString(3).trim());
+ assertEquals("db_1__tb_1_index_1__", rs.getString(4).trim());
+ assertEquals("compact", rs.getString(5).trim());
+ }
+
+ /**
+ * Tests that users without privileges cannot execute show partitions
+ * and that users with select on table can execute show partitions
+ */
+ @Test
+ public void testShowPartitions1() throws Exception {
+ // grant privilege to non-existent table to allow use db1
+ policyFile.addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_NONTABLE)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1)
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ Connection connection = context.createConnection(ADMIN1, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.execute("DROP TABLE IF EXISTS " + TBL1);
+ statement.execute("create table " + TBL1
+ + " (under_col int, value string) PARTITIONED BY (dt INT)");
+ statement.execute("load data local inpath '" + dataFile.getPath()
+ + "' into table " + TBL1 + " PARTITION (dt=3)");
+ statement.execute("DROP VIEW IF EXISTS " + VIEW1);
+ statement.execute("CREATE VIEW " + VIEW1 + " (value) AS SELECT value from " + TBL1 + " LIMIT 10");
+ statement.close();
+ connection.close();
+ connection = context.createConnection(USER1, "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ context.assertAuthzException(statement, "SHOW PARTITIONS " + TBL1);
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_VIEW1)
+ .write(context.getPolicyFile());
+ context.assertAuthzException(statement, "SHOW PARTITIONS " + TBL1);
+ policyFile
+ .removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_VIEW1)
+ .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL1)
+ .write(context.getPolicyFile());
+ verifyParition(statement, TBL1);
+ policyFile.removePermissionsFromRole(GROUP1_ROLE, SELECT_DB1_TBL1)
+ .addPermissionsToRole(GROUP1_ROLE, INSERT_DB1_TBL1)
+ .write(context.getPolicyFile());
+ verifyParition(statement, TBL1);
+ statement.close();
+ connection.close();
+ }
+
+ private void verifyParition(Statement statement, String table) throws Exception {
+ ResultSet rs = statement.executeQuery("SHOW PARTITIONS " + TBL1);
+ assertTrue(rs.next());
+ assertEquals("dt=3", rs.getString(1).trim());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMetadataPermissions.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMetadataPermissions.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMetadataPermissions.java
new file mode 100644
index 0000000..cddd1d7
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMetadataPermissions.java
@@ -0,0 +1,158 @@
+/*
+ * 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.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.Assert;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class TestMetadataPermissions extends AbstractTestWithStaticLocalFS {
+ private Context context;
+ private PolicyFile policyFile;
+
+ @Before
+ public void setup() throws Exception {
+ context = createContext();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+
+/*
+ String testPolicies[] = {
+ "[groups]",
+ "admin_group = admin_role",
+ "user_group1 = db1_all,db2_all",
+ "user_group2 = db1_all",
+ "[roles]",
+ "db1_all = server=server1->db=db1",
+ "db2_all = server=server1->db=db2",
+ "admin_role = server=server1",
+ "[users]",
+ "user1 = user_group1",
+ "user2 = user_group2",
+ "admin = admin_group"
+ };
+ context.makeNewPolicy(testPolicies);
+*/
+ policyFile
+ .addRolesToGroup("user_group1", "db1_all", "db2_all")
+ .addRolesToGroup("user_group2", "db1_all")
+ .addPermissionsToRole("db1_all", "server=server1->db=db1")
+ .addPermissionsToRole("db2_all", "server=server1->db=db2")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .write(context.getPolicyFile());
+
+ Connection adminCon = context.createConnection(ADMIN1, "foo");
+ Statement adminStmt = context.createStatement(adminCon);
+ for (String dbName : new String[] { "db1", "db2" }) {
+ adminStmt.execute("USE default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.execute("USE " + dbName);
+ for (String tabName : new String[] { "tab1", "tab2" }) {
+ adminStmt.execute("CREATE TABLE " + tabName + " (id int)");
+ }
+ }
+ context.close();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /**
+ * Ensure that a user with no privileges on a database cannot
+ * query that databases metadata.
+ */
+ @Test
+ public void testDescPrivilegesNegative() throws Exception {
+ String dbName = "db2";
+ Connection connection = context.createConnection("user2", "password");
+ Statement statement = context.createStatement(connection);
+ context.assertAuthzException(statement, "USE " + dbName);
+// TODO when DESCRIBE db.table is supported tests should be uncommented
+// for (String tabName : new String[] { "tab1", "tab2" }) {
+// context.assertAuthzException(statement, "DESCRIBE " + dbName + "." + tabName);
+// context.assertAuthzException(statement, "DESCRIBE EXTENDED " + dbName + "." + tabName);
+// }
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Ensure that a user cannot describe databases to which the user
+ * has no privilege.
+ */
+ @Test
+ public void testDescDbPrivilegesNegative() throws Exception {
+ String dbName = "db2";
+ Connection connection = context.createConnection("user2", "password");
+ Statement statement = context.createStatement(connection);
+ context.assertAuthzException(statement, "DESCRIBE DATABASE " + dbName);
+ context.assertAuthzException(statement, "DESCRIBE DATABASE EXTENDED " + dbName);
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Ensure that a user with privileges on a database can describe
+ * the database.
+ */
+ @Test
+ public void testDescDbPrivilegesPositive() throws Exception {
+ Connection connection = context.createConnection("user1", "password");
+ Statement statement = context.createStatement(connection);
+ for (String dbName : new String[] { "db1", "db2" }) {
+ statement.execute("USE " + dbName);
+ Assert.assertTrue(statement.executeQuery("DESCRIBE DATABASE " + dbName).next());
+ Assert.assertTrue(statement.executeQuery("DESCRIBE DATABASE EXTENDED " + dbName).next());
+ }
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Ensure that a user with privileges on a table can describe the table.
+ */
+ @Test
+ public void testDescPrivilegesPositive() throws Exception {
+ Connection connection = context.createConnection("user1", "password");
+ Statement statement = context.createStatement(connection);
+ for (String dbName : new String[] { "db1", "db2" }) {
+ statement.execute("USE " + dbName);
+ Assert.assertTrue(statement.executeQuery("DESCRIBE DATABASE " + dbName).next());
+ for (String tabName : new String[] { "tab1", "tab2" }) {
+ Assert.assertTrue(statement.executeQuery("DESCRIBE " + tabName).next());
+ Assert.assertTrue(statement.executeQuery("DESCRIBE EXTENDED " + tabName).next());
+
+ }
+ }
+ statement.close();
+ connection.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMovingToProduction.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMovingToProduction.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMovingToProduction.java
new file mode 100644
index 0000000..ae3105c
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestMovingToProduction.java
@@ -0,0 +1,231 @@
+/*
+ * 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.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 junit.framework.Assert;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestMovingToProduction extends AbstractTestWithStaticLocalFS {
+ private Context context;
+ private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ private PolicyFile policyFile;
+
+
+ @Before
+ public void setUp() throws Exception {
+ context = createContext();
+ 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();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /**
+ * Steps:
+ * 1. admin create DB_1, admin create GROUP_1, GROUP_2
+ * 2. admin grant all to GROUP_1 on DB_1
+ * 3. user in GROUP_1 create table tb_1 and load data into
+ * 4. admin create table production.tb_1.
+ * 5. admin grant all to GROUP_1 on production.tb_1.
+ * positive test cases:
+ * a)verify user in GROUP_1 can load data from DB_1.tb_1 to production.tb_1
+ * b)verify user in GROUP_1 has proper privilege on production.tb_1
+ * (read and insert)
+ * negative test cases:
+ * c)verify user in GROUP_2 cannot load data from DB_1.tb_1
+ * to production.tb_1
+ * d)verify user in GROUP_1 cannot drop production.tb_1
+ */
+ @Test
+ public void testMovingTable1() throws Exception {
+ policyFile
+ .addRolesToGroup("group1", "all_db1", "load_data", "select_proddb_tbl1", "insert_proddb_tbl1")
+ .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataDir.getPath())
+ .addPermissionsToRole("all_db1", "server=server1->db=db_1")
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group2")
+ .write(context.getPolicyFile());
+
+ String dbName1 = "db_1";
+ String dbName2 = "proddb";
+ String tableName1 = "tb_1";
+
+ Connection connection = context.createConnection(ADMIN1, "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS " + dbName2 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ statement.execute("CREATE DATABASE " + dbName2);
+ statement.execute("DROP TABLE IF EXISTS " + dbName2 + "." + tableName1);
+ statement.execute("create table " + dbName2 + "." + tableName1
+ + " (under_col int comment 'the under column', value string)");
+ statement.close();
+ connection.close();
+
+ // a
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName1);
+ statement.execute("DROP TABLE IF EXISTS " + tableName1);
+ statement.execute("create table " + tableName1
+ + " (under_col int comment 'the under column', value string)");
+ statement.execute("LOAD DATA INPATH 'file://" + dataDir.getPath()
+ + "' INTO TABLE " + tableName1);
+
+ policyFile
+ .addPermissionsToRole("insert_proddb_tbl1", "server=server1->db=proddb->table=tb_1->action=insert")
+ .write(context.getPolicyFile());
+ statement.execute("USE " + dbName2);
+ statement.execute("INSERT OVERWRITE TABLE "
+ + tableName1 + " SELECT * FROM " + dbName1
+ + "." + tableName1);
+
+ // b
+ policyFile
+ .addPermissionsToRole("select_proddb_tbl1", "server=server1->db=proddb->table=tb_1->action=select")
+ .write(context.getPolicyFile());
+ ResultSet resultSet = statement.executeQuery("SELECT * FROM " + tableName1 + " LIMIT 10");
+ int count = 0;
+ while(resultSet.next()) {
+ count++;
+ }
+ assertEquals(10, count);
+ statement.execute("DESCRIBE " + tableName1);
+
+ // c
+ connection = context.createConnection("user2", "foo");
+ statement = context.createStatement(connection);
+ context.assertAuthzException(statement, "USE " + dbName2);
+ context.assertAuthzException(statement, "INSERT OVERWRITE TABLE "
+ + dbName2 + "." + tableName1 + " SELECT * FROM " + dbName1
+ + "." + tableName1);
+ context.assertAuthzException(statement, "SELECT * FROM " + dbName2 + "." + tableName1 + " LIMIT 10");
+ statement.close();
+ connection.close();
+
+ // d
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName2);
+ context.assertAuthzException(statement, "DROP TABLE " + tableName1);
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * repeat above tests, only difference is don't do 'USE <database>'
+ * in this test. Instead, access table objects across database by
+ * database.table
+ * @throws Exception
+ */
+ @Test
+ public void testMovingTable2() throws Exception {
+ policyFile
+ .addRolesToGroup("group1", "all_db1", "load_data", "select_proddb_tbl1", "insert_proddb_tbl1")
+ .addPermissionsToRole("all_db1", "server=server1->db=db_1")
+ .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataDir.getPath())
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group2")
+ .write(context.getPolicyFile());
+
+ String dbName1 = "db_1";
+ String dbName2 = "proddb";
+ String tableName1 = "tb_1";
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS " + dbName2 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ statement.execute("CREATE DATABASE " + dbName2);
+ statement.execute("DROP TABLE IF EXISTS " + dbName2 + "." + tableName1);
+ statement.execute("create table " + dbName2 + "." + tableName1
+ + " (under_col int comment 'the under column', value string)");
+ statement.close();
+ connection.close();
+
+ // a
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ 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 INPATH 'file://" + dataDir.getPath()
+ + "' INTO TABLE " + dbName1 + "." + tableName1);
+
+ policyFile
+ .addPermissionsToRole("insert_proddb_tbl1", "server=server1->db=proddb->table=tb_1->action=insert")
+ .write(context.getPolicyFile());
+ statement.execute("INSERT OVERWRITE TABLE "
+ + dbName2 + "." + tableName1 + " SELECT * FROM " + dbName1
+ + "." + tableName1);
+
+ // b
+ policyFile
+ .addPermissionsToRole("select_proddb_tbl1", "server=server1->db=proddb->table=tb_1->action=select")
+ .write(context.getPolicyFile());
+ assertTrue("user1 should be able to select data from "
+ + dbName2 + "." + dbName2 + "." + tableName1, statement.execute("SELECT * FROM "
+ + dbName2 + "." + tableName1 + " LIMIT 10"));
+ assertTrue("user1 should be able to describe table " + dbName2 + "." + tableName1,
+ statement.execute("DESCRIBE " + dbName2 + "." + tableName1));
+
+ // c
+ connection = context.createConnection("user2", "foo");
+ statement = context.createStatement(connection);
+
+ context.assertAuthzException(statement, "INSERT OVERWRITE TABLE "
+ + dbName2 + "." + tableName1 + " SELECT * FROM " + dbName1
+ + "." + tableName1);
+
+ context.assertAuthzException(statement, "SELECT * FROM "
+ + dbName2 + "." + tableName1 + " LIMIT 10");
+ statement.close();
+ connection.close();
+
+ // d
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + dbName2);
+ context.assertAuthzException(statement, "DROP TABLE " + tableName1);
+ statement.close();
+ connection.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java
new file mode 100644
index 0000000..17f4de1
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java
@@ -0,0 +1,486 @@
+/*
+ * 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.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.provider.file.SimplePolicyEngine;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
+import com.google.common.io.Files;
+import com.google.common.io.Resources;
+
+/**
+ * Test privileges per database policy files
+ */
+public class TestPerDBConfiguration extends AbstractTestWithStaticLocalFS {
+ private static final String MULTI_TYPE_DATA_FILE_NAME = "emp.dat";
+ private static final String DB2_POLICY_FILE = "db2-policy-file.ini";
+
+ private Context context;
+ private File dataFile;
+ private PolicyFile policyFile;
+
+ @Before
+ public void setup() throws Exception {
+ context = createContext();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+
+ File dataDir = context.getDataDir();
+ //copy data file to test dir
+ 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();
+
+ }
+
+ @After
+ public void teardown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ @Test
+ public void testPerDB() throws Exception {
+ PolicyFile db2PolicyFile = new PolicyFile();
+ File db2PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB2_POLICY_FILE);
+ db2PolicyFile
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
+ .write(db2PolicyFileHandle);
+
+ policyFile
+ .addRolesToGroup("user_group1", "select_tbl1")
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .addDatabase("db2", db2PolicyFileHandle.getPath())
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection(ADMIN1, "hive");
+ Statement statement = context.createStatement(connection);
+
+ 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("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl1");
+ 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.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db1");
+ // test user1 can execute query on tbl1
+ verifyCount(statement, "SELECT COUNT(*) FROM tbl1");
+
+ // user1 cannot query db2.tbl2
+ context.assertAuthzException(statement, "USE db2");
+ context.assertAuthzException(statement, "SELECT COUNT(*) FROM db2.tbl2");
+ statement.close();
+ connection.close();
+
+ // test per-db file for db2
+
+ connection = context.createConnection("user2", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db2");
+ // test user2 can execute query on tbl2
+ verifyCount(statement, "SELECT COUNT(*) FROM tbl2");
+
+ // user2 cannot query db1.tbl1
+ context.assertAuthzException(statement, "SELECT COUNT(*) FROM db1.tbl1");
+ context.assertAuthzException(statement, "USE db1");
+
+ statement.close();
+ connection.close();
+
+ //test cleanup
+ connection = context.createConnection(ADMIN1, "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE db1 CASCADE");
+ statement.execute("DROP DATABASE db2 CASCADE");
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Multiple DB files with some containing badly formatted rules
+ * The privileges should work for good files
+ * No access for bad formatted ones
+ * @throws Exception
+ */
+ @Test
+ public void testMultiPerDBwithErrors() throws Exception {
+ String DB3_POLICY_FILE = "db3-policy-file.ini";
+ String DB4_POLICY_FILE = "db4-policy-file.ini";
+
+ File db2PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB2_POLICY_FILE);
+ File db3PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB3_POLICY_FILE);
+ File db4PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB4_POLICY_FILE);
+
+ PolicyFile db2PolicyFile = new PolicyFile();
+ PolicyFile db3PolicyFile = new PolicyFile();
+ PolicyFile db4PolicyFile = new PolicyFile();
+ db2PolicyFile
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
+ .write(db2PolicyFileHandle);
+ db3PolicyFile
+ .addRolesToGroup("user_group3", "select_tbl3_BAD")
+ .addPermissionsToRole("select_tbl3_BAD", "server=server1->db=db3------>table->action=select")
+ .write(db3PolicyFileHandle);
+ db4PolicyFile
+ .addRolesToGroup("user_group4", "select_tbl4")
+ .addPermissionsToRole("select_tbl4", "server=server1->db=db4->table=tbl4->action=select")
+ .write(db4PolicyFileHandle);
+ policyFile
+ .addRolesToGroup("user_group1", "select_tbl1")
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .addGroupsToUser("user3", "user_group3")
+ .addGroupsToUser("user4", "user_group4")
+ .addDatabase("db2", db2PolicyFileHandle.getPath())
+ .addDatabase("db3", db3PolicyFileHandle.getPath())
+ .addDatabase("db4", db4PolicyFileHandle.getPath())
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection(ADMIN1, "hive");
+ Statement statement = context.createStatement(connection);
+
+ 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("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl1");
+
+ 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.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
+
+ statement.execute("DROP DATABASE IF EXISTS db3 CASCADE");
+ statement.execute("CREATE DATABASE db3");
+ statement.execute("USE db3");
+ statement.execute("CREATE TABLE tbl3(B INT, A STRING) " +
+ " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl3");
+
+ statement.execute("DROP DATABASE IF EXISTS db4 CASCADE");
+ statement.execute("CREATE DATABASE db4");
+ statement.execute("USE db4");
+ statement.execute("CREATE TABLE tbl4(B INT, A STRING) " +
+ " row format delimited fields terminated by '|' stored as textfile");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl4");
+
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db1");
+ // test user1 can execute query on tbl1
+ verifyCount(statement, "SELECT COUNT(*) FROM tbl1");
+ connection.close();
+
+ connection = context.createConnection("user2", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db2");
+ // test user1 can execute query on tbl1
+ verifyCount(statement, "SELECT COUNT(*) FROM tbl2");
+ connection.close();
+
+ // verify no access to db3 due to badly formatted rule in db3 policy file
+ connection = context.createConnection("user3", "password");
+ statement = context.createStatement(connection);
+ context.assertAuthzException(statement, "USE db3");
+ // test user1 can execute query on tbl1
+ context.assertAuthzException(statement, "SELECT COUNT(*) FROM db3.tbl3");
+ connection.close();
+
+ connection = context.createConnection("user4", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db4");
+ // test user1 can execute query on tbl1
+ verifyCount(statement, "SELECT COUNT(*) FROM tbl4");
+ connection.close();
+
+ //test cleanup
+ connection = context.createConnection(ADMIN1, "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE db1 CASCADE");
+ statement.execute("DROP DATABASE db2 CASCADE");
+ statement.execute("DROP DATABASE db3 CASCADE");
+ statement.execute("DROP DATABASE db4 CASCADE");
+ statement.close();
+ connection.close();
+ }
+
+ @Test
+ public void testPerDBPolicyFileWithURI() throws Exception {
+ File db2PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB2_POLICY_FILE);
+
+ policyFile
+ .addRolesToGroup("user_group1", "select_tbl1")
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .addDatabase("db2", db2PolicyFileHandle.getPath())
+ .write(context.getPolicyFile());
+
+ PolicyFile db2PolicyFile = new PolicyFile();
+ db2PolicyFile
+ .addRolesToGroup("user_group2", "select_tbl2", "data_read", "insert_tbl2")
+ .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
+ .addPermissionsToRole("insert_tbl2", "server=server1->db=db2->table=tbl2->action=insert")
+ .addPermissionsToRole("data_read", "server=server1->URI=file://" + dataFile)
+ .write(db2PolicyFileHandle);
+ // ugly hack: needs to go away once this becomes a config property. Note that this property
+ // will not be set with external HS and this test will fail. Hope is this fix will go away
+ // by then.
+ System.setProperty(SimplePolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "true");
+ // setup db objects needed by the test
+ Connection connection = context.createConnection(ADMIN1, "hive");
+ Statement statement = context.createStatement(connection);
+
+ 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("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl1");
+ 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.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db1");
+ // test user1 can execute query on tbl1
+ verifyCount(statement, "SELECT COUNT(*) FROM tbl1");
+
+ // user1 cannot query db2.tbl2
+ context.assertAuthzException(statement, "USE db2");
+ context.assertAuthzException(statement, "SELECT COUNT(*) FROM db2.tbl2");
+ statement.close();
+ connection.close();
+
+ // test per-db file for db2
+ connection = context.createConnection("user2", "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE db2");
+ // test user2 can execute query on tbl2
+ verifyCount(statement, "SELECT COUNT(*) FROM tbl2");
+
+ // verify user2 can execute LOAD
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
+
+ // user2 cannot query db1.tbl1
+ context.assertAuthzException(statement, "SELECT COUNT(*) FROM db1.tbl1");
+ context.assertAuthzException(statement, "USE db1");
+
+ statement.close();
+ connection.close();
+
+ //test cleanup
+ connection = context.createConnection(ADMIN1, "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE db1 CASCADE");
+ statement.execute("DROP DATABASE db2 CASCADE");
+ statement.close();
+ connection.close();
+ 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 {
+ policyFile
+ .addRolesToGroup("user_group1", "select_tbl1")
+ .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
+ .addGroupsToUser("user_1", "user_group1")
+ .addGroupsToUser("user_2", "user_group2")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection(ADMIN1, "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 {
+ File db2PolicyFileHandle = new File(context.getPolicyFile().getParent(), DB2_POLICY_FILE);
+ File defaultPolicyFileHandle = new File(context.getPolicyFile().getParent(), "default.ini");
+
+ policyFile
+ .addRolesToGroup("user_group1", "select_tbl1")
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
+ .addGroupsToUser("user_1", "user_group1")
+ .addGroupsToUser("user_2", "user_group2")
+ .addGroupsToUser("user_3", "user_group3")
+ .addDatabase("db2", db2PolicyFileHandle.getPath())
+ .addDatabase("default", defaultPolicyFileHandle.getPath())
+ .write(context.getPolicyFile());
+
+ PolicyFile db2PolicyFile = new PolicyFile();
+ db2PolicyFile
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
+ .write(db2PolicyFileHandle);
+
+ PolicyFile defaultPolicyFile = new PolicyFile();
+ defaultPolicyFile
+ .addRolesToGroup("user_group2", "select_def")
+ .addPermissionsToRole("select_def", "server=server1->db=default->table=dtab->action=select")
+ .write(defaultPolicyFileHandle);
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection(ADMIN1, "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;
+ int countRows = 0;
+
+ while (resultSet.next()) {
+ count = resultSet.getInt(1);
+ countRows++;
+ }
+ assertTrue("Incorrect row count", countRows == 1);
+ assertTrue("Incorrect result", count == 12);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDatabasePolicyFile.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDatabasePolicyFile.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDatabasePolicyFile.java
new file mode 100644
index 0000000..a89988a
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDatabasePolicyFile.java
@@ -0,0 +1,134 @@
+/*
+ * 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.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.Statement;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestPerDatabasePolicyFile extends AbstractTestWithStaticLocalFS {
+ private static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ private static final String ADMIN1 = "admin1";
+ private Context context;
+ private PolicyFile policyFile;
+ private File globalPolicyFile;
+ private File dataDir;
+ private File dataFile;
+
+ @Before
+ public void setup() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ context = createContext();
+ globalPolicyFile = context.getPolicyFile();
+ dataDir = context.getDataDir();
+ assertTrue("Could not delete " + globalPolicyFile, context.deletePolicyFile());
+ 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();
+ }
+
+ @After
+ public void teardown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ private void createSampleDbTable(Statement statement, String db, String table)
+ throws Exception {
+ statement.execute("DROP DATABASE IF EXISTS " + db + " CASCADE");
+ statement.execute("CREATE DATABASE " + db);
+ statement.execute("USE " + db);
+ statement.execute("CREATE TABLE " + table + "(a STRING)");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE " + table);
+
+ }
+
+ /**
+ * Ensure that db specific file cannot grant to other db
+ */
+ @Test
+ public void testDbSpecificFileGrantsToOtherDb() throws Exception {
+ doTestDbSpecificFileGrants("server=server1->db=db1");
+ }
+ /**
+ * Ensure that db specific file cannot grant to all db
+ */
+ @Test
+ public void testDbSpecificFileGrantsToAllDb() throws Exception {
+ doTestDbSpecificFileGrants("server=server1");
+ }
+ /**
+ * Ensure that db specific file cannot grant to all servers
+ */
+ @Test
+ public void testDbSpecificFileGrantsToAllServers() throws Exception {
+ doTestDbSpecificFileGrants("server=*");
+ }
+ /**
+ * Ensure that db specific file cannot grant to all
+ */
+ @Test
+ public void testDbSpecificFileGrantsToAll() throws Exception {
+ doTestDbSpecificFileGrants("*");
+ }
+
+ public void doTestDbSpecificFileGrants(String grant) throws Exception {
+
+ policyFile.write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection(ADMIN1, "password");
+ Statement statement = context.createStatement(connection);
+ createSampleDbTable(statement, "db1", "tbl1");
+ createSampleDbTable(statement, "db2", "tbl1");
+ statement.close();
+ connection.close();
+
+ File specificPolicyFileFile = new File(context.getBaseDir(), "db2-policy.ini");
+
+ PolicyFile specificPolicyFile = new PolicyFile()
+ .addPermissionsToRole("db1_role", grant)
+ .addRolesToGroup("group1", "db1_role")
+ .addGroupsToUser("user1", "group1");
+ specificPolicyFile.write(specificPolicyFileFile);
+
+ policyFile.addDatabase("db2", specificPolicyFileFile.getPath());
+ policyFile.write(context.getPolicyFile());
+
+
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+ // test user can query table
+ context.assertAuthzException(statement, "USE db1");
+ context.assertAuthzException(statement, "SELECT COUNT(a) FROM db1.tbl1");
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegeAtTransform.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegeAtTransform.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegeAtTransform.java
new file mode 100644
index 0000000..0b71c87
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPrivilegeAtTransform.java
@@ -0,0 +1,118 @@
+/*
+ * 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.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.Statement;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestPrivilegeAtTransform extends AbstractTestWithStaticLocalFS {
+ private Context context;
+ private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ private File dataDir;
+ private File dataFile;
+ private PolicyFile policyFile;
+
+ @Before
+ public void setup() throws Exception {
+ context = createContext();
+ dataDir = context.getDataDir();
+ 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();
+ policyFile = PolicyFile.createAdminOnServer1("admin1");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /**
+ * Steps:
+ * 1. admin create database, create table, load data into it
+ * 2. all@server can issue transforms command
+ * 3. all@database cannot issue transform command
+ * 4. insert@table select@table cannot issue transform command
+ * 5. select@view cannot issue transform command
+ * 6. transform@server can issue the transform command
+ */
+ @Test
+ public void testTransform1() throws Exception {
+ policyFile
+ .addGroupsToUser("user1", "group1")
+ .addPermissionsToRole("all_db1", "server=server1->db=db_1")
+ .addRolesToGroup("group1", "all_db1");
+ policyFile.write(context.getPolicyFile());
+
+ // verify by SQL
+ // 1, 2
+ String dbName1 = "db_1";
+ String tableName1 = "tb_1";
+ String query = "select TRANSFORM(a.under_col, a.value) USING 'cat' AS (tunder_col, tvalue) FROM " + dbName1 + "." + tableName1 + " a";
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
+ statement.execute("CREATE DATABASE " + dbName1);
+ statement.execute("DROP TABLE IF EXISTS " + dbName1 + "." + tableName1);
+ statement.execute("create table " + dbName1 + "." + tableName1
+ + " (under_col int, value string)");
+ statement.execute("load data local inpath '" + dataFile.getPath()
+ + "' into table " + dbName1 + "." + tableName1);
+ assertTrue(query, statement.execute(query));
+
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+
+ // 3
+ context.assertAuthzExecHookException(statement, query);
+
+ // 4
+ policyFile
+ .addPermissionsToRole("select_tb1", "server=server1->db=db_1->table=tb_1->action=select")
+ .addPermissionsToRole("insert_tb1", "server=server1->db=db_1->table=tb_1->action=insert")
+ .addRolesToGroup("group1", "select_tb1", "insert_tb1");
+ policyFile.write(context.getPolicyFile());
+ context.assertAuthzExecHookException(statement, query);
+
+ // 5
+ policyFile
+ .addPermissionsToRole("all_server1", "server=server1")
+ .addRolesToGroup("group1", "all_server1");
+ policyFile.write(context.getPolicyFile());
+ assertTrue(query, statement.execute(query));
+ statement.close();
+ connection.close();
+ }
+}
[3/9] SENTRY-16: Move sentry-tests to sentry-tests-hive package
(Gregory Chanan via Shreepadma Venugopalan)
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtDatabaseScope.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtDatabaseScope.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtDatabaseScope.java
deleted file mode 100644
index 69bfddc..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtDatabaseScope.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertFalse;
-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.SQLException;
-import java.sql.Statement;
-import java.util.HashMap;
-import java.util.Map;
-
-import junit.framework.Assert;
-
-import org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-/* Tests privileges at table scope within a single database.
- */
-
-public class TestPrivilegesAtDatabaseScope extends AbstractTestWithHiveServer {
-
- private Context context;
- private File dataFile;
- private PolicyFile policyFile;
-
- Map <String, String >testProperties;
- private static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
-
- @Before
- public void setup() throws Exception {
- testProperties = new HashMap<String, String>();
- policyFile = PolicyFile.createAdminOnServer1("admin1");
- }
-
- @After
- public void teardown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /* Admin creates database DB_1
- * Admin grants ALL to USER_GROUP of which user1 is a member.
- */
- @Test
- public void testAllPrivilege() throws Exception {
- context = createContext(testProperties);
-
- //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();
-
- policyFile
- .addRolesToGroup("user_group1", "all_db1", "load_data")
- .addRolesToGroup("user_group2", "all_db2")
- .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
- .addPermissionsToRole("all_db2", "server=server1->db=DB_2")
- .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataFile.getPath())
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("CREATE DATABASE DB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- // test user can create table
- statement.execute("CREATE TABLE DB_1.TAB_1(A STRING)");
- // test user can execute load
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE DB_1.TAB_1");
- statement.execute("CREATE TABLE DB_1.TAB_2(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE DB_1.TAB_2");
-
- // test user can switch db
- statement.execute("USE DB_1");
- //test user can create view
- statement.execute("CREATE VIEW VIEW_1(A) AS SELECT A FROM TAB_1");
-
- // test user can insert
- statement.execute("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
- // test user can query table
- ResultSet resultSet = statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
- int count = 0;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 1000);
-
- // test user can execute alter table rename
- statement.execute("ALTER TABLE TAB_1 RENAME TO TAB_3");
-
- // test user can execute create as select
- statement.execute("CREATE TABLE TAB_4 AS SELECT * FROM TAB_2");
-
- // test user can execute alter table rename cols
- statement.execute("ALTER TABLE TAB_3 ADD COLUMNS (B INT)");
-
- // test user can drop table
- statement.execute("DROP TABLE TAB_3");
-
- //negative test case: user can't drop another user's database
- try {
- statement.execute("DROP DATABASE DB_2 CASCADE");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- //negative test case: user can't switch into another user's database
- try {
- statement.execute("USE DB_2");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- //negative test case: user can't drop own database
- try {
- statement.execute("DROP DATABASE DB_1 CASCADE");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- statement.close();
- connection.close();
-
- //test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.execute("DROP DATABASE DB_2 CASCADE");
- statement.close();
- connection.close();
- context.close();
- }
-
- /* Admin creates database DB_1, creates table TAB_1, loads data into it
- * Admin grants ALL to USER_GROUP of which user1 is a member.
- */
- @Test
- public void testAllPrivilegeOnObjectOwnedByAdmin() throws Exception {
- context = createContext(testProperties);
-
- //copy data file to test dir
- File dataDir = context.getDataDir();
- File dataFile = new File(dataDir, SINGLE_TYPE_DATA_FILE_NAME);
- File externalTblDir = new File(dataDir, "exttab");
- FileOutputStream to = new FileOutputStream(dataFile);
- Resources.copy(Resources.getResource(SINGLE_TYPE_DATA_FILE_NAME), to);
- to.close();
-
- policyFile
- .addRolesToGroup("user_group1", "all_db1", "load_data", "exttab")
- .addRolesToGroup("user_group2", "all_db2")
- .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
- .addPermissionsToRole("all_db2", "server=server1->db=DB_2")
- .addPermissionsToRole("exttab", "server=server1->uri=file://" + dataDir.getPath())
- .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataFile.getPath())
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("CREATE DATABASE DB_2");
- statement.execute("USE DB_1");
- statement.execute("CREATE TABLE TAB_1(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_1");
- statement.execute("CREATE TABLE PART_TAB_1(A STRING) partitioned by (B INT) STORED AS TEXTFILE");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE PART_TAB_1 PARTITION(B=1)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE PART_TAB_1 PARTITION(B=2)");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- // test user can switch db
- statement.execute("USE DB_1");
- // test user can execute load
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_1");
- statement.execute("CREATE TABLE TAB_2(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE TAB_2");
-
- //test user can create view
- statement.execute("CREATE VIEW VIEW_1(A) AS SELECT A FROM TAB_1");
-
- // test user can insert
- statement.execute("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
- // test user can query table
- ResultSet resultSet = statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
- int count = 0;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 1500);
-
- // test user can execute alter table rename
- statement.execute("ALTER TABLE TAB_1 RENAME TO TAB_3");
-
- // test user can drop table
- statement.execute("DROP TABLE TAB_3");
-
- //negative test case: user can't drop db
- try {
- statement.execute("DROP DATABASE DB_1 CASCADE");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- //negative test case: user can't create external tables
- assertTrue("Unable to create directory for external table test" , externalTblDir.mkdir());
- statement.execute("CREATE EXTERNAL TABLE EXT_TAB_1(A STRING) STORED AS TEXTFILE LOCATION 'file:"+
- externalTblDir.getAbsolutePath() + "'");
-
- //negative test case: user can't execute alter table set location
- try {
- statement.execute("ALTER TABLE TAB_2 SET LOCATION 'hdfs://nn1.example.com/hive/warehouse'");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- statement.close();
- connection.close();
-
- connection = context.createConnection("user2", "password");
- statement = context.createStatement(connection);
- try {
- statement.execute("CREATE EXTERNAL TABLE EXT_TAB_1(A STRING) STORED AS TEXTFILE LOCATION 'file:"+
- externalTblDir.getAbsolutePath() + "'");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- statement.close();
- connection.close();
-
- //test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.execute("DROP DATABASE DB_2 CASCADE");
- statement.close();
- connection.close();
- context.close();
- }
-
- /**
- * Test privileges for 'use <db>'
- * Admin should be able to run use <db> with server level access
- * User with db level access should be able to run use <db>
- * User with table level access should be able to run use <db>
- * User with no access to that db objects, should NOT be able run use <db>
- * @throws Exception
- */
- @Test
- public void testUseDbPrivilege() throws Exception {
- context = createContext(testProperties);
-
- policyFile
- .addRolesToGroup("user_group1", "all_db1")
- .addRolesToGroup("user_group2", "select_db2")
- .addRolesToGroup("user_group3", "all_db3")
- .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
- .addPermissionsToRole("select_db2", "server=server1->db=DB_2->table=tab_2->action=select")
- .addPermissionsToRole("all_db3", "server=server1->db=DB_3")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .addGroupsToUser("user3", "user_group3")
- .write(context.getPolicyFile());
-
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("use DB_1");
- statement.execute("CREATE TABLE TAB_1(A STRING)");
- statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
- statement.execute("CREATE DATABASE DB_2");
- statement.execute("use DB_1");
- statement.execute("CREATE TABLE TAB_2(A STRING)");
- context.close();
-
- // user1 should be able to connect db_1
- connection = context.createConnection("user1", "hive");
- statement = context.createStatement(connection);
- statement.execute("use DB_1");
- context.close();
-
- // user2 should not be able to connect db_1
- connection = context.createConnection("user2", "hive");
- statement = context.createStatement(connection);
- try {
- statement.execute("use DB_1");
- assertFalse("user2 shouldn't be able switch to db_1", true);
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- statement.execute("use DB_2");
- context.close();
-
- // user3 who is not listed in policy file should not be able to connect db_2
- connection = context.createConnection("user3", "hive");
- statement = context.createStatement(connection);
- try {
- statement.execute("use DB_2");
- assertFalse("user3 shouldn't be able switch to db_2", true);
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- context.close();
- }
-
- /**
- * Test access to default DB with out of box authz config
- * All users should be able to switch to default, including the users that don't have any
- * privilege on default db objects via policy file
- * @throws Exception
- */
- @Test
- public void testDefaultDbPrivilege() throws Exception {
- context = createContext(testProperties);
-
- policyFile
- .addRolesToGroup("user_group1", "all_db1")
- .addRolesToGroup("user_group2", "select_db2")
- .addRolesToGroup("user_group3", "all_default")
- .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
- .addPermissionsToRole("select_db2", "server=server1->db=DB_2->table=tab_2->action=select")
- .addPermissionsToRole("all_default", "server=server1->db=default")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .addGroupsToUser("user3", "user_group3")
- .write(context.getPolicyFile());
-
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- statement.execute("use default");
- context.close();
-
- connection = context.createConnection("user1", "hive");
- statement = context.createStatement(connection);
- statement.execute("use default");
- context.close();
-
- connection = context.createConnection("user2", "hive");
- statement = context.createStatement(connection);
- statement.execute("use default");
- context.close();
-
- connection = context.createConnection("user3", "hive");
- statement = context.createStatement(connection);
- statement.execute("use default");
- context.close();
- }
-
- /**
- * Test access to default DB with explicit privilege requirement
- * Admin should be able to run use default with server level access
- * User with db level access should be able to run use default
- * User with table level access should be able to run use default
- * User with no access to default db objects, should NOT be able run use default
- * @throws Exception
- */
- @Test
- public void testDefaultDbRestrictivePrivilege() throws Exception {
- testProperties.put(AuthzConfVars.AUTHZ_RESTRICT_DEFAULT_DB.getVar(), "true");
- context = createContext(testProperties);
-
- policyFile
- .addRolesToGroup("user_group1", "all_default")
- .addRolesToGroup("user_group2", "select_default")
- .addRolesToGroup("user_group3", "all_db1")
- .addPermissionsToRole("all_default", "server=server1->db=default")
- .addPermissionsToRole("select_default", "server=server1->db=default->table=tab_2->action=select")
- .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2")
- .addGroupsToUser("user3", "user_group3")
- .write(context.getPolicyFile());
-
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- statement.execute("use default");
- context.close();
-
- connection = context.createConnection("user1", "hive");
- statement = context.createStatement(connection);
- statement.execute("use default");
- context.close();
-
- connection = context.createConnection("user2", "hive");
- statement = context.createStatement(connection);
- statement.execute("use default");
- context.close();
-
- connection = context.createConnection("user3", "hive");
- statement = context.createStatement(connection);
- try {
- // user3 doesn't have any implicit permission for default
- statement.execute("use default");
- assertFalse("user3 shouldn't be able switch to default", true);
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- context.close();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtFunctionScope.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtFunctionScope.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtFunctionScope.java
deleted file mode 100644
index 25746c1..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtFunctionScope.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
-printf_test_3 * 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;
-
-import static org.junit.Assert.assertFalse;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-public class TestPrivilegesAtFunctionScope extends AbstractTestWithStaticLocalFS {
- private Context context;
- private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- private File dataDir;
- private File dataFile;
- private PolicyFile policyFile;
-
- @Before
- public void setup() throws Exception {
- context = createContext();
- dataDir = context.getDataDir();
- 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();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
-
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /**
- * admin should be able to create/drop temp functions
- * user with db level access should be able to create/drop temp functions
- * user with table level access should be able to create/drop temp functions
- * user with no privilege should NOT be able to create/drop temp functions
- */
- @Test
- public void testFuncPrivileges1() throws Exception {
- String dbName1 = "db_1";
- String tableName1 = "tb_1";
-
- policyFile
- .addRolesToGroup("group1", "db1_all", "UDF_JAR")
- .addRolesToGroup("group2", "db1_tab1", "UDF_JAR")
- .addRolesToGroup("group3", "db1_tab1")
- .addPermissionsToRole("db1_all", "server=server1->db=" + dbName1)
- .addPermissionsToRole("db1_tab1", "server=server1->db=" + dbName1 + "->table=" + tableName1)
- .addPermissionsToRole("UDF_JAR", "server=server1->uri=file://${user.home}/.m2")
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group2")
- .addGroupsToUser("user3", "group3")
- .write(context.getPolicyFile());
-
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- 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 INPATH '" + dataFile.getPath() + "' INTO TABLE "
- + dbName1 + "." + tableName1);
- statement.execute("DROP TEMPORARY FUNCTION IF EXISTS printf_test");
- statement.execute("DROP TEMPORARY FUNCTION IF EXISTS printf_test_2");
- context.close();
-
- // user1 should be able create/drop temp functions
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName1);
- statement.execute(
- "CREATE TEMPORARY FUNCTION printf_test AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
- statement.execute("DROP TEMPORARY FUNCTION printf_test");
- context.close();
-
- // user2 has select privilege on one of the tables in db2, should be able create/drop temp functions
- connection = context.createConnection("user2", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName1);
- statement.execute(
- "CREATE TEMPORARY FUNCTION printf_test_2 AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
- statement.execute("DROP TEMPORARY FUNCTION printf_test");
- context.close();
-
- // user3 shouldn't be able to create/drop temp functions since it doesn't have permission for jar
- connection = context.createConnection("user3", "foo");
- statement = context.createStatement(connection);
- try {
- statement.execute("USE " + dbName1);
- statement.execute(
- "CREATE TEMPORARY FUNCTION printf_test_bad AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
- assertFalse("CREATE TEMPORARY FUNCTION should fail for user3", true);
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- context.close();
-
- // user4 (not part of any group ) shouldn't be able to create/drop temp functions
- connection = context.createConnection("user4", "foo");
- statement = context.createStatement(connection);
- try {
- statement.execute("USE default");
- statement.execute(
- "CREATE TEMPORARY FUNCTION printf_test_bad AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
- assertFalse("CREATE TEMPORARY FUNCTION should fail for user4", true);
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- context.close();
-
- }
-
- @Test
- public void testUdfWhiteList () throws Exception {
- String dbName1 = "db1";
- String tableName1 = "tab1";
-
- policyFile
- .addRolesToGroup("group1", "db1_all", "UDF_JAR")
- .addRolesToGroup("group2", "db1_tab1", "UDF_JAR")
- .addRolesToGroup("group3", "db1_tab1")
- .addPermissionsToRole("db1_all", "server=server1->db=" + dbName1)
- .addPermissionsToRole("db1_tab1", "server=server1->db=" + dbName1 + "->table=" + tableName1)
- .addPermissionsToRole("UDF_JAR", "server=server1->uri=file://${user.home}/.m2")
- .addGroupsToUser("user1", "group1")
- .write(context.getPolicyFile());
-
- Connection connection = context.createConnection("admin1", "password");
- Statement statement = connection.createStatement();
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- statement.execute("USE " + dbName1);
- statement.execute("create table " + tableName1
- + " (under_col int comment 'the under column', value string)");
- statement.execute("LOAD DATA INPATH '" + dataFile.getPath() + "' INTO TABLE "
- + dbName1 + "." + tableName1);
- statement.execute("SELECT rand(), concat(value, '_foo') FROM " + tableName1);
-
- context.assertAuthzException(statement,
- "SELECT reflect('java.net.URLDecoder', 'decode', 'http://www.apache.org', 'utf-8'), value FROM " + tableName1);
- context.assertAuthzException(statement,
- "SELECT java_method('java.net.URLDecoder', 'decode', 'http://www.apache.org', 'utf-8'), value FROM " + tableName1);
- statement.close();
- connection.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtTableScope.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtTableScope.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtTableScope.java
deleted file mode 100644
index ed4509e..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestPrivilegesAtTableScope.java
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.*;
-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.SQLException;
-import java.sql.Statement;
-
-import junit.framework.Assert;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-/* Tests privileges at table scope within a single database.
- */
-
-public class TestPrivilegesAtTableScope extends AbstractTestWithStaticLocalFS {
-
- private Context context;
- private PolicyFile policyFile;
-
- private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- private final String MULTI_TYPE_DATA_FILE_NAME = "emp.dat";
-
- @Before
- public void setup() throws Exception {
- context = createContext();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- }
-
- @After
- public void teardown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /*
- * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, loads data into
- * TAB_1, TAB_2 Admin grants SELECT on TAB_1, TAB_2, INSERT on TAB_1 to
- * USER_GROUP of which user1 is a member.
- */
- @Test
- public void testInsertAndSelect() throws Exception {
- File dataDir = context.getDataDir();
- // copy data file to test dir
- 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();
-
- policyFile
- .addRolesToGroup("user_group", "select_tab1", "insert_tab1", "select_tab2")
- .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
- .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=TAB_1->action=insert")
- .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("USE DB_1");
- statement.execute("CREATE TABLE TAB_1(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_1");
- statement.execute("CREATE TABLE TAB_2(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
- // test user can insert
- statement.execute("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
- // test user can query table
- ResultSet resultSet = statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
- int count = 0;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
-
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 1000);
-
- // negative test: test user can't drop
- try {
- statement.execute("DROP TABLE TAB_1");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- statement.close();
- connection.close();
-
- // connect as admin and drop tab_1
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
- statement.execute("DROP TABLE TAB_1");
- statement.close();
- connection.close();
-
- // negative test: connect as user1 and try to recreate tab_1
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
- try {
- statement.execute("CREATE TABLE TAB_1(A STRING)");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- statement.close();
- connection.close();
-
- // test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.close();
- connection.close();
-
- }
-
- /*
- * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, loads data into
- * TAB_1, TAB_2. Admin grants INSERT on TAB_1, SELECT on TAB_2 to USER_GROUP
- * of which user1 is a member.
- */
- @Test
- public void testInsert() throws Exception {
- File dataDir = context.getDataDir();
- // copy data file to test dir
- 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();
-
- policyFile
- .addRolesToGroup("user_group", "insert_tab1", "select_tab2")
- .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=TAB_1->action=insert")
- .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("USE DB_1");
- statement.execute("CREATE TABLE TAB_1(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_1");
- statement.execute("CREATE VIEW VIEW_1(A) AS SELECT A FROM TAB_1");
- statement.execute("CREATE TABLE TAB_2(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
- // test user can execute insert on table
- statement.executeQuery("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
-
- // negative test: user can't query table
- try {
- statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- // negative test: test user can't query view
- try {
- statement.executeQuery("SELECT COUNT(A) FROM VIEW_1");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- // negative test case: show tables shouldn't list VIEW_1
- ResultSet resultSet = statement.executeQuery("SHOW TABLES");
- while (resultSet.next()) {
- String tableName = resultSet.getString(1);
- assertNotNull("table name is null in result set", tableName);
- assertFalse("Found VIEW_1 in the result set",
- "VIEW_1".equalsIgnoreCase(tableName));
- }
-
- // negative test: test user can't create a new view
- try {
- statement.executeQuery("CREATE VIEW VIEW_2(A) AS SELECT A FROM TAB_1");
- Assert.fail("Expected SQL Exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- statement.close();
- connection.close();
-
- // test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.close();
- connection.close();
- }
-
- /*
- * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, loads data into
- * TAB_1, TAB_2. Admin grants SELECT on TAB_1, TAB_2 to USER_GROUP of which
- * user1 is a member.
- */
- @Test
- public void testSelect() 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();
-
- policyFile
- .addRolesToGroup("user_group", "select_tab1", "select_tab2")
- .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
- .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=TAB_1->action=insert")
- .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
-
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("USE DB_1");
- statement.execute("CREATE TABLE TAB_1(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_1");
- statement.execute("CREATE VIEW VIEW_1(A) AS SELECT A FROM TAB_1");
- statement.execute("CREATE TABLE TAB_2(A STRING)");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
- // test user can execute query on table
- ResultSet resultSet = statement.executeQuery("SELECT COUNT(A) FROM TAB_1");
- int count = 0;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 500);
-
- // negative test: test insert into table
- try {
- statement.executeQuery("INSERT INTO TABLE TAB_1 SELECT A FROM TAB_2");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- // negative test: test user can't query view
- try {
- statement.executeQuery("SELECT COUNT(A) FROM VIEW_1");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- // negative test: test user can't create a new view
- try {
- statement.executeQuery("CREATE VIEW VIEW_2(A) AS SELECT A FROM TAB_1");
- Assert.fail("Expected SQL Exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- statement.close();
- connection.close();
-
- // test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.close();
- connection.close();
- }
-
- /*
- * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, VIEW_1 on TAB_1
- * loads data into TAB_1, TAB_2. Admin grants SELECT on TAB_1,TAB_2 to
- * USER_GROUP of which user1 is a member.
- */
- @Test
- public void testTableViewJoin() throws Exception {
- // copy data file to test dir
- File dataDir = context.getDataDir();
- 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();
-
- policyFile
- .addRolesToGroup("user_group", "select_tab1", "select_tab2")
- .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
- .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
-
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("USE DB_1");
- statement.execute("CREATE TABLE TAB_1(B INT, A STRING) "
- + " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_1");
- statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM TAB_1");
- statement.execute("CREATE TABLE TAB_2(B INT, A STRING) "
- + " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
- // test user can execute query TAB_1 JOIN TAB_2
- ResultSet resultSet = statement
- .executeQuery("SELECT COUNT(*) FROM TAB_1 T1 JOIN TAB_2 T2 ON (T1.B = T2.B)");
- int count = 0;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 12);
-
- // negative test: test user can't execute query VIEW_1 JOIN TAB_2
- try {
- statement
- .executeQuery("SELECT COUNT(*) FROM VIEW_1 V1 JOIN TAB_2 T2 ON (V1.B = T2.B)");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- statement.close();
- connection.close();
-
- // test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.close();
- connection.close();
- }
-
- /*
- * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, VIEW_1 on TAB_1
- * loads data into TAB_1, TAB_2. Admin grants SELECT on TAB_2 to USER_GROUP of
- * which user1 is a member.
- */
- @Test
- public void testTableViewJoin2() throws Exception {
-
- 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();
-
- policyFile
- .addRolesToGroup("user_group", "select_tab2")
- .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
- .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
-
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("USE DB_1");
- statement.execute("CREATE TABLE TAB_1(B INT, A STRING) "
- + " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_1");
- statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM TAB_1");
- statement.execute("CREATE TABLE TAB_2(B INT, A STRING) "
- + " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
- // test user can execute query on TAB_2
- ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) FROM TAB_2");
- int count = 0;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 12);
-
- // negative test: test user can't execute query VIEW_1 JOIN TAB_2
- try {
- statement
- .executeQuery("SELECT COUNT(*) FROM VIEW_1 JOIN TAB_2 ON (VIEW_1.B = TAB_2.B)");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- // negative test: test user can't execute query TAB_1 JOIN TAB_2
- try {
- statement
- .executeQuery("SELECT COUNT(*) FROM TAB_1 JOIN TAB_2 ON (TAB_1.B = TAB_2.B)");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- statement.close();
- connection.close();
-
- // test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.close();
- connection.close();
- }
-
- /*
- * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, VIEW_1 on TAB_1
- * loads data into TAB_1, TAB_2. Admin grants SELECT on TAB_2, VIEW_1 to
- * USER_GROUP of which user1 is a member.
- */
- @Test
- public void testTableViewJoin3() throws Exception {
- 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();
-
- policyFile
- .addRolesToGroup("user_group", "select_tab2", "select_view1")
- .addPermissionsToRole("select_view1", "server=server1->db=DB_1->table=VIEW_1->action=select")
- .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=TAB_2->action=select")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
-
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("USE DB_1");
- statement.execute("CREATE TABLE TAB_1(B INT, A STRING) "
- + " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_1");
- statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM TAB_1");
- statement.execute("CREATE TABLE TAB_2(B INT, A STRING) "
- + " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
- // test user can execute query on TAB_2
- ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) FROM TAB_2");
- int count = 0;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 12);
-
- // test user can execute query VIEW_1 JOIN TAB_2
- resultSet = statement
- .executeQuery("SELECT COUNT(*) FROM VIEW_1 V1 JOIN TAB_2 T2 ON (V1.B = T2.B)");
- count = 0;
- countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 12);
-
- // test user can execute query on VIEW_1
- resultSet = statement.executeQuery("SELECT COUNT(*) FROM VIEW_1");
- count = 0;
- countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 12);
-
- // negative test: test user can't execute query TAB_1 JOIN TAB_2
- try {
- statement
- .executeQuery("SELECT COUNT(*) FROM TAB_1 T1 JOIN TAB_2 T2 ON (T1.B = T2.B)");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- statement.close();
- connection.close();
-
- // test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.close();
- connection.close();
- }
-
- /*
- * Admin creates database DB_1, table TAB_1, TAB_2 in DB_1, VIEW_1 on TAB_1
- * loads data into TAB_1, TAB_2. Admin grants SELECT on TAB_1, VIEW_1 to
- * USER_GROUP of which user1 is a member.
- */
- @Test
- public void testTableViewJoin4() throws Exception {
- 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();
-
- policyFile
- .addRolesToGroup("user_group", "select_tab1", "select_view1")
- .addPermissionsToRole("select_view1", "server=server1->db=DB_1->table=VIEW_1->action=select")
- .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=TAB_1->action=select")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- // setup db objects needed by the test
- Connection connection = context.createConnection("admin1", "hive");
- Statement statement = context.createStatement(connection);
-
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("CREATE DATABASE DB_1");
- statement.execute("USE DB_1");
- statement.execute("CREATE TABLE TAB_1(B INT, A STRING) "
- + " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_1");
- statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM TAB_1");
- statement.execute("CREATE TABLE TAB_2(B INT, A STRING) "
- + " row format delimited fields terminated by '|' stored as textfile");
- statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE TAB_2");
- statement.close();
- connection.close();
-
- // test execution
- connection = context.createConnection("user1", "password");
- statement = context.createStatement(connection);
- statement.execute("USE DB_1");
-
- // test user can execute query VIEW_1 JOIN TAB_1
- ResultSet resultSet = statement
- .executeQuery("SELECT COUNT(*) FROM VIEW_1 JOIN TAB_1 ON (VIEW_1.B = TAB_1.B)");
- int count = 0;
- int countRows = 0;
-
- while (resultSet.next()) {
- count = resultSet.getInt(1);
- countRows++;
- }
- assertTrue("Incorrect row count", countRows == 1);
- assertTrue("Incorrect result", count == 12);
-
- // negative test: test user can't execute query TAB_1 JOIN TAB_2
- try {
- statement
- .executeQuery("SELECT COUNT(*) FROM TAB_1 JOIN TAB_2 ON (TAB_1.B = TAB_2.B)");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
-
- statement.close();
- connection.close();
-
- // test cleanup
- connection = context.createConnection("admin1", "hive");
- statement = context.createStatement(connection);
- statement.execute("DROP DATABASE DB_1 CASCADE");
- statement.close();
- connection.close();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestRuntimeMetadataRetrieval.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestRuntimeMetadataRetrieval.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestRuntimeMetadataRetrieval.java
deleted file mode 100644
index b9f71a9..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestRuntimeMetadataRetrieval.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * 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;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-/**
- * Metadata tests for show tables and show databases. * Unlike rest of the
- * access privilege validation which is handled in semantic hooks, these
- * statements are validaed via a runtime fetch hook
- */
-public class TestRuntimeMetadataRetrieval
- extends
- AbstractTestWithStaticLocalFS {
- private Context context;
- private PolicyFile policyFile;
- private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- private File dataDir;
- private File dataFile;
-
- @Before
- public void setup() throws Exception {
- context = createContext();
- dataDir = context.getDataDir();
- 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();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /**
- * Steps: 1. admin create db_1 and db_1.tb_1
- * 2. admin should see all tables
- * 3. user1 should only see the tables it has any level of privilege
- */
- @Test
- public void testShowTables1() throws Exception {
- String dbName1 = "db_1";
- // tables visible to user1 (not access to tb_4
- String tableNames[] = {"tb_1", "tb_2", "tb_3", "tb_4"};
- List<String> tableNamesValidation = new ArrayList<String>();
-
- policyFile
- .addRolesToGroup("user_group", "tab1_priv,tab2_priv,tab3_priv")
- .addPermissionsToRole("tab1_priv", "server=server1->db=" + dbName1 + "->table="
- + tableNames[0] + "->action=select")
- .addPermissionsToRole("tab2_priv", "server=server1->db=" + dbName1 + "->table="
- + tableNames[1] + "->action=insert")
- .addPermissionsToRole("tab3_priv", "server=server1->db=" + dbName1 + "->table="
- + tableNames[2] + "->action=select")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- String user1TableNames[] = {"tb_1", "tb_2", "tb_3"};
-
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- statement.execute("USE " + dbName1);
- createTabs(statement, dbName1, tableNames);
- // Admin should see all tables
- ResultSet rs = statement.executeQuery("SHOW TABLES");
- tableNamesValidation.addAll(Arrays.asList(tableNames));
-
- validateTables(rs, dbName1, tableNamesValidation);
- statement.close();
- context.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName1);
- // User1 should see tables with any level of access
- rs = statement.executeQuery("SHOW TABLES");
- tableNamesValidation.addAll(Arrays.asList(user1TableNames));
- validateTables(rs, dbName1, tableNamesValidation);
- statement.close();
- context.close();
- }
-
- /**
- * Steps: 1. admin create db_1 and tables
- * 2. admin should see all tables
- * 3. user1 should only see the all tables with db level privilege
- */
- @Test
- public void testShowTables2() throws Exception {
- String dbName1 = "db_1";
- // tables visible to user1 (not access to tb_4
- String tableNames[] = {"tb_1", "tb_2", "tb_3", "tb_4"};
- List<String> tableNamesValidation = new ArrayList<String>();
-
- policyFile
- .addRolesToGroup("user_group", "db_priv")
- .addPermissionsToRole("db_priv", "server=server1->db=" + dbName1)
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- String user1TableNames[] = {"tb_1", "tb_2", "tb_3", "tb_4"};
-
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- statement.execute("USE " + dbName1);
- createTabs(statement, dbName1, tableNames);
- // Admin should see all tables
- ResultSet rs = statement.executeQuery("SHOW TABLES");
- tableNamesValidation.addAll(Arrays.asList(tableNames));
- validateTables(rs, dbName1, tableNamesValidation);
- statement.close();
- context.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName1);
- // User1 should see tables with any level of access
- rs = statement.executeQuery("SHOW TABLES");
- tableNamesValidation.addAll(Arrays.asList(user1TableNames));
- validateTables(rs, dbName1, tableNamesValidation);
- statement.close();
- context.close();
- }
-
- /**
- * Steps: 1. admin create db_1 and db_1.tb_1
- * 2. admin should see all tables
- * 3. user1 should only see the tables he/she has any level of privilege
- */
- @Test
- public void testShowTables3() throws Exception {
- String dbName1 = "db_1";
- // tables visible to user1 (not access to tb_4
- String tableNames[] = {"tb_1", "tb_2", "tb_3", "newtab_3"};
- List<String> tableNamesValidation = new ArrayList<String>();
-
- policyFile
- .addRolesToGroup("user_group", "tab_priv")
- .addPermissionsToRole("tab_priv", "server=server1->db=" + dbName1 + "->table="
- + tableNames[3] + "->action=insert")
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- String adminTableNames[] = {"tb_3", "newtab_3", "tb_2", "tb_1"};
- String user1TableNames[] = {"newtab_3"};
-
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- statement.execute("USE " + dbName1);
- createTabs(statement, dbName1, tableNames);
- // Admin should see all tables
- ResultSet rs = statement.executeQuery("SHOW TABLES");
- tableNamesValidation.addAll(Arrays.asList(adminTableNames));
- validateTables(rs, dbName1, tableNamesValidation);
- statement.close();
- context.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName1);
- // User1 should see tables with any level of access
- rs = statement.executeQuery("SHOW TABLES");
- tableNamesValidation.addAll(Arrays.asList(user1TableNames));
- validateTables(rs, dbName1, tableNamesValidation);
- statement.close();
- context.close();
- }
-
- /**
- * Steps: 1. admin create db_1 and db_1.tb_1
- * 2. admin should see all tables
- * 3. user1 should only see the tables with db level privilege
- */
- @Test
- public void testShowTables4() throws Exception {
- String dbName1 = "db_1";
- String tableNames[] = {"tb_1", "tb_2", "tb_3", "newtab_3"};
- List<String> tableNamesValidation = new ArrayList<String>();
-
- policyFile
- .addRolesToGroup("user_group", "tab_priv")
- .addPermissionsToRole("tab_priv", "server=server1->db=" + dbName1)
- .addGroupsToUser("user1", "user_group")
- .write(context.getPolicyFile());
-
- String adminTableNames[] = {"tb_3", "newtab_3", "tb_1", "tb_2"};
- String user1TableNames[] = {"tb_3", "newtab_3", "tb_1", "tb_2"};
-
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS " + dbName1 + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName1);
- statement.execute("USE " + dbName1);
- createTabs(statement, dbName1, tableNames);
- // Admin should be able to see all tables
- ResultSet rs = statement.executeQuery("SHOW TABLES");
- tableNamesValidation.addAll(Arrays.asList(adminTableNames));
- validateTables(rs, dbName1, tableNamesValidation);
- statement.close();
- context.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- statement.execute("USE " + dbName1);
- // User1 should see tables with any level of access
- rs = statement.executeQuery("SHOW TABLES");
- tableNamesValidation.addAll(Arrays.asList(user1TableNames));
- validateTables(rs, dbName1, tableNamesValidation);
- statement.close();
- context.close();
- }
-
- /**
- * Steps: 1. admin creates tables in default db
- * 2. user1 shouldn't see any table when he/she doesn't have any privilege on default
- */
- @Test
- public void testShowTables5() throws Exception {
- String tableNames[] = {"tb_1", "tb_2", "tb_3", "tb_4"};
-
- policyFile
- .addRolesToGroup("user_group", "db_priv")
- .write(context.getPolicyFile());
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- createTabs(statement, "default", tableNames);
- context.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- // User1 should see tables with any level of access
- ResultSet rs = statement.executeQuery("SHOW TABLES");
- // user1 doesn't have access to any tables in default db
- Assert.assertFalse(rs.next());
- statement.close();
- context.close();
- }
-
- /**
- * Steps: 1. admin create few dbs
- * 2. admin can do show databases
- * 3. users with db level permissions should only those dbs on 'show database'
- */
- @Test
- public void testShowDatabases1() throws Exception {
- List<String> dbNamesValidation = new ArrayList<String>();
- String[] dbNames = {"db_1", "db_2", "db_3"};
- String[] user1DbNames = {"db_1"};
-
- policyFile
- .addRolesToGroup("group1", "db1_all")
- .addPermissionsToRole("db1_all", "server=server1->db=db_1")
- .addGroupsToUser("user1", "group1")
- .write(context.getPolicyFile());
-
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- // create all dbs
- createDBs(statement, dbNames);
- ResultSet rs = statement.executeQuery("SHOW DATABASES");
- dbNamesValidation.addAll(Arrays.asList(dbNames));
- dbNamesValidation.add("default");
- // admin should see all dbs
- validateDBs(rs, dbNamesValidation);
- rs.close();
- context.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- rs = statement.executeQuery("SHOW DATABASES");
- dbNamesValidation.addAll(Arrays.asList(user1DbNames));
- dbNamesValidation.add("default");
- // user should see only dbs with access
- validateDBs(rs, dbNamesValidation);
- rs.close();
- context.close();
- }
-
- /**
- * Steps: 1. admin create few dbs
- * 2. admin can do show databases
- * 3. users with table level permissions should should only those parent dbs on 'show
- * database'
- */
- @Test
- public void testShowDatabases2() throws Exception {
- String[] dbNames = {"db_1", "db_2", "db_3"};
- List<String> dbNamesValidation = new ArrayList<String>();
- String[] user1DbNames = {"db_1", "db_2"};
-
- policyFile
- .addRolesToGroup("group1", "db1_tab,db2_tab")
- .addPermissionsToRole("db1_tab", "server=server1->db=db_1->table=tb_1->action=select")
- .addPermissionsToRole("db2_tab", "server=server1->db=db_2->table=tb_1->action=insert")
- .addGroupsToUser("user1", "group1")
- .write(context.getPolicyFile());
-
- // verify by SQL
- // 1, 2
- Connection connection = context.createConnection("admin1", "foo");
- Statement statement = context.createStatement(connection);
- createDBs(statement, dbNames); // create all dbs
- ResultSet rs = statement.executeQuery("SHOW DATABASES");
- dbNamesValidation.addAll(Arrays.asList(dbNames));
- dbNamesValidation.add("default");
- validateDBs(rs, dbNamesValidation); // admin should see all dbs
- rs.close();
- context.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
- rs = statement.executeQuery("SHOW DATABASES");
- dbNamesValidation.addAll(Arrays.asList(user1DbNames));
- dbNamesValidation.add("default");
- // user should see only dbs with access
- validateDBs(rs, dbNamesValidation);
- rs.close();
- context.close();
- }
-
- // create given dbs
- private void createDBs(Statement statement, String dbNames[])
- throws SQLException {
- for (String dbName : dbNames) {
- statement.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- statement.execute("CREATE DATABASE " + dbName);
- }
- }
-
- // compare the table resultset with given array of table names
- private void validateDBs(ResultSet rs, List<String> dbNames)
- throws SQLException {
- while (rs.next()) {
- String dbName = rs.getString(1);
- Assert.assertTrue(dbName, dbNames.remove(dbName.toLowerCase()));
- }
- Assert.assertTrue(dbNames.toString(), dbNames.isEmpty());
- rs.close();
- }
-
- // Create the give tables
- private void createTabs(Statement statement, String dbName,
- String tableNames[]) throws SQLException {
- for (String tabName : tableNames) {
- statement.execute("DROP TABLE IF EXISTS " + dbName + "." + tabName);
- statement.execute("create table " + dbName + "." + tabName
- + " (under_col int comment 'the under column', value string)");
- }
- }
-
- // compare the table resultset with given array of table names
- private void validateTables(ResultSet rs, String dbName,
- List<String> tableNames) throws SQLException {
- while (rs.next()) {
- String tableName = rs.getString(1);
- Assert.assertTrue(tableName, tableNames.remove(tableName.toLowerCase()));
- }
- Assert.assertTrue(tableNames.toString(), tableNames.isEmpty());
- rs.close();
- }
-}
[9/9] git commit: SENTRY-16: Move sentry-tests to sentry-tests-hive
package (Gregory Chanan via Shreepadma Venugopalan)
Posted by sh...@apache.org.
SENTRY-16: Move sentry-tests to sentry-tests-hive package (Gregory Chanan 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/aef404c6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/aef404c6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/aef404c6
Branch: refs/heads/master
Commit: aef404c6091785cd1e8879e7279b9eb45678c5d5
Parents: 3c232e1
Author: Shreepadma Venugopalan <sh...@apache.org>
Authored: Fri Sep 20 16:38:07 2013 -0700
Committer: Shreepadma Venugopalan <sh...@apache.org>
Committed: Fri Sep 20 16:38:07 2013 -0700
----------------------------------------------------------------------
.../test/resources/sentry-deprecated-site.xml | 53 ++
sentry-tests/pom.xml | 312 +--------
sentry-tests/sentry-tests-hive/pom.xml | 334 +++++++++
.../e2e/hive/AbstractTestWithHiveServer.java | 85 +++
.../AbstractTestWithStaticConfiguration.java | 157 +++++
.../e2e/hive/AbstractTestWithStaticDFS.java | 69 ++
.../e2e/hive/AbstractTestWithStaticLocalFS.java | 37 +
.../apache/sentry/tests/e2e/hive/Context.java | 210 ++++++
.../e2e/hive/DummySentryOnFailureHook.java | 32 +
.../sentry/tests/e2e/hive/PolicyFileEditor.java | 78 +++
.../sentry/tests/e2e/hive/TestCrossDbOps.java | 691 +++++++++++++++++++
.../sentry/tests/e2e/hive/TestEndToEnd.java | 143 ++++
.../e2e/hive/TestExportImportPrivileges.java | 154 +++++
.../e2e/hive/TestMetadataObjectRetrieval.java | 453 ++++++++++++
.../tests/e2e/hive/TestMetadataPermissions.java | 158 +++++
.../tests/e2e/hive/TestMovingToProduction.java | 231 +++++++
.../tests/e2e/hive/TestPerDBConfiguration.java | 486 +++++++++++++
.../e2e/hive/TestPerDatabasePolicyFile.java | 134 ++++
.../e2e/hive/TestPrivilegeAtTransform.java | 118 ++++
.../e2e/hive/TestPrivilegesAtDatabaseScope.java | 464 +++++++++++++
.../e2e/hive/TestPrivilegesAtFunctionScope.java | 177 +++++
.../e2e/hive/TestPrivilegesAtTableScope.java | 678 ++++++++++++++++++
.../e2e/hive/TestRuntimeMetadataRetrieval.java | 401 +++++++++++
.../sentry/tests/e2e/hive/TestSandboxOps.java | 585 ++++++++++++++++
.../hive/TestSentryOnFailureHookLoading.java | 129 ++++
.../tests/e2e/hive/TestServerConfiguration.java | 209 ++++++
.../tests/e2e/hive/TestUriPermissions.java | 270 ++++++++
.../tests/e2e/hive/TestUserManagement.java | 333 +++++++++
.../e2e/hive/hiveserver/AbstractHiveServer.java | 88 +++
.../e2e/hive/hiveserver/EmbeddedHiveServer.java | 59 ++
.../e2e/hive/hiveserver/ExternalHiveServer.java | 124 ++++
.../tests/e2e/hive/hiveserver/HiveServer.java | 34 +
.../e2e/hive/hiveserver/HiveServerFactory.java | 212 ++++++
.../e2e/hive/hiveserver/InternalHiveServer.java | 55 ++
.../hive/hiveserver/UnmanagedHiveServer.java | 96 +++
.../src/test/resources/emp.dat | 12 +
.../src/test/resources/hive-site.xml | 45 ++
.../src/test/resources/kv1.dat | 500 ++++++++++++++
.../src/test/resources/log4j.properties | 35 +
.../src/test/resources/sentry-site.xml | 33 +
.../src/test/resources/test-authz-provider.ini | 25 +
.../tests/e2e/AbstractTestWithHiveServer.java | 85 ---
.../AbstractTestWithStaticConfiguration.java | 157 -----
.../tests/e2e/AbstractTestWithStaticDFS.java | 69 --
.../e2e/AbstractTestWithStaticLocalFS.java | 37 -
.../org/apache/sentry/tests/e2e/Context.java | 210 ------
.../tests/e2e/DummySentryOnFailureHook.java | 32 -
.../sentry/tests/e2e/PolicyFileEditor.java | 78 ---
.../apache/sentry/tests/e2e/TestCrossDbOps.java | 691 -------------------
.../apache/sentry/tests/e2e/TestEndToEnd.java | 143 ----
.../tests/e2e/TestExportImportPrivileges.java | 154 -----
.../tests/e2e/TestMetadataObjectRetrieval.java | 453 ------------
.../tests/e2e/TestMetadataPermissions.java | 158 -----
.../tests/e2e/TestMovingToProduction.java | 231 -------
.../tests/e2e/TestPerDBConfiguration.java | 486 -------------
.../tests/e2e/TestPerDatabasePolicyFile.java | 134 ----
.../tests/e2e/TestPrivilegeAtTransform.java | 118 ----
.../e2e/TestPrivilegesAtDatabaseScope.java | 464 -------------
.../e2e/TestPrivilegesAtFunctionScope.java | 177 -----
.../tests/e2e/TestPrivilegesAtTableScope.java | 678 ------------------
.../tests/e2e/TestRuntimeMetadataRetrieval.java | 401 -----------
.../apache/sentry/tests/e2e/TestSandboxOps.java | 585 ----------------
.../e2e/TestSentryOnFailureHookLoading.java | 129 ----
.../tests/e2e/TestServerConfiguration.java | 209 ------
.../sentry/tests/e2e/TestUriPermissions.java | 270 --------
.../sentry/tests/e2e/TestUserManagement.java | 333 ---------
.../e2e/hiveserver/AbstractHiveServer.java | 88 ---
.../e2e/hiveserver/EmbeddedHiveServer.java | 59 --
.../e2e/hiveserver/ExternalHiveServer.java | 124 ----
.../sentry/tests/e2e/hiveserver/HiveServer.java | 34 -
.../tests/e2e/hiveserver/HiveServerFactory.java | 212 ------
.../e2e/hiveserver/InternalHiveServer.java | 55 --
.../e2e/hiveserver/UnmanagedHiveServer.java | 96 ---
sentry-tests/src/test/resources/access-site.xml | 33 -
sentry-tests/src/test/resources/emp.dat | 12 -
sentry-tests/src/test/resources/hive-site.xml | 45 --
sentry-tests/src/test/resources/kv1.dat | 500 --------------
.../src/test/resources/log4j.properties | 35 -
sentry-tests/src/test/resources/sentry-site.xml | 33 -
.../src/test/resources/test-authz-provider.ini | 25 -
80 files changed, 8193 insertions(+), 8139 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-binding/sentry-binding-hive/src/test/resources/sentry-deprecated-site.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/resources/sentry-deprecated-site.xml b/sentry-binding/sentry-binding-hive/src/test/resources/sentry-deprecated-site.xml
new file mode 100644
index 0000000..e5c5a36
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/resources/sentry-deprecated-site.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+ 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.
+-->
+
+<configuration>
+ <property>
+ <name>hive.sentry.provider</name>
+ <value>deprecated</value>
+ </property>
+ <property>
+ <name>hive.sentry.provider.resource</name>
+ <value>deprecated</value>
+ </property>
+ <property>
+ <name>hive.sentry.server</name>
+ <value>deprecated</value>
+ </property>
+ <property>
+ <name>hive.sentry.restrict.defaultDB</name>
+ <value>deprecated</value>
+ </property>
+ <property>
+ <name>hive.sentry.testing.mode</name>
+ <value>deprecated</value>
+ </property>
+ <property>
+ <name>hive.sentry.udf.whitelist</name>
+ <value>deprecated</value>
+ </property>
+ <property>
+ <name>hive.sentry.allow.hive.impersonation</name>
+ <value>deprecated</value>
+ </property>
+ <property>
+ <name>hive.sentry.failure.hooks</name>
+ <value>deprecated</value>
+ </property>
+</configuration>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/pom.xml b/sentry-tests/pom.xml
index 5536348..1b3c58d 100644
--- a/sentry-tests/pom.xml
+++ b/sentry-tests/pom.xml
@@ -25,310 +25,10 @@ limitations under the License.
<artifactId>sentry-tests</artifactId>
<name>Sentry Tests</name>
<description>end to end tests for sentry project</description>
- <properties>
- <hadoop-dist></hadoop-dist>
- <hive-dist>${hadoop-dist}</hive-dist>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.apache.thrift</groupId>
- <artifactId>libthrift</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.derby</groupId>
- <artifactId>derby</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.thrift</groupId>
- <artifactId>libthrift</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.derby</groupId>
- <artifactId>derby</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sentry</groupId>
- <artifactId>sentry-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-service</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-shims</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-serde</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-metastore</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-pdk</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-hwi</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-jdbc</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-hbase-handler</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-exec</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-contrib</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-common</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-cli</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-builtins</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-anttasks</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-common</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-annotations</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-auth</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-hdfs</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-mapreduce-client-common</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-mapreduce-client-core</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-mapreduce-client-shuffle</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-yarn-api</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-yarn-common</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-yarn-server-common</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-yarn-server-nodemanager</artifactId>
- <version>${hadoop.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- <version>${zookeeper.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.easytesting</groupId>
- <artifactId>fest-reflect</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sentry</groupId>
- <artifactId>sentry-binding-hive</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sentry</groupId>
- <artifactId>sentry-provider-file</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-minicluster</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <systemPropertyVariables>
- <buildDirectory>${project.build.directory}</buildDirectory>
- </systemPropertyVariables>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <profiles>
- <profile>
- <id>download-hadoop</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <configuration>
- <skipTests>false</skipTests>
- </configuration>
- <executions>
- <execution>
- <id>download-hadoop</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>run</goal>
- </goals>
- <configuration>
- <target>
- <echo file="target/download.sh">
- set -e
- set -x
- /bin/pwd
- BASE_DIR=./target
- DOWNLOAD_DIR=$BASE_DIR/downloads
- download() {
- url=$1;
- tarName=$2
- finalName=$3
- rm -rf $BASE_DIR/$finalName
- wget -nv -O $DOWNLOAD_DIR/$tarName $url
- tar -zxf $DOWNLOAD_DIR/$tarName -C $BASE_DIR
- rm $DOWNLOAD_DIR/$tarName
- mv $BASE_DIR/${finalName}* $BASE_DIR/$finalName
- }
- rm -rf $DOWNLOAD_DIR
- mkdir -p $DOWNLOAD_DIR
- download "http://archive.cloudera.com/cdh4/cdh/4/hadoop-latest.tar.gz" hadoop.tar.gz hadoop
- download "http://archive.cloudera.com/cdh4/cdh/4/hive-latest.tar.gz" hive.tar.gz hive
- </echo>
- <exec executable="sh" dir="${basedir}" failonerror="true">
- <arg line="target/download.sh"/>
- </exec>
- </target>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>link-hadoop</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <configuration>
- <skipTests>false</skipTests>
- </configuration>
- <executions>
- <execution>
- <id>link-hadoop</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>run</goal>
- </goals>
- <configuration>
- <target>
- <echo file="target/link_dist.sh">
- set -e
- set -x
- /bin/pwd
- BASE_DIR=./target
- rm -f $BASE_DIR/hadoop
- ln -s $1/hadoop $BASE_DIR/.
- rm -f $BASE_DIR/hive
- ln -s $2/hive $BASE_DIR/.
- </echo>
- <exec executable="sh" dir="${basedir}" failonerror="true">
- <arg line="target/link_dist.sh ${hadoop-dist} ${hive-dist}"/>
- </exec>
- </target>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>sentry-tests-hive</module>
+ </modules>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/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
new file mode 100644
index 0000000..27b45c0
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/pom.xml
@@ -0,0 +1,334 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-tests</artifactId>
+ <version>1.3.0-incubating-SNAPSHOT</version>
+ </parent>
+ <artifactId>sentry-tests-hive</artifactId>
+ <name>Sentry Hive Tests</name>
+ <description>end to end tests for sentry-hive integration</description>
+ <properties>
+ <hadoop-dist></hadoop-dist>
+ <hive-dist>${hadoop-dist}</hive-dist>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.thrift</groupId>
+ <artifactId>libthrift</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.thrift</groupId>
+ <artifactId>libthrift</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-service</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-shims</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-serde</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-metastore</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-pdk</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-hwi</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-jdbc</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-hbase-handler</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-exec</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-contrib</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-common</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-cli</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-builtins</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-anttasks</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-common</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-annotations</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-auth</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-hdfs</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-mapreduce-client-common</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-mapreduce-client-core</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-mapreduce-client-shuffle</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-yarn-api</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-yarn-common</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-yarn-server-common</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-yarn-server-nodemanager</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>${zookeeper.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.easytesting</groupId>
+ <artifactId>fest-reflect</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-binding-hive</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-provider-file</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-minicluster</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <buildDirectory>${project.build.directory}</buildDirectory>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>download-hadoop</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <skipTests>false</skipTests>
+ </configuration>
+ <executions>
+ <execution>
+ <id>download-hadoop</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <echo file="target/download.sh">
+ set -e
+ set -x
+ /bin/pwd
+ BASE_DIR=./target
+ DOWNLOAD_DIR=$BASE_DIR/downloads
+ download() {
+ url=$1;
+ tarName=$2
+ finalName=$3
+ rm -rf $BASE_DIR/$finalName
+ wget -nv -O $DOWNLOAD_DIR/$tarName $url
+ tar -zxf $DOWNLOAD_DIR/$tarName -C $BASE_DIR
+ rm $DOWNLOAD_DIR/$tarName
+ mv $BASE_DIR/${finalName}* $BASE_DIR/$finalName
+ }
+ rm -rf $DOWNLOAD_DIR
+ mkdir -p $DOWNLOAD_DIR
+ download "http://archive.cloudera.com/cdh4/cdh/4/hadoop-latest.tar.gz" hadoop.tar.gz hadoop
+ download "http://archive.cloudera.com/cdh4/cdh/4/hive-latest.tar.gz" hive.tar.gz hive
+ </echo>
+ <exec executable="sh" dir="${basedir}" failonerror="true">
+ <arg line="target/download.sh"/>
+ </exec>
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>link-hadoop</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <skipTests>false</skipTests>
+ </configuration>
+ <executions>
+ <execution>
+ <id>link-hadoop</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <echo file="target/link_dist.sh">
+ set -e
+ set -x
+ /bin/pwd
+ BASE_DIR=./target
+ rm -f $BASE_DIR/hadoop
+ ln -s $1/hadoop $BASE_DIR/.
+ rm -f $BASE_DIR/hive
+ ln -s $2/hive $BASE_DIR/.
+ </echo>
+ <exec executable="sh" dir="${basedir}" failonerror="true">
+ <arg line="target/link_dist.sh ${hadoop-dist} ${hive-dist}"/>
+ </exec>
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithHiveServer.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithHiveServer.java
new file mode 100644
index 0000000..25c64c7
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithHiveServer.java
@@ -0,0 +1,85 @@
+/*
+ * 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.util.Map;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServer;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.After;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.Files;
+
+public abstract class AbstractTestWithHiveServer {
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(AbstractTestWithHiveServer.class);
+ protected File baseDir;
+ protected File logDir;
+ protected File confDir;
+ protected File dataDir;
+ protected File policyFile;
+ protected HiveServer hiveServer;
+ protected FileSystem fileSystem;
+
+ public Context createContext(Map<String, String> properties)
+ throws Exception {
+ fileSystem = FileSystem.get(new Configuration());
+ baseDir = Files.createTempDir();
+ LOGGER.info("BaseDir = " + baseDir);
+ logDir = assertCreateDir(new File(baseDir, "log"));
+ confDir = assertCreateDir(new File(baseDir, "etc"));
+ dataDir = assertCreateDir(new File(baseDir, "data"));
+ policyFile = new File(confDir, HiveServerFactory.AUTHZ_PROVIDER_FILENAME);
+ hiveServer = HiveServerFactory.create(properties, baseDir, confDir, logDir, policyFile, fileSystem);
+ hiveServer.start();
+ return new Context(hiveServer, getFileSystem(),
+ baseDir, confDir, dataDir, policyFile);
+ }
+
+ protected static File assertCreateDir(File dir) {
+ if(!dir.isDirectory()) {
+ Assert.assertTrue("Failed creating " + dir, dir.mkdirs());
+ }
+ return dir;
+ }
+
+ protected FileSystem getFileSystem() {
+ return fileSystem;
+ }
+
+ @After
+ public void tearDownWithHiveServer() throws Exception {
+ if(hiveServer != null) {
+ hiveServer.shutdown();
+ hiveServer = null;
+ }
+ if(baseDir != null) {
+ if(System.getProperty(HiveServerFactory.KEEP_BASEDIR) == null) {
+ FileUtils.deleteQuietly(baseDir);
+ }
+ baseDir = null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
new file mode 100644
index 0000000..e56eb92
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
@@ -0,0 +1,157 @@
+/*
+ * 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.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServer;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+import com.google.common.io.Files;
+
+public abstract class AbstractTestWithStaticConfiguration {
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(AbstractTestWithStaticConfiguration.class);
+ protected static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ protected static final String ADMIN1 = "admin1";
+ protected static final String ALL_DB1 = "server=server1->db=db_1",
+ ALL_DB2 = "server=server1->db=db_2",
+ SELECT_DB1_TBL1 = "server=server1->db=db_1->table=tb_1->action=select",
+ SELECT_DB1_TBL2 = "server=server1->db=db_1->table=tb_2->action=select",
+ SELECT_DB1_NONTABLE = "server=server1->db=db_1->table=this table does not exist->action=select",
+ INSERT_DB1_TBL1 = "server=server1->db=db_1->table=tb_1->action=insert",
+ INSERT_DB1_TBL2 = "server=server1->db=db_1->table=tb_2->action=insert",
+ SELECT_DB2_TBL2 = "server=server1->db=db_2->table=tb_2->action=select",
+ INSERT_DB2_TBL1 = "server=server1->db=db_2->table=tb_1->action=insert",
+ SELECT_DB1_VIEW1 = "server=server1->db=db_1->table=view_1->action=select",
+ USER1 = "user1",
+ USER2 = "user2",
+ GROUP1 = "group1",
+ GROUP1_ROLE = "group1_role",
+ DB1 = "db_1",
+ DB2 = "db_2",
+ DB3 = "db_3",
+ TBL1 = "tb_1",
+ TBL2 = "tb_2",
+ TBL3 = "tb_3",
+ VIEW1 = "view_1",
+ VIEW2 = "view_2",
+ VIEW3 = "view_3",
+ INDEX1 = "index_1",
+ INDEX2 = "index_2";
+
+
+ protected static File baseDir;
+ protected static File logDir;
+ protected static File confDir;
+ protected static File dataDir;
+ protected static File policyFile;
+ protected static HiveServer hiveServer;
+ protected static FileSystem fileSystem;
+ protected static Map<String, String> properties;
+ protected Context context;
+
+ public Context createContext() throws Exception {
+ return new Context(hiveServer, fileSystem,
+ baseDir, confDir, dataDir, policyFile);
+ }
+ protected void dropDb(String user, String...dbs) throws Exception {
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = connection.createStatement();
+ for(String db : dbs) {
+ statement.execute("DROP DATABASE IF EXISTS " + db + " CASCADE");
+ }
+ statement.close();
+ connection.close();
+ }
+ protected void createDb(String user, String...dbs) throws Exception {
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = connection.createStatement();
+ for(String db : dbs) {
+ statement.execute("CREATE DATABASE " + db);
+ }
+ statement.close();
+ connection.close();
+ }
+ protected void createTable(String user, String db, File dataFile, String...tables)
+ throws Exception {
+ Connection connection = context.createConnection(user, "password");
+ 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();
+ connection.close();
+ }
+
+ protected static File assertCreateDir(File dir) {
+ if(!dir.isDirectory()) {
+ Assert.assertTrue("Failed creating " + dir, dir.mkdirs());
+ }
+ return dir;
+ }
+
+ protected FileSystem getFileSystem() {
+ return fileSystem;
+ }
+ @BeforeClass
+ public static void setupTestStaticConfiguration()
+ throws Exception {
+ properties = Maps.newHashMap();
+ baseDir = Files.createTempDir();
+ LOGGER.info("BaseDir = " + baseDir);
+ logDir = assertCreateDir(new File(baseDir, "log"));
+ confDir = assertCreateDir(new File(baseDir, "etc"));
+ dataDir = assertCreateDir(new File(baseDir, "data"));
+ policyFile = new File(confDir, HiveServerFactory.AUTHZ_PROVIDER_FILENAME);
+ }
+
+ @AfterClass
+ public static void tearDownTestStaticConfiguration() throws Exception {
+ if(hiveServer != null) {
+ hiveServer.shutdown();
+ hiveServer = null;
+ }
+ if(baseDir != null) {
+ if(System.getProperty(HiveServerFactory.KEEP_BASEDIR) == null) {
+ FileUtils.deleteQuietly(baseDir);
+ }
+ baseDir = null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticDFS.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticDFS.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticDFS.java
new file mode 100644
index 0000000..f670f89
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticDFS.java
@@ -0,0 +1,69 @@
+/*
+ * 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.IOException;
+
+import junit.framework.Assert;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+public abstract class AbstractTestWithStaticDFS extends AbstractTestWithStaticConfiguration {
+
+ protected static MiniDFSCluster dfsCluster;
+ protected static Path dfsBaseDir;
+
+ @Before
+ public void setupTestWithDFS() throws IOException {
+ Assert.assertTrue(dfsBaseDir.toString(), fileSystem.delete(dfsBaseDir, true));
+ Assert.assertTrue(dfsBaseDir.toString(), fileSystem.mkdirs(dfsBaseDir));
+ }
+
+ protected static Path assertCreateDfsDir(Path dir) throws IOException {
+ if(!fileSystem.isDirectory(dir)) {
+ Assert.assertTrue("Failed creating " + dir, fileSystem.mkdirs(dir));
+ }
+ return dir;
+ }
+ @BeforeClass
+ public static void setupTestWithStaticDFS()
+ throws Exception {
+ Configuration conf = new Configuration();
+ File dfsDir = assertCreateDir(new File(baseDir, "dfs"));
+ conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
+ dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
+ fileSystem = dfsCluster.getFileSystem();
+ dfsBaseDir = assertCreateDfsDir(new Path(new Path(fileSystem.getUri()), "/base"));
+ hiveServer = HiveServerFactory.create(properties, baseDir, confDir, logDir, policyFile, fileSystem);
+ hiveServer.start();
+ }
+
+ @AfterClass
+ public static void tearDownTestWithStaticDFS() throws Exception {
+ if(dfsCluster != null) {
+ dfsCluster.shutdown();
+ dfsCluster = null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticLocalFS.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticLocalFS.java
new file mode 100644
index 0000000..3954b9a
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticLocalFS.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractTestWithStaticLocalFS extends AbstractTestWithStaticConfiguration {
+ @SuppressWarnings("unused")
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(AbstractTestWithStaticLocalFS.class);
+ @BeforeClass
+ public static void setupTestWithStaticHiveServer()
+ throws Exception {
+ fileSystem = FileSystem.get(new Configuration());
+ hiveServer = HiveServerFactory.create(properties, baseDir, confDir, logDir, policyFile, fileSystem);
+ hiveServer.start();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java
new file mode 100644
index 0000000..f86ae6d
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java
@@ -0,0 +1,210 @@
+/*
+ * 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.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class Context {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(Context.class);
+
+ public static final String AUTHZ_EXCEPTION_SQL_STATE = "42000";
+ public static final String AUTHZ_EXEC_HOOK_EXCEPTION_SQL_STATE = "08S01";
+ public static final String AUTHZ_EXCEPTION_ERROR_MSG = "No valid privileges";
+
+ private final HiveServer hiveServer;
+ private final FileSystem fileSystem;
+ private final File baseDir;
+ private final File dataDir;
+
+ private final File policyFile;
+ private final Set<Connection> connections;
+ private final Set<Statement> statements;
+
+
+ public Context(HiveServer hiveServer, FileSystem fileSystem,
+ File baseDir, File confDir, File dataDir, File policyFile) throws Exception {
+ this.hiveServer = hiveServer;
+ this.fileSystem = fileSystem;
+ this.baseDir = baseDir;
+ this.dataDir = dataDir;
+ this.policyFile = policyFile;
+ connections = Sets.newHashSet();
+ statements = Sets.newHashSet();
+ }
+
+ public Connection createConnection(String username, String password) throws Exception {
+ Connection connection = hiveServer.createConnection(username, password);
+ connections.add(connection);
+ assertNotNull("Connection is null", connection);
+ assertFalse("Connection should not be closed", connection.isClosed());
+ Statement statement = connection.createStatement();
+ statement.close();
+ return connection;
+ }
+
+ public Statement createStatement(Connection connection)
+ throws Exception {
+ Statement statement = connection.createStatement();
+ assertNotNull("Statement is null", statement);
+ statements.add(statement);
+ return statement;
+ }
+ /**
+ * Deprecated} use append()
+ */
+ public void writePolicyFile(String buf) throws IOException {
+ FileOutputStream out = new FileOutputStream(policyFile);
+ out.write(buf.getBytes(Charsets.UTF_8));
+ out.close();
+ }
+ /**
+ * Deprecated} use append()
+ */
+ @Deprecated
+ public void appendToPolicyFileWithNewLine(String line) throws IOException {
+ append(line);
+ }
+ public void append(String...lines) throws IOException {
+ StringBuffer buffer = new StringBuffer();
+ for(String line : lines) {
+ buffer.append(line).append("\n");
+ }
+ Files.append(buffer, policyFile, Charsets.UTF_8);
+ }
+
+ public boolean deletePolicyFile() throws IOException {
+ return policyFile.delete();
+ }
+ /**
+ * Deprecated} use append()
+ */
+ public void makeNewPolicy(String policyLines[]) throws FileNotFoundException {
+ PrintWriter policyWriter = new PrintWriter (policyFile.toString());
+ for (String line : policyLines) {
+ policyWriter.println(line);
+ }
+ policyWriter.close();
+ assertFalse(policyWriter.checkError());
+ }
+
+ public void close() {
+ for(Statement statement : statements) {
+ try {
+ statement.close();
+ } catch (SQLException exception) {
+ LOGGER.warn("Error closing " + statement, exception);
+ }
+ }
+ statements.clear();
+
+ for(Connection connection : connections) {
+ try {
+ connection.close();
+ } catch (SQLException exception) {
+ LOGGER.warn("Error closing " + connection, exception);
+ }
+ }
+ connections.clear();
+ }
+
+ public void assertAuthzException(Statement statement, String query)
+ throws SQLException {
+ try {
+ statement.execute(query);
+ Assert.fail("Expected SQLException for '" + query + "'");
+ } catch (SQLException e) {
+ verifyAuthzException(e);
+ }
+ }
+
+ public void assertAuthzExecHookException(Statement statement, String query)
+ throws SQLException {
+ try {
+ statement.execute(query);
+ Assert.fail("Expected SQLException for '" + query + "'");
+ } catch (SQLException e) {
+ verifyAuthzExecHookException(e);
+ }
+ }
+
+
+ // verify that the sqlexception is due to authorization failure
+ public void verifyAuthzException(SQLException sqlException) throws SQLException{
+ verifyAuthzExceptionForState(sqlException, AUTHZ_EXCEPTION_SQL_STATE);
+ }
+
+ // verify that the sqlexception is due to authorization failure due to exec hooks
+ public void verifyAuthzExecHookException(SQLException sqlException) throws SQLException{
+ verifyAuthzExceptionForState(sqlException, AUTHZ_EXEC_HOOK_EXCEPTION_SQL_STATE);
+ }
+
+ // verify that the sqlexception is due to authorization failure
+ private void verifyAuthzExceptionForState(SQLException sqlException,
+ String expectedSqlState) throws SQLException {
+ if (!expectedSqlState.equals(sqlException.getSQLState())) {
+ throw sqlException;
+ }
+ }
+
+ public File getBaseDir() {
+ return baseDir;
+ }
+
+ public File getDataDir() {
+ return dataDir;
+ }
+
+ public File getPolicyFile() {
+ return policyFile;
+ }
+
+ @SuppressWarnings("static-access")
+ public URI getDFSUri() throws IOException {
+ return fileSystem.getDefaultUri(fileSystem.getConf());
+ }
+
+ public String getProperty(String propName) {
+ return hiveServer.getProperty(propName);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/DummySentryOnFailureHook.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/DummySentryOnFailureHook.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/DummySentryOnFailureHook.java
new file mode 100644
index 0000000..e4055a7
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/DummySentryOnFailureHook.java
@@ -0,0 +1,32 @@
+/*
+ * 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 org.apache.sentry.binding.hive.SentryOnFailureHook;
+import org.apache.sentry.binding.hive.SentryOnFailureHookContext;
+
+public class DummySentryOnFailureHook implements SentryOnFailureHook {
+
+ static boolean invoked = false;
+
+ @Override
+ public void run(SentryOnFailureHookContext failureHookContext)
+ throws Exception {
+ invoked = true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/PolicyFileEditor.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/PolicyFileEditor.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/PolicyFileEditor.java
new file mode 100644
index 0000000..1c9511d
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/PolicyFileEditor.java
@@ -0,0 +1,78 @@
+/*
+ * 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.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+
+/**
+ * Deprecated} use Context.append()
+ */
+public class PolicyFileEditor {
+
+ private static final String NL = System.getProperty("line.separator", "\n");
+
+ private File policy;
+
+ public PolicyFileEditor (File policy) throws IOException {
+ policy.delete();
+ policy.createNewFile();
+ this.policy = policy;
+ }
+
+ public void clearOldPolicy() throws IOException {
+ policy.delete();
+ policy.createNewFile();
+ }
+
+ public void addPolicy(String line, String cat) throws IOException {
+ List<String> result = new ArrayList<String>();
+ boolean exist = false;
+ for(String s : Files.readLines(policy, Charsets.UTF_8)) {
+ result.add(s);
+ if (s.equals("[" + cat + "]")) {
+ result.add(line);
+ exist = true;
+ }
+ }
+ if (!exist) {
+ result.add("[" + cat + "]");
+ result.add(line);
+ }
+ Files.write(Joiner.on(NL).join(result), policy, Charsets.UTF_8);
+ }
+ public void removePolicy(String line) throws IOException {
+ List<String> result = Lists.newArrayList();
+ for(String s : Files.readLines(policy, Charsets.UTF_8)) {
+ if (!s.equals(line)) {
+ result.add(s);
+ }
+ }
+ Files.write(Joiner.on(NL).join(result), policy, Charsets.UTF_8);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java
new file mode 100644
index 0000000..45854e9
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java
@@ -0,0 +1,691 @@
+/*
+ * 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.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.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+/* Tests privileges at table scope with cross database access */
+
+public class TestCrossDbOps extends AbstractTestWithStaticLocalFS {
+ private File dataFile;
+ private PolicyFile policyFile;
+ private String loadData;
+
+ @Before
+ public void setup() throws Exception {
+ context = createContext();
+ File dataDir = context.getDataDir();
+ // copy data file to test dir
+ 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();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ loadData = "server=server1->uri=file://" + dataFile.getPath();
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /*
+ * Admin creates DB_1, DB2, tables (tab_1 ) and (tab_2, tab_3) in DB_1 and
+ * DB_2 respectively. User user1 has select on DB_1.tab_1, insert on
+ * DB2.tab_2 User user2 has select on DB2.tab_3 Test show database and show
+ * tables for both user1 and user2
+ */
+ @Test
+ public void testShowDatabasesAndShowTables() throws Exception {
+ // edit policy file
+ policyFile
+ .addRolesToGroup("group1", "select_tab1", "insert_tab2")
+ .addRolesToGroup("group2", "select_tab3")
+ .addPermissionsToRole("select_tab1", "server=server1->db=db1->table=tab1->action=select")
+ .addPermissionsToRole("select_tab3", "server=server1->db=db2->table=tab3->action=select")
+ .addPermissionsToRole("insert_tab2", "server=server1->db=db2->table=tab2->action=insert")
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group2");
+ policyFile.write(context.getPolicyFile());
+
+ // admin create two databases
+ Connection connection = context.createConnection(ADMIN1, "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB1 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB2 CASCADE");
+
+ statement.execute("CREATE DATABASE DB1");
+ statement.execute("CREATE DATABASE DB2");
+ statement.execute("USE DB1");
+ statement.execute("CREATE TABLE TAB1(id int)");
+ statement.executeQuery("SHOW TABLES");
+ statement.execute("USE DB2");
+ statement.execute("CREATE TABLE TAB2(id int)");
+ statement.execute("CREATE TABLE TAB3(id int)");
+
+ // test show databases
+ // show databases shouldn't filter any of the dbs from the resultset
+ Connection conn = context.createConnection("user1", "");
+ Statement stmt = context.createStatement(conn);
+ ResultSet res = stmt.executeQuery("SHOW DATABASES");
+ List<String> result = new ArrayList<String>();
+ result.add("db1");
+ result.add("db2");
+ result.add("default");
+
+ while (res.next()) {
+ String dbName = res.getString(1);
+ assertTrue(dbName, result.remove(dbName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ // test show tables
+ stmt.execute("USE DB1");
+ res = stmt.executeQuery("SHOW TABLES");
+ result.clear();
+ result.add("tab1");
+
+ while (res.next()) {
+ String tableName = res.getString(1);
+ assertTrue(tableName, result.remove(tableName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ stmt.execute("USE DB2");
+ res = stmt.executeQuery("SHOW TABLES");
+ result.clear();
+ result.add("tab2");
+
+ while (res.next()) {
+ String tableName = res.getString(1);
+ assertTrue(tableName, result.remove(tableName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ stmt.close();
+ conn.close();
+
+ // test show databases and show tables for user2
+ conn = context.createConnection("user2", "");
+ stmt = context.createStatement(conn);
+ res = stmt.executeQuery("SHOW DATABASES");
+ result.clear();
+ result.add("db2");
+ result.add("default");
+
+ while (res.next()) {
+ String dbName = res.getString(1);
+ assertTrue(dbName, result.remove(dbName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ // test show tables
+ stmt.execute("USE DB2");
+ res = stmt.executeQuery("SHOW TABLES");
+ result.clear();
+ result.add("tab3");
+
+ while (res.next()) {
+ String tableName = res.getString(1);
+ assertTrue(tableName, result.remove(tableName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ try {
+ stmt.execute("USE DB1");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ context.close();
+ }
+
+ /*
+ * Admin creates DB_1, DB2, tables (tab_1 ) and (tab_2, tab_3) in DB_1 and
+ * DB_2 respectively. User user1 has select on DB_1.tab_1, insert on
+ * DB2.tab_2 User user2 has select on DB2.tab_3 Test show database and show
+ * tables for both user1 and user2
+ */
+ @Test
+ public void testJDBCGetSchemasAndGetTables() throws Exception {
+ // edit policy file
+ policyFile.addRolesToGroup("group1", "select_tab1", "insert_tab2")
+ .addRolesToGroup("group2", "select_tab3")
+ .addPermissionsToRole("select_tab1", "server=server1->db=db1->table=tab1->action=select")
+ .addPermissionsToRole("select_tab3", "server=server1->db=db2->table=tab3->action=select")
+ .addPermissionsToRole("insert_tab2", "server=server1->db=db2->table=tab2->action=insert")
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group2");
+ policyFile.write(context.getPolicyFile());
+
+ // admin create two databases
+ Connection connection = context.createConnection(ADMIN1, "foo");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB1 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB2 CASCADE");
+
+ statement.execute("CREATE DATABASE DB1");
+ statement.execute("CREATE DATABASE DB2");
+ statement.execute("USE DB1");
+ statement.execute("CREATE TABLE TAB1(id int)");
+ statement.executeQuery("SHOW TABLES");
+ statement.execute("USE DB2");
+ statement.execute("CREATE TABLE TAB2(id int)");
+ statement.execute("CREATE TABLE TAB3(id int)");
+
+ // test show databases
+ // show databases shouldn't filter any of the dbs from the resultset
+ Connection conn = context.createConnection("user1", "");
+ List<String> result = new ArrayList<String>();
+
+ // test direct JDBC metadata API
+ ResultSet res = conn.getMetaData().getSchemas();
+ ResultSetMetaData resMeta = res.getMetaData();
+ assertEquals(2, resMeta.getColumnCount());
+ assertEquals("TABLE_SCHEM", resMeta.getColumnName(1));
+ assertEquals("TABLE_CATALOG", resMeta.getColumnName(2));
+
+ result.add("db1");
+ result.add("db2");
+ result.add("default");
+
+ while (res.next()) {
+ String dbName = res.getString(1);
+ assertTrue(dbName, result.remove(dbName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ // test direct JDBC metadata API
+ res = conn.getMetaData().getTables(null, "DB1", "tab%", null);
+ result.add("tab1");
+
+ while (res.next()) {
+ String tableName = res.getString(3);
+ assertTrue(tableName, result.remove(tableName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ // test direct JDBC metadata API
+ res = conn.getMetaData().getTables(null, "DB2", "tab%", null);
+ result.add("tab2");
+
+ while (res.next()) {
+ String tableName = res.getString(3);
+ assertTrue(tableName, result.remove(tableName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ res = conn.getMetaData().getTables(null, "DB%", "tab%", null);
+ result.add("tab2");
+ result.add("tab1");
+
+ while (res.next()) {
+ String tableName = res.getString(3);
+ assertTrue(tableName, result.remove(tableName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ //test show columns
+ res = conn.getMetaData().getColumns(null, "DB%", "tab%","i%" );
+ result.add("id");
+ result.add("id");
+
+ while (res.next()) {
+ String columnName = res.getString(4);
+ assertTrue(columnName, result.remove(columnName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ conn.close();
+
+ // test show databases and show tables for user2
+ conn = context.createConnection("user2", "");
+
+ // test direct JDBC metadata API
+ res = conn.getMetaData().getSchemas();
+ resMeta = res.getMetaData();
+ assertEquals(2, resMeta.getColumnCount());
+ assertEquals("TABLE_SCHEM", resMeta.getColumnName(1));
+ assertEquals("TABLE_CATALOG", resMeta.getColumnName(2));
+
+ result.add("db2");
+ result.add("default");
+
+ while (res.next()) {
+ String dbName = res.getString(1);
+ assertTrue(dbName, result.remove(dbName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ // test JDBC direct API
+ res = conn.getMetaData().getTables(null, "DB%", "tab%", null);
+ result.add("tab3");
+
+ while (res.next()) {
+ String tableName = res.getString(3);
+ assertTrue(tableName, result.remove(tableName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ //test show columns
+ res = conn.getMetaData().getColumns(null, "DB%", "tab%","i%" );
+ result.add("id");
+
+ while (res.next()) {
+ String columnName = res.getString(4);
+ assertTrue(columnName, result.remove(columnName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ //test show columns
+ res = conn.getMetaData().getColumns(null, "DB1", "tab%","i%" );
+
+ while (res.next()) {
+ String columnName = res.getString(4);
+ assertTrue(columnName, result.remove(columnName));
+ }
+ assertTrue(result.toString(), result.isEmpty());
+ res.close();
+
+ context.close();
+ }
+
+ /**
+ * 2.8 admin user create two database, DB_1, DB_2 admin grant all to USER1,
+ * USER2 on DB_1, admin grant all to user1's group, user2's group on DB_2
+ * positive test case: user1, user2 has ALL privilege on both DB_1 and DB_2
+ * negative test case: user1, user2 don't have ALL privilege on SERVER
+ */
+ @Test
+ public void testDbPrivileges() throws Exception {
+ // edit policy file
+ policyFile.addRolesToGroup("user_group", "db1_all,db2_all, load_data")
+ .addPermissionsToRole("db1_all", "server=server1->db=" + DB1)
+ .addPermissionsToRole("db2_all", "server=server1->db=" + DB2)
+ .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
+ .addGroupsToUser("user1", "user_group")
+ .addGroupsToUser("user2", "user_group");
+ policyFile.write(context.getPolicyFile());
+
+ dropDb(ADMIN1, DB1, DB2);
+ createDb(ADMIN1, DB1, DB2);
+ for (String user : new String[]{USER1, USER2}) {
+ for (String dbName : new String[]{DB1, DB2}) {
+ Connection userConn = context.createConnection(user, "foo");
+ String tabName = user + "_tab1";
+ Statement userStmt = context.createStatement(userConn);
+ // Positive case: test user1 and user2 has permissions to access
+ // db1 and
+ // db2
+ userStmt
+ .execute("create table " + dbName + "." + tabName + " (id int)");
+ userStmt.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
+ + "' INTO TABLE " + dbName + "." + tabName);
+ userStmt.execute("select * from " + dbName + "." + tabName);
+ context.close();
+ }
+ }
+ }
+
+ /**
+ * Test Case 2.11 admin user create a new database DB_1 and grant ALL to
+ * himself on DB_1 should work
+ */
+ @Test
+ public void testAdminDbPrivileges() throws Exception {
+ policyFile.write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ Connection adminCon = context.createConnection(ADMIN1, "password");
+ Statement adminStmt = context.createStatement(adminCon);
+ String tabName = DB1 + "." + "admin_tab1";
+ adminStmt.execute("create table " + tabName + "(c1 string)");
+ adminStmt.execute("load data local inpath '" + dataFile.getPath() + "' into table "
+ + tabName);
+ assertTrue(adminStmt.executeQuery("select * from " + tabName).next());
+ adminStmt.close();
+ adminCon.close();
+ }
+
+ /**
+ * Test Case 2.14 admin user create a new database DB_1 create TABLE_1 in DB_1
+ * admin user grant INSERT to user1's group on TABLE_1 negative test case:
+ * user1 try to do following on TABLE_1 will fail: --explain --analyze
+ * --describe --describe function --show columns --show table status --show
+ * table properties --show create table --show partitions --show indexes
+ * --select * from TABLE_1.
+ */
+ @Test
+ public void testNegativeUserPrivileges() throws Exception {
+ // edit policy file
+ policyFile.addRolesToGroup("user_group", "db1_tab1_insert", "db1_tab2_all")
+ .addPermissionsToRole("db1_tab2_all", "server=server1->db=db1->table=table_2")
+ .addPermissionsToRole("db1_tab1_insert", "server=server1->db=db1->table=table_1->action=insert")
+ .addGroupsToUser("user3", "user_group");
+ policyFile.write(context.getPolicyFile());
+
+ Connection adminCon = context.createConnection(ADMIN1, "foo");
+ Statement adminStmt = context.createStatement(adminCon);
+ String dbName = "db1";
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.execute("create table " + dbName + ".table_1 (id int)");
+ adminStmt.close();
+ adminCon.close();
+ Connection userConn = context.createConnection("user3", "foo");
+ Statement userStmt = context.createStatement(userConn);
+ context.assertAuthzException(userStmt, "select * from " + dbName + ".table_1");
+ userConn.close();
+ userStmt.close();
+ }
+
+ /**
+ * Test Case 2.16 admin user create a new database DB_1 create TABLE_1 and
+ * TABLE_2 (same schema) in DB_1 admin user grant SELECT, INSERT to user1's
+ * group on TABLE_2 negative test case: user1 try to do following on TABLE_1
+ * will fail: --insert overwrite TABLE_2 select * from TABLE_1
+ */
+ @Test
+ public void testNegativeUserDMLPrivileges() throws Exception {
+ policyFile
+ .addPermissionsToRole("db1_tab2_all", "server=server1->db=db1->table=table_2")
+ .addRolesToGroup("group1", "db1_tab2_all")
+ .addGroupsToUser("user3", "group1");
+ policyFile.write(context.getPolicyFile());
+
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ Connection adminCon = context.createConnection(ADMIN1, "password");
+ Statement adminStmt = context.createStatement(adminCon);
+ adminStmt.execute("create table " + DB1 + ".table_1 (id int)");
+ adminStmt.execute("create table " + DB1 + ".table_2 (id int)");
+ adminStmt.close();
+ adminCon.close();
+ Connection userConn = context.createConnection("user3", "foo");
+ Statement userStmt = context.createStatement(userConn);
+ context.assertAuthzException(userStmt, "insert overwrite table " + DB1
+ + ".table_2 select * from " + DB1 + ".table_1");
+ context.assertAuthzException(userStmt, "insert overwrite directory '" + dataDir.getPath()
+ + "' select * from " + DB1 + ".table_1");
+ userStmt.close();
+ userConn.close();
+ }
+
+ /**
+ * Test Case 2.17 Execution steps
+ * a) Admin user creates a new database DB_1,
+ * b) Admin user grants ALL on DB_1 to group GROUP_1
+ * c) User from GROUP_1 creates table TAB_1, TAB_2 in DB_1
+ * d) Admin user grants SELECT on TAB_1 to group GROUP_2
+ *
+ * 1) verify users from GROUP_2 have only SELECT privileges on TAB_1. They
+ * shouldn't be able to perform any operation other than those listed as
+ * requiring SELECT in the privilege model.
+ *
+ * 2) verify users from GROUP_2 can't perform queries involving join between
+ * TAB_1 and TAB_2.
+ *
+ * 3) verify users from GROUP_1 can't perform operations requiring ALL @
+ * SERVER scope. Refer to list
+ */
+ @Test
+ public void testNegUserPrivilegesAll() throws Exception {
+
+ policyFile
+ .addRolesToGroup("user_group1", "db1_all")
+ .addRolesToGroup("user_group2", "db1_tab1_select")
+ .addPermissionsToRole("db1_all", "server=server1->db=db1")
+ .addPermissionsToRole("db1_tab1_select", "server=server1->db=db1->table=table_1->action=select")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2");
+ policyFile.write(context.getPolicyFile());
+
+ // create dbs
+ Connection adminCon = context.createConnection(ADMIN1, "foo");
+ Statement adminStmt = context.createStatement(adminCon);
+ String dbName = "db1";
+ adminStmt.execute("use default");
+ adminStmt.execute("create table table_def (name string)");
+ adminStmt
+ .execute("load data local inpath '" + dataFile.getPath() + "' into table table_def");
+
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.execute("use " + dbName);
+
+ adminStmt.execute("create table table_1 (name string)");
+ adminStmt
+ .execute("load data local inpath '" + dataFile.getPath() + "' into table table_1");
+ adminStmt.execute("create table table_2 (name string)");
+ adminStmt
+ .execute("load data local inpath '" + dataFile.getPath() + "' into table table_2");
+ adminStmt.execute("create view v1 AS select * from table_1");
+ adminStmt
+ .execute("create table table_part_1 (name string) PARTITIONED BY (year INT)");
+ adminStmt.execute("ALTER TABLE table_part_1 ADD PARTITION (year = 2012)");
+
+ adminStmt.close();
+ adminCon.close();
+
+ Connection userConn = context.createConnection("user2", "foo");
+ Statement userStmt = context.createStatement(userConn);
+
+ context.assertAuthzException(userStmt, "drop database " + dbName);
+
+ // Hive currently doesn't support cross db index DDL
+
+ context.assertAuthzException(userStmt, "CREATE TEMPORARY FUNCTION strip AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
+ context.assertAuthzException(userStmt, "create table " + dbName
+ + ".c_tab_2 as select * from " + dbName + ".table_2");
+ context.assertAuthzException(userStmt, "select * from " + dbName + ".table_2");
+ context.assertAuthzException(userStmt, "ALTER DATABASE " + dbName
+ + " SET DBPROPERTIES ('foo' = 'bar')");
+ context.assertAuthzException(userStmt, "drop table " + dbName + ".table_1");
+ context.assertAuthzException(userStmt, "DROP VIEW IF EXISTS " + dbName + ".v1");
+ context.assertAuthzException(userStmt, "create table " + dbName + ".table_5 (name string)");
+ context.assertAuthzException(userStmt, "ALTER TABLE " + dbName + ".table_1 RENAME TO "
+ + dbName + ".table_99");
+ context.assertAuthzException(userStmt, "insert overwrite table " + dbName
+ + ".table_2 select * from " + dbName + ".table_1");
+ context.assertAuthzException(userStmt, "insert overwrite table " + dbName
+ + ".table_2 select * from " + "table_def");
+ context.assertAuthzException(userStmt, "ALTER TABLE " + dbName
+ + ".table_part_1 ADD IF NOT EXISTS PARTITION (year = 2012)");
+ context.assertAuthzException(userStmt, "ALTER TABLE " + dbName
+ + ".table_part_1 PARTITION (year = 2012) SET LOCATION '/etc'");
+ userStmt.close();
+ userConn.close();
+ }
+
+ /**
+ * Steps: 1. admin user create databases, DB_1 and DB_2, no table or other
+ * object in database
+ * 2. admin grant all to user1's group on DB_1 and DB_2
+ * positive test case:
+ * a)user1 has the privilege to create table, load data,
+ * drop table, create view, insert more data on both databases
+ * b) user1 can switch between DB_1 and DB_2 without exception
+ * negative test case:
+ * c) user1 cannot drop database
+ */
+ @Test
+ public void testSandboxOpt9() throws Exception {
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, ALL_DB1, ALL_DB2, loadData)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1);
+ policyFile.write(context.getPolicyFile());
+
+ dropDb(ADMIN1, DB1, DB2);
+ createDb(ADMIN1, DB1, DB2);
+
+ Connection connection = context.createConnection(USER1, "password");
+ Statement statement = context.createStatement(connection);
+
+ // a
+ statement.execute("DROP TABLE IF EXISTS " + DB1 + "." + TBL1);
+ statement.execute("create table " + DB1 + "." + TBL1
+ + " (under_col int comment 'the under column', value string)");
+ statement.execute("load data local inpath '" + dataFile.getPath()
+ + "' into table " + DB1 + "." + TBL1);
+ statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW1);
+ statement.execute("CREATE VIEW " + DB1 + "." + VIEW1
+ + " (value) AS SELECT value from " + DB1 + "." + TBL1
+ + " LIMIT 10");
+ statement.execute("DROP TABLE IF EXISTS " + DB2 + "." + TBL1);
+ statement.execute("CREATE TABLE " + DB2 + "." + TBL1
+ + " AS SELECT value from " + DB1 + "." + TBL1
+ + " LIMIT 10");
+
+ // b
+ statement.execute("DROP TABLE IF EXISTS " + DB2 + "." + TBL2);
+ statement.execute("create table " + DB2 + "." + TBL2
+ + " (under_col int comment 'the under column', value string)");
+ statement.execute("load data local inpath '" + dataFile.getPath()
+ + "' into table " + DB2 + "." + TBL2);
+ statement.execute("DROP TABLE IF EXISTS " + DB2 + "." + TBL3);
+ statement.execute("create table " + DB2 + "." + TBL3
+ + " (under_col int comment 'the under column', value string)");
+ statement.execute("load data local inpath '" + dataFile.getPath()
+ + "' into table " + DB2 + "." + TBL3);
+
+ // c
+ context.assertAuthzException(statement, "DROP DATABASE IF EXISTS " + DB1);
+ context.assertAuthzException(statement, "DROP DATABASE IF EXISTS " + DB2);
+
+ policyFile.removePermissionsFromRole(GROUP1_ROLE, ALL_DB2);
+ policyFile.write(context.getPolicyFile());
+
+ // create db1.view1 as select from db2.tbl2
+ statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW2);
+ context.assertAuthzException(statement, "CREATE VIEW " + DB1 + "." + VIEW2 +
+ " (value) AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
+ // create db1.tbl2 as select from db2.tbl2
+ statement.execute("DROP TABLE IF EXISTS " + DB1 + "." + TBL2);
+ context.assertAuthzException(statement, "CREATE TABLE " + DB1 + "." + TBL2 +
+ " AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
+
+
+
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Steps: 1. admin user create databases, DB_1 and DB_2, no table or other
+ * object in database positive test case:
+ * d) user1 has the privilege to create view on tables in DB_1 negative test case:
+ * e) user1 cannot create view in DB_1 that select from tables in DB_2
+ * with no select privilege 2.
+ * positive test case:
+ * f) user1 has the privilege to create view to select from DB_1.tb_1
+ * and DB_2.tb_2 negative test case:
+ * g) user1 cannot create view to select from DB_1.tb_1 and DB_2.tb_3
+ */
+ @Test
+ public void testCrossDbViewOperations() throws Exception {
+ // edit policy file
+ policyFile
+ .addRolesToGroup("group1", "all_db1", "load_data", "select_tb2")
+ .addPermissionsToRole("all_db1", "server=server1->db=db_1")
+ .addPermissionsToRole("all_db2", "server=server1->db=db_2")
+ .addPermissionsToRole("select_tb2", "server=server1->db=db_2->table=tb_1->action=select")
+ .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
+ .addGroupsToUser("user1", "group1");
+ policyFile.write(context.getPolicyFile());
+
+ // admin create two databases
+ dropDb(ADMIN1, DB1, DB2);
+ createDb(ADMIN1, DB1, DB2);
+ Connection connection = context.createConnection(ADMIN1, "password");
+ Statement statement = context.createStatement(connection);
+ statement
+ .execute("CREATE TABLE " + DB1 + "." + TBL1 + "(id int)");
+ statement
+ .execute("CREATE TABLE " + DB2 + "." + TBL1 + "(id int)");
+ statement
+ .execute("CREATE TABLE " + DB2 + "." + TBL2 + "(id int)");
+ context.close();
+
+ connection = context.createConnection("user1", "foo");
+ statement = context.createStatement(connection);
+
+ // d
+ statement.execute("DROP TABLE IF EXISTS " + DB1 + "." + TBL1);
+ statement.execute("create table " + DB1 + "." + TBL1
+ + " (under_col int comment 'the under column', value string)");
+
+ // e
+ statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW1);
+ context.assertAuthzException(statement, "CREATE VIEW " + DB1 + "." + VIEW1
+ + " (value) AS SELECT value from " + DB2 + "." + TBL2
+ + " LIMIT 10");
+ // f
+ statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW2);
+ statement.execute("CREATE VIEW " + DB1 + "." + VIEW2
+ + " (value) AS SELECT value from " + DB1 + "." + TBL1
+ + " LIMIT 10");
+
+ // g
+ statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW3);
+ context.assertAuthzException(statement, "CREATE VIEW " + DB1 + "." + VIEW3
+ + " (value) AS SELECT value from " + DB2 + "." + TBL2
+ + " LIMIT 10");
+ }
+}
[5/9] SENTRY-16: Move sentry-tests to sentry-tests-hive package
(Gregory Chanan via Shreepadma Venugopalan)
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/HiveServerFactory.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/HiveServerFactory.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/HiveServerFactory.java
new file mode 100644
index 0000000..f6d1791
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/HiveServerFactory.java
@@ -0,0 +1,212 @@
+/*
+ * 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.hiveserver;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.URL;
+import java.util.Map;
+
+import com.google.common.annotations.VisibleForTesting;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.hdfs.DistributedFileSystem;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
+import org.fest.reflect.core.Reflection;
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.Resources;
+
+public class HiveServerFactory {
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(HiveServerFactory.class);
+ private static final String HIVE_DRIVER_NAME = "org.apache.hive.jdbc.HiveDriver";
+ private static final String DERBY_DRIVER_NAME = "org.apache.derby.jdbc.EmbeddedDriver";
+ public static final String HIVESERVER2_TYPE = "sentry.e2etest.hiveServer2Type";
+ public static final String KEEP_BASEDIR = "sentry.e2etest.keepBaseDir";
+ public static final String METASTORE_CONNECTION_URL = HiveConf.ConfVars.METASTORECONNECTURLKEY.varname;
+ public static final String WAREHOUSE_DIR = HiveConf.ConfVars.METASTOREWAREHOUSE.varname;
+ public static final String AUTHZ_PROVIDER = HiveAuthzConf.AuthzConfVars.AUTHZ_PROVIDER.getVar();
+ public static final String AUTHZ_PROVIDER_RESOURCE = HiveAuthzConf.AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar();
+ public static final String AUTHZ_PROVIDER_FILENAME = "test-authz-provider.ini";
+ public static final String AUTHZ_SERVER_NAME = HiveAuthzConf.AuthzConfVars.AUTHZ_SERVER_NAME.getVar();
+ public static final String ACCESS_TESTING_MODE = HiveAuthzConf.AuthzConfVars.ACCESS_TESTING_MODE.getVar();
+ public static final String HS2_PORT = ConfVars.HIVE_SERVER2_THRIFT_PORT.toString();
+ public static final String SUPPORT_CONCURRENCY = HiveConf.ConfVars.HIVE_SUPPORT_CONCURRENCY.varname;
+ public static final String HADOOPBIN = ConfVars.HADOOPBIN.toString();
+ public static final String DEFAULT_AUTHZ_SERVER_NAME = "server1";
+ public static final String HIVESERVER2_IMPERSONATION = "hive.server2.enable.doAs";
+
+
+ static {
+ try {
+ Assert.assertNotNull(DERBY_DRIVER_NAME + " is null", Class.forName(DERBY_DRIVER_NAME));
+ Assert.assertNotNull(HIVE_DRIVER_NAME + " is null", Class.forName(HIVE_DRIVER_NAME));
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static HiveServer create(Map<String, String> properties,
+ File baseDir, File confDir, File logDir, File policyFile,
+ FileSystem fileSystem)
+ throws Exception {
+ String type = properties.get(HIVESERVER2_TYPE);
+ if(type == null) {
+ type = System.getProperty(HIVESERVER2_TYPE);
+ }
+ if(type == null) {
+ type = HiveServer2Type.InternalHiveServer2.name();
+ }
+ return create(HiveServer2Type.valueOf(type.trim()), properties,
+ baseDir, confDir, logDir, policyFile, fileSystem);
+ }
+
+ private static HiveServer create(HiveServer2Type type,
+ Map<String, String> properties, File baseDir, File confDir,
+ File logDir, File policyFile, FileSystem fileSystem) throws Exception {
+ if(!properties.containsKey(WAREHOUSE_DIR)) {
+ LOGGER.error("fileSystem " + fileSystem.getClass().getSimpleName());
+ if (fileSystem instanceof DistributedFileSystem) {
+ @SuppressWarnings("static-access")
+ String dfsUri = fileSystem.getDefaultUri(fileSystem.getConf()).toString();
+ LOGGER.error("dfsUri " + dfsUri);
+ properties.put(WAREHOUSE_DIR, dfsUri + "/data");
+ } else {
+ properties.put(WAREHOUSE_DIR, new File(baseDir, "warehouse").getPath());
+ }
+ }
+ if(!properties.containsKey(METASTORE_CONNECTION_URL)) {
+ properties.put(METASTORE_CONNECTION_URL,
+ String.format("jdbc:derby:;databaseName=%s;create=true",
+ new File(baseDir, "metastore").getPath()));
+ }
+ if(policyFile.exists()) {
+ LOGGER.info("Policy file " + policyFile + " exists");
+ } else {
+ LOGGER.info("Creating policy file " + policyFile);
+ FileOutputStream to = new FileOutputStream(policyFile);
+ Resources.copy(Resources.getResource(AUTHZ_PROVIDER_FILENAME), to);
+ to.close();
+ }
+ if(!properties.containsKey(ACCESS_TESTING_MODE)) {
+ properties.put(ACCESS_TESTING_MODE, "true");
+ }
+ if(!properties.containsKey(AUTHZ_PROVIDER_RESOURCE)) {
+ properties.put(AUTHZ_PROVIDER_RESOURCE, policyFile.getPath());
+ }
+ if(!properties.containsKey(AUTHZ_PROVIDER)) {
+ properties.put(AUTHZ_PROVIDER, LocalGroupResourceAuthorizationProvider.class.getName());
+ }
+ if(!properties.containsKey(AUTHZ_SERVER_NAME)) {
+ properties.put(AUTHZ_SERVER_NAME, DEFAULT_AUTHZ_SERVER_NAME);
+ }
+ if(!properties.containsKey(HS2_PORT)) {
+ properties.put(HS2_PORT, String.valueOf(findPort()));
+ }
+ if(!properties.containsKey(SUPPORT_CONCURRENCY)) {
+ properties.put(SUPPORT_CONCURRENCY, "false");
+ }
+ if(!properties.containsKey(HADOOPBIN)) {
+ properties.put(HADOOPBIN, "./target/hadoop/bin/hadoop");
+ }
+ String hadoopBinPath = properties.get(HADOOPBIN);
+ Assert.assertNotNull(hadoopBinPath, "Hadoop Bin");
+ File hadoopBin = new File(hadoopBinPath);
+ if(!hadoopBin.isFile()) {
+ Assert.fail("Path to hadoop bin " + hadoopBin.getPath() + "is invalid. "
+ + "Perhaps you missed the download-hadoop profile.");
+ }
+ /*
+ * This hack, setting the hiveSiteURL field removes a previous hack involving
+ * setting of system properties for each property. Although both are hacks,
+ * I prefer this hack because once the system properties are set they can
+ * affect later tests unless those tests clear them. This hack allows for
+ * a clean switch to a new set of defaults when a new HiveConf object is created.
+ */
+ Reflection.staticField("hiveSiteURL")
+ .ofType(URL.class)
+ .in(HiveConf.class)
+ .set(null);
+ HiveConf hiveConf = new HiveConf();
+ HiveAuthzConf authzConf = new HiveAuthzConf(Resources.getResource("sentry-site.xml"));
+ for(Map.Entry<String, String> entry : properties.entrySet()) {
+ LOGGER.info(entry.getKey() + " => " + entry.getValue());
+ hiveConf.set(entry.getKey(), entry.getValue());
+ authzConf.set(entry.getKey(), entry.getValue());
+ }
+ File hiveSite = new File(confDir, "hive-site.xml");
+ File accessSite = new File(confDir, HiveAuthzConf.AUTHZ_SITE_FILE);
+ OutputStream out = new FileOutputStream(accessSite);
+ authzConf.writeXml(out);
+ out.close();
+ // points hive-site.xml at access-site.xml
+ hiveConf.set(HiveAuthzConf.HIVE_ACCESS_CONF_URL, accessSite.toURI().toURL().toExternalForm());
+ if(!properties.containsKey(HiveConf.ConfVars.HIVE_SERVER2_SESSION_HOOK.varname)) {
+ hiveConf.set(HiveConf.ConfVars.HIVE_SERVER2_SESSION_HOOK.varname,
+ "org.apache.sentry.binding.hive.HiveAuthzBindingSessionHook");
+ }
+ hiveConf.set(HIVESERVER2_IMPERSONATION, "false");
+ out = new FileOutputStream(hiveSite);
+ hiveConf.writeXml(out);
+ out.close();
+
+ Reflection.staticField("hiveSiteURL")
+ .ofType(URL.class)
+ .in(HiveConf.class)
+ .set(hiveSite.toURI().toURL());
+
+ switch (type) {
+ case EmbeddedHiveServer2:
+ LOGGER.info("Creating EmbeddedHiveServer");
+ return new EmbeddedHiveServer();
+ case InternalHiveServer2:
+ LOGGER.info("Creating InternalHiveServer");
+ return new InternalHiveServer(hiveConf);
+ case ExternalHiveServer2:
+ LOGGER.info("Creating ExternalHiveServer");
+ return new ExternalHiveServer(hiveConf, confDir, logDir);
+ case UnmanagedHiveServer2:
+ LOGGER.info("Creating UnmanagedHiveServer");
+ return new UnmanagedHiveServer();
+ default:
+ throw new UnsupportedOperationException(type.name());
+ }
+ }
+ private static int findPort() throws IOException {
+ ServerSocket socket = new ServerSocket(0);
+ int port = socket.getLocalPort();
+ socket.close();
+ return port;
+ }
+
+ @VisibleForTesting
+ public static enum HiveServer2Type {
+ EmbeddedHiveServer2, // Embedded HS2, directly executed by JDBC, without thrift
+ InternalHiveServer2, // Start a thrift HS2 in the same process
+ ExternalHiveServer2, // start a remote thrift HS2
+ UnmanagedHiveServer2 // Use a remote thrift HS2 already running
+ ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/InternalHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/InternalHiveServer.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/InternalHiveServer.java
new file mode 100644
index 0000000..3a257bf
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/InternalHiveServer.java
@@ -0,0 +1,55 @@
+/*
+ * 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.hiveserver;
+
+import java.io.IOException;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.metastore.HiveMetaStore;
+import org.apache.hive.service.server.HiveServer2;
+import org.fest.reflect.core.Reflection;
+
+public class InternalHiveServer extends AbstractHiveServer {
+
+ private final HiveServer2 hiveServer2;
+ private final HiveConf conf;
+
+ public InternalHiveServer(HiveConf conf) throws IOException {
+ super(conf, getHostname(conf), getPort(conf));
+ // Fix for ACCESS-148. Resets a static field
+ // so the default database is created even
+ // though is has been created before in this JVM
+ Reflection.staticField("createDefaultDB")
+ .ofType(boolean.class)
+ .in(HiveMetaStore.HMSHandler.class)
+ .set(false);
+ hiveServer2 = new HiveServer2();
+ this.conf = conf;
+ }
+
+ @Override
+ public synchronized void start() throws Exception {
+ hiveServer2.init(conf);
+ hiveServer2.start();
+ waitForStartup(this);
+ }
+
+ @Override
+ public synchronized void shutdown() {
+ hiveServer2.stop();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/UnmanagedHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/UnmanagedHiveServer.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/UnmanagedHiveServer.java
new file mode 100644
index 0000000..5a49c4c
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/UnmanagedHiveServer.java
@@ -0,0 +1,96 @@
+/*
+ * 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.hiveserver;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import org.apache.hadoop.hive.conf.HiveConf;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.Properties;
+
+public class UnmanagedHiveServer implements HiveServer {
+ private static final Logger LOGGER = LoggerFactory.getLogger(UnmanagedHiveServer.class);
+ public static String hostname;
+ public static int port;
+ public static final String hs2Host = System.getProperty("hs2Host");
+ public static final int hs2Port = Integer.parseInt(System.getProperty("hivePort", "10000"));
+ public static final String auth = System.getProperty("auth", "kerberos");
+ public static final String hivePrincipal = System.getProperty("hivePrincipal");
+ public static final String kerbRealm = System.getProperty("kerberosRealm");
+ private HiveConf hiveConf;
+
+ public UnmanagedHiveServer() {
+ Preconditions.checkNotNull(hs2Host);
+ if(auth.equalsIgnoreCase("kerberos")){
+ Preconditions.checkNotNull(kerbRealm);
+ Preconditions.checkNotNull(hivePrincipal);
+ }
+ this.hostname = hs2Host;
+ this.port = hs2Port;
+ hiveConf = new HiveConf();
+ }
+
+ @Override
+ public void start() throws Exception {
+ //For Unmanaged HiveServer, service need not be started within the test
+ }
+
+ @Override
+ public void shutdown() throws Exception {
+ //For Unmanaged HiveServer, service need not be stopped within the test
+ }
+
+ @Override
+ public String getURL() {
+ return "jdbc:hive2://" + hostname + ":" + port + "/default;";
+ }
+
+ @Override
+ public String getProperty(String key) {
+ return hiveConf.get(key);
+ }
+
+ @Override
+ public Connection createConnection(String user, String password) throws Exception{
+ String url = getURL();
+ Properties oProps = new Properties();
+
+ if(auth.equalsIgnoreCase("kerberos")){
+ String commandFormat = "kinit -kt /cdep/keytabs/%s.keytab %s@" + kerbRealm;
+ String command = String.format(commandFormat, user, user, user);
+ Process proc = Runtime.getRuntime().exec(command);
+ String status = (proc.waitFor()==0)?"passed":"failed";
+ LOGGER.info(command + ": " + status);
+
+ command = "kinit -R";
+ proc = Runtime.getRuntime().exec(command);
+ status = (proc.waitFor()==0)?"passed":"failed";
+ LOGGER.info(command + ": " + status);
+
+ url += "principal=" + hivePrincipal;
+ }else{
+ oProps.setProperty("user",user);
+ oProps.setProperty("password",password);
+ }
+ LOGGER.info("url: " + url);
+ return DriverManager.getConnection(url, oProps);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/resources/emp.dat
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/resources/emp.dat b/sentry-tests/sentry-tests-hive/src/test/resources/emp.dat
new file mode 100644
index 0000000..5922b20
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/resources/emp.dat
@@ -0,0 +1,12 @@
+16|john
+17|robert
+18|andrew
+19|katty
+21|tom
+22|tim
+23|james
+24|paul
+27|edward
+29|alan
+31|kerry
+34|terri
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/resources/hive-site.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/resources/hive-site.xml b/sentry-tests/sentry-tests-hive/src/test/resources/hive-site.xml
new file mode 100644
index 0000000..237c408
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/resources/hive-site.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+ 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.
+-->
+
+<configuration>
+<property>
+ <name>hive.metastore.warehouse.dir</name>
+ <value>invalid</value>
+</property>
+
+<property>
+ <name>mapreduce.framework.name</name>
+ <value>local</value>
+</property>
+
+<property>
+ <name>javax.jdo.option.ConnectionURL</name>
+ <value>invalid</value>
+</property>
+
+<property>
+ <name>hadoop.bin.path</name>
+ <value>./target/hadoop/bin/hadoop</value>
+</property>
+
+<property>
+ <name>hive.support.concurrency</name>
+ <value>false</value>
+</property>
+</configuration>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/resources/kv1.dat
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/resources/kv1.dat b/sentry-tests/sentry-tests-hive/src/test/resources/kv1.dat
new file mode 100644
index 0000000..20fb0dc
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/resources/kv1.dat
@@ -0,0 +1,500 @@
+238
+86
+311
+27
+165
+409
+255
+278
+98
+484
+265
+193
+401
+150
+273
+224
+369
+66
+128
+213
+146
+406
+429
+374
+152
+469
+145
+495
+37
+327
+281
+277
+209
+15
+82
+403
+166
+417
+430
+252
+292
+219
+287
+153
+193
+338
+446
+459
+394
+237
+482
+174
+413
+494
+207
+199
+466
+208
+174
+399
+396
+247
+417
+489
+162
+377
+397
+309
+365
+266
+439
+342
+367
+325
+167
+195
+475
+17
+113
+155
+203
+339
+0
+455
+128
+311
+316
+57
+302
+205
+149
+438
+345
+129
+170
+20
+489
+157
+378
+221
+92
+111
+47
+72
+4
+280
+35
+427
+277
+208
+356
+399
+169
+382
+498
+125
+386
+437
+469
+192
+286
+187
+176
+54
+459
+51
+138
+103
+239
+213
+216
+430
+278
+176
+289
+221
+65
+318
+332
+311
+275
+137
+241
+83
+333
+180
+284
+12
+230
+181
+67
+260
+404
+384
+489
+353
+373
+272
+138
+217
+84
+348
+466
+58
+8
+411
+230
+208
+348
+24
+463
+431
+179
+172
+42
+129
+158
+119
+496
+0
+322
+197
+468
+393
+454
+100
+298
+199
+191
+418
+96
+26
+165
+327
+230
+205
+120
+131
+51
+404
+43
+436
+156
+469
+468
+308
+95
+196
+288
+481
+457
+98
+282
+197
+187
+318
+318
+409
+470
+137
+369
+316
+169
+413
+85
+77
+0
+490
+87
+364
+179
+118
+134
+395
+282
+138
+238
+419
+15
+118
+72
+90
+307
+19
+435
+10
+277
+273
+306
+224
+309
+389
+327
+242
+369
+392
+272
+331
+401
+242
+452
+177
+226
+5
+497
+402
+396
+317
+395
+58
+35
+336
+95
+11
+168
+34
+229
+233
+143
+472
+322
+498
+160
+195
+42
+321
+430
+119
+489
+458
+78
+76
+41
+223
+492
+149
+449
+218
+228
+138
+453
+30
+209
+64
+468
+76
+74
+342
+69
+230
+33
+368
+103
+296
+113
+216
+367
+344
+167
+274
+219
+239
+485
+116
+223
+256
+263
+70
+487
+480
+401
+288
+191
+5
+244
+438
+128
+467
+432
+202
+316
+229
+469
+463
+280
+2
+35
+283
+331
+235
+80
+44
+193
+321
+335
+104
+466
+366
+175
+403
+483
+53
+105
+257
+406
+409
+190
+406
+401
+114
+258
+90
+203
+262
+348
+424
+12
+396
+201
+217
+164
+431
+454
+478
+298
+125
+431
+164
+424
+187
+382
+5
+70
+397
+480
+291
+24
+351
+255
+104
+70
+163
+438
+119
+414
+200
+491
+237
+439
+360
+248
+479
+305
+417
+199
+444
+120
+429
+169
+443
+323
+325
+277
+230
+478
+178
+468
+310
+317
+333
+493
+460
+207
+249
+265
+480
+83
+136
+353
+172
+214
+462
+233
+406
+133
+175
+189
+454
+375
+401
+421
+407
+384
+256
+26
+134
+67
+384
+379
+18
+462
+492
+100
+298
+9
+341
+498
+146
+458
+362
+186
+285
+348
+167
+18
+273
+183
+281
+344
+97
+469
+315
+84
+28
+37
+448
+152
+348
+307
+194
+414
+477
+222
+126
+90
+169
+403
+400
+200
+97
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/resources/log4j.properties b/sentry-tests/sentry-tests-hive/src/test/resources/log4j.properties
new file mode 100644
index 0000000..d941816
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/resources/log4j.properties
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+
+# Define some default values that can be overridden by system properties.
+#
+# For testing, it may also be convenient to specify
+
+sentry.root.logger=INFO,console
+log4j.rootLogger=${sentry.root.logger}
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d (%t) [%p - %l] %m%n
+
+log4j.logger.org.apache.hadoop.conf.Configuration=ERROR
+log4j.logger.org.apache.sentry=DEBUG
+
+log4j.category.DataNucleus=ERROR
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/resources/sentry-site.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/resources/sentry-site.xml b/sentry-tests/sentry-tests-hive/src/test/resources/sentry-site.xml
new file mode 100644
index 0000000..de0c9cf
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/resources/sentry-site.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+ 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.
+-->
+
+<configuration>
+ <property>
+ <name>hive.sentry.provider</name>
+ <value>invalid</value>
+ </property>
+ <property>
+ <name>hive.sentry.provider.resource</name>
+ <value>invalid</value>
+ </property>
+ <property>
+ <name>hive.sentry.server</name>
+ <value>myHS2</value>
+ </property>
+</configuration>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/resources/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/resources/test-authz-provider.ini b/sentry-tests/sentry-tests-hive/src/test/resources/test-authz-provider.ini
new file mode 100644
index 0000000..014d827
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/resources/test-authz-provider.ini
@@ -0,0 +1,25 @@
+# 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.
+
+[groups]
+foo = all_default
+
+[roles]
+all_default = server=server1->db=default
+
+[users]
+foo = foo
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithHiveServer.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithHiveServer.java
deleted file mode 100644
index d4060d3..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithHiveServer.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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;
-
-import java.io.File;
-import java.util.Map;
-
-import junit.framework.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServer;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServerFactory;
-import org.junit.After;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.io.Files;
-
-public abstract class AbstractTestWithHiveServer {
- private static final Logger LOGGER = LoggerFactory
- .getLogger(AbstractTestWithHiveServer.class);
- protected File baseDir;
- protected File logDir;
- protected File confDir;
- protected File dataDir;
- protected File policyFile;
- protected HiveServer hiveServer;
- protected FileSystem fileSystem;
-
- public Context createContext(Map<String, String> properties)
- throws Exception {
- fileSystem = FileSystem.get(new Configuration());
- baseDir = Files.createTempDir();
- LOGGER.info("BaseDir = " + baseDir);
- logDir = assertCreateDir(new File(baseDir, "log"));
- confDir = assertCreateDir(new File(baseDir, "etc"));
- dataDir = assertCreateDir(new File(baseDir, "data"));
- policyFile = new File(confDir, HiveServerFactory.AUTHZ_PROVIDER_FILENAME);
- hiveServer = HiveServerFactory.create(properties, baseDir, confDir, logDir, policyFile, fileSystem);
- hiveServer.start();
- return new Context(hiveServer, getFileSystem(),
- baseDir, confDir, dataDir, policyFile);
- }
-
- protected static File assertCreateDir(File dir) {
- if(!dir.isDirectory()) {
- Assert.assertTrue("Failed creating " + dir, dir.mkdirs());
- }
- return dir;
- }
-
- protected FileSystem getFileSystem() {
- return fileSystem;
- }
-
- @After
- public void tearDownWithHiveServer() throws Exception {
- if(hiveServer != null) {
- hiveServer.shutdown();
- hiveServer = null;
- }
- if(baseDir != null) {
- if(System.getProperty(HiveServerFactory.KEEP_BASEDIR) == null) {
- FileUtils.deleteQuietly(baseDir);
- }
- baseDir = null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticConfiguration.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticConfiguration.java
deleted file mode 100644
index 40232c8..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticConfiguration.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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;
-
-import java.io.File;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.Statement;
-import java.util.Map;
-
-import junit.framework.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServer;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServerFactory;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Maps;
-import com.google.common.io.Files;
-
-public abstract class AbstractTestWithStaticConfiguration {
- private static final Logger LOGGER = LoggerFactory
- .getLogger(AbstractTestWithStaticConfiguration.class);
- protected static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
- protected static final String ADMIN1 = "admin1";
- protected static final String ALL_DB1 = "server=server1->db=db_1",
- ALL_DB2 = "server=server1->db=db_2",
- SELECT_DB1_TBL1 = "server=server1->db=db_1->table=tb_1->action=select",
- SELECT_DB1_TBL2 = "server=server1->db=db_1->table=tb_2->action=select",
- SELECT_DB1_NONTABLE = "server=server1->db=db_1->table=this table does not exist->action=select",
- INSERT_DB1_TBL1 = "server=server1->db=db_1->table=tb_1->action=insert",
- INSERT_DB1_TBL2 = "server=server1->db=db_1->table=tb_2->action=insert",
- SELECT_DB2_TBL2 = "server=server1->db=db_2->table=tb_2->action=select",
- INSERT_DB2_TBL1 = "server=server1->db=db_2->table=tb_1->action=insert",
- SELECT_DB1_VIEW1 = "server=server1->db=db_1->table=view_1->action=select",
- USER1 = "user1",
- USER2 = "user2",
- GROUP1 = "group1",
- GROUP1_ROLE = "group1_role",
- DB1 = "db_1",
- DB2 = "db_2",
- DB3 = "db_3",
- TBL1 = "tb_1",
- TBL2 = "tb_2",
- TBL3 = "tb_3",
- VIEW1 = "view_1",
- VIEW2 = "view_2",
- VIEW3 = "view_3",
- INDEX1 = "index_1",
- INDEX2 = "index_2";
-
-
- protected static File baseDir;
- protected static File logDir;
- protected static File confDir;
- protected static File dataDir;
- protected static File policyFile;
- protected static HiveServer hiveServer;
- protected static FileSystem fileSystem;
- protected static Map<String, String> properties;
- protected Context context;
-
- public Context createContext() throws Exception {
- return new Context(hiveServer, fileSystem,
- baseDir, confDir, dataDir, policyFile);
- }
- protected void dropDb(String user, String...dbs) throws Exception {
- Connection connection = context.createConnection(user, "password");
- Statement statement = connection.createStatement();
- for(String db : dbs) {
- statement.execute("DROP DATABASE IF EXISTS " + db + " CASCADE");
- }
- statement.close();
- connection.close();
- }
- protected void createDb(String user, String...dbs) throws Exception {
- Connection connection = context.createConnection(user, "password");
- Statement statement = connection.createStatement();
- for(String db : dbs) {
- statement.execute("CREATE DATABASE " + db);
- }
- statement.close();
- connection.close();
- }
- protected void createTable(String user, String db, File dataFile, String...tables)
- throws Exception {
- Connection connection = context.createConnection(user, "password");
- 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();
- connection.close();
- }
-
- protected static File assertCreateDir(File dir) {
- if(!dir.isDirectory()) {
- Assert.assertTrue("Failed creating " + dir, dir.mkdirs());
- }
- return dir;
- }
-
- protected FileSystem getFileSystem() {
- return fileSystem;
- }
- @BeforeClass
- public static void setupTestStaticConfiguration()
- throws Exception {
- properties = Maps.newHashMap();
- baseDir = Files.createTempDir();
- LOGGER.info("BaseDir = " + baseDir);
- logDir = assertCreateDir(new File(baseDir, "log"));
- confDir = assertCreateDir(new File(baseDir, "etc"));
- dataDir = assertCreateDir(new File(baseDir, "data"));
- policyFile = new File(confDir, HiveServerFactory.AUTHZ_PROVIDER_FILENAME);
- }
-
- @AfterClass
- public static void tearDownTestStaticConfiguration() throws Exception {
- if(hiveServer != null) {
- hiveServer.shutdown();
- hiveServer = null;
- }
- if(baseDir != null) {
- if(System.getProperty(HiveServerFactory.KEEP_BASEDIR) == null) {
- FileUtils.deleteQuietly(baseDir);
- }
- baseDir = null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticDFS.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticDFS.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticDFS.java
deleted file mode 100644
index ab30fa5..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticDFS.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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;
-
-import java.io.File;
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hdfs.MiniDFSCluster;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServerFactory;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-
-public abstract class AbstractTestWithStaticDFS extends AbstractTestWithStaticConfiguration {
-
- protected static MiniDFSCluster dfsCluster;
- protected static Path dfsBaseDir;
-
- @Before
- public void setupTestWithDFS() throws IOException {
- Assert.assertTrue(dfsBaseDir.toString(), fileSystem.delete(dfsBaseDir, true));
- Assert.assertTrue(dfsBaseDir.toString(), fileSystem.mkdirs(dfsBaseDir));
- }
-
- protected static Path assertCreateDfsDir(Path dir) throws IOException {
- if(!fileSystem.isDirectory(dir)) {
- Assert.assertTrue("Failed creating " + dir, fileSystem.mkdirs(dir));
- }
- return dir;
- }
- @BeforeClass
- public static void setupTestWithStaticDFS()
- throws Exception {
- Configuration conf = new Configuration();
- File dfsDir = assertCreateDir(new File(baseDir, "dfs"));
- conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
- dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
- fileSystem = dfsCluster.getFileSystem();
- dfsBaseDir = assertCreateDfsDir(new Path(new Path(fileSystem.getUri()), "/base"));
- hiveServer = HiveServerFactory.create(properties, baseDir, confDir, logDir, policyFile, fileSystem);
- hiveServer.start();
- }
-
- @AfterClass
- public static void tearDownTestWithStaticDFS() throws Exception {
- if(dfsCluster != null) {
- dfsCluster.shutdown();
- dfsCluster = null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticLocalFS.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticLocalFS.java
deleted file mode 100644
index c29c16c..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/AbstractTestWithStaticLocalFS.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServerFactory;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractTestWithStaticLocalFS extends AbstractTestWithStaticConfiguration {
- @SuppressWarnings("unused")
- private static final Logger LOGGER = LoggerFactory
- .getLogger(AbstractTestWithStaticLocalFS.class);
- @BeforeClass
- public static void setupTestWithStaticHiveServer()
- throws Exception {
- fileSystem = FileSystem.get(new Configuration());
- hiveServer = HiveServerFactory.create(properties, baseDir, confDir, logDir, policyFile, fileSystem);
- hiveServer.start();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/Context.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/Context.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/Context.java
deleted file mode 100644
index 45ec493..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/Context.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.URI;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Set;
-
-import junit.framework.Assert;
-
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.sentry.tests.e2e.hiveserver.HiveServer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class Context {
-
- private static final Logger LOGGER = LoggerFactory
- .getLogger(Context.class);
-
- public static final String AUTHZ_EXCEPTION_SQL_STATE = "42000";
- public static final String AUTHZ_EXEC_HOOK_EXCEPTION_SQL_STATE = "08S01";
- public static final String AUTHZ_EXCEPTION_ERROR_MSG = "No valid privileges";
-
- private final HiveServer hiveServer;
- private final FileSystem fileSystem;
- private final File baseDir;
- private final File dataDir;
-
- private final File policyFile;
- private final Set<Connection> connections;
- private final Set<Statement> statements;
-
-
- public Context(HiveServer hiveServer, FileSystem fileSystem,
- File baseDir, File confDir, File dataDir, File policyFile) throws Exception {
- this.hiveServer = hiveServer;
- this.fileSystem = fileSystem;
- this.baseDir = baseDir;
- this.dataDir = dataDir;
- this.policyFile = policyFile;
- connections = Sets.newHashSet();
- statements = Sets.newHashSet();
- }
-
- public Connection createConnection(String username, String password) throws Exception {
- Connection connection = hiveServer.createConnection(username, password);
- connections.add(connection);
- assertNotNull("Connection is null", connection);
- assertFalse("Connection should not be closed", connection.isClosed());
- Statement statement = connection.createStatement();
- statement.close();
- return connection;
- }
-
- public Statement createStatement(Connection connection)
- throws Exception {
- Statement statement = connection.createStatement();
- assertNotNull("Statement is null", statement);
- statements.add(statement);
- return statement;
- }
- /**
- * Deprecated} use append()
- */
- public void writePolicyFile(String buf) throws IOException {
- FileOutputStream out = new FileOutputStream(policyFile);
- out.write(buf.getBytes(Charsets.UTF_8));
- out.close();
- }
- /**
- * Deprecated} use append()
- */
- @Deprecated
- public void appendToPolicyFileWithNewLine(String line) throws IOException {
- append(line);
- }
- public void append(String...lines) throws IOException {
- StringBuffer buffer = new StringBuffer();
- for(String line : lines) {
- buffer.append(line).append("\n");
- }
- Files.append(buffer, policyFile, Charsets.UTF_8);
- }
-
- public boolean deletePolicyFile() throws IOException {
- return policyFile.delete();
- }
- /**
- * Deprecated} use append()
- */
- public void makeNewPolicy(String policyLines[]) throws FileNotFoundException {
- PrintWriter policyWriter = new PrintWriter (policyFile.toString());
- for (String line : policyLines) {
- policyWriter.println(line);
- }
- policyWriter.close();
- assertFalse(policyWriter.checkError());
- }
-
- public void close() {
- for(Statement statement : statements) {
- try {
- statement.close();
- } catch (SQLException exception) {
- LOGGER.warn("Error closing " + statement, exception);
- }
- }
- statements.clear();
-
- for(Connection connection : connections) {
- try {
- connection.close();
- } catch (SQLException exception) {
- LOGGER.warn("Error closing " + connection, exception);
- }
- }
- connections.clear();
- }
-
- public void assertAuthzException(Statement statement, String query)
- throws SQLException {
- try {
- statement.execute(query);
- Assert.fail("Expected SQLException for '" + query + "'");
- } catch (SQLException e) {
- verifyAuthzException(e);
- }
- }
-
- public void assertAuthzExecHookException(Statement statement, String query)
- throws SQLException {
- try {
- statement.execute(query);
- Assert.fail("Expected SQLException for '" + query + "'");
- } catch (SQLException e) {
- verifyAuthzExecHookException(e);
- }
- }
-
-
- // verify that the sqlexception is due to authorization failure
- public void verifyAuthzException(SQLException sqlException) throws SQLException{
- verifyAuthzExceptionForState(sqlException, AUTHZ_EXCEPTION_SQL_STATE);
- }
-
- // verify that the sqlexception is due to authorization failure due to exec hooks
- public void verifyAuthzExecHookException(SQLException sqlException) throws SQLException{
- verifyAuthzExceptionForState(sqlException, AUTHZ_EXEC_HOOK_EXCEPTION_SQL_STATE);
- }
-
- // verify that the sqlexception is due to authorization failure
- private void verifyAuthzExceptionForState(SQLException sqlException,
- String expectedSqlState) throws SQLException {
- if (!expectedSqlState.equals(sqlException.getSQLState())) {
- throw sqlException;
- }
- }
-
- public File getBaseDir() {
- return baseDir;
- }
-
- public File getDataDir() {
- return dataDir;
- }
-
- public File getPolicyFile() {
- return policyFile;
- }
-
- @SuppressWarnings("static-access")
- public URI getDFSUri() throws IOException {
- return fileSystem.getDefaultUri(fileSystem.getConf());
- }
-
- public String getProperty(String propName) {
- return hiveServer.getProperty(propName);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/DummySentryOnFailureHook.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/DummySentryOnFailureHook.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/DummySentryOnFailureHook.java
deleted file mode 100644
index 87d1b01..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/DummySentryOnFailureHook.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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;
-
-import org.apache.sentry.binding.hive.SentryOnFailureHook;
-import org.apache.sentry.binding.hive.SentryOnFailureHookContext;
-
-public class DummySentryOnFailureHook implements SentryOnFailureHook {
-
- static boolean invoked = false;
-
- @Override
- public void run(SentryOnFailureHookContext failureHookContext)
- throws Exception {
- invoked = true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/PolicyFileEditor.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/PolicyFileEditor.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/PolicyFileEditor.java
deleted file mode 100644
index 69bf2ad..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/PolicyFileEditor.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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;
-
-
-
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-
-/**
- * Deprecated} use Context.append()
- */
-public class PolicyFileEditor {
-
- private static final String NL = System.getProperty("line.separator", "\n");
-
- private File policy;
-
- public PolicyFileEditor (File policy) throws IOException {
- policy.delete();
- policy.createNewFile();
- this.policy = policy;
- }
-
- public void clearOldPolicy() throws IOException {
- policy.delete();
- policy.createNewFile();
- }
-
- public void addPolicy(String line, String cat) throws IOException {
- List<String> result = new ArrayList<String>();
- boolean exist = false;
- for(String s : Files.readLines(policy, Charsets.UTF_8)) {
- result.add(s);
- if (s.equals("[" + cat + "]")) {
- result.add(line);
- exist = true;
- }
- }
- if (!exist) {
- result.add("[" + cat + "]");
- result.add(line);
- }
- Files.write(Joiner.on(NL).join(result), policy, Charsets.UTF_8);
- }
- public void removePolicy(String line) throws IOException {
- List<String> result = Lists.newArrayList();
- for(String s : Files.readLines(policy, Charsets.UTF_8)) {
- if (!s.equals(line)) {
- result.add(s);
- }
- }
- Files.write(Joiner.on(NL).join(result), policy, Charsets.UTF_8);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestCrossDbOps.java
----------------------------------------------------------------------
diff --git a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestCrossDbOps.java b/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestCrossDbOps.java
deleted file mode 100644
index c822863..0000000
--- a/sentry-tests/src/test/java/org/apache/sentry/tests/e2e/TestCrossDbOps.java
+++ /dev/null
@@ -1,691 +0,0 @@
-/*
- * 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;
-
-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.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.Assert;
-
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Resources;
-
-/* Tests privileges at table scope with cross database access */
-
-public class TestCrossDbOps extends AbstractTestWithStaticLocalFS {
- private File dataFile;
- private PolicyFile policyFile;
- private String loadData;
-
- @Before
- public void setup() throws Exception {
- context = createContext();
- File dataDir = context.getDataDir();
- // copy data file to test dir
- 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();
- policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
- loadData = "server=server1->uri=file://" + dataFile.getPath();
-
- }
-
- @After
- public void tearDown() throws Exception {
- if (context != null) {
- context.close();
- }
- }
-
- /*
- * Admin creates DB_1, DB2, tables (tab_1 ) and (tab_2, tab_3) in DB_1 and
- * DB_2 respectively. User user1 has select on DB_1.tab_1, insert on
- * DB2.tab_2 User user2 has select on DB2.tab_3 Test show database and show
- * tables for both user1 and user2
- */
- @Test
- public void testShowDatabasesAndShowTables() throws Exception {
- // edit policy file
- policyFile
- .addRolesToGroup("group1", "select_tab1", "insert_tab2")
- .addRolesToGroup("group2", "select_tab3")
- .addPermissionsToRole("select_tab1", "server=server1->db=db1->table=tab1->action=select")
- .addPermissionsToRole("select_tab3", "server=server1->db=db2->table=tab3->action=select")
- .addPermissionsToRole("insert_tab2", "server=server1->db=db2->table=tab2->action=insert")
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group2");
- policyFile.write(context.getPolicyFile());
-
- // admin create two databases
- Connection connection = context.createConnection(ADMIN1, "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB1 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB2 CASCADE");
-
- statement.execute("CREATE DATABASE DB1");
- statement.execute("CREATE DATABASE DB2");
- statement.execute("USE DB1");
- statement.execute("CREATE TABLE TAB1(id int)");
- statement.executeQuery("SHOW TABLES");
- statement.execute("USE DB2");
- statement.execute("CREATE TABLE TAB2(id int)");
- statement.execute("CREATE TABLE TAB3(id int)");
-
- // test show databases
- // show databases shouldn't filter any of the dbs from the resultset
- Connection conn = context.createConnection("user1", "");
- Statement stmt = context.createStatement(conn);
- ResultSet res = stmt.executeQuery("SHOW DATABASES");
- List<String> result = new ArrayList<String>();
- result.add("db1");
- result.add("db2");
- result.add("default");
-
- while (res.next()) {
- String dbName = res.getString(1);
- assertTrue(dbName, result.remove(dbName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- // test show tables
- stmt.execute("USE DB1");
- res = stmt.executeQuery("SHOW TABLES");
- result.clear();
- result.add("tab1");
-
- while (res.next()) {
- String tableName = res.getString(1);
- assertTrue(tableName, result.remove(tableName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- stmt.execute("USE DB2");
- res = stmt.executeQuery("SHOW TABLES");
- result.clear();
- result.add("tab2");
-
- while (res.next()) {
- String tableName = res.getString(1);
- assertTrue(tableName, result.remove(tableName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- stmt.close();
- conn.close();
-
- // test show databases and show tables for user2
- conn = context.createConnection("user2", "");
- stmt = context.createStatement(conn);
- res = stmt.executeQuery("SHOW DATABASES");
- result.clear();
- result.add("db2");
- result.add("default");
-
- while (res.next()) {
- String dbName = res.getString(1);
- assertTrue(dbName, result.remove(dbName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- // test show tables
- stmt.execute("USE DB2");
- res = stmt.executeQuery("SHOW TABLES");
- result.clear();
- result.add("tab3");
-
- while (res.next()) {
- String tableName = res.getString(1);
- assertTrue(tableName, result.remove(tableName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- try {
- stmt.execute("USE DB1");
- Assert.fail("Expected SQL exception");
- } catch (SQLException e) {
- context.verifyAuthzException(e);
- }
- context.close();
- }
-
- /*
- * Admin creates DB_1, DB2, tables (tab_1 ) and (tab_2, tab_3) in DB_1 and
- * DB_2 respectively. User user1 has select on DB_1.tab_1, insert on
- * DB2.tab_2 User user2 has select on DB2.tab_3 Test show database and show
- * tables for both user1 and user2
- */
- @Test
- public void testJDBCGetSchemasAndGetTables() throws Exception {
- // edit policy file
- policyFile.addRolesToGroup("group1", "select_tab1", "insert_tab2")
- .addRolesToGroup("group2", "select_tab3")
- .addPermissionsToRole("select_tab1", "server=server1->db=db1->table=tab1->action=select")
- .addPermissionsToRole("select_tab3", "server=server1->db=db2->table=tab3->action=select")
- .addPermissionsToRole("insert_tab2", "server=server1->db=db2->table=tab2->action=insert")
- .addGroupsToUser("user1", "group1")
- .addGroupsToUser("user2", "group2");
- policyFile.write(context.getPolicyFile());
-
- // admin create two databases
- Connection connection = context.createConnection(ADMIN1, "foo");
- Statement statement = context.createStatement(connection);
- statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB1 CASCADE");
- statement.execute("DROP DATABASE IF EXISTS DB2 CASCADE");
-
- statement.execute("CREATE DATABASE DB1");
- statement.execute("CREATE DATABASE DB2");
- statement.execute("USE DB1");
- statement.execute("CREATE TABLE TAB1(id int)");
- statement.executeQuery("SHOW TABLES");
- statement.execute("USE DB2");
- statement.execute("CREATE TABLE TAB2(id int)");
- statement.execute("CREATE TABLE TAB3(id int)");
-
- // test show databases
- // show databases shouldn't filter any of the dbs from the resultset
- Connection conn = context.createConnection("user1", "");
- List<String> result = new ArrayList<String>();
-
- // test direct JDBC metadata API
- ResultSet res = conn.getMetaData().getSchemas();
- ResultSetMetaData resMeta = res.getMetaData();
- assertEquals(2, resMeta.getColumnCount());
- assertEquals("TABLE_SCHEM", resMeta.getColumnName(1));
- assertEquals("TABLE_CATALOG", resMeta.getColumnName(2));
-
- result.add("db1");
- result.add("db2");
- result.add("default");
-
- while (res.next()) {
- String dbName = res.getString(1);
- assertTrue(dbName, result.remove(dbName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- // test direct JDBC metadata API
- res = conn.getMetaData().getTables(null, "DB1", "tab%", null);
- result.add("tab1");
-
- while (res.next()) {
- String tableName = res.getString(3);
- assertTrue(tableName, result.remove(tableName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- // test direct JDBC metadata API
- res = conn.getMetaData().getTables(null, "DB2", "tab%", null);
- result.add("tab2");
-
- while (res.next()) {
- String tableName = res.getString(3);
- assertTrue(tableName, result.remove(tableName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- res = conn.getMetaData().getTables(null, "DB%", "tab%", null);
- result.add("tab2");
- result.add("tab1");
-
- while (res.next()) {
- String tableName = res.getString(3);
- assertTrue(tableName, result.remove(tableName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- //test show columns
- res = conn.getMetaData().getColumns(null, "DB%", "tab%","i%" );
- result.add("id");
- result.add("id");
-
- while (res.next()) {
- String columnName = res.getString(4);
- assertTrue(columnName, result.remove(columnName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- conn.close();
-
- // test show databases and show tables for user2
- conn = context.createConnection("user2", "");
-
- // test direct JDBC metadata API
- res = conn.getMetaData().getSchemas();
- resMeta = res.getMetaData();
- assertEquals(2, resMeta.getColumnCount());
- assertEquals("TABLE_SCHEM", resMeta.getColumnName(1));
- assertEquals("TABLE_CATALOG", resMeta.getColumnName(2));
-
- result.add("db2");
- result.add("default");
-
- while (res.next()) {
- String dbName = res.getString(1);
- assertTrue(dbName, result.remove(dbName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- // test JDBC direct API
- res = conn.getMetaData().getTables(null, "DB%", "tab%", null);
- result.add("tab3");
-
- while (res.next()) {
- String tableName = res.getString(3);
- assertTrue(tableName, result.remove(tableName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- //test show columns
- res = conn.getMetaData().getColumns(null, "DB%", "tab%","i%" );
- result.add("id");
-
- while (res.next()) {
- String columnName = res.getString(4);
- assertTrue(columnName, result.remove(columnName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- //test show columns
- res = conn.getMetaData().getColumns(null, "DB1", "tab%","i%" );
-
- while (res.next()) {
- String columnName = res.getString(4);
- assertTrue(columnName, result.remove(columnName));
- }
- assertTrue(result.toString(), result.isEmpty());
- res.close();
-
- context.close();
- }
-
- /**
- * 2.8 admin user create two database, DB_1, DB_2 admin grant all to USER1,
- * USER2 on DB_1, admin grant all to user1's group, user2's group on DB_2
- * positive test case: user1, user2 has ALL privilege on both DB_1 and DB_2
- * negative test case: user1, user2 don't have ALL privilege on SERVER
- */
- @Test
- public void testDbPrivileges() throws Exception {
- // edit policy file
- policyFile.addRolesToGroup("user_group", "db1_all,db2_all, load_data")
- .addPermissionsToRole("db1_all", "server=server1->db=" + DB1)
- .addPermissionsToRole("db2_all", "server=server1->db=" + DB2)
- .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
- .addGroupsToUser("user1", "user_group")
- .addGroupsToUser("user2", "user_group");
- policyFile.write(context.getPolicyFile());
-
- dropDb(ADMIN1, DB1, DB2);
- createDb(ADMIN1, DB1, DB2);
- for (String user : new String[]{USER1, USER2}) {
- for (String dbName : new String[]{DB1, DB2}) {
- Connection userConn = context.createConnection(user, "foo");
- String tabName = user + "_tab1";
- Statement userStmt = context.createStatement(userConn);
- // Positive case: test user1 and user2 has permissions to access
- // db1 and
- // db2
- userStmt
- .execute("create table " + dbName + "." + tabName + " (id int)");
- userStmt.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath()
- + "' INTO TABLE " + dbName + "." + tabName);
- userStmt.execute("select * from " + dbName + "." + tabName);
- context.close();
- }
- }
- }
-
- /**
- * Test Case 2.11 admin user create a new database DB_1 and grant ALL to
- * himself on DB_1 should work
- */
- @Test
- public void testAdminDbPrivileges() throws Exception {
- policyFile.write(context.getPolicyFile());
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- Connection adminCon = context.createConnection(ADMIN1, "password");
- Statement adminStmt = context.createStatement(adminCon);
- String tabName = DB1 + "." + "admin_tab1";
- adminStmt.execute("create table " + tabName + "(c1 string)");
- adminStmt.execute("load data local inpath '" + dataFile.getPath() + "' into table "
- + tabName);
- assertTrue(adminStmt.executeQuery("select * from " + tabName).next());
- adminStmt.close();
- adminCon.close();
- }
-
- /**
- * Test Case 2.14 admin user create a new database DB_1 create TABLE_1 in DB_1
- * admin user grant INSERT to user1's group on TABLE_1 negative test case:
- * user1 try to do following on TABLE_1 will fail: --explain --analyze
- * --describe --describe function --show columns --show table status --show
- * table properties --show create table --show partitions --show indexes
- * --select * from TABLE_1.
- */
- @Test
- public void testNegativeUserPrivileges() throws Exception {
- // edit policy file
- policyFile.addRolesToGroup("user_group", "db1_tab1_insert", "db1_tab2_all")
- .addPermissionsToRole("db1_tab2_all", "server=server1->db=db1->table=table_2")
- .addPermissionsToRole("db1_tab1_insert", "server=server1->db=db1->table=table_1->action=insert")
- .addGroupsToUser("user3", "user_group");
- policyFile.write(context.getPolicyFile());
-
- Connection adminCon = context.createConnection(ADMIN1, "foo");
- Statement adminStmt = context.createStatement(adminCon);
- String dbName = "db1";
- adminStmt.execute("use default");
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.execute("create table " + dbName + ".table_1 (id int)");
- adminStmt.close();
- adminCon.close();
- Connection userConn = context.createConnection("user3", "foo");
- Statement userStmt = context.createStatement(userConn);
- context.assertAuthzException(userStmt, "select * from " + dbName + ".table_1");
- userConn.close();
- userStmt.close();
- }
-
- /**
- * Test Case 2.16 admin user create a new database DB_1 create TABLE_1 and
- * TABLE_2 (same schema) in DB_1 admin user grant SELECT, INSERT to user1's
- * group on TABLE_2 negative test case: user1 try to do following on TABLE_1
- * will fail: --insert overwrite TABLE_2 select * from TABLE_1
- */
- @Test
- public void testNegativeUserDMLPrivileges() throws Exception {
- policyFile
- .addPermissionsToRole("db1_tab2_all", "server=server1->db=db1->table=table_2")
- .addRolesToGroup("group1", "db1_tab2_all")
- .addGroupsToUser("user3", "group1");
- policyFile.write(context.getPolicyFile());
-
- dropDb(ADMIN1, DB1);
- createDb(ADMIN1, DB1);
- Connection adminCon = context.createConnection(ADMIN1, "password");
- Statement adminStmt = context.createStatement(adminCon);
- adminStmt.execute("create table " + DB1 + ".table_1 (id int)");
- adminStmt.execute("create table " + DB1 + ".table_2 (id int)");
- adminStmt.close();
- adminCon.close();
- Connection userConn = context.createConnection("user3", "foo");
- Statement userStmt = context.createStatement(userConn);
- context.assertAuthzException(userStmt, "insert overwrite table " + DB1
- + ".table_2 select * from " + DB1 + ".table_1");
- context.assertAuthzException(userStmt, "insert overwrite directory '" + dataDir.getPath()
- + "' select * from " + DB1 + ".table_1");
- userStmt.close();
- userConn.close();
- }
-
- /**
- * Test Case 2.17 Execution steps
- * a) Admin user creates a new database DB_1,
- * b) Admin user grants ALL on DB_1 to group GROUP_1
- * c) User from GROUP_1 creates table TAB_1, TAB_2 in DB_1
- * d) Admin user grants SELECT on TAB_1 to group GROUP_2
- *
- * 1) verify users from GROUP_2 have only SELECT privileges on TAB_1. They
- * shouldn't be able to perform any operation other than those listed as
- * requiring SELECT in the privilege model.
- *
- * 2) verify users from GROUP_2 can't perform queries involving join between
- * TAB_1 and TAB_2.
- *
- * 3) verify users from GROUP_1 can't perform operations requiring ALL @
- * SERVER scope. Refer to list
- */
- @Test
- public void testNegUserPrivilegesAll() throws Exception {
-
- policyFile
- .addRolesToGroup("user_group1", "db1_all")
- .addRolesToGroup("user_group2", "db1_tab1_select")
- .addPermissionsToRole("db1_all", "server=server1->db=db1")
- .addPermissionsToRole("db1_tab1_select", "server=server1->db=db1->table=table_1->action=select")
- .addGroupsToUser("user1", "user_group1")
- .addGroupsToUser("user2", "user_group2");
- policyFile.write(context.getPolicyFile());
-
- // create dbs
- Connection adminCon = context.createConnection(ADMIN1, "foo");
- Statement adminStmt = context.createStatement(adminCon);
- String dbName = "db1";
- adminStmt.execute("use default");
- adminStmt.execute("create table table_def (name string)");
- adminStmt
- .execute("load data local inpath '" + dataFile.getPath() + "' into table table_def");
-
- adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
- adminStmt.execute("CREATE DATABASE " + dbName);
- adminStmt.execute("use " + dbName);
-
- adminStmt.execute("create table table_1 (name string)");
- adminStmt
- .execute("load data local inpath '" + dataFile.getPath() + "' into table table_1");
- adminStmt.execute("create table table_2 (name string)");
- adminStmt
- .execute("load data local inpath '" + dataFile.getPath() + "' into table table_2");
- adminStmt.execute("create view v1 AS select * from table_1");
- adminStmt
- .execute("create table table_part_1 (name string) PARTITIONED BY (year INT)");
- adminStmt.execute("ALTER TABLE table_part_1 ADD PARTITION (year = 2012)");
-
- adminStmt.close();
- adminCon.close();
-
- Connection userConn = context.createConnection("user2", "foo");
- Statement userStmt = context.createStatement(userConn);
-
- context.assertAuthzException(userStmt, "drop database " + dbName);
-
- // Hive currently doesn't support cross db index DDL
-
- context.assertAuthzException(userStmt, "CREATE TEMPORARY FUNCTION strip AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
- context.assertAuthzException(userStmt, "create table " + dbName
- + ".c_tab_2 as select * from " + dbName + ".table_2");
- context.assertAuthzException(userStmt, "select * from " + dbName + ".table_2");
- context.assertAuthzException(userStmt, "ALTER DATABASE " + dbName
- + " SET DBPROPERTIES ('foo' = 'bar')");
- context.assertAuthzException(userStmt, "drop table " + dbName + ".table_1");
- context.assertAuthzException(userStmt, "DROP VIEW IF EXISTS " + dbName + ".v1");
- context.assertAuthzException(userStmt, "create table " + dbName + ".table_5 (name string)");
- context.assertAuthzException(userStmt, "ALTER TABLE " + dbName + ".table_1 RENAME TO "
- + dbName + ".table_99");
- context.assertAuthzException(userStmt, "insert overwrite table " + dbName
- + ".table_2 select * from " + dbName + ".table_1");
- context.assertAuthzException(userStmt, "insert overwrite table " + dbName
- + ".table_2 select * from " + "table_def");
- context.assertAuthzException(userStmt, "ALTER TABLE " + dbName
- + ".table_part_1 ADD IF NOT EXISTS PARTITION (year = 2012)");
- context.assertAuthzException(userStmt, "ALTER TABLE " + dbName
- + ".table_part_1 PARTITION (year = 2012) SET LOCATION '/etc'");
- userStmt.close();
- userConn.close();
- }
-
- /**
- * Steps: 1. admin user create databases, DB_1 and DB_2, no table or other
- * object in database
- * 2. admin grant all to user1's group on DB_1 and DB_2
- * positive test case:
- * a)user1 has the privilege to create table, load data,
- * drop table, create view, insert more data on both databases
- * b) user1 can switch between DB_1 and DB_2 without exception
- * negative test case:
- * c) user1 cannot drop database
- */
- @Test
- public void testSandboxOpt9() throws Exception {
- policyFile
- .addPermissionsToRole(GROUP1_ROLE, ALL_DB1, ALL_DB2, loadData)
- .addRolesToGroup(GROUP1, GROUP1_ROLE)
- .addGroupsToUser(USER1, GROUP1);
- policyFile.write(context.getPolicyFile());
-
- dropDb(ADMIN1, DB1, DB2);
- createDb(ADMIN1, DB1, DB2);
-
- Connection connection = context.createConnection(USER1, "password");
- Statement statement = context.createStatement(connection);
-
- // a
- statement.execute("DROP TABLE IF EXISTS " + DB1 + "." + TBL1);
- statement.execute("create table " + DB1 + "." + TBL1
- + " (under_col int comment 'the under column', value string)");
- statement.execute("load data local inpath '" + dataFile.getPath()
- + "' into table " + DB1 + "." + TBL1);
- statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW1);
- statement.execute("CREATE VIEW " + DB1 + "." + VIEW1
- + " (value) AS SELECT value from " + DB1 + "." + TBL1
- + " LIMIT 10");
- statement.execute("DROP TABLE IF EXISTS " + DB2 + "." + TBL1);
- statement.execute("CREATE TABLE " + DB2 + "." + TBL1
- + " AS SELECT value from " + DB1 + "." + TBL1
- + " LIMIT 10");
-
- // b
- statement.execute("DROP TABLE IF EXISTS " + DB2 + "." + TBL2);
- statement.execute("create table " + DB2 + "." + TBL2
- + " (under_col int comment 'the under column', value string)");
- statement.execute("load data local inpath '" + dataFile.getPath()
- + "' into table " + DB2 + "." + TBL2);
- statement.execute("DROP TABLE IF EXISTS " + DB2 + "." + TBL3);
- statement.execute("create table " + DB2 + "." + TBL3
- + " (under_col int comment 'the under column', value string)");
- statement.execute("load data local inpath '" + dataFile.getPath()
- + "' into table " + DB2 + "." + TBL3);
-
- // c
- context.assertAuthzException(statement, "DROP DATABASE IF EXISTS " + DB1);
- context.assertAuthzException(statement, "DROP DATABASE IF EXISTS " + DB2);
-
- policyFile.removePermissionsFromRole(GROUP1_ROLE, ALL_DB2);
- policyFile.write(context.getPolicyFile());
-
- // create db1.view1 as select from db2.tbl2
- statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW2);
- context.assertAuthzException(statement, "CREATE VIEW " + DB1 + "." + VIEW2 +
- " (value) AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
- // create db1.tbl2 as select from db2.tbl2
- statement.execute("DROP TABLE IF EXISTS " + DB1 + "." + TBL2);
- context.assertAuthzException(statement, "CREATE TABLE " + DB1 + "." + TBL2 +
- " AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
-
-
-
- statement.close();
- connection.close();
- }
-
- /**
- * Steps: 1. admin user create databases, DB_1 and DB_2, no table or other
- * object in database positive test case:
- * d) user1 has the privilege to create view on tables in DB_1 negative test case:
- * e) user1 cannot create view in DB_1 that select from tables in DB_2
- * with no select privilege 2.
- * positive test case:
- * f) user1 has the privilege to create view to select from DB_1.tb_1
- * and DB_2.tb_2 negative test case:
- * g) user1 cannot create view to select from DB_1.tb_1 and DB_2.tb_3
- */
- @Test
- public void testCrossDbViewOperations() throws Exception {
- // edit policy file
- policyFile
- .addRolesToGroup("group1", "all_db1", "load_data", "select_tb2")
- .addPermissionsToRole("all_db1", "server=server1->db=db_1")
- .addPermissionsToRole("all_db2", "server=server1->db=db_2")
- .addPermissionsToRole("select_tb2", "server=server1->db=db_2->table=tb_1->action=select")
- .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
- .addGroupsToUser("user1", "group1");
- policyFile.write(context.getPolicyFile());
-
- // admin create two databases
- dropDb(ADMIN1, DB1, DB2);
- createDb(ADMIN1, DB1, DB2);
- Connection connection = context.createConnection(ADMIN1, "password");
- Statement statement = context.createStatement(connection);
- statement
- .execute("CREATE TABLE " + DB1 + "." + TBL1 + "(id int)");
- statement
- .execute("CREATE TABLE " + DB2 + "." + TBL1 + "(id int)");
- statement
- .execute("CREATE TABLE " + DB2 + "." + TBL2 + "(id int)");
- context.close();
-
- connection = context.createConnection("user1", "foo");
- statement = context.createStatement(connection);
-
- // d
- statement.execute("DROP TABLE IF EXISTS " + DB1 + "." + TBL1);
- statement.execute("create table " + DB1 + "." + TBL1
- + " (under_col int comment 'the under column', value string)");
-
- // e
- statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW1);
- context.assertAuthzException(statement, "CREATE VIEW " + DB1 + "." + VIEW1
- + " (value) AS SELECT value from " + DB2 + "." + TBL2
- + " LIMIT 10");
- // f
- statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW2);
- statement.execute("CREATE VIEW " + DB1 + "." + VIEW2
- + " (value) AS SELECT value from " + DB1 + "." + TBL1
- + " LIMIT 10");
-
- // g
- statement.execute("DROP VIEW IF EXISTS " + DB1 + "." + VIEW3);
- context.assertAuthzException(statement, "CREATE VIEW " + DB1 + "." + VIEW3
- + " (value) AS SELECT value from " + DB2 + "." + TBL2
- + " LIMIT 10");
- }
-}
[6/9] SENTRY-16: Move sentry-tests to sentry-tests-hive package
(Gregory Chanan via Shreepadma Venugopalan)
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestSandboxOps.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestSandboxOps.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestSandboxOps.java
new file mode 100644
index 0000000..63778a7
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestSandboxOps.java
@@ -0,0 +1,585 @@
+/*
+ * 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.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.hadoop.fs.Path;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
+import com.google.common.io.Files;
+import com.google.common.io.Resources;
+
+public class TestSandboxOps extends AbstractTestWithStaticDFS {
+ private PolicyFile policyFile;
+ private File dataFile;
+ private String loadData;
+ private static final String DB2_POLICY_FILE = "db2-policy-file.ini";
+
+
+ @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();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ loadData = "server=server1->uri=file://" + dataFile.getPath();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+ private PolicyFile addTwoUsersWithAllDb() {
+ policyFile
+ .addGroupsToUser("user1", "user_group")
+ .addGroupsToUser("user2", "user_group")
+ .addPermissionsToRole("db1_all", "server=server1->db=db1")
+ .addPermissionsToRole("db2_all", "server=server1->db=db2")
+ .addRolesToGroup("user_group", "db1_all", "db2_all");
+ return policyFile;
+ }
+ /**
+ * Tests to ensure that users with all@db can create tables
+ * and that they cannot create databases or load data
+ */
+ @Test
+ public void testDbPrivileges() throws Exception {
+ addTwoUsersWithAllDb().write(context.getPolicyFile());
+ String[] dbs = new String[] { "db1", "db2" };
+ for (String dbName : dbs) {
+ dropDb(ADMIN1, dbName);
+ createDb(ADMIN1, dbName);
+ }
+ for (String user : new String[] { "user1", "user2" }) {
+ for (String dbName : new String[] { "db1", "db2" }) {
+ Connection userConn = context.createConnection(user, "foo");
+ String tabName = user + "_tab1";
+ Statement userStmt = context.createStatement(userConn);
+ // Positive case: test user1 and user2 has
+ // permissions to access db1 and db2
+ userStmt.execute("use " + dbName);
+ userStmt.execute("create table " + tabName + " (id int)");
+ context.assertAuthzException(userStmt, "load data local inpath '" + dataFile + "' into table " + tabName);
+ assertTrue(userStmt.execute("select * from " + tabName));
+ // negative users cannot create databases
+ context.assertAuthzException(userStmt, "CREATE DATABASE " + user + "_db");
+ userStmt.close();
+ userConn.close();
+ }
+ }
+
+ for (String dbName : dbs) {
+ dropDb(ADMIN1, dbName);
+ }
+
+ }
+ /**
+ * Test Case 2.11 admin user create a new database DB_1 and grant ALL to
+ * himself on DB_1 should work
+ */
+ @Test
+ public void testAdminDbPrivileges() throws Exception {
+ policyFile.write(context.getPolicyFile());
+ Connection adminCon = context.createConnection(ADMIN1, "password");
+ Statement adminStmt = context.createStatement(adminCon);
+ String dbName = "db1";
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+
+ // access the new databases
+ adminStmt.execute("use " + dbName);
+ String tabName = "admin_tab1";
+ adminStmt.execute("create table " + tabName + "(c1 string)");
+ adminStmt.execute("load data local inpath '" + dataFile.getPath() + "' into table "
+ + tabName);
+ adminStmt.execute("select * from " + tabName);
+
+ // cleanup
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE " + dbName + " CASCADE");
+ adminStmt.close();
+ adminCon.close();
+ }
+
+ /**
+ * Test Case 2.16 admin user create a new database DB_1 create TABLE_1 and
+ * TABLE_2 (same schema) in DB_1 admin user grant SELECT, INSERT to user1's
+ * group on TABLE_2 negative test case: user1 try to do following on TABLE_1
+ * will fail: --insert overwrite TABLE_2 select * from TABLE_1
+ */
+ @Test
+ public void testNegativeUserDMLPrivileges() throws Exception {
+ policyFile
+ .addPermissionsToRole("db1_tab2_all", "server=server1->db=db1->table=table_2")
+ .addRolesToGroup("group1", "db1_tab2_all")
+ .addGroupsToUser("user3", "group1");
+ policyFile.write(context.getPolicyFile());
+ Connection adminCon = context.createConnection(ADMIN1, "password");
+ Statement adminStmt = context.createStatement(adminCon);
+ String dbName = "db1";
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.execute("use " + dbName);
+ adminStmt.execute("create table table_1 (id int)");
+ adminStmt.execute("create table table_2 (id int)");
+ adminStmt.close();
+ adminCon.close();
+ Connection userConn = context.createConnection("user3", "password");
+ Statement userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ // user3 doesn't have select privilege on table_1, so insert/select should fail
+ context.assertAuthzException(userStmt, "insert overwrite table table_2 select * from table_1");
+ context.assertAuthzException(userStmt, "insert overwrite directory '" + baseDir.getPath() + "' select * from table_1");
+ userConn.close();
+ userStmt.close();
+ }
+
+ /**
+ * Test Case 2.17 Execution steps a) Admin user creates a new database DB_1,
+ * b) Admin user grants ALL on DB_1 to group GROUP_1 c) User from GROUP_1
+ * creates table TAB_1, TAB_2 in DB_1 d) Admin user grants SELECT on TAB_1 to
+ * group GROUP_2
+ *
+ * 1) verify users from GROUP_2 have only SELECT privileges on TAB_1. They
+ * shouldn't be able to perform any operation other than those listed as
+ * requiring SELECT in the privilege model.
+ *
+ * 2) verify users from GROUP_2 can't perform queries involving join between
+ * TAB_1 and TAB_2.
+ *
+ * 3) verify users from GROUP_1 can't perform operations requiring ALL @
+ * SERVER scope. Refer to list
+ */
+ @Test
+ public void testNegUserPrivilegesAll() throws Exception {
+ policyFile
+ .addRolesToGroup("user_group1", "db1_all")
+ .addRolesToGroup("user_group2", "db1_tab1_select")
+ .addPermissionsToRole("db1_tab1_select", "server=server1->db=db1->table=table_1->action=select")
+ .addPermissionsToRole("db1_all", "server=server1->db=db1")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .write(context.getPolicyFile());
+ // create dbs
+ Connection adminCon = context.createConnection("admin1", "foo");
+ Statement adminStmt = context.createStatement(adminCon);
+ String dbName = "db1";
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.execute("use " + dbName);
+ adminStmt.execute("create table table_1 (name string)");
+ adminStmt.execute("load data local inpath '" + dataFile.getPath() + "' into table table_1");
+ adminStmt.execute("create table table_2 (name string)");
+ adminStmt.execute("load data local inpath '" + dataFile.getPath() + "' into table table_2");
+ adminStmt.execute("create view v1 AS select * from table_1");
+ adminStmt.execute("create table table_part_1 (name string) PARTITIONED BY (year INT)");
+ adminStmt.execute("ALTER TABLE table_part_1 ADD PARTITION (year = 2012)");
+ adminStmt.execute("ALTER TABLE table_1 SET TBLPROPERTIES (\"createTime\"=\"1375824555\")");
+ adminStmt.close();
+ adminCon.close();
+
+ Connection userConn = context.createConnection("user2", "foo");
+ Statement userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+
+ context.assertAuthzException(userStmt, "alter table table_2 add columns (id int)");
+ context.assertAuthzException(userStmt, "drop database " + dbName);
+ context.assertAuthzException(userStmt, "CREATE INDEX x ON TABLE table_1(name) AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'");
+ context.assertAuthzException(userStmt, "CREATE TEMPORARY FUNCTION strip AS 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFPrintf'");
+ context.assertAuthzException(userStmt, "create table foo(id int)");
+ context.assertAuthzException(userStmt, "create table c_tab_2 as select * from table_2"); // no select or create privilege
+ context.assertAuthzException(userStmt, "create table c_tab_1 as select * from table_1"); // no create privilege
+ context.assertAuthzException(userStmt, "ALTER DATABASE " + dbName + " SET DBPROPERTIES ('foo' = 'bar')");
+ context.assertAuthzException(userStmt, "ALTER VIEW v1 SET TBLPROPERTIES ('foo' = 'bar')");
+ context.assertAuthzException(userStmt, "DROP VIEW IF EXISTS v1");
+ context.assertAuthzException(userStmt, "create table table_5 (name string)");
+ context.assertAuthzException(userStmt, "ALTER TABLE table_1 RENAME TO table_99");
+ context.assertAuthzException(userStmt, "insert overwrite table table_2 select * from table_1");
+ context.assertAuthzException(userStmt, "ALTER TABLE table_part_1 ADD IF NOT EXISTS PARTITION (year = 2012)");
+ context.assertAuthzException(userStmt, "ALTER TABLE table_part_1 PARTITION (year = 2012) SET LOCATION '" + baseDir.getPath() + "'");
+ context.assertAuthzException(userStmt, "ALTER TABLE table_1 SET TBLPROPERTIES (\"createTime\"=\"1375824555\")");
+ }
+
+ /**
+ * Steps:
+ * 1. admin user create databases, DB_1 and DB_2, no table or other
+ * object in database
+ * 2. admin grant all to user1's group on DB_1 and DB_2
+ * positive test case:
+ * a)user1 has the privilege to create table, load data,
+ * drop table, create view, insert more data on both databases
+ * b) user1 can switch between DB_1 and DB_2 without
+ * exception negative test case:
+ * c) user1 cannot drop database
+ * 3. admin remove all to group1 on DB_2
+ * positive test case:
+ * d) user1 has the privilege to create view on tables in DB_1
+ * negative test case:
+ * e) user1 cannot create view on tables in DB_1 that select
+ * from tables in DB_2
+ * 4. admin grant select to group1 on DB_2.ta_2
+ * positive test case:
+ * f) user1 has the privilege to create view to select from
+ * DB_1.tb_1 and DB_2.tb_2
+ * negative test case:
+ * g) user1 cannot create view to select from DB_1.tb_1
+ * and DB_2.tb_3
+ * @throws Exception
+ */
+ @Test
+ public void testSandboxOpt9() throws Exception {
+
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, ALL_DB1, ALL_DB2, loadData)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1);
+ policyFile.write(context.getPolicyFile());
+
+ dropDb(ADMIN1, DB1, DB2);
+ createDb(ADMIN1, DB1, DB2);
+
+ Connection connection = context.createConnection(USER1, "password");
+ Statement statement = context.createStatement(connection);
+
+ // a
+ statement.execute("USE " + DB1);
+ createTable(USER1, DB1, dataFile, TBL1);
+ statement.execute("DROP VIEW IF EXISTS " + VIEW1);
+ statement.execute("CREATE VIEW " + VIEW1 + " (value) AS SELECT value from " + TBL1 + " LIMIT 10");
+
+ createTable(USER1, DB2, dataFile, TBL2, TBL3);
+ // c
+ context.assertAuthzException(statement, "DROP DATABASE IF EXISTS " + DB1 + " CASCADE");
+ context.assertAuthzException(statement, "DROP DATABASE IF EXISTS " + DB2 + " CASCADE");
+ // d
+ statement.execute("USE " + DB1);
+ policyFile.removePermissionsFromRole(GROUP1_ROLE, ALL_DB2);
+ policyFile.write(context.getPolicyFile());
+ // e
+ // create db1.view1 as select from db2.tbl2
+ statement.execute("DROP VIEW IF EXISTS " + VIEW2);
+ context.assertAuthzException(statement, "CREATE VIEW " + VIEW2 +
+ " (value) AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
+ // create db1.tbl2 as select from db2.tbl2
+ statement.execute("DROP TABLE IF EXISTS " + TBL2);
+ context.assertAuthzException(statement, "CREATE TABLE " + TBL2 +
+ " AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
+ context.assertAuthzException(statement, "CREATE TABLE " + DB2 + "." + TBL2 +
+ " AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
+
+ // f
+ policyFile.addPermissionsToRole(GROUP1_ROLE, SELECT_DB2_TBL2);
+ policyFile.write(context.getPolicyFile());
+ statement.execute("DROP VIEW IF EXISTS " + VIEW2);
+ statement.execute("CREATE VIEW " + VIEW2
+ + " (value) AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
+
+ // g
+ statement.execute("DROP VIEW IF EXISTS " + VIEW3);
+ context.assertAuthzException(statement, "CREATE VIEW " + VIEW3
+ + " (value) AS SELECT value from " + DB2 + "." + TBL3 + " LIMIT 10");
+ statement.close();
+ connection.close();
+ dropDb(ADMIN1, DB1, DB2);
+ }
+
+ /**
+ * Tests select on table with index.
+ *
+ * Steps:
+ * 1. admin user create a new database DB_1
+ * 2. admin create TABLE_1 in DB_1
+ * 3. admin create INDEX_1 for COLUMN_1 in TABLE_1 in DB_1
+ * 4. admin user grant INSERT and SELECT to user1's group on TABLE_1
+ *
+ * negative test case:
+ * a) user1 try to SELECT * FROM TABLE_1 WHERE COLUMN_1 == ...
+ * should NOT work
+ * b) user1 should not be able to check the list of view or
+ * index in DB_1
+ * @throws Exception
+ */
+ @Test
+ public void testSandboxOpt13() throws Exception {
+ // unrelated permission to allow user1 to connect to db1
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL2)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1);
+ policyFile.write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+ Connection connection = context.createConnection(ADMIN1, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.execute("DROP INDEX IF EXISTS " + INDEX1 + " ON " + TBL1);
+ statement.execute("CREATE INDEX " + INDEX1 + " ON TABLE " + TBL1
+ + " (under_col) as 'COMPACT' WITH DEFERRED REBUILD");
+ statement.close();
+ connection.close();
+ connection = context.createConnection(USER1, "password");
+ statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ context.assertAuthzException(statement, "SELECT * FROM " + TBL1 + " WHERE under_col == 5");
+ context.assertAuthzException(statement, "SHOW INDEXES ON " + TBL1);
+ policyFile.addPermissionsToRole(GROUP1_ROLE, SELECT_DB1_TBL1, INSERT_DB1_TBL1, loadData);
+ policyFile.write(context.getPolicyFile());
+ statement.execute("USE " + DB1);
+ assertTrue(statement.execute("SELECT * FROM " + TBL1 + " WHERE under_col == 5"));
+ assertTrue(statement.execute("SHOW INDEXES ON " + TBL1));
+ policyFile.write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1, DB2);
+ }
+
+ /**
+ * Steps:
+ * 1. Admin user creates a new database DB_1
+ * 2. Admin user grants ALL on DB_1 to group GROUP_1
+ * 3. User from GROUP_1 creates table TAB_1, TAB_2 in DB_1
+ * 4. Admin user grants SELECT/INSERT on TAB_1 to group GROUP_2
+ * a) verify users from GROUP_2 have only SELECT/INSERT
+ * privileges on TAB_1. They shouldn't be able to perform
+ * any operation other than those listed as
+ * requiring SELECT in the privilege model.
+ * b) verify users from GROUP_2 can't perform queries
+ * involving join between TAB_1 and TAB_2.
+ * c) verify users from GROUP_1 can't perform operations
+ * requiring ALL @SERVER scope:
+ * *) create database
+ * *) drop database
+ * *) show databases
+ * *) show locks
+ * *) execute ALTER TABLE .. SET LOCATION on a table in DB_1
+ * *) execute ALTER PARTITION ... SET LOCATION on a table in DB_1
+ * *) execute CREATE EXTERNAL TABLE ... in DB_1
+ * *) execute ADD JAR
+ * *) execute a query with TRANSOFORM
+ * @throws Exception
+ */
+ @Test
+ public void testSandboxOpt17() throws Exception {
+
+ policyFile
+ .addRolesToGroup("group1", "all_db1", "load_data")
+ .addRolesToGroup("group2", "select_tb1")
+ .addPermissionsToRole("select_tb1", "server=server1->db=db_1->table=tbl_1->action=select")
+ .addPermissionsToRole("all_db1", "server=server1->db=db_1")
+ .addPermissionsToRole("load_data", "server=server1->uri=file://" + dataFile.toString())
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group2")
+ .write(context.getPolicyFile());
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+
+ createTable(USER1, DB1, dataFile, TBL1, TBL2);
+ Connection connection = context.createConnection(USER1, "password");
+ Statement statement = context.createStatement(connection);
+ // c
+ statement.execute("USE " + DB1);
+ context.assertAuthzException(statement, "CREATE DATABASE " + DB3);
+ context.assertAuthzException(statement, "DROP DATABASE " + DB1);
+ ResultSet rs = statement.executeQuery("SHOW DATABASES");
+ assertTrue(rs.next());
+ assertEquals(DB1, rs.getString(1));
+ context.assertAuthzException(statement, "ALTER TABLE " + TBL1 +
+ " ADD PARTITION (value = 10) LOCATION '" + dataDir.getPath() + "'");
+ context.assertAuthzException(statement, "ALTER TABLE " + TBL1
+ + " PARTITION (value = 10) SET LOCATION '" + dataDir.getPath() + "'");
+ context.assertAuthzException(statement, "CREATE EXTERNAL TABLE " + TBL3
+ + " (under_col int, value string) LOCATION '" + dataDir.getPath() + "'");
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection(USER2, "password");
+ statement = context.createStatement(connection);
+
+ // a
+ statement.execute("USE " + DB1);
+ context.assertAuthzException(statement, "SELECT * FROM TABLE " + TBL2 + " LIMIT 10");
+ context.assertAuthzException(statement, "EXPLAIN SELECT * FROM TABLE " + TBL2 + " WHERE under_col > 5 LIMIT 10");
+ context.assertAuthzException(statement, "DESCRIBE " + TBL2);
+ context.assertAuthzException(statement, "LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE " + TBL2);
+ context.assertAuthzException(statement, "analyze table " + TBL2 + " compute statistics for columns under_col, value");
+ // b
+ context.assertAuthzException(statement, "SELECT " + TBL1 + ".* FROM " + TBL1 + " JOIN " + TBL2 +
+ " ON (" + TBL1 + ".value = " + TBL2 + ".value)");
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Positive and negative tests for INSERT OVERWRITE [LOCAL] DIRECTORY and
+ * LOAD DATA [LOCAL] INPATH. EXPORT/IMPORT are handled in separate junit class.
+ * Formerly testSandboxOpt18
+ */
+ @Test
+ public void testInsertOverwriteAndLoadData() throws Exception {
+ long counter = System.currentTimeMillis();
+ File allowedDir = assertCreateDir(new File(baseDir,
+ "test-" + (counter++)));
+ File restrictedDir = assertCreateDir(new File(baseDir,
+ "test-" + (counter++)));
+ Path allowedDfsDir = assertCreateDfsDir(new Path(dfsBaseDir, "test-" + (counter++)));
+ Path restrictedDfsDir = assertCreateDfsDir(new Path(dfsBaseDir, "test-" + (counter++)));
+
+ policyFile
+ .addRolesToGroup("group1", "all_db1", "load_data")
+ .addPermissionsToRole("all_db1", "server=server1->db=db_1")
+ .addPermissionsToRole("load_data", "server=server1->uri=file://" + allowedDir.getPath() +
+ ", server=server1->uri=file://" + allowedDir.getPath() +
+ ", server=server1->uri=" + allowedDfsDir.toString())
+ .addGroupsToUser("user1", "group1")
+ .write(context.getPolicyFile());
+
+ dropDb(ADMIN1, DB1);
+ createDb(ADMIN1, DB1);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+ Connection connection = context.createConnection(USER1, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.execute("INSERT OVERWRITE LOCAL DIRECTORY 'file://" + allowedDir.getPath() + "' SELECT * FROM " + TBL1);
+ statement.execute("INSERT OVERWRITE DIRECTORY '" + allowedDfsDir + "' SELECT * FROM " + TBL1);
+ statement.execute("LOAD DATA LOCAL INPATH 'file://" + allowedDir.getPath() + "' INTO TABLE " + TBL1);
+ statement.execute("LOAD DATA INPATH '" + allowedDfsDir + "' INTO TABLE " + TBL1);
+ context.assertAuthzException(statement, "INSERT OVERWRITE LOCAL DIRECTORY 'file://" + restrictedDir.getPath() + "' SELECT * FROM " + TBL1);
+ context.assertAuthzException(statement, "INSERT OVERWRITE DIRECTORY '" + restrictedDfsDir + "' SELECT * FROM " + TBL1);
+ context.assertAuthzException(statement, "LOAD DATA INPATH 'file://" + restrictedDir.getPath() + "' INTO TABLE " + TBL1);
+ context.assertAuthzException(statement, "LOAD DATA LOCAL INPATH 'file://" + restrictedDir.getPath() + "' INTO TABLE " + TBL1);
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * test create table as with cross database ref
+ * @throws Exception
+ */
+ @Test
+ public void testSandboxOpt10() throws Exception {
+
+ String rTab1 = "rtab_1";
+ String rTab2 = "rtab_2";
+
+ policyFile
+ .addPermissionsToRole(GROUP1_ROLE, ALL_DB1, SELECT_DB2_TBL2, loadData)
+ .addRolesToGroup(GROUP1, GROUP1_ROLE)
+ .addGroupsToUser(USER1, GROUP1);
+ policyFile.write(context.getPolicyFile());
+
+ dropDb(ADMIN1, DB1, DB2);
+ createDb(ADMIN1, DB1, DB2);
+ createTable(ADMIN1, DB1, dataFile, TBL1);
+ createTable(ADMIN1, DB2, dataFile, TBL2, TBL3);
+
+ // a
+ Connection connection = context.createConnection(USER1, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.execute("CREATE TABLE " + rTab1 + " AS SELECT * FROM " + DB2 + "." + TBL2);
+ // user1 doesn't have access to db2, so following create table as should fail
+ context.assertAuthzException(statement, "CREATE TABLE " + rTab2 + " AS SELECT * FROM " + DB2 + "." + TBL3);
+
+ statement.close();
+ connection.close();
+ dropDb(ADMIN1, DB1, DB2);
+ }
+
+ // Create per-db policy file on hdfs and global policy on local.
+ @Test
+ public void testPerDbPolicyOnDFS() throws Exception {
+
+ policyFile
+ .addRolesToGroup("user_group1", "select_tbl1")
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl1", "server=server1->db=db1->table=tbl1->action=select")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .addDatabase("db2", dfsBaseDir.toUri().toString() + "/" + DB2_POLICY_FILE)
+ .write(context.getPolicyFile());
+
+ File db2PolicyFileHandle = new File(baseDir.getPath(), DB2_POLICY_FILE);
+
+ PolicyFile db2PolicyFile = new PolicyFile();
+ db2PolicyFile
+ .addRolesToGroup("user_group2", "select_tbl2")
+ .addPermissionsToRole("select_tbl2", "server=server1->db=db2->table=tbl2->action=select")
+ .write(db2PolicyFileHandle);
+ PolicyFiles.copyFilesToDir(dfsCluster.getFileSystem(), dfsBaseDir, db2PolicyFileHandle);
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+
+ 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("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl1");
+ 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.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE tbl2");
+ statement.close();
+ connection.close();
+
+ // test per-db file for db2
+
+ connection = context.createConnection("user2", "password");
+ statement = context.createStatement(connection);
+ // test user2 can use db2
+ statement.execute("USE db2");
+ statement.execute("select * from tbl2");
+
+ statement.close();
+ connection.close();
+
+ //test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE db1 CASCADE");
+ statement.execute("DROP DATABASE db2 CASCADE");
+ statement.close();
+ connection.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestSentryOnFailureHookLoading.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestSentryOnFailureHookLoading.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestSentryOnFailureHookLoading.java
new file mode 100644
index 0000000..4cfbbaa
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestSentryOnFailureHookLoading.java
@@ -0,0 +1,129 @@
+/*
+ * 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 com.google.common.io.Resources;
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+import junit.framework.Assert;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+public class TestSentryOnFailureHookLoading extends AbstractTestWithHiveServer {
+
+ private Context context;
+ private PolicyFile policyFile;
+
+ Map<String, String > testProperties;
+ private static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+
+ @Before
+ public void setup() throws Exception {
+ testProperties = new HashMap<String, String>();
+ testProperties.put(HiveAuthzConf.AuthzConfVars.AUTHZ_ONFAILURE_HOOKS.getVar(),
+ DummySentryOnFailureHook.class.getName());
+ policyFile = PolicyFile.createAdminOnServer1("admin1");
+ }
+
+ @After
+ public void teardown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /* Admin creates database DB_2
+ * user1 tries to drop DB_2, but it has permissions for DB_1.
+ */
+ @Test
+ public void testOnFailureHookLoading() throws Exception {
+
+ // Do not run this test if run with external HiveServer2
+ // This test checks for a static member, which will not
+ // be set if HiveServer2 and the test run in different JVMs
+ String hiveServer2Type = System.getProperty(
+ HiveServerFactory.HIVESERVER2_TYPE);
+ if (hiveServer2Type != null &&
+ HiveServerFactory.HiveServer2Type.valueOf(hiveServer2Type.trim()) !=
+ HiveServerFactory.HiveServer2Type.InternalHiveServer2) {
+ return;
+ }
+
+ context = createContext(testProperties);
+
+ File dataDir = context.getDataDir();
+ //copy data file to test dir
+ 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();
+
+ policyFile
+ .addRolesToGroup("user_group1", "all_db1", "load_data")
+ .addPermissionsToRole("all_db1", "server=server1->db=DB_1")
+ .addGroupsToUser("user1", "user_group1")
+ .write(context.getPolicyFile());
+
+ // setup db objects needed by the test
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+ statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
+ statement.execute("CREATE DATABASE DB_1");
+ statement.execute("CREATE DATABASE DB_2");
+ statement.close();
+ connection.close();
+
+ // test execution
+ connection = context.createConnection("user1", "password");
+ statement = context.createStatement(connection);
+
+ //negative test case: user can't drop another user's database
+ assertFalse(DummySentryOnFailureHook.invoked);
+ try {
+ statement.execute("DROP DATABASE DB_2 CASCADE");
+ Assert.fail("Expected SQL exception");
+ } catch (SQLException e) {
+ assertTrue(DummySentryOnFailureHook.invoked);
+ }
+
+ statement.close();
+ connection.close();
+
+ //test cleanup
+ connection = context.createConnection("admin1", "hive");
+ statement = context.createStatement(connection);
+ statement.execute("DROP DATABASE DB_1 CASCADE");
+ statement.execute("DROP DATABASE DB_2 CASCADE");
+ statement.close();
+ connection.close();
+ context.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java
new file mode 100644
index 0000000..d02a193
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java
@@ -0,0 +1,209 @@
+/*
+ * 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.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+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.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.sentry.binding.hive.HiveAuthzBindingSessionHook;
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.Maps;
+import com.google.common.io.Files;
+
+public class TestServerConfiguration extends AbstractTestWithHiveServer {
+
+ private Context context;
+ private Map<String, String> properties;
+ private PolicyFile policyFile;
+
+ @Before
+ public void setup() throws Exception {
+ properties = Maps.newHashMap();
+ policyFile = PolicyFile.createAdminOnServer1("admin1");
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if(context != null) {
+ context.close();
+ }
+ }
+
+ /**
+ * hive.server2.enable.impersonation must be disabled
+ */
+ @Test
+ public void testImpersonationIsDisabled() throws Exception {
+ properties.put(HiveServerFactory.ACCESS_TESTING_MODE, "false");
+ properties.put("hive.server2.enable.impersonation", "true");
+ context = createContext(properties);
+ policyFile.write(context.getPolicyFile());
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ try {
+ statement.execute("create table test (a string)");
+ Assert.fail("Expected SQLException");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ }
+
+ /**
+ * hive.server2.authentication must be set to LDAP or KERBEROS
+ */
+ @Test
+ public void testAuthenticationIsStrong() throws Exception {
+ properties.put(HiveServerFactory.ACCESS_TESTING_MODE, "false");
+ properties.put("hive.server2.authentication", "NONE");
+ context = createContext(properties);
+ policyFile.write(context.getPolicyFile());
+ System.out.println(Files.toString(context.getPolicyFile(), Charsets.UTF_8));
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ try {
+ statement.execute("create table test (a string)");
+ Assert.fail("Expected SQLException");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ }
+
+ /**
+ * Test removal of policy file
+ */
+ @Test
+ public void testRemovalOfPolicyFile() throws Exception {
+ context = createContext(properties);
+ File policyFile = context.getPolicyFile();
+ assertTrue("Could not delete " + policyFile, policyFile.delete());
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ try {
+ statement.execute("create table test (a string)");
+ Assert.fail("Expected SQLException");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ }
+
+ /**
+ * Test corruption of policy file
+ */
+ @Test
+ public void testCorruptionOfPolicyFile() throws Exception {
+ context = createContext(properties);
+ File policyFile = context.getPolicyFile();
+ assertTrue("Could not delete " + policyFile, policyFile.delete());
+ FileOutputStream out = new FileOutputStream(policyFile);
+ out.write("this is not valid".getBytes(Charsets.UTF_8));
+ out.close();
+ Connection connection = context.createConnection("admin1", "hive");
+ Statement statement = context.createStatement(connection);
+ try {
+ statement.execute("create table test (a string)");
+ Assert.fail("Expected SQLException");
+ } catch (SQLException e) {
+ context.verifyAuthzException(e);
+ }
+ }
+
+ @Test
+ public void testAddDeleteDFSRestriction() throws Exception {
+ context = createContext(properties);
+
+ policyFile
+ .addRolesToGroup("group1", "all_db1")
+ .addRolesToGroup("group2", "select_tb1")
+ .addPermissionsToRole("select_tb1", "server=server1->db=db_1->table=tbl_1->action=select")
+ .addPermissionsToRole("all_db1", "server=server1->db=db_1")
+ .addGroupsToUser("user1", "group1")
+ .write(context.getPolicyFile());
+
+ Connection connection = context.createConnection("user1", "password");
+ Statement statement = context.createStatement(connection);
+
+ // disallow external executables. The external.exec is set to false by session hooks
+ context.assertAuthzException(statement, "ADD JAR /usr/lib/hive/lib/hbase.jar");
+ context.assertAuthzException(statement, "ADD FILE /tmp/tt.py");
+ context.assertAuthzException(statement, "DFS -ls");
+ context.assertAuthzException(statement, "DELETE JAR /usr/lib/hive/lib/hbase.jar");
+ context.assertAuthzException(statement, "DELETE FILE /tmp/tt.py");
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Test that the required access configs are set by session hook
+ */
+ @Test
+ public void testAccessConfigRestrictions() throws Exception {
+ context = createContext(properties);
+ policyFile.write(context.getPolicyFile());
+
+ String testUser = "user1";
+ // verify the config is set correctly by session hook
+ verifyConfig(testUser, ConfVars.SEMANTIC_ANALYZER_HOOK.varname,
+ HiveAuthzBindingSessionHook.SEMANTIC_HOOK);
+ verifyConfig(testUser, ConfVars.PREEXECHOOKS.varname,
+ HiveAuthzBindingSessionHook.PRE_EXEC_HOOK);
+ verifyConfig(testUser, ConfVars.HIVE_EXEC_FILTER_HOOK.varname,
+ HiveAuthzBindingSessionHook.FILTER_HOOK);
+ verifyConfig(testUser, ConfVars.HIVE_EXTENDED_ENITITY_CAPTURE.varname, "true");
+ verifyConfig(testUser, ConfVars.HIVE_SERVER2_AUTHZ_EXTERNAL_EXEC.varname, "false");
+ verifyConfig(testUser, ConfVars.SCRATCHDIRPERMISSION.varname, HiveAuthzBindingSessionHook.SCRATCH_DIR_PERMISSIONS);
+ verifyConfig(testUser, HiveConf.ConfVars.HIVE_CONF_RESTRICTED_LIST.varname,
+ HiveAuthzBindingSessionHook.ACCESS_RESTRICT_LIST);
+ verifyConfig(testUser, HiveAuthzConf.HIVE_ACCESS_SUBJECT_NAME, testUser);
+ }
+
+ private void verifyConfig(String userName, String confVar, String expectedValue) throws Exception {
+ Connection connection = context.createConnection(userName, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("set " + confVar);
+ ResultSet res = statement.getResultSet();
+ assertTrue(res.next());
+ String configValue = res.getString(1);
+ assertNotNull(configValue);
+ String restrictListValues = (configValue.split("="))[1];
+ assertFalse(restrictListValues.isEmpty());
+ for (String restrictConfig: expectedValue.split(",")) {
+ assertTrue(restrictListValues.toLowerCase().contains(restrictConfig.toLowerCase()));
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUriPermissions.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUriPermissions.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUriPermissions.java
new file mode 100644
index 0000000..aae68e5
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUriPermissions.java
@@ -0,0 +1,270 @@
+/*
+ * 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.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import junit.framework.Assert;
+
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestUriPermissions extends AbstractTestWithStaticLocalFS {
+ private Context context;
+ private PolicyFile policyFile;
+
+ private static final String dataFile = "/kv1.dat";
+ private String dataFilePath = this.getClass().getResource(dataFile).getFile();
+
+ @Before
+ public void setup() throws Exception {
+ context = createContext();
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ // test load data into table
+ @Test
+ public void testLoadPrivileges() throws Exception {
+ String dbName = "db1";
+ String tabName = "tab1";
+ Connection userConn = null;
+ Statement userStmt = null;
+
+ policyFile
+ .addRolesToGroup("user_group1", "db1_read", "db1_write", "data_read")
+ .addRolesToGroup("user_group2", "db1_write")
+ .addPermissionsToRole("db1_write", "server=server1->db=" + dbName + "->table=" + tabName + "->action=INSERT")
+ .addPermissionsToRole("db1_read", "server=server1->db=" + dbName + "->table=" + tabName + "->action=SELECT")
+ .addPermissionsToRole("data_read", "server=server1->URI=file://" + dataFilePath
+ + ", server=server1->URI=file://" + dataFilePath)
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .write(context.getPolicyFile());
+
+ // create dbs
+ Connection adminCon = context.createConnection("admin1", "foo");
+ Statement adminStmt = context.createStatement(adminCon);
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.execute("use " + dbName);
+ adminStmt.execute("CREATE TABLE " + tabName + "(id int)");
+ context.close();
+
+ // positive test, user1 has access to file being loaded
+ userConn = context.createConnection("user1", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ userStmt.execute("load data local inpath '" + dataFilePath +
+ "' 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", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ context.assertAuthzException(userStmt, "load data local inpath '" + dataFilePath +
+ "' into table " + tabName);
+ userStmt.close();
+ userConn.close();
+ }
+
+ // Test alter partition location
+ @Test
+ public void testAlterPartitionLocationPrivileges() throws Exception {
+ String dbName = "db1";
+ String tabName = "tab1";
+ String newPartitionDir = "foo";
+ String tabDir = "file://" + hiveServer.getProperty(HiveServerFactory.WAREHOUSE_DIR) +
+ "/" + tabName + "/" + newPartitionDir;
+ Connection userConn = null;
+ Statement userStmt = null;
+
+ policyFile
+ .addRolesToGroup("user_group1", "db1_all", "data_read")
+ .addRolesToGroup("user_group2", "db1_all")
+ .addRolesToGroup("user_group3", "db1_tab1_all", "data_read")
+ .addPermissionsToRole("db1_all", "server=server1->db=" + dbName)
+ .addPermissionsToRole("db1_tab1_all", "server=server1->db=" + dbName + "->table=" + tabName)
+ .addPermissionsToRole("data_read", "server=server1->URI=" + tabDir)
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .addGroupsToUser("user3", "user_group3")
+ .write(context.getPolicyFile());
+
+ // create dbs
+ Connection adminCon = context.createConnection("admin1", "foo");
+ Statement adminStmt = context.createStatement(adminCon);
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.execute("use " + dbName);
+ adminStmt.execute("CREATE TABLE " + tabName + " (id int) PARTITIONED BY (dt string)");
+ adminCon.close();
+
+ // positive test: user1 has privilege to alter table add partition but not set location
+ userConn = context.createConnection("user1", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ userStmt.execute("ALTER TABLE " + tabName + " ADD PARTITION (dt = '21-Dec-2012') " +
+ " LOCATION '" + tabDir + "'");
+ // negative test user1 cannot alter partition location
+ context.assertAuthzException(userStmt,
+ "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", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ 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')");
+ userConn.close();
+
+ // negative test: user3 doesn't have privilege to add/drop partitions
+ userConn = context.createConnection("user3", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ context.assertAuthzException(userStmt,
+ "ALTER TABLE " + tabName + " ADD PARTITION (dt = '22-Dec-2012') " +
+ " LOCATION '" + tabDir + "/foo'");
+ context.assertAuthzException(userStmt,
+ "ALTER TABLE " + tabName + " DROP PARTITION (dt = '21-Dec-2012')");
+ userConn.close();
+
+ // positive test: user1 has privilege to alter drop partition
+ userConn = context.createConnection("user1", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ 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 dbName = "db1";
+ String tabName = "tab1";
+ String tabDir = "file://" + hiveServer.getProperty(HiveServerFactory.WAREHOUSE_DIR) + "/" + tabName;
+ Connection userConn = null;
+ Statement userStmt = null;
+
+ policyFile
+ .addRolesToGroup("user_group1", "server1_all")
+ .addRolesToGroup("user_group2", "db1_all, data_read")
+ .addPermissionsToRole("db1_all", "server=server1->db=" + dbName)
+ .addPermissionsToRole("data_read", "server=server1->URI=" + tabDir)
+ .addPermissionsToRole("server1_all", "server=server1")
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .write(context.getPolicyFile());
+
+ // create dbs
+ Connection adminCon = context.createConnection("admin1", "foo");
+ Statement adminStmt = context.createStatement(adminCon);
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.execute("use " + dbName);
+ adminStmt.execute("CREATE TABLE " + tabName + " (id int) PARTITIONED BY (dt string)");
+ adminCon.close();
+
+ // negative test: user2 doesn't have privilege to alter table set partition
+ userConn = context.createConnection("user2", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ context.assertAuthzException(userStmt,
+ "ALTER TABLE " + tabName + " SET LOCATION '" + tabDir + "'");
+ userConn.close();
+
+ // positive test: user1 has privilege to alter table set partition
+ userConn = context.createConnection("user1", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ userStmt.execute("ALTER TABLE " + tabName + " SET LOCATION '" + tabDir + "'");
+ userConn.close();
+ }
+
+ // Test external table
+ @Test
+ public void testExternalTablePrivileges() throws Exception {
+ String dbName = "db1";
+ Connection userConn = null;
+ Statement userStmt = null;
+ String tableDir = "file://" + context.getDataDir();
+
+ policyFile
+ .addRolesToGroup("user_group1", "db1_all", "data_read")
+ .addRolesToGroup("user_group2", "db1_all")
+ .addPermissionsToRole("db1_all", "server=server1->db=" + dbName)
+ .addPermissionsToRole("data_read", "server=server1->URI=" + tableDir)
+ .addGroupsToUser("user1", "user_group1")
+ .addGroupsToUser("user2", "user_group2")
+ .write(context.getPolicyFile());
+
+ // create dbs
+ Connection adminCon = context.createConnection("admin1", "foo");
+ Statement adminStmt = context.createStatement(adminCon);
+ adminStmt.execute("use default");
+ adminStmt.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ adminStmt.execute("CREATE DATABASE " + dbName);
+ adminStmt.close();
+ adminCon.close();
+
+ // negative test: user2 doesn't have privilege to create external table in given path
+ userConn = context.createConnection("user2", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ 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", "foo");
+ userStmt = context.createStatement(userConn);
+ userStmt.execute("use " + dbName);
+ 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();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java
new file mode 100644
index 0000000..a7bb393
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java
@@ -0,0 +1,333 @@
+/*
+ * 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.junit.Assert.assertFalse;
+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.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestUserManagement extends AbstractTestWithStaticLocalFS {
+ private static final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+ private static final String dbName = "db1";
+ private static final String tableName = "t1";
+ private static final String tableComment = "Test table";
+ private File dataFile;
+ private Context context;
+ private PolicyFile policyFile;
+
+ @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();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (context != null) {
+ context.close();
+ }
+ }
+ private void doCreateDbLoadDataDropDb(String admin, String...users) throws Exception {
+ doDropDb(admin);
+ for (String user : users) {
+ doCreateDb(user);
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = context.createStatement(connection);
+ ResultSet res = statement.executeQuery("SHOW DATABASES");
+ boolean created = false;
+ while (res.next()) {
+ if (res.getString(1).equals(dbName)) {
+ created = true;
+ }
+ }
+ assertTrue("database " + dbName + " is not created", created);
+ doCreateTableLoadData(user);
+ doDropDb(user);
+ statement.close();
+ connection.close();
+ }
+ }
+ private void doDropDb(String user) throws Exception {
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = connection.createStatement();
+ statement.execute("DROP DATABASE IF EXISTS " + dbName + " CASCADE");
+ statement.close();
+ connection.close();
+ }
+ private void doCreateDb(String user) throws Exception {
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = connection.createStatement();
+ statement.execute("CREATE DATABASE " + dbName);
+ statement.close();
+ connection.close();
+ }
+ private void doCreateTableLoadData(String user) throws Exception {
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + dbName);
+ statement.execute("CREATE TABLE " + tableName +
+ " (under_col int comment 'the under column', value string) comment '"
+ + tableComment + "'");
+ statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' into table " + tableName);
+ assertTrue(statement.execute("SELECT * FROM " + tableName));
+ statement.close();
+ connection.close();
+ }
+ /**
+ * Basic sanity test
+ */
+ @Test
+ public void testSanity() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ policyFile.write(context.getPolicyFile());
+ doCreateDbLoadDataDropDb("admin1", "admin1");
+ }
+
+ /**
+ * Tests admin privileges allow admins to create/drop dbs
+ **/
+ @Test
+ public void testAdmin1() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ policyFile
+ .addGroupsToUser("admin2", "admin")
+ .addGroupsToUser("admin3", "admin")
+ .write(context.getPolicyFile());
+
+ doCreateDbLoadDataDropDb("admin1", "admin1", "admin2", "admin3");
+ }
+
+ /**
+ * Negative case: Tests that when a user is removed
+ * from the policy file their permissions have no effect
+ **/
+ @Test
+ public void testAdmin3() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ policyFile
+ .addGroupsToUser("admin2", "admin")
+ .addGroupsToUser("admin3", "admin")
+ .write(context.getPolicyFile());
+ doCreateDbLoadDataDropDb("admin1", "admin1", "admin2", "admin3");
+
+ // remove admin1 from admin group
+ policyFile
+ .removeGroupsFromUser("admin1", "admin")
+ .write(context.getPolicyFile());
+ // verify admin1 doesn't have admin privilege
+ Connection connection = context.createConnection("admin1", "foo");
+ Statement statement = connection.createStatement();
+ context.assertAuthzException(statement, "CREATE DATABASE somedb");
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Tests that users in two groups work correctly
+ **/
+ @Test
+ public void testAdmin5() throws Exception {
+ policyFile = new PolicyFile();
+ policyFile
+ .addRolesToGroup("admin_group1", "admin")
+ .addRolesToGroup("admin_group2", "admin")
+ .addPermissionsToRole("admin", "server=server1")
+ .addGroupsToUser("admin1", "admin_group1", "admin_group2")
+ .addGroupsToUser("admin2", "admin_group1", "admin_group2")
+ .addGroupsToUser("admin3", "admin_group1", "admin_group2")
+ .write(context.getPolicyFile());
+ doCreateDbLoadDataDropDb("admin1", "admin1", "admin2", "admin3");
+ }
+
+ /**
+ * Tests admin group does not infect non-admin group
+ **/
+ @Test
+ public void testAdmin6() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ policyFile
+ .addRolesToGroup("group1", "non_admin_role")
+ .addPermissionsToRole("non_admin_role", "server=server1->db=" + dbName)
+ .addGroupsToUser("user1", "group1")
+ .write(context.getPolicyFile());
+
+ doCreateDbLoadDataDropDb("admin1", "admin1");
+ Connection connection = context.createConnection("user1", "password");
+ Statement statement = connection.createStatement();
+ context.assertAuthzException(statement, "CREATE DATABASE " + dbName);
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Tests that user with two roles the most powerful role takes effect
+ **/
+ @Test
+ public void testGroup2() throws Exception {
+ policyFile = new PolicyFile();
+ policyFile
+ .addRolesToGroup("group1", "admin", "analytics")
+ .addPermissionsToRole("admin", "server=server1")
+ .addPermissionsToRole("analytics", "server=server1->db=" + dbName)
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group1")
+ .addGroupsToUser("user3", "group1")
+ .write(context.getPolicyFile());
+ doCreateDbLoadDataDropDb("user1", "user1", "user2", "user3");
+ }
+ /**
+ * Tests that user without uri privilege can create table but not load data
+ **/
+ @Test
+ public void testGroup4() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ policyFile
+ .addRolesToGroup("group1", "non_admin_role", "load_data")
+ .addPermissionsToRole("non_admin_role", "server=server1->db=" + dbName)
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group1")
+ .addGroupsToUser("user3", "group1")
+ .write(context.getPolicyFile());
+
+ doDropDb("admin1");
+ for(String user : new String[]{"user1", "user2", "user3"}) {
+ doCreateDb("admin1");
+ Connection connection = context.createConnection(user, "password");
+ Statement statement = context.createStatement(connection);
+ statement.execute("USE " + dbName);
+ statement.execute("CREATE TABLE " + tableName +
+ " (under_col int comment 'the under column', value string) comment '"
+ + tableComment + "'");
+ context.assertAuthzException(statement,
+ "LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' into table " + tableName);
+ assertTrue(statement.execute("SELECT * FROM " + tableName));
+ statement.close();
+ connection.close();
+ doDropDb("admin1");
+ }
+ }
+ /**
+ * Tests users can have same name as groups
+ **/
+ @Test
+ public void testGroup5() throws Exception {
+
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ policyFile
+ .addRolesToGroup("group1", "non_admin_role", "load_data")
+ .addPermissionsToRole("non_admin_role", "server=server1->db=" + dbName)
+ .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
+ .addGroupsToUser("group1", "group1")
+ .addGroupsToUser("user2", "group1")
+ .addGroupsToUser("user3", "group1")
+ .write(context.getPolicyFile());
+
+ doDropDb("admin1");
+ for(String user : new String[]{"group1", "user2", "user3"}) {
+ doCreateDb("admin1");
+ doCreateTableLoadData(user);
+ doDropDb("admin1");
+ }
+ }
+
+ /**
+ * Tests that group names with special characters are handled correctly
+ **/
+ @Test
+ public void testGroup6() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ policyFile
+ .addRolesToGroup("group1~!@#$%^&*()+-", "analytics", "load_data")
+ .addPermissionsToRole("analytics", "server=server1->db=" + dbName)
+ .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
+ .addGroupsToUser("user1", "group1~!@#$%^&*()+-")
+ .addGroupsToUser("user2", "group1~!@#$%^&*()+-")
+ .addGroupsToUser("user3", "group1~!@#$%^&*()+-")
+ .write(context.getPolicyFile());
+
+ doDropDb("admin1");
+ for(String user : new String[]{"user1", "user2", "user3"}) {
+ doCreateDb("admin1");
+ doCreateTableLoadData(user);
+ doDropDb("admin1");
+ }
+ }
+
+ /**
+ * Tests that user names with special characters are handled correctly
+ **/
+ @Test
+ public void testGroup7() throws Exception {
+ policyFile = new PolicyFile();
+ policyFile
+ .addRolesToGroup("group1", "admin")
+ .addPermissionsToRole("admin", "server=server1")
+ .addGroupsToUser("user1~!@#$%^&*()+-", "group1")
+ .addGroupsToUser("user2", "group1")
+ .addGroupsToUser("user3", "group1")
+ .write(context.getPolicyFile());
+ doCreateDbLoadDataDropDb("user1~!@#$%^&*()+-", "user1~!@#$%^&*()+-", "user2", "user3");
+ }
+
+ /**
+ * Tests that users with no privileges cannot list any tables
+ **/
+ @Test
+ public void testGroup8() throws Exception {
+ policyFile = PolicyFile.createAdminOnServer1(ADMIN1);
+ policyFile
+ .addRolesToGroup("group1", "analytics")
+ .addGroupsToUser("user1", "group1")
+ .addGroupsToUser("user2", "group1")
+ .addGroupsToUser("user3", "group1")
+ .write(context.getPolicyFile());
+
+ Connection connection = context.createConnection("admin1", "password");
+ Statement statement = connection.createStatement();
+ statement.execute("DROP DATABASE IF EXISTS db1 CASCADE");
+ statement.execute("CREATE DATABASE db1");
+ statement.execute("USE db1");
+ statement.execute("CREATE TABLE t1 (under_col int, value string)");
+ statement.close();
+ connection.close();
+ String[] users = { "user1", "user2", "user3" };
+ for (String user : users) {
+ connection = context.createConnection(user, "foo");
+ statement = context.createStatement(connection);
+ assertFalse("No results should be returned",
+ statement.executeQuery("SHOW TABLES").next());
+ statement.close();
+ connection.close();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/AbstractHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/AbstractHiveServer.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/AbstractHiveServer.java
new file mode 100644
index 0000000..24a6fe9
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/AbstractHiveServer.java
@@ -0,0 +1,88 @@
+/*
+ * 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.hiveserver;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+
+import com.google.common.base.Strings;
+
+public abstract class AbstractHiveServer implements HiveServer {
+
+ private static final String LINK_FAILURE_SQL_STATE = "08S01";
+
+ private final Configuration configuration;
+ private final String hostname;
+ private final int port;
+
+ public AbstractHiveServer(Configuration configuration, String hostname,
+ int port) {
+ this.configuration = configuration;
+ this.hostname = hostname;
+ this.port = port;
+ }
+
+ @Override
+ public String getProperty(String key) {
+ return configuration.get(key);
+ }
+
+ @Override
+ public String getURL() {
+ return "jdbc:hive2://" + hostname + ":" + port + "/default";
+ }
+
+ public Connection createConnection(String user, String password) throws Exception{
+ String url = getURL();
+ Connection connection = DriverManager.getConnection(url, user, password);
+ return connection;
+ }
+
+ protected static String getHostname(HiveConf hiveConf) {
+ return hiveConf.get(ConfVars.HIVE_SERVER2_THRIFT_BIND_HOST.toString(), "localhost").trim();
+ }
+ protected static int getPort(HiveConf hiveConf) {
+ return Integer.parseInt(hiveConf.get(ConfVars.HIVE_SERVER2_THRIFT_PORT.toString(), "10000").trim());
+ }
+ protected static void waitForStartup(HiveServer hiveServer) throws Exception {
+ int waitTime = 0;
+ long startupTimeout = 1000L * 10L;
+ do {
+ Thread.sleep(500L);
+ waitTime += 500L;
+ if (waitTime > startupTimeout) {
+ throw new TimeoutException("Couldn't access new HiveServer: " + hiveServer.getURL());
+ }
+ try {
+ Connection connection = DriverManager.getConnection(hiveServer.getURL(), "hive", "bar");
+ connection.close();
+ break;
+ } catch (SQLException e) {
+ String state = Strings.nullToEmpty(e.getSQLState()).trim();
+ if (!state.equalsIgnoreCase(LINK_FAILURE_SQL_STATE)) {
+ throw e;
+ }
+ }
+ } while (true);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/EmbeddedHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/EmbeddedHiveServer.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/EmbeddedHiveServer.java
new file mode 100644
index 0000000..853f75a
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/EmbeddedHiveServer.java
@@ -0,0 +1,59 @@
+/*
+ * 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.hiveserver;
+
+import org.apache.hadoop.hive.metastore.HiveMetaStore;
+import org.fest.reflect.core.Reflection;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+public class EmbeddedHiveServer implements HiveServer {
+
+ @Override
+ public void start() {
+ // Fix for ACCESS-148. Resets a static field
+ // so the default database is created even
+ // though is has been created before in this JVM
+ Reflection.staticField("createDefaultDB")
+ .ofType(boolean.class)
+ .in(HiveMetaStore.HMSHandler.class)
+ .set(false);
+ }
+
+ public Connection createConnection(String user, String password) throws Exception{
+ String url = getURL();
+ Connection connection = DriverManager.getConnection(url, user, password);
+ return connection;
+ }
+
+ @Override
+ public void shutdown() {
+
+ }
+
+ @Override
+ public String getURL() {
+ return "jdbc:hive2://";
+ }
+
+ @Override
+ public String getProperty(String key) {
+ throw new UnsupportedOperationException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/ExternalHiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/ExternalHiveServer.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/ExternalHiveServer.java
new file mode 100644
index 0000000..88edc08
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/ExternalHiveServer.java
@@ -0,0 +1,124 @@
+/*
+ * 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.hiveserver;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.List;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+
+
+public class ExternalHiveServer extends AbstractHiveServer {
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(ExternalHiveServer.class);
+ private final File confDir;
+ private final File logDir;
+ private Process process;
+
+ public ExternalHiveServer(HiveConf hiveConf, File confDir, File logDir) throws Exception {
+ super(hiveConf, getHostname(hiveConf), getPort(hiveConf));
+ this.confDir = confDir;
+ this.logDir = logDir;
+ }
+
+
+ @Override
+ public synchronized void start() throws Exception {
+ String hiveCommand = System.getProperty("hive.bin.path", "./target/hive/bin/hive");
+ String hadoopHome = System.getProperty("hadoop.home", "./target/hadoop");
+ String hadoopClasspath = getHadoopClasspath();
+ String command = "export ";
+ command += String.format("HIVE_CONF_DIR=\"%s\" HADOOP_HOME=\"%s\" ", confDir.getPath(), hadoopHome);
+ command += String.format("HADOOP_CLASSPATH=\"%s:%s\" ", confDir.getPath(), hadoopClasspath);
+ command += "HADOOP_CLIENT_OPTS=\"-Dhive.log.dir=./target/\"";
+ command += "; ";
+ command += String.format("%s --service hiveserver2 >%s/hs2.out 2>&1 & echo $! > %s/hs2.pid",
+ hiveCommand, logDir.getPath(), logDir.getPath());
+ LOGGER.info("Executing " + command);
+ process = Runtime.getRuntime().
+ exec(new String[]{"/bin/sh", "-c", command});
+ waitForStartup(this);
+ }
+
+ @Override
+ public synchronized void shutdown() throws Exception {
+ if(process != null) {
+ process.destroy();
+ process = null;
+ String pid = Strings.nullToEmpty(Files.readFirstLine(new File(logDir, "hs2.pid"), Charsets.UTF_8)).trim();
+ if(!pid.isEmpty()) {
+ LOGGER.info("Killing " + pid);
+ Process killCommand = Runtime.getRuntime().
+ exec(new String[]{"/bin/sh", "-c", "kill " + pid});
+ // TODO this isn't strictly correct but kill won't output much data
+ String error = read(killCommand.getErrorStream());
+ String output = read(killCommand.getInputStream());
+ LOGGER.info("Kill exit code " + killCommand.waitFor() +
+ ", output = '" + output + "', error = '" + error + "'");
+ }
+ }
+ }
+
+ private String read(InputStream is) throws IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ StringBuffer buffer = new StringBuffer();
+ try {
+ String line;
+ while((line = reader.readLine()) != null) {
+ buffer.append(line);
+ }
+ return buffer.toString();
+ } finally {
+ reader.close();
+ }
+
+ }
+
+ private String getHadoopClasspath() {
+ List<String> result = Lists.newArrayList();
+ String clazzPath = Preconditions.checkNotNull(System.getProperty("java.class.path"), "java.class.path");
+ String sep = Preconditions.checkNotNull(System.getProperty("path.separator"), "path.separator");
+ for(String item : Splitter.on(sep).omitEmptyStrings().trimResults().split(clazzPath)) {
+ if(item.endsWith("/sentry-tests/target/classes") ||
+ item.endsWith("/sentry-tests/target/test-classes")) {
+ result.add(item);
+ } else {
+ File clazzPathItem = new File(item);
+ String fileName = clazzPathItem.getName();
+ if(clazzPathItem.isFile() && fileName.startsWith("sentry-") && fileName.endsWith(".jar")) {
+ result.add(item);
+ }
+ }
+ }
+ return Joiner.on(sep).join(result);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/aef404c6/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/HiveServer.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/HiveServer.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/HiveServer.java
new file mode 100644
index 0000000..ee6155b
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/hiveserver/HiveServer.java
@@ -0,0 +1,34 @@
+/*
+ * 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.hiveserver;
+
+import java.sql.Connection;
+
+public interface HiveServer {
+
+ public void start() throws Exception;
+
+ public void shutdown() throws Exception;
+
+ public String getURL();
+
+ public String getProperty(String key);
+
+ public Connection createConnection(String user, String password) throws Exception;
+
+}