// 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.

#include "kudu/ranger/ranger_client.h"

#include <cstddef>
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include <boost/functional/hash/hash.hpp>
#include <gflags/gflags_declare.h>
#include <glog/logging.h>
#include <google/protobuf/any.pb.h>
#include <gtest/gtest.h>

#include "kudu/gutil/map-util.h"
#include "kudu/gutil/ref_counted.h"
#include "kudu/gutil/strings/join.h"
#include "kudu/gutil/strings/split.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/ranger/mini_ranger.h"
#include "kudu/ranger/ranger.pb.h"
#include "kudu/subprocess/server.h"
#include "kudu/subprocess/subprocess.pb.h"
#include "kudu/util/env.h"
#include "kudu/util/env_util.h"
#include "kudu/util/faststring.h"
#include "kudu/util/metrics.h"
#include "kudu/util/path_util.h"
#include "kudu/util/status.h"
#include "kudu/util/test_macros.h"
#include "kudu/util/test_util.h"

DECLARE_string(log_dir);
DECLARE_string(ranger_config_path);
DECLARE_string(ranger_log_config_dir);
DECLARE_string(ranger_log_level);
DECLARE_bool(ranger_logtostdout);
DECLARE_bool(ranger_overwrite_log_config);

using boost::hash_combine;
using kudu::env_util::ListFilesInDir;
using kudu::subprocess::SubprocessMetrics;
using kudu::subprocess::SubprocessRequestPB;
using kudu::subprocess::SubprocessResponsePB;
using kudu::subprocess::SubprocessServer;
using std::move;
using std::string;
using std::unordered_map;
using std::unordered_set;
using std::vector;
using strings::SkipEmpty;
using strings::Split;
using strings::Substitute;

namespace kudu {
namespace ranger {

struct AuthorizedAction {
  string user_name;
  ActionPB action;
  string database_name;
  string table_name;
  string column_name;

  bool operator==(const AuthorizedAction& rhs) const {
    return user_name == rhs.user_name &&
      action == rhs.action &&
      database_name == rhs.database_name &&
      table_name == rhs.table_name &&
      column_name == rhs.column_name;
  }
};

struct AuthorizedActionHash {
 public:
  size_t operator()(const AuthorizedAction& action) const {
    size_t seed = 0;
    hash_combine(seed, action.action);
    hash_combine(seed, action.column_name);
    hash_combine(seed, action.database_name);
    hash_combine(seed, action.table_name);
    hash_combine(seed, action.user_name);

    return seed;
  }
};

class MockSubprocessServer : public SubprocessServer {
 public:
  unordered_set<AuthorizedAction, AuthorizedActionHash> next_response_;

  Status Init() override {
    // don't want to start anything
    return Status::OK();
  }

  ~MockSubprocessServer() override {}

  MockSubprocessServer()
      : SubprocessServer(Env::Default(), "", {"mock"}, SubprocessMetrics()) {}

  Status Execute(SubprocessRequestPB* req,
                 SubprocessResponsePB* resp) override {
    RangerRequestListPB req_list;
    CHECK(req->request().UnpackTo(&req_list));

    RangerResponseListPB resp_list;

    for (const RangerRequestPB& req : req_list.requests()) {
      AuthorizedAction action;
      action.user_name = req_list.user();
      action.action = req.action();
      action.table_name = req.table();
      action.database_name = req.database();
      action.column_name = req.has_column() ? req.column() : "";

      auto r = resp_list.add_responses();
      r->set_allowed(ContainsKey(next_response_, action));
    }

    resp->mutable_response()->PackFrom(resp_list);

    return Status::OK();
  }
};

class RangerClientTest : public KuduTest {
 public:
  RangerClientTest() :
    client_(env_, METRIC_ENTITY_server.Instantiate(&metric_registry_, "ranger_client-test")) {}

