blob: 320b99372df8d46b9062eeb7bda6047c7690fc0e [file] [log] [blame]
// Copyright (c) 2017 The Chromium 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 "chrome/browser/chromeos/policy/cached_policy_key_loader_chromeos.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/test/scoped_task_environment.h"
#include "chromeos/dbus/fake_cryptohome_client.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace policy {
namespace {
const char kDummyKey1[] = "dummy-key-1";
const char kDummyKey2[] = "dummy-key-2";
const char kTestUserName[] = "test-user@example.com";
class CachedPolicyKeyLoaderTest : public testing::Test {
protected:
CachedPolicyKeyLoaderTest() = default;
void SetUp() override {
ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
cached_policy_key_loader_ = base::MakeUnique<CachedPolicyKeyLoaderChromeOS>(
&cryptohome_client_, scoped_task_environment_.GetMainThreadTaskRunner(),
account_id_, user_policy_keys_dir());
}
void StoreUserPolicyKey(const std::string& public_key) {
ASSERT_TRUE(base::CreateDirectory(user_policy_key_file().DirName()));
ASSERT_EQ(static_cast<int>(public_key.size()),
base::WriteFile(user_policy_key_file(), public_key.data(),
public_key.size()));
}
base::FilePath user_policy_keys_dir() const {
return tmp_dir_.GetPath().AppendASCII("var_run_user_policy");
}
base::FilePath user_policy_key_file() const {
const std::string sanitized_username =
chromeos::CryptohomeClient::GetStubSanitizedUsername(cryptohome_id_);
return user_policy_keys_dir()
.AppendASCII(sanitized_username)
.AppendASCII("policy.pub");
}
void OnPolicyKeyLoaded() { ++policy_key_loaded_callback_invocations_; }
void CallEnsurePolicyKeyLoaded() {
cached_policy_key_loader_->EnsurePolicyKeyLoaded(base::Bind(
&CachedPolicyKeyLoaderTest::OnPolicyKeyLoaded, base::Unretained(this)));
}
void CallReloadPolicyKey() {
cached_policy_key_loader_->ReloadPolicyKey(base::Bind(
&CachedPolicyKeyLoaderTest::OnPolicyKeyLoaded, base::Unretained(this)));
}
base::test::ScopedTaskEnvironment scoped_task_environment_ = {
base::test::ScopedTaskEnvironment::MainThreadType::UI};
chromeos::FakeCryptohomeClient cryptohome_client_;
const AccountId account_id_ = AccountId::FromUserEmail(kTestUserName);
const cryptohome::Identification cryptohome_id_ =
cryptohome::Identification(account_id_);
std::unique_ptr<CachedPolicyKeyLoaderChromeOS> cached_policy_key_loader_;
// Counts how many times OnPolicyKeyLoaded() has been invoked.
int policy_key_loaded_callback_invocations_ = 0;
private:
base::ScopedTempDir tmp_dir_;
DISALLOW_COPY_AND_ASSIGN(CachedPolicyKeyLoaderTest);
};
// Loads an existing key file using EnsurePolicyKeyLoaded.
TEST_F(CachedPolicyKeyLoaderTest, Basic) {
StoreUserPolicyKey(kDummyKey1);
CallEnsurePolicyKeyLoaded();
scoped_task_environment_.RunUntilIdle();
EXPECT_EQ(1, policy_key_loaded_callback_invocations_);
EXPECT_EQ(kDummyKey1, cached_policy_key_loader_->cached_policy_key());
}
// Tries to load key using EnsurePolicyKeyLoaded, but the key is missing.
TEST_F(CachedPolicyKeyLoaderTest, KeyFileMissing) {
CallEnsurePolicyKeyLoaded();
scoped_task_environment_.RunUntilIdle();
EXPECT_EQ(1, policy_key_loaded_callback_invocations_);
EXPECT_EQ(std::string(), cached_policy_key_loader_->cached_policy_key());
}
// Loads an existing key file using EnsurePolicyKeyLoaded. While the load is in
// progress, EnsurePolicyKeyLoaded is called again.
TEST_F(CachedPolicyKeyLoaderTest, EnsureCalledTwice) {
StoreUserPolicyKey(kDummyKey1);
CallEnsurePolicyKeyLoaded();
CallEnsurePolicyKeyLoaded();
EXPECT_EQ(0, policy_key_loaded_callback_invocations_);
scoped_task_environment_.RunUntilIdle();
// We expect that the callback was called for each EnsurePolicyKeyLoaded
// invocation.
EXPECT_EQ(2, policy_key_loaded_callback_invocations_);
EXPECT_EQ(kDummyKey1, cached_policy_key_loader_->cached_policy_key());
}
// After a successful load, changes the policy key file and calls
// EnsurePolicyKeyLoaded.
TEST_F(CachedPolicyKeyLoaderTest, EnsureAfterSuccessfulLoad) {
StoreUserPolicyKey(kDummyKey1);
CallEnsurePolicyKeyLoaded();
EXPECT_EQ(0, policy_key_loaded_callback_invocations_);
scoped_task_environment_.RunUntilIdle();
EXPECT_EQ(1, policy_key_loaded_callback_invocations_);
EXPECT_EQ(kDummyKey1, cached_policy_key_loader_->cached_policy_key());
// Change the policy key file.
StoreUserPolicyKey(kDummyKey2);
CallEnsurePolicyKeyLoaded();
scoped_task_environment_.RunUntilIdle();
// We expect that the callback was invoked, but that the cached policy key is
// still the old one. EnsurePolicyKeyLoaded is not supposed to reload the key.
EXPECT_EQ(2, policy_key_loaded_callback_invocations_);
EXPECT_EQ(kDummyKey1, cached_policy_key_loader_->cached_policy_key());
}
// After a successful load, changes the policy key file and calls
// ReloadPolicyKey.
TEST_F(CachedPolicyKeyLoaderTest, ReloadAfterEnsure) {
StoreUserPolicyKey(kDummyKey1);
CallEnsurePolicyKeyLoaded();
EXPECT_EQ(0, policy_key_loaded_callback_invocations_);
scoped_task_environment_.RunUntilIdle();
EXPECT_EQ(1, policy_key_loaded_callback_invocations_);
EXPECT_EQ(kDummyKey1, cached_policy_key_loader_->cached_policy_key());
// Change the policy key file.
StoreUserPolicyKey(kDummyKey2);
CallReloadPolicyKey();
scoped_task_environment_.RunUntilIdle();
// We expect that the callback was invoked, and that the policy key file has
// been reloded, so the cached policy key is now the new policy key.
EXPECT_EQ(2, policy_key_loaded_callback_invocations_);
EXPECT_EQ(kDummyKey2, cached_policy_key_loader_->cached_policy_key());
}
// During a load, ReloadPolicyKeyFile is invoked.
TEST_F(CachedPolicyKeyLoaderTest, ReloadWhileLoading) {
StoreUserPolicyKey(kDummyKey1);
CallEnsurePolicyKeyLoaded();
CallReloadPolicyKey();
EXPECT_EQ(0, policy_key_loaded_callback_invocations_);
scoped_task_environment_.RunUntilIdle();
// We expect that the callback was called for both the EnsurePolicyKeyLoaded
// and ReloadPolicyKey invocation.
EXPECT_EQ(2, policy_key_loaded_callback_invocations_);
EXPECT_EQ(kDummyKey1, cached_policy_key_loader_->cached_policy_key());
}
// Synchronous load on the caller's thread.
TEST_F(CachedPolicyKeyLoaderTest, LoadImmediately) {
StoreUserPolicyKey(kDummyKey1);
cached_policy_key_loader_->LoadPolicyKeyImmediately();
EXPECT_EQ(kDummyKey1, cached_policy_key_loader_->cached_policy_key());
}
} // namespace
} // namespace policy