/**
 * 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.binding.metastore;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
import org.apache.hadoop.hive.ql.metadata.AuthorizationException;
import org.apache.hadoop.hive.ql.plan.HiveOperation;
import org.apache.sentry.binding.hive.authz.HiveAuthzBinding;
import org.apache.sentry.binding.hive.authz.HiveAuthzPrivileges;
import org.apache.sentry.binding.hive.authz.HiveAuthzPrivileges.HiveOperationScope;
import org.apache.sentry.binding.hive.authz.HiveAuthzPrivileges.HiveOperationType;
import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
import org.apache.sentry.core.common.Subject;
import org.apache.sentry.core.model.db.Column;
import org.apache.sentry.core.model.db.DBModelAction;
import org.apache.sentry.core.model.db.DBModelAuthorizable;
import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
import org.apache.sentry.core.model.db.Database;
import org.apache.sentry.core.model.db.Server;
import org.apache.sentry.core.model.db.Table;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

/**
 * Testing classes for the {@code }SentryMetaStoreFilterHook}. {@code} SentryMetaStoreFilterHook}
 * may be used by the HMS server to filter databases, tables and partitions that are authorized
 * to be seen by a user making the HMS request.
 */
public class TestSentryMetaStoreFilterHook {
  // Mock the HiveAuthzBinding to avoid making real connections to a Sentry server
  private HiveAuthzBinding mockBinding = Mockito.mock(HiveAuthzBinding.class);
  private final HiveAuthzPrivileges LIST_DATABASES_PRIVILEGES = new HiveAuthzPrivileges.AuthzPrivilegeBuilder()
      .addInputObjectPriviledge(
          AuthorizableType.Column,
          EnumSet.of(
              DBModelAction.SELECT, DBModelAction.INSERT, DBModelAction.ALTER,
              DBModelAction.CREATE, DBModelAction.DROP, DBModelAction.INDEX,
              DBModelAction.LOCK))
      .addInputObjectPriviledge(AuthorizableType.URI, EnumSet.of(DBModelAction.SELECT))
      .setOperationScope(HiveOperationScope.CONNECT)
      .setOperationType(HiveOperationType.QUERY)
      .build();
  private final HiveAuthzPrivileges LIST_TABLES_PRIVILEGES = new HiveAuthzPrivileges.AuthzPrivilegeBuilder()
      .addInputObjectPriviledge(
          AuthorizableType.Column,
          EnumSet.of(
              DBModelAction.SELECT, DBModelAction.INSERT, DBModelAction.ALTER,
              DBModelAction.CREATE, DBModelAction.DROP, DBModelAction.INDEX, DBModelAction.LOCK))
      .setOperationScope(HiveOperationScope.TABLE)
      .setOperationType(
          HiveAuthzPrivileges.HiveOperationType.INFO)
      .build();
  private HiveAuthzConf authzConf = new HiveAuthzConf();
  private final Server SERVER1 = new Server("server1");

  // Mock the authorize() method to throw an exception for the following list of databases
  private void restrictDatabaseNamesOnBinding(String username, List<String> dbNames) {
    for (String dbName : dbNames) {
      Database database = new Database(dbName);
      List<DBModelAuthorizable> authorizable = Arrays.asList(
        SERVER1, database, Table.ALL, Column.ALL
      );

      Mockito.doThrow(new AuthorizationException())
        .when(mockBinding).authorize(HiveOperation.SHOWDATABASES, LIST_DATABASES_PRIVILEGES, new Subject(username),
        Collections.singleton(authorizable), Collections.emptySet());
    }
  }

  // Mock the authorize() method to throw an exception for the following list of databases
  private void restrictTablesNamesOnBinding(String username, String dbName, List<String> tableNames) {
    Database database = new Database(dbName);

    for (String tableName : tableNames) {
      Table table = new Table(tableName);
      List<DBModelAuthorizable> authorizable = Arrays.asList(
        SERVER1, database, table, Column.ALL
      );

      Mockito.doThrow(new AuthorizationException())
        .when(mockBinding).authorize(HiveOperation.SHOWTABLES,
        LIST_TABLES_PRIVILEGES, new Subject(username), Collections.singleton(authorizable), Collections.emptySet());
    }
  }