  void SetUp() override {
    std::unique_ptr<MockSubprocessServer> server(new MockSubprocessServer());
    next_response_ = &server->next_response_;
    client_.ReplaceServerForTests(std::move(server));
  }

  void Allow(string user_name, ActionPB action, string database_name,
             string table_name, string column_name = "") {
    AuthorizedAction authorized_action;
    authorized_action.user_name = move(user_name);
    authorized_action.action = action;
    authorized_action.database_name = move(database_name);
    authorized_action.table_name = move(table_name);
    authorized_action.column_name = move(column_name);

    next_response_->emplace(authorized_action);
  }

 protected:
  MetricRegistry metric_registry_;
  unordered_set<AuthorizedAction, AuthorizedActionHash>* next_response_;
  RangerClient client_;
};

TEST_F(RangerClientTest, TestAuthorizeCreateTableUnauthorized) {
  bool authorized;
  ASSERT_OK(client_.AuthorizeAction("jdoe", ActionPB::CREATE, "bar", "baz", /*is_owner=*/false,
                                    /*requires_delegate_admin=*/false, &authorized));
  ASSERT_FALSE(authorized);
}

TEST_F(RangerClientTest, TestAuthorizeCreateTableAuthorized) {
  Allow("jdoe", ActionPB::CREATE, "foo", "bar");
  bool authorized;
  ASSERT_OK(client_.AuthorizeAction("jdoe", ActionPB::CREATE, "foo", "bar", /*is_owner=*/false,
                                    /*requires_delegate_admin=*/false, &authorized));
  ASSERT_TRUE(authorized);
}

TEST_F(RangerClientTest, TestAuthorizeListNoTables) {
  unordered_map<string, bool> tables;
  ASSERT_OK(client_.AuthorizeActionMultipleTables("jdoe", ActionPB::METADATA, &tables));
  ASSERT_EQ(0, tables.size());
}

TEST_F(RangerClientTest, TestAuthorizeListNoTablesAuthorized) {
  unordered_map<string, bool> tables;
  tables.emplace("foo.bar", false);
  tables.emplace("foo.baz", false);
  ASSERT_OK(client_.AuthorizeActionMultipleTables("jdoe", ActionPB::METADATA, &tables));
  ASSERT_EQ(0, tables.size());
}

TEST_F(RangerClientTest, TestAuthorizeMetadataSubsetOfTablesAuthorized) {
  Allow("jdoe", ActionPB::METADATA, "default", "foobar");
  unordered_map<string, bool> tables;
  tables.emplace("default.foobar", false);
  tables.emplace("barbaz", false);
  ASSERT_OK(client_.AuthorizeActionMultipleTables("jdoe", ActionPB::METADATA, &tables));
  ASSERT_EQ(1, tables.size());
  ASSERT_EQ("default.foobar", tables.begin()->first);
}

TEST_F(RangerClientTest, TestAuthorizeMetadataAllAuthorized) {
  Allow("jdoe", ActionPB::METADATA, "default", "foobar");
  Allow("jdoe", ActionPB::METADATA, "default", "barbaz");
  unordered_map<string, bool> tables;
  tables.emplace("default.foobar", false);
  tables.emplace("barbaz", false);
  ASSERT_OK(client_.AuthorizeActionMultipleTables("jdoe", ActionPB::METADATA, &tables));
  ASSERT_EQ(2, tables.size());
  ASSERT_TRUE(ContainsKey(tables, "default.foobar"));
  ASSERT_TRUE(ContainsKey(tables, "barbaz"));
}

TEST_F(RangerClientTest, TestAuthorizeMetadataAllNonRanger) {
  unordered_map<string, bool> tables;
  tables.emplace("foo.", false);
  tables.emplace(".bar", false);
  ASSERT_OK(client_.AuthorizeActionMultipleTables("jdoe", ActionPB::METADATA, &tables));
  ASSERT_EQ(0, tables.size());
}

TEST_F(RangerClientTest, TestAuthorizeMetadataNoneAuthorizedContainsNonRanger) {
  unordered_map<string, bool> tables;
  tables.emplace("foo.", false);
  tables.emplace(".bar", false);
  tables.emplace("foo.bar", false);
  tables.emplace("foo.baz", false);
  ASSERT_OK(client_.AuthorizeActionMultipleTables("jdoe", ActionPB::METADATA, &tables));
  ASSERT_EQ(0, tables.size());
}

TEST_F(RangerClientTest, TestAuthorizeMetadataAllAuthorizedContainsNonRanger) {
  Allow("jdoe", ActionPB::METADATA, "default", "foobar");
  Allow("jdoe", ActionPB::METADATA, "default", "barbaz");
  unordered_map<string, bool> tables;
  tables.emplace("default.foobar", false);
  tables.emplace("barbaz", false);
  tables.emplace("foo.", false);
  ASSERT_OK(client_.AuthorizeActionMultipleTables("jdoe", ActionPB::METADATA, &tables));
  ASSERT_EQ(2, tables.size());
  ASSERT_TRUE(ContainsKey(tables, "default.foobar"));
  ASSERT_TRUE(ContainsKey(tables, "barbaz"));
  ASSERT_FALSE(ContainsKey(tables, "foo."));
}

TEST_F(RangerClientTest, TestAuthorizeScanSubsetAuthorized) {
  Allow("jdoe", ActionPB::SELECT, "default", "foobar", "col1");
  Allow("jdoe", ActionPB::SELECT, "default", "foobar", "col3");
  unordered_set<string> columns;
  columns.emplace("col1");
  columns.emplace("col2");
  columns.emplace("col3");
  columns.emplace("col4");
  ASSERT_OK(client_.AuthorizeActionMultipleColumns("jdoe", ActionPB::SELECT,
                                                   "default", "foobar", /*is_owner=*/false,
                                                   &columns));
  ASSERT_EQ(2, columns.size());
  ASSERT_TRUE(ContainsKey(columns, "col1"));
  ASSERT_TRUE(ContainsKey(columns, "col3"));
  ASSERT_FALSE(ContainsKey(columns, "col2"));
  ASSERT_FALSE(ContainsKey(columns, "col4"));
}

TEST_F(RangerClientTest, TestAuthorizeScanAllColumnsAuthorized) {
  Allow("jdoe", ActionPB::SELECT, "default", "foobar", "col1");
  Allow("jdoe", ActionPB::SELECT, "default", "foobar", "col2");
  Allow("jdoe", ActionPB::SELECT, "default", "foobar", "col3");
  Allow("jdoe", ActionPB::SELECT, "default", "foobar", "col4");
  unordered_set<string> columns;
  columns.emplace("col1");
  columns.emplace("col2");
  columns.emplace("col3");
  columns.emplace("col4");
  ASSERT_OK(client_.AuthorizeActionMultipleColumns("jdoe", ActionPB::SELECT,
                                                   "default", "foobar", /*is_owner=*/false,
                                                   &columns));
  ASSERT_EQ(4, columns.size());
  ASSERT_TRUE(ContainsKey(columns, "col1"));
  ASSERT_TRUE(ContainsKey(columns, "col2"));
  ASSERT_TRUE(ContainsKey(columns, "col3"));
  ASSERT_TRUE(ContainsKey(columns, "col4"));
}

TEST_F(RangerClientTest, TestAuthorizeScanNoColumnsAuthorized) {
  unordered_set<string> columns;
  for (int i = 0; i < 4; ++i) {
    columns.emplace(Substitute("col$0", i));
  }
  ASSERT_OK(client_.AuthorizeActionMultipleColumns("jdoe", ActionPB::SELECT,
                                                   "default", "foobar", /*is_owner=*/false,
                                                   &columns));
  ASSERT_EQ(0, columns.size());
}

TEST_F(RangerClientTest, TestAuthorizeActionsNoneAuthorized) {
  unordered_set<ActionPB, ActionHash> actions;
  actions.emplace(ActionPB::DROP);
  actions.emplace(ActionPB::SELECT);
  actions.emplace(ActionPB::INSERT);
  ASSERT_OK(client_.AuthorizeActions("jdoe", "default", "foobar", /*is_owner=*/false, &actions));
  ASSERT_EQ(0, actions.size());
}

TEST_F(RangerClientTest, TestAuthorizeActionsSomeAuthorized) {
  Allow("jdoe", ActionPB::SELECT, "default", "foobar");
  unordered_set<ActionPB, ActionHash> actions;
  actions.emplace(ActionPB::DROP);
  actions.emplace(ActionPB::SELECT);
  actions.emplace(ActionPB::INSERT);
  ASSERT_OK(client_.AuthorizeActions("jdoe", "default", "foobar", /*is_owner=*/false, &actions));
  ASSERT_EQ(1, actions.size());
  ASSERT_TRUE(ContainsKey(actions, ActionPB::SELECT));
}

TEST_F(RangerClientTest, TestAuthorizeActionsAllAuthorized) {
  Allow("jdoe", ActionPB::DROP, "default", "foobar");
  Allow("jdoe", ActionPB::SELECT, "default", "foobar");
  Allow("jdoe", ActionPB::INSERT, "default", "foobar");
  unordered_set<ActionPB, ActionHash> actions;
  actions.emplace(ActionPB::DROP);
  actions.emplace(ActionPB::SELECT);
  actions.emplace(ActionPB::INSERT);
  ASSERT_OK(client_.AuthorizeActions("jdoe", "default", "foobar", /*is_owner=*/false, &actions));
  ASSERT_EQ(3, actions.size());
}

class RangerClientTestBase : public KuduTest {
 public:
  RangerClientTestBase()
      : test_dir_(GetTestDataDirectory()) {}

