/**
 * 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.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.sentry.provider.file.PolicyFile;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import com.google.common.io.Resources;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Test all operations that require index on table alone (part 2)
 1. Create index : HiveOperation.CREATEINDEX
 2. Drop index : HiveOperation.DROPINDEX
 3. HiveOperation.ALTERINDEX_REBUILD
 4. TODO: HiveOperation.ALTERINDEX_PROPS
 */
public class TestOperationsPart2 extends AbstractTestWithStaticConfiguration {
  private static final Logger LOGGER = LoggerFactory
      .getLogger(TestOperationsPart2.class);

  private PolicyFile policyFile;
  final String tableName = "tb1";

  static Map<String, String> privileges = new HashMap<String, String>();
  static {
    privileges.put("all_server", "server=server1->action=all");
    privileges.put("create_server", "server=server1->action=create");
    privileges.put("all_db1", "server=server1->db=" + DB1 + "->action=all");
    privileges.put("select_db1", "server=server1->db=" + DB1 + "->action=select");
    privileges.put("insert_db1", "server=server1->db=" + DB1 + "->action=insert");
    privileges.put("create_db1", "server=server1->db=" + DB1 + "->action=create");
    privileges.put("drop_db1", "server=server1->db=" + DB1 + "->action=drop");
    privileges.put("alter_db1", "server=server1->db=" + DB1 + "->action=alter");
    privileges.put("create_db2", "server=server1->db=" + DB2 + "->action=create");

    privileges.put("all_db1_tb1", "server=server1->db=" + DB1 + "->table=tb1->action=all");
    privileges.put("select_db1_tb1", "server=server1->db=" + DB1 + "->table=tb1->action=select");
    privileges.put("insert_db1_tb1", "server=server1->db=" + DB1 + "->table=tb1->action=insert");
    privileges.put("alter_db1_tb1", "server=server1->db=" + DB1 + "->table=tb1->action=alter");
    privileges.put("alter_db1_ptab", "server=server1->db=" + DB1 + "->table=ptab->action=alter");
    privileges.put("index_db1_tb1", "server=server1->db=" + DB1 + "->table=tb1->action=index");
    privileges.put("lock_db1_tb1", "server=server1->db=" + DB1 + "->table=tb1->action=lock");
    privileges.put("drop_db1_tb1", "server=server1->db=" + DB1 + "->table=tb1->action=drop");
    privileges.put("insert_db2_tb2", "server=server1->db=" + DB2 + "->table=tb2->action=insert");
    privileges.put("select_db1_view1", "server=server1->db=" + DB1 + "->table=view1->action=select");

  }

  @Before
  public void setup() throws Exception{
    policyFile = PolicyFile.setAdminOnServer1(ADMINGROUP)
        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
    writePolicyFile(policyFile);
  }

  private void adminCreate(String db, String table) throws Exception{
    adminCreate(db, table, false);
  }

