Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / component_updater / supervised_user_whitelist_installer_unittest.cc
blob1222b32a139704429b662a9314cb5cd1f8ebb12c
1 // Copyright 2014 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.
5 #include "base/bind.h"
6 #include "base/callback.h"
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/json/json_file_value_serializer.h"
11 #include "base/json/json_reader.h"
12 #include "base/json/json_writer.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/path_service.h"
15 #include "base/prefs/testing_pref_service.h"
16 #include "base/run_loop.h"
17 #include "base/sequenced_task_runner.h"
18 #include "base/strings/string_util.h"
19 #include "base/test/scoped_path_override.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "base/values.h"
22 #include "chrome/browser/component_updater/supervised_user_whitelist_installer.h"
23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/pref_names.h"
25 #include "components/component_updater/component_updater_paths.h"
26 #include "components/component_updater/component_updater_service.h"
27 #include "components/crx_file/id_util.h"
28 #include "components/safe_json/testing_json_parser.h"
29 #include "components/update_client/crx_update_item.h"
30 #include "components/update_client/update_client.h"
31 #include "components/update_client/utils.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h"
35 using update_client::CrxComponent;
36 using update_client::CrxUpdateItem;
38 namespace component_updater {
40 namespace {
42 const char kClientId[] = "client-id";
43 const char kCrxId[] = "abcdefghijklmnopponmlkjihgfedcba";
44 const char kName[] = "Some Whitelist";
45 const char kOtherClientId[] = "other-client-id";
46 const char kVersion[] = "1.2.3.4";
47 const char kWhitelistContents[] = "{\"foo\": \"bar\"}";
48 const char kWhitelistFile[] = "whitelist.json";
50 std::string CrxIdToHashToCrxId(const std::string& kCrxId) {
51 CrxComponent component;
52 component.pk_hash =
53 SupervisedUserWhitelistInstaller::GetHashFromCrxId(kCrxId);
54 EXPECT_EQ(16u, component.pk_hash.size());
55 return GetCrxComponentID(component);
58 std::string JsonToString(const base::DictionaryValue& dict) {
59 std::string json;
60 base::JSONWriter::Write(dict, &json);
61 return json;
64 class MockComponentUpdateService : public ComponentUpdateService,
65 public OnDemandUpdater {
66 public:
67 MockComponentUpdateService(
68 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
69 : task_runner_(task_runner), on_demand_update_called_(false) {}
71 ~MockComponentUpdateService() override {}
73 bool on_demand_update_called() const { return on_demand_update_called_; }
75 const CrxComponent* registered_component() { return component_.get(); }
77 void set_registration_callback(const base::Closure& registration_callback) {
78 registration_callback_ = registration_callback;
81 // ComponentUpdateService implementation:
82 void AddObserver(Observer* observer) override { ADD_FAILURE(); }
83 void RemoveObserver(Observer* observer) override { ADD_FAILURE(); }
85 std::vector<std::string> GetComponentIDs() const override {
86 ADD_FAILURE();
87 return std::vector<std::string>();
90 bool RegisterComponent(const CrxComponent& component) override {
91 EXPECT_EQ(nullptr, component_.get());
92 component_.reset(new CrxComponent(component));
93 if (!registration_callback_.is_null())
94 registration_callback_.Run();
96 return true;
99 bool UnregisterComponent(const std::string& crx_id) override {
100 if (!component_) {
101 ADD_FAILURE();
102 return false;
105 EXPECT_EQ(GetCrxComponentID(*component_), crx_id);
106 if (!component_->installer->Uninstall()) {
107 ADD_FAILURE();
108 return false;
111 component_.reset();
112 return true;
115 OnDemandUpdater& GetOnDemandUpdater() override { return *this; }
117 void MaybeThrottle(const std::string& kCrxId,
118 const base::Closure& callback) override {
119 ADD_FAILURE();
122 scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() override {
123 return task_runner_;
126 bool GetComponentDetails(const std::string& component_id,
127 CrxUpdateItem* item) const override {
128 ADD_FAILURE();
129 return false;
132 // OnDemandUpdater implementation:
133 bool OnDemandUpdate(const std::string& crx_id) override {
134 on_demand_update_called_ = true;
136 if (!component_) {
137 ADD_FAILURE() << "Trying to update unregistered component " << crx_id;
138 return false;
141 EXPECT_EQ(GetCrxComponentID(*component_), crx_id);
142 return true;
145 private:
146 scoped_refptr<base::SequencedTaskRunner> task_runner_;
147 scoped_ptr<CrxComponent> component_;
148 base::Closure registration_callback_;
149 bool on_demand_update_called_;
152 class WhitelistLoadObserver {
153 public:
154 explicit WhitelistLoadObserver(SupervisedUserWhitelistInstaller* installer)
155 : weak_ptr_factory_(this) {
156 installer->Subscribe(base::Bind(&WhitelistLoadObserver::OnWhitelistReady,
157 weak_ptr_factory_.GetWeakPtr()));
160 void Wait() { run_loop_.Run(); }
162 const base::FilePath& whitelist_path() { return whitelist_path_; }
164 private:
165 void OnWhitelistReady(const std::string& crx_id,
166 const base::FilePath& whitelist_path) {
167 EXPECT_EQ(base::FilePath::StringType(), whitelist_path_.value());
168 whitelist_path_ = whitelist_path;
169 run_loop_.Quit();
172 base::FilePath whitelist_path_;
174 base::RunLoop run_loop_;
175 base::WeakPtrFactory<WhitelistLoadObserver> weak_ptr_factory_;
178 } // namespace
180 class SupervisedUserWhitelistInstallerTest : public testing::Test {
181 public:
182 SupervisedUserWhitelistInstallerTest()
183 : raw_whitelists_path_override_(DIR_SUPERVISED_USER_WHITELISTS),
184 installed_whitelists_path_override_(
185 chrome::DIR_SUPERVISED_USER_INSTALLED_WHITELISTS),
186 component_update_service_(base::ThreadTaskRunnerHandle::Get()),
187 installer_(
188 SupervisedUserWhitelistInstaller::Create(&component_update_service_,
189 nullptr,
190 &local_state_)) {}
192 ~SupervisedUserWhitelistInstallerTest() override {}
194 void SetUp() override {
195 SupervisedUserWhitelistInstaller::RegisterPrefs(local_state_.registry());
197 ASSERT_TRUE(PathService::Get(DIR_SUPERVISED_USER_WHITELISTS,
198 &whitelist_base_directory_));
199 whitelist_directory_ = whitelist_base_directory_.AppendASCII(kCrxId);
200 whitelist_version_directory_ = whitelist_directory_.AppendASCII(kVersion);
202 ASSERT_TRUE(
203 PathService::Get(chrome::DIR_SUPERVISED_USER_INSTALLED_WHITELISTS,
204 &installed_whitelist_directory_));
205 std::string crx_id(kCrxId);
206 whitelist_path_ =
207 installed_whitelist_directory_.AppendASCII(crx_id + ".json");
209 scoped_ptr<base::DictionaryValue> whitelist_dict(
210 new base::DictionaryValue);
211 whitelist_dict->SetString("file", kWhitelistFile);
212 manifest_.Set("whitelist", whitelist_dict.release());
213 manifest_.SetString("version", kVersion);
215 scoped_ptr<base::DictionaryValue> crx_dict(new base::DictionaryValue);
216 crx_dict->SetString("name", kName);
217 scoped_ptr<base::ListValue> clients(new base::ListValue);
218 clients->AppendString(kClientId);
219 clients->AppendString(kOtherClientId);
220 crx_dict->Set("clients", clients.release());
221 pref_.Set(kCrxId, crx_dict.release());
224 protected:
225 void PrepareWhitelistFile(const base::FilePath& whitelist_path) {
226 size_t whitelist_contents_length = sizeof(kWhitelistContents) - 1;
227 ASSERT_EQ(static_cast<int>(whitelist_contents_length),
228 base::WriteFile(whitelist_path, kWhitelistContents,
229 whitelist_contents_length));
232 void PrepareWhitelistDirectory(const base::FilePath& whitelist_directory) {
233 PrepareWhitelistFile(whitelist_directory.AppendASCII(kWhitelistFile));
234 base::FilePath manifest_file =
235 whitelist_directory.AppendASCII("manifest.json");
236 ASSERT_TRUE(JSONFileValueSerializer(manifest_file).Serialize(manifest_));
239 void RegisterExistingComponents() {
240 local_state_.Set(prefs::kRegisteredSupervisedUserWhitelists, pref_);
241 installer_->RegisterComponents();
242 base::RunLoop().RunUntilIdle();
245 void CheckRegisteredComponent(const char* version) {
246 const CrxComponent* component =
247 component_update_service_.registered_component();
248 ASSERT_TRUE(component);
249 EXPECT_EQ(kName, component->name);
250 EXPECT_EQ(kCrxId, GetCrxComponentID(*component));
251 EXPECT_EQ(version, component->version.GetString());
254 base::MessageLoop message_loop_;
255 base::ScopedPathOverride raw_whitelists_path_override_;
256 base::ScopedPathOverride installed_whitelists_path_override_;
257 safe_json::TestingJsonParser::ScopedFactoryOverride json_parser_override_;
258 MockComponentUpdateService component_update_service_;
259 TestingPrefServiceSimple local_state_;
260 scoped_ptr<SupervisedUserWhitelistInstaller> installer_;
261 base::FilePath whitelist_base_directory_;
262 base::FilePath whitelist_directory_;
263 base::FilePath whitelist_version_directory_;
264 base::FilePath installed_whitelist_directory_;
265 base::FilePath whitelist_path_;
266 base::DictionaryValue manifest_;
267 base::DictionaryValue pref_;
270 TEST_F(SupervisedUserWhitelistInstallerTest, GetHashFromCrxId) {
272 std::string extension_id = "abcdefghijklmnopponmlkjihgfedcba";
273 ASSERT_EQ(extension_id, CrxIdToHashToCrxId(extension_id));
277 std::string extension_id = "aBcDeFgHiJkLmNoPpOnMlKjIhGfEdCbA";
278 ASSERT_EQ(base::ToLowerASCII(extension_id),
279 CrxIdToHashToCrxId(extension_id));
283 std::string extension_id = crx_file::id_util::GenerateId("Moose");
284 ASSERT_EQ(extension_id, CrxIdToHashToCrxId(extension_id));
288 TEST_F(SupervisedUserWhitelistInstallerTest, InstallNewWhitelist) {
289 base::RunLoop registration_run_loop;
290 component_update_service_.set_registration_callback(
291 registration_run_loop.QuitClosure());
293 WhitelistLoadObserver observer(installer_.get());
294 installer_->RegisterWhitelist(kClientId, kCrxId, kName);
295 registration_run_loop.Run();
297 ASSERT_NO_FATAL_FAILURE(CheckRegisteredComponent("0.0.0.0"));
298 EXPECT_TRUE(component_update_service_.on_demand_update_called());
300 // Registering the same whitelist for another client should not do anything.
301 installer_->RegisterWhitelist(kOtherClientId, kCrxId, kName);
303 base::ScopedTempDir temp_dir;
304 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
305 base::FilePath unpacked_path = temp_dir.path();
306 ASSERT_NO_FATAL_FAILURE(PrepareWhitelistDirectory(unpacked_path));
308 const CrxComponent* component =
309 component_update_service_.registered_component();
310 ASSERT_TRUE(component);
311 EXPECT_TRUE(component->installer->Install(manifest_, unpacked_path));
313 observer.Wait();
314 EXPECT_EQ(whitelist_path_.value(), observer.whitelist_path().value());
316 std::string whitelist_contents;
317 ASSERT_TRUE(base::ReadFileToString(whitelist_path_, &whitelist_contents));
319 // The actual file contents don't have to be equal, but the parsed values
320 // should be.
321 EXPECT_TRUE(base::JSONReader::Read(kWhitelistContents)
322 ->Equals(base::JSONReader::Read(whitelist_contents).get()))
323 << kWhitelistContents << " vs. " << whitelist_contents;
325 EXPECT_EQ(JsonToString(pref_),
326 JsonToString(*local_state_.GetDictionary(
327 prefs::kRegisteredSupervisedUserWhitelists)));
330 TEST_F(SupervisedUserWhitelistInstallerTest,
331 RegisterAndUninstallExistingWhitelist) {
332 ASSERT_TRUE(base::CreateDirectory(whitelist_version_directory_));
333 ASSERT_NO_FATAL_FAILURE(
334 PrepareWhitelistDirectory(whitelist_version_directory_));
335 ASSERT_NO_FATAL_FAILURE(PrepareWhitelistFile(whitelist_path_));
337 // Create another whitelist directory, with an ID that is not registered.
338 base::FilePath other_directory =
339 whitelist_base_directory_.AppendASCII("paobncmdlekfjgihhigjfkeldmcnboap");
340 ASSERT_TRUE(base::CreateDirectory(other_directory));
341 ASSERT_NO_FATAL_FAILURE(PrepareWhitelistDirectory(other_directory));
343 // Create a directory that is not a valid whitelist directory.
344 base::FilePath non_whitelist_directory =
345 whitelist_base_directory_.AppendASCII("Not a whitelist");
346 ASSERT_TRUE(base::CreateDirectory(non_whitelist_directory));
348 RegisterExistingComponents();
350 ASSERT_NO_FATAL_FAILURE(CheckRegisteredComponent(kVersion));
351 EXPECT_FALSE(component_update_service_.on_demand_update_called());
353 // Check that unregistered whitelists have been removed:
354 // The registered whitelist directory should still exist.
355 EXPECT_TRUE(base::DirectoryExists(whitelist_directory_));
357 // The other directory should be gone.
358 EXPECT_FALSE(base::DirectoryExists(other_directory));
360 // The non-whitelist directory should still exist as well.
361 EXPECT_TRUE(base::DirectoryExists(non_whitelist_directory));
363 // Unregistering for the first client should do nothing.
365 base::RunLoop run_loop;
366 installer_->UnregisterWhitelist(kClientId, kCrxId);
367 run_loop.RunUntilIdle();
369 EXPECT_TRUE(component_update_service_.registered_component());
370 EXPECT_TRUE(base::DirectoryExists(whitelist_version_directory_));
371 EXPECT_TRUE(base::PathExists(whitelist_path_));
373 // Unregistering for the second client should uninstall the whitelist.
375 base::RunLoop run_loop;
376 installer_->UnregisterWhitelist(kOtherClientId, kCrxId);
377 run_loop.RunUntilIdle();
379 EXPECT_FALSE(component_update_service_.registered_component());
380 EXPECT_FALSE(base::DirectoryExists(whitelist_directory_));
381 EXPECT_FALSE(base::PathExists(whitelist_path_));
384 } // namespace component_updater