// Copyright (c) 2012 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 "login_manager/user_policy_service.h"

#include <stdint.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/memory/ptr_util.h>
#include <base/run_loop.h>
#include <brillo/message_loops/fake_message_loop.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "bindings/device_management_backend.pb.h"
#include "login_manager/blob_util.h"
#include "login_manager/matchers.h"
#include "login_manager/mock_policy_key.h"
#include "login_manager/mock_policy_service.h"
#include "login_manager/mock_policy_store.h"
#include "login_manager/policy_service.h"
#include "login_manager/system_utils_impl.h"

namespace em = enterprise_management;

using ::testing::_;
using ::testing::ElementsAre;
using ::testing::InSequence;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::Sequence;
using ::testing::StrictMock;

namespace login_manager {

namespace {

PolicyNamespace MakeExtensionPolicyNamespace() {
  return std::make_pair(POLICY_DOMAIN_EXTENSIONS,
                        "ababababcdcdcdcdefefefefghghghgh");
}

void InitPolicyFetchResponse(const std::string& policy_value_str,
                             em::PolicyData::AssociationState state,
                             const std::string& signature,
                             em::PolicyFetchResponse* policy_proto) {
  em::PolicyData policy_data;
  policy_data.set_state(state);
  policy_data.set_policy_value(policy_value_str);
  std::string policy_data_str;
  ASSERT_TRUE(policy_data.SerializeToString(&policy_data_str));

  policy_proto->Clear();
  policy_proto->set_policy_data(policy_data_str);
  if (!signature.empty())
    policy_proto->set_policy_data_signature(signature);
}

}  // namespace

class UserPolicyServiceTest : public ::testing::Test {
 public:
  UserPolicyServiceTest() = default;

  void SetUp() override {
    fake_loop_.SetAsCurrent();
    ASSERT_TRUE(tmpdir_.CreateUniqueTempDir());
    key_copy_file_ = tmpdir_.GetPath().Append("hash/key_copy.pub");

    key_ = new StrictMock<MockPolicyKey>;
    store_ = new StrictMock<MockPolicyStore>;
    service_.reset(new UserPolicyService(tmpdir_.GetPath(),
                                         std::unique_ptr<PolicyKey>(key_),
                                         key_copy_file_, &system_utils_));
    service_->SetStoreForTesting(MakeChromePolicyNamespace(),
                                 std::unique_ptr<PolicyStore>(store_));
  }

  void InitPolicy(em::PolicyData::AssociationState state,
                  const std::string& signature) {
    ASSERT_NO_FATAL_FAILURE(InitPolicyFetchResponse(
        "" /* policy_value */, state, signature, &policy_proto_));
  }

  void ExpectStorePolicy(const Sequence& sequence) {
    EXPECT_CALL(*store_, Set(ProtoEq(policy_proto_))).InSequence(sequence);
    EXPECT_CALL(*store_, Persist()).InSequence(sequence).WillOnce(Return(true));
  }

 protected:
  SystemUtilsImpl system_utils_;
  base::ScopedTempDir tmpdir_;
  base::FilePath key_copy_file_;

  const std::string fake_signature_ = "fake_signature";

  // Various representations of the policy protobuf.
  em::PolicyFetchResponse policy_proto_;

  brillo::FakeMessageLoop fake_loop_{nullptr};

  // Use StrictMock to make sure that no unexpected policy or key mutations can
  // occur without the test failing.
  StrictMock<MockPolicyKey>* key_;
  StrictMock<MockPolicyStore>* store_;

  std::unique_ptr<UserPolicyService> service_;