  // Returns a mock of the HiveAuthzBindingFactory with the userName wrapped inside.
  private HiveAuthzBindingFactory getMockBinding(String userName) {
    return new HiveAuthzBindingFactory() {
      @Override
      public HiveAuthzBinding fromMetaStoreConf(HiveConf hiveConf, HiveAuthzConf authzConf) throws Exception {
        return mockBinding;
      }

      @Override
      public String getUserName() {
        return userName;
      }
    };
  }

  private org.apache.hadoop.hive.metastore.api.Database newHmsDatabase(String dbName) {
    org.apache.hadoop.hive.metastore.api.Database db =
      new org.apache.hadoop.hive.metastore.api.Database();

    db.setName(dbName);
    return db;
  }

  private org.apache.hadoop.hive.metastore.api.Table newHmsTable(String dbName, String tableName) {
    org.apache.hadoop.hive.metastore.api.Table table =
      new org.apache.hadoop.hive.metastore.api.Table();

    table.setDbName(dbName);
    table.setTableName(tableName);
    return table;
  }

  @Before
  public void setup() {
    // Reset the mocks in case it was modified on the test methods
    Mockito.reset(mockBinding);

    Mockito.when(mockBinding.getAuthServer()).thenReturn(SERVER1);
    Mockito.when(mockBinding.getAuthzConf()).thenReturn(authzConf);
  }

  @Test
  public void testFilterListOfDatabases() {
    final String USER1 = "user1";
    SentryMetaStoreFilterHook filterHook = new SentryMetaStoreFilterHook(null, authzConf,
      getMockBinding(USER1));

    // Verify that only db2 is returned by the filter
    restrictDatabaseNamesOnBinding(USER1, Arrays.asList("db1", "db3"));
    assertThat(filterHook.filterDatabases(Arrays.asList("db1", "db2", "db3"))).containsExactly("db2");
  }

  @Test
  public void testFilterSingleDatabase() throws NoSuchObjectException {
    final String USER1 = "user1";
    SentryMetaStoreFilterHook filterHook = new SentryMetaStoreFilterHook(null, authzConf,
      getMockBinding(USER1));

    restrictDatabaseNamesOnBinding(USER1, Arrays.asList("db1", "db3"));

    // db1 and db3 must be denied
    assertThatExceptionOfType(NoSuchObjectException.class)
      .isThrownBy(() -> filterHook.filterDatabase(newHmsDatabase("db1")));
    assertThatExceptionOfType(NoSuchObjectException.class)
      .isThrownBy(() -> filterHook.filterDatabase(newHmsDatabase("db3")));

    // db2 must be allowed
    assertThat(filterHook.filterDatabase(newHmsDatabase("db2")))
      .isEqualTo(newHmsDatabase("db2"));
  }

  @Test
  public void testFilterListOfTables() {
    final String USER1 = "user1";
    final String DB1 = "db1";
    SentryMetaStoreFilterHook filterHook = new SentryMetaStoreFilterHook(null, authzConf,
      getMockBinding(USER1));

    // Verify that only t2 is returned by the filter
    restrictTablesNamesOnBinding(USER1, DB1, Arrays.asList("t1", "t3"));
    assertThat(filterHook.filterTableNames(DB1, Arrays.asList("t1", "t2", "t3"))).containsExactly("t2");
    assertThat(filterHook.filterTables(Arrays.asList(
      newHmsTable(DB1, "t1"),
      newHmsTable(DB1, "t2"),
      newHmsTable(DB1, "t3")
    ))).containsExactly(newHmsTable(DB1, "t2"));
  }

  @Test
  public void testFilterSingleTable() throws NoSuchObjectException {
    final String USER1 = "user1";
    final String DB1 = "db1";
    SentryMetaStoreFilterHook filterHook = new SentryMetaStoreFilterHook(null, authzConf,
      getMockBinding(USER1));

    restrictTablesNamesOnBinding(USER1, DB1, Arrays.asList("t1", "t3"));

    // t1 and t3 must be denied
    assertThatExceptionOfType(NoSuchObjectException.class)
      .isThrownBy(() -> filterHook.filterTable(newHmsTable(DB1, "t1")));
    assertThatExceptionOfType(NoSuchObjectException.class)
      .isThrownBy(() -> filterHook.filterTable(newHmsTable(DB1, "t3")));

    // t2 must be allowed
    assertThat(filterHook.filterTable(newHmsTable(DB1, "t2")))
      .isEqualTo(newHmsTable(DB1, "t2"));
  }
}