  void SetUp() override {
    metric_entity_ = METRIC_ENTITY_server.Instantiate(&metric_registry_, "ranger_client-test");
    FLAGS_ranger_log_level = "debug";
    FLAGS_ranger_logtostdout = true;
    FLAGS_ranger_config_path = test_dir_;
    FLAGS_ranger_log_config_dir = JoinPathSegments(test_dir_, "log_conf");
    FLAGS_log_dir = JoinPathSegments(test_dir_, "logs");
    ASSERT_OK(env_->CreateDir(FLAGS_log_dir));
    ASSERT_OK(InitializeRanger());
  }

  Status InitializeRanger() {
    ranger_.reset(new MiniRanger("127.0.0.1"));
    RETURN_NOT_OK(ranger_->Start());
    // Create a policy so the Ranger client policy refresher can pick something
    // up. In some environments the absense of policies can cause the plugin to
    // wait for a policy to appear indefinitely.
    // See KUDU-3154 and RANGER-2899 for more details.
    // TODO(awong): remove this when RANGER-2899 is fixed.
    PolicyItem item({"user"}, {ActionPB::METADATA}, false);
    AuthorizationPolicy policy;
    policy.databases.emplace_back("db");
    policy.tables.emplace_back("table");
    policy.items.emplace_back(std::move(item));
    RETURN_NOT_OK(ranger_->AddPolicy(std::move(policy)));
    RETURN_NOT_OK(ranger_->CreateClientConfig(test_dir_));
    client_.reset(new RangerClient(env_, metric_entity_));
    return client_->Start();
  }

