// 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/device_local_account_policy_service.h"

#include <algorithm>

#include <base/basictypes.h>
#include <base/compiler_specific.h>
#include <base/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/memory/scoped_ptr.h>
#include <base/message_loop/message_loop.h>
#include <base/message_loop/message_loop_proxy.h>
#include <base/run_loop.h>
#include <chromeos/cryptohome.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "login_manager/chrome_device_policy.pb.h"
#include "login_manager/mock_policy_key.h"
#include "login_manager/mock_policy_service.h"
#include "login_manager/mock_policy_store.h"

namespace em = enterprise_management;

using testing::Return;
using testing::StrictMock;
using testing::_;

namespace login_manager {

class DeviceLocalAccountPolicyServiceTest : public ::testing::Test {
 public:
  DeviceLocalAccountPolicyServiceTest()
      : fake_account_("account@example.com") {
  }

  virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    base::FilePath salt_path = temp_dir_.path().Append("salt");
    ASSERT_EQ(0, base::WriteFile(salt_path, NULL, 0));
    chromeos::cryptohome::home::SetSystemSaltPath(salt_path.value());

    fake_account_policy_path_ =
        temp_dir_.path()
            .Append(chromeos::cryptohome::home::SanitizeUserName(fake_account_))
            .Append(DeviceLocalAccountPolicyService::kPolicyDir)
            .Append(DeviceLocalAccountPolicyService::kPolicyFileName);

    em::PolicyFetchResponse policy_proto;
    policy_proto.set_policy_data("policy-data");
    policy_proto.set_policy_data_signature("policy-data-signature");
    ASSERT_TRUE(policy_proto.SerializeToString(&policy_blob_));

    scoped_refptr<base::MessageLoopProxy> message_loop(
        base::MessageLoopProxy::current());
    service_.reset(new DeviceLocalAccountPolicyService(temp_dir_.path(),
                                                 &key_,
                                                 message_loop));
  }

  void SetupAccount() {
    em::ChromeDeviceSettingsProto device_settings;
    em::DeviceLocalAccountInfoProto* account =
        device_settings.mutable_device_local_accounts()->add_account();
    account->set_type(
        em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION);
    account->set_account_id(fake_account_);
    service_->UpdateDeviceSettings(device_settings);
  }

  void SetupKey() {
    EXPECT_CALL(key_, PopulateFromDiskIfPossible()).Times(0);
    EXPECT_CALL(key_, IsPopulated())
        .WillRepeatedly(Return(true));
    EXPECT_CALL(key_, Verify(_, _, _, _))
        .WillRepeatedly(Return(true));
  }

 protected:
  const std::string fake_account_;
  base::FilePath fake_account_policy_path_;

  std::string policy_blob_;

  base::MessageLoop loop_;
  base::ScopedTempDir temp_dir_;

  MockPolicyKey key_;
  MockPolicyServiceCompletion completion_;

  scoped_ptr<DeviceLocalAccountPolicyService> service_;

 private:
  DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountPolicyServiceTest);
};

TEST_F(DeviceLocalAccountPolicyServiceTest, StoreInvalidAccount) {
  EXPECT_CALL(completion_, ReportFailure(_));
  EXPECT_FALSE(
      service_->Store(fake_account_,
                      reinterpret_cast<const uint8*>(policy_blob_.c_str()),
                      policy_blob_.size(), &completion_));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(base::PathExists(fake_account_policy_path_));
}

TEST_F(DeviceLocalAccountPolicyServiceTest, StoreSuccess) {
  SetupAccount();
  SetupKey();

  EXPECT_CALL(completion_, ReportSuccess());
  EXPECT_TRUE(
      service_->Store(fake_account_,
                      reinterpret_cast<const uint8*>(policy_blob_.c_str()),
                      policy_blob_.size(), &completion_));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(base::PathExists(fake_account_policy_path_));
}

TEST_F(DeviceLocalAccountPolicyServiceTest, StoreBadPolicy) {
  SetupAccount();
  SetupKey();

  policy_blob_ = "bad!";

  EXPECT_CALL(completion_, ReportFailure(_));
  EXPECT_FALSE(
      service_->Store(fake_account_,
                      reinterpret_cast<const uint8*>(policy_blob_.c_str()),
                      policy_blob_.size(), &completion_));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(base::PathExists(fake_account_policy_path_));
}

TEST_F(DeviceLocalAccountPolicyServiceTest, StoreBadSignature) {
  SetupAccount();
  SetupKey();
  EXPECT_CALL(key_, Verify(_, _, _, _))
      .WillRepeatedly(Return(false));

  EXPECT_CALL(completion_, ReportFailure(_));
  EXPECT_FALSE(
      service_->Store(fake_account_,
                      reinterpret_cast<const uint8*>(policy_blob_.c_str()),
                      policy_blob_.size(), &completion_));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(base::PathExists(fake_account_policy_path_));
}

TEST_F(DeviceLocalAccountPolicyServiceTest, StoreNoRotation) {
  em::PolicyFetchResponse policy_proto;
  policy_proto.set_policy_data("policy-data");
  policy_proto.set_policy_data_signature("policy-data-signature");
  policy_proto.set_new_public_key("new-public-key");
  policy_proto.set_new_public_key_signature("new-public-key-signature");
  ASSERT_TRUE(policy_proto.SerializeToString(&policy_blob_));

  SetupAccount();
  SetupKey();

  // No key modifications.
  EXPECT_CALL(key_, Equals(_)).WillRepeatedly(Return(false));
  EXPECT_CALL(key_, PopulateFromBuffer(_)).Times(0);
  EXPECT_CALL(key_, PopulateFromKeypair(_)).Times(0);
  EXPECT_CALL(key_, Rotate(_, _)).Times(0);
  EXPECT_CALL(key_, ClobberCompromisedKey(_)).Times(0);

  EXPECT_CALL(completion_, ReportFailure(_));
  EXPECT_FALSE(
      service_->Store(fake_account_,
                      reinterpret_cast<const uint8*>(policy_blob_.c_str()),
                      policy_blob_.size(), &completion_));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(base::PathExists(fake_account_policy_path_));
}