  private void adminCreate(String db, String table, boolean partitioned) throws Exception{
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);
    exec(statement, "DROP DATABASE IF EXISTS " + db + " CASCADE");
    exec(statement, "CREATE DATABASE " + db);
    if(table !=null) {
      if (partitioned) {
        exec(statement, "CREATE table  " + db + "." + table + " (a string) PARTITIONED BY (b string)");
      } else{
        exec(statement, "CREATE table  " + db + "." + table + " (a string)");
      }

    }
    statement.close();
    connection.close();
  }

  private void assertSemanticException(Statement stmt, String command) throws SQLException{
    context.assertSentrySemanticException(stmt, command, semanticException);
  }

  @Test
  public void testIndexTable() throws Exception {
    adminCreate(DB1, tableName, true);
    String indexLocation = dfs.getBaseDir() + "/" + Math.random();
    policyFile
        .addPermissionsToRole("index_db1_tb1", privileges.get("index_db1_tb1"))
        .addRolesToGroup(USERGROUP1, "index_db1_tb1")
        .addRolesToGroup(USERGROUP3, "index_db1_tb1")
        .addPermissionsToRole("uri_role", "server=server1->uri=" + indexLocation)
        .addRolesToGroup(USERGROUP3, "uri_role")
        .addPermissionsToRole("insert_db1_tb1", privileges.get("insert_db1_tb1"))
        .addRolesToGroup(USERGROUP2, "insert_db1_tb1");
    writePolicyFile(policyFile);

    Connection connection;
    Statement statement;

    //Positive cases
    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "CREATE INDEX table01_index ON TABLE tb1 (a) AS 'COMPACT' WITH DEFERRED REBUILD");
    exec(statement, "ALTER INDEX table01_index ON tb1 REBUILD");
    statement.close();
    connection.close();

    //Negative case
    connection = context.createConnection(USER2_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    assertSemanticException(statement, "CREATE INDEX table02_index ON TABLE tb1 (a) AS 'COMPACT' WITH DEFERRED REBUILD");
    assertSemanticException(statement, "ALTER INDEX table01_index ON tb1 REBUILD");
    assertSemanticException(statement, "DROP INDEX table01_index ON tb1");
    statement.close();
    connection.close();

    //Positive cases
    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "DROP INDEX table01_index ON tb1");
    statement.close();
    connection.close();

    //Positive case for location
    connection = context.createConnection(USER3_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "CREATE INDEX table01_index ON TABLE tb1 (a) AS 'COMPACT' WITH DEFERRED REBUILD LOCATION '"
        + indexLocation + "'");
    exec(statement, "ALTER INDEX table01_index ON tb1 REBUILD");
    exec(statement, "DROP INDEX table01_index ON tb1");
    statement.close();
    connection.close();

    //Negative case
    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    assertSemanticException(statement, "CREATE INDEX table01_index ON TABLE tb1 (a) AS 'COMPACT' WITH DEFERRED REBUILD " +
            "LOCATION '" + indexLocation + "'");
    statement.close();
    connection.close();
  }

  /* Test all operations that require drop on table alone
  1. Create index : HiveOperation.DROPTABLE
  */
  @Test
  public void testDropTable() throws Exception {
    adminCreate(DB1, tableName, true);
    policyFile
        .addPermissionsToRole("drop_db1_tb1", privileges.get("drop_db1_tb1"))
        .addRolesToGroup(USERGROUP1, "drop_db1_tb1")
        .addPermissionsToRole("insert_db1_tb1", privileges.get("insert_db1_tb1"))
        .addRolesToGroup(USERGROUP2, "insert_db1_tb1");
    writePolicyFile(policyFile);

    Connection connection;
    Statement statement;

    //Negative case
    connection = context.createConnection(USER2_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    assertSemanticException(statement, "drop table " + tableName);

    statement.close();
    connection.close();

    //Positive cases
    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "drop table " + tableName);

    statement.close();
    connection.close();
  }

  @Ignore
  @Test
  public void testLockTable() throws Exception {
    //TODO
  }

  /* Operations that require alter + drop on table
    1. HiveOperation.ALTERTABLE_DROPPARTS
  */
  @Test
  public void dropPartition() throws Exception {
    adminCreate(DB1, tableName, true);
    policyFile
        .addPermissionsToRole("alter_db1_tb1", privileges.get("alter_db1_tb1"))
        .addPermissionsToRole("drop_db1_tb1", privileges.get("drop_db1_tb1"))
        .addRolesToGroup(USERGROUP1, "alter_db1_tb1", "drop_db1_tb1")
        .addRolesToGroup(USERGROUP2, "alter_db1_tb1");

    writePolicyFile(policyFile);

    Connection connection;
    Statement statement;
    //Setup
    connection = context.createConnection(ADMIN1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "ALTER TABLE tb1 ADD IF NOT EXISTS PARTITION (b = '10') ");

    //Negative case
    connection = context.createConnection(USER2_1);
    statement = context.createStatement(connection);
    exec(statement, "USE " + DB1);
    assertSemanticException(statement, "ALTER TABLE tb1 DROP PARTITION (b = 10)");

    //Positive case
    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "ALTER TABLE tb1 DROP PARTITION (b = 10)");
    statement.close();
    connection.close();
  }

  /*
   1. HiveOperation.ALTERTABLE_RENAME
   */
  @Test
  public void renameTablePositive() throws Exception {
    adminCreate(DB1, "TAB_1");
    adminCreate(DB2, "TAB_3");
    adminCreate(DB3, null);
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);
    exec(statement, "CREATE table  " + DB1 + ".TAB_2 (a string)");
    statement.close();
    connection.close();

    policyFile
        .addRolesToGroup(USERGROUP1, "all_db1")
        .addRolesToGroup(USERGROUP1, "drop_db2")
        .addRolesToGroup(USERGROUP1, "create_db3")
        .addRolesToGroup(USERGROUP1, "all_db2_table3")
        .addPermissionsToRole("all_db1", "server=server1->db=" + DB1 + "->action=all")
        .addPermissionsToRole("drop_db2", "server=server1->db=" + DB2 + "->action=drop")
        .addPermissionsToRole("create_db3", "server=server1->db=" + DB3 + "->action=create")
        .addPermissionsToRole("all_db2_table3", "server=server1->db=" + DB2 + "->table=TAB_3" + "->action=all")
        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
    writePolicyFile(policyFile);

    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);

    // user1 have all permission with db_1 and create permission with db_3, alter_table_rename pass
    exec(statement, "use " + DB1);
    exec(statement, "alter table TAB_1 rename to " + DB3 + ".TAB_1");
    exec(statement, "alter table " + DB1 + ".TAB_2 rename to " + DB3 + ".TAB_2");

    // user1 have all permission with db_2.tab_3 and create permission with db_3, alter_table_rename pass
    exec(statement, "use " + DB2);
    exec(statement, "alter table TAB_3 rename to " + DB3 + ".TAB_3");
  }

  /*
   1. HiveOperation.ALTERTABLE_RENAME
   */
  @Test
  public void renameTableNegative() throws Exception {
    adminCreate(DB1, "TAB_1");
    adminCreate(DB2, "TAB_3");
    adminCreate(DB3, "TAB_3");
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);
    exec(statement, "CREATE table  " + DB1 + ".TAB_2 (a string)");
    statement.close();
    connection.close();

    policyFile
        .addRolesToGroup(USERGROUP1, "all_db1")
        .addRolesToGroup(USERGROUP1, "drop_db2")
        .addRolesToGroup(USERGROUP1, "create_db3")
        .addRolesToGroup(USERGROUP1, "all_db2_table3")
        .addPermissionsToRole("all_db1", "server=server1->db=" + DB1 + "->action=all")
        .addPermissionsToRole("drop_db2", "server=server1->db=" + DB2 + "->action=drop")
        .addPermissionsToRole("create_db3", "server=server1->db=" + DB3 + "->action=create")
        .addPermissionsToRole("all_db2_table3", "server=server1->db=" + DB2 + "->table=TAB_3" + "->action=all")
        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
    writePolicyFile(policyFile);

    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    // user1 haven't create permission with db_2, can't move table to db_2
    exec(statement, "use " + DB1);
    try {
      exec(statement, "alter table TAB_1 rename to " + DB2 + ".TAB_1");
      fail("the exception should be thrown");
    } catch (Exception e) {
      // ignore the exception
    }
    try {
      // test with the format of table name: db.table
      exec(statement, "alter table " + DB1 + ".TAB_1 rename to " + DB2 + ".TAB_1");
      fail("the exception should be thrown");
    } catch (Exception e) {
      // ignore the exception
    }

    // user1 haven't create permission with db_2, can't move table from db_2
    exec(statement, "use " + DB2);
    try {
      exec(statement, "alter table TAB_3 rename to " + DB2 + ".TAB_1");
      fail("the exception should be thrown");
    } catch (Exception e) {
      // ignore the exception
    }
    try {
      // test with the format of table name: db.table
      exec(statement, "alter table " + DB2 + ".TAB_3 rename to " + DB2 + ".TAB_1");
      fail("the exception should be thrown");
    } catch (Exception e) {
      // ignore the exception
    }

    // user1 does not have all permission with db_3.tab_3, cannot move table to db_3.tab_4
    exec(statement, "use " + DB3);
    try {
      exec(statement, "alter table TAB_3 rename to TAB_4");
      fail("the exception should be thrown");
    } catch (Exception e) {
      // ignore the exception
    }
  }

  /* Test all operations which require alter on table (+ all on URI)
   1. HiveOperation.ALTERTABLE_LOCATION
   2. HiveOperation.ALTERTABLE_ADDPARTS
   3. TODO: HiveOperation.ALTERPARTITION_LOCATION
   4. TODO: HiveOperation.ALTERTBLPART_SKEWED_LOCATION
   */
  @Test
  public void testAlterOnTableAndURI() throws Exception {
    adminCreate(DB1, tableName, true);
    String tabLocation = dfs.getBaseDir() + "/" + Math.random();
    policyFile
        .addPermissionsToRole("alter_db1_tb1", privileges.get("alter_db1_tb1"))
        .addPermissionsToRole("all_uri", "server=server1->uri=" + tabLocation)
        .addRolesToGroup(USERGROUP1, "alter_db1_tb1", "all_uri")
        .addRolesToGroup(USERGROUP2, "alter_db1_tb1");

    writePolicyFile(policyFile);

    //Case with out uri
    Connection connection = context.createConnection(USER2_1);
    Statement statement = context.createStatement(connection);
    exec(statement, "USE " + DB1);
    assertSemanticException(statement, "ALTER TABLE tb1 SET LOCATION '" + tabLocation + "'");
    assertSemanticException(statement, "ALTER TABLE tb1 ADD IF NOT EXISTS PARTITION (b = '3') LOCATION '" + tabLocation + "/part'");
    exec(statement, "ALTER TABLE tb1 ADD IF NOT EXISTS PARTITION (b = '1') ");

    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "ALTER TABLE tb1 SET LOCATION '" + tabLocation + "'");
    exec(statement, "ALTER TABLE tb1 ADD IF NOT EXISTS PARTITION (b = '3') LOCATION '" + tabLocation + "/part'");
    exec(statement, "ALTER TABLE tb1 ADD IF NOT EXISTS PARTITION (b = '10') ");
    statement.close();
    connection.close();

    //Negative case: User2_1 has privileges on table but on on uri
    connection = context.createConnection(USER2_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    context.assertSentrySemanticException(statement, "ALTER TABLE tb1 SET LOCATION '" + tabLocation + "'",
        semanticException);
    context.assertSentrySemanticException(statement,
        "ALTER TABLE tb1 ADD IF NOT EXISTS PARTITION (b = '3') LOCATION '" + tabLocation + "/part'",
        semanticException);
    statement.close();
    connection.close();

    //Negative case: User3_1 has only insert privileges on table
    policyFile
        .addPermissionsToRole("insert_db1_tb1", privileges.get("insert_db1_tb1"))
        .addRolesToGroup(USERGROUP3, "insert_db1_tb1", "all_uri");
    writePolicyFile(policyFile);

    connection = context.createConnection(USER3_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    assertSemanticException(statement, "ALTER TABLE tb1 ADD IF NOT EXISTS PARTITION (b = '2') ");
    assertSemanticException(statement, "ALTER TABLE tb1 SET LOCATION '" + tabLocation + "'");

    assertSemanticException(statement, "ALTER TABLE tb1 ADD IF NOT EXISTS PARTITION (b = '3') LOCATION '"
        + tabLocation + "/part'");
    statement.close();
    connection.close();


  }

  /* Create on Database and select on table
  1. Create view :  HiveOperation.CREATEVIEW
   */
  @Test
  public void testCreateView() throws Exception {
    adminCreate(DB1, tableName);
    adminCreate(DB2, null);
    policyFile
        .addPermissionsToRole("select_db1_tb1", privileges.get("select_db1_tb1"))
        .addPermissionsToRole("create_db2", privileges.get("create_db2"))
        .addRolesToGroup(USERGROUP1, "select_db1_tb1", "create_db2");
    writePolicyFile(policyFile);

    Connection connection = context.createConnection(USER1_1);
    Statement statement = context.createStatement(connection);
    exec(statement, "use " + DB2);
    exec(statement, "create view view1 as select a from " + DB1 + ".tb1");
    statement.close();
    connection.close();

    //Negative case
    policyFile
        .addPermissionsToRole("insert_db1_tb1", privileges.get("insert_db1_tb1"))
        .addRolesToGroup(USERGROUP3, "insert_db1_tb1", "create_db2");
    writePolicyFile(policyFile);

    connection = context.createConnection(USER3_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB2);
    context.assertSentrySemanticException(statement, "create view view1 as select a from " + DB1 + ".tb1",
        semanticException);
    statement.close();
    connection.close();


  }

  /*
   1. HiveOperation.IMPORT : Create on db + all on URI
   2. HiveOperation.EXPORT : SELECT on table + all on uri
   */

  @Test
  public void testExportImport() throws Exception {
    File dataFile;
    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();

    dropDb(ADMIN1, DB1);
    createDb(ADMIN1, DB1);
    createTable(ADMIN1, DB1, dataFile, tableName);
    String location = dfs.getBaseDir() + "/" + Math.random();
    policyFile
        .addPermissionsToRole("create_db1", privileges.get("create_db1"))
        .addPermissionsToRole("all_uri", "server=server1->uri="+ location)
        .addPermissionsToRole("select_db1_tb1", privileges.get("select_db1_tb1"))
        .addPermissionsToRole("insert_db1", privileges.get("insert_db1"))
        .addRolesToGroup(USERGROUP1, "select_db1_tb1", "all_uri")
        .addRolesToGroup(USERGROUP2, "create_db1", "all_uri")
        .addRolesToGroup(USERGROUP3, "insert_db1", "all_uri");
    writePolicyFile(policyFile);
    Connection connection;
    Statement statement;

    //Negative case
    connection = context.createConnection(USER3_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    // Import/Export works with s3 storage system only when this is turned on.
    exec(statement, "set hive.exim.uri.scheme.whitelist=hdfs,pfile,s3a;");
    context.assertSentrySemanticException(statement, "export table tb1 to '" + location + "'",
        semanticException);
    statement.close();
    connection.close();

    //Positive
    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "set hive.exim.uri.scheme.whitelist=hdfs,pfile,s3a;");
    exec(statement, "export table tb1 to '" + location + "'" );
    statement.close();
    connection.close();

    //Negative
    connection = context.createConnection(USER3_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "set hive.exim.uri.scheme.whitelist=hdfs,pfile,s3a;");
    context.assertSentrySemanticException(statement, "import table tb2 from '" + location + "'",
        semanticException);
    statement.close();
    connection.close();

    //Positive
    connection = context.createConnection(USER2_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "set hive.exim.uri.scheme.whitelist=hdfs,pfile,s3a;");
    exec(statement, "import table tb2 from '" + location + "'");
    statement.close();
    connection.close();

  }

  /*
  1. HiveOperation.LOAD: INSERT on table + all on uri
   */
  @Test
  public void testLoad() throws Exception {
    File dataFile;
    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();

    adminCreate(DB1, tableName);

    policyFile
        .addPermissionsToRole("insert_db1_tb1", privileges.get("insert_db1_tb1"))
        .addPermissionsToRole("all_uri", "server=server1->uri=file://" + dataDir)
        .addRolesToGroup(USERGROUP1, "insert_db1_tb1", "all_uri");
    writePolicyFile(policyFile);

    Connection connection = context.createConnection(USER1_1);
    Statement statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "load data local inpath '" + dataFile.getPath() + "' into table tb1" );
    statement.close();
    connection.close();
  }

  /*
  1. HiveOperation.CREATETABLE_AS_SELECT : Create on db + select on table
   */
  @Test
  public void testCTAS() throws Exception {
    adminCreate(DB1, tableName);
    adminCreate(DB2, null);

    String location = dfs.getBaseDir() + "/" + Math.random();

    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);
    exec(statement, "Use " + DB1);
    exec(statement, "create view view1 as select a from " + DB1 + ".tb1");
    statement.close();
    connection.close();

    policyFile
        .addPermissionsToRole("select_db1_tb1", privileges.get("select_db1_tb1"))
        .addPermissionsToRole("select_db1_view1", privileges.get("select_db1_view1"))
        .addPermissionsToRole("create_db2", privileges.get("create_db2"))
        .addPermissionsToRole("all_uri", "server=server1->uri=" + location)
        .addRolesToGroup(USERGROUP1, "select_db1_tb1", "create_db2")
        .addRolesToGroup(USERGROUP2, "select_db1_view1", "create_db2")
        .addRolesToGroup(USERGROUP3, "select_db1_tb1", "create_db2,all_uri");
    writePolicyFile(policyFile);

    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB2);
    exec(statement, "create table tb2 as select a from " + DB1 + ".tb1");
    //Ensure CTAS fails without URI
    context.assertSentrySemanticException(statement, "create table tb3 location '" + location +
            "' as select a from " + DB1 + ".tb1",
        semanticException);
    context.assertSentrySemanticException(statement, "create table tb3 as select a from " + DB1 + ".view1",
        semanticException);


    statement.close();
    connection.close();

    connection = context.createConnection(USER2_1);
    statement = context.createStatement(connection);
    exec(statement, "Use " + DB2);
    exec(statement, "create table tb3 as select a from " + DB1 + ".view1" );
    context.assertSentrySemanticException(statement, "create table tb4 as select a from " + DB1 + ".tb1",
        semanticException);

    statement.close();
    connection.close();

    connection = context.createConnection(USER3_1);
    statement = context.createStatement(connection);
    //CTAS is valid with URI
    exec(statement, "Use " + DB2);
    exec(statement, "create table tb4 location '" + location +
        "' as select a from " + DB1 + ".tb1");

    statement.close();
    connection.close();

  }


  /*
  1. INSERT : IP: select on table, OP: insert on table + all on uri(optional)
   */
  @Test
  public void testInsert() throws Exception {
    File dataFile;
    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();

    dropDb(ADMIN1, DB1);
    dropDb(ADMIN1, DB2);
    createDb(ADMIN1, DB1);
    createDb(ADMIN1, DB2);
    createTable(ADMIN1, DB1, dataFile, tableName);
    createTable(ADMIN1, DB2, null, "tb2");
    String location = dfs.getBaseDir() + "/" + Math.random();

    policyFile
        .addPermissionsToRole("select_db1_tb1", privileges.get("select_db1_tb1"))
        .addPermissionsToRole("insert_db2_tb2", privileges.get("insert_db2_tb2"))
        .addRolesToGroup(USERGROUP1, "select_db1_tb1", "insert_db2_tb2")
        .addPermissionsToRole("all_uri", "server=server1->uri=" + location)
        .addRolesToGroup(USERGROUP2, "select_db1_tb1", "all_uri");
    writePolicyFile(policyFile);

    Connection connection = context.createConnection(USER1_1);
    Statement statement = context.createStatement(connection);
    assertSemanticException(statement, "insert overwrite directory '" + location + "' select * from " + DB1 + ".tb1");
    exec(statement, "insert overwrite table " + DB2 + ".tb2 select * from " + DB1 + ".tb1");
    statement.close();
    connection.close();

    connection = context.createConnection(USER2_1);
    statement = context.createStatement(connection);
    exec(statement, "insert overwrite directory '" + location + "' select * from " + DB1 + ".tb1" );
    assertSemanticException(statement, "insert overwrite table " + DB2 + ".tb2 select * from " + DB1 + ".tb1");
    statement.close();
    connection.close();
  }

  @Test
  public void testFullyQualifiedTableName() throws Exception{
    Connection connection;
    Statement statement;
    connection = context.createConnection(ADMIN1);
    statement = context.createStatement(connection);
    exec(statement, "create database " + DB1);
    exec(statement, "create table " + DB1 + ".tb1(a int)");
    exec(statement, "DROP table " + DB1 + ".tb1");
    exec(statement, "create table " + DB1 + ".tb1(a int)");
    exec(statement, "use " + DB1);
    exec(statement, "drop table tb1");
  }

  @Test
  public void testExternalTables() throws Exception{
    createDb(ADMIN1, DB1);
    File externalTblDir = new File(dataDir, "exttab");
    assertTrue("Unable to create directory for external table test" , externalTblDir.mkdir());

    policyFile
        .addPermissionsToRole("create_db1", privileges.get("create_db1"))
        .addPermissionsToRole("all_uri", "server=server1->uri=file://" + dataDir.getPath())
        .addRolesToGroup(USERGROUP1, "create_db1", "all_uri")
        .addRolesToGroup(USERGROUP2, "create_db1");
    writePolicyFile(policyFile);

    Connection connection = context.createConnection(USER2_1);
    Statement statement = context.createStatement(connection);
    assertSemanticException(statement, "create external table " + DB1 + ".tb1(a int) stored as " +
        "textfile location 'file:" + externalTblDir.getAbsolutePath() + "'");
    //Create external table on HDFS
    assertSemanticException(statement, "create external table " + DB1 + ".tb2(a int) location '/user/hive/warehouse/blah'");
    statement.close();
    connection.close();

    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    exec(statement, "create external table " + DB1 + ".tb1(a int) stored as " +
        "textfile location 'file:" + externalTblDir.getAbsolutePath() + "'");
    statement.close();
    connection.close();


  }

  @Test
  public void testCaseSensitivity() throws Exception {
    Statement statement = null;
    Connection connection = null;
    try {
      createDb(ADMIN1, DB1);
      String scratchLikeDir = context.getProperty(HiveConf.ConfVars.SCRATCHDIR.varname);
      LOGGER.info("scratch like dir = " + scratchLikeDir);
      String extParentDir = scratchLikeDir + "/ABC/hhh";
      String extTableDir = scratchLikeDir + "/abc/hhh";
      LOGGER.info("Creating extParentDir = " + extParentDir + ", extTableDir = " + extTableDir);
      dfs.assertCreateDir(extParentDir);
      dfs.assertCreateDir(extTableDir);

      if (! (extParentDir.toLowerCase().startsWith("hdfs://")
          || extParentDir.toLowerCase().startsWith("s3://")
          || extParentDir.contains("://"))) {
        String scheme = fileSystem.getUri().toString();
        LOGGER.info("scheme = " + scheme);
        extParentDir = scheme + extParentDir;
        extTableDir = scheme + extTableDir;
        LOGGER.info("Add scheme in extParentDir = " + extParentDir + ", extTableDir = " + extTableDir);
      }

      policyFile
          .addPermissionsToRole("all_db1", privileges.get("all_db1"))
          .addPermissionsToRole("all_uri", "server=server1->uri=" + extParentDir)
          .addRolesToGroup(USERGROUP1, "all_db1", "all_uri");
      writePolicyFile(policyFile);
      connection = context.createConnection(USER1_1);
      statement = context.createStatement(connection);
      assertSemanticException(statement,
          "create external table " + DB1 + ".tb1(a int) location '" + extTableDir + "'");
    } finally {
      if (statement != null) {
        statement.close();
      }
      if (connection != null) {
        connection.close();
      }
    }
  }
}