 protected:
  const string test_dir_;
  MetricRegistry metric_registry_;

  scoped_refptr<MetricEntity> metric_entity_;
  std::unique_ptr<MiniRanger> ranger_;
  std::unique_ptr<RangerClient> client_;
};

namespace {

// Looks in --log_dir and returns the full Kudu Ranger subprocess log filename
// and the lines contained therein.
Status GetLinesFromLogFile(Env* env, string* file, vector<string>* lines) {
  vector<string> matches;
  RETURN_NOT_OK(env->Glob(JoinPathSegments(FLAGS_log_dir, "kudu-ranger-subprocess*.log"),
                                           &matches));
  if (matches.size() != 1) {
    return Status::Corruption(Substitute("Expected one file but got $0: $1",
                                         matches.size(), JoinStrings(matches, ", ")));
  }
  faststring contents;
  const string& full_log_file = matches[0];
  RETURN_NOT_OK(ReadFileToString(env, full_log_file, &contents));
  *file = full_log_file;
  *lines = Split(contents.ToString(), "\n", SkipEmpty());
  return Status::OK();
}

} // anonymous namespace

TEST_F(RangerClientTestBase, TestLogging) {
  {
    // Check that a logging configuration was produced by the Ranger client.
    vector<string> files;
    ASSERT_OK(ListFilesInDir(env_, FLAGS_ranger_log_config_dir, &files));
    SCOPED_TRACE(JoinStrings(files, "\n"));
    ASSERT_STRINGS_ANY_MATCH(files, ".*log4j2.properties");
  }
  // Make a request. It doesn't matter whether it succeeds or not -- debug logs
  // should include info about each request.
  bool authorized;
  ASSERT_OK(client_->AuthorizeAction("user", ActionPB::ALL, "db", "table", /*is_owner=*/false,
                                     /*requires_delegate_admin=*/false, &authorized));
  ASSERT_FALSE(authorized);
  {
    // Check that the Ranger client logs some DEBUG messages.
    vector<string> lines;
    string log_file;
    ASSERT_OK(GetLinesFromLogFile(env_, &log_file, &lines));
    ASSERT_STRINGS_ANY_MATCH(lines, ".*DEBUG.*");
    // Delete the log file so we can start a fresh log.
    ASSERT_OK(env_->DeleteFile(log_file));
  }
  // Try reconfiguring our logging to spit out info-level logs and start a new
  // log file by restarting the Ranger client. Since we're set up to not
  // overwrite the logging config, this won't be effective -- we should still
  // see DEBUG messages.
  FLAGS_ranger_log_level = "info";
  FLAGS_ranger_overwrite_log_config = false;
  client_.reset(new RangerClient(env_, metric_entity_));
  ASSERT_OK(client_->Start());
  ASSERT_OK(client_->AuthorizeAction("user", ActionPB::ALL, "db", "table", /*is_owner=*/false,
                                     /*requires_delegate_admin=*/false, &authorized));
  ASSERT_FALSE(authorized);
  {
    // Our logs should still contain DEBUG messages since we didn't update the
    // logging configuration.
    vector<string> lines;
    string log_file;
    ASSERT_OK(GetLinesFromLogFile(env_, &log_file, &lines));
    ASSERT_STRINGS_ANY_MATCH(lines, ".*DEBUG.*");
    // Delete the log file so we can start a fresh log.
    ASSERT_OK(env_->DeleteFile(log_file));
  }
  // Now try again but this time overwrite the logging configuration.
  FLAGS_ranger_overwrite_log_config = true;
  client_.reset(new RangerClient(env_, metric_entity_));
  ASSERT_OK(client_->Start());
  ASSERT_OK(client_->AuthorizeAction("user", ActionPB::ALL, "db", "table", /*is_owner=*/false,
                                     /*requires_delegate_admin=*/false, &authorized));
  ASSERT_FALSE(authorized);
  {
    // We shouldn't see any DEBUG messages since the client is configured to
    // use INFO-level logging.
    vector<string> lines;
    string unused;
    ASSERT_OK(GetLinesFromLogFile(env_, &unused, &lines));
    // We should see no DEBUG messages.
    for (const auto& l : lines) {
      ASSERT_STR_NOT_CONTAINS(l, "DEBUG");
    }
  }
}

} // namespace ranger
} // namespace kudu