TEST_F(DeviceLocalAccountPolicyServiceTest, RetrieveInvalidAccount) {
  SetupKey();

  std::vector<uint8> policy_data;
  EXPECT_FALSE(service_->Retrieve(fake_account_, &policy_data));
  EXPECT_TRUE(policy_data.empty());
}

TEST_F(DeviceLocalAccountPolicyServiceTest, RetrieveNoPolicy) {
  SetupAccount();
  SetupKey();

  std::vector<uint8> policy_data;
  EXPECT_TRUE(service_->Retrieve(fake_account_, &policy_data));
  EXPECT_TRUE(policy_data.empty());
}

TEST_F(DeviceLocalAccountPolicyServiceTest, RetrieveSuccess) {
  SetupAccount();
  SetupKey();

  ASSERT_TRUE(base::CreateDirectory(fake_account_policy_path_.DirName()));
  ASSERT_EQ(policy_blob_.size(),
            base::WriteFile(fake_account_policy_path_,
                            policy_blob_.c_str(), policy_blob_.size()));

  std::vector<uint8> policy_data;
  EXPECT_TRUE(service_->Retrieve(fake_account_, &policy_data));
  EXPECT_FALSE(policy_data.empty());
}

TEST_F(DeviceLocalAccountPolicyServiceTest, PurgeStaleAccounts) {
  SetupKey();

  ASSERT_TRUE(base::WriteFile(fake_account_policy_path_,
                              policy_blob_.c_str(), policy_blob_.size()));

  em::ChromeDeviceSettingsProto device_settings;
  service_->UpdateDeviceSettings(device_settings);
  EXPECT_FALSE(base::PathExists(fake_account_policy_path_));
}

TEST_F(DeviceLocalAccountPolicyServiceTest, MigrateUppercaseDirs) {
  const char *kDir1 = "356a192b7913b04c54574d18c28d46e6395428ab";
  const char *kDir2 = "DA4B9237BACCCDF19C0760CAB7AEC4A8359010B0";
  const char *kDir2Lower = "da4b9237bacccdf19c0760cab7aec4a8359010b0";
  const char *kUnrelated = "foobar";

  base::FilePath fp1(temp_dir_.path().Append(kDir1));
  base::FilePath fp2(temp_dir_.path().Append(kDir2));
  base::FilePath fp2lower(temp_dir_.path().Append(kDir2Lower));
  base::FilePath fpunrel(temp_dir_.path().Append(kUnrelated));

  EXPECT_TRUE(base::CreateDirectory(fp1));
  EXPECT_TRUE(base::CreateDirectory(fp2));
  EXPECT_TRUE(base::CreateDirectory(fpunrel));

  EXPECT_TRUE(service_->MigrateUppercaseDirs());

  EXPECT_TRUE(base::DirectoryExists(fp1));
  EXPECT_FALSE(base::DirectoryExists(fp2));
  EXPECT_TRUE(base::DirectoryExists(fp2lower));
  EXPECT_TRUE(base::DirectoryExists(fpunrel));
}

TEST_F(DeviceLocalAccountPolicyServiceTest, LegacyPublicSessionIdFallback) {
  // Check that a legacy public session ID continues to work as long as the
  // account_id / type fields are not present.
  em::ChromeDeviceSettingsProto device_settings;
  em::DeviceLocalAccountInfoProto* account =
      device_settings.mutable_device_local_accounts()->add_account();
  account->set_deprecated_public_session_id(fake_account_);
  service_->UpdateDeviceSettings(device_settings);
  SetupKey();

  EXPECT_CALL(completion_, ReportSuccess());
  EXPECT_TRUE(
      service_->Store(fake_account_,
                      reinterpret_cast<const uint8*>(policy_blob_.c_str()),
                      policy_blob_.size(), &completion_));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(base::PathExists(fake_account_policy_path_));

  std::vector<uint8> policy_data;
  EXPECT_TRUE(service_->Retrieve(fake_account_, &policy_data));

  ASSERT_EQ(policy_blob_.size(), policy_data.size());
  EXPECT_TRUE(std::equal(policy_blob_.begin(), policy_blob_.end(),
                         policy_data.begin()));
}

TEST_F(DeviceLocalAccountPolicyServiceTest, LegacyPublicSessionIdIgnored) {
  // If there's a legacy public session ID and an account id / type pair, the
  // former should get ignored.
  const char kDeprecatedId[] = "deprecated";
  em::ChromeDeviceSettingsProto device_settings;
  em::DeviceLocalAccountInfoProto* account =
      device_settings.mutable_device_local_accounts()->add_account();
  account->set_deprecated_public_session_id(kDeprecatedId);
  account->set_type(
      em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION);
  account->set_account_id(fake_account_);
  service_->UpdateDeviceSettings(device_settings);
  SetupKey();

  EXPECT_CALL(completion_, ReportFailure(_));
  EXPECT_FALSE(
      service_->Store(kDeprecatedId,
                      reinterpret_cast<const uint8*>(policy_blob_.c_str()),
                      policy_blob_.size(), &completion_));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(base::PathExists(fake_account_policy_path_));
}

}  // namespace login_manager
