/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.sentry.tests.e2e.dbprovider;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.sql.Connection;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.sentry.provider.db.log.appender.AuditLoggerTestAppender;
import org.apache.sentry.provider.db.log.util.CommandUtil;
import org.apache.sentry.provider.db.log.util.Constants;
import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
import org.codehaus.jettison.json.JSONObject;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

public class TestDbDDLAuditLog extends AbstractTestWithStaticConfiguration {

  @BeforeClass
  public static void setupTestStaticConfiguration() throws Exception {
    useSentryService = true;
    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
    Logger logger = Logger.getLogger("sentry.hive.authorization.ddl.logger");
    AuditLoggerTestAppender testAppender = new AuditLoggerTestAppender();
    logger.addAppender(testAppender);
    logger.setLevel(Level.INFO);
  }

  @Override
  @Before
  public void setup() throws Exception {
    super.setupAdmin();
    super.setup();
  }

  @Test
  @Ignore
  public void testBasic() throws Exception {
    String roleName = "testRole";
    String groupName = "testGroup";
    String dbName = "dbTest";
    String tableName = "tableTest";
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);
    Map<String, String> fieldValueMap = new HashMap<String, String>();

    // for success audit log
    statement.execute("CREATE ROLE " + roleName);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_CREATE_ROLE);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "CREATE ROLE " + roleName);
    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
    fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
    assertAuditLog(fieldValueMap);

    statement.execute("GRANT ROLE " + roleName + " TO GROUP " + groupName);
    fieldValueMap.clear();
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_ADD_ROLE);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ROLE " + roleName + " TO GROUP "
        + groupName);
    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
    fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
    assertAuditLog(fieldValueMap);

    statement.execute("create database " + dbName);
    statement.execute("use " + dbName);
    statement.execute("CREATE TABLE " + tableName + " (c1 string)");
    statement.execute("GRANT ALL ON DATABASE " + dbName + " TO ROLE " + roleName);
    fieldValueMap.clear();
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ALL ON DATABASE " + dbName
        + " TO ROLE " + roleName);
    fieldValueMap.put(Constants.LOG_FIELD_DATABASE_NAME, dbName);
    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
    fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
    assertAuditLog(fieldValueMap);

    statement.execute("GRANT SELECT ON TABLE " + tableName + " TO ROLE " + roleName
        + " WITH GRANT OPTION");
    fieldValueMap.clear();
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT SELECT ON TABLE " + tableName
        + " TO ROLE " + roleName + " WITH GRANT OPTION");
    fieldValueMap.put(Constants.LOG_FIELD_TABLE_NAME, tableName);
    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
    fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
    assertAuditLog(fieldValueMap);

    // for error audit log
    try {
      statement.execute("CREATE ROLE " + roleName);
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_CREATE_ROLE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "CREATE ROLE " + roleName);
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }
    try {
      statement.execute("GRANT ROLE errorROLE TO GROUP " + groupName);
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_ADD_ROLE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ROLE errorROLE TO GROUP "
          + groupName);
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }
    try {
      statement.execute("GRANT ALL ON DATABASE " + dbName + " TO ROLE errorRole");
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ALL ON DATABASE " + dbName
          + " TO ROLE errorRole");
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }
    try {
      statement.execute("GRANT INSERT ON DATABASE " + dbName + " TO ROLE errorRole");
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT INSERT ON DATABASE " + dbName
          + " TO ROLE errorRole");
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }
    try {
      statement.execute("GRANT SELECT ON DATABASE " + dbName + " TO ROLE errorRole");
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT SELECT ON DATABASE " + dbName
          + " TO ROLE errorRole");
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }
    try {
      statement.execute("GRANT SELECT ON TABLE " + tableName + " TO ROLE errorRole");
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT SELECT ON TABLE " + tableName
          + " TO ROLE errorRole");
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }

    statement.execute("REVOKE SELECT ON TABLE " + tableName + " FROM ROLE " + roleName);
    fieldValueMap.clear();
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE SELECT ON TABLE " + tableName
        + " FROM ROLE " + roleName);
    fieldValueMap.put(Constants.LOG_FIELD_TABLE_NAME, tableName);
    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
    fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
    assertAuditLog(fieldValueMap);

    statement.execute("REVOKE ALL ON DATABASE " + dbName + " FROM ROLE " + roleName);
    fieldValueMap.clear();
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ALL ON DATABASE " + dbName
        + " FROM ROLE " + roleName);
    fieldValueMap.put(Constants.LOG_FIELD_DATABASE_NAME, dbName);
    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
    fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
    assertAuditLog(fieldValueMap);

    statement.execute("REVOKE ROLE " + roleName + " FROM GROUP " + groupName);
    fieldValueMap.clear();
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DELETE_ROLE);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ROLE " + roleName
        + " FROM GROUP " + groupName);
    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
    fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
    assertAuditLog(fieldValueMap);

    statement.execute("DROP ROLE " + roleName);
    fieldValueMap.clear();
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DROP_ROLE);
    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "DROP ROLE " + roleName);
    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
    fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
    assertAuditLog(fieldValueMap);

    // for error audit log
    try {
      statement.execute("REVOKE SELECT ON TABLE " + tableName + " FROM ROLE errorRole");
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE SELECT ON TABLE " + tableName
          + " FROM ROLE errorRole");
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }

    try {
      statement.execute("REVOKE ALL ON DATABASE " + dbName + " FROM ROLE errorRole");
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ALL ON DATABASE " + dbName
          + " FROM ROLE errorRole");
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }

    try {
      statement.execute("REVOKE ROLE errorRole FROM GROUP " + groupName);
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DELETE_ROLE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ROLE errorRole FROM GROUP "
          + groupName);
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }

    try {
      statement.execute("DROP ROLE errorRole");
      fail("Exception should have been thrown");
    } catch (Exception e) {
      fieldValueMap.clear();
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DROP_ROLE);
      fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "DROP ROLE errorRole");
      fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE);
      fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
      assertAuditLog(fieldValueMap);
    }

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

  private void assertAuditLog(Map<String, String> fieldValueMap) throws Exception {
    assertThat(AuditLoggerTestAppender.getLastLogLevel(), is(Level.INFO));
    JSONObject jsonObject = new JSONObject(AuditLoggerTestAppender.getLastLogEvent());
    if (fieldValueMap != null) {
      for (Map.Entry<String, String> entry : fieldValueMap.entrySet()) {
        String entryKey = entry.getKey();
        if (Constants.LOG_FIELD_IP_ADDRESS.equals(entryKey)) {
          assertTrue(CommandUtil.assertIPInAuditLog(jsonObject.get(entryKey).toString()));
        } else {
          assertTrue(entry.getValue().equalsIgnoreCase(jsonObject.get(entryKey).toString()));
        }
      }
    }
  }
}