// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>
#include <utility>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/macros.h>
#include <base/strings/stringprintf.h>
#include <components/policy/core/common/registry_dict.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "authpolicy/policy/policy_encoder_helper.h"
#include "authpolicy/policy/preg_policy_encoder.h"
#include "authpolicy/policy/preg_policy_writer.h"
#include "bindings/authpolicy_containers.pb.h"
#include "bindings/chrome_device_policy.pb.h"
#include "bindings/cloud_policy.pb.h"
#include "bindings/policy_constants.h"

namespace em = enterprise_management;

namespace {

constexpr char kPreg1Filename[] = "registry1.pol";
constexpr char kPreg2Filename[] = "registry2.pol";

// Some constants for policy testing.
const bool kPolicyBool = true;
const bool kOtherPolicyBool = false;

const int kPolicyInt = 321;
const int kOtherPolicyInt = 234;

constexpr char kPolicyStr[] = "Str";
constexpr char kOtherPolicyStr[] = "OtherStr";

constexpr char kExtensionId[] = "abcdeFGHabcdefghAbcdefGhabcdEfgh";
constexpr char kOtherExtensionId[] = "ababababcdcdcdcdefefefefghghghgh";
constexpr char kInvalidExtensionId[] = "abcdeFGHabcdefgh";

constexpr char kExtensionPolicy1[] = "Policy1";
constexpr char kExtensionPolicy2[] = "Policy2";
constexpr char kExtensionPolicy3[] = "Policy3";
constexpr char kExtensionPolicy4[] = "Policy4";

// Converts a json string that contains a dict into a base::DictionaryValue.
std::unique_ptr<base::DictionaryValue> JsonStringToDictionaryValue(
    const std::string& json_string) {
  std::unique_ptr<base::Value> root =
      base::JSONReader::Read(json_string, base::JSON_ALLOW_TRAILING_COMMAS);
  return root ? base::DictionaryValue::From(std::move(root)) : nullptr;
}

}  // namespace

namespace policy {

// Tests basic preg-to-policy encoding and the promises
// ParsePRegFilesIntoUserPolicy and ParsePRegFilesIntoDevicePolicy make.
class PregPolicyEncoderTest : public ::testing::Test {
 public:
  PregPolicyEncoderTest() = default;

  void SetUp() override {
    // Create temp directory for policy files.
    CHECK(base::CreateNewTempDirectory("" /* prefix (ignored) */, &base_path_));

    preg_1_path_ = base_path_.Append(kPreg1Filename);
    preg_2_path_ = base_path_.Append(kPreg2Filename);
  }

  void TearDown() override {
    // Don't not leave no mess behind.
    base::DeleteFile(base_path_, true /* recursive */);
  }

 protected:
  // Whether policies from the first or the second file win.
  enum WhoWins { FIRST_WINS, SECOND_WINS };

