1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory>
6 #include <string>
7
8 #include "base/bind.h"
9 #include "base/callback.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/path_service.h"
14 #include "base/run_loop.h"
15 #include "base/test/task_environment.h"
16 #include "base/threading/thread_restrictions.h"
17 #include "base/values.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/browser_process_platform_part.h"
20 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
21 #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base.h"
22 #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h"
23 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
24 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
25 #include "chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.h"
26 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
27 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
28 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
29 #include "chrome/browser/ui/browser.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chromeos/constants/chromeos_paths.h"
33 #include "components/policy/core/common/cloud/cloud_policy_core.h"
34 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
35 #include "components/policy/core/common/external_data_fetcher.h"
36 #include "components/policy/core/common/policy_map.h"
37 #include "components/policy/core/common/policy_service.h"
38 #include "components/policy/policy_constants.h"
39 #include "content/public/test/browser_test.h"
40 #include "content/public/test/test_utils.h"
41 #include "net/test/embedded_test_server/embedded_test_server.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43
44 namespace policy {
45
46 namespace {
47
48 // The contents of these files are served as external data.
49 const char kExternalDataPath[] = "policy/printers_configuration.json";
50 const char kExternalDataPathUpdated[] =
51 "policy/printers_configuration_updated.json";
52 const char kExternalDataPathOverSizeLimit[] =
53 "policy/printers_configuration_over_size_limit.json";
54 // The name of an External Data Policy in Device Policy.
55 const char* const kPolicyName = policy::key::kDevicePrinters;
56
57 const int64_t kTestCacheMaxSize = 64;
58
59 } // namespace
60
61 class DevicePolicyCloudExternalDataManagerTest
62 : public DevicePolicyCrosBrowserTest {
63 public:
DevicePolicyCloudExternalDataManagerTest()64 DevicePolicyCloudExternalDataManagerTest() {
65 DevicePolicyCloudExternalDataManager::SetCacheMaxSizeForTesting(
66 kTestCacheMaxSize);
67 }
68 ~DevicePolicyCloudExternalDataManagerTest() override = default;
69
70 protected:
SetUpOnMainThread()71 void SetUpOnMainThread() override {
72 ASSERT_TRUE(embedded_test_server()->Start());
73 DevicePolicyCrosBrowserTest::SetUpOnMainThread();
74
75 BrowserPolicyConnectorChromeOS* policy_connector =
76 g_browser_process->platform_part()->browser_policy_connector_chromeos();
77 ASSERT_TRUE(policy_connector);
78 policy_service_ = policy_connector->GetPolicyService();
79 ASSERT_TRUE(
80 policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
81 policy_change_registrar_ = std::make_unique<PolicyChangeRegistrar>(
82 policy_service_, PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
83 policy_change_registrar_->Observe(
84 kPolicyName,
85 base::BindRepeating(
86 &DevicePolicyCloudExternalDataManagerTest::PolicyChangedCallback,
87 base::Unretained(this)));
88
89 policy_change_waiting_run_loop_ = std::make_unique<base::RunLoop>();
90 }
91
TearDownOnMainThread()92 void TearDownOnMainThread() override {
93 policy_change_registrar_.reset();
94 DevicePolicyCrosBrowserTest::TearDownOnMainThread();
95 }
96
GetExternalData()97 std::string GetExternalData() {
98 const PolicyMap& policies = policy_service_->GetPolicies(
99 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
100 const PolicyMap::Entry* policy_entry = policies.Get(kPolicyName);
101 EXPECT_TRUE(policy_entry);
102 EXPECT_TRUE(policy_entry->external_data_fetcher);
103
104 base::RunLoop run_loop;
105 std::unique_ptr<std::string> fetched_external_data;
106 base::FilePath file_path;
107 policy_entry->external_data_fetcher->Fetch(
108 base::BindOnce(&test::ExternalDataFetchCallback, &fetched_external_data,
109 &file_path, run_loop.QuitClosure()));
110 run_loop.Run();
111
112 EXPECT_TRUE(fetched_external_data);
113 return *fetched_external_data;
114 }
115
ComputeExternalDataCacheDirectorySize()116 int64_t ComputeExternalDataCacheDirectorySize() {
117 const base::FilePath device_policy_external_data_path =
118 base::PathService::CheckedGet(
119 chromeos::DIR_DEVICE_POLICY_EXTERNAL_DATA);
120 base::ScopedAllowBlockingForTesting allow_blocking;
121 return base::ComputeDirectorySize(device_policy_external_data_path);
122 }
123
SetDeviceNativePrintersExternalData(const std::string & policy)124 void SetDeviceNativePrintersExternalData(const std::string& policy) {
125 device_policy()
126 ->payload()
127 .mutable_native_device_printers()
128 ->set_external_policy(policy);
129 RefreshDevicePolicy();
130 WaitUntilPolicyChanged();
131 }
132
ClearDeviceNativePrintersExternalData()133 void ClearDeviceNativePrintersExternalData() {
134 device_policy()->payload().clear_native_device_printers();
135 RefreshDevicePolicy();
136 WaitUntilPolicyChanged();
137 }
138
ReadExternalDataFile(const std::string & file_path)139 std::string ReadExternalDataFile(const std::string& file_path) {
140 base::FilePath test_data_dir;
141 EXPECT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
142 std::string external_data;
143 {
144 base::ScopedAllowBlockingForTesting allow_blocking;
145 EXPECT_TRUE(base::ReadFileToString(test_data_dir.AppendASCII(file_path),
146 &external_data));
147 }
148 return external_data;
149 }
150
151 private:
PolicyChangedCallback(const base::Value * old_value,const base::Value * new_value)152 void PolicyChangedCallback(const base::Value* old_value,
153 const base::Value* new_value) {
154 policy_change_waiting_run_loop_->Quit();
155 }
156
WaitUntilPolicyChanged()157 void WaitUntilPolicyChanged() {
158 policy_change_waiting_run_loop_->Run();
159 policy_change_waiting_run_loop_.reset(new base::RunLoop());
160 }
161
162 PolicyService* policy_service_ = nullptr;
163 std::unique_ptr<PolicyChangeRegistrar> policy_change_registrar_;
164 std::unique_ptr<base::RunLoop> policy_change_waiting_run_loop_;
165 };
166
IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,FetchExternalData)167 IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,
168 FetchExternalData) {
169 SetDeviceNativePrintersExternalData(test::ConstructExternalDataPolicy(
170 *embedded_test_server(), kExternalDataPath));
171 EXPECT_EQ(ReadExternalDataFile(kExternalDataPath), GetExternalData());
172 }
173
IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,FetchOverSizeLimitExternalData)174 IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,
175 FetchOverSizeLimitExternalData) {
176 EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize());
177
178 std::string external_data =
179 ReadExternalDataFile(kExternalDataPathOverSizeLimit);
180 // Check that file size is greater than cache limit.
181 ASSERT_GT(base::checked_cast<int64_t>(external_data.size()),
182 kTestCacheMaxSize);
183 SetDeviceNativePrintersExternalData(test::ConstructExternalDataPolicy(
184 *embedded_test_server(), kExternalDataPathOverSizeLimit));
185 EXPECT_EQ(external_data, GetExternalData());
186
187 // Check that nothing is cached because file was too big.
188 EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize());
189 }
190
IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,CleanUpResourceCache)191 IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,
192 CleanUpResourceCache) {
193 EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize());
194
195 std::string external_data = ReadExternalDataFile(kExternalDataPath);
196 SetDeviceNativePrintersExternalData(test::ConstructExternalDataPolicy(
197 *embedded_test_server(), kExternalDataPath));
198 EXPECT_EQ(external_data, GetExternalData());
199 EXPECT_EQ(base::checked_cast<int64_t>(external_data.size()),
200 ComputeExternalDataCacheDirectorySize());
201
202 external_data = ReadExternalDataFile(kExternalDataPathUpdated);
203 SetDeviceNativePrintersExternalData(test::ConstructExternalDataPolicy(
204 *embedded_test_server(), kExternalDataPathUpdated));
205 EXPECT_EQ(external_data, GetExternalData());
206 // Check that previous policy data was cleared and replaced by new one.
207 EXPECT_EQ(base::checked_cast<int64_t>(external_data.size()),
208 ComputeExternalDataCacheDirectorySize());
209
210 ClearDeviceNativePrintersExternalData();
211 // We have to wait until
212 // CloudExternalDataManagerBase::Backend::OnMetadataUpdated(), which is
213 // responsible for removing outdated external policy files, is completed.
214 content::RunAllTasksUntilIdle();
215 // Check that policy data was cleared.
216 EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize());
217 }
218
219 } // namespace policy
220