 private:
  DISALLOW_COPY_AND_ASSIGN(UserPolicyServiceTest);
};

TEST_F(UserPolicyServiceTest, StoreSignedPolicy) {
  InitPolicy(em::PolicyData::ACTIVE, fake_signature_);

  Sequence s1;
  EXPECT_CALL(*key_, Verify(_, _)).InSequence(s1).WillOnce(Return(true));
  ExpectStorePolicy(s1);

  EXPECT_TRUE(service_->Store(
      MakeChromePolicyNamespace(), SerializeAsBlob(policy_proto_),
      PolicyService::KEY_NONE, SignatureCheck::kEnabled,
      MockPolicyService::CreateExpectSuccessCallback()));
  fake_loop_.Run();
}

TEST_F(UserPolicyServiceTest, StoreUnmanagedSigned) {
  InitPolicy(em::PolicyData::UNMANAGED, fake_signature_);

  Sequence s1;
  EXPECT_CALL(*key_, Verify(_, _)).InSequence(s1).WillOnce(Return(true));
  ExpectStorePolicy(s1);

  EXPECT_TRUE(service_->Store(
      MakeChromePolicyNamespace(), SerializeAsBlob(policy_proto_),
      PolicyService::KEY_NONE, SignatureCheck::kEnabled,
      MockPolicyService::CreateExpectSuccessCallback()));
  fake_loop_.Run();
}

TEST_F(UserPolicyServiceTest, StoreUnmanagedKeyPresent) {
  InitPolicy(em::PolicyData::UNMANAGED, "");

  Sequence s1;
  ExpectStorePolicy(s1);
  std::vector<uint8_t> key_value;
  key_value.push_back(0x12);

  EXPECT_CALL(*key_, IsPopulated()).WillRepeatedly(Return(true));
  EXPECT_CALL(*key_, public_key_der()).WillRepeatedly(ReturnRef(key_value));

  Sequence s2;
  EXPECT_CALL(*key_, ClobberCompromisedKey(ElementsAre())).InSequence(s2);
  EXPECT_CALL(*key_, Persist()).InSequence(s2).WillOnce(Return(true));

  EXPECT_FALSE(base::PathExists(key_copy_file_));
  EXPECT_TRUE(service_->Store(
      MakeChromePolicyNamespace(), SerializeAsBlob(policy_proto_),
      PolicyService::KEY_NONE, SignatureCheck::kEnabled,
      MockPolicyService::CreateExpectSuccessCallback()));
  fake_loop_.Run();

  EXPECT_TRUE(base::PathExists(key_copy_file_));
  std::string content;
  EXPECT_TRUE(base::ReadFileToString(key_copy_file_, &content));
  ASSERT_EQ(1u, content.size());
  EXPECT_EQ(key_value[0], content[0]);
}

TEST_F(UserPolicyServiceTest, StoreUnmanagedNoKey) {
  InitPolicy(em::PolicyData::UNMANAGED, "");

  Sequence s1;
  ExpectStorePolicy(s1);

  EXPECT_CALL(*key_, IsPopulated()).WillRepeatedly(Return(false));

  EXPECT_TRUE(service_->Store(
      MakeChromePolicyNamespace(), SerializeAsBlob(policy_proto_),
      PolicyService::KEY_NONE, SignatureCheck::kEnabled,
      MockPolicyService::CreateExpectSuccessCallback()));
  fake_loop_.Run();
  EXPECT_FALSE(base::PathExists(key_copy_file_));
}

TEST_F(UserPolicyServiceTest, StoreInvalidSignature) {
  InitPolicy(em::PolicyData::ACTIVE, fake_signature_);

  InSequence s;
  EXPECT_CALL(*key_, Verify(_, _)).WillOnce(Return(false));

  EXPECT_FALSE(service_->Store(
      MakeChromePolicyNamespace(), SerializeAsBlob(policy_proto_),
      PolicyService::KEY_NONE, SignatureCheck::kEnabled,
      MockPolicyService::CreateExpectFailureCallback()));

  fake_loop_.Run();
}

TEST_F(UserPolicyServiceTest, PersistKeyCopy) {
  std::vector<uint8_t> key_value;
  key_value.push_back(0x12);
  EXPECT_CALL(*key_, IsPopulated()).WillRepeatedly(Return(true));
  EXPECT_CALL(*key_, public_key_der()).WillOnce(ReturnRef(key_value));
  EXPECT_FALSE(base::PathExists(key_copy_file_));

  service_->PersistKeyCopy();
  EXPECT_TRUE(base::PathExists(key_copy_file_));
  std::string content;
  EXPECT_TRUE(base::ReadFileToString(key_copy_file_, &content));
  ASSERT_EQ(1u, content.size());
  EXPECT_EQ(key_value[0], content[0]);

  // Now persist an empty key, and verify that the copy is removed.
  EXPECT_CALL(*key_, IsPopulated()).WillRepeatedly(Return(false));
  service_->PersistKeyCopy();
  EXPECT_FALSE(base::PathExists(key_copy_file_));
}

TEST_F(UserPolicyServiceTest, PersistPolicyMultipleNamespaces) {
  // Set up store for extension policy.
  auto extension_store = new StrictMock<MockPolicyStore>;
  service_->SetStoreForTesting(MakeExtensionPolicyNamespace(),
                               base::WrapUnique(extension_store));

  // Set up user policy.
  InitPolicy(em::PolicyData::ACTIVE, fake_signature_);

  // Set up extension policy.
  em::PolicyFetchResponse extension_policy_proto;
  ASSERT_NO_FATAL_FAILURE(
      InitPolicyFetchResponse("fake_extension_policy", em::PolicyData::ACTIVE,
                              fake_signature_, &extension_policy_proto));

  // Store user policy.
  EXPECT_CALL(*key_, Verify(_, _)).WillOnce(Return(true));
  EXPECT_CALL(*store_, Set(ProtoEq(policy_proto_)));
  EXPECT_CALL(*store_, Persist()).WillOnce(Return(true));
  EXPECT_TRUE(service_->Store(
      MakeChromePolicyNamespace(), SerializeAsBlob(policy_proto_),
      PolicyService::KEY_NONE, SignatureCheck::kEnabled,
      MockPolicyService::CreateExpectSuccessCallback()));
  fake_loop_.Run();
  testing::Mock::VerifyAndClearExpectations(&key_);
  testing::Mock::VerifyAndClearExpectations(store_);

  // Store extension policy.
  EXPECT_CALL(*key_, Verify(_, _)).WillOnce(Return(true));
  EXPECT_CALL(*extension_store, Set(ProtoEq(extension_policy_proto)));
  EXPECT_CALL(*extension_store, Persist()).WillOnce(Return(true));
  EXPECT_TRUE(service_->Store(
      MakeExtensionPolicyNamespace(), SerializeAsBlob(extension_policy_proto),
      PolicyService::KEY_NONE, SignatureCheck::kEnabled,
      MockPolicyService::CreateExpectSuccessCallback()));
  fake_loop_.Run();
}

}  // namespace login_manager