  // Writes two files with policies, encodes them and tests whether policies
  // from the first of the second file 'won' (prevailed). |level1| and |level2|
  // are the policy levels for the two files.
  void TestUserPolicyFileOverride(PolicyLevel level1,
                                  PolicyLevel level2,
                                  WhoWins who_wins) {
    // Write file 1 with some interesting data. Set policy level to level1.
    PRegUserDevicePolicyWriter writer1;
    writer1.AppendBoolean(key::kSearchSuggestEnabled, kOtherPolicyBool, level1);
    writer1.AppendInteger(key::kPolicyRefreshRate, kPolicyInt, level1);
    writer1.AppendString(key::kHomepageLocation, kPolicyStr, level1);
    const std::vector<std::string> apps1 = {"App1", "App2", "App3"};
    writer1.AppendStringList(key::kPinnedLauncherApps, apps1, level1);
    writer1.WriteToFile(preg_1_path_);

    // Write file 2 with the same policies, but different values. Set policy
    // level to level2.
    PRegUserDevicePolicyWriter writer2;
    writer2.AppendBoolean(key::kSearchSuggestEnabled, kPolicyBool, level2);
    writer2.AppendInteger(key::kPolicyRefreshRate, kOtherPolicyInt, level2);
    writer2.AppendString(key::kHomepageLocation, kOtherPolicyStr, level2);
    const std::vector<std::string> apps2 = {"App4", "App5"};
    writer2.AppendStringList(key::kPinnedLauncherApps, apps2, level2);
    writer2.WriteToFile(preg_2_path_);

    // Encode to policy.
    em::CloudPolicySettings policy;
    EXPECT_TRUE(ParsePRegFilesIntoUserPolicy(
        {preg_1_path_, preg_2_path_}, &policy, false /* log_policy_values */));

    bool win_bool = (who_wins == FIRST_WINS ? kOtherPolicyBool : kPolicyBool);
    int win_int = (who_wins == FIRST_WINS ? kPolicyInt : kOtherPolicyInt);
    const std::string& win_string =
        (who_wins == FIRST_WINS ? kPolicyStr : kOtherPolicyStr);
    const auto& win_string_list = (who_wins == FIRST_WINS ? apps1 : apps2);
    PolicyLevel win_level = (who_wins == FIRST_WINS ? level1 : level2);
    em::PolicyOptions::PolicyMode win_mode =
        win_level == POLICY_LEVEL_MANDATORY ? em::PolicyOptions::MANDATORY
                                            : em::PolicyOptions::RECOMMENDED;

    // Check that the expected values prevail.
    EXPECT_TRUE(policy.searchsuggestenabled().has_policy_options());
    EXPECT_EQ(win_mode, policy.searchsuggestenabled().policy_options().mode());
    EXPECT_TRUE(policy.searchsuggestenabled().has_value());
    EXPECT_EQ(win_bool, policy.searchsuggestenabled().value());

    EXPECT_TRUE(policy.policyrefreshrate().has_policy_options());
    EXPECT_EQ(win_mode, policy.policyrefreshrate().policy_options().mode());
    EXPECT_TRUE(policy.policyrefreshrate().has_value());
    EXPECT_EQ(win_int, policy.policyrefreshrate().value());

    EXPECT_TRUE(policy.homepagelocation().has_policy_options());
    EXPECT_EQ(win_mode, policy.homepagelocation().policy_options().mode());
    EXPECT_TRUE(policy.homepagelocation().has_value());
    EXPECT_EQ(win_string, policy.homepagelocation().value());

    EXPECT_TRUE(policy.homepagelocation().has_policy_options());
    EXPECT_EQ(win_mode, policy.pinnedlauncherapps().policy_options().mode());
    EXPECT_TRUE(policy.pinnedlauncherapps().has_value());
    const em::StringList& apps_proto = policy.pinnedlauncherapps().value();
    EXPECT_EQ(apps_proto.entries_size(),
              static_cast<int>(win_string_list.size()));
    for (int n = 0; n < apps_proto.entries_size(); ++n)
      EXPECT_EQ(apps_proto.entries(n), win_string_list.at(n));
  }

  base::FilePath base_path_;
  base::FilePath preg_1_path_;
  base::FilePath preg_2_path_;

