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