 private:
  DISALLOW_COPY_AND_ASSIGN(PregPolicyEncoderTest);
};

// Encodes user policies of different types.
TEST_F(PregPolicyEncoderTest, UserPolicyEncodingWorks) {
  // Create a preg file with some interesting data.
  PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(key::kSearchSuggestEnabled, kPolicyBool);
  writer.AppendInteger(key::kPolicyRefreshRate, kPolicyInt);
  writer.AppendString(key::kHomepageLocation, kPolicyStr);
  const std::vector<std::string> apps = {"App1", "App2"};
  writer.AppendStringList(key::kPinnedLauncherApps, apps);
  writer.WriteToFile(preg_1_path_);

  // Encode preg file into policy.
  em::CloudPolicySettings policy;
  EXPECT_TRUE(ParsePRegFilesIntoUserPolicy({preg_1_path_}, &policy,
                                           false /* log_policy_values */));

  // Check that policy has the same values as we wrote to the file.
  EXPECT_EQ(kPolicyBool, policy.searchsuggestenabled().value());
  EXPECT_EQ(kPolicyInt, policy.policyrefreshrate().value());
  EXPECT_EQ(kPolicyStr, policy.homepagelocation().value());
  const em::StringList& apps_proto = policy.pinnedlauncherapps().value();
  EXPECT_EQ(apps_proto.entries_size(), static_cast<int>(apps.size()));
  for (int n = 0; n < apps_proto.entries_size(); ++n)
    EXPECT_EQ(apps_proto.entries(n), apps.at(n));
}

// Checks that a user GPO later in the list overrides prior GPOs for recommended
// policies.
TEST_F(PregPolicyEncoderTest, UserPolicyRecommendedOverridesRecommended) {
  TestUserPolicyFileOverride(POLICY_LEVEL_RECOMMENDED, POLICY_LEVEL_RECOMMENDED,
                             SECOND_WINS);
}

// Checks that a user GPO later in the list overrides prior GPOs for mandatory
// policies.
TEST_F(PregPolicyEncoderTest, UserPolicyMandatoryOverridesMandatory) {
  TestUserPolicyFileOverride(POLICY_LEVEL_MANDATORY, POLICY_LEVEL_MANDATORY,
                             SECOND_WINS);
}

// Verifies that a mandatory policy is not overridden by a recommended policy.
TEST_F(PregPolicyEncoderTest, UserPolicyRecommendedDoesNotOverrideMandatory) {
  TestUserPolicyFileOverride(POLICY_LEVEL_MANDATORY, POLICY_LEVEL_RECOMMENDED,
                             FIRST_WINS);
}

// Verifies that a mandatory policy overrides a recommended policy.
TEST_F(PregPolicyEncoderTest, UserPolicyMandatoryOverridesRecommended) {
  TestUserPolicyFileOverride(POLICY_LEVEL_RECOMMENDED, POLICY_LEVEL_MANDATORY,
                             SECOND_WINS);
}

// Encodes device policies of different types.
TEST_F(PregPolicyEncoderTest, DevicePolicyEncodingWorks) {
  // Create a preg file with some interesting data.
  PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(key::kDeviceGuestModeEnabled, kPolicyBool);
  writer.AppendInteger(key::kDevicePolicyRefreshRate, kPolicyInt);
  writer.AppendString(key::kSystemTimezone, kPolicyStr);
  const std::vector<std::string> str_list = {"str1", "str2"};
  writer.AppendStringList(key::kDeviceUserWhitelist, str_list);
  writer.WriteToFile(preg_1_path_);

  // Encode preg file into policy.
  em::ChromeDeviceSettingsProto policy;
  EXPECT_TRUE(ParsePRegFilesIntoDevicePolicy({preg_1_path_}, &policy,
                                             false /* log_policy_values */));

  // Check that policy has the same values as we wrote to the file.
  EXPECT_EQ(kPolicyBool, policy.guest_mode_enabled().guest_mode_enabled());
  EXPECT_EQ(kPolicyInt,
            policy.device_policy_refresh_rate().device_policy_refresh_rate());
  EXPECT_EQ(kPolicyStr, policy.system_timezone().timezone());
  const em::UserWhitelistProto& str_list_proto = policy.user_whitelist();
  EXPECT_EQ(str_list_proto.user_whitelist_size(),
            static_cast<int>(str_list.size()));
  for (int n = 0; n < str_list_proto.user_whitelist_size(); ++n)
    EXPECT_EQ(str_list_proto.user_whitelist(n), str_list.at(n));
}

// Checks that a device GPO later in the list overrides prior GPOs.
TEST_F(PregPolicyEncoderTest, DevicePolicyFileOverride) {
  // Write file 1 with some interesting data. Note that device policy doesn't
  // support mandatory/recommended policies.
  PRegUserDevicePolicyWriter writer1;
  writer1.AppendBoolean(key::kDeviceGuestModeEnabled, kOtherPolicyBool);
  writer1.AppendInteger(key::kDevicePolicyRefreshRate, kPolicyInt);
  writer1.AppendString(key::kSystemTimezone, kPolicyStr);
  const std::vector<std::string> str_list1 = {"str1", "str2", "str3"};
  writer1.AppendStringList(key::kDeviceUserWhitelist, str_list1);
  writer1.WriteToFile(preg_1_path_);

  // Write file 2 with the same policies, but different values.
  PRegUserDevicePolicyWriter writer2;
  writer2.AppendBoolean(key::kDeviceGuestModeEnabled, kPolicyBool);
  writer2.AppendInteger(key::kDevicePolicyRefreshRate, kOtherPolicyInt);
  writer2.AppendString(key::kSystemTimezone, kOtherPolicyStr);
  const std::vector<std::string> str_list2 = {"str4", "str5"};
  writer2.AppendStringList(key::kDeviceUserWhitelist, str_list2);
  writer2.WriteToFile(preg_2_path_);

  // Encode to policy.
  em::ChromeDeviceSettingsProto policy;
  EXPECT_TRUE(ParsePRegFilesIntoDevicePolicy(
      {preg_1_path_, preg_2_path_}, &policy, false /* log_policy_values */));

  // Check that the values from file 2 prevailed.
  EXPECT_EQ(kPolicyBool, policy.guest_mode_enabled().guest_mode_enabled());
  EXPECT_EQ(kOtherPolicyInt,
            policy.device_policy_refresh_rate().device_policy_refresh_rate());
  EXPECT_EQ(kOtherPolicyStr, policy.system_timezone().timezone());
  const em::UserWhitelistProto& str_list_proto = policy.user_whitelist();
  EXPECT_EQ(str_list_proto.user_whitelist_size(),
            static_cast<int>(str_list2.size()));
  for (int n = 0; n < str_list_proto.user_whitelist_size(); ++n)
    EXPECT_EQ(str_list_proto.user_whitelist(n), str_list2.at(n));
}

// Encodes extension policies of different types.
TEST_F(PregPolicyEncoderTest, ExtensionPolicyEncodingWorks) {
  // Create a preg file with some interesting data.
  PRegExtensionPolicyWriter writer(kExtensionId);
  writer.AppendBoolean(kExtensionPolicy1, kPolicyBool);
  writer.AppendInteger(kExtensionPolicy2, kPolicyInt);
  writer.AppendString(kExtensionPolicy3, kPolicyStr);
  const std::vector<std::string> str_list = {"str1", "str2"};
  writer.AppendStringList(kExtensionPolicy4, str_list);
  writer.WriteToFile(preg_1_path_);

  // Encode preg file into policy.
  ExtensionPolicies policies;
  EXPECT_TRUE(ParsePRegFilesIntoExtensionPolicy({preg_1_path_}, &policies,
                                                false /* log_policy_values */));

  const std::string expected_json = base::StringPrintf(
      "{\"%s\":{\"%s\":1,\"%s\":%i,\"%s\":"
      "\"%s\",\"%s\":{\"1\":\"%s\",\"2\":\"%s\"}}}",
      kKeyMandatoryExtension, kExtensionPolicy1, kExtensionPolicy2, kPolicyInt,
      kExtensionPolicy3, kPolicyStr, kExtensionPolicy4, str_list[0].c_str(),
      str_list[1].c_str());

  // Check that policy has the same values as we wrote to the file.
  ASSERT_EQ(1, policies.size());
  EXPECT_EQ(kExtensionId, policies[0].id());
  EXPECT_EQ(expected_json, policies[0].json_data());
}

// Make sure invalid extension IDs are ignored.
TEST_F(PregPolicyEncoderTest, ExtensionPolicyIgnoresInvalidIds) {
  // Create a preg file with several valid and invalid extension ids.
  PRegExtensionPolicyWriter writer(kExtensionId);
  writer.AppendBoolean(kExtensionPolicy1, kPolicyBool);
  writer.SetKeysForExtensionPolicy(kInvalidExtensionId);
  writer.AppendBoolean(kExtensionPolicy1, kPolicyBool);
  writer.SetKeysForExtensionPolicy(kOtherExtensionId);
  writer.AppendBoolean(kExtensionPolicy1, kPolicyBool);
  writer.WriteToFile(preg_1_path_);

  // Encode preg file into policy.
  ExtensionPolicies policies;
  EXPECT_TRUE(ParsePRegFilesIntoExtensionPolicy({preg_1_path_}, &policies,
                                                false /* log_policy_values */));

  // Extensions with IDs kExtensionId and kOtherExtensionId should be in the
  // output, kInvalidExtensionId shouldn't.
  const std::string expected_json_0 = base::StringPrintf(
      "{\"%s\":{\"%s\":1}}", kKeyMandatoryExtension, kExtensionPolicy1);
  const std::string expected_json_1 = base::StringPrintf(
      "{\"%s\":{\"%s\":1}}", kKeyMandatoryExtension, kExtensionPolicy1);

  ASSERT_EQ(2, policies.size());
  EXPECT_EQ(kOtherExtensionId, policies[0].id());
  EXPECT_EQ(expected_json_0, policies[0].json_data());
  EXPECT_EQ(kExtensionId, policies[1].id());
  EXPECT_EQ(expected_json_1, policies[1].json_data());
}

// Verify that recommended and mandatory policies get encoded separately.
TEST_F(PregPolicyEncoderTest, ExtensionPolicyRecommendedAndMandatory) {
  // Create a preg file with several valid and invalid extension ids.
  PRegExtensionPolicyWriter writer(kExtensionId);
  writer.AppendBoolean(kExtensionPolicy1, kPolicyBool);
  writer.AppendInteger(kExtensionPolicy2, kPolicyInt, POLICY_LEVEL_RECOMMENDED);
  writer.WriteToFile(preg_1_path_);

  // Encode preg file into policy.
  ExtensionPolicies policies;
  EXPECT_TRUE(ParsePRegFilesIntoExtensionPolicy({preg_1_path_}, &policies,
                                                false /* log_policy_values */));

  // Extensions with IDs kExtensionId and kOtherExtensionId should be in the
  // output, kInvalidExtensionId shouldn't.
  const std::string expected_json = base::StringPrintf(
      "{\"%s\":{\"%s\":1},\"%s\":{\"%s\":%i}}", kKeyMandatoryExtension,
      kExtensionPolicy1, kKeyRecommended, kExtensionPolicy2, kPolicyInt);

  ASSERT_EQ(1, policies.size());
  EXPECT_EQ(kExtensionId, policies[0].id());
  EXPECT_EQ(expected_json, policies[0].json_data());
}

// Roundtrips a multi-line JSON dict through a PReg file, and ensures that
// the multi-line string that is roundtripped can be read by JSONReader.
TEST_F(PregPolicyEncoderTest, TestJsonWithNewlinesRoundtrip) {
  PRegUserDevicePolicyWriter writer1;
  const std::vector<std::string> json_with_newlines = {
      "{",
      "  \"TestBool\": true,",
      "  \"TestInt\":",
      "        123456,",
      "  \"TestString\": \"elephant\",",
      "}",
  };
  writer1.AppendMultiString("TestJson", json_with_newlines);
  writer1.WriteToFile(preg_1_path_);

  RegistryDict dict;
  EXPECT_TRUE(LoadPRegFile(preg_1_path_, kKeyUserDevice, &dict));
  const std::string& roundtripped_json = dict.GetValue("TestJson")->GetString();
  std::unique_ptr<base::DictionaryValue> json_dict =
      JsonStringToDictionaryValue(roundtripped_json);
  ASSERT_TRUE(json_dict != nullptr);

  bool test_bool;
  json_dict->GetBoolean("TestBool", &test_bool);
  EXPECT_EQ(true, test_bool);

  int test_int;
  json_dict->GetInteger("TestInt", &test_int);
  EXPECT_EQ(123456, test_int);

  std::string test_string;
  json_dict->GetString("TestString", &test_string);
  EXPECT_EQ("elephant", test_string);
}

// Roundtrips a JSON dict that contains unescaped newlines within a single
// JSON string literal, ensures that the multi-line string that is roundtripped
// can be read by JSONReader.
// This is not strictly valid JSON, but we make sure to allow it anyway since
// pasting certificates into JSON is much easier if they are allowed to contain
// raw newlines, so the admin doesn't have to escape them first.
TEST_F(PregPolicyEncoderTest, TestJsonWithNewlinesInsideStringRoundtrip) {
  PRegUserDevicePolicyWriter writer1;
  const std::vector<std::string> json_with_newlines = {
      "{",
      "  \"TestCertificate\": \"A-B-C-D-E-F-G",
      "H-I-J-K-LMNOP",
      "Q-R-S...T-U-V",
      "W-X...Y-and-Z\"",
      "}",
  };
  writer1.AppendMultiString("TestJson", json_with_newlines);
  writer1.WriteToFile(preg_1_path_);

  RegistryDict dict;
  EXPECT_TRUE(LoadPRegFile(preg_1_path_, kKeyUserDevice, &dict));
  const std::string& roundtripped_json = dict.GetValue("TestJson")->GetString();
  std::unique_ptr<base::DictionaryValue> json_dict =
      JsonStringToDictionaryValue(roundtripped_json);
  ASSERT_TRUE(json_dict != nullptr);

  std::string test_certificate;
  json_dict->GetString("TestCertificate", &test_certificate);
  EXPECT_EQ("A-B-C-D-E-F-G\nH-I-J-K-LMNOP\nQ-R-S...T-U-V\nW-X...Y-and-Z",
            test_certificate);
}

}  // namespace policy
