1 // Copyright (c) 2013 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 "chrome/browser/extensions/extension_service.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <algorithm>
11 #include <map>
12 #include <memory>
13 #include <set>
14 #include <string>
15 #include <utility>
16 #include <vector>
17
18 #include "base/at_exit.h"
19 #include "base/bind.h"
20 #include "base/command_line.h"
21 #include "base/files/file_util.h"
22 #include "base/files/scoped_temp_dir.h"
23 #include "base/json/json_file_value_serializer.h"
24 #include "base/json/json_reader.h"
25 #include "base/json/json_string_value_serializer.h"
26 #include "base/location.h"
27 #include "base/memory/ptr_util.h"
28 #include "base/one_shot_event.h"
29 #include "base/run_loop.h"
30 #include "base/single_thread_task_runner.h"
31 #include "base/stl_util.h"
32 #include "base/strings/pattern.h"
33 #include "base/strings/string16.h"
34 #include "base/strings/string_number_conversions.h"
35 #include "base/strings/string_util.h"
36 #include "base/strings/stringprintf.h"
37 #include "base/strings/utf_string_conversions.h"
38 #include "base/test/bind.h"
39 #include "base/time/time.h"
40 #include "base/values.h"
41 #include "base/version.h"
42 #include "build/build_config.h"
43 #include "chrome/browser/browser_process.h"
44 #include "chrome/browser/chrome_notification_types.h"
45 #include "chrome/browser/extensions/blocklist.h"
46 #include "chrome/browser/extensions/chrome_app_sorting.h"
47 #include "chrome/browser/extensions/chrome_extension_cookies.h"
48 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
49 #include "chrome/browser/extensions/component_loader.h"
50 #include "chrome/browser/extensions/crx_installer.h"
51 #include "chrome/browser/extensions/default_apps.h"
52 #include "chrome/browser/extensions/extension_error_ui.h"
53 #include "chrome/browser/extensions/extension_management_test_util.h"
54 #include "chrome/browser/extensions/extension_service_test_base.h"
55 #include "chrome/browser/extensions/extension_service_test_with_install.h"
56 #include "chrome/browser/extensions/extension_special_storage_policy.h"
57 #include "chrome/browser/extensions/extension_util.h"
58 #include "chrome/browser/extensions/external_install_error.h"
59 #include "chrome/browser/extensions/external_install_manager.h"
60 #include "chrome/browser/extensions/external_policy_loader.h"
61 #include "chrome/browser/extensions/external_pref_loader.h"
62 #include "chrome/browser/extensions/external_provider_impl.h"
63 #include "chrome/browser/extensions/external_testing_loader.h"
64 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
65 #include "chrome/browser/extensions/installed_loader.h"
66 #include "chrome/browser/extensions/load_error_reporter.h"
67 #include "chrome/browser/extensions/pack_extension_job.h"
68 #include "chrome/browser/extensions/pending_extension_info.h"
69 #include "chrome/browser/extensions/pending_extension_manager.h"
70 #include "chrome/browser/extensions/permissions_test_util.h"
71 #include "chrome/browser/extensions/permissions_updater.h"
72 #include "chrome/browser/extensions/plugin_manager.h"
73 #include "chrome/browser/extensions/test_blocklist.h"
74 #include "chrome/browser/extensions/test_extension_system.h"
75 #include "chrome/browser/extensions/unpacked_installer.h"
76 #include "chrome/browser/extensions/updater/extension_updater.h"
77 #include "chrome/browser/policy/profile_policy_connector.h"
78 #include "chrome/browser/themes/theme_service.h"
79 #include "chrome/browser/ui/global_error/global_error.h"
80 #include "chrome/browser/ui/global_error/global_error_service.h"
81 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
82 #include "chrome/browser/ui/global_error/global_error_waiter.h"
83 #include "chrome/browser/web_applications/components/external_app_install_features.h"
84 #include "chrome/common/chrome_constants.h"
85 #include "chrome/common/chrome_switches.h"
86 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
87 #include "chrome/common/pref_names.h"
88 #include "chrome/common/url_constants.h"
89 #include "chrome/grit/browser_resources.h"
90 #include "chrome/grit/generated_resources.h"
91 #include "chrome/test/base/scoped_browser_locale.h"
92 #include "chrome/test/base/testing_profile.h"
93 #include "components/crx_file/id_util.h"
94 #include "components/pref_registry/pref_registry_syncable.h"
95 #include "components/prefs/scoped_user_pref_update.h"
96 #include "components/safe_browsing/buildflags.h"
97 #include "components/services/storage/public/mojom/indexed_db_control.mojom.h"
98 #include "components/sync/model/string_ordinal.h"
99 #include "components/sync_preferences/pref_service_syncable.h"
100 #include "components/sync_preferences/testing_pref_service_syncable.h"
101 #include "content/public/browser/dom_storage_context.h"
102 #include "content/public/browser/gpu_data_manager.h"
103 #include "content/public/browser/notification_service.h"
104 #include "content/public/browser/plugin_service.h"
105 #include "content/public/browser/render_process_host.h"
106 #include "content/public/browser/storage_partition.h"
107 #include "content/public/common/content_constants.h"
108 #include "content/public/test/browser_task_environment.h"
109 #include "content/public/test/test_utils.h"
110 #include "extensions/browser/disable_reason.h"
111 #include "extensions/browser/extension_creator.h"
112 #include "extensions/browser/extension_prefs.h"
113 #include "extensions/browser/extension_registry.h"
114 #include "extensions/browser/extension_system.h"
115 #include "extensions/browser/extension_util.h"
116 #include "extensions/browser/external_install_info.h"
117 #include "extensions/browser/external_provider_interface.h"
118 #include "extensions/browser/install_flag.h"
119 #include "extensions/browser/management_policy.h"
120 #include "extensions/browser/mock_external_provider.h"
121 #include "extensions/browser/pref_names.h"
122 #include "extensions/browser/test_extension_registry_observer.h"
123 #include "extensions/browser/test_management_policy.h"
124 #include "extensions/browser/uninstall_reason.h"
125 #include "extensions/browser/updater/extension_downloader_test_helper.h"
126 #include "extensions/browser/updater/null_extension_cache.h"
127 #include "extensions/common/extension.h"
128 #include "extensions/common/extension_builder.h"
129 #include "extensions/common/extension_l10n_util.h"
130 #include "extensions/common/extension_resource.h"
131 #include "extensions/common/extension_urls.h"
132 #include "extensions/common/file_util.h"
133 #include "extensions/common/manifest_constants.h"
134 #include "extensions/common/manifest_handlers/background_info.h"
135 #include "extensions/common/manifest_handlers/content_scripts_handler.h"
136 #include "extensions/common/manifest_handlers/permissions_parser.h"
137 #include "extensions/common/manifest_url_handlers.h"
138 #include "extensions/common/permissions/permission_set.h"
139 #include "extensions/common/permissions/permissions_data.h"
140 #include "extensions/common/switches.h"
141 #include "extensions/common/url_pattern.h"
142 #include "extensions/common/value_builder.h"
143 #include "extensions/common/verifier_formats.h"
144 #include "extensions/test/test_extension_dir.h"
145 #include "mojo/public/cpp/bindings/remote.h"
146 #include "net/cookies/canonical_cookie.h"
147 #include "net/cookies/cookie_access_result.h"
148 #include "net/cookies/cookie_options.h"
149 #include "net/cookies/cookie_store.h"
150 #include "net/cookies/cookie_util.h"
151 #include "ppapi/buildflags/buildflags.h"
152 #include "services/network/public/mojom/cookie_manager.mojom.h"
153 #include "services/network/public/mojom/network_service.mojom.h"
154 #include "storage/browser/database/database_tracker.h"
155 #include "storage/browser/quota/quota_manager.h"
156 #include "storage/common/database/database_identifier.h"
157 #include "testing/gmock/include/gmock/gmock.h"
158 #include "testing/gtest/include/gtest/gtest.h"
159 #include "testing/platform_test.h"
160 #include "ui/base/l10n/l10n_util.h"
161 #include "url/gurl.h"
162 #include "url/origin.h"
163
164 // The blocklist tests rely on the safe-browsing database.
165 #if BUILDFLAG(SAFE_BROWSING_DB_LOCAL)
166 #define ENABLE_BLOCKLIST_TESTS
167 #endif
168
169 using content::BrowserContext;
170 using content::BrowserThread;
171 using content::DOMStorageContext;
172 using content::PluginService;
173
174 namespace extensions {
175
176 namespace keys = manifest_keys;
177
178 namespace {
179
180 // Extension ids used during testing.
181 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
182 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
183 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
184 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
185 const char good2048[] = "dfhpodpjggiioolfhoimofdbfjibmedp";
186 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
187 const char minimal_platform_app_crx[] = "jjeoclcdfjddkdjokiejckgcildcflpp";
188 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
189 const char page_action[] = "dpfmafkdlbmopmcepgpjkpldjbghdibm";
190 const char theme_crx[] = "idlfhncioikpdnlhnmcjogambnefbbfp";
191 const char theme2_crx[] = "ibcijncamhmjjdodjamgiipcgnnaeagd";
192 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
193 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
194 const char updates_from_webstore2[] = "oolblhbomdbcpmafphaodhjfcgbihcdg";
195 const char updates_from_webstore3[] = "bmfoocgfinpmkmlbjhcbofejhkhlbchk";
196 const char permissions_blocklist[] = "noffkehfcaggllbcojjbopcmlhcnhcdn";
197 const char cast_stable[] = "boadgeojelhgndaghljhdicfkmllpafd";
198 const char cast_beta[] = "dliochdbjfkdbacpmhlcpmleaejidimm";
199 const char genius_app[] = "ljoammodoonkhnehlncldjelhidljdpi";
200 const char kPrefBlocklist[] = "blacklist";
201
202 struct BubbleErrorsTestData {
BubbleErrorsTestDataextensions::__anonafc55fc40111::BubbleErrorsTestData203 BubbleErrorsTestData(const std::string& id,
204 const std::string& version,
205 const base::FilePath& crx_path,
206 size_t expected_bubble_error_count)
207 : id(id),
208 version(version),
209 crx_path(crx_path),
210 expected_bubble_error_count(expected_bubble_error_count) {}
211 std::string id;
212 std::string version;
213 base::FilePath crx_path;
214 size_t expected_bubble_error_count;
215 bool expect_has_shown_bubble_view;
216 };
217
AddPattern(URLPatternSet * extent,const std::string & pattern)218 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
219 int schemes = URLPattern::SCHEME_ALL;
220 extent->AddPattern(URLPattern(schemes, pattern));
221 }
222
GetTemporaryFile()223 base::FilePath GetTemporaryFile() {
224 base::FilePath temp_file;
225 CHECK(base::CreateTemporaryFile(&temp_file));
226 return temp_file;
227 }
228
WaitForCountNotificationsCallback(int * count)229 bool WaitForCountNotificationsCallback(int *count) {
230 return --(*count) == 0;
231 }
232
HasExternalInstallErrors(ExtensionService * service)233 bool HasExternalInstallErrors(ExtensionService* service) {
234 return !service->external_install_manager()->GetErrorsForTesting().empty();
235 }
236
HasExternalInstallBubble(ExtensionService * service)237 bool HasExternalInstallBubble(ExtensionService* service) {
238 std::vector<ExternalInstallError*> errors =
239 service->external_install_manager()->GetErrorsForTesting();
240 auto found = std::find_if(
241 errors.begin(), errors.end(),
242 [](const ExternalInstallError* error) {
243 return error->alert_type() == ExternalInstallError::BUBBLE_ALERT;
244 });
245 return found != errors.end();
246 }
247
GetExternalInstallBubbleCount(ExtensionService * service)248 size_t GetExternalInstallBubbleCount(ExtensionService* service) {
249 size_t bubble_count = 0u;
250 std::vector<ExternalInstallError*> errors =
251 service->external_install_manager()->GetErrorsForTesting();
252 for (auto* error : errors)
253 bubble_count += error->alert_type() == ExternalInstallError::BUBBLE_ALERT;
254 return bubble_count;
255 }
256
CreateExtension(const std::string & name,const base::FilePath & path,Manifest::Location location)257 scoped_refptr<const Extension> CreateExtension(const std::string& name,
258 const base::FilePath& path,
259 Manifest::Location location) {
260 return ExtensionBuilder(name).SetPath(path).SetLocation(location).Build();
261 }
262
CreateExternalExtension(const ExtensionId & extension_id,const std::string & version_str,const base::FilePath & path,Manifest::Location location,Extension::InitFromValueFlags flags)263 std::unique_ptr<ExternalInstallInfoFile> CreateExternalExtension(
264 const ExtensionId& extension_id,
265 const std::string& version_str,
266 const base::FilePath& path,
267 Manifest::Location location,
268 Extension::InitFromValueFlags flags) {
269 return std::make_unique<ExternalInstallInfoFile>(
270 extension_id, base::Version(version_str), path, location, flags, false,
271 false);
272 }
273
274 // Helper function to persist the passed directories and file paths in
275 // |extension_dir|. Also, writes a generic manifest file.
PersistExtensionWithPaths(const base::FilePath & extension_dir,const std::vector<base::FilePath> & directory_paths,const std::vector<base::FilePath> & file_paths)276 void PersistExtensionWithPaths(
277 const base::FilePath& extension_dir,
278 const std::vector<base::FilePath>& directory_paths,
279 const std::vector<base::FilePath>& file_paths) {
280 for (const auto& directory : directory_paths)
281 EXPECT_TRUE(base::CreateDirectory(directory));
282
283 std::string data = "file_data";
284 for (const auto& file : file_paths) {
285 EXPECT_EQ(static_cast<int>(data.size()),
286 base::WriteFile(file, data.c_str(), data.size()));
287 }
288
289 std::unique_ptr<base::DictionaryValue> manifest =
290 DictionaryBuilder()
291 .Set(keys::kName, "Test extension")
292 .Set(keys::kVersion, "1.0")
293 .Set(keys::kManifestVersion, 2)
294 .Build();
295
296 // Persist manifest file.
297 base::FilePath manifest_path = extension_dir.Append(kManifestFilename);
298 JSONFileValueSerializer(manifest_path).Serialize(*manifest);
299 EXPECT_TRUE(base::PathExists(manifest_path));
300 }
301
302 } // namespace
303
304 class MockProviderVisitor : public ExternalProviderInterface::VisitorInterface {
305 public:
306 // The provider will return |fake_base_path| from
307 // GetBaseCrxFilePath(). User can test the behavior with
308 // and without an empty path using this parameter.
MockProviderVisitor(base::FilePath fake_base_path)309 explicit MockProviderVisitor(base::FilePath fake_base_path)
310 : ids_found_(0),
311 fake_base_path_(fake_base_path),
312 expected_creation_flags_(Extension::NO_FLAGS) {
313 profile_.reset(new TestingProfile);
314 }
315
MockProviderVisitor(base::FilePath fake_base_path,int expected_creation_flags)316 MockProviderVisitor(base::FilePath fake_base_path,
317 int expected_creation_flags)
318 : ids_found_(0),
319 fake_base_path_(fake_base_path),
320 expected_creation_flags_(expected_creation_flags) {
321 profile_.reset(new TestingProfile);
322 }
323
Visit(const std::string & json_data)324 int Visit(const std::string& json_data) {
325 return Visit(json_data, Manifest::EXTERNAL_PREF,
326 Manifest::EXTERNAL_PREF_DOWNLOAD);
327 }
328
Visit(const std::string & json_data,Manifest::Location crx_location,Manifest::Location download_location)329 int Visit(const std::string& json_data,
330 Manifest::Location crx_location,
331 Manifest::Location download_location) {
332 crx_location_ = crx_location;
333 // Give the test json file to the provider for parsing.
334 provider_.reset(new ExternalProviderImpl(
335 this, new ExternalTestingLoader(json_data, fake_base_path_),
336 profile_.get(), crx_location, download_location, Extension::NO_FLAGS));
337 if (crx_location == Manifest::EXTERNAL_REGISTRY)
338 provider_->set_allow_updates(true);
339
340 // We also parse the file into a dictionary to compare what we get back
341 // from the provider.
342 prefs_ = GetDictionaryFromJSON(json_data);
343
344 // Reset our counter.
345 ids_found_ = 0;
346 // Ask the provider to look up all extensions and return them.
347 provider_->VisitRegisteredExtension();
348
349 return ids_found_;
350 }
351
OnExternalExtensionFileFound(const ExternalInstallInfoFile & info)352 bool OnExternalExtensionFileFound(
353 const ExternalInstallInfoFile& info) override {
354 EXPECT_EQ(expected_creation_flags_, info.creation_flags);
355
356 ++ids_found_;
357 base::DictionaryValue* pref;
358 // This tests is to make sure that the provider only notifies us of the
359 // values we gave it. So if the id we doesn't exist in our internal
360 // dictionary then something is wrong.
361 EXPECT_TRUE(prefs_->GetDictionary(info.extension_id, &pref))
362 << "Got back ID (" << info.extension_id.c_str()
363 << ") we weren't expecting";
364
365 EXPECT_TRUE(info.path.IsAbsolute());
366 if (!fake_base_path_.empty())
367 EXPECT_TRUE(fake_base_path_.IsParent(info.path));
368
369 if (pref) {
370 EXPECT_TRUE(provider_->HasExtension(info.extension_id));
371
372 // Ask provider if the extension we got back is registered.
373 Manifest::Location location = Manifest::INVALID_LOCATION;
374 std::unique_ptr<base::Version> v1;
375 base::FilePath crx_path;
376
377 EXPECT_TRUE(
378 provider_->GetExtensionDetails(info.extension_id, nullptr, &v1));
379 EXPECT_EQ(info.version.GetString(), v1->GetString());
380
381 std::unique_ptr<base::Version> v2;
382 EXPECT_TRUE(
383 provider_->GetExtensionDetails(info.extension_id, &location, &v2));
384 EXPECT_EQ(info.version.GetString(), v1->GetString());
385 EXPECT_EQ(info.version.GetString(), v2->GetString());
386 EXPECT_EQ(crx_location_, location);
387
388 // Remove it so we won't count it ever again.
389 prefs_->Remove(info.extension_id, nullptr);
390 }
391 return true;
392 }
393
OnExternalExtensionUpdateUrlFound(const ExternalInstallInfoUpdateUrl & info,bool is_initial_load)394 bool OnExternalExtensionUpdateUrlFound(
395 const ExternalInstallInfoUpdateUrl& info,
396 bool is_initial_load) override {
397 ++ids_found_;
398 base::DictionaryValue* pref;
399 // This tests is to make sure that the provider only notifies us of the
400 // values we gave it. So if the id we doesn't exist in our internal
401 // dictionary then something is wrong.
402 EXPECT_TRUE(prefs_->GetDictionary(info.extension_id, &pref))
403 << L"Got back ID (" << info.extension_id.c_str()
404 << ") we weren't expecting";
405 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, info.download_location);
406
407 if (pref) {
408 EXPECT_TRUE(provider_->HasExtension(info.extension_id));
409
410 // External extensions with update URLs do not have versions.
411 std::unique_ptr<base::Version> v1;
412 Manifest::Location location1 = Manifest::INVALID_LOCATION;
413 EXPECT_TRUE(
414 provider_->GetExtensionDetails(info.extension_id, &location1, &v1));
415 EXPECT_FALSE(v1.get());
416 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
417
418 std::string parsed_install_parameter;
419 pref->GetString("install_parameter", &parsed_install_parameter);
420 EXPECT_EQ(parsed_install_parameter, info.install_parameter);
421
422 // Remove it so we won't count it again.
423 prefs_->Remove(info.extension_id, nullptr);
424 }
425 return true;
426 }
427
OnExternalProviderUpdateComplete(const ExternalProviderInterface * provider,const std::vector<ExternalInstallInfoUpdateUrl> & update_url_extensions,const std::vector<ExternalInstallInfoFile> & file_extensions,const std::set<std::string> & removed_extensions)428 void OnExternalProviderUpdateComplete(
429 const ExternalProviderInterface* provider,
430 const std::vector<ExternalInstallInfoUpdateUrl>& update_url_extensions,
431 const std::vector<ExternalInstallInfoFile>& file_extensions,
432 const std::set<std::string>& removed_extensions) override {
433 ADD_FAILURE() << "MockProviderVisitor does not provide incremental updates,"
434 " use MockUpdateProviderVisitor instead.";
435 }
436
OnExternalProviderReady(const ExternalProviderInterface * provider)437 void OnExternalProviderReady(
438 const ExternalProviderInterface* provider) override {
439 EXPECT_EQ(provider, provider_.get());
440 EXPECT_TRUE(provider->IsReady());
441 }
442
profile()443 Profile* profile() { return profile_.get(); }
provider() const444 const ExternalProviderImpl& provider() const { return *provider_; }
445
446 protected:
447 std::unique_ptr<ExternalProviderImpl> provider_;
448
GetDictionaryFromJSON(const std::string & json_data)449 std::unique_ptr<base::DictionaryValue> GetDictionaryFromJSON(
450 const std::string& json_data) {
451 // We also parse the file into a dictionary to compare what we get back
452 // from the provider.
453 JSONStringValueDeserializer deserializer(json_data);
454 std::unique_ptr<base::Value> json_value =
455 deserializer.Deserialize(nullptr, nullptr);
456
457 if (!json_value || !json_value->is_dict()) {
458 ADD_FAILURE() << "Unable to deserialize json data";
459 return std::unique_ptr<base::DictionaryValue>();
460 } else {
461 return base::DictionaryValue::From(std::move(json_value));
462 }
463 }
464
465 private:
466 int ids_found_;
467 base::FilePath fake_base_path_;
468 int expected_creation_flags_;
469 Manifest::Location crx_location_;
470 std::unique_ptr<base::DictionaryValue> prefs_;
471 std::unique_ptr<TestingProfile> profile_;
472
473 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
474 };
475
476 // Mock provider that can simulate incremental update like
477 // ExternalRegistryLoader.
478 class MockUpdateProviderVisitor : public MockProviderVisitor {
479 public:
480 // The provider will return |fake_base_path| from
481 // GetBaseCrxFilePath(). User can test the behavior with
482 // and without an empty path using this parameter.
MockUpdateProviderVisitor(base::FilePath fake_base_path)483 explicit MockUpdateProviderVisitor(base::FilePath fake_base_path)
484 : MockProviderVisitor(fake_base_path) {}
485
VisitDueToUpdate(const std::string & json_data)486 void VisitDueToUpdate(const std::string& json_data) {
487 update_url_extension_ids_.clear();
488 file_extension_ids_.clear();
489 removed_extension_ids_.clear();
490
491 std::unique_ptr<base::DictionaryValue> new_prefs =
492 GetDictionaryFromJSON(json_data);
493 if (!new_prefs)
494 return;
495 provider_->UpdatePrefs(std::move(new_prefs));
496 }
497
OnExternalProviderUpdateComplete(const ExternalProviderInterface * provider,const std::vector<ExternalInstallInfoUpdateUrl> & update_url_extensions,const std::vector<ExternalInstallInfoFile> & file_extensions,const std::set<std::string> & removed_extensions)498 void OnExternalProviderUpdateComplete(
499 const ExternalProviderInterface* provider,
500 const std::vector<ExternalInstallInfoUpdateUrl>& update_url_extensions,
501 const std::vector<ExternalInstallInfoFile>& file_extensions,
502 const std::set<std::string>& removed_extensions) override {
503 for (const auto& extension_info : update_url_extensions)
504 update_url_extension_ids_.insert(extension_info.extension_id);
505 EXPECT_EQ(update_url_extension_ids_.size(), update_url_extensions.size());
506
507 for (const auto& extension_info : file_extensions)
508 file_extension_ids_.insert(extension_info.extension_id);
509 EXPECT_EQ(file_extension_ids_.size(), file_extensions.size());
510
511 for (const auto& extension_id : removed_extensions)
512 removed_extension_ids_.insert(extension_id);
513 }
514
GetUpdateURLExtensionCount()515 size_t GetUpdateURLExtensionCount() {
516 return update_url_extension_ids_.size();
517 }
GetFileExtensionCount()518 size_t GetFileExtensionCount() { return file_extension_ids_.size(); }
GetRemovedExtensionCount()519 size_t GetRemovedExtensionCount() { return removed_extension_ids_.size(); }
520
HasSeenUpdateWithUpdateUrl(const std::string & extension_id)521 bool HasSeenUpdateWithUpdateUrl(const std::string& extension_id) {
522 return update_url_extension_ids_.count(extension_id) > 0u;
523 }
HasSeenUpdateWithFile(const std::string & extension_id)524 bool HasSeenUpdateWithFile(const std::string& extension_id) {
525 return file_extension_ids_.count(extension_id) > 0u;
526 }
HasSeenRemoval(const std::string & extension_id)527 bool HasSeenRemoval(const std::string& extension_id) {
528 return removed_extension_ids_.count(extension_id) > 0u;
529 }
530
531 private:
532 std::set<std::string> update_url_extension_ids_;
533 std::set<std::string> file_extension_ids_;
534 std::set<std::string> removed_extension_ids_;
535
536 DISALLOW_COPY_AND_ASSIGN(MockUpdateProviderVisitor);
537 };
538
539 struct MockExtensionRegistryObserver : public ExtensionRegistryObserver {
540 MockExtensionRegistryObserver() = default;
541 ~MockExtensionRegistryObserver() override = default;
542
543 // ExtensionRegistryObserver:
OnExtensionLoadedextensions::MockExtensionRegistryObserver544 void OnExtensionLoaded(content::BrowserContext* browser_context,
545 const Extension* extension) override {
546 last_extension_loaded = extension->id();
547 }
OnExtensionUnloadedextensions::MockExtensionRegistryObserver548 void OnExtensionUnloaded(content::BrowserContext* browser_context,
549 const Extension* extension,
550 UnloadedExtensionReason reason) override {
551 last_extension_unloaded = extension->id();
552 }
OnExtensionWillBeInstalledextensions::MockExtensionRegistryObserver553 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
554 const Extension* extension,
555 bool is_update,
556 const std::string& old_name) override {
557 last_extension_installed = extension->id();
558 }
OnExtensionUninstalledextensions::MockExtensionRegistryObserver559 void OnExtensionUninstalled(content::BrowserContext* browser_context,
560 const Extension* extension,
561 UninstallReason reason) override {
562 last_extension_uninstalled = extension->id();
563 }
564
565 std::string last_extension_loaded;
566 std::string last_extension_unloaded;
567 std::string last_extension_installed;
568 std::string last_extension_uninstalled;
569
570 private:
571 DISALLOW_COPY_AND_ASSIGN(MockExtensionRegistryObserver);
572 };
573
574 class ExtensionServiceTest : public ExtensionServiceTestWithInstall {
575 public:
576 ExtensionServiceTest() = default;
577
AddMockExternalProvider(Manifest::Location location)578 MockExternalProvider* AddMockExternalProvider(Manifest::Location location) {
579 auto provider = std::make_unique<MockExternalProvider>(service(), location);
580 MockExternalProvider* provider_ptr = provider.get();
581 service()->AddProviderForTesting(std::move(provider));
582 return provider_ptr;
583 }
584
585 // Checks for external extensions and waits for one to complete installing.
WaitForExternalExtensionInstalled()586 void WaitForExternalExtensionInstalled() {
587 content::WindowedNotificationObserver observer(
588 NOTIFICATION_CRX_INSTALLER_DONE,
589 content::NotificationService::AllSources());
590 service()->CheckForExternalUpdates();
591 observer.Wait();
592 }
593
594 protected:
595 void TestExternalProvider(MockExternalProvider* provider,
596 Manifest::Location location);
597
598 // Grants all optional permissions stated in manifest to active permission
599 // set for extension |id|.
GrantAllOptionalPermissions(const std::string & id)600 void GrantAllOptionalPermissions(const std::string& id) {
601 const Extension* extension = registry()->GetInstalledExtension(id);
602 const PermissionSet& all_optional_permissions =
603 PermissionsParser::GetOptionalPermissions(extension);
604 permissions_test_util::GrantOptionalPermissionsAndWaitForCompletion(
605 profile(), *extension, all_optional_permissions);
606 }
607
IsBlocked(const std::string & id)608 testing::AssertionResult IsBlocked(const std::string& id) {
609 std::unique_ptr<ExtensionSet> all_unblocked_extensions =
610 registry()->GenerateInstalledExtensionsSet(
611 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::BLOCKED);
612 if (all_unblocked_extensions->Contains(id))
613 return testing::AssertionFailure() << id << " is still unblocked!";
614 if (!registry()->blocked_extensions().Contains(id))
615 return testing::AssertionFailure() << id << " is not blocked!";
616 return testing::AssertionSuccess();
617 }
618
619 // Helper method to test that an extension moves through being blocked and
620 // unblocked as appropriate for its type.
AssertExtensionBlocksAndUnblocks(bool should_block,const std::string extension_id)621 void AssertExtensionBlocksAndUnblocks(
622 bool should_block, const std::string extension_id) {
623 // Assume we start in an unblocked state.
624 EXPECT_FALSE(IsBlocked(extension_id));
625
626 // Block the extensions.
627 service()->BlockAllExtensions();
628 content::RunAllTasksUntilIdle();
629
630 if (should_block)
631 ASSERT_TRUE(IsBlocked(extension_id));
632 else
633 ASSERT_FALSE(IsBlocked(extension_id));
634
635 service()->UnblockAllExtensions();
636 content::RunAllTasksUntilIdle();
637
638 ASSERT_FALSE(IsBlocked(extension_id));
639 }
640
IsPrefExist(const std::string & extension_id,const std::string & pref_path)641 bool IsPrefExist(const std::string& extension_id,
642 const std::string& pref_path) {
643 const base::DictionaryValue* dict =
644 profile()->GetPrefs()->GetDictionary(pref_names::kExtensions);
645 if (!dict)
646 return false;
647 const base::DictionaryValue* pref = nullptr;
648 if (!dict->GetDictionary(extension_id, &pref)) {
649 return false;
650 }
651 if (!pref) {
652 return false;
653 }
654 bool val;
655 if (!pref->GetBoolean(pref_path, &val)) {
656 return false;
657 }
658 return true;
659 }
660
SetPref(const std::string & extension_id,const std::string & pref_path,std::unique_ptr<base::Value> value,const std::string & msg)661 void SetPref(const std::string& extension_id,
662 const std::string& pref_path,
663 std::unique_ptr<base::Value> value,
664 const std::string& msg) {
665 DictionaryPrefUpdate update(profile()->GetPrefs(), pref_names::kExtensions);
666 base::DictionaryValue* dict = update.Get();
667 ASSERT_TRUE(dict) << msg;
668 base::DictionaryValue* pref = nullptr;
669 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
670 EXPECT_TRUE(pref) << msg;
671 pref->Set(pref_path, std::move(value));
672 }
673
SetPrefInteg(const std::string & extension_id,const std::string & pref_path,int value)674 void SetPrefInteg(const std::string& extension_id,
675 const std::string& pref_path,
676 int value) {
677 std::string msg = " while setting: ";
678 msg += extension_id;
679 msg += " ";
680 msg += pref_path;
681 msg += " = ";
682 msg += base::NumberToString(value);
683
684 SetPref(extension_id, pref_path, std::make_unique<base::Value>(value), msg);
685 }
686
SetPrefBool(const std::string & extension_id,const std::string & pref_path,bool value)687 void SetPrefBool(const std::string& extension_id,
688 const std::string& pref_path,
689 bool value) {
690 std::string msg = " while setting: ";
691 msg += extension_id + " " + pref_path;
692 msg += " = ";
693 msg += (value ? "true" : "false");
694
695 SetPref(extension_id, pref_path, std::make_unique<base::Value>(value), msg);
696 }
697
ClearPref(const std::string & extension_id,const std::string & pref_path)698 void ClearPref(const std::string& extension_id,
699 const std::string& pref_path) {
700 std::string msg = " while clearing: ";
701 msg += extension_id + " " + pref_path;
702
703 DictionaryPrefUpdate update(profile()->GetPrefs(), pref_names::kExtensions);
704 base::DictionaryValue* dict = update.Get();
705 ASSERT_TRUE(dict) << msg;
706 base::DictionaryValue* pref = nullptr;
707 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
708 EXPECT_TRUE(pref) << msg;
709 pref->Remove(pref_path, nullptr);
710 }
711
SetPrefStringSet(const std::string & extension_id,const std::string & pref_path,const std::set<std::string> & value)712 void SetPrefStringSet(const std::string& extension_id,
713 const std::string& pref_path,
714 const std::set<std::string>& value) {
715 std::string msg = " while setting: ";
716 msg += extension_id + " " + pref_path;
717
718 auto list_value = std::make_unique<base::ListValue>();
719 for (auto iter = value.begin(); iter != value.end(); ++iter)
720 list_value->AppendString(*iter);
721
722 SetPref(extension_id, pref_path, std::move(list_value), msg);
723 }
724
InitPluginService()725 void InitPluginService() {
726 #if BUILDFLAG(ENABLE_PLUGINS)
727 PluginService::GetInstance()->Init();
728 #endif
729 }
730
InitializeEmptyExtensionServiceWithTestingPrefs()731 void InitializeEmptyExtensionServiceWithTestingPrefs() {
732 ExtensionServiceTestBase::ExtensionServiceInitParams params =
733 CreateDefaultInitParams();
734 params.pref_file = base::FilePath();
735 InitializeExtensionService(params);
736 }
737
GetManagementPolicy()738 ManagementPolicy* GetManagementPolicy() {
739 return ExtensionSystem::Get(browser_context())->management_policy();
740 }
741
GetError(const std::string & extension_id)742 ExternalInstallError* GetError(const std::string& extension_id) {
743 std::vector<ExternalInstallError*> errors =
744 service_->external_install_manager()->GetErrorsForTesting();
745 auto found = std::find_if(
746 errors.begin(), errors.end(),
747 [&extension_id](const ExternalInstallError* error) {
748 return error->extension_id() == extension_id;
749 });
750 return found == errors.end() ? nullptr : *found;
751 }
752
753 typedef ExtensionManagementPrefUpdater<
754 sync_preferences::TestingPrefServiceSyncable>
755 ManagementPrefUpdater;
756 };
757
758 // Receives notifications from a PackExtensionJob, indicating either that
759 // packing succeeded or that there was some error.
760 class PackExtensionTestClient : public PackExtensionJob::Client {
761 public:
762 PackExtensionTestClient(const base::FilePath& expected_crx_path,
763 const base::FilePath& expected_private_key_path);
764 void OnPackSuccess(const base::FilePath& crx_path,
765 const base::FilePath& private_key_path) override;
766 void OnPackFailure(const std::string& error_message,
767 ExtensionCreator::ErrorType type) override;
768
769 private:
770 const base::FilePath expected_crx_path_;
771 const base::FilePath expected_private_key_path_;
772 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
773 };
774
PackExtensionTestClient(const base::FilePath & expected_crx_path,const base::FilePath & expected_private_key_path)775 PackExtensionTestClient::PackExtensionTestClient(
776 const base::FilePath& expected_crx_path,
777 const base::FilePath& expected_private_key_path)
778 : expected_crx_path_(expected_crx_path),
779 expected_private_key_path_(expected_private_key_path) {}
780
781 // If packing succeeded, we make sure that the package names match our
782 // expectations.
OnPackSuccess(const base::FilePath & crx_path,const base::FilePath & private_key_path)783 void PackExtensionTestClient::OnPackSuccess(
784 const base::FilePath& crx_path,
785 const base::FilePath& private_key_path) {
786 // We got the notification and processed it; we don't expect any further tasks
787 // to be posted to the current thread, so we should stop blocking and continue
788 // on with the rest of the test.
789 // This call to |Quit()| matches the call to |Run()| in the
790 // |PackPunctuatedExtension| test.
791 base::RunLoop::QuitCurrentWhenIdleDeprecated();
792 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
793 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
794 ASSERT_TRUE(base::PathExists(private_key_path));
795 }
796
797 // The tests are designed so that we never expect to see a packing error.
OnPackFailure(const std::string & error_message,ExtensionCreator::ErrorType type)798 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
799 ExtensionCreator::ErrorType type) {
800 if (type == ExtensionCreator::kCRXExists)
801 FAIL() << "Packing should not fail.";
802 else
803 FAIL() << "Existing CRX should have been overwritten.";
804 }
805
806 // Test loading good extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAllExtensionsFromDirectorySuccess)807 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
808 InitPluginService();
809 InitializeGoodInstalledExtensionService();
810 service()->Init();
811
812 uint32_t expected_num_extensions = 3u;
813 ASSERT_EQ(expected_num_extensions, loaded_.size());
814
815 EXPECT_EQ(std::string(good0), loaded_[0]->id());
816 EXPECT_EQ(std::string("My extension 1"),
817 loaded_[0]->name());
818 EXPECT_EQ(std::string("The first extension that I made."),
819 loaded_[0]->description());
820 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
821 EXPECT_TRUE(registry()->enabled_extensions().GetByID(loaded_[0]->id()));
822 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
823
824 ValidatePrefKeyCount(3);
825 ValidateIntegerPref(good0, "state", Extension::ENABLED);
826 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
827 ValidateIntegerPref(good1, "state", Extension::ENABLED);
828 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
829 ValidateIntegerPref(good2, "state", Extension::ENABLED);
830 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
831
832 URLPatternSet expected_patterns;
833 AddPattern(&expected_patterns, "file:///*");
834 AddPattern(&expected_patterns, "http://*.google.com/*");
835 AddPattern(&expected_patterns, "https://*.google.com/*");
836 const Extension* extension = loaded_[0].get();
837 const UserScriptList& scripts =
838 ContentScriptsInfo::GetContentScripts(extension);
839 ASSERT_EQ(2u, scripts.size());
840 EXPECT_EQ(expected_patterns, scripts[0]->url_patterns());
841 EXPECT_EQ(2u, scripts[0]->js_scripts().size());
842 ExtensionResource resource00(extension->id(),
843 scripts[0]->js_scripts()[0]->extension_root(),
844 scripts[0]->js_scripts()[0]->relative_path());
845 base::FilePath expected_path =
846 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
847 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
848 ExtensionResource resource01(extension->id(),
849 scripts[0]->js_scripts()[1]->extension_root(),
850 scripts[0]->js_scripts()[1]->relative_path());
851 expected_path =
852 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
853 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
854 EXPECT_EQ(1u, scripts[1]->url_patterns().patterns().size());
855 EXPECT_EQ("http://*.news.com/*",
856 scripts[1]->url_patterns().begin()->GetAsString());
857 ExtensionResource resource10(extension->id(),
858 scripts[1]->js_scripts()[0]->extension_root(),
859 scripts[1]->js_scripts()[0]->relative_path());
860 expected_path =
861 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
862 expected_path = base::MakeAbsoluteFilePath(expected_path);
863 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
864
865 expected_patterns.ClearPatterns();
866 AddPattern(&expected_patterns, "http://*.google.com/*");
867 AddPattern(&expected_patterns, "https://*.google.com/*");
868 EXPECT_EQ(
869 expected_patterns,
870 extension->permissions_data()->active_permissions().explicit_hosts());
871
872 EXPECT_EQ(std::string(good1), loaded_[1]->id());
873 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
874 EXPECT_EQ(std::string(), loaded_[1]->description());
875 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
876 BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
877 EXPECT_TRUE(ContentScriptsInfo::GetContentScripts(loaded_[1].get()).empty());
878 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
879
880 int index = expected_num_extensions - 1;
881 EXPECT_EQ(std::string(good2), loaded_[index]->id());
882 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
883 EXPECT_EQ(std::string(), loaded_[index]->description());
884 EXPECT_TRUE(
885 ContentScriptsInfo::GetContentScripts(loaded_[index].get()).empty());
886 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
887 }
888
889 // Test loading bad extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAllExtensionsFromDirectoryFail)890 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
891 // Initialize the test dir with a bad Preferences/extensions.
892 base::FilePath source_install_dir =
893 data_dir().AppendASCII("bad").AppendASCII("Extensions");
894 base::FilePath pref_path =
895 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
896
897 InitializeInstalledExtensionService(pref_path, source_install_dir);
898
899 service()->Init();
900
901 ASSERT_EQ(4u, GetErrors().size());
902 ASSERT_EQ(0u, loaded_.size());
903
904 EXPECT_TRUE(base::MatchPattern(
905 base::UTF16ToUTF8(GetErrors()[0]),
906 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
907 manifest_errors::kManifestUnreadable))
908 << base::UTF16ToUTF8(GetErrors()[0]);
909
910 EXPECT_TRUE(base::MatchPattern(
911 base::UTF16ToUTF8(GetErrors()[1]),
912 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
913 manifest_errors::kManifestUnreadable))
914 << base::UTF16ToUTF8(GetErrors()[1]);
915
916 EXPECT_TRUE(base::MatchPattern(
917 base::UTF16ToUTF8(GetErrors()[2]),
918 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
919 manifest_errors::kMissingFile))
920 << base::UTF16ToUTF8(GetErrors()[2]);
921
922 EXPECT_TRUE(base::MatchPattern(
923 base::UTF16ToUTF8(GetErrors()[3]),
924 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
925 manifest_errors::kManifestUnreadable))
926 << base::UTF16ToUTF8(GetErrors()[3]);
927 }
928
929 // Test various cases for delayed install because of missing imports.
TEST_F(ExtensionServiceTest,PendingImports)930 TEST_F(ExtensionServiceTest, PendingImports) {
931 InitPluginService();
932
933 base::FilePath source_install_dir =
934 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII(
935 "Extensions");
936 base::FilePath pref_path =
937 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
938
939 InitializeInstalledExtensionService(pref_path, source_install_dir);
940
941 // Verify there are no pending extensions initially.
942 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
943
944 service()->Init();
945 // Wait for GarbageCollectExtensions task to complete.
946 content::RunAllTasksUntilIdle();
947
948 // These extensions are used by the extensions we test below, they must be
949 // installed.
950 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
951 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
952 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
953 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
954
955 // Each of these extensions should have been rejected because of dependencies
956 // that cannot be satisfied.
957 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
958 EXPECT_FALSE(
959 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
960 EXPECT_FALSE(
961 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
962 EXPECT_FALSE(
963 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
964 EXPECT_FALSE(
965 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
966 EXPECT_FALSE(
967 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
968 EXPECT_FALSE(
969 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
970
971 // Make sure the import started for the extension with a dependency.
972 EXPECT_TRUE(
973 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
974 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
975 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
976
977 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII(
978 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
979
980 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions());
981 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
982 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
983 // Remove it because we are not testing the pending extension manager's
984 // ability to download and install extensions.
985 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
986 }
987
988 // Tests that reloading extension with a install delayed due to pending imports
989 // reloads currently installed extension version, rather than installing the
990 // delayed install.
TEST_F(ExtensionServiceTest,ReloadExtensionWithPendingImports)991 TEST_F(ExtensionServiceTest, ReloadExtensionWithPendingImports) {
992 InitializeEmptyExtensionService();
993
994 // Wait for GarbageCollectExtensions task to complete.
995 content::RunAllTasksUntilIdle();
996
997 const base::FilePath base_path =
998 data_dir()
999 .AppendASCII("pending_updates_with_imports")
1000 .AppendASCII("updated_with_imports");
1001
1002 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1003
1004 // Initially installed version - the version with no imports.
1005 const base::FilePath installed_path = base_path.AppendASCII("1.0.0");
1006
1007 // The updated version - has import that is not satisfied (due to the imported
1008 // extension not being installed).
1009 const base::FilePath updated_path = base_path.AppendASCII("2.0.0");
1010
1011 ASSERT_TRUE(base::PathExists(pem_path));
1012 ASSERT_TRUE(base::PathExists(installed_path));
1013 ASSERT_TRUE(base::PathExists(updated_path));
1014
1015 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1016
1017 // Install version 1.
1018 const Extension* extension =
1019 PackAndInstallCRX(installed_path, pem_path, INSTALL_NEW,
1020 Extension::FROM_WEBSTORE, Manifest::Location::INTERNAL);
1021 content::RunAllTasksUntilIdle();
1022 ASSERT_TRUE(extension);
1023 const std::string id = extension->id();
1024
1025 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1026 EXPECT_EQ("1.0.0", extension->VersionString());
1027
1028 // No pending extensions at this point.
1029 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
1030
1031 // Update to version 2 that adds an unsatisfied import.
1032 PackCRXAndUpdateExtension(id, updated_path, pem_path, ENABLED);
1033 content::RunAllTasksUntilIdle();
1034
1035 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1036 extension = registry()->GetInstalledExtension(id);
1037 ASSERT_TRUE(extension);
1038
1039 // The extension update should be delayed at this point - the old version
1040 // should still be installed.
1041 EXPECT_EQ("1.0.0", extension->VersionString());
1042
1043 // Make sure the import started for the extension with a dependency.
1044 EXPECT_TRUE(prefs->GetDelayedInstallInfo(id));
1045 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1046 prefs->GetDelayedInstallReason(id));
1047
1048 const std::string pending_id(32, 'e');
1049 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1050
1051 MockExtensionRegistryObserver reload_observer;
1052 registry()->AddObserver(&reload_observer);
1053
1054 // Reload the extension, and verify that the installed version does not
1055 // change.
1056 service()->ReloadExtension(id);
1057 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1058 EXPECT_EQ(id, reload_observer.last_extension_loaded);
1059 EXPECT_EQ(id, reload_observer.last_extension_unloaded);
1060 registry()->RemoveObserver(&reload_observer);
1061
1062 extension = registry()->GetInstalledExtension(id);
1063 ASSERT_TRUE(extension);
1064 EXPECT_EQ("1.0.0", extension->VersionString());
1065
1066 // The update should remain delayed, with the import pending.
1067 EXPECT_TRUE(prefs->GetDelayedInstallInfo(id));
1068 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1069 prefs->GetDelayedInstallReason(id));
1070
1071 // Attempt delayed installed - similar to reloading the extension, the update
1072 // should remain delayed.
1073 EXPECT_FALSE(service()->FinishDelayedInstallationIfReady(id, true));
1074
1075 extension = registry()->GetInstalledExtension(id);
1076 ASSERT_TRUE(extension);
1077 EXPECT_EQ("1.0.0", extension->VersionString());
1078 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1079 prefs->GetDelayedInstallReason(id));
1080 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1081
1082 // Remove the pending install because the pending extension manager's
1083 // ability to download and install extensions is not important for this test.
1084 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
1085 }
1086
1087 // Tests that installation fails with extensions disabled.
TEST_F(ExtensionServiceTest,InstallExtensionsWithExtensionsDisabled)1088 TEST_F(ExtensionServiceTest, InstallExtensionsWithExtensionsDisabled) {
1089 InitializeExtensionServiceWithExtensionsDisabled();
1090 base::FilePath path = data_dir().AppendASCII("good.crx");
1091 InstallCRX(path, INSTALL_FAILED);
1092 }
1093
1094 // Test installing extensions. This test tries to install few extensions using
1095 // crx files. If you need to change those crx files, feel free to repackage
1096 // them, throw away the key used and change the id's above.
TEST_F(ExtensionServiceTest,InstallExtension)1097 TEST_F(ExtensionServiceTest, InstallExtension) {
1098 InitializeEmptyExtensionService();
1099 ValidatePrefKeyCount(0);
1100
1101 // A simple extension that should install without error.
1102 base::FilePath path = data_dir().AppendASCII("good.crx");
1103 InstallCRX(path, INSTALL_NEW);
1104 // TODO(erikkay): verify the contents of the installed extension.
1105
1106 int pref_count = 0;
1107 ValidatePrefKeyCount(++pref_count);
1108 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1109 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1110
1111 // An extension with page actions.
1112 path = data_dir().AppendASCII("page_action.crx");
1113 InstallCRX(path, INSTALL_NEW);
1114 ValidatePrefKeyCount(++pref_count);
1115 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1116 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1117
1118 // Bad signature.
1119 path = data_dir().AppendASCII("bad_signature.crx");
1120 InstallCRX(path, INSTALL_FAILED);
1121 ValidatePrefKeyCount(pref_count);
1122
1123 // 0-length extension file.
1124 path = data_dir().AppendASCII("not_an_extension.crx");
1125 InstallCRX(path, INSTALL_FAILED);
1126 ValidatePrefKeyCount(pref_count);
1127
1128 // Bad magic number.
1129 path = data_dir().AppendASCII("bad_magic.crx");
1130 InstallCRX(path, INSTALL_FAILED);
1131 ValidatePrefKeyCount(pref_count);
1132
1133 // Packed extensions may have folders or files that have underscores.
1134 // This will only cause a warning, rather than a fatal error.
1135 path = data_dir().AppendASCII("bad_underscore.crx");
1136 InstallCRX(path, INSTALL_NEW);
1137 ValidatePrefKeyCount(++pref_count);
1138
1139 // A test for an extension with a 2048-bit public key.
1140 path = data_dir().AppendASCII("good2048.crx");
1141 InstallCRX(path, INSTALL_NEW);
1142 ValidatePrefKeyCount(++pref_count);
1143 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1144 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1145
1146 // TODO(erikkay): add more tests for many of the failure cases.
1147 // TODO(erikkay): add tests for upgrade cases.
1148 }
1149
1150 // Test that correct notifications are sent to ExtensionRegistryObserver on
1151 // extension install and uninstall.
TEST_F(ExtensionServiceTest,InstallObserverNotified)1152 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1153 InitializeEmptyExtensionService();
1154
1155 ExtensionRegistry* registry(ExtensionRegistry::Get(profile()));
1156 MockExtensionRegistryObserver observer;
1157 registry->AddObserver(&observer);
1158
1159 // A simple extension that should install without error.
1160 ASSERT_TRUE(observer.last_extension_installed.empty());
1161 base::FilePath path = data_dir().AppendASCII("good.crx");
1162 InstallCRX(path, INSTALL_NEW);
1163 ASSERT_EQ(good_crx, observer.last_extension_installed);
1164
1165 // Uninstall the extension.
1166 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1167 UninstallExtension(good_crx);
1168 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1169
1170 registry->RemoveObserver(&observer);
1171 }
1172
1173 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1174 // extension object.
TEST_F(ExtensionServiceTest,InstallingExternalExtensionWithFlags)1175 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1176 const char kPrefFromBookmark[] = "from_bookmark";
1177
1178 InitializeEmptyExtensionService();
1179
1180 base::FilePath path = data_dir().AppendASCII("good.crx");
1181
1182 // Register and install an external extension.
1183 std::string version_str = "1.0.0.0";
1184 std::unique_ptr<ExternalInstallInfoFile> info = CreateExternalExtension(
1185 good_crx, version_str, path, Manifest::EXTERNAL_PREF,
1186 Extension::FROM_BOOKMARK);
1187 MockExternalProvider* provider =
1188 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
1189 provider->UpdateOrAddExtension(std::move(info));
1190 WaitForExternalExtensionInstalled();
1191
1192 const Extension* extension =
1193 registry()->enabled_extensions().GetByID(good_crx);
1194 ASSERT_TRUE(extension);
1195 ASSERT_TRUE(extension->from_bookmark());
1196 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1197
1198 // Upgrade to version 2.0, the flag should be preserved.
1199 path = data_dir().AppendASCII("good2.crx");
1200 UpdateExtension(good_crx, path, ENABLED);
1201 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1202 extension = registry()->enabled_extensions().GetByID(good_crx);
1203 ASSERT_TRUE(extension);
1204 ASSERT_TRUE(extension->from_bookmark());
1205 }
1206
1207 // Test the handling of uninstalling external extensions.
TEST_F(ExtensionServiceTest,UninstallingExternalExtensions)1208 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1209 InitializeEmptyExtensionService();
1210
1211 base::FilePath path = data_dir().AppendASCII("good.crx");
1212
1213 std::string version_str = "1.0.0.0";
1214 // Install an external extension.
1215 std::unique_ptr<ExternalInstallInfoFile> info =
1216 CreateExternalExtension(good_crx, version_str, path,
1217 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1218 MockExternalProvider* provider =
1219 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
1220 provider->UpdateOrAddExtension(std::move(info));
1221 WaitForExternalExtensionInstalled();
1222
1223 ASSERT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
1224
1225 // Uninstall it and check that its killbit gets set.
1226 UninstallExtension(good_crx);
1227 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1228 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
1229
1230 // Try to re-install it externally. This should fail because of the killbit.
1231 info = CreateExternalExtension(good_crx, version_str, path,
1232 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1233 provider->UpdateOrAddExtension(std::move(info));
1234 content::RunAllTasksUntilIdle();
1235 ASSERT_FALSE(registry()->enabled_extensions().GetByID(good_crx));
1236 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
1237
1238 std::string newer_version = "1.0.0.1";
1239 // Repeat the same thing with a newer version of the extension.
1240 path = data_dir().AppendASCII("good2.crx");
1241 info = CreateExternalExtension(good_crx, newer_version, path,
1242 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1243 provider->UpdateOrAddExtension(std::move(info));
1244 content::RunAllTasksUntilIdle();
1245 ASSERT_FALSE(registry()->enabled_extensions().GetByID(good_crx));
1246 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
1247
1248 // Try adding the same extension from an external update URL.
1249 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1250 good_crx,
1251 std::string(),
1252 GURL("http:://fake.update/url"),
1253 Manifest::EXTERNAL_PREF_DOWNLOAD,
1254 Extension::NO_FLAGS,
1255 false));
1256
1257 // Installation of the same extension through the policy should be successful.
1258 ASSERT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1259 good_crx,
1260 std::string(),
1261 GURL("http:://fake.update/url"),
1262 Manifest::EXTERNAL_POLICY_DOWNLOAD,
1263 Extension::NO_FLAGS,
1264 false));
1265 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
1266 EXPECT_TRUE(service()->pending_extension_manager()->Remove(good_crx));
1267
1268 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
1269 }
1270
1271 // Tests that uninstalling an external extension, and then reinstalling the
1272 // extension as a user install (e.g. from the webstore) succeeds.
TEST_F(ExtensionServiceTest,UninstallExternalExtensionAndReinstallAsUser)1273 TEST_F(ExtensionServiceTest, UninstallExternalExtensionAndReinstallAsUser) {
1274 InitializeEmptyExtensionService();
1275
1276 base::FilePath path = data_dir().AppendASCII("good.crx");
1277
1278 std::string version_str = "1.0.0.0";
1279 // Install an external extension.
1280 std::unique_ptr<ExternalInstallInfoFile> info =
1281 CreateExternalExtension(good_crx, version_str, path,
1282 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1283 MockExternalProvider* provider =
1284 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
1285 provider->UpdateOrAddExtension(std::move(info));
1286 WaitForExternalExtensionInstalled();
1287
1288 ASSERT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
1289
1290 // Uninstall the extension.
1291 UninstallExtension(good_crx);
1292 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1293 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
1294
1295 // Reinstall the extension as a user-space extension. This should succeed.
1296 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1297 installer->set_allow_silent_install(true);
1298 base::RunLoop run_loop;
1299 installer->set_installer_callback(base::BindOnce(
1300 [](base::Closure quit_closure,
1301 const base::Optional<CrxInstallError>& result) {
1302 ASSERT_FALSE(result) << result->message();
1303 quit_closure.Run();
1304 },
1305 run_loop.QuitWhenIdleClosure()));
1306 installer->InstallCrx(path);
1307 run_loop.Run();
1308
1309 ASSERT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
1310 }
1311
1312 // Tests uninstalling an external extension from a higher version, and then
1313 // installing a lower version as a user. This should succeed.
1314 // Regression test for https://crbug.com/795026.
TEST_F(ExtensionServiceTest,UninstallExternalExtensionAndReinstallAsUserWithLowerVersion)1315 TEST_F(ExtensionServiceTest,
1316 UninstallExternalExtensionAndReinstallAsUserWithLowerVersion) {
1317 InitializeEmptyExtensionService();
1318
1319 base::FilePath path = data_dir().AppendASCII("good2.crx");
1320
1321 constexpr char kExternalVersion[] = "1.0.0.1";
1322 // Install an external extension.
1323 std::unique_ptr<ExternalInstallInfoFile> info =
1324 CreateExternalExtension(good_crx, kExternalVersion, path,
1325 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1326 MockExternalProvider* provider =
1327 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
1328 provider->UpdateOrAddExtension(std::move(info));
1329 WaitForExternalExtensionInstalled();
1330
1331 ASSERT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
1332
1333 // Uninstall the extension.
1334 UninstallExtension(good_crx);
1335 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1336 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
1337
1338 // Reinstall the extension as a user-space extension with a lower version.
1339 // This should succeed.
1340 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1341 installer->set_allow_silent_install(true);
1342 base::RunLoop run_loop;
1343 installer->set_installer_callback(base::BindOnce(
1344 [](base::Closure quit_closure,
1345 const base::Optional<CrxInstallError>& result) {
1346 ASSERT_FALSE(result) << result->message();
1347 quit_closure.Run();
1348 },
1349 run_loop.QuitWhenIdleClosure()));
1350 installer->InstallCrx(data_dir().AppendASCII("good.crx"));
1351 run_loop.Run();
1352
1353 const Extension* extension =
1354 registry()->enabled_extensions().GetByID(good_crx);
1355 ASSERT_TRUE(extension);
1356 constexpr char kLowerVersion[] = "1.0.0.0";
1357 EXPECT_EQ(kLowerVersion, extension->version().GetString());
1358 }
1359
1360 // Test that uninstalling an external extension does not crash when
1361 // the extension could not be loaded.
1362 // This extension shown in preferences file requires an experimental permission.
1363 // It could not be loaded without such permission.
TEST_F(ExtensionServiceTest,UninstallingNotLoadedExtension)1364 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1365 base::FilePath source_install_dir =
1366 data_dir().AppendASCII("good").AppendASCII("Extensions");
1367 // The preference contains an external extension
1368 // that requires 'experimental' permission.
1369 base::FilePath pref_path = source_install_dir
1370 .DirName()
1371 .AppendASCII("PreferencesExperimental");
1372
1373 // Aforementioned extension will not be loaded if
1374 // there is no '--enable-experimental-extension-apis' command line flag.
1375 InitializeInstalledExtensionService(pref_path, source_install_dir);
1376
1377 service()->Init();
1378
1379 // Check and try to uninstall it.
1380 // If we don't check whether the extension is loaded before we uninstall it
1381 // in CheckExternalUninstall, a crash will happen here because we will get or
1382 // dereference a NULL pointer (extension) inside UninstallExtension.
1383 MockExternalProvider provider(nullptr, Manifest::EXTERNAL_REGISTRY);
1384 service()->OnExternalProviderReady(&provider);
1385 }
1386
1387 // Test that external extensions with incorrect IDs are not installed.
TEST_F(ExtensionServiceTest,FailOnWrongId)1388 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1389 InitializeEmptyExtensionService();
1390 base::FilePath path = data_dir().AppendASCII("good.crx");
1391
1392 std::string version_str = "1.0.0.0";
1393
1394 const std::string wrong_id = all_zero;
1395 const std::string correct_id = good_crx;
1396 ASSERT_NE(correct_id, wrong_id);
1397
1398 MockExternalProvider* provider =
1399 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
1400
1401 // Install an external extension with an ID from the external
1402 // source that is not equal to the ID in the extension manifest.
1403 std::unique_ptr<ExternalInstallInfoFile> info =
1404 CreateExternalExtension(wrong_id, version_str, path,
1405 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1406 provider->UpdateOrAddExtension(std::move(info));
1407 WaitForExternalExtensionInstalled();
1408 ASSERT_FALSE(registry()->enabled_extensions().GetByID(good_crx));
1409
1410 // Try again with the right ID. Expect success.
1411 info = CreateExternalExtension(correct_id, version_str, path,
1412 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1413 provider->UpdateOrAddExtension(std::move(info));
1414 WaitForExternalExtensionInstalled();
1415 ASSERT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
1416 }
1417
1418 // Test that external extensions with incorrect versions are not installed.
TEST_F(ExtensionServiceTest,FailOnWrongVersion)1419 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1420 InitializeEmptyExtensionService();
1421 base::FilePath path = data_dir().AppendASCII("good.crx");
1422 MockExternalProvider* provider =
1423 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
1424
1425 // Install an external extension with a version from the external
1426 // source that is not equal to the version in the extension manifest.
1427 std::string wrong_version_str = "1.2.3.4";
1428 std::unique_ptr<ExternalInstallInfoFile> wrong_info =
1429 CreateExternalExtension(good_crx, wrong_version_str, path,
1430 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1431 provider->UpdateOrAddExtension(std::move(wrong_info));
1432 WaitForExternalExtensionInstalled();
1433 ASSERT_FALSE(registry()->enabled_extensions().GetByID(good_crx));
1434
1435 // Try again with the right version. Expect success.
1436 service()->pending_extension_manager()->Remove(good_crx);
1437 std::unique_ptr<ExternalInstallInfoFile> correct_info =
1438 CreateExternalExtension(good_crx, "1.0.0.0", path,
1439 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1440 provider->UpdateOrAddExtension(std::move(correct_info));
1441 WaitForExternalExtensionInstalled();
1442 ASSERT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
1443 }
1444
1445 // Install a user script (they get converted automatically to an extension)
TEST_F(ExtensionServiceTest,InstallUserScript)1446 TEST_F(ExtensionServiceTest, InstallUserScript) {
1447 // The details of script conversion are tested elsewhere, this just tests
1448 // integration with ExtensionService.
1449 InitializeEmptyExtensionService();
1450
1451 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js");
1452
1453 ASSERT_TRUE(base::PathExists(path));
1454 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1455 installer->set_allow_silent_install(true);
1456 installer->InstallUserScript(
1457 path,
1458 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1459
1460 content::RunAllTasksUntilIdle();
1461 std::vector<base::string16> errors = GetErrors();
1462 EXPECT_TRUE(installed_) << "Nothing was installed.";
1463 EXPECT_FALSE(was_update_) << path.value();
1464 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1465 EXPECT_EQ(0u, errors.size())
1466 << "There were errors: "
1467 << base::JoinString(errors, base::ASCIIToUTF16(","));
1468 EXPECT_TRUE(registry()->enabled_extensions().GetByID(loaded_[0]->id()))
1469 << path.value();
1470
1471 installed_ = nullptr;
1472 was_update_ = false;
1473 loaded_.clear();
1474 LoadErrorReporter::GetInstance()->ClearErrors();
1475 }
1476
1477 // Extensions don't install during shutdown.
TEST_F(ExtensionServiceTest,InstallExtensionDuringShutdown)1478 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1479 InitializeEmptyExtensionService();
1480
1481 // Simulate shutdown.
1482 service()->set_browser_terminating_for_test(true);
1483
1484 base::FilePath path = data_dir().AppendASCII("good.crx");
1485 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1486 installer->set_allow_silent_install(true);
1487 installer->InstallCrx(path);
1488 content::RunAllTasksUntilIdle();
1489
1490 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1491 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1492 }
1493
1494 // This tests that the granted permissions preferences are correctly set when
1495 // installing an extension.
TEST_F(ExtensionServiceTest,GrantedPermissions)1496 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1497 InitializeEmptyExtensionService();
1498 base::FilePath path = data_dir().AppendASCII("permissions");
1499
1500 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1501 path = path.AppendASCII("unknown");
1502
1503 ASSERT_TRUE(base::PathExists(pem_path));
1504 ASSERT_TRUE(base::PathExists(path));
1505
1506 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1507
1508 APIPermissionSet expected_api_perms;
1509 URLPatternSet expected_host_perms;
1510
1511 // Make sure there aren't any granted permissions before the
1512 // extension is installed.
1513 EXPECT_FALSE(prefs->GetGrantedPermissions(permissions_crx).get());
1514
1515 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
1516
1517 EXPECT_EQ(0u, GetErrors().size());
1518 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1519 EXPECT_EQ(permissions_crx, extension->id());
1520
1521 // Verify that the valid API permissions have been recognized.
1522 expected_api_perms.insert(APIPermission::kTab);
1523
1524 AddPattern(&expected_host_perms, "http://*.google.com/*");
1525 AddPattern(&expected_host_perms, "https://*.google.com/*");
1526 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1527 AddPattern(&expected_host_perms, "http://www.example.com/*");
1528
1529 std::unique_ptr<const PermissionSet> known_perms =
1530 prefs->GetGrantedPermissions(extension->id());
1531 ASSERT_TRUE(known_perms.get());
1532 EXPECT_FALSE(known_perms->IsEmpty());
1533 EXPECT_EQ(expected_api_perms, known_perms->apis());
1534 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
1535 }
1536
1537 // This tests that the granted permissions preferences are correctly set when
1538 // updating an extension, and the extension is disabled in case of a permission
1539 // escalation.
TEST_F(ExtensionServiceTest,GrantedPermissionsOnUpdate)1540 TEST_F(ExtensionServiceTest, GrantedPermissionsOnUpdate) {
1541 InitializeEmptyExtensionService();
1542 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1543
1544 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1545 const base::FilePath path1 = base_path.AppendASCII("update_1");
1546 const base::FilePath path2 = base_path.AppendASCII("update_2");
1547 const base::FilePath path3 = base_path.AppendASCII("update_3");
1548 const base::FilePath path4 = base_path.AppendASCII("update_4");
1549 const base::FilePath path5 = base_path.AppendASCII("update_5");
1550
1551 ASSERT_TRUE(base::PathExists(pem_path));
1552 ASSERT_TRUE(base::PathExists(path1));
1553 ASSERT_TRUE(base::PathExists(path2));
1554 ASSERT_TRUE(base::PathExists(path3));
1555 ASSERT_TRUE(base::PathExists(path4));
1556 ASSERT_TRUE(base::PathExists(path5));
1557
1558 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1559
1560 // Install version 1, which has the kHistory permission.
1561 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1562 const std::string id = extension->id();
1563
1564 EXPECT_EQ(0u, GetErrors().size());
1565 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1566
1567 // Verify that the history permission has been recognized.
1568 APIPermissionSet expected_api_perms;
1569 expected_api_perms.insert(APIPermission::kHistory);
1570 {
1571 std::unique_ptr<const PermissionSet> known_perms =
1572 prefs->GetGrantedPermissions(id);
1573 ASSERT_TRUE(known_perms.get());
1574 EXPECT_EQ(expected_api_perms, known_perms->apis());
1575 }
1576
1577 // Update to version 2 that adds the kTopSites permission, which has a
1578 // separate message, but is implied by kHistory. The extension should remain
1579 // enabled.
1580 PackCRXAndUpdateExtension(id, path2, pem_path, ENABLED);
1581 extension = registry()->GetInstalledExtension(id);
1582 ASSERT_TRUE(extension);
1583 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1584
1585 // The extra permission should have been granted automatically.
1586 expected_api_perms.insert(APIPermission::kTopSites);
1587 {
1588 std::unique_ptr<const PermissionSet> known_perms =
1589 prefs->GetGrantedPermissions(id);
1590 ASSERT_TRUE(known_perms.get());
1591 EXPECT_EQ(expected_api_perms, known_perms->apis());
1592 }
1593
1594 // Update to version 3 that adds the kStorage permission, which does not have
1595 // a message. The extension should remain enabled.
1596 PackCRXAndUpdateExtension(id, path3, pem_path, ENABLED);
1597 extension = registry()->GetInstalledExtension(id);
1598 ASSERT_TRUE(extension);
1599 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1600
1601 // The extra permission should have been granted automatically.
1602 expected_api_perms.insert(APIPermission::kStorage);
1603 {
1604 std::unique_ptr<const PermissionSet> known_perms =
1605 prefs->GetGrantedPermissions(id);
1606 ASSERT_TRUE(known_perms.get());
1607 EXPECT_EQ(expected_api_perms, known_perms->apis());
1608 }
1609
1610 // Update to version 4 that adds the kNotifications permission, which has a
1611 // message and hence is considered a permission increase. Now the extension
1612 // should get disabled.
1613 PackCRXAndUpdateExtension(id, path4, pem_path, DISABLED);
1614 extension = registry()->GetInstalledExtension(id);
1615 ASSERT_TRUE(extension);
1616 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1617
1618 // No new permissions should have been granted.
1619 {
1620 std::unique_ptr<const PermissionSet> known_perms =
1621 prefs->GetGrantedPermissions(id);
1622 ASSERT_TRUE(known_perms.get());
1623 EXPECT_EQ(expected_api_perms, known_perms->apis());
1624 }
1625 }
1626
TEST_F(ExtensionServiceTest,ReenableWithAllPermissionsGranted)1627 TEST_F(ExtensionServiceTest, ReenableWithAllPermissionsGranted) {
1628 InitializeEmptyExtensionService();
1629 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1630
1631 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1632 const base::FilePath path1 = base_path.AppendASCII("update_1");
1633 const base::FilePath path4 = base_path.AppendASCII("update_4");
1634 const base::FilePath path5 = base_path.AppendASCII("update_5");
1635
1636 ASSERT_TRUE(base::PathExists(pem_path));
1637 ASSERT_TRUE(base::PathExists(path1));
1638 ASSERT_TRUE(base::PathExists(path4));
1639 ASSERT_TRUE(base::PathExists(path5));
1640
1641 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1642
1643 // Install version 1, which has the kHistory permission.
1644 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1645 const std::string id = extension->id();
1646
1647 EXPECT_EQ(0u, GetErrors().size());
1648 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1649
1650 // Update to version 4 that adds the kNotifications permission, which has a
1651 // message and hence is considered a permission increase. The extension
1652 // should get disabled due to a permissions increase.
1653 PackCRXAndUpdateExtension(id, path4, pem_path, DISABLED);
1654 extension = registry()->GetInstalledExtension(id);
1655 ASSERT_TRUE(extension);
1656 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1657 EXPECT_TRUE(prefs->HasDisableReason(
1658 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
1659
1660 // Update to version 5 that removes the kNotifications permission again.
1661 // The extension should get re-enabled.
1662 PackCRXAndUpdateExtension(id, path5, pem_path, ENABLED);
1663 extension = registry()->GetInstalledExtension(id);
1664 ASSERT_TRUE(extension);
1665 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1666 }
1667
TEST_F(ExtensionServiceTest,ReenableWithAllPermissionsGrantedOnStartup)1668 TEST_F(ExtensionServiceTest, ReenableWithAllPermissionsGrantedOnStartup) {
1669 InitializeEmptyExtensionService();
1670 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1671
1672 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1673 const base::FilePath path1 = base_path.AppendASCII("update_1");
1674
1675 ASSERT_TRUE(base::PathExists(pem_path));
1676 ASSERT_TRUE(base::PathExists(path1));
1677
1678 // Install an extension which has the kHistory permission.
1679 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1680 const std::string id = extension->id();
1681
1682 EXPECT_EQ(0u, GetErrors().size());
1683 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1684
1685 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1686
1687 // Disable the extension due to a supposed permission increase, but retain its
1688 // granted permissions.
1689 service()->DisableExtension(id, disable_reason::DISABLE_PERMISSIONS_INCREASE);
1690 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1691 EXPECT_TRUE(prefs->HasDisableReason(
1692 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
1693
1694 // Simulate a Chrome restart. Since the extension has all required
1695 // permissions, it should get re-enabled.
1696 service()->ReloadExtensionsForTest();
1697 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1698 EXPECT_FALSE(prefs->HasDisableReason(
1699 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
1700 }
1701
TEST_F(ExtensionServiceTest,DontReenableWithAllPermissionsGrantedButOtherReason)1702 TEST_F(ExtensionServiceTest,
1703 DontReenableWithAllPermissionsGrantedButOtherReason) {
1704 InitializeEmptyExtensionService();
1705 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1706
1707 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1708 const base::FilePath path1 = base_path.AppendASCII("update_1");
1709 const base::FilePath path4 = base_path.AppendASCII("update_4");
1710 const base::FilePath path5 = base_path.AppendASCII("update_5");
1711
1712 ASSERT_TRUE(base::PathExists(pem_path));
1713 ASSERT_TRUE(base::PathExists(path1));
1714 ASSERT_TRUE(base::PathExists(path4));
1715 ASSERT_TRUE(base::PathExists(path5));
1716
1717 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1718
1719 // Install version 1, which has the kHistory permission.
1720 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1721 const std::string id = extension->id();
1722
1723 EXPECT_EQ(0u, GetErrors().size());
1724 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1725
1726 // Disable the extension.
1727 service()->DisableExtension(id, disable_reason::DISABLE_USER_ACTION);
1728 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1729 EXPECT_TRUE(prefs->HasDisableReason(id, disable_reason::DISABLE_USER_ACTION));
1730
1731 // Update to version 4 that adds the kNotifications permission, which has a
1732 // message and hence is considered a permission increase. The extension
1733 // should get disabled due to a permissions increase.
1734 PackCRXAndUpdateExtension(id, path4, pem_path, DISABLED);
1735 extension = registry()->GetInstalledExtension(id);
1736 ASSERT_TRUE(extension);
1737 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1738 EXPECT_TRUE(prefs->HasDisableReason(
1739 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
1740 // The USER_ACTION reason should also still be there.
1741 EXPECT_TRUE(prefs->HasDisableReason(id, disable_reason::DISABLE_USER_ACTION));
1742
1743 // Update to version 5 that removes the kNotifications permission again.
1744 // The PERMISSIONS_INCREASE should be removed, but the extension should stay
1745 // disabled since USER_ACTION is still there.
1746 PackCRXAndUpdateExtension(id, path5, pem_path, DISABLED);
1747 extension = registry()->GetInstalledExtension(id);
1748 ASSERT_TRUE(extension);
1749 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1750 EXPECT_EQ(disable_reason::DISABLE_USER_ACTION, prefs->GetDisableReasons(id));
1751 }
1752
TEST_F(ExtensionServiceTest,DontReenableWithAllPermissionsGrantedOnStartupButOtherReason)1753 TEST_F(ExtensionServiceTest,
1754 DontReenableWithAllPermissionsGrantedOnStartupButOtherReason) {
1755 InitializeEmptyExtensionService();
1756 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1757
1758 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1759 const base::FilePath path1 = base_path.AppendASCII("update_1");
1760
1761 ASSERT_TRUE(base::PathExists(pem_path));
1762 ASSERT_TRUE(base::PathExists(path1));
1763
1764 // Install an extension which has the kHistory permission.
1765 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1766 const std::string id = extension->id();
1767
1768 EXPECT_EQ(0u, GetErrors().size());
1769 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1770
1771 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1772
1773 // Disable the extension due to a supposed permission increase, but retain its
1774 // granted permissions.
1775 service()->DisableExtension(id, disable_reason::DISABLE_PERMISSIONS_INCREASE |
1776 disable_reason::DISABLE_USER_ACTION);
1777 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1778 EXPECT_TRUE(prefs->HasDisableReason(
1779 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
1780
1781 // Simulate a Chrome restart. Since the extension has all required
1782 // permissions, the DISABLE_PERMISSIONS_INCREASE should get removed, but it
1783 // should stay disabled due to the remaining DISABLE_USER_ACTION reason.
1784 service()->ReloadExtensionsForTest();
1785 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1786 EXPECT_EQ(disable_reason::DISABLE_USER_ACTION, prefs->GetDisableReasons(id));
1787 }
1788
1789 // Tests that installing an extension with a permission adds it to the granted
1790 // permissions, so that if it is later removed and then re-added the extension
1791 // is not disabled.
TEST_F(ExtensionServiceTest,ReaddingOldPermissionInUpdateDoesntDisableExtension)1792 TEST_F(ExtensionServiceTest,
1793 ReaddingOldPermissionInUpdateDoesntDisableExtension) {
1794 InitializeEmptyExtensionService();
1795
1796 // Borrow a PEM for consistent IDs.
1797 const base::FilePath pem_path =
1798 data_dir().AppendASCII("permissions/update.pem");
1799 ASSERT_TRUE(base::PathExists(pem_path));
1800
1801 constexpr char kManifestTemplate[] =
1802 R"({
1803 "name": "Test",
1804 "description": "Test permissions update flow",
1805 "manifest_version": 2,
1806 "version": "%s",
1807 "permissions": [%s]
1808 })";
1809
1810 // Install version 1, which includes the tabs permission.
1811 TestExtensionDir version1;
1812 version1.WriteManifest(
1813 base::StringPrintf(kManifestTemplate, "1", R"("tabs")"));
1814
1815 const Extension* extension =
1816 PackAndInstallCRX(version1.UnpackedPath(), pem_path, INSTALL_NEW);
1817 ASSERT_TRUE(extension);
1818
1819 const std::string id = extension->id();
1820
1821 EXPECT_EQ(0u, GetErrors().size());
1822 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1823
1824 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1825
1826 auto get_granted_permissions = [prefs, id]() {
1827 return prefs->GetGrantedPermissions(id);
1828 };
1829
1830 auto get_active_permissions = [prefs, id]() {
1831 return prefs->GetActivePermissions(id);
1832 };
1833
1834 APIPermissionSet tabs_permission_set;
1835 tabs_permission_set.insert(APIPermission::kTab);
1836
1837 EXPECT_EQ(tabs_permission_set, get_granted_permissions()->apis());
1838 EXPECT_EQ(tabs_permission_set, get_active_permissions()->apis());
1839
1840 // Version 2 removes the tabs permission. The tabs permission should be
1841 // gone from the active permissions, but retained in the granted permissions.
1842 TestExtensionDir version2;
1843 version2.WriteManifest(base::StringPrintf(kManifestTemplate, "2", ""));
1844
1845 PackCRXAndUpdateExtension(id, version2.UnpackedPath(), pem_path, ENABLED);
1846 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1847
1848 EXPECT_EQ(tabs_permission_set, get_granted_permissions()->apis());
1849 EXPECT_TRUE(get_active_permissions()->IsEmpty());
1850
1851 // Version 3 re-adds the tabs permission. Even though this is an increase in
1852 // privilege from version 2, it's not from the granted permissions (which
1853 // include the permission from version 1). Therefore, the extension should
1854 // remain enabled.
1855 TestExtensionDir version3;
1856 version3.WriteManifest(
1857 base::StringPrintf(kManifestTemplate, "3", R"("tabs")"));
1858
1859 PackCRXAndUpdateExtension(id, version3.UnpackedPath(), pem_path, ENABLED);
1860 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1861
1862 EXPECT_EQ(tabs_permission_set, get_granted_permissions()->apis());
1863 EXPECT_EQ(tabs_permission_set, get_active_permissions()->apis());
1864 }
1865
1866 // Tests that updating incognito to not_allowed revokes extension's permission
1867 // to run in incognito.
TEST_F(ExtensionServiceTest,UpdateIncognitoMode)1868 TEST_F(ExtensionServiceTest, UpdateIncognitoMode) {
1869 InitializeEmptyExtensionService();
1870
1871 // Borrow a PEM for consistent IDs.
1872 const base::FilePath path = data_dir().AppendASCII("permissions/update.pem");
1873 ASSERT_TRUE(base::PathExists(path));
1874
1875 constexpr char kManifestTemplate[] =
1876 R"({
1877 "name": "Test",
1878 "description": "Test incognito mode update flow",
1879 "manifest_version": 2,
1880 "version": "%s",
1881 "incognito": "%s"
1882 })";
1883
1884 // Install version 1, which has incognito set to split.
1885 TestExtensionDir version1;
1886 version1.WriteManifest(base::StringPrintf(kManifestTemplate, "1", "split"));
1887
1888 const Extension* extension =
1889 PackAndInstallCRX(version1.UnpackedPath(), path, INSTALL_NEW);
1890 ASSERT_TRUE(extension);
1891
1892 const std::string id = extension->id();
1893
1894 EXPECT_EQ(0u, GetErrors().size());
1895 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1896 util::SetIsIncognitoEnabled(id, profile(), true);
1897
1898 EXPECT_TRUE(util::IsIncognitoEnabled(id, profile()));
1899
1900 // Version 2 updates the incognito mode to not_allowed. This should revoke its
1901 // permissions, i.e., the extension should not be allowed to run in incognito.
1902 TestExtensionDir version2;
1903 version2.WriteManifest(
1904 base::StringPrintf(kManifestTemplate, "2", "not_allowed"));
1905
1906 PackCRXAndUpdateExtension(id, version2.UnpackedPath(), path, ENABLED);
1907 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1908 EXPECT_FALSE(util::IsIncognitoEnabled(id, profile()));
1909
1910 // Version 3 updates the incognito mode to split. The extension should not
1911 // have the permissions.
1912 TestExtensionDir version3;
1913 version3.WriteManifest(base::StringPrintf(kManifestTemplate, "3", "split"));
1914
1915 service()->EnableExtension(id);
1916 PackCRXAndUpdateExtension(id, version3.UnpackedPath(), path, ENABLED);
1917 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1918
1919 EXPECT_FALSE(util::IsIncognitoEnabled(id, profile()));
1920 }
1921
1922 #if !defined(OS_CHROMEOS)
1923 // This tests that the granted permissions preferences are correctly set for
1924 // default apps.
TEST_F(ExtensionServiceTest,DefaultAppsGrantedPermissions)1925 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
1926 InitializeEmptyExtensionService();
1927 base::FilePath path = data_dir().AppendASCII("permissions");
1928
1929 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1930 path = path.AppendASCII("unknown");
1931
1932 ASSERT_TRUE(base::PathExists(pem_path));
1933 ASSERT_TRUE(base::PathExists(path));
1934
1935 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1936
1937 APIPermissionSet expected_api_perms;
1938 URLPatternSet expected_host_perms;
1939
1940 // Make sure there aren't any granted permissions before the
1941 // extension is installed.
1942 EXPECT_FALSE(prefs->GetGrantedPermissions(permissions_crx).get());
1943
1944 const Extension* extension = PackAndInstallCRX(
1945 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT,
1946 Manifest::Location::INTERNAL);
1947
1948 EXPECT_EQ(0u, GetErrors().size());
1949 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1950 EXPECT_EQ(permissions_crx, extension->id());
1951
1952 // Verify that the valid API permissions have been recognized.
1953 expected_api_perms.insert(APIPermission::kTab);
1954
1955 std::unique_ptr<const PermissionSet> known_perms =
1956 prefs->GetGrantedPermissions(extension->id());
1957 EXPECT_TRUE(known_perms.get());
1958 EXPECT_FALSE(known_perms->IsEmpty());
1959 EXPECT_EQ(expected_api_perms, known_perms->apis());
1960 }
1961 #endif
1962
1963 // Tests that the extension is disabled when permissions are missing from
1964 // the extension's granted permissions preferences. (This simulates updating
1965 // the browser to a version which recognizes more permissions).
TEST_F(ExtensionServiceTest,GrantedAPIAndHostPermissions)1966 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1967 InitializeEmptyExtensionService();
1968
1969 base::FilePath path =
1970 data_dir().AppendASCII("permissions").AppendASCII("unknown");
1971
1972 ASSERT_TRUE(base::PathExists(path));
1973
1974 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
1975
1976 EXPECT_EQ(0u, GetErrors().size());
1977 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1978 std::string extension_id = extension->id();
1979
1980 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1981
1982 APIPermissionSet expected_api_permissions;
1983 URLPatternSet expected_host_permissions;
1984
1985 expected_api_permissions.insert(APIPermission::kTab);
1986 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1987 AddPattern(&expected_host_permissions, "https://*.google.com/*");
1988 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1989 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1990
1991 std::set<std::string> host_permissions;
1992
1993 // Test that the extension is disabled when an API permission is missing from
1994 // the extension's granted api permissions preference. (This simulates
1995 // updating the browser to a version which recognizes a new API permission).
1996 SetPref(extension_id, "granted_permissions.api",
1997 std::make_unique<base::ListValue>(), "granted_permissions.api");
1998 service()->ReloadExtensionsForTest();
1999
2000 EXPECT_EQ(1u, registry()->disabled_extensions().size());
2001 extension = registry()->disabled_extensions().begin()->get();
2002
2003 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2004 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
2005 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2006
2007 // Now grant and re-enable the extension, making sure the prefs are updated.
2008 service()->GrantPermissionsAndEnableExtension(extension);
2009
2010 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
2011 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2012 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2013
2014 std::unique_ptr<const PermissionSet> current_perms =
2015 prefs->GetGrantedPermissions(extension_id);
2016 ASSERT_TRUE(current_perms.get());
2017 ASSERT_FALSE(current_perms->IsEmpty());
2018 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2019 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2020
2021 // Tests that the extension is disabled when a host permission is missing from
2022 // the extension's granted host permissions preference. (This simulates
2023 // updating the browser to a version which recognizes additional host
2024 // permissions).
2025 host_permissions.clear();
2026 current_perms = nullptr;
2027
2028 host_permissions.insert("http://*.google.com/*");
2029 host_permissions.insert("https://*.google.com/*");
2030 host_permissions.insert("http://*.google.com.hk/*");
2031
2032 auto api_permissions = std::make_unique<base::ListValue>();
2033 api_permissions->AppendString("tabs");
2034 SetPref(extension_id, "granted_permissions.api", std::move(api_permissions),
2035 "granted_permissions.api");
2036 SetPrefStringSet(
2037 extension_id, "granted_permissions.scriptable_host", host_permissions);
2038
2039 service()->ReloadExtensionsForTest();
2040
2041 EXPECT_EQ(1u, registry()->disabled_extensions().size());
2042 extension = registry()->disabled_extensions().begin()->get();
2043
2044 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2045 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
2046 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2047
2048 // Now grant and re-enable the extension, making sure the prefs are updated.
2049 service()->GrantPermissionsAndEnableExtension(extension);
2050
2051 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2052 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2053
2054 current_perms = prefs->GetGrantedPermissions(extension_id);
2055 ASSERT_TRUE(current_perms.get());
2056 ASSERT_FALSE(current_perms->IsEmpty());
2057 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2058 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2059 }
2060
2061 // Test Packaging and installing an extension.
TEST_F(ExtensionServiceTest,PackExtension)2062 TEST_F(ExtensionServiceTest, PackExtension) {
2063 InitializeEmptyExtensionService();
2064 base::FilePath input_directory =
2065 data_dir()
2066 .AppendASCII("good")
2067 .AppendASCII("Extensions")
2068 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2069 .AppendASCII("1.0.0.0");
2070
2071 base::ScopedTempDir temp_dir;
2072 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2073 base::FilePath output_directory = temp_dir.GetPath();
2074
2075 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2076 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2077
2078 std::unique_ptr<ExtensionCreator> creator(new ExtensionCreator());
2079 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2080 privkey_path, ExtensionCreator::kNoRunFlags));
2081 ASSERT_TRUE(base::PathExists(crx_path));
2082 ASSERT_TRUE(base::PathExists(privkey_path));
2083
2084 // Repeat the run with the pem file gone, and no special flags
2085 // Should refuse to overwrite the existing crx.
2086 base::DeleteFile(privkey_path);
2087 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2088 privkey_path, ExtensionCreator::kNoRunFlags));
2089
2090 // OK, now try it with a flag to overwrite existing crx. Should work.
2091 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2092 privkey_path, ExtensionCreator::kOverwriteCRX));
2093
2094 // Repeat the run allowing existing crx, but the existing pem is still
2095 // an error. Should fail.
2096 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2097 privkey_path, ExtensionCreator::kOverwriteCRX));
2098
2099 ASSERT_TRUE(base::PathExists(privkey_path));
2100 InstallCRX(crx_path, INSTALL_NEW);
2101
2102 // Try packing with invalid paths.
2103 creator.reset(new ExtensionCreator());
2104 ASSERT_FALSE(
2105 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2106 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2107
2108 // Try packing an empty directory. Should fail because an empty directory is
2109 // not a valid extension.
2110 base::ScopedTempDir temp_dir2;
2111 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2112 creator.reset(new ExtensionCreator());
2113 ASSERT_FALSE(creator->Run(temp_dir2.GetPath(), crx_path, privkey_path,
2114 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2115
2116 // Try packing with an invalid manifest.
2117 std::string invalid_manifest_content = "I am not a manifest.";
2118 ASSERT_EQ(static_cast<int>(invalid_manifest_content.size()),
2119 base::WriteFile(temp_dir2.GetPath().Append(kManifestFilename),
2120 invalid_manifest_content.c_str(),
2121 invalid_manifest_content.size()));
2122 creator.reset(new ExtensionCreator());
2123 ASSERT_FALSE(creator->Run(temp_dir2.GetPath(), crx_path, privkey_path,
2124 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2125
2126 // Try packing with a private key that is a valid key, but invalid for the
2127 // extension.
2128 base::FilePath bad_private_key_dir =
2129 data_dir().AppendASCII("bad_private_key");
2130 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2131 privkey_path = data_dir().AppendASCII("bad_private_key.pem");
2132 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2133 privkey_path, ExtensionCreator::kOverwriteCRX));
2134 }
2135
2136 // Test Packaging and installing an extension whose name contains punctuation.
TEST_F(ExtensionServiceTest,PackPunctuatedExtension)2137 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2138 InitializeEmptyExtensionService();
2139 base::FilePath input_directory = data_dir()
2140 .AppendASCII("good")
2141 .AppendASCII("Extensions")
2142 .AppendASCII(good0)
2143 .AppendASCII("1.0.0.0");
2144
2145 base::ScopedTempDir temp_dir;
2146 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2147
2148 // Extension names containing punctuation, and the expected names for the
2149 // packed extensions.
2150 const base::FilePath punctuated_names[] = {
2151 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2152 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2153 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2154 NormalizePathSeparators(),
2155 };
2156 const base::FilePath expected_crx_names[] = {
2157 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2158 base::FilePath(
2159 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2160 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2161 };
2162 const base::FilePath expected_private_key_names[] = {
2163 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2164 base::FilePath(
2165 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2166 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2167 };
2168
2169 for (size_t i = 0; i < base::size(punctuated_names); ++i) {
2170 SCOPED_TRACE(punctuated_names[i].value().c_str());
2171 base::FilePath output_dir = temp_dir.GetPath().Append(punctuated_names[i]);
2172
2173 // Copy the extension into the output directory, as PackExtensionJob doesn't
2174 // let us choose where to output the packed extension.
2175 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2176
2177 base::FilePath expected_crx_path =
2178 temp_dir.GetPath().Append(expected_crx_names[i]);
2179 base::FilePath expected_private_key_path =
2180 temp_dir.GetPath().Append(expected_private_key_names[i]);
2181 PackExtensionTestClient pack_client(expected_crx_path,
2182 expected_private_key_path);
2183 {
2184 PackExtensionJob packer(&pack_client, output_dir, base::FilePath(),
2185 ExtensionCreator::kOverwriteCRX);
2186 packer.Start();
2187
2188 // The packer will post a notification task to the current thread's
2189 // message loop when it is finished. We manually run the loop here so
2190 // that we block and catch the notification; otherwise, the process would
2191 // exit.
2192 // This call to |Run()| is matched by a call to |Quit()| in the
2193 // |PackExtensionTestClient|'s notification handling code.
2194 base::RunLoop().Run();
2195 }
2196
2197 if (HasFatalFailure())
2198 return;
2199
2200 InstallCRX(expected_crx_path, INSTALL_NEW);
2201 }
2202 }
2203
TEST_F(ExtensionServiceTest,PackExtensionContainingKeyFails)2204 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2205 InitializeEmptyExtensionService();
2206
2207 base::ScopedTempDir extension_temp_dir;
2208 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2209 base::FilePath input_directory =
2210 extension_temp_dir.GetPath().AppendASCII("ext");
2211 ASSERT_TRUE(
2212 base::CopyDirectory(data_dir()
2213 .AppendASCII("good")
2214 .AppendASCII("Extensions")
2215 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2216 .AppendASCII("1.0.0.0"),
2217 input_directory,
2218 /*recursive=*/true));
2219
2220 base::ScopedTempDir output_temp_dir;
2221 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2222 base::FilePath output_directory = output_temp_dir.GetPath();
2223
2224 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2225 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2226
2227 // Pack the extension once to get a private key.
2228 std::unique_ptr<ExtensionCreator> creator(new ExtensionCreator());
2229 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2230 privkey_path, ExtensionCreator::kNoRunFlags))
2231 << creator->error_message();
2232 ASSERT_TRUE(base::PathExists(crx_path));
2233 ASSERT_TRUE(base::PathExists(privkey_path));
2234
2235 base::DeleteFile(crx_path);
2236 // Move the pem file into the extension.
2237 base::Move(privkey_path,
2238 input_directory.AppendASCII("privkey.pem"));
2239
2240 // This pack should fail because of the contained private key.
2241 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2242 privkey_path, ExtensionCreator::kNoRunFlags));
2243 EXPECT_THAT(creator->error_message(),
2244 testing::ContainsRegex(
2245 "extension includes the key file.*privkey.pem"));
2246 }
2247
2248 // Test Packaging and installing an extension using an openssl generated key.
2249 // The openssl is generated with the following:
2250 // > openssl genrsa -out privkey.pem 1024
2251 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2252 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2253 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
TEST_F(ExtensionServiceTest,PackExtensionOpenSSLKey)2254 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2255 InitializeEmptyExtensionService();
2256 base::FilePath input_directory =
2257 data_dir()
2258 .AppendASCII("good")
2259 .AppendASCII("Extensions")
2260 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2261 .AppendASCII("1.0.0.0");
2262 base::FilePath privkey_path(
2263 data_dir().AppendASCII("openssl_privkey_asn1.pem"));
2264 ASSERT_TRUE(base::PathExists(privkey_path));
2265
2266 base::ScopedTempDir temp_dir;
2267 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2268 base::FilePath output_directory = temp_dir.GetPath();
2269
2270 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2271
2272 std::unique_ptr<ExtensionCreator> creator(new ExtensionCreator());
2273 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2274 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2275
2276 InstallCRX(crx_path, INSTALL_NEW);
2277 }
2278
TEST_F(ExtensionServiceTest,TestInstallThemeWithExtensionsDisabled)2279 TEST_F(ExtensionServiceTest, TestInstallThemeWithExtensionsDisabled) {
2280 // Themes can be installed, even when extensions are disabled.
2281 InitializeExtensionServiceWithExtensionsDisabled();
2282 base::FilePath path = data_dir().AppendASCII("theme.crx");
2283 InstallCRX(path, INSTALL_NEW);
2284 ValidatePrefKeyCount(1);
2285 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2286 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2287 }
2288
2289 #if defined(THREAD_SANITIZER)
2290 // Flaky under Tsan. http://crbug.com/377702
2291 #define MAYBE_InstallTheme DISABLED_InstallTheme
2292 #else
2293 #define MAYBE_InstallTheme InstallTheme
2294 #endif
2295
TEST_F(ExtensionServiceTest,MAYBE_InstallTheme)2296 TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) {
2297 InitializeEmptyExtensionService();
2298 service()->Init();
2299
2300 // A theme.
2301 base::FilePath path = data_dir().AppendASCII("theme.crx");
2302 InstallCRX(path, INSTALL_NEW);
2303 int pref_count = 0;
2304 ValidatePrefKeyCount(++pref_count);
2305 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2306 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2307
2308 path = data_dir().AppendASCII("theme2.crx");
2309 InstallCRX(path, INSTALL_NEW);
2310 ValidatePrefKeyCount(++pref_count);
2311 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2312 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2313
2314 // A theme with extension elements. Themes cannot have extension elements,
2315 // so any such elements (like content scripts) should be ignored.
2316 {
2317 path = data_dir().AppendASCII("theme_with_extension.crx");
2318 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2319 ValidatePrefKeyCount(++pref_count);
2320 ASSERT_TRUE(extension);
2321 EXPECT_TRUE(extension->is_theme());
2322 EXPECT_TRUE(ContentScriptsInfo::GetContentScripts(extension).empty());
2323 }
2324
2325 // A theme with image resources missing (misspelt path).
2326 path = data_dir().AppendASCII("theme_missing_image.crx");
2327 InstallCRX(path, INSTALL_FAILED);
2328 ValidatePrefKeyCount(pref_count);
2329 }
2330
TEST_F(ExtensionServiceTest,LoadLocalizedTheme)2331 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2332 // Load.
2333 InitializeEmptyExtensionService();
2334 service()->Init();
2335
2336 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n");
2337
2338 // Don't create "Cached Theme.pak" in the extension directory, so as not to
2339 // modify the source tree.
2340 ThemeService::DisableThemePackForTesting();
2341
2342 UnpackedInstaller::Create(service())->Load(extension_path);
2343 content::RunAllTasksUntilIdle();
2344 EXPECT_EQ(0u, GetErrors().size());
2345 ASSERT_EQ(1u, loaded_.size());
2346 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2347 const Extension* theme = registry()->enabled_extensions().begin()->get();
2348 EXPECT_EQ("name", theme->name());
2349 EXPECT_EQ("description", theme->description());
2350 }
2351
2352 #if defined(OS_POSIX)
TEST_F(ExtensionServiceTest,UnpackedExtensionMayContainSymlinkedFiles)2353 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2354 base::FilePath source_data_dir =
2355 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed");
2356
2357 // Paths to test data files.
2358 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2359 ASSERT_TRUE(base::PathExists(source_manifest));
2360 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2361 ASSERT_TRUE(base::PathExists(source_icon));
2362
2363 // Set up the temporary extension directory.
2364 base::ScopedTempDir temp;
2365 ASSERT_TRUE(temp.CreateUniqueTempDir());
2366 base::FilePath extension_path = temp.GetPath();
2367 base::FilePath manifest = extension_path.Append(kManifestFilename);
2368 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2369 base::CopyFile(source_manifest, manifest);
2370 base::CreateSymbolicLink(source_icon, icon_symlink);
2371
2372 // Load extension.
2373 InitializeEmptyExtensionService();
2374 UnpackedInstaller::Create(service())->Load(extension_path);
2375 content::RunAllTasksUntilIdle();
2376
2377 EXPECT_TRUE(GetErrors().empty());
2378 ASSERT_EQ(1u, loaded_.size());
2379 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2380 }
2381 #endif
2382
2383 // Tests than an unpacked extension with an empty kMetadataFolder loads
2384 // successfully.
TEST_F(ExtensionServiceTest,UnpackedExtensionWithEmptyMetadataFolder)2385 TEST_F(ExtensionServiceTest, UnpackedExtensionWithEmptyMetadataFolder) {
2386 InitializeEmptyExtensionService();
2387 base::ScopedTempDir temp_dir;
2388 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2389 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
2390 base::FilePath metadata_dir = extension_dir.Append(kMetadataFolder);
2391 PersistExtensionWithPaths(extension_dir, {metadata_dir}, {});
2392 EXPECT_TRUE(base::DirectoryExists(metadata_dir));
2393
2394 UnpackedInstaller::Create(service())->Load(extension_dir);
2395 content::RunAllTasksUntilIdle();
2396 EXPECT_EQ(0u, GetErrors().size());
2397 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2398
2399 // The kMetadataFolder should have been deleted since it did not contain
2400 // any non-reserved filenames.
2401 EXPECT_FALSE(base::DirectoryExists(metadata_dir));
2402 }
2403
2404 // Tests that an unpacked extension with only reserved filenames in the
2405 // kMetadataFolder loads successfully.
TEST_F(ExtensionServiceTest,UnpackedExtensionWithReservedMetadataFiles)2406 TEST_F(ExtensionServiceTest, UnpackedExtensionWithReservedMetadataFiles) {
2407 InitializeEmptyExtensionService();
2408 base::ScopedTempDir temp_dir;
2409 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2410 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
2411 base::FilePath metadata_dir = extension_dir.Append(kMetadataFolder);
2412 PersistExtensionWithPaths(
2413 extension_dir, {metadata_dir},
2414 file_util::GetReservedMetadataFilePaths(extension_dir));
2415 EXPECT_TRUE(base::DirectoryExists(metadata_dir));
2416
2417 UnpackedInstaller::Create(service())->Load(extension_dir);
2418 content::RunAllTasksUntilIdle();
2419 EXPECT_EQ(0u, GetErrors().size());
2420 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2421
2422 // The kMetadataFolder should have been deleted since it did not contain
2423 // any non-reserved filenames.
2424 EXPECT_FALSE(base::DirectoryExists(metadata_dir));
2425 }
2426
2427 // Tests that an unpacked extension with non-reserved files in the
2428 // kMetadataFolder fails to load.
TEST_F(ExtensionServiceTest,UnpackedExtensionWithUserMetadataFiles)2429 TEST_F(ExtensionServiceTest, UnpackedExtensionWithUserMetadataFiles) {
2430 InitializeEmptyExtensionService();
2431 base::ScopedTempDir temp_dir;
2432 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2433 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
2434 base::FilePath metadata_dir = extension_dir.Append(kMetadataFolder);
2435 base::FilePath non_reserved_file =
2436 metadata_dir.Append(FILE_PATH_LITERAL("a.txt"));
2437 PersistExtensionWithPaths(
2438 extension_dir, {metadata_dir},
2439 {file_util::GetVerifiedContentsPath(extension_dir), non_reserved_file});
2440 EXPECT_TRUE(base::PathExists(non_reserved_file));
2441
2442 UnpackedInstaller::Create(service())->Load(extension_dir);
2443 content::RunAllTasksUntilIdle();
2444 ASSERT_EQ(1u, GetErrors().size());
2445
2446 // Format expected error string.
2447 std::string expected("Failed to load extension from: ");
2448 expected.append(extension_dir.MaybeAsASCII())
2449 .append(
2450 ". Cannot load extension with file or directory name _metadata. "
2451 "Filenames starting with \"_\" are reserved for use by the system.");
2452
2453 EXPECT_EQ(base::UTF8ToUTF16(expected), GetErrors()[0]);
2454 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2455
2456 // Non-reserved filepaths inside the kMetadataFolder should not have been
2457 // deleted.
2458 EXPECT_TRUE(base::PathExists(non_reserved_file));
2459 }
2460
2461 // Tests than an unpacked extension with an empty kMetadataFolder and a folder
2462 // beginning with "_" fails to load.
TEST_F(ExtensionServiceTest,UnpackedExtensionWithEmptyMetadataAndUnderscoreFolders)2463 TEST_F(ExtensionServiceTest,
2464 UnpackedExtensionWithEmptyMetadataAndUnderscoreFolders) {
2465 InitializeEmptyExtensionService();
2466 base::ScopedTempDir temp_dir;
2467 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2468 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
2469 base::FilePath metadata_dir = extension_dir.Append(kMetadataFolder);
2470 PersistExtensionWithPaths(
2471 extension_dir,
2472 {metadata_dir, extension_dir.Append(FILE_PATH_LITERAL("_badfolder"))},
2473 {});
2474
2475 UnpackedInstaller::Create(service())->Load(extension_dir);
2476 content::RunAllTasksUntilIdle();
2477 EXPECT_EQ(1u, GetErrors().size());
2478
2479 // Format expected error string.
2480 std::string expected("Failed to load extension from: ");
2481 expected.append(extension_dir.MaybeAsASCII())
2482 .append(
2483 ". Cannot load extension with file or directory name _badfolder. "
2484 "Filenames starting with \"_\" are reserved for use by the system.");
2485
2486 EXPECT_EQ(base::UTF8ToUTF16(expected), GetErrors()[0]);
2487 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2488
2489 // The kMetadataFolder should have been deleted since it did not contain any
2490 // non-reserved filenames.
2491 EXPECT_FALSE(base::DirectoryExists(metadata_dir));
2492 }
2493
2494 // Tests that an unpacked extension with an arbitrary folder beginning with an
2495 // underscore can't load.
TEST_F(ExtensionServiceTest,UnpackedExtensionMayNotHaveUnderscore)2496 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2497 InitializeEmptyExtensionService();
2498 base::ScopedTempDir temp_dir;
2499 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2500 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
2501 base::FilePath underscore_folder =
2502 extension_dir.Append(FILE_PATH_LITERAL("_badfolder"));
2503 PersistExtensionWithPaths(
2504 extension_dir, {underscore_folder},
2505 {underscore_folder.Append(FILE_PATH_LITERAL("a.js"))});
2506 EXPECT_TRUE(base::DirectoryExists(underscore_folder));
2507
2508 UnpackedInstaller::Create(service())->Load(extension_dir);
2509 content::RunAllTasksUntilIdle();
2510 EXPECT_EQ(1u, GetErrors().size());
2511
2512 // Format expected error string.
2513 std::string expected("Failed to load extension from: ");
2514 expected.append(extension_dir.MaybeAsASCII())
2515 .append(
2516 ". Cannot load extension with file or directory name _badfolder. "
2517 "Filenames starting with \"_\" are reserved for use by the system.");
2518
2519 EXPECT_EQ(base::UTF8ToUTF16(expected), GetErrors()[0]);
2520 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2521 }
2522
2523 // Tests that an unpacked extension with a malformed manifest can't reload.
2524 // Reload succeeds after fixing the manifest.
TEST_F(ExtensionServiceTest,ReloadExtensionWithMalformedManifestAndCorrectManifest)2525 TEST_F(ExtensionServiceTest,
2526 ReloadExtensionWithMalformedManifestAndCorrectManifest) {
2527 InitializeEmptyExtensionService();
2528 base::ScopedTempDir temp_dir;
2529 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2530 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
2531 base::FilePath manifest_dir = extension_dir.Append(kManifestFilename);
2532 ASSERT_FALSE(base::PathExists(manifest_dir));
2533
2534 // First create a correct manifest and Load the extension successfully.
2535 base::DictionaryValue manifest;
2536 manifest.SetString("version", "1.0");
2537 manifest.SetString("name", "malformed manifest reload test");
2538 manifest.SetInteger("manifest_version", 2);
2539
2540 JSONFileValueSerializer serializer(manifest_dir);
2541 ASSERT_TRUE(serializer.Serialize(manifest));
2542
2543 // Load the extension successfully.
2544 UnpackedInstaller::Create(service())->Load(extension_dir);
2545 content::RunAllTasksUntilIdle();
2546 // Verify that Load was successful
2547 EXPECT_EQ(0u, GetErrors().size());
2548 ASSERT_EQ(1u, loaded_.size());
2549 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2550 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2551 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2552
2553 // Change the version to a malformed version.
2554 manifest.SetString("version", "2.0b");
2555 ASSERT_TRUE(serializer.Serialize(manifest));
2556
2557 std::string extension_id = loaded_[0]->id();
2558
2559 // Reload the extension.
2560 service()->ReloadExtension(extension_id);
2561 content::RunAllTasksUntilIdle();
2562
2563 // An error is generated.
2564 ASSERT_EQ(1u, GetErrors().size());
2565 EXPECT_THAT(
2566 base::UTF16ToUTF8(GetErrors()[0]),
2567 ::testing::HasSubstr("Required value 'version' is missing or invalid."));
2568
2569 // Verify that ReloadExtension() was not successful.
2570 ASSERT_EQ(0u, loaded_.size());
2571 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension_id));
2572
2573 // Fix the version.
2574 manifest.SetString("version", "2.0");
2575 ASSERT_TRUE(serializer.Serialize(manifest));
2576
2577 // Reload the extension.
2578 service()->ReloadExtension(extension_id);
2579 content::RunAllTasksUntilIdle();
2580
2581 // No new error is generated. Since the error generated above is still there,
2582 // the error size is 1.
2583 EXPECT_EQ(1u, GetErrors().size());
2584 // Verify that ReloadExtension() was successful.
2585 ASSERT_EQ(1u, loaded_.size());
2586 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2587 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2588 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2589 }
2590
TEST_F(ExtensionServiceTest,InstallLocalizedTheme)2591 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2592 InitializeEmptyExtensionService();
2593 service()->Init();
2594
2595 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n");
2596
2597 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2598
2599 EXPECT_EQ(0u, GetErrors().size());
2600 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2601 EXPECT_EQ("name", theme->name());
2602 EXPECT_EQ("description", theme->description());
2603 }
2604
TEST_F(ExtensionServiceTest,InstallApps)2605 TEST_F(ExtensionServiceTest, InstallApps) {
2606 InitializeEmptyExtensionService();
2607
2608 // An empty app.
2609 const Extension* app =
2610 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2611 int pref_count = 0;
2612 ValidatePrefKeyCount(++pref_count);
2613 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2614 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2615 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2616
2617 // Another app with non-overlapping extent. Should succeed.
2618 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2619 ValidatePrefKeyCount(++pref_count);
2620
2621 // A third app whose extent overlaps the first. Should fail.
2622 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED);
2623 ValidatePrefKeyCount(pref_count);
2624 }
2625
2626 // Tests that file access is OFF by default.
TEST_F(ExtensionServiceTest,DefaultFileAccess)2627 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2628 InitializeEmptyExtensionService();
2629 const Extension* extension = PackAndInstallCRX(
2630 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW);
2631 EXPECT_EQ(0u, GetErrors().size());
2632 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2633 EXPECT_FALSE(
2634 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id()));
2635 }
2636
TEST_F(ExtensionServiceTest,UpdateApps)2637 TEST_F(ExtensionServiceTest, UpdateApps) {
2638 InitializeEmptyExtensionService();
2639 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2640
2641 // First install v1 of a hosted app.
2642 const Extension* extension =
2643 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2644 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2645 std::string id = extension->id();
2646 ASSERT_EQ(std::string("1"), extension->version().GetString());
2647
2648 // Now try updating to v2.
2649 UpdateExtension(id,
2650 extensions_path.AppendASCII("v2.crx"),
2651 ENABLED);
2652 ASSERT_EQ(
2653 std::string("2"),
2654 registry()->enabled_extensions().GetByID(id)->version().GetString());
2655 }
2656
2657 // Verifies that the NTP page and launch ordinals are kept when updating apps.
TEST_F(ExtensionServiceTest,UpdateAppsRetainOrdinals)2658 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2659 InitializeEmptyExtensionService();
2660 AppSorting* sorting = ExtensionSystem::Get(profile())->app_sorting();
2661 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2662
2663 // First install v1 of a hosted app.
2664 const Extension* extension =
2665 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2666 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2667 std::string id = extension->id();
2668 ASSERT_EQ(std::string("1"), extension->version().GetString());
2669
2670 // Modify the ordinals so we can distinguish them from the defaults.
2671 syncer::StringOrdinal new_page_ordinal =
2672 sorting->GetPageOrdinal(id).CreateAfter();
2673 syncer::StringOrdinal new_launch_ordinal =
2674 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2675
2676 sorting->SetPageOrdinal(id, new_page_ordinal);
2677 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2678
2679 // Now try updating to v2.
2680 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2681 ASSERT_EQ(
2682 std::string("2"),
2683 registry()->enabled_extensions().GetByID(id)->version().GetString());
2684
2685 // Verify that the ordinals match.
2686 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2687 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2688 }
2689
2690 // Ensures that the CWS has properly initialized ordinals.
TEST_F(ExtensionServiceTest,EnsureCWSOrdinalsInitialized)2691 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2692 InitializeEmptyExtensionService();
2693 service()->component_loader()->Add(
2694 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2695 service()->Init();
2696
2697 AppSorting* sorting = ExtensionSystem::Get(profile())->app_sorting();
2698 EXPECT_TRUE(sorting->GetPageOrdinal(kWebStoreAppId).IsValid());
2699 EXPECT_TRUE(sorting->GetAppLaunchOrdinal(kWebStoreAppId).IsValid());
2700 }
2701
TEST_F(ExtensionServiceTest,InstallAppsWithUnlimitedStorage)2702 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2703 InitializeEmptyExtensionService();
2704 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2705
2706 int pref_count = 0;
2707
2708 // Install app1 with unlimited storage.
2709 const Extension* extension =
2710 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2711 ValidatePrefKeyCount(++pref_count);
2712 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2713 const std::string id1 = extension->id();
2714 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2715 APIPermission::kUnlimitedStorage));
2716 EXPECT_TRUE(extension->web_extent().MatchesURL(
2717 AppLaunchInfo::GetFullLaunchURL(extension)));
2718 const GURL origin1(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2719 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2720 origin1));
2721
2722 // Install app2 from the same origin with unlimited storage.
2723 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2724 ValidatePrefKeyCount(++pref_count);
2725 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2726 const std::string id2 = extension->id();
2727 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2728 APIPermission::kUnlimitedStorage));
2729 EXPECT_TRUE(extension->web_extent().MatchesURL(
2730 AppLaunchInfo::GetFullLaunchURL(extension)));
2731 const GURL origin2(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2732 EXPECT_EQ(origin1, origin2);
2733 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2734 origin2));
2735
2736 // Uninstall one of them, unlimited storage should still be granted
2737 // to the origin.
2738 UninstallExtension(id1);
2739 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2740 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2741 origin1));
2742
2743 // Uninstall the other, unlimited storage should be revoked.
2744 UninstallExtension(id2);
2745 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2746 EXPECT_FALSE(
2747 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2748 origin2));
2749 }
2750
TEST_F(ExtensionServiceTest,InstallAppsAndCheckStorageProtection)2751 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2752 InitializeEmptyExtensionService();
2753 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2754
2755 int pref_count = 0;
2756
2757 const Extension* extension =
2758 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2759 ValidatePrefKeyCount(++pref_count);
2760 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2761 EXPECT_TRUE(extension->is_app());
2762 const std::string id1 = extension->id();
2763 const GURL origin1(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2764 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2765 origin1));
2766
2767 // App 4 has a different origin (maps.google.com).
2768 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
2769 ValidatePrefKeyCount(++pref_count);
2770 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2771 const std::string id2 = extension->id();
2772 const GURL origin2(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2773 ASSERT_NE(origin1, origin2);
2774 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2775 origin2));
2776
2777 UninstallExtension(id1);
2778 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2779
2780 UninstallExtension(id2);
2781
2782 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2783 EXPECT_FALSE(
2784 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2785 origin1));
2786 EXPECT_FALSE(
2787 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2788 origin2));
2789 }
2790
2791 // Test that when an extension version is reinstalled, nothing happens.
TEST_F(ExtensionServiceTest,Reinstall)2792 TEST_F(ExtensionServiceTest, Reinstall) {
2793 InitializeEmptyExtensionService();
2794
2795 // A simple extension that should install without error.
2796 base::FilePath path = data_dir().AppendASCII("good.crx");
2797 InstallCRX(path, INSTALL_NEW);
2798
2799 ValidatePrefKeyCount(1);
2800 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2801 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2802
2803 // Reinstall the same version, it should overwrite the previous one.
2804 InstallCRX(path, INSTALL_UPDATED);
2805
2806 ValidatePrefKeyCount(1);
2807 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2808 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2809 }
2810
2811 // Test that we can determine if extensions came from the
2812 // Chrome web store.
TEST_F(ExtensionServiceTest,FromWebStore)2813 TEST_F(ExtensionServiceTest, FromWebStore) {
2814 InitializeEmptyExtensionService();
2815
2816 // A simple extension that should install without error.
2817 base::FilePath path = data_dir().AppendASCII("good.crx");
2818 // Not from web store.
2819 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2820 std::string id = extension->id();
2821
2822 ValidatePrefKeyCount(1);
2823 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2824 ASSERT_FALSE(extension->from_webstore());
2825
2826 // Test install from web store.
2827 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2828
2829 ValidatePrefKeyCount(1);
2830 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2831
2832 // Reload so extension gets reinitialized with new value.
2833 service()->ReloadExtensionsForTest();
2834 extension = registry()->enabled_extensions().GetByID(id);
2835 ASSERT_TRUE(extension->from_webstore());
2836
2837 // Upgrade to version 2.0
2838 path = data_dir().AppendASCII("good2.crx");
2839 UpdateExtension(good_crx, path, ENABLED);
2840 ValidatePrefKeyCount(1);
2841 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2842 }
2843
2844 // Test upgrading a signed extension.
TEST_F(ExtensionServiceTest,UpgradeSignedGood)2845 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2846 InitializeEmptyExtensionService();
2847
2848 base::FilePath path = data_dir().AppendASCII("good.crx");
2849 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2850 std::string id = extension->id();
2851
2852 ASSERT_EQ("1.0.0.0", extension->version().GetString());
2853 ASSERT_EQ(0u, GetErrors().size());
2854
2855 // Upgrade to version 1.0.0.1.
2856 // Also test that the extension's old and new title are correctly retrieved.
2857 path = data_dir().AppendASCII("good2.crx");
2858 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2859 extension = registry()->enabled_extensions().GetByID(id);
2860
2861 ASSERT_EQ("1.0.0.1", extension->version().GetString());
2862 ASSERT_EQ("My updated extension 1", extension->name());
2863 ASSERT_EQ(0u, GetErrors().size());
2864 }
2865
2866 // Test upgrading a signed extension with a bad signature.
TEST_F(ExtensionServiceTest,UpgradeSignedBad)2867 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2868 InitializeEmptyExtensionService();
2869
2870 base::FilePath path = data_dir().AppendASCII("good.crx");
2871 InstallCRX(path, INSTALL_NEW);
2872
2873 // Try upgrading with a bad signature. This should fail during the unpack,
2874 // because the key will not match the signature.
2875 path = data_dir().AppendASCII("bad_signature.crx");
2876 InstallCRX(path, INSTALL_FAILED);
2877 }
2878
2879 // Test a normal update via the UpdateExtension API
TEST_F(ExtensionServiceTest,UpdateExtension)2880 TEST_F(ExtensionServiceTest, UpdateExtension) {
2881 InitializeEmptyExtensionService();
2882
2883 base::FilePath path = data_dir().AppendASCII("good.crx");
2884
2885 const Extension* good = InstallCRX(path, INSTALL_NEW);
2886 ASSERT_EQ("1.0.0.0", good->VersionString());
2887 ASSERT_EQ(good_crx, good->id());
2888
2889 path = data_dir().AppendASCII("good2.crx");
2890 UpdateExtension(good_crx, path, ENABLED);
2891 ASSERT_EQ("1.0.0.1", registry()
2892 ->enabled_extensions()
2893 .GetByID(good_crx)
2894 ->version()
2895 .GetString());
2896 }
2897
2898 // Extensions should not be updated during browser shutdown.
TEST_F(ExtensionServiceTest,UpdateExtensionDuringShutdown)2899 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2900 InitializeEmptyExtensionService();
2901
2902 // Install an extension.
2903 base::FilePath path = data_dir().AppendASCII("good.crx");
2904 const Extension* good = InstallCRX(path, INSTALL_NEW);
2905 ASSERT_EQ(good_crx, good->id());
2906
2907 // Simulate shutdown.
2908 service()->set_browser_terminating_for_test(true);
2909
2910 // Update should fail and extension should not be updated.
2911 path = data_dir().AppendASCII("good2.crx");
2912 CRXFileInfo crx_info(path, GetTestVerifierFormat());
2913 crx_info.extension_id = good_crx;
2914 bool updated = service()->UpdateExtension(crx_info, true, nullptr);
2915 ASSERT_FALSE(updated);
2916 ASSERT_EQ("1.0.0.0", registry()
2917 ->enabled_extensions()
2918 .GetByID(good_crx)
2919 ->version()
2920 .GetString());
2921 }
2922
2923 // Test updating a not-already-installed extension - this should fail
TEST_F(ExtensionServiceTest,UpdateNotInstalledExtension)2924 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2925 InitializeEmptyExtensionService();
2926
2927 base::FilePath path = data_dir().AppendASCII("good.crx");
2928 UpdateExtension(good_crx, path, UPDATED);
2929 content::RunAllTasksUntilIdle();
2930
2931 ASSERT_EQ(0u, registry()->enabled_extensions().size());
2932 ASSERT_FALSE(installed_);
2933 ASSERT_EQ(0u, loaded_.size());
2934 }
2935
2936 // Makes sure you can't downgrade an extension via UpdateExtension
TEST_F(ExtensionServiceTest,UpdateWillNotDowngrade)2937 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2938 InitializeEmptyExtensionService();
2939
2940 base::FilePath path = data_dir().AppendASCII("good2.crx");
2941
2942 const Extension* good = InstallCRX(path, INSTALL_NEW);
2943 ASSERT_EQ("1.0.0.1", good->VersionString());
2944 ASSERT_EQ(good_crx, good->id());
2945
2946 // Change path from good2.crx -> good.crx
2947 path = data_dir().AppendASCII("good.crx");
2948 UpdateExtension(good_crx, path, FAILED);
2949 ASSERT_EQ("1.0.0.1", registry()
2950 ->enabled_extensions()
2951 .GetByID(good_crx)
2952 ->version()
2953 .GetString());
2954 }
2955
2956 // Make sure calling update with an identical version does nothing
TEST_F(ExtensionServiceTest,UpdateToSameVersionIsNoop)2957 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2958 InitializeEmptyExtensionService();
2959
2960 base::FilePath path = data_dir().AppendASCII("good.crx");
2961
2962 const Extension* good = InstallCRX(path, INSTALL_NEW);
2963 ASSERT_EQ(good_crx, good->id());
2964 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2965 }
2966
2967 // Tests that updating an extension does not clobber old state.
TEST_F(ExtensionServiceTest,UpdateExtensionPreservesState)2968 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2969 InitializeEmptyExtensionService();
2970
2971 base::FilePath path = data_dir().AppendASCII("good.crx");
2972
2973 const Extension* good = InstallCRX(path, INSTALL_NEW);
2974 ASSERT_EQ("1.0.0.0", good->VersionString());
2975 ASSERT_EQ(good_crx, good->id());
2976
2977 // Disable it and allow it to run in incognito. These settings should carry
2978 // over to the updated version.
2979 service()->DisableExtension(good->id(), disable_reason::DISABLE_USER_ACTION);
2980 util::SetIsIncognitoEnabled(good->id(), profile(), true);
2981
2982 path = data_dir().AppendASCII("good2.crx");
2983 UpdateExtension(good_crx, path, INSTALLED);
2984 ASSERT_EQ(1u, registry()->disabled_extensions().size());
2985 const Extension* good2 = registry()->disabled_extensions().GetByID(good_crx);
2986 ASSERT_EQ("1.0.0.1", good2->version().GetString());
2987 EXPECT_TRUE(util::IsIncognitoEnabled(good2->id(), profile()));
2988 EXPECT_EQ(disable_reason::DISABLE_USER_ACTION,
2989 ExtensionPrefs::Get(profile())->GetDisableReasons(good2->id()));
2990 }
2991
2992 // Tests that updating preserves extension location.
TEST_F(ExtensionServiceTest,UpdateExtensionPreservesLocation)2993 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2994 InitializeEmptyExtensionService();
2995 base::FilePath path = data_dir().AppendASCII("good.crx");
2996
2997 const Extension* good = InstallCRX(path, Manifest::EXTERNAL_PREF, INSTALL_NEW,
2998 Extension::NO_FLAGS);
2999
3000 ASSERT_EQ("1.0.0.0", good->VersionString());
3001 ASSERT_EQ(good_crx, good->id());
3002
3003 path = data_dir().AppendASCII("good2.crx");
3004 UpdateExtension(good_crx, path, ENABLED);
3005 const Extension* good2 = registry()->enabled_extensions().GetByID(good_crx);
3006 ASSERT_EQ("1.0.0.1", good2->version().GetString());
3007 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
3008 }
3009
3010 // Makes sure that LOAD extension types can downgrade.
TEST_F(ExtensionServiceTest,LoadExtensionsCanDowngrade)3011 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
3012 InitializeEmptyExtensionService();
3013
3014 base::ScopedTempDir temp;
3015 ASSERT_TRUE(temp.CreateUniqueTempDir());
3016
3017 // We'll write the extension manifest dynamically to a temporary path
3018 // to make it easier to change the version number.
3019 base::FilePath extension_path = temp.GetPath();
3020 base::FilePath manifest_path = extension_path.Append(kManifestFilename);
3021 ASSERT_FALSE(base::PathExists(manifest_path));
3022
3023 // Start with version 2.0.
3024 base::DictionaryValue manifest;
3025 manifest.SetString("version", "2.0");
3026 manifest.SetString("name", "LOAD Downgrade Test");
3027 manifest.SetInteger("manifest_version", 2);
3028
3029 JSONFileValueSerializer serializer(manifest_path);
3030 ASSERT_TRUE(serializer.Serialize(manifest));
3031
3032 UnpackedInstaller::Create(service())->Load(extension_path);
3033 content::RunAllTasksUntilIdle();
3034
3035 EXPECT_EQ(0u, GetErrors().size());
3036 ASSERT_EQ(1u, loaded_.size());
3037 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
3038 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3039 EXPECT_EQ("2.0", loaded_[0]->VersionString());
3040
3041 // Now set the version number to 1.0, reload the extensions and verify that
3042 // the downgrade was accepted.
3043 manifest.SetString("version", "1.0");
3044 ASSERT_TRUE(serializer.Serialize(manifest));
3045
3046 UnpackedInstaller::Create(service())->Load(extension_path);
3047 content::RunAllTasksUntilIdle();
3048
3049 EXPECT_EQ(0u, GetErrors().size());
3050 ASSERT_EQ(1u, loaded_.size());
3051 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
3052 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3053 EXPECT_EQ("1.0", loaded_[0]->VersionString());
3054 }
3055
3056 namespace {
3057
IsExtension(const Extension * extension)3058 bool IsExtension(const Extension* extension) {
3059 return extension->GetType() == Manifest::TYPE_EXTENSION;
3060 }
3061
3062 #if defined(ENABLE_BLOCKLIST_TESTS)
StringSet(const std::string & s)3063 std::set<std::string> StringSet(const std::string& s) {
3064 std::set<std::string> set;
3065 set.insert(s);
3066 return set;
3067 }
StringSet(const std::string & s1,const std::string & s2)3068 std::set<std::string> StringSet(const std::string& s1, const std::string& s2) {
3069 std::set<std::string> set = StringSet(s1);
3070 set.insert(s2);
3071 return set;
3072 }
3073 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3074
3075 } // namespace
3076
3077 // Test adding a pending extension.
TEST_F(ExtensionServiceTest,AddPendingExtensionFromSync)3078 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
3079 InitializeEmptyExtensionService();
3080
3081 const std::string kFakeId(all_zero);
3082 const GURL kFakeUpdateURL("http:://fake.update/url");
3083 const bool kFakeRemoteInstall(false);
3084
3085 EXPECT_TRUE(
3086 service()->pending_extension_manager()->AddFromSync(
3087 kFakeId,
3088 kFakeUpdateURL,
3089 base::Version(),
3090 &IsExtension,
3091 kFakeRemoteInstall));
3092
3093 const PendingExtensionInfo* pending_extension_info;
3094 ASSERT_TRUE((pending_extension_info =
3095 service()->pending_extension_manager()->GetById(kFakeId)));
3096 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
3097 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
3098 // Use
3099 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install())
3100 // instead of
3101 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install())
3102 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is
3103 // turned into an error with -Werror=conversion-null:
3104 // converting 'false' to pointer type for argument 1 of
3105 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
3106 // https://code.google.com/p/googletest/issues/detail?id=458
3107 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install());
3108 }
3109
3110 namespace {
3111 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
3112 const char kGoodUpdateURL[] = "http://good.update/url";
3113 const char kGoodVersion[] = "1";
3114 const bool kGoodIsFromSync = true;
3115 const bool kGoodRemoteInstall = false;
3116 } // namespace
3117
3118 // Test installing a pending extension (this goes through
3119 // ExtensionService::UpdateExtension).
TEST_F(ExtensionServiceTest,UpdatePendingExtension)3120 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
3121 InitializeEmptyExtensionService();
3122 EXPECT_TRUE(
3123 service()->pending_extension_manager()->AddFromSync(
3124 kGoodId,
3125 GURL(kGoodUpdateURL),
3126 base::Version(kGoodVersion),
3127 &IsExtension,
3128 kGoodRemoteInstall));
3129 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3130
3131 base::FilePath path = data_dir().AppendASCII("good.crx");
3132 UpdateExtension(kGoodId, path, ENABLED);
3133
3134 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3135
3136 const Extension* extension =
3137 registry()->enabled_extensions().GetByID(kGoodId);
3138 EXPECT_TRUE(extension);
3139 }
3140
TEST_F(ExtensionServiceTest,UpdatePendingExtensionWrongVersion)3141 TEST_F(ExtensionServiceTest, UpdatePendingExtensionWrongVersion) {
3142 InitializeEmptyExtensionService();
3143 base::Version other_version("0.1");
3144 ASSERT_TRUE(other_version.IsValid());
3145 ASSERT_NE(other_version, base::Version(kGoodVersion));
3146 EXPECT_TRUE(
3147 service()->pending_extension_manager()->AddFromSync(
3148 kGoodId,
3149 GURL(kGoodUpdateURL),
3150 other_version,
3151 &IsExtension,
3152 kGoodRemoteInstall));
3153 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3154
3155 base::FilePath path = data_dir().AppendASCII("good.crx");
3156 // After installation, the extension should be disabled, because it's missing
3157 // permissions.
3158 UpdateExtension(kGoodId, path, DISABLED);
3159
3160 EXPECT_TRUE(
3161 ExtensionPrefs::Get(profile())->DidExtensionEscalatePermissions(kGoodId));
3162
3163 // It should still have been installed though.
3164 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3165
3166 const Extension* extension =
3167 registry()->disabled_extensions().GetByID(kGoodId);
3168 EXPECT_TRUE(extension);
3169 }
3170
3171 namespace {
3172
IsTheme(const Extension * extension)3173 bool IsTheme(const Extension* extension) {
3174 return extension->is_theme();
3175 }
3176
3177 } // namespace
3178
3179 // Test updating a pending theme.
TEST_F(ExtensionServiceTest,UpdatePendingTheme)3180 TEST_F(ExtensionServiceTest, UpdatePendingTheme) {
3181 InitializeEmptyExtensionService();
3182 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3183 theme_crx, GURL(), base::Version(), &IsTheme, false));
3184 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3185
3186 base::FilePath path = data_dir().AppendASCII("theme.crx");
3187 UpdateExtension(theme_crx, path, ENABLED);
3188
3189 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3190
3191 const Extension* extension =
3192 registry()->enabled_extensions().GetByID(theme_crx);
3193 ASSERT_TRUE(extension);
3194
3195 EXPECT_FALSE(
3196 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3197 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx));
3198 }
3199
3200 // Test updating a pending CRX as if the source is an external extension
3201 // with an update URL. In this case we don't know if the CRX is a theme
3202 // or not.
TEST_F(ExtensionServiceTest,UpdatePendingExternalCrx)3203 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrx) {
3204 InitializeEmptyExtensionService();
3205 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3206 theme_crx,
3207 std::string(),
3208 GURL(),
3209 Manifest::EXTERNAL_PREF_DOWNLOAD,
3210 Extension::NO_FLAGS,
3211 false));
3212
3213 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3214
3215 base::FilePath path = data_dir().AppendASCII("theme.crx");
3216 UpdateExtension(theme_crx, path, ENABLED);
3217
3218 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3219
3220 const Extension* extension =
3221 registry()->enabled_extensions().GetByID(theme_crx);
3222 ASSERT_TRUE(extension);
3223
3224 EXPECT_FALSE(
3225 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3226 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id()));
3227 EXPECT_FALSE(util::IsIncognitoEnabled(extension->id(), profile()));
3228 }
3229
3230 // Test updating a pending CRX as if the source is an external extension
3231 // with an update URL. The external update should overwrite a sync update,
3232 // but a sync update should not overwrite a non-sync update.
TEST_F(ExtensionServiceTest,UpdatePendingExternalCrxWinsOverSync)3233 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3234 InitializeEmptyExtensionService();
3235
3236 // Add a crx to be installed from the update mechanism.
3237 EXPECT_TRUE(
3238 service()->pending_extension_manager()->AddFromSync(
3239 kGoodId,
3240 GURL(kGoodUpdateURL),
3241 base::Version(),
3242 &IsExtension,
3243 kGoodRemoteInstall));
3244
3245 // Check that there is a pending crx, with is_from_sync set to true.
3246 const PendingExtensionInfo* pending_extension_info;
3247 ASSERT_TRUE((pending_extension_info =
3248 service()->pending_extension_manager()->GetById(kGoodId)));
3249 EXPECT_TRUE(pending_extension_info->is_from_sync());
3250
3251 // Add a crx to be updated, with the same ID, from a non-sync source.
3252 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3253 kGoodId,
3254 std::string(),
3255 GURL(kGoodUpdateURL),
3256 Manifest::EXTERNAL_PREF_DOWNLOAD,
3257 Extension::NO_FLAGS,
3258 false));
3259
3260 // Check that there is a pending crx, with is_from_sync set to false.
3261 ASSERT_TRUE((pending_extension_info =
3262 service()->pending_extension_manager()->GetById(kGoodId)));
3263 EXPECT_FALSE(pending_extension_info->is_from_sync());
3264 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3265 pending_extension_info->install_source());
3266
3267 // Add a crx to be installed from the update mechanism.
3268 EXPECT_FALSE(
3269 service()->pending_extension_manager()->AddFromSync(
3270 kGoodId,
3271 GURL(kGoodUpdateURL),
3272 base::Version(),
3273 &IsExtension,
3274 kGoodRemoteInstall));
3275
3276 // Check that the external, non-sync update was not overridden.
3277 ASSERT_TRUE((pending_extension_info =
3278 service()->pending_extension_manager()->GetById(kGoodId)));
3279 EXPECT_FALSE(pending_extension_info->is_from_sync());
3280 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3281 pending_extension_info->install_source());
3282 }
3283
3284 // Updating a theme should fail if the updater is explicitly told that
3285 // the CRX is not a theme.
TEST_F(ExtensionServiceTest,UpdatePendingCrxThemeMismatch)3286 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3287 InitializeEmptyExtensionService();
3288 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3289 theme_crx, GURL(), base::Version(), &IsExtension, false));
3290
3291 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3292
3293 base::FilePath path = data_dir().AppendASCII("theme.crx");
3294 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3295
3296 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3297
3298 const Extension* extension =
3299 registry()->GetExtensionById(theme_crx, ExtensionRegistry::EVERYTHING);
3300 ASSERT_FALSE(extension);
3301 }
3302
3303 // TODO(akalin): Test updating a pending extension non-silently once
3304 // we can mock out ExtensionInstallUI and inject our version into
3305 // UpdateExtension().
3306
3307 // Test updating a pending extension which fails the should-install test.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionFailedShouldInstallTest)3308 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
3309 InitializeEmptyExtensionService();
3310 // Add pending extension with a flipped is_theme.
3311 EXPECT_TRUE(
3312 service()->pending_extension_manager()->AddFromSync(
3313 kGoodId,
3314 GURL(kGoodUpdateURL),
3315 base::Version(),
3316 &IsTheme,
3317 kGoodRemoteInstall));
3318 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3319
3320 base::FilePath path = data_dir().AppendASCII("good.crx");
3321 UpdateExtension(kGoodId, path, UPDATED);
3322
3323 // TODO(akalin): Figure out how to check that the extensions
3324 // directory is cleaned up properly in OnExtensionInstalled().
3325
3326 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3327 }
3328
3329 // TODO(akalin): Figure out how to test that installs of pending
3330 // unsyncable extensions are blocked.
3331
3332 // Test updating a pending extension for one that is not pending.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionNotPending)3333 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3334 InitializeEmptyExtensionService();
3335
3336 base::FilePath path = data_dir().AppendASCII("good.crx");
3337 UpdateExtension(kGoodId, path, UPDATED);
3338
3339 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3340 }
3341
3342 // Test updating a pending extension for one that is already
3343 // installed.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionAlreadyInstalled)3344 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3345 InitializeEmptyExtensionService();
3346
3347 base::FilePath path = data_dir().AppendASCII("good.crx");
3348 const Extension* good = InstallCRX(path, INSTALL_NEW);
3349 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3350
3351 EXPECT_FALSE(good->is_theme());
3352
3353 // Use AddExtensionImpl() as AddFrom*() would balk.
3354 service()->pending_extension_manager()->AddExtensionImpl(
3355 good->id(), std::string(), ManifestURL::GetUpdateURL(good),
3356 base::Version(), &IsExtension, kGoodIsFromSync, Manifest::INTERNAL,
3357 Extension::NO_FLAGS, false, kGoodRemoteInstall);
3358 UpdateExtension(good->id(), path, ENABLED);
3359
3360 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3361 }
3362
3363 #if defined(ENABLE_BLOCKLIST_TESTS)
3364 // Tests blocklisting then unblocklisting extensions after the service has been
3365 // initialized.
TEST_F(ExtensionServiceTest,SetUnsetBlocklistInPrefs)3366 TEST_F(ExtensionServiceTest, SetUnsetBlocklistInPrefs) {
3367 TestBlocklist test_blocklist;
3368 // A profile with 3 extensions installed: good0, good1, and good2.
3369 InitializeGoodInstalledExtensionService();
3370 test_blocklist.Attach(service()->blocklist_);
3371 service()->Init();
3372
3373 const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
3374 const ExtensionSet& blocklisted_extensions =
3375 registry()->blocklisted_extensions();
3376
3377 EXPECT_TRUE(enabled_extensions.Contains(good0) &&
3378 !blocklisted_extensions.Contains(good0));
3379 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3380 !blocklisted_extensions.Contains(good1));
3381 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3382 !blocklisted_extensions.Contains(good2));
3383
3384 EXPECT_FALSE(IsPrefExist(good0, kPrefBlocklist));
3385 EXPECT_FALSE(IsPrefExist(good1, kPrefBlocklist));
3386 EXPECT_FALSE(IsPrefExist(good2, kPrefBlocklist));
3387 EXPECT_FALSE(IsPrefExist("invalid_id", kPrefBlocklist));
3388
3389 // Blocklist good0 and good1 (and an invalid extension ID).
3390 test_blocklist.SetBlocklistState(good0, BLOCKLISTED_MALWARE, true);
3391 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_MALWARE, true);
3392 test_blocklist.SetBlocklistState("invalid_id", BLOCKLISTED_MALWARE, true);
3393 content::RunAllTasksUntilIdle();
3394
3395 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3396 blocklisted_extensions.Contains(good0));
3397 EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
3398 blocklisted_extensions.Contains(good1));
3399 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3400 !blocklisted_extensions.Contains(good2));
3401
3402 EXPECT_TRUE(ValidateBooleanPref(good0, kPrefBlocklist, true));
3403 EXPECT_TRUE(ValidateBooleanPref(good1, kPrefBlocklist, true));
3404 EXPECT_FALSE(IsPrefExist(good2, kPrefBlocklist));
3405 EXPECT_FALSE(IsPrefExist("invalid_id", kPrefBlocklist));
3406
3407 // Un-blocklist good1 and blocklist good2.
3408 test_blocklist.Clear(false);
3409 test_blocklist.SetBlocklistState(good0, BLOCKLISTED_MALWARE, true);
3410 test_blocklist.SetBlocklistState(good2, BLOCKLISTED_MALWARE, true);
3411 test_blocklist.SetBlocklistState("invalid_id", BLOCKLISTED_MALWARE, true);
3412 content::RunAllTasksUntilIdle();
3413
3414 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3415 blocklisted_extensions.Contains(good0));
3416 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3417 !blocklisted_extensions.Contains(good1));
3418 EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
3419 blocklisted_extensions.Contains(good2));
3420
3421 EXPECT_TRUE(ValidateBooleanPref(good0, kPrefBlocklist, true));
3422 EXPECT_FALSE(IsPrefExist(good1, kPrefBlocklist));
3423 EXPECT_TRUE(ValidateBooleanPref(good2, kPrefBlocklist, true));
3424 EXPECT_FALSE(IsPrefExist("invalid_id", kPrefBlocklist));
3425 }
3426
3427 // Tests that an extension that was disabled through Omaha won't be
3428 // re-enabled if it's not present in the Safe Browsing blocklist.
3429 // Regression test for https://crbug.com/1107040.
TEST_F(ExtensionServiceTest,NoUnsetBlocklistInPrefs)3430 TEST_F(ExtensionServiceTest, NoUnsetBlocklistInPrefs) {
3431 TestBlocklist test_blocklist;
3432 // A profile with 3 extensions installed: good0, good1, and good2.
3433 // We really only care about good0 for this test since the other
3434 // functionality is already tested in the above test.
3435 InitializeGoodInstalledExtensionService();
3436 test_blocklist.Attach(service()->blocklist_);
3437 service()->Init();
3438
3439 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3440 EXPECT_FALSE(registry()->blocklisted_extensions().Contains(good0));
3441
3442 base::Value attributes(base::Value::Type::DICTIONARY);
3443 attributes.SetKey("_malware", base::Value(true));
3444
3445 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
3446 service()->PerformActionBasedOnOmahaAttributes(good0, attributes);
3447 EXPECT_EQ(disable_reason::DISABLE_REMOTELY_FOR_MALWARE,
3448 prefs->GetDisableReasons(good0));
3449 EXPECT_TRUE(IsPrefExist(good0, kPrefBlocklist));
3450 EXPECT_FALSE(registry()->enabled_extensions().Contains(good0));
3451 EXPECT_TRUE(registry()->blocklisted_extensions().Contains(good0));
3452
3453 // Un-blocklist all extensions.
3454 test_blocklist.Clear(false);
3455 content::RunAllTasksUntilIdle();
3456
3457 // If the extension has a DISABLE_REMOTELY_FOR_MALWARE disable reason,
3458 // the extension should still not be enabled even if it's no on the
3459 // SB blocklist. This disable reason needs to be removed prior to
3460 // unblocklisting/re-enabling.
3461 EXPECT_FALSE(registry()->enabled_extensions().Contains(good0));
3462 EXPECT_TRUE(registry()->blocklisted_extensions().Contains(good0));
3463 EXPECT_TRUE(ValidateBooleanPref(good0, kPrefBlocklist, true));
3464 EXPECT_FALSE(IsPrefExist(good1, kPrefBlocklist));
3465 }
3466 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3467
3468 #if defined(ENABLE_BLOCKLIST_TESTS)
3469 // Tests trying to install a blocklisted extension.
TEST_F(ExtensionServiceTest,BlocklistedExtensionWillNotInstall)3470 TEST_F(ExtensionServiceTest, BlocklistedExtensionWillNotInstall) {
3471 scoped_refptr<FakeSafeBrowsingDatabaseManager> blocklist_db(
3472 new FakeSafeBrowsingDatabaseManager(true));
3473 Blocklist::ScopedDatabaseManagerForTest scoped_blocklist_db(blocklist_db);
3474
3475 InitializeEmptyExtensionService();
3476 service()->Init();
3477
3478 // After blocklisting good_crx, we cannot install it.
3479 blocklist_db->SetUnsafe(good_crx).NotifyUpdate();
3480 content::RunAllTasksUntilIdle();
3481
3482 base::FilePath path = data_dir().AppendASCII("good.crx");
3483 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3484 // decide to install this silently. Somebody should fix these tests, all
3485 // 6,000 lines of them. Hah!
3486 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3487 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3488 }
3489 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3490
3491 #if defined(ENABLE_BLOCKLIST_TESTS)
3492 // Tests that previously blocklisted extension will be enabled if it is removed
3493 // from the blocklist. Also checks that all blocklisted preferences will be
3494 // cleared in that case.
TEST_F(ExtensionServiceTest,RemoveExtensionFromBlocklist)3495 TEST_F(ExtensionServiceTest, RemoveExtensionFromBlocklist) {
3496 TestBlocklist test_blocklist;
3497 // A profile with 3 extensions installed: good0, good1, and good2.
3498 InitializeGoodInstalledExtensionService();
3499 test_blocklist.Attach(service()->blocklist_);
3500 service()->Init();
3501
3502 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3503 TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile()),
3504 good0);
3505
3506 // Add the extension to the blocklist.
3507 test_blocklist.SetBlocklistState(good0, BLOCKLISTED_MALWARE, true);
3508 observer.WaitForExtensionUnloaded();
3509
3510 // The extension should be disabled, both "blocklist" and "blocklist_state"
3511 // prefs should be set.
3512 auto* prefs = ExtensionPrefs::Get(profile());
3513 EXPECT_FALSE(registry()->enabled_extensions().Contains(good0));
3514 EXPECT_TRUE(prefs->IsExtensionBlocklisted(good0));
3515 EXPECT_EQ(BLOCKLISTED_MALWARE, prefs->GetExtensionBlocklistState(good0));
3516
3517 // Remove the extension from the blocklist.
3518 test_blocklist.SetBlocklistState(good0, NOT_BLOCKLISTED, true);
3519 observer.WaitForExtensionLoaded()->id();
3520
3521 // The extension should be enabled, both "blocklist" and "blocklist_state"
3522 // should be cleared.
3523 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3524 EXPECT_FALSE(prefs->IsExtensionBlocklisted(good0));
3525 EXPECT_EQ(NOT_BLOCKLISTED, prefs->GetExtensionBlocklistState(good0));
3526 }
3527 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3528
3529 #if defined(ENABLE_BLOCKLIST_TESTS)
3530 // Unload blocklisted extension on policy change.
TEST_F(ExtensionServiceTest,UnloadBlocklistedExtensionPolicy)3531 TEST_F(ExtensionServiceTest, UnloadBlocklistedExtensionPolicy) {
3532 TestBlocklist test_blocklist;
3533
3534 // A profile with no extensions installed.
3535 InitializeEmptyExtensionServiceWithTestingPrefs();
3536 test_blocklist.Attach(service()->blocklist_);
3537
3538 base::FilePath path = data_dir().AppendASCII("good.crx");
3539
3540 const Extension* good = InstallCRX(path, INSTALL_NEW);
3541 EXPECT_EQ(good_crx, good->id());
3542 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3543 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3544
3545 {
3546 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3547 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3548 }
3549
3550 test_blocklist.SetBlocklistState(good_crx, BLOCKLISTED_MALWARE, true);
3551 content::RunAllTasksUntilIdle();
3552
3553 // The good_crx is blocklisted and the allowlist doesn't negate it.
3554 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefBlocklist, true));
3555 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3556 }
3557 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3558
3559 #if defined(ENABLE_BLOCKLIST_TESTS)
3560 // Tests that a blocklisted extension is eventually unloaded on startup, if it
3561 // wasn't already.
TEST_F(ExtensionServiceTest,WillNotLoadBlocklistedExtensionsFromDirectory)3562 TEST_F(ExtensionServiceTest, WillNotLoadBlocklistedExtensionsFromDirectory) {
3563 TestBlocklist test_blocklist;
3564
3565 // A profile with 3 extensions installed: good0, good1, and good2.
3566 InitializeGoodInstalledExtensionService();
3567 test_blocklist.Attach(service()->blocklist_);
3568
3569 // Blocklist good1 before the service initializes.
3570 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_MALWARE, false);
3571
3572 // Load extensions.
3573 service()->Init();
3574 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blocklist yet
3575
3576 content::RunAllTasksUntilIdle();
3577
3578 ASSERT_EQ(1u, registry()->blocklisted_extensions().size());
3579 ASSERT_EQ(2u, registry()->enabled_extensions().size());
3580
3581 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3582 ASSERT_TRUE(registry()->blocklisted_extensions().Contains(good1));
3583 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2));
3584 }
3585 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3586
3587 #if defined(ENABLE_BLOCKLIST_TESTS)
3588 // Tests extensions blocklisted in prefs on startup; one still blocklisted by
3589 // safe browsing, the other not. The not-blocklisted one should recover.
TEST_F(ExtensionServiceTest,BlocklistedInPrefsFromStartup)3590 TEST_F(ExtensionServiceTest, BlocklistedInPrefsFromStartup) {
3591 TestBlocklist test_blocklist;
3592
3593 InitializeGoodInstalledExtensionService();
3594 test_blocklist.Attach(service()->blocklist_);
3595 ExtensionPrefs::Get(profile())->SetExtensionBlocklistState(
3596 good0, BLOCKLISTED_MALWARE);
3597 ExtensionPrefs::Get(profile())->SetExtensionBlocklistState(
3598 good1, BLOCKLISTED_MALWARE);
3599
3600 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_MALWARE, false);
3601
3602 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of
3603 // prefs. Ensure it takes into account the blocklist state (crbug.com/373842).
3604 EXPECT_FALSE(service()->IsExtensionEnabled(good0));
3605 EXPECT_FALSE(service()->IsExtensionEnabled(good1));
3606 EXPECT_TRUE(service()->IsExtensionEnabled(good2));
3607
3608 service()->Init();
3609
3610 EXPECT_EQ(2u, registry()->blocklisted_extensions().size());
3611 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3612
3613 EXPECT_TRUE(registry()->blocklisted_extensions().Contains(good0));
3614 EXPECT_TRUE(registry()->blocklisted_extensions().Contains(good1));
3615 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3616
3617 // Give time for the blocklist to update.
3618 content::RunAllTasksUntilIdle();
3619
3620 EXPECT_EQ(1u, registry()->blocklisted_extensions().size());
3621 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3622
3623 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3624 EXPECT_TRUE(registry()->blocklisted_extensions().Contains(good1));
3625 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3626 }
3627 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3628
3629 #if defined(ENABLE_BLOCKLIST_TESTS)
3630 // Extension is added to blocklist with BLOCKLISTED_POTENTIALLY_UNWANTED state
3631 // after it is installed. It is then successfully re-enabled by the user.
TEST_F(ExtensionServiceTest,GreylistedExtensionDisabled)3632 TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
3633 TestBlocklist test_blocklist;
3634 // A profile with 3 extensions installed: good0, good1, and good2.
3635 InitializeGoodInstalledExtensionService();
3636 test_blocklist.Attach(service()->blocklist_);
3637 service()->Init();
3638
3639 const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
3640 const ExtensionSet& disabled_extensions = registry()->disabled_extensions();
3641
3642 EXPECT_TRUE(enabled_extensions.Contains(good0));
3643 EXPECT_TRUE(enabled_extensions.Contains(good1));
3644 EXPECT_TRUE(enabled_extensions.Contains(good2));
3645
3646 // Blocklist good0 and good1 (and an invalid extension ID).
3647 test_blocklist.SetBlocklistState(good0, BLOCKLISTED_CWS_POLICY_VIOLATION,
3648 true);
3649 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_POTENTIALLY_UNWANTED,
3650 true);
3651 test_blocklist.SetBlocklistState("invalid_id", BLOCKLISTED_MALWARE, true);
3652 content::RunAllTasksUntilIdle();
3653
3654 EXPECT_FALSE(enabled_extensions.Contains(good0));
3655 EXPECT_TRUE(disabled_extensions.Contains(good0));
3656 EXPECT_FALSE(enabled_extensions.Contains(good1));
3657 EXPECT_TRUE(disabled_extensions.Contains(good1));
3658 EXPECT_TRUE(enabled_extensions.Contains(good2));
3659 EXPECT_FALSE(disabled_extensions.Contains(good2));
3660
3661 ValidateIntegerPref(good0, "blacklist_state",
3662 BLOCKLISTED_CWS_POLICY_VIOLATION);
3663 ValidateIntegerPref(good1, "blacklist_state",
3664 BLOCKLISTED_POTENTIALLY_UNWANTED);
3665
3666 // Now user enables good0.
3667 service()->EnableExtension(good0);
3668
3669 EXPECT_TRUE(enabled_extensions.Contains(good0));
3670 EXPECT_FALSE(disabled_extensions.Contains(good0));
3671 EXPECT_FALSE(enabled_extensions.Contains(good1));
3672 EXPECT_TRUE(disabled_extensions.Contains(good1));
3673
3674 // Remove extensions from blocklist.
3675 test_blocklist.SetBlocklistState(good0, NOT_BLOCKLISTED, true);
3676 test_blocklist.SetBlocklistState(good1, NOT_BLOCKLISTED, true);
3677 content::RunAllTasksUntilIdle();
3678
3679 // All extensions are enabled.
3680 EXPECT_TRUE(enabled_extensions.Contains(good0));
3681 EXPECT_FALSE(disabled_extensions.Contains(good0));
3682 EXPECT_TRUE(enabled_extensions.Contains(good1));
3683 EXPECT_FALSE(disabled_extensions.Contains(good1));
3684 EXPECT_TRUE(enabled_extensions.Contains(good2));
3685 EXPECT_FALSE(disabled_extensions.Contains(good2));
3686 }
3687 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3688
3689 #if defined(ENABLE_BLOCKLIST_TESTS)
3690 // When extension is removed from greylist, do not re-enable it if it is
3691 // disabled by user.
TEST_F(ExtensionServiceTest,GreylistDontEnableManuallyDisabled)3692 TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
3693 TestBlocklist test_blocklist;
3694 // A profile with 3 extensions installed: good0, good1, and good2.
3695 InitializeGoodInstalledExtensionService();
3696 test_blocklist.Attach(service()->blocklist_);
3697 service()->Init();
3698
3699 const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
3700 const ExtensionSet& disabled_extensions = registry()->disabled_extensions();
3701
3702 // Manually disable.
3703 service()->DisableExtension(good0, disable_reason::DISABLE_USER_ACTION);
3704
3705 test_blocklist.SetBlocklistState(good0, BLOCKLISTED_CWS_POLICY_VIOLATION,
3706 true);
3707 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_POTENTIALLY_UNWANTED,
3708 true);
3709 test_blocklist.SetBlocklistState(good2, BLOCKLISTED_SECURITY_VULNERABILITY,
3710 true);
3711 content::RunAllTasksUntilIdle();
3712
3713 // All extensions disabled.
3714 EXPECT_FALSE(enabled_extensions.Contains(good0));
3715 EXPECT_TRUE(disabled_extensions.Contains(good0));
3716 EXPECT_FALSE(enabled_extensions.Contains(good1));
3717 EXPECT_TRUE(disabled_extensions.Contains(good1));
3718 EXPECT_FALSE(enabled_extensions.Contains(good2));
3719 EXPECT_TRUE(disabled_extensions.Contains(good2));
3720
3721 // Greylisted extension can be enabled.
3722 service()->EnableExtension(good1);
3723 EXPECT_TRUE(enabled_extensions.Contains(good1));
3724 EXPECT_FALSE(disabled_extensions.Contains(good1));
3725
3726 // good1 is now manually disabled.
3727 service()->DisableExtension(good1, disable_reason::DISABLE_USER_ACTION);
3728 EXPECT_FALSE(enabled_extensions.Contains(good1));
3729 EXPECT_TRUE(disabled_extensions.Contains(good1));
3730
3731 // Remove extensions from blocklist.
3732 test_blocklist.SetBlocklistState(good0, NOT_BLOCKLISTED, true);
3733 test_blocklist.SetBlocklistState(good1, NOT_BLOCKLISTED, true);
3734 test_blocklist.SetBlocklistState(good2, NOT_BLOCKLISTED, true);
3735 content::RunAllTasksUntilIdle();
3736
3737 // good0 and good1 remain disabled.
3738 EXPECT_FALSE(enabled_extensions.Contains(good0));
3739 EXPECT_TRUE(disabled_extensions.Contains(good0));
3740 EXPECT_FALSE(enabled_extensions.Contains(good1));
3741 EXPECT_TRUE(disabled_extensions.Contains(good1));
3742 EXPECT_TRUE(enabled_extensions.Contains(good2));
3743 EXPECT_FALSE(disabled_extensions.Contains(good2));
3744 }
3745 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3746
3747 #if defined(ENABLE_BLOCKLIST_TESTS)
3748 // Blocklisted extension with unknown state are not enabled/disabled.
TEST_F(ExtensionServiceTest,GreylistUnknownDontChange)3749 TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
3750 TestBlocklist test_blocklist;
3751 // A profile with 3 extensions installed: good0, good1, and good2.
3752 InitializeGoodInstalledExtensionService();
3753 test_blocklist.Attach(service()->blocklist_);
3754 service()->Init();
3755
3756 const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
3757 const ExtensionSet& disabled_extensions = registry()->disabled_extensions();
3758
3759 test_blocklist.SetBlocklistState(good0, BLOCKLISTED_CWS_POLICY_VIOLATION,
3760 true);
3761 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_POTENTIALLY_UNWANTED,
3762 true);
3763 content::RunAllTasksUntilIdle();
3764
3765 EXPECT_FALSE(enabled_extensions.Contains(good0));
3766 EXPECT_TRUE(disabled_extensions.Contains(good0));
3767 EXPECT_FALSE(enabled_extensions.Contains(good1));
3768 EXPECT_TRUE(disabled_extensions.Contains(good1));
3769 EXPECT_TRUE(enabled_extensions.Contains(good2));
3770 EXPECT_FALSE(disabled_extensions.Contains(good2));
3771
3772 test_blocklist.SetBlocklistState(good0, NOT_BLOCKLISTED, true);
3773 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_UNKNOWN, true);
3774 test_blocklist.SetBlocklistState(good2, BLOCKLISTED_UNKNOWN, true);
3775 content::RunAllTasksUntilIdle();
3776
3777 // good0 re-enabled, other remain as they were.
3778 EXPECT_TRUE(enabled_extensions.Contains(good0));
3779 EXPECT_FALSE(disabled_extensions.Contains(good0));
3780 EXPECT_FALSE(enabled_extensions.Contains(good1));
3781 EXPECT_TRUE(disabled_extensions.Contains(good1));
3782 EXPECT_TRUE(enabled_extensions.Contains(good2));
3783 EXPECT_FALSE(disabled_extensions.Contains(good2));
3784 }
3785
3786 // Tests that blocklisted extensions cannot be reloaded, both those loaded
3787 // before and after extension service startup.
TEST_F(ExtensionServiceTest,ReloadBlocklistedExtension)3788 TEST_F(ExtensionServiceTest, ReloadBlocklistedExtension) {
3789 TestBlocklist test_blocklist;
3790
3791 InitializeGoodInstalledExtensionService();
3792 test_blocklist.Attach(service()->blocklist_);
3793
3794 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_MALWARE, false);
3795 service()->Init();
3796 test_blocklist.SetBlocklistState(good2, BLOCKLISTED_MALWARE, false);
3797 content::RunAllTasksUntilIdle();
3798
3799 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3800 EXPECT_EQ(StringSet(good1, good2),
3801 registry()->blocklisted_extensions().GetIDs());
3802
3803 service()->ReloadExtension(good1);
3804 service()->ReloadExtension(good2);
3805 content::RunAllTasksUntilIdle();
3806
3807 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3808 EXPECT_EQ(StringSet(good1, good2),
3809 registry()->blocklisted_extensions().GetIDs());
3810 }
3811 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3812
3813 // Tests blocking then unblocking enabled extensions after the service has been
3814 // initialized.
TEST_F(ExtensionServiceTest,BlockAndUnblockEnabledExtension)3815 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledExtension) {
3816 InitializeGoodInstalledExtensionService();
3817 service()->Init();
3818
3819 AssertExtensionBlocksAndUnblocks(true, good0);
3820 }
3821
3822 // Tests blocking then unblocking disabled extensions after the service has been
3823 // initialized.
TEST_F(ExtensionServiceTest,BlockAndUnblockDisabledExtension)3824 TEST_F(ExtensionServiceTest, BlockAndUnblockDisabledExtension) {
3825 InitializeGoodInstalledExtensionService();
3826 service()->Init();
3827
3828 service()->DisableExtension(good0, disable_reason::DISABLE_RELOAD);
3829
3830 AssertExtensionBlocksAndUnblocks(true, good0);
3831 }
3832
3833 // Tests blocking then unblocking terminated extensions after the service has
3834 // been initialized.
TEST_F(ExtensionServiceTest,BlockAndUnblockTerminatedExtension)3835 TEST_F(ExtensionServiceTest, BlockAndUnblockTerminatedExtension) {
3836 InitializeGoodInstalledExtensionService();
3837 service()->Init();
3838
3839 TerminateExtension(good0);
3840
3841 AssertExtensionBlocksAndUnblocks(true, good0);
3842 }
3843
3844 // Tests blocking then unblocking policy-forced extensions after the service has
3845 // been initialized.
TEST_F(ExtensionServiceTest,BlockAndUnblockPolicyExtension)3846 TEST_F(ExtensionServiceTest, BlockAndUnblockPolicyExtension) {
3847 InitializeEmptyExtensionServiceWithTestingPrefs();
3848
3849 {
3850 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3851 // // Blocklist everything.
3852 // pref.SetBlocklistedByDefault(true);
3853 // Mark good.crx for force-installation.
3854 pref.SetIndividualExtensionAutoInstalled(
3855 good_crx, "http://example.com/update_url", true);
3856 }
3857
3858 // Have policy force-install an extension.
3859 MockExternalProvider* provider =
3860 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
3861 provider->UpdateOrAddExtension(
3862 good_crx, "1.0.0.0", data_dir().AppendASCII("good_crx"));
3863
3864 // Reloading extensions should find our externally registered extension
3865 // and install it.
3866 WaitForExternalExtensionInstalled();
3867
3868 AssertExtensionBlocksAndUnblocks(false, good_crx);
3869 }
3870
3871 #if defined(ENABLE_BLOCKLIST_TESTS)
3872 // Tests blocking then unblocking extensions that are blocklisted both before
3873 // and after Init().
TEST_F(ExtensionServiceTest,BlockAndUnblockBlocklistedExtension)3874 TEST_F(ExtensionServiceTest, BlockAndUnblockBlocklistedExtension) {
3875 TestBlocklist test_blocklist;
3876
3877 InitializeGoodInstalledExtensionService();
3878 test_blocklist.Attach(service()->blocklist_);
3879
3880 test_blocklist.SetBlocklistState(good0, BLOCKLISTED_MALWARE, true);
3881 content::RunAllTasksUntilIdle();
3882
3883 service()->Init();
3884
3885 test_blocklist.SetBlocklistState(good1, BLOCKLISTED_MALWARE, true);
3886 content::RunAllTasksUntilIdle();
3887
3888 // Blocklisted extensions stay blocklisted.
3889 AssertExtensionBlocksAndUnblocks(false, good0);
3890 AssertExtensionBlocksAndUnblocks(false, good1);
3891
3892 service()->BlockAllExtensions();
3893
3894 // Remove an extension from the blocklist while the service is blocked.
3895 test_blocklist.SetBlocklistState(good0, NOT_BLOCKLISTED, true);
3896 // Add an extension to the blocklist while the service is blocked.
3897 test_blocklist.SetBlocklistState(good2, BLOCKLISTED_MALWARE, true);
3898 content::RunAllTasksUntilIdle();
3899
3900 // Go directly to blocked, do not pass go, do not collect $200.
3901 ASSERT_TRUE(IsBlocked(good0));
3902 // Get on the blocklist - even if you were blocked!
3903 ASSERT_FALSE(IsBlocked(good2));
3904 }
3905 #endif // defined(ENABLE_BLOCKLIST_TESTS)
3906
3907 // Tests blocking then unblocking enabled component extensions after the service
3908 // has been initialized.
TEST_F(ExtensionServiceTest,BlockAndUnblockEnabledComponentExtension)3909 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledComponentExtension) {
3910 InitializeEmptyExtensionServiceWithTestingPrefs();
3911
3912 // Install a component extension.
3913 base::FilePath path = data_dir()
3914 .AppendASCII("good")
3915 .AppendASCII("Extensions")
3916 .AppendASCII(good0)
3917 .AppendASCII("1.0.0.0");
3918 std::string manifest;
3919 ASSERT_TRUE(
3920 base::ReadFileToString(path.Append(kManifestFilename), &manifest));
3921 service()->component_loader()->Add(manifest, path);
3922 service()->Init();
3923
3924 // Component extension should never block.
3925 AssertExtensionBlocksAndUnblocks(false, good0);
3926 }
3927
3928 // Tests blocking then unblocking a theme after the service has been
3929 // initialized.
TEST_F(ExtensionServiceTest,BlockAndUnblockTheme)3930 TEST_F(ExtensionServiceTest, BlockAndUnblockTheme) {
3931 InitializeEmptyExtensionService();
3932 service()->Init();
3933
3934 base::FilePath path = data_dir().AppendASCII("theme.crx");
3935 InstallCRX(path, INSTALL_NEW);
3936
3937 AssertExtensionBlocksAndUnblocks(true, theme_crx);
3938 }
3939
3940 // Tests that blocking extensions before Init() results in loading blocked
3941 // extensions.
TEST_F(ExtensionServiceTest,WillNotLoadExtensionsWhenBlocked)3942 TEST_F(ExtensionServiceTest, WillNotLoadExtensionsWhenBlocked) {
3943 InitializeGoodInstalledExtensionService();
3944
3945 service()->BlockAllExtensions();
3946
3947 service()->Init();
3948
3949 ASSERT_TRUE(IsBlocked(good0));
3950 ASSERT_TRUE(IsBlocked(good0));
3951 ASSERT_TRUE(IsBlocked(good0));
3952 }
3953
3954 // Tests that IsEnabledExtension won't crash on an uninstalled extension.
TEST_F(ExtensionServiceTest,IsEnabledExtensionBlockedAndNotInstalled)3955 TEST_F(ExtensionServiceTest, IsEnabledExtensionBlockedAndNotInstalled) {
3956 InitializeEmptyExtensionService();
3957
3958 service()->BlockAllExtensions();
3959
3960 service()->IsExtensionEnabled(theme_crx);
3961 }
3962
3963 // Will not install extension blocklisted by policy.
TEST_F(ExtensionServiceTest,BlocklistedByPolicyWillNotInstall)3964 TEST_F(ExtensionServiceTest, BlocklistedByPolicyWillNotInstall) {
3965 InitializeEmptyExtensionServiceWithTestingPrefs();
3966
3967 // Blocklist everything.
3968 {
3969 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3970 pref.SetBlocklistedByDefault(true);
3971 }
3972
3973 // Blocklist prevents us from installing good_crx.
3974 base::FilePath path = data_dir().AppendASCII("good.crx");
3975 InstallCRX(path, INSTALL_FAILED);
3976 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3977
3978 // Now allowlist this particular extension.
3979 {
3980 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3981 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3982 }
3983
3984 // Ensure we can now install good_crx.
3985 InstallCRX(path, INSTALL_NEW);
3986 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3987 }
3988
3989 // Extension blocklisted by policy get unloaded after installing.
TEST_F(ExtensionServiceTest,BlocklistedByPolicyRemovedIfRunning)3990 TEST_F(ExtensionServiceTest, BlocklistedByPolicyRemovedIfRunning) {
3991 InitializeEmptyExtensionServiceWithTestingPrefs();
3992
3993 // Install good_crx.
3994 base::FilePath path = data_dir().AppendASCII("good.crx");
3995 InstallCRX(path, INSTALL_NEW);
3996 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3997
3998 {
3999 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4000 // Blocklist this extension.
4001 pref.SetIndividualExtensionInstallationAllowed(good_crx, false);
4002 }
4003
4004 // Extension should not be running now.
4005 content::RunAllTasksUntilIdle();
4006 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4007 }
4008
4009 // Tests that component extensions are not blocklisted by policy.
TEST_F(ExtensionServiceTest,ComponentExtensionAllowlisted)4010 TEST_F(ExtensionServiceTest, ComponentExtensionAllowlisted) {
4011 InitializeEmptyExtensionServiceWithTestingPrefs();
4012
4013 // Blocklist everything.
4014 {
4015 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4016 pref.SetBlocklistedByDefault(true);
4017 }
4018
4019 // Install a component extension.
4020 base::FilePath path = data_dir()
4021 .AppendASCII("good")
4022 .AppendASCII("Extensions")
4023 .AppendASCII(good0)
4024 .AppendASCII("1.0.0.0");
4025 std::string manifest;
4026 ASSERT_TRUE(
4027 base::ReadFileToString(path.Append(kManifestFilename), &manifest));
4028 service()->component_loader()->Add(manifest, path);
4029 service()->Init();
4030
4031 // Extension should be installed despite blocklist.
4032 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4033 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good0));
4034
4035 // Poke external providers and make sure the extension is still present.
4036 service()->CheckForExternalUpdates();
4037 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4038 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good0));
4039
4040 // Extension should not be uninstalled on blocklist changes.
4041 {
4042 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4043 pref.SetIndividualExtensionInstallationAllowed(good0, false);
4044 }
4045 content::RunAllTasksUntilIdle();
4046 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4047 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good0));
4048 }
4049
4050 // Tests that active permissions are not revoked from component extensions
4051 // by policy when the policy is updated. https://crbug.com/746017.
TEST_F(ExtensionServiceTest,ComponentExtensionAllowlistedPermission)4052 TEST_F(ExtensionServiceTest, ComponentExtensionAllowlistedPermission) {
4053 InitializeEmptyExtensionServiceWithTestingPrefs();
4054
4055 // Install a component extension.
4056 base::FilePath path = data_dir()
4057 .AppendASCII("good")
4058 .AppendASCII("Extensions")
4059 .AppendASCII(good0)
4060 .AppendASCII("1.0.0.0");
4061 std::string manifest;
4062 ASSERT_TRUE(
4063 base::ReadFileToString(path.Append(kManifestFilename), &manifest));
4064 service()->component_loader()->Add(manifest, path);
4065 service()->Init();
4066
4067 // Extension should have the "tabs" permission.
4068 EXPECT_TRUE(registry()
4069 ->enabled_extensions()
4070 .GetByID(good0)
4071 ->permissions_data()
4072 ->active_permissions()
4073 .HasAPIPermission(APIPermission::kTab));
4074
4075 // Component should not lose permissions on policy change.
4076 {
4077 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4078 pref.AddBlockedPermission(good0, "tabs");
4079 }
4080
4081 service()->OnExtensionManagementSettingsChanged();
4082 content::RunAllTasksUntilIdle();
4083 EXPECT_TRUE(registry()
4084 ->enabled_extensions()
4085 .GetByID(good0)
4086 ->permissions_data()
4087 ->active_permissions()
4088 .HasAPIPermission(APIPermission::kTab));
4089 }
4090
4091 // Tests that policy-installed extensions are not blocklisted by policy.
TEST_F(ExtensionServiceTest,PolicyInstalledExtensionsAllowlisted)4092 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsAllowlisted) {
4093 InitializeEmptyExtensionServiceWithTestingPrefs();
4094
4095 {
4096 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4097 // Blocklist everything.
4098 pref.SetBlocklistedByDefault(true);
4099 // Mark good.crx for force-installation.
4100 pref.SetIndividualExtensionAutoInstalled(
4101 good_crx, "http://example.com/update_url", true);
4102 }
4103
4104 // Have policy force-install an extension.
4105 MockExternalProvider* provider =
4106 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
4107 provider->UpdateOrAddExtension(
4108 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
4109
4110 // Reloading extensions should find our externally registered extension
4111 // and install it.
4112 WaitForExternalExtensionInstalled();
4113
4114 // Extension should be installed despite blocklist.
4115 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4116 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4117
4118 // Blocklist update should not uninstall the extension.
4119 {
4120 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4121 pref.SetIndividualExtensionInstallationAllowed(good0, false);
4122 }
4123 content::RunAllTasksUntilIdle();
4124 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4125 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4126 }
4127
4128 // Tests that extensions cannot be installed if the policy provider prohibits
4129 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsInstall)4130 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
4131 InitializeEmptyExtensionService();
4132
4133 GetManagementPolicy()->UnregisterAllProviders();
4134 TestManagementPolicyProvider provider_(
4135 TestManagementPolicyProvider::PROHIBIT_LOAD);
4136 GetManagementPolicy()->RegisterProvider(&provider_);
4137
4138 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED);
4139 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4140 }
4141
4142 // Tests that extensions cannot be loaded from prefs if the policy provider
4143 // prohibits it. This functionality is implemented in InstalledLoader::Load().
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsLoadFromPrefs)4144 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
4145 InitializeEmptyExtensionService();
4146
4147 // Create a fake extension to be loaded as though it were read from prefs.
4148 base::FilePath path =
4149 data_dir().AppendASCII("management").AppendASCII("simple_extension");
4150 base::DictionaryValue manifest;
4151 manifest.SetString(keys::kName, "simple_extension");
4152 manifest.SetString(keys::kVersion, "1");
4153 manifest.SetInteger(keys::kManifestVersion, 2);
4154 // UNPACKED is for extensions loaded from a directory. We use it here, even
4155 // though we're testing loading from prefs, so that we don't need to provide
4156 // an extension key.
4157 ExtensionInfo extension_info(&manifest, std::string(), path,
4158 Manifest::UNPACKED);
4159
4160 // Ensure we can load it with no management policy in place.
4161 GetManagementPolicy()->UnregisterAllProviders();
4162 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4163 InstalledLoader(service()).Load(extension_info, false);
4164 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4165
4166 const Extension* extension =
4167 (registry()->enabled_extensions().begin())->get();
4168 EXPECT_TRUE(service()->UninstallExtension(
4169 extension->id(), UNINSTALL_REASON_FOR_TESTING, nullptr));
4170 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4171
4172 // Ensure we cannot load it if management policy prohibits installation.
4173 TestManagementPolicyProvider provider_(
4174 TestManagementPolicyProvider::PROHIBIT_LOAD);
4175 GetManagementPolicy()->RegisterProvider(&provider_);
4176
4177 InstalledLoader(service()).Load(extension_info, false);
4178 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4179 }
4180
4181 // Tests disabling an extension when prohibited by the ManagementPolicy.
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsDisable)4182 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
4183 InitializeEmptyExtensionService();
4184
4185 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4186 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4187 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4188
4189 GetManagementPolicy()->UnregisterAllProviders();
4190 TestManagementPolicyProvider provider(
4191 TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
4192 GetManagementPolicy()->RegisterProvider(&provider);
4193
4194 // Attempt to disable it.
4195 service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION);
4196
4197 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4198 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4199 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4200 EXPECT_EQ(disable_reason::DISABLE_NONE,
4201 ExtensionPrefs::Get(profile())->GetDisableReasons(good_crx));
4202
4203 // Internal disable reasons are allowed.
4204 service()->DisableExtension(
4205 good_crx,
4206 disable_reason::DISABLE_CORRUPTED | disable_reason::DISABLE_USER_ACTION);
4207
4208 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4209 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4210 EXPECT_TRUE(registry()->disabled_extensions().GetByID(good_crx));
4211 EXPECT_FALSE(registry()->enabled_extensions().GetByID(good_crx));
4212 EXPECT_EQ(disable_reason::DISABLE_CORRUPTED,
4213 ExtensionPrefs::Get(profile())->GetDisableReasons(good_crx));
4214 }
4215
4216 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsUninstall)4217 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
4218 InitializeEmptyExtensionService();
4219
4220 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4221 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4222 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4223
4224 GetManagementPolicy()->UnregisterAllProviders();
4225 TestManagementPolicyProvider provider(
4226 TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
4227 GetManagementPolicy()->RegisterProvider(&provider);
4228
4229 // Attempt to uninstall it.
4230 EXPECT_FALSE(service()->UninstallExtension(
4231 good_crx, UNINSTALL_REASON_FOR_TESTING, nullptr));
4232
4233 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4234 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4235 }
4236
4237 // Tests that previously installed extensions that are now prohibited from
4238 // being installed are disabled.
TEST_F(ExtensionServiceTest,ManagementPolicyUnloadsAllProhibited)4239 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
4240 InitializeEmptyExtensionService();
4241
4242 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4243 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
4244 EXPECT_EQ(2u, registry()->enabled_extensions().size());
4245 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4246
4247 GetManagementPolicy()->UnregisterAllProviders();
4248 TestManagementPolicyProvider provider(
4249 TestManagementPolicyProvider::PROHIBIT_LOAD);
4250 GetManagementPolicy()->RegisterProvider(&provider);
4251
4252 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4253
4254 // Run the policy check.
4255 service()->CheckManagementPolicy();
4256 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4257 EXPECT_EQ(2u, registry()->disabled_extensions().size());
4258 EXPECT_EQ(disable_reason::DISABLE_BLOCKED_BY_POLICY,
4259 prefs->GetDisableReasons(good_crx));
4260 EXPECT_EQ(disable_reason::DISABLE_BLOCKED_BY_POLICY,
4261 prefs->GetDisableReasons(page_action));
4262
4263 // Removing the extensions from policy blocklist should re-enable them.
4264 GetManagementPolicy()->UnregisterAllProviders();
4265 service()->CheckManagementPolicy();
4266 EXPECT_EQ(2u, registry()->enabled_extensions().size());
4267 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4268 }
4269
4270 // Tests that previously disabled extensions that are now required to be
4271 // enabled are re-enabled on reinstall.
TEST_F(ExtensionServiceTest,ManagementPolicyRequiresEnable)4272 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
4273 InitializeEmptyExtensionService();
4274
4275 // Install, then disable, an extension.
4276 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4277 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4278 service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION);
4279 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4280
4281 // Register an ExtensionManagementPolicy that requires the extension to remain
4282 // enabled.
4283 GetManagementPolicy()->UnregisterAllProviders();
4284 TestManagementPolicyProvider provider(
4285 TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
4286 GetManagementPolicy()->RegisterProvider(&provider);
4287
4288 // Reinstall the extension.
4289 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED);
4290 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4291 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4292 }
4293
4294 // Tests that extensions disabled by management policy can be installed but
4295 // will get disabled after installing.
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsEnableOnInstalled)4296 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsEnableOnInstalled) {
4297 InitializeEmptyExtensionService();
4298
4299 // Register an ExtensionManagementPolicy that disables all extensions, with
4300 // a specified disable_reason::DisableReason.
4301 GetManagementPolicy()->UnregisterAllProviders();
4302 TestManagementPolicyProvider provider(
4303 TestManagementPolicyProvider::MUST_REMAIN_DISABLED);
4304 provider.SetDisableReason(disable_reason::DISABLE_NOT_VERIFIED);
4305 GetManagementPolicy()->RegisterProvider(&provider);
4306
4307 // Attempts to install an extensions, it should be installed but disabled.
4308 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4309 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4310 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_WITHOUT_LOAD);
4311 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4312 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4313
4314 // Verifies that the disable reason is set properly.
4315 EXPECT_EQ(disable_reason::DISABLE_NOT_VERIFIED,
4316 service()->extension_prefs_->GetDisableReasons(kGoodId));
4317 }
4318
4319 // Tests that extensions with conflicting required permissions by enterprise
4320 // policy cannot be installed.
TEST_F(ExtensionServiceTest,PolicyBlockedPermissionNewExtensionInstall)4321 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionNewExtensionInstall) {
4322 InitializeEmptyExtensionServiceWithTestingPrefs();
4323 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4324
4325 {
4326 // Update policy to block one of the required permissions of target.
4327 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4328 pref.AddBlockedPermission("*", "tabs");
4329 }
4330
4331 // The extension should be failed to install.
4332 PackAndInstallCRX(path, INSTALL_FAILED);
4333
4334 {
4335 // Update policy to block one of the optional permissions instead.
4336 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4337 pref.ClearBlockedPermissions("*");
4338 pref.AddBlockedPermission("*", "history");
4339 }
4340
4341 // The extension should succeed to install this time.
4342 std::string id = PackAndInstallCRX(path, INSTALL_NEW)->id();
4343
4344 // Uninstall the extension and update policy to block some arbitrary
4345 // unknown permission.
4346 UninstallExtension(id);
4347 {
4348 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4349 pref.ClearBlockedPermissions("*");
4350 pref.AddBlockedPermission("*", "unknown.permission.for.testing");
4351 }
4352
4353 // The extension should succeed to install as well.
4354 PackAndInstallCRX(path, INSTALL_NEW);
4355 }
4356
4357 // Tests that extension supposed to be force installed but with conflicting
4358 // required permissions cannot be installed.
TEST_F(ExtensionServiceTest,PolicyBlockedPermissionConflictsWithForceInstall)4359 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionConflictsWithForceInstall) {
4360 InitializeEmptyExtensionServiceWithTestingPrefs();
4361
4362 // Pack the crx file.
4363 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4364 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4365 base::ScopedTempDir temp_dir;
4366 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4367 base::FilePath crx_path = temp_dir.GetPath().AppendASCII("temp.crx");
4368
4369 PackCRX(path, pem_path, crx_path);
4370
4371 {
4372 // Block one of the required permissions.
4373 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4374 pref.AddBlockedPermission("*", "tabs");
4375 }
4376
4377 // Use MockExternalProvider to simulate force installing extension.
4378 MockExternalProvider* provider =
4379 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
4380 provider->UpdateOrAddExtension(permissions_blocklist, "1.0", crx_path);
4381
4382 // Attempts to force install this extension.
4383 WaitForExternalExtensionInstalled();
4384
4385 // The extension should not be installed.
4386 ASSERT_FALSE(registry()->GetInstalledExtension(permissions_blocklist));
4387
4388 // Remove this extension from pending extension manager as we would like to
4389 // give another attempt later.
4390 service()->pending_extension_manager()->Remove(permissions_blocklist);
4391
4392 {
4393 // Clears the permission block list.
4394 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4395 pref.ClearBlockedPermissions("*");
4396 }
4397
4398 // Attempts to force install this extension again.
4399 WaitForExternalExtensionInstalled();
4400
4401 const Extension* installed =
4402 registry()->GetInstalledExtension(permissions_blocklist);
4403 ASSERT_TRUE(installed);
4404 EXPECT_EQ(installed->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4405 }
4406
4407 // Tests that newer versions of an extension with conflicting required
4408 // permissions by enterprise policy cannot be updated to.
TEST_F(ExtensionServiceTest,PolicyBlockedPermissionExtensionUpdate)4409 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionExtensionUpdate) {
4410 InitializeEmptyExtensionServiceWithTestingPrefs();
4411
4412 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4413 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4414 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4415
4416 // Install 'permissions_blocklist'.
4417 const Extension* installed = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
4418 EXPECT_EQ(installed->id(), permissions_blocklist);
4419
4420 {
4421 // Block one of the required permissions of 'permissions_blocklist2'.
4422 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4423 pref.AddBlockedPermission("*", "downloads");
4424 }
4425
4426 // Install 'permissions_blocklist' again, should be updated.
4427 const Extension* updated = PackAndInstallCRX(path, pem_path, INSTALL_UPDATED);
4428 EXPECT_EQ(updated->id(), permissions_blocklist);
4429
4430 std::string old_version = updated->VersionString();
4431
4432 // Attempts to update to 'permissions_blocklist2' should fail.
4433 PackAndInstallCRX(path2, pem_path, INSTALL_FAILED);
4434
4435 // Verify that the old version is still enabled.
4436 updated = registry()->enabled_extensions().GetByID(permissions_blocklist);
4437 ASSERT_TRUE(updated);
4438 EXPECT_EQ(old_version, updated->VersionString());
4439 }
4440
4441 // Tests that policy update with additional permissions blocked revoke
4442 // conflicting granted optional permissions and unload extensions with
4443 // conflicting required permissions, including the force installed ones.
TEST_F(ExtensionServiceTest,PolicyBlockedPermissionPolicyUpdate)4444 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionPolicyUpdate) {
4445 InitializeEmptyExtensionServiceWithTestingPrefs();
4446
4447 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4448 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4449 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4450
4451 // Pack the crx file.
4452 base::ScopedTempDir temp_dir;
4453 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4454 base::FilePath crx_path = temp_dir.GetPath().AppendASCII("temp.crx");
4455
4456 PackCRX(path2, pem_path, crx_path);
4457
4458 // Install two arbitary extensions with specified manifest.
4459 std::string ext1 = PackAndInstallCRX(path, INSTALL_NEW)->id();
4460 std::string ext2 = PackAndInstallCRX(path2, INSTALL_NEW)->id();
4461 ASSERT_NE(ext1, permissions_blocklist);
4462 ASSERT_NE(ext2, permissions_blocklist);
4463 ASSERT_NE(ext1, ext2);
4464
4465 // Force install another extension with known id and same manifest as 'ext2'.
4466 std::string ext2_forced = permissions_blocklist;
4467 MockExternalProvider* provider =
4468 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
4469 provider->UpdateOrAddExtension(ext2_forced, "2.0", crx_path);
4470 WaitForExternalExtensionInstalled();
4471
4472 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
4473
4474 // Verify all three extensions are installed and enabled.
4475 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext1));
4476 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2));
4477 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2_forced));
4478
4479 // Grant all optional permissions to each extension.
4480 GrantAllOptionalPermissions(ext1);
4481 GrantAllOptionalPermissions(ext2);
4482 GrantAllOptionalPermissions(ext2_forced);
4483
4484 std::unique_ptr<const PermissionSet> active_permissions =
4485 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
4486 EXPECT_TRUE(active_permissions->HasAPIPermission(APIPermission::kDownloads));
4487
4488 // Set policy to block 'downloads' permission.
4489 {
4490 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4491 pref.AddBlockedPermission("*", "downloads");
4492 }
4493
4494 content::RunAllTasksUntilIdle();
4495
4496 // 'ext1' should still be enabled, but with 'downloads' permission revoked.
4497 EXPECT_TRUE(registry->enabled_extensions().GetByID(ext1));
4498 active_permissions =
4499 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
4500 EXPECT_FALSE(active_permissions->HasAPIPermission(APIPermission::kDownloads));
4501
4502 // 'ext2' should be disabled because one of its required permissions is
4503 // blocked.
4504 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2));
4505
4506 // 'ext2_forced' should be handled the same as 'ext2'
4507 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2_forced));
4508 }
4509
4510 // Flaky on windows; http://crbug.com/309833
4511 #if defined(OS_WIN)
4512 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
4513 #else
4514 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
4515 #endif
TEST_F(ExtensionServiceTest,MAYBE_ExternalExtensionAutoAcknowledgement)4516 TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
4517 InitializeEmptyExtensionService();
4518
4519 {
4520 // Register and install an external extension.
4521 MockExternalProvider* provider =
4522 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
4523 provider->UpdateOrAddExtension(
4524 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
4525 }
4526 {
4527 // Have policy force-install an extension.
4528 MockExternalProvider* provider =
4529 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
4530 provider->UpdateOrAddExtension(
4531 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
4532 }
4533
4534 // Providers are set up. Let them run.
4535 int count = 2;
4536 content::WindowedNotificationObserver observer(
4537 NOTIFICATION_CRX_INSTALLER_DONE,
4538 base::Bind(&WaitForCountNotificationsCallback, &count));
4539 service()->CheckForExternalUpdates();
4540
4541 observer.Wait();
4542
4543 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4544 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4545 EXPECT_TRUE(registry()->enabled_extensions().GetByID(page_action));
4546 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4547 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
4548 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
4549 }
4550
4551 // Tests that an extension added through an external source is initially
4552 // disabled with the "prompt for external extensions" feature.
TEST_F(ExtensionServiceTest,ExternalExtensionDisabledOnInstallation)4553 TEST_F(ExtensionServiceTest, ExternalExtensionDisabledOnInstallation) {
4554 FeatureSwitch::ScopedOverride external_prompt_override(
4555 FeatureSwitch::prompt_for_external_extensions(), true);
4556 InitializeEmptyExtensionService();
4557
4558 // Register and install an external extension.
4559 MockExternalProvider* provider =
4560 AddMockExternalProvider(Manifest::EXTERNAL_PREF); // Takes ownership.
4561 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
4562 data_dir().AppendASCII("good.crx"));
4563
4564 WaitForExternalExtensionInstalled();
4565
4566 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
4567 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4568 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
4569 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
4570 prefs->GetDisableReasons(good_crx));
4571
4572 // Updating the extension shouldn't cause it to be enabled.
4573 provider->UpdateOrAddExtension(good_crx, "1.0.0.1",
4574 data_dir().AppendASCII("good2.crx"));
4575 WaitForExternalExtensionInstalled();
4576
4577 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
4578 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
4579 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
4580 prefs->GetDisableReasons(good_crx));
4581 const Extension* extension =
4582 registry()->disabled_extensions().GetByID(good_crx);
4583 ASSERT_TRUE(extension);
4584 // Double check that we did, in fact, update the extension.
4585 EXPECT_EQ("1.0.0.1", extension->version().GetString());
4586 }
4587
4588 // Test that if an extension is installed before the "prompt for external
4589 // extensions" feature is enabled, but is updated when the feature is
4590 // enabled, the extension is not disabled.
TEST_F(ExtensionServiceTest,ExternalExtensionIsNotDisabledOnUpdate)4591 TEST_F(ExtensionServiceTest, ExternalExtensionIsNotDisabledOnUpdate) {
4592 auto external_prompt_override =
4593 std::make_unique<FeatureSwitch::ScopedOverride>(
4594 FeatureSwitch::prompt_for_external_extensions(), false);
4595 InitializeEmptyExtensionService();
4596
4597 // Register and install an external extension.
4598 MockExternalProvider* provider =
4599 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
4600 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
4601 data_dir().AppendASCII("good.crx"));
4602
4603 WaitForExternalExtensionInstalled();
4604
4605 EXPECT_TRUE(registry()->enabled_extensions().Contains(good_crx));
4606 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4607 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
4608 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
4609
4610 provider->UpdateOrAddExtension(good_crx, "1.0.0.1",
4611 data_dir().AppendASCII("good2.crx"));
4612
4613 // We explicitly reset the override first. ScopedOverrides reset the value
4614 // to the original value on destruction, but if we reset by passing a new
4615 // object, the new object is constructed (overriding the current value)
4616 // before the old is destructed (which will immediately reset to the
4617 // original).
4618 external_prompt_override.reset();
4619 external_prompt_override = std::make_unique<FeatureSwitch::ScopedOverride>(
4620 FeatureSwitch::prompt_for_external_extensions(), true);
4621 WaitForExternalExtensionInstalled();
4622
4623 EXPECT_TRUE(registry()->enabled_extensions().Contains(good_crx));
4624 {
4625 const Extension* extension =
4626 registry()->enabled_extensions().GetByID(good_crx);
4627 ASSERT_TRUE(extension);
4628 EXPECT_EQ("1.0.0.1", extension->version().GetString());
4629 }
4630 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
4631 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
4632 }
4633
4634 // Test that if an external extension warning is ignored three times, the
4635 // extension no longer prompts
TEST_F(ExtensionServiceTest,ExternalExtensionRemainsDisabledIfIgnored)4636 TEST_F(ExtensionServiceTest, ExternalExtensionRemainsDisabledIfIgnored) {
4637 FeatureSwitch::ScopedOverride prompt_override(
4638 FeatureSwitch::prompt_for_external_extensions(), true);
4639 InitializeEmptyExtensionService();
4640
4641 // Register and install an external extension.
4642 MockExternalProvider* provider =
4643 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
4644 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
4645 data_dir().AppendASCII("good.crx"));
4646
4647 WaitForExternalExtensionInstalled();
4648
4649 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
4650 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4651 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
4652 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
4653 prefs->GetDisableReasons(good_crx));
4654
4655 ExternalInstallManager* external_install_manager =
4656 service()->external_install_manager();
4657
4658 for (int i = 0; i < 3; ++i) {
4659 std::vector<ExternalInstallError*> errors =
4660 external_install_manager->GetErrorsForTesting();
4661 ASSERT_EQ(1u, errors.size());
4662 errors[0]->OnInstallPromptDone(ExtensionInstallPrompt::Result::ABORTED);
4663 base::RunLoop().RunUntilIdle();
4664 // Note: Calling OnInstallPromptDone() can result in the removal of the
4665 // error by the manager (which owns the object), so the contents |errors|
4666 // are invalidated now!
4667 EXPECT_TRUE(external_install_manager->GetErrorsForTesting().empty());
4668 external_install_manager->ClearShownIdsForTesting();
4669 external_install_manager->UpdateExternalExtensionAlert();
4670 }
4671
4672 // We should have stopped prompting, since the user was shown the warning
4673 // three times.
4674 EXPECT_TRUE(external_install_manager->GetErrorsForTesting().empty());
4675 EXPECT_TRUE(prefs->IsExternalExtensionAcknowledged(good_crx));
4676 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
4677 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
4678 prefs->GetDisableReasons(good_crx));
4679
4680 // The extension should remain disabled.
4681 service()->ReloadExtensionsForTest();
4682 EXPECT_TRUE(prefs->IsExternalExtensionAcknowledged(good_crx));
4683 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
4684 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
4685 prefs->GetDisableReasons(good_crx));
4686
4687 // Then re-enabling the extension (or otherwise causing the alert to be
4688 // updated again) should work. Regression test for https://crbug.com/736292.
4689 {
4690 TestExtensionRegistryObserver registry_observer(registry());
4691 service()->EnableExtension(good_crx);
4692 registry_observer.WaitForExtensionLoaded();
4693 base::RunLoop().RunUntilIdle();
4694 }
4695 }
4696
4697 #if !defined(OS_CHROMEOS)
4698 // This tests if default apps are installed correctly.
TEST_F(ExtensionServiceTest,DefaultAppsInstall)4699 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
4700 InitializeEmptyExtensionService();
4701
4702 {
4703 std::string json_data =
4704 "{"
4705 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
4706 " \"external_crx\": \"good.crx\","
4707 " \"external_version\": \"1.0.0.0\","
4708 " \"is_bookmark_app\": false"
4709 " }"
4710 "}";
4711 default_apps::Provider* provider = new default_apps::Provider(
4712 profile(), service(), new ExternalTestingLoader(json_data, data_dir()),
4713 Manifest::INTERNAL, Manifest::INVALID_LOCATION,
4714 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4715
4716 service()->AddProviderForTesting(base::WrapUnique(provider));
4717 }
4718
4719 ASSERT_EQ(0u, registry()->enabled_extensions().size());
4720 WaitForExternalExtensionInstalled();
4721
4722 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4723 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4724 const Extension* extension =
4725 registry()->enabled_extensions().GetByID(good_crx);
4726 EXPECT_TRUE(extension->from_webstore());
4727 EXPECT_TRUE(extension->was_installed_by_default());
4728 }
4729 #endif
4730
4731 // Crashes on Linux/CrOS. https://crbug.com/703712
4732 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
4733 #define MAYBE_UpdatingPendingExternalExtensionWithFlags \
4734 DISABLED_UpdatingPendingExternalExtensionWithFlags
4735 #else
4736 #define MAYBE_UpdatingPendingExternalExtensionWithFlags \
4737 UpdatingPendingExternalExtensionWithFlags
4738 #endif
4739
TEST_F(ExtensionServiceTest,MAYBE_UpdatingPendingExternalExtensionWithFlags)4740 TEST_F(ExtensionServiceTest, MAYBE_UpdatingPendingExternalExtensionWithFlags) {
4741 // Regression test for crbug.com/627522
4742 const char kPrefFromBookmark[] = "from_bookmark";
4743
4744 InitializeEmptyExtensionService();
4745
4746 base::FilePath path = data_dir().AppendASCII("good.crx");
4747
4748 // Register and install an external extension.
4749 base::Version version("1.0.0.0");
4750 content::WindowedNotificationObserver observer(
4751 NOTIFICATION_CRX_INSTALLER_DONE,
4752 content::NotificationService::AllSources());
4753 ExternalInstallInfoFile info(good_crx, version, path, Manifest::EXTERNAL_PREF,
4754 Extension::FROM_BOOKMARK,
4755 false /* mark_acknowledged */,
4756 false /* install_immediately */);
4757 ASSERT_TRUE(service()->OnExternalExtensionFileFound(info));
4758 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
4759
4760 // Upgrade to version 2.0, the flag should be preserved.
4761 path = data_dir().AppendASCII("good2.crx");
4762 UpdateExtension(good_crx, path, ENABLED);
4763 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
4764 const Extension* extension =
4765 registry()->enabled_extensions().GetByID(good_crx);
4766 ASSERT_TRUE(extension);
4767 ASSERT_TRUE(extension->from_bookmark());
4768 }
4769
4770 // Tests disabling extensions
TEST_F(ExtensionServiceTest,DisableExtension)4771 TEST_F(ExtensionServiceTest, DisableExtension) {
4772 InitializeEmptyExtensionService();
4773
4774 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4775 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4776
4777 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4778 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4779 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4780 EXPECT_EQ(0u, registry()->blocklisted_extensions().size());
4781
4782 // Disable it.
4783 service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION);
4784
4785 EXPECT_TRUE(registry()->disabled_extensions().GetByID(good_crx));
4786 EXPECT_FALSE(registry()->enabled_extensions().GetByID(good_crx));
4787 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4788 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4789 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4790 EXPECT_EQ(0u, registry()->blocklisted_extensions().size());
4791 }
4792
4793 // Tests performing actions on extension Omaha attributes.
TEST_F(ExtensionServiceTest,PerformActionBasedOnOmahaAttributes)4794 TEST_F(ExtensionServiceTest, PerformActionBasedOnOmahaAttributes) {
4795 InitializeEmptyExtensionService();
4796
4797 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4798 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4799
4800 base::Value attributes(base::Value::Type::DICTIONARY);
4801 attributes.SetKey("_malware", base::Value(true));
4802 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4803
4804 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4805 service()->PerformActionBasedOnOmahaAttributes(good_crx, attributes);
4806 EXPECT_EQ(disable_reason::DISABLE_REMOTELY_FOR_MALWARE,
4807 prefs->GetDisableReasons(good_crx));
4808 EXPECT_TRUE(prefs->IsExtensionBlocklisted(good_crx));
4809
4810 attributes.SetKey("_malware", base::Value(false));
4811 service()->PerformActionBasedOnOmahaAttributes(good_crx, attributes);
4812 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4813 EXPECT_EQ(0, prefs->GetDisableReasons(good_crx));
4814 EXPECT_FALSE(prefs->IsExtensionBlocklisted(good_crx));
4815 }
4816
4817 // Tests not re-enabling previously remotely disabled extension if it's not the
4818 // only reason but the disable reasons should be gone.
TEST_F(ExtensionServiceTest,NoEnableRemotelyDisabledExtension)4819 TEST_F(ExtensionServiceTest, NoEnableRemotelyDisabledExtension) {
4820 InitializeEmptyExtensionService();
4821
4822 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4823 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
4824
4825 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4826 service()->DisableExtension(good_crx,
4827 disable_reason::DISABLE_REMOTELY_FOR_MALWARE |
4828 disable_reason::DISABLE_USER_ACTION);
4829 EXPECT_TRUE(registry()->disabled_extensions().GetByID(good_crx));
4830 service()->BlocklistExtensionForTest(good_crx);
4831 EXPECT_TRUE(prefs->IsExtensionBlocklisted(good_crx));
4832
4833 base::Value empty_attr(base::Value::Type::DICTIONARY);
4834 service()->PerformActionBasedOnOmahaAttributes(good_crx, empty_attr);
4835 EXPECT_TRUE(registry()->disabled_extensions().GetByID(good_crx));
4836 EXPECT_FALSE(prefs->GetDisableReasons(good_crx) &
4837 disable_reason::DISABLE_REMOTELY_FOR_MALWARE);
4838 EXPECT_FALSE(prefs->IsExtensionBlocklisted(good_crx));
4839 }
4840
TEST_F(ExtensionServiceTest,TerminateExtension)4841 TEST_F(ExtensionServiceTest, TerminateExtension) {
4842 InitializeEmptyExtensionService();
4843
4844 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4845 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4846 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4847 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4848 EXPECT_EQ(0u, registry()->blocklisted_extensions().size());
4849
4850 TerminateExtension(good_crx);
4851
4852 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4853 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4854 EXPECT_EQ(1u, registry()->terminated_extensions().size());
4855 EXPECT_EQ(0u, registry()->blocklisted_extensions().size());
4856 }
4857
TEST_F(ExtensionServiceTest,DisableTerminatedExtension)4858 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
4859 InitializeEmptyExtensionService();
4860
4861 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4862 TerminateExtension(good_crx);
4863 EXPECT_TRUE(registry()->terminated_extensions().GetByID(good_crx));
4864
4865 // Disable it.
4866 service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION);
4867
4868 EXPECT_FALSE(registry()->terminated_extensions().GetByID(good_crx));
4869 EXPECT_TRUE(registry()->disabled_extensions().GetByID(good_crx));
4870
4871 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4872 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4873 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4874 EXPECT_EQ(0u, registry()->blocklisted_extensions().size());
4875 }
4876
4877 // Tests that with the kDisableExtensions flag, extensions are not loaded by
4878 // the ExtensionService...
TEST_F(ExtensionServiceTest,PRE_DisableAllExtensions)4879 TEST_F(ExtensionServiceTest, PRE_DisableAllExtensions) {
4880 base::CommandLine::ForCurrentProcess()->AppendSwitch(
4881 ::switches::kDisableExtensions);
4882 InitializeGoodInstalledExtensionService();
4883 service()->Init();
4884 EXPECT_TRUE(registry()->GenerateInstalledExtensionsSet()->is_empty());
4885 }
4886
4887 // ... But, if we remove the switch, they are.
TEST_F(ExtensionServiceTest,DisableAllExtensions)4888 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
4889 EXPECT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
4890 ::switches::kDisableExtensions));
4891 InitializeGoodInstalledExtensionService();
4892 service()->Init();
4893 EXPECT_FALSE(registry()->GenerateInstalledExtensionsSet()->is_empty());
4894 EXPECT_FALSE(registry()->enabled_extensions().is_empty());
4895 }
4896
4897 // Tests reloading extensions.
TEST_F(ExtensionServiceTest,ReloadExtensions)4898 TEST_F(ExtensionServiceTest, ReloadExtensions) {
4899 InitializeEmptyExtensionService();
4900
4901 // Simple extension that should install without error.
4902 base::FilePath path = data_dir().AppendASCII("good.crx");
4903 InstallCRX(path, INSTALL_NEW,
4904 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4905 const char* const extension_id = good_crx;
4906 service()->DisableExtension(extension_id,
4907 disable_reason::DISABLE_USER_ACTION);
4908
4909 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4910 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4911
4912 service()->ReloadExtensionsForTest();
4913
4914 // The creation flags should not change when reloading the extension.
4915 const Extension* extension =
4916 registry()->disabled_extensions().GetByID(good_crx);
4917 EXPECT_TRUE(extension->from_webstore());
4918 EXPECT_TRUE(extension->was_installed_by_default());
4919 EXPECT_FALSE(extension->from_bookmark());
4920
4921 // Extension counts shouldn't change.
4922 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4923 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4924
4925 service()->EnableExtension(extension_id);
4926
4927 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4928 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4929
4930 // Need to clear |loaded_| manually before reloading as the
4931 // EnableExtension() call above inserted into it and
4932 // UnloadAllExtensions() doesn't send out notifications.
4933 loaded_.clear();
4934 service()->ReloadExtensionsForTest();
4935
4936 // Extension counts shouldn't change.
4937 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4938 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4939 }
4940
4941 // Tests reloading an extension.
TEST_F(ExtensionServiceTest,ReloadExtension)4942 TEST_F(ExtensionServiceTest, ReloadExtension) {
4943 InitializeEmptyExtensionService();
4944
4945 // Simple extension that should install without error.
4946 const char extension_id[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
4947 base::FilePath ext = data_dir()
4948 .AppendASCII("good")
4949 .AppendASCII("Extensions")
4950 .AppendASCII(extension_id)
4951 .AppendASCII("1.0.0.0");
4952 UnpackedInstaller::Create(service())->Load(ext);
4953 content::RunAllTasksUntilIdle();
4954
4955 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4956 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4957
4958 service()->ReloadExtension(extension_id);
4959
4960 // Extension should be disabled now, waiting to be reloaded.
4961 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4962 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4963 EXPECT_EQ(disable_reason::DISABLE_RELOAD,
4964 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id));
4965
4966 // Reloading again should not crash.
4967 service()->ReloadExtension(extension_id);
4968
4969 // Finish reloading
4970 content::RunAllTasksUntilIdle();
4971
4972 // Extension should be enabled again.
4973 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4974 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4975 }
4976
TEST_F(ExtensionServiceTest,UninstallExtension)4977 TEST_F(ExtensionServiceTest, UninstallExtension) {
4978 InitializeEmptyExtensionService();
4979 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4980 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4981 UninstallExtension(good_crx);
4982 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4983 EXPECT_EQ(UnloadedExtensionReason::UNINSTALL, unloaded_reason_);
4984 }
4985
TEST_F(ExtensionServiceTest,UninstallTerminatedExtension)4986 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4987 InitializeEmptyExtensionService();
4988 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4989 TerminateExtension(good_crx);
4990 UninstallExtension(good_crx);
4991 EXPECT_EQ(UnloadedExtensionReason::TERMINATE, unloaded_reason_);
4992 }
4993
4994 // An extension disabled because of unsupported requirements should re-enabled
4995 // if updated to a version with supported requirements as long as there are no
4996 // other disable reasons.
TEST_F(ExtensionServiceTest,UpgradingRequirementsEnabled)4997 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4998 InitializeEmptyExtensionService();
4999 content::GpuDataManager::GetInstance()->BlocklistWebGLForTesting();
5000
5001 base::FilePath path = data_dir().AppendASCII("requirements");
5002 base::FilePath pem_path =
5003 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
5004 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
5005 pem_path,
5006 INSTALL_NEW);
5007 std::string id = extension_v1->id();
5008 EXPECT_TRUE(service()->IsExtensionEnabled(id));
5009
5010 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
5011
5012 PackCRX(path.AppendASCII("v2_bad_requirements"),
5013 pem_path,
5014 v2_bad_requirements_crx);
5015 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
5016 EXPECT_FALSE(service()->IsExtensionEnabled(id));
5017
5018 base::FilePath v3_good_crx = GetTemporaryFile();
5019
5020 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
5021 UpdateExtension(id, v3_good_crx, ENABLED);
5022 EXPECT_TRUE(service()->IsExtensionEnabled(id));
5023 }
5024
5025 // Extensions disabled through user action should stay disabled.
TEST_F(ExtensionServiceTest,UpgradingRequirementsDisabled)5026 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
5027 InitializeEmptyExtensionService();
5028 content::GpuDataManager::GetInstance()->BlocklistWebGLForTesting();
5029
5030 base::FilePath path = data_dir().AppendASCII("requirements");
5031 base::FilePath pem_path =
5032 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
5033 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
5034 pem_path,
5035 INSTALL_NEW);
5036 std::string id = extension_v1->id();
5037 service()->DisableExtension(id, disable_reason::DISABLE_USER_ACTION);
5038 EXPECT_FALSE(service()->IsExtensionEnabled(id));
5039
5040 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
5041
5042 PackCRX(path.AppendASCII("v2_bad_requirements"),
5043 pem_path,
5044 v2_bad_requirements_crx);
5045 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
5046 EXPECT_FALSE(service()->IsExtensionEnabled(id));
5047
5048 base::FilePath v3_good_crx = GetTemporaryFile();
5049
5050 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
5051 UpdateExtension(id, v3_good_crx, INSTALLED);
5052 EXPECT_FALSE(service()->IsExtensionEnabled(id));
5053 }
5054
5055 // The extension should not re-enabled because it was disabled from a
5056 // permission increase.
TEST_F(ExtensionServiceTest,UpgradingRequirementsPermissions)5057 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
5058 InitializeEmptyExtensionService();
5059 content::GpuDataManager::GetInstance()->BlocklistWebGLForTesting();
5060
5061 base::FilePath path = data_dir().AppendASCII("requirements");
5062 base::FilePath pem_path =
5063 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
5064 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
5065 pem_path,
5066 INSTALL_NEW);
5067 std::string id = extension_v1->id();
5068 EXPECT_TRUE(service()->IsExtensionEnabled(id));
5069
5070 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
5071
5072 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
5073 pem_path,
5074 v2_bad_requirements_and_permissions_crx);
5075 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
5076 EXPECT_FALSE(service()->IsExtensionEnabled(id));
5077
5078 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
5079
5080 PackCRX(path.AppendASCII("v3_bad_permissions"),
5081 pem_path,
5082 v3_bad_permissions_crx);
5083 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
5084 EXPECT_FALSE(service()->IsExtensionEnabled(id));
5085 }
5086
5087 // Unpacked extensions are not allowed to be installed if they have unsupported
5088 // requirements.
TEST_F(ExtensionServiceTest,UnpackedRequirements)5089 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
5090 InitializeEmptyExtensionService();
5091 content::GpuDataManager::GetInstance()->BlocklistWebGLForTesting();
5092
5093 base::FilePath path =
5094 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements");
5095 UnpackedInstaller::Create(service())->Load(path);
5096 content::RunAllTasksUntilIdle();
5097 EXPECT_EQ(1u, GetErrors().size());
5098 EXPECT_EQ(0u, registry()->enabled_extensions().size());
5099 }
5100
5101 class ExtensionCookieCallback {
5102 public:
ExtensionCookieCallback()5103 ExtensionCookieCallback() : result_(false) {}
5104
SetCookieCallback(net::CookieAccessResult result)5105 void SetCookieCallback(net::CookieAccessResult result) {
5106 result_ = result.status.IsInclude();
5107 }
5108
GetAllCookiesCallback(const net::CookieAccessResultList & list,const net::CookieAccessResultList & excluded_list)5109 void GetAllCookiesCallback(const net::CookieAccessResultList& list,
5110 const net::CookieAccessResultList& excluded_list) {
5111 list_ = net::cookie_util::StripAccessResults(list);
5112 }
5113 net::CookieList list_;
5114 bool result_;
5115 };
5116
5117 namespace {
5118 // Helper to create (open, close, verify) a WebSQL database.
5119 // Must be run on the DatabaseTracker's task runner.
CreateDatabase(storage::DatabaseTracker * db_tracker,const std::string & origin_id)5120 void CreateDatabase(storage::DatabaseTracker* db_tracker,
5121 const std::string& origin_id) {
5122 DCHECK(db_tracker->task_runner()->RunsTasksInCurrentSequence());
5123 base::string16 db_name = base::UTF8ToUTF16("db");
5124 base::string16 description = base::UTF8ToUTF16("db_description");
5125 int64_t size;
5126 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
5127 db_tracker->DatabaseClosed(origin_id, db_name);
5128 std::vector<storage::OriginInfo> origins;
5129 db_tracker->GetAllOriginsInfo(&origins);
5130 EXPECT_EQ(1U, origins.size());
5131 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
5132 }
5133 } // namespace
5134
5135 // Verifies extension state is removed upon uninstall.
TEST_F(ExtensionServiceTest,ClearExtensionData)5136 TEST_F(ExtensionServiceTest, ClearExtensionData) {
5137 InitializeEmptyExtensionService();
5138 ExtensionCookieCallback callback;
5139
5140 // Load a test extension.
5141 base::FilePath path = data_dir();
5142 path = path.AppendASCII("good.crx");
5143 const Extension* extension = InstallCRX(path, INSTALL_NEW);
5144 ASSERT_TRUE(extension);
5145 GURL ext_url(extension->url());
5146 std::string origin_id = storage::GetIdentifierFromOrigin(ext_url);
5147
5148 // Set a cookie for the extension.
5149 net::CookieStore* cookie_store =
5150 extensions::ChromeExtensionCookies::Get(profile())
5151 ->GetCookieStoreForTesting();
5152 ASSERT_TRUE(cookie_store);
5153 auto cookie =
5154 net::CanonicalCookie::Create(ext_url, "dummy=value", base::Time::Now(),
5155 base::nullopt /* server_time */);
5156 cookie_store->SetCanonicalCookieAsync(
5157 std::move(cookie), ext_url, net::CookieOptions::MakeAllInclusive(),
5158 base::BindOnce(&ExtensionCookieCallback::SetCookieCallback,
5159 base::Unretained(&callback)));
5160 content::RunAllTasksUntilIdle();
5161 EXPECT_TRUE(callback.result_);
5162
5163 cookie_store->GetCookieListWithOptionsAsync(
5164 ext_url, net::CookieOptions::MakeAllInclusive(),
5165 base::BindOnce(&ExtensionCookieCallback::GetAllCookiesCallback,
5166 base::Unretained(&callback)));
5167 content::RunAllTasksUntilIdle();
5168 EXPECT_EQ(1U, callback.list_.size());
5169
5170 // Open a database.
5171 storage::DatabaseTracker* db_tracker =
5172 BrowserContext::GetDefaultStoragePartition(profile())
5173 ->GetDatabaseTracker();
5174 db_tracker->task_runner()->PostTask(
5175 FROM_HERE,
5176 base::BindOnce(&CreateDatabase, base::Unretained(db_tracker), origin_id));
5177 content::RunAllTasksUntilIdle();
5178
5179 // Create local storage. We only simulate this by creating the backing files.
5180 // Note: This test depends on details of how the dom_storage library
5181 // stores data in the host file system.
5182 base::FilePath lso_dir_path =
5183 profile()->GetPath().AppendASCII("Local Storage");
5184 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
5185 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
5186 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
5187 EXPECT_EQ(0, base::WriteFile(lso_file_path, nullptr, 0));
5188 EXPECT_TRUE(base::PathExists(lso_file_path));
5189
5190 // Create indexed db. Similarly, it is enough to only simulate this by
5191 // creating the directory on the disk, and resetting the caches of
5192 // "known" origins.
5193 auto& idb_control = BrowserContext::GetDefaultStoragePartition(profile())
5194 ->GetIndexedDBControl();
5195 mojo::Remote<storage::mojom::IndexedDBControlTest> idb_control_test;
5196 idb_control.BindTestInterface(idb_control_test.BindNewPipeAndPassReceiver());
5197
5198 base::FilePath idb_path;
5199 {
5200 base::RunLoop run_loop;
5201 idb_control_test->GetFilePathForTesting(
5202 url::Origin::Create(ext_url),
5203 base::BindLambdaForTesting([&](const base::FilePath& path) {
5204 idb_path = path;
5205 EXPECT_TRUE(base::CreateDirectory(idb_path));
5206 EXPECT_TRUE(base::DirectoryExists(idb_path));
5207 idb_control_test->ResetCachesForTesting(
5208 base::BindLambdaForTesting([&]() { run_loop.Quit(); }));
5209 }));
5210 run_loop.Run();
5211 }
5212
5213 // Uninstall the extension.
5214 ASSERT_TRUE(service()->UninstallExtension(
5215 good_crx, UNINSTALL_REASON_FOR_TESTING, nullptr));
5216 // The data deletion happens on the IO thread; since we use a
5217 // BrowserTaskEnvironment (without REAL_IO_THREAD), the IO and UI threads are
5218 // the same, and RunAllTasksUntilIdle() should run IO thread tasks.
5219 content::RunAllTasksUntilIdle();
5220
5221 // Check that the cookie is gone.
5222 cookie_store->GetCookieListWithOptionsAsync(
5223 ext_url, net::CookieOptions::MakeAllInclusive(),
5224 base::BindOnce(&ExtensionCookieCallback::GetAllCookiesCallback,
5225 base::Unretained(&callback)));
5226 content::RunAllTasksUntilIdle();
5227 EXPECT_EQ(0U, callback.list_.size());
5228
5229 // The database should have vanished as well.
5230 db_tracker->task_runner()->PostTask(
5231 FROM_HERE, base::BindOnce(
5232 [](storage::DatabaseTracker* db_tracker) {
5233 std::vector<storage::OriginInfo> origins;
5234 db_tracker->GetAllOriginsInfo(&origins);
5235 EXPECT_EQ(0U, origins.size());
5236 },
5237 base::Unretained(db_tracker)));
5238 content::RunAllTasksUntilIdle();
5239
5240 // Check that the LSO file has been removed.
5241 EXPECT_FALSE(base::PathExists(lso_file_path));
5242
5243 // Check if the indexed db has disappeared too.
5244 EXPECT_FALSE(base::DirectoryExists(idb_path));
5245 }
5246
SetCookieSaveData(bool * result_out,base::OnceClosure callback,net::CookieAccessResult result)5247 void SetCookieSaveData(bool* result_out,
5248 base::OnceClosure callback,
5249 net::CookieAccessResult result) {
5250 *result_out = result.status.IsInclude();
5251 std::move(callback).Run();
5252 }
5253
GetCookiesSaveData(std::vector<net::CanonicalCookie> * result_out,base::OnceClosure callback,const net::CookieAccessResultList & result,const net::CookieAccessResultList & excluded_cookies)5254 void GetCookiesSaveData(std::vector<net::CanonicalCookie>* result_out,
5255 base::OnceClosure callback,
5256 const net::CookieAccessResultList& result,
5257 const net::CookieAccessResultList& excluded_cookies) {
5258 *result_out = net::cookie_util::StripAccessResults(result);
5259 std::move(callback).Run();
5260 }
5261
5262 // Verifies app state is removed upon uninstall.
TEST_F(ExtensionServiceTest,ClearAppData)5263 TEST_F(ExtensionServiceTest, ClearAppData) {
5264 InitializeEmptyExtensionService();
5265 ExtensionCookieCallback callback;
5266
5267 int pref_count = 0;
5268
5269 // Install app1 with unlimited storage.
5270 const Extension* extension =
5271 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
5272 ValidatePrefKeyCount(++pref_count);
5273 ASSERT_EQ(1u, registry()->enabled_extensions().size());
5274 const std::string id1 = extension->id();
5275 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
5276 APIPermission::kUnlimitedStorage));
5277 const GURL origin1(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
5278 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5279 origin1));
5280 std::string origin_id = storage::GetIdentifierFromOrigin(origin1);
5281
5282 // Install app2 from the same origin with unlimited storage.
5283 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
5284 ValidatePrefKeyCount(++pref_count);
5285 ASSERT_EQ(2u, registry()->enabled_extensions().size());
5286 const std::string id2 = extension->id();
5287 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
5288 APIPermission::kUnlimitedStorage));
5289 EXPECT_TRUE(extension->web_extent().MatchesURL(
5290 AppLaunchInfo::GetFullLaunchURL(extension)));
5291 const GURL origin2(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
5292 EXPECT_EQ(origin1, origin2);
5293 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5294 origin2));
5295
5296 network::mojom::NetworkContext* network_context =
5297 content::BrowserContext::GetDefaultStoragePartition(profile())
5298 ->GetNetworkContext();
5299 mojo::Remote<network::mojom::CookieManager> cookie_manager_remote;
5300 network_context->GetCookieManager(
5301 cookie_manager_remote.BindNewPipeAndPassReceiver());
5302
5303 std::unique_ptr<net::CanonicalCookie> cc(
5304 net::CanonicalCookie::Create(origin1, "dummy=value", base::Time::Now(),
5305 base::nullopt /* server_time */));
5306 ASSERT_TRUE(cc.get());
5307
5308 {
5309 bool set_result = false;
5310 base::RunLoop run_loop;
5311 cookie_manager_remote->SetCanonicalCookie(
5312 *cc.get(), origin1, net::CookieOptions::MakeAllInclusive(),
5313 base::BindOnce(&SetCookieSaveData, &set_result,
5314 run_loop.QuitClosure()));
5315 run_loop.Run();
5316 EXPECT_TRUE(set_result);
5317 }
5318
5319 {
5320 base::RunLoop run_loop;
5321 std::vector<net::CanonicalCookie> cookies_result;
5322 cookie_manager_remote->GetCookieList(
5323 origin1, net::CookieOptions::MakeAllInclusive(),
5324 base::BindOnce(&GetCookiesSaveData, &cookies_result,
5325 run_loop.QuitClosure()));
5326 run_loop.Run();
5327 EXPECT_EQ(1U, cookies_result.size());
5328 }
5329
5330 // Open a database.
5331 storage::DatabaseTracker* db_tracker =
5332 BrowserContext::GetDefaultStoragePartition(profile())
5333 ->GetDatabaseTracker();
5334 db_tracker->task_runner()->PostTask(
5335 FROM_HERE,
5336 base::BindOnce(&CreateDatabase, base::Unretained(db_tracker), origin_id));
5337 content::RunAllTasksUntilIdle();
5338
5339 // Create local storage. We only simulate this by creating the backing files.
5340 // Note: This test depends on details of how the dom_storage library
5341 // stores data in the host file system.
5342 base::FilePath lso_dir_path =
5343 profile()->GetPath().AppendASCII("Local Storage");
5344 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
5345 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
5346 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
5347 EXPECT_EQ(0, base::WriteFile(lso_file_path, nullptr, 0));
5348 EXPECT_TRUE(base::PathExists(lso_file_path));
5349
5350 // Create indexed db. Similarly, it is enough to only simulate this by
5351 // creating the directory on the disk, and resetting the caches of
5352 // "known" origins.
5353 auto& idb_control = BrowserContext::GetDefaultStoragePartition(profile())
5354 ->GetIndexedDBControl();
5355 mojo::Remote<storage::mojom::IndexedDBControlTest> idb_control_test;
5356 idb_control.BindTestInterface(idb_control_test.BindNewPipeAndPassReceiver());
5357
5358 base::FilePath idb_path;
5359 {
5360 base::RunLoop run_loop;
5361 idb_control_test->GetFilePathForTesting(
5362 url::Origin::Create(origin1),
5363 base::BindLambdaForTesting([&](const base::FilePath& path) {
5364 idb_path = path;
5365 EXPECT_TRUE(base::CreateDirectory(idb_path));
5366 EXPECT_TRUE(base::DirectoryExists(idb_path));
5367 idb_control_test->ResetCachesForTesting(
5368 base::BindLambdaForTesting([&]() { run_loop.Quit(); }));
5369 }));
5370 run_loop.Run();
5371 }
5372
5373 // Uninstall one of them, unlimited storage should still be granted
5374 // to the origin.
5375 UninstallExtension(id1);
5376 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5377 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5378 origin1));
5379
5380 {
5381 // Check that the cookie is still there.
5382 base::RunLoop run_loop;
5383 std::vector<net::CanonicalCookie> cookies_result;
5384 cookie_manager_remote->GetCookieList(
5385 origin1, net::CookieOptions::MakeAllInclusive(),
5386 base::BindOnce(&GetCookiesSaveData, &cookies_result,
5387 run_loop.QuitClosure()));
5388 run_loop.Run();
5389 EXPECT_EQ(1U, cookies_result.size());
5390 }
5391
5392 // Now uninstall the other. Storage should be cleared for the apps.
5393 UninstallExtension(id2);
5394 EXPECT_EQ(0u, registry()->enabled_extensions().size());
5395 EXPECT_FALSE(
5396 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5397 origin1));
5398
5399 {
5400 // Check that the cookie is gone.
5401 base::RunLoop run_loop;
5402 std::vector<net::CanonicalCookie> cookies_result;
5403 cookie_manager_remote->GetCookieList(
5404 origin1, net::CookieOptions::MakeAllInclusive(),
5405 base::BindOnce(&GetCookiesSaveData, &cookies_result,
5406 run_loop.QuitClosure()));
5407 run_loop.Run();
5408 EXPECT_EQ(0U, cookies_result.size());
5409 }
5410
5411 // The database should have vanished as well.
5412 db_tracker->task_runner()->PostTask(
5413 FROM_HERE, base::BindOnce(
5414 [](storage::DatabaseTracker* db_tracker) {
5415 std::vector<storage::OriginInfo> origins;
5416 db_tracker->GetAllOriginsInfo(&origins);
5417 EXPECT_EQ(0U, origins.size());
5418 },
5419 base::Unretained(db_tracker)));
5420 content::RunAllTasksUntilIdle();
5421
5422 // Check that the LSO file has been removed.
5423 EXPECT_FALSE(base::PathExists(lso_file_path));
5424
5425 // Check if the indexed db has disappeared too.
5426 EXPECT_FALSE(base::DirectoryExists(idb_path));
5427 }
5428
5429 // Tests loading single extensions (like --load-extension)
TEST_F(ExtensionServiceTest,LoadExtension)5430 TEST_F(ExtensionServiceTest, LoadExtension) {
5431 InitializeEmptyExtensionService();
5432 TestExtensionDir good_extension_dir;
5433 good_extension_dir.WriteManifest(
5434 R"({
5435 "name": "Good Extension",
5436 "version": "0.1",
5437 "manifest_version": 2
5438 })");
5439
5440 {
5441 ChromeTestExtensionLoader loader(profile());
5442 loader.set_pack_extension(false);
5443 loader.LoadExtension(good_extension_dir.UnpackedPath());
5444 }
5445 EXPECT_EQ(0u, GetErrors().size());
5446 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5447 ValidatePrefKeyCount(1);
5448
5449 auto get_extension_by_name = [](const ExtensionSet& extensions,
5450 const std::string& name) {
5451 // NOTE: lambda type deduction doesn't recognize returning
5452 // const Extension* in one place and nullptr in another as the same type, so
5453 // we have to make sure to return an explicit type here.
5454 const Extension* result = nullptr;
5455 for (const auto& extension : extensions) {
5456 if (extension->name() == name) {
5457 result = extension.get();
5458 break;
5459 }
5460 }
5461 return result;
5462 };
5463 constexpr const char kGoodExtension[] = "Good Extension";
5464 {
5465 const Extension* extension =
5466 get_extension_by_name(registry()->enabled_extensions(), kGoodExtension);
5467 ASSERT_TRUE(extension);
5468 EXPECT_EQ(Manifest::UNPACKED, extension->location());
5469 }
5470
5471 // Try loading an extension with no manifest. It should fail.
5472 TestExtensionDir bad_extension_dir;
5473 bad_extension_dir.WriteFile(FILE_PATH_LITERAL("background.js"), "// some JS");
5474 {
5475 ChromeTestExtensionLoader loader(profile());
5476 loader.set_pack_extension(false);
5477 loader.set_should_fail(true);
5478 loader.LoadExtension(bad_extension_dir.UnpackedPath());
5479 }
5480
5481 EXPECT_EQ(1u, GetErrors().size());
5482 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5483 EXPECT_EQ(1u, registry()->GenerateInstalledExtensionsSet()->size());
5484 EXPECT_TRUE(
5485 get_extension_by_name(registry()->enabled_extensions(), kGoodExtension));
5486
5487 // Test uninstalling the good extension.
5488 const ExtensionId good_id =
5489 get_extension_by_name(registry()->enabled_extensions(), kGoodExtension)
5490 ->id();
5491 service()->UninstallExtension(good_id, UNINSTALL_REASON_FOR_TESTING, nullptr);
5492 content::RunAllTasksUntilIdle();
5493 EXPECT_TRUE(registry()->GenerateInstalledExtensionsSet()->is_empty());
5494 }
5495
5496 // Tests that we generate IDs when they are not specified in the manifest for
5497 // --load-extension.
TEST_F(ExtensionServiceTest,GenerateID)5498 TEST_F(ExtensionServiceTest, GenerateID) {
5499 InitializeEmptyExtensionService();
5500
5501 base::FilePath no_id_ext = data_dir().AppendASCII("no_id");
5502 UnpackedInstaller::Create(service())->Load(no_id_ext);
5503 content::RunAllTasksUntilIdle();
5504 EXPECT_EQ(0u, GetErrors().size());
5505 ASSERT_EQ(1u, loaded_.size());
5506 ASSERT_TRUE(crx_file::id_util::IdIsValid(loaded_[0]->id()));
5507 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
5508
5509 ValidatePrefKeyCount(1);
5510
5511 std::string previous_id = loaded_[0]->id();
5512
5513 // If we reload the same path, we should get the same extension ID.
5514 UnpackedInstaller::Create(service())->Load(no_id_ext);
5515 content::RunAllTasksUntilIdle();
5516 ASSERT_EQ(1u, loaded_.size());
5517 ASSERT_EQ(previous_id, loaded_[0]->id());
5518 }
5519
TEST_F(ExtensionServiceTest,UnpackedValidatesLocales)5520 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
5521 InitializeEmptyExtensionService();
5522
5523 base::FilePath bad_locale =
5524 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file");
5525 UnpackedInstaller::Create(service())->Load(bad_locale);
5526 content::RunAllTasksUntilIdle();
5527 EXPECT_EQ(1u, GetErrors().size());
5528 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
5529 .AppendASCII("ms")
5530 .AppendASCII("messages.json");
5531 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]),
5532 testing::HasSubstr(
5533 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())));
5534 ASSERT_EQ(0u, loaded_.size());
5535 }
5536
TestExternalProvider(MockExternalProvider * provider,Manifest::Location location)5537 void ExtensionServiceTest::TestExternalProvider(MockExternalProvider* provider,
5538 Manifest::Location location) {
5539 // Verify that starting with no providers loads no extensions.
5540 service()->Init();
5541 ASSERT_EQ(0u, loaded_.size());
5542
5543 provider->set_visit_count(0);
5544
5545 // Register a test extension externally using the mock registry provider.
5546 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5547
5548 // Add the extension.
5549 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5550
5551 // Reloading extensions should find our externally registered extension
5552 // and install it.
5553 WaitForExternalExtensionInstalled();
5554
5555 ASSERT_EQ(0u, GetErrors().size());
5556 ASSERT_EQ(1u, loaded_.size());
5557 ASSERT_EQ(location, loaded_[0]->location());
5558 ASSERT_EQ("1.0.0.0", loaded_[0]->version().GetString());
5559 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
5560 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
5561 // TODO(devlin): Testing the underlying values of the prefs for extensions
5562 // should be done in an ExtensionPrefs test, not here. This should only be
5563 // using the public ExtensionPrefs interfaces.
5564 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5565 ValidateIntegerPref(good_crx, "location", location);
5566
5567 // Reload extensions without changing anything. The extension should be
5568 // loaded again.
5569 loaded_.clear();
5570 service()->ReloadExtensionsForTest();
5571 content::RunAllTasksUntilIdle();
5572 ASSERT_EQ(0u, GetErrors().size());
5573 ASSERT_EQ(1u, loaded_.size());
5574 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
5575 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5576 ValidateIntegerPref(good_crx, "location", location);
5577
5578 // Now update the extension with a new version. We should get upgraded.
5579 source_path = source_path.DirName().AppendASCII("good2.crx");
5580 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5581
5582 loaded_.clear();
5583 WaitForExternalExtensionInstalled();
5584 ASSERT_EQ(0u, GetErrors().size());
5585 ASSERT_EQ(1u, loaded_.size());
5586 ASSERT_EQ("1.0.0.1", loaded_[0]->version().GetString());
5587 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
5588 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5589 ValidateIntegerPref(good_crx, "location", location);
5590
5591 // Uninstall the extension and reload. Nothing should happen because the
5592 // preference should prevent us from reinstalling.
5593 std::string id = loaded_[0]->id();
5594 EXPECT_EQ(id, good_crx);
5595 bool no_uninstall =
5596 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), nullptr);
5597 service()->UninstallExtension(id, UNINSTALL_REASON_FOR_TESTING, nullptr);
5598 content::RunAllTasksUntilIdle();
5599
5600 base::FilePath install_path = extensions_install_dir().AppendASCII(id);
5601 if (no_uninstall) {
5602 // Policy controlled extensions should not have been touched by uninstall.
5603 ASSERT_TRUE(base::PathExists(install_path));
5604 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
5605 EXPECT_FALSE(prefs->IsExternalExtensionUninstalled(good_crx));
5606 } else {
5607 // The extension should also be gone from the install directory.
5608 ASSERT_FALSE(base::PathExists(install_path));
5609 loaded_.clear();
5610 service()->CheckForExternalUpdates();
5611 content::RunAllTasksUntilIdle();
5612 ASSERT_EQ(0u, loaded_.size());
5613 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
5614 EXPECT_FALSE(prefs->GetInstalledExtensionInfo(good_crx));
5615
5616 // Now clear the preference and reinstall.
5617 prefs->ClearExternalUninstallForTesting(good_crx);
5618
5619 loaded_.clear();
5620 WaitForExternalExtensionInstalled();
5621 ASSERT_EQ(1u, loaded_.size());
5622 }
5623 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
5624 EXPECT_FALSE(prefs->IsExternalExtensionUninstalled(good_crx));
5625 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5626 ValidateIntegerPref(good_crx, "location", location);
5627
5628 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), nullptr)) {
5629 EXPECT_EQ(2, provider->visit_count());
5630 } else {
5631 // Now test an externally triggered uninstall (deleting the registry key or
5632 // the pref entry).
5633 provider->RemoveExtension(good_crx);
5634
5635 loaded_.clear();
5636 service()->OnExternalProviderReady(provider);
5637 content::RunAllTasksUntilIdle();
5638 ASSERT_EQ(0u, loaded_.size());
5639 EXPECT_FALSE(prefs->IsExternalExtensionUninstalled(good_crx));
5640 EXPECT_FALSE(prefs->GetInstalledExtensionInfo(good_crx));
5641
5642 // The extension should also be gone from the install directory.
5643 ASSERT_FALSE(base::PathExists(install_path));
5644
5645 // Now test the case where user uninstalls and then the extension is removed
5646 // from the external provider.
5647 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5648 WaitForExternalExtensionInstalled();
5649
5650 ASSERT_EQ(1u, loaded_.size());
5651 ASSERT_EQ(0u, GetErrors().size());
5652
5653 // User uninstalls.
5654 loaded_.clear();
5655 service()->UninstallExtension(id, UNINSTALL_REASON_FOR_TESTING, nullptr);
5656 content::RunAllTasksUntilIdle();
5657 ASSERT_EQ(0u, loaded_.size());
5658
5659 // Then remove the extension from the extension provider.
5660 provider->RemoveExtension(good_crx);
5661
5662 // Should still be at 0.
5663 loaded_.clear();
5664 service()->ReloadExtensionsForTest();
5665 content::RunAllTasksUntilIdle();
5666 ASSERT_EQ(0u, loaded_.size());
5667
5668 EXPECT_FALSE(prefs->GetInstalledExtensionInfo(good_crx));
5669 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
5670
5671 EXPECT_EQ(5, provider->visit_count());
5672 }
5673 }
5674
5675 // Tests the external installation feature
5676 #if defined(OS_WIN)
TEST_F(ExtensionServiceTest,ExternalInstallRegistry)5677 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
5678 // This should all work, even when normal extension installation is disabled.
5679 InitializeExtensionServiceWithExtensionsDisabled();
5680
5681 // Now add providers. Extension system takes ownership of the objects.
5682 MockExternalProvider* reg_provider =
5683 AddMockExternalProvider(Manifest::EXTERNAL_REGISTRY);
5684 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
5685 }
5686 #endif
5687
TEST_F(ExtensionServiceTest,ExternalInstallPref)5688 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
5689 InitializeEmptyExtensionService();
5690
5691 // Now add providers. Extension system takes ownership of the objects.
5692 MockExternalProvider* pref_provider =
5693 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
5694
5695 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
5696 }
5697
TEST_F(ExtensionServiceTest,ExternalInstallPrefUpdateUrl)5698 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
5699 // This should all work, even when normal extension installation is disabled.
5700 InitializeExtensionServiceWithExtensionsDisabled();
5701
5702 // TODO(skerner): The mock provider is not a good model of a provider
5703 // that works with update URLs, because it adds file and version info.
5704 // Extend the mock to work with update URLs. This test checks the
5705 // behavior that is common to all external extension visitors. The
5706 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5707 // what the visitor does results in an extension being downloaded and
5708 // installed.
5709 MockExternalProvider* pref_provider =
5710 AddMockExternalProvider(Manifest::EXTERNAL_PREF_DOWNLOAD);
5711 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
5712 }
5713
TEST_F(ExtensionServiceTest,ExternalInstallPolicyUpdateUrl)5714 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
5715 // This should all work, even when normal extension installation is disabled.
5716 InitializeExtensionServiceWithExtensionsDisabled();
5717
5718 // TODO(skerner): The mock provider is not a good model of a provider
5719 // that works with update URLs, because it adds file and version info.
5720 // Extend the mock to work with update URLs. This test checks the
5721 // behavior that is common to all external extension visitors. The
5722 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5723 // what the visitor does results in an extension being downloaded and
5724 // installed.
5725 MockExternalProvider* pref_provider =
5726 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
5727 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
5728 }
5729
5730 // Tests that external extensions get uninstalled when the external extension
5731 // providers can't account for them.
TEST_F(ExtensionServiceTest,ExternalUninstall)5732 TEST_F(ExtensionServiceTest, ExternalUninstall) {
5733 // Start the extensions service with one external extension already installed.
5734 base::FilePath source_install_dir =
5735 data_dir().AppendASCII("good").AppendASCII("Extensions");
5736 base::FilePath pref_path = source_install_dir
5737 .DirName()
5738 .AppendASCII("PreferencesExternal");
5739
5740 InitializeInstalledExtensionService(pref_path, source_install_dir);
5741 service()->Init();
5742
5743 ASSERT_EQ(0u, GetErrors().size());
5744 ASSERT_EQ(0u, loaded_.size());
5745 }
5746
5747 // Test that running multiple update checks simultaneously does not
5748 // keep the update from succeeding.
TEST_F(ExtensionServiceTest,MultipleExternalUpdateCheck)5749 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
5750 InitializeEmptyExtensionService();
5751
5752 MockExternalProvider* provider =
5753 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
5754
5755 // Verify that starting with no providers loads no extensions.
5756 service()->Init();
5757 ASSERT_EQ(0u, loaded_.size());
5758
5759 // Start two checks for updates.
5760 provider->set_visit_count(0);
5761 service()->CheckForExternalUpdates();
5762 service()->CheckForExternalUpdates();
5763 content::RunAllTasksUntilIdle();
5764
5765 // Two calls should cause two checks for external extensions.
5766 EXPECT_EQ(2, provider->visit_count());
5767 EXPECT_EQ(0u, GetErrors().size());
5768 EXPECT_EQ(0u, loaded_.size());
5769
5770 // Register a test extension externally using the mock registry provider.
5771 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5772 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5773
5774 // Two checks for external updates should find the extension, and install it
5775 // once.
5776 content::WindowedNotificationObserver observer(
5777 NOTIFICATION_CRX_INSTALLER_DONE,
5778 content::NotificationService::AllSources());
5779 provider->set_visit_count(0);
5780 service()->CheckForExternalUpdates();
5781 service()->CheckForExternalUpdates();
5782 observer.Wait();
5783 EXPECT_EQ(2, provider->visit_count());
5784 ASSERT_EQ(0u, GetErrors().size());
5785 ASSERT_EQ(1u, loaded_.size());
5786 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
5787 ASSERT_EQ("1.0.0.0", loaded_[0]->version().GetString());
5788 ValidatePrefKeyCount(1);
5789 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5790 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
5791
5792 provider->RemoveExtension(good_crx);
5793 provider->set_visit_count(0);
5794 service()->CheckForExternalUpdates();
5795 service()->CheckForExternalUpdates();
5796 content::RunAllTasksUntilIdle();
5797
5798 // Two calls should cause two checks for external extensions.
5799 // Because the external source no longer includes good_crx,
5800 // good_crx will be uninstalled. So, expect that no extensions
5801 // are loaded.
5802 EXPECT_EQ(2, provider->visit_count());
5803 EXPECT_EQ(0u, GetErrors().size());
5804 EXPECT_EQ(0u, loaded_.size());
5805 }
5806
TEST_F(ExtensionServiceTest,ExternalPrefProvider)5807 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
5808 InitializeEmptyExtensionService();
5809
5810 // Test some valid extension records.
5811 // Set a base path to avoid erroring out on relative paths.
5812 // Paths starting with // are absolute on every platform we support.
5813 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5814 ASSERT_TRUE(base_path.IsAbsolute());
5815 MockProviderVisitor visitor(base_path);
5816 std::string json_data =
5817 "{"
5818 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5819 " \"external_crx\": \"RandomExtension.crx\","
5820 " \"external_version\": \"1.0\""
5821 " },"
5822 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5823 " \"external_crx\": \"RandomExtension2.crx\","
5824 " \"external_version\": \"2.0\""
5825 " },"
5826 " \"cccccccccccccccccccccccccccccccc\": {"
5827 " \"external_update_url\": \"http:\\\\foo.com/update\","
5828 " \"install_parameter\": \"id\""
5829 " }"
5830 "}";
5831 EXPECT_EQ(3, visitor.Visit(json_data));
5832
5833 // Simulate an external_extensions.json file that contains seven invalid
5834 // records:
5835 // - One that is missing the 'external_crx' key.
5836 // - One that is missing the 'external_version' key.
5837 // - One that is specifying .. in the path.
5838 // - One that specifies both a file and update URL.
5839 // - One that specifies no file or update URL.
5840 // - One that has an update URL that is not well formed.
5841 // - One that contains a malformed version.
5842 // - One that has an invalid id.
5843 // - One that has a non-dictionary value.
5844 // - One that has an integer 'external_version' instead of a string.
5845 // The final extension is valid, and we check that it is read to make sure
5846 // failures don't stop valid records from being read.
5847 json_data =
5848 "{"
5849 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5850 " \"external_version\": \"1.0\""
5851 " },"
5852 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5853 " \"external_crx\": \"RandomExtension.crx\""
5854 " },"
5855 " \"cccccccccccccccccccccccccccccccc\": {"
5856 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
5857 " \"external_version\": \"2.0\""
5858 " },"
5859 " \"dddddddddddddddddddddddddddddddd\": {"
5860 " \"external_crx\": \"RandomExtension2.crx\","
5861 " \"external_version\": \"2.0\","
5862 " \"external_update_url\": \"http:\\\\foo.com/update\""
5863 " },"
5864 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5865 " },"
5866 " \"ffffffffffffffffffffffffffffffff\": {"
5867 " \"external_update_url\": \"This string is not a valid URL\""
5868 " },"
5869 " \"gggggggggggggggggggggggggggggggg\": {"
5870 " \"external_crx\": \"RandomExtension3.crx\","
5871 " \"external_version\": \"This is not a valid version!\""
5872 " },"
5873 " \"This is not a valid id!\": {},"
5874 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
5875 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
5876 " \"external_crx\": \"RandomExtension4.crx\","
5877 " \"external_version\": 1.0"
5878 " },"
5879 " \"pppppppppppppppppppppppppppppppp\": {"
5880 " \"external_crx\": \"RandomValidExtension.crx\","
5881 " \"external_version\": \"1.0\""
5882 " }"
5883 "}";
5884 EXPECT_EQ(1, visitor.Visit(json_data));
5885
5886 // Check that if a base path is not provided, use of a relative
5887 // path fails.
5888 base::FilePath empty;
5889 MockProviderVisitor visitor_no_relative_paths(empty);
5890
5891 // Use absolute paths. Expect success.
5892 json_data =
5893 "{"
5894 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5895 " \"external_crx\": \"//RandomExtension1.crx\","
5896 " \"external_version\": \"3.0\""
5897 " },"
5898 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5899 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
5900 " \"external_version\": \"3.0\""
5901 " }"
5902 "}";
5903 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
5904
5905 // Use a relative path. Expect that it will error out.
5906 json_data =
5907 "{"
5908 " \"cccccccccccccccccccccccccccccccc\": {"
5909 " \"external_crx\": \"RandomExtension2.crx\","
5910 " \"external_version\": \"3.0\""
5911 " }"
5912 "}";
5913 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
5914
5915 // Test supported_locales.
5916 json_data =
5917 "{"
5918 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5919 " \"external_crx\": \"RandomExtension.crx\","
5920 " \"external_version\": \"1.0\","
5921 " \"supported_locales\": [ \"en\" ]"
5922 " },"
5923 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5924 " \"external_crx\": \"RandomExtension2.crx\","
5925 " \"external_version\": \"2.0\","
5926 " \"supported_locales\": [ \"en-GB\" ]"
5927 " },"
5928 " \"cccccccccccccccccccccccccccccccc\": {"
5929 " \"external_crx\": \"RandomExtension2.crx\","
5930 " \"external_version\": \"3.0\","
5931 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5932 " }"
5933 "}";
5934 {
5935 ScopedBrowserLocale guard("en-US");
5936 EXPECT_EQ(2, visitor.Visit(json_data));
5937 }
5938
5939 // Test web_app_migration_flag.
5940 {
5941 json_data = R"(
5942 {
5943 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": {
5944 "external_crx": "RandomExtension.crx",
5945 "external_version": "1.0",
5946 "web_app_migration_flag": "TestFeature"
5947 }
5948 })";
5949
5950 {
5951 base::AutoReset<bool> testing_scope =
5952 web_app::SetExternalAppInstallFeatureAlwaysEnabledForTesting();
5953 EXPECT_EQ(0, visitor.Visit(json_data));
5954 visitor.provider().HasExtension("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
5955 }
5956
5957 {
5958 EXPECT_EQ(1, visitor.Visit(json_data));
5959 visitor.provider().HasExtension("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
5960 }
5961 }
5962
5963 // Test keep_if_present.
5964 json_data =
5965 "{"
5966 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5967 " \"external_crx\": \"RandomExtension.crx\","
5968 " \"external_version\": \"1.0\","
5969 " \"keep_if_present\": true"
5970 " }"
5971 "}";
5972 {
5973 EXPECT_EQ(0, visitor.Visit(json_data));
5974 }
5975
5976 // Test is_bookmark_app.
5977 MockProviderVisitor from_bookmark_visitor(
5978 base_path, Extension::FROM_BOOKMARK);
5979 json_data =
5980 "{"
5981 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5982 " \"external_crx\": \"RandomExtension.crx\","
5983 " \"external_version\": \"1.0\","
5984 " \"is_bookmark_app\": true"
5985 " }"
5986 "}";
5987 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
5988
5989 // Test is_from_webstore.
5990 MockProviderVisitor from_webstore_visitor(
5991 base_path, Extension::FROM_WEBSTORE);
5992 json_data =
5993 "{"
5994 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5995 " \"external_crx\": \"RandomExtension.crx\","
5996 " \"external_version\": \"1.0\","
5997 " \"is_from_webstore\": true"
5998 " }"
5999 "}";
6000 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
6001
6002 // Test was_installed_by_eom.
6003 MockProviderVisitor was_installed_by_eom_visitor(
6004 base_path, Extension::WAS_INSTALLED_BY_OEM);
6005 json_data =
6006 "{"
6007 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
6008 " \"external_crx\": \"RandomExtension.crx\","
6009 " \"external_version\": \"1.0\","
6010 " \"was_installed_by_oem\": true"
6011 " }"
6012 "}";
6013 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data));
6014
6015 // Test min_profile_created_by_version.
6016 MockProviderVisitor min_profile_created_by_version_visitor(base_path);
6017 json_data =
6018 "{"
6019 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
6020 " \"external_crx\": \"RandomExtension.crx\","
6021 " \"external_version\": \"1.0\","
6022 " \"min_profile_created_by_version\": \"42.0.0.1\""
6023 " },"
6024 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
6025 " \"external_crx\": \"RandomExtension2.crx\","
6026 " \"external_version\": \"1.0\","
6027 " \"min_profile_created_by_version\": \"43.0.0.1\""
6028 " },"
6029 " \"cccccccccccccccccccccccccccccccc\": {"
6030 " \"external_crx\": \"RandomExtension3.crx\","
6031 " \"external_version\": \"3.0\","
6032 " \"min_profile_created_by_version\": \"44.0.0.1\""
6033 " }"
6034 "}";
6035 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
6036 prefs::kProfileCreatedByVersion, "40.0.0.1");
6037 EXPECT_EQ(0, min_profile_created_by_version_visitor.Visit(json_data));
6038 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
6039 prefs::kProfileCreatedByVersion, "43.0.0.1");
6040 EXPECT_EQ(2, min_profile_created_by_version_visitor.Visit(json_data));
6041 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
6042 prefs::kProfileCreatedByVersion, "45.0.0.1");
6043 EXPECT_EQ(3, min_profile_created_by_version_visitor.Visit(json_data));
6044 }
6045
TEST_F(ExtensionServiceTest,DoNotInstallForEnterprise)6046 TEST_F(ExtensionServiceTest, DoNotInstallForEnterprise) {
6047 InitializeEmptyExtensionService();
6048
6049 const base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
6050 ASSERT_TRUE(base_path.IsAbsolute());
6051 MockProviderVisitor visitor(base_path);
6052 policy::ProfilePolicyConnector* const connector =
6053 visitor.profile()->GetProfilePolicyConnector();
6054 connector->OverrideIsManagedForTesting(true);
6055 EXPECT_TRUE(connector->IsManaged());
6056
6057 std::string json_data =
6058 "{"
6059 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
6060 " \"external_crx\": \"RandomExtension.crx\","
6061 " \"external_version\": \"1.0\","
6062 " \"do_not_install_for_enterprise\": true"
6063 " },"
6064 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
6065 " \"external_crx\": \"RandomExtension2.crx\","
6066 " \"external_version\": \"1.0\""
6067 " }"
6068 "}";
6069 EXPECT_EQ(1, visitor.Visit(json_data));
6070 }
6071
TEST_F(ExtensionServiceTest,IncrementalUpdateThroughRegistry)6072 TEST_F(ExtensionServiceTest, IncrementalUpdateThroughRegistry) {
6073 InitializeEmptyExtensionService();
6074
6075 // Test some valid extension records.
6076 // Set a base path to avoid erroring out on relative paths.
6077 // Paths starting with // are absolute on every platform we support.
6078 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
6079 ASSERT_TRUE(base_path.IsAbsolute());
6080 MockUpdateProviderVisitor visitor(base_path);
6081 std::string json_data =
6082 "{"
6083 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
6084 " \"external_crx\": \"RandomExtension.crx\","
6085 " \"external_version\": \"1.0\""
6086 " },"
6087 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
6088 " \"external_crx\": \"RandomExtension2.crx\","
6089 " \"external_version\": \"2.0\""
6090 " },"
6091 " \"cccccccccccccccccccccccccccccccc\": {"
6092 " \"external_update_url\": \"http:\\\\foo.com/update\","
6093 " \"install_parameter\": \"id\""
6094 " }"
6095 "}";
6096 EXPECT_EQ(3, visitor.Visit(json_data, Manifest::EXTERNAL_REGISTRY,
6097 Manifest::EXTERNAL_PREF_DOWNLOAD));
6098
6099 // c* removed and d*, e*, f* added, a*, b* existing.
6100 json_data =
6101 "{"
6102 " \"dddddddddddddddddddddddddddddddd\": {"
6103 " \"external_crx\": \"RandomExtension3.crx\","
6104 " \"external_version\": \"1.0\""
6105 " },"
6106 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
6107 " \"external_update_url\": \"http:\\\\foo.com/update\","
6108 " \"install_parameter\": \"id\""
6109 " },"
6110 " \"ffffffffffffffffffffffffffffffff\": {"
6111 " \"external_update_url\": \"http:\\\\bar.com/update\","
6112 " \"install_parameter\": \"id\""
6113 " },"
6114 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
6115 " \"external_crx\": \"RandomExtension.crx\","
6116 " \"external_version\": \"1.0\""
6117 " },"
6118 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
6119 " \"external_crx\": \"RandomExtension2.crx\","
6120 " \"external_version\": \"2.0\""
6121 " }"
6122 "}";
6123
6124 // This will simulate registry loader observing new changes in registry and
6125 // hence will discover new extensions.
6126 visitor.VisitDueToUpdate(json_data);
6127
6128 // UpdateUrl.
6129 EXPECT_EQ(2u, visitor.GetUpdateURLExtensionCount());
6130 EXPECT_TRUE(
6131 visitor.HasSeenUpdateWithUpdateUrl("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"));
6132 EXPECT_TRUE(
6133 visitor.HasSeenUpdateWithUpdateUrl("ffffffffffffffffffffffffffffffff"));
6134
6135 // File.
6136 EXPECT_EQ(3u, visitor.GetFileExtensionCount());
6137 EXPECT_TRUE(
6138 visitor.HasSeenUpdateWithFile("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
6139 EXPECT_TRUE(
6140 visitor.HasSeenUpdateWithFile("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
6141 EXPECT_TRUE(
6142 visitor.HasSeenUpdateWithFile("dddddddddddddddddddddddddddddddd"));
6143
6144 // Removed extensions.
6145 EXPECT_EQ(1u, visitor.GetRemovedExtensionCount());
6146 EXPECT_TRUE(visitor.HasSeenRemoval("cccccccccccccccccccccccccccccccc"));
6147
6148 // Simulate all 5 extensions being removed.
6149 json_data = "{}";
6150 visitor.VisitDueToUpdate(json_data);
6151 EXPECT_EQ(0u, visitor.GetUpdateURLExtensionCount());
6152 EXPECT_EQ(0u, visitor.GetFileExtensionCount());
6153 EXPECT_EQ(5u, visitor.GetRemovedExtensionCount());
6154 }
6155
6156 // Test loading good extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAndRelocalizeExtensions)6157 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
6158 // Ensure we're testing in "en" and leave global state untouched.
6159 extension_l10n_util::ScopedLocaleForTest testLocale("en");
6160
6161 // Initialize the test dir with a good Preferences/extensions.
6162 base::FilePath source_install_dir = data_dir().AppendASCII("l10n");
6163 base::FilePath pref_path =
6164 source_install_dir.Append(chrome::kPreferencesFilename);
6165 InitializeInstalledExtensionService(pref_path, source_install_dir);
6166
6167 service()->Init();
6168
6169 ASSERT_EQ(3u, loaded_.size());
6170
6171 // This was equal to "sr" on load.
6172 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
6173
6174 // These are untouched by re-localization.
6175 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
6176 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
6177
6178 // This one starts with Serbian name, and gets re-localized into English.
6179 EXPECT_EQ("My name is simple.", loaded_[0]->name());
6180
6181 // These are untouched by re-localization.
6182 EXPECT_EQ("My name is simple.", loaded_[1]->name());
6183 EXPECT_EQ("no l10n", loaded_[2]->name());
6184 }
6185
6186 // Test that we get enabled/disabled correctly for all the pref/command-line
6187 // combinations. We don't want to derive from the ExtensionServiceTest class
6188 // for this test, so we use ExtensionServiceTestSimple.
6189 //
6190 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
6191 // enabled or not.
6192 class ExtensionServiceTestSimple : public testing::Test {
6193 content::BrowserTaskEnvironment task_environment_;
6194 };
6195
TEST_F(ExtensionServiceTestSimple,Enabledness)6196 TEST_F(ExtensionServiceTestSimple, Enabledness) {
6197 // Make sure the PluginService singleton is destroyed at the end of the test.
6198 base::ShadowingAtExitManager at_exit_manager;
6199 #if BUILDFLAG(ENABLE_PLUGINS)
6200 content::PluginService::GetInstance()->Init();
6201 #endif
6202
6203 LoadErrorReporter::Init(false); // no noisy errors
6204 std::unique_ptr<base::CommandLine> command_line;
6205
6206 // The profile lifetimes must not overlap: services may use global variables.
6207 {
6208 auto profile = std::make_unique<TestingProfile>();
6209 bool ready = false;
6210 auto on_ready = [](bool* ready) { *ready = true; };
6211 ExtensionSystem::Get(profile.get())
6212 ->ready()
6213 .Post(FROM_HERE, base::BindOnce(on_ready, &ready));
6214
6215 base::FilePath install_dir =
6216 profile->GetPath().AppendASCII(kInstallDirectoryName);
6217
6218 // By default, we are enabled.
6219 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
6220 ExtensionService* service =
6221 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile.get()))
6222 ->CreateExtensionService(command_line.get(), install_dir, false);
6223 EXPECT_TRUE(service->extensions_enabled());
6224 service->Init();
6225 content::RunAllTasksUntilIdle();
6226 EXPECT_TRUE(ready);
6227 }
6228
6229 {
6230 auto profile = std::make_unique<TestingProfile>();
6231 bool ready = false;
6232 auto on_ready = [](bool* ready) { *ready = true; };
6233 ExtensionSystem::Get(profile.get())
6234 ->ready()
6235 .Post(FROM_HERE, base::BindOnce(on_ready, &ready));
6236
6237 base::FilePath install_dir =
6238 profile->GetPath().AppendASCII(kInstallDirectoryName);
6239 command_line->AppendSwitch(::switches::kDisableExtensions);
6240 ExtensionService* service =
6241 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile.get()))
6242 ->CreateExtensionService(command_line.get(), install_dir, false);
6243 EXPECT_FALSE(service->extensions_enabled());
6244 service->Init();
6245 content::RunAllTasksUntilIdle();
6246 EXPECT_TRUE(ready);
6247 }
6248
6249 {
6250 auto profile = std::make_unique<TestingProfile>();
6251 bool ready = false;
6252 auto on_ready = [](bool* ready) { *ready = true; };
6253 ExtensionSystem::Get(profile.get())
6254 ->ready()
6255 .Post(FROM_HERE, base::BindOnce(on_ready, &ready));
6256
6257 base::FilePath install_dir =
6258 profile->GetPath().AppendASCII(kInstallDirectoryName);
6259 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
6260 ExtensionService* service =
6261 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile.get()))
6262 ->CreateExtensionService(command_line.get(), install_dir, false);
6263 EXPECT_FALSE(service->extensions_enabled());
6264 service->Init();
6265 content::RunAllTasksUntilIdle();
6266 EXPECT_TRUE(ready);
6267 }
6268
6269 {
6270 auto profile = std::make_unique<TestingProfile>();
6271 bool ready = false;
6272 auto on_ready = [](bool* ready) { *ready = true; };
6273 ExtensionSystem::Get(profile.get())
6274 ->ready()
6275 .Post(FROM_HERE, base::BindOnce(on_ready, &ready));
6276
6277 base::FilePath install_dir =
6278 profile->GetPath().AppendASCII(kInstallDirectoryName);
6279 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
6280 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
6281 ExtensionService* service =
6282 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile.get()))
6283 ->CreateExtensionService(command_line.get(), install_dir, false);
6284 EXPECT_FALSE(service->extensions_enabled());
6285 service->Init();
6286 content::RunAllTasksUntilIdle();
6287 EXPECT_TRUE(ready);
6288 }
6289
6290 // Execute any pending deletion tasks.
6291 content::RunAllTasksUntilIdle();
6292 }
6293
6294 // Test loading extensions that require limited and unlimited storage quotas.
TEST_F(ExtensionServiceTest,StorageQuota)6295 TEST_F(ExtensionServiceTest, StorageQuota) {
6296 InitializeEmptyExtensionService();
6297
6298 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota");
6299
6300 base::FilePath limited_quota_ext =
6301 extensions_path.AppendASCII("limited_quota")
6302 .AppendASCII("1.0");
6303
6304 // The old permission name for unlimited quota was "unlimited_storage", but
6305 // we changed it to "unlimitedStorage". This tests both versions.
6306 base::FilePath unlimited_quota_ext =
6307 extensions_path.AppendASCII("unlimited_quota")
6308 .AppendASCII("1.0");
6309 base::FilePath unlimited_quota_ext2 =
6310 extensions_path.AppendASCII("unlimited_quota")
6311 .AppendASCII("2.0");
6312 UnpackedInstaller::Create(service())->Load(limited_quota_ext);
6313 UnpackedInstaller::Create(service())->Load(unlimited_quota_ext);
6314 UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2);
6315 content::RunAllTasksUntilIdle();
6316
6317 ASSERT_EQ(3u, loaded_.size());
6318 EXPECT_TRUE(profile());
6319 EXPECT_FALSE(profile()->IsOffTheRecord());
6320 EXPECT_FALSE(
6321 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
6322 loaded_[0]->url()));
6323 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
6324 loaded_[1]->url()));
6325 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
6326 loaded_[2]->url()));
6327 }
6328
6329 // Tests ComponentLoader::Add().
TEST_F(ExtensionServiceTest,ComponentExtensions)6330 TEST_F(ExtensionServiceTest, ComponentExtensions) {
6331 // Component extensions should work even when extensions are disabled.
6332 InitializeExtensionServiceWithExtensionsDisabled();
6333
6334 base::FilePath path = data_dir()
6335 .AppendASCII("good")
6336 .AppendASCII("Extensions")
6337 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
6338 .AppendASCII("1.0.0.0");
6339
6340 std::string manifest;
6341 ASSERT_TRUE(
6342 base::ReadFileToString(path.Append(kManifestFilename), &manifest));
6343
6344 service()->component_loader()->Add(manifest, path);
6345 service()->Init();
6346
6347 // Note that we do not pump messages -- the extension should be loaded
6348 // immediately.
6349
6350 EXPECT_EQ(0u, GetErrors().size());
6351 ASSERT_EQ(1u, loaded_.size());
6352 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
6353 EXPECT_EQ(1u, registry()->enabled_extensions().size());
6354
6355 // Component extensions get a prefs entry on first install.
6356 ValidatePrefKeyCount(1);
6357
6358 // Reload all extensions, and make sure it comes back.
6359 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
6360 loaded_.clear();
6361 service()->ReloadExtensionsForTest();
6362 ASSERT_EQ(1u, registry()->enabled_extensions().size());
6363 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
6364 }
6365
TEST_F(ExtensionServiceTest,InstallPriorityExternalUpdateUrl)6366 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
6367 InitializeEmptyExtensionService();
6368
6369 base::FilePath path = data_dir().AppendASCII("good.crx");
6370 InstallCRX(path, INSTALL_NEW);
6371 ValidatePrefKeyCount(1u);
6372 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
6373 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
6374
6375 PendingExtensionManager* pending = service()->pending_extension_manager();
6376 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6377
6378 // Skip install when the location is the same.
6379 GURL good_update_url(kGoodUpdateURL);
6380 ExternalInstallInfoUpdateUrl info(
6381 kGoodId, std::string(), std::move(good_update_url), Manifest::INTERNAL,
6382 Extension::NO_FLAGS, false);
6383 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(info, true));
6384 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6385
6386 // Update the download location when install is requested from higher priority
6387 // location.
6388 info.download_location = Manifest::EXTERNAL_POLICY_DOWNLOAD;
6389 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(info, true));
6390 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6391
6392 // Try the low priority again. Should be rejected.
6393 info.download_location = Manifest::EXTERNAL_PREF_DOWNLOAD;
6394 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(info, true));
6395 // The existing record should still be present in the pending extension
6396 // manager.
6397 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6398
6399 // Skip install when the location has the same priority as the installed
6400 // location.
6401 info.download_location = Manifest::EXTERNAL_POLICY_DOWNLOAD;
6402 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(info, true));
6403
6404 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6405 }
6406
TEST_F(ExtensionServiceTest,InstallPriorityExternalLocalFile)6407 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
6408 base::Version older_version("0.1.0.0");
6409 base::Version newer_version("2.0.0.0");
6410
6411 // We don't want the extension to be installed. A path that doesn't
6412 // point to a valid CRX ensures this.
6413 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
6414
6415 const int kCreationFlags = 0;
6416 const bool kDontMarkAcknowledged = false;
6417 const bool kDontInstallImmediately = false;
6418
6419 InitializeEmptyExtensionService();
6420
6421 // The test below uses install source constants to test that
6422 // priority is enforced. It assumes a specific ranking of install
6423 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
6424 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
6425 // The following assertions verify these assumptions:
6426 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6427 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6428 Manifest::EXTERNAL_PREF));
6429 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6430 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6431 Manifest::INTERNAL));
6432 ASSERT_EQ(Manifest::EXTERNAL_PREF,
6433 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
6434 Manifest::INTERNAL));
6435
6436 PendingExtensionManager* pending = service()->pending_extension_manager();
6437 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6438
6439 ExternalInstallInfoFile info(kGoodId, older_version, kInvalidPathToCrx,
6440 Manifest::INTERNAL, kCreationFlags,
6441 kDontMarkAcknowledged, kDontInstallImmediately);
6442 {
6443 // Simulate an external source adding the extension as INTERNAL.
6444 content::WindowedNotificationObserver observer(
6445 NOTIFICATION_CRX_INSTALLER_DONE,
6446 content::NotificationService::AllSources());
6447 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
6448 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6449 observer.Wait();
6450 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6451 }
6452
6453 {
6454 // Simulate an external source adding the extension as EXTERNAL_PREF.
6455 content::WindowedNotificationObserver observer(
6456 NOTIFICATION_CRX_INSTALLER_DONE,
6457 content::NotificationService::AllSources());
6458 info.crx_location = Manifest::EXTERNAL_PREF;
6459 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
6460 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6461 observer.Wait();
6462 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6463 }
6464
6465 // Simulate an external source adding as EXTERNAL_PREF again.
6466 // This is rejected because the version and the location are the same as
6467 // the previous installation, which is still pending.
6468 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6469 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6470
6471 // Try INTERNAL again. Should fail.
6472 info.crx_location = Manifest::INTERNAL;
6473 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6474 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6475
6476 {
6477 // Now the registry adds the extension.
6478 content::WindowedNotificationObserver observer(
6479 NOTIFICATION_CRX_INSTALLER_DONE,
6480 content::NotificationService::AllSources());
6481 info.crx_location = Manifest::EXTERNAL_REGISTRY;
6482 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
6483 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6484 observer.Wait();
6485 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6486 }
6487
6488 // Registry outranks both external pref and internal, so both fail.
6489 info.crx_location = Manifest::EXTERNAL_PREF;
6490 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6491 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6492
6493 info.crx_location = Manifest::INTERNAL;
6494 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6495 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6496
6497 pending->Remove(kGoodId);
6498
6499 // Install the extension.
6500 base::FilePath path = data_dir().AppendASCII("good.crx");
6501 const Extension* ext = InstallCRX(path, INSTALL_NEW);
6502 ValidatePrefKeyCount(1u);
6503 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
6504 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
6505
6506 // Now test the logic of OnExternalExtensionFileFound() when the extension
6507 // being added is already installed.
6508
6509 // Tests assume |older_version| is less than the installed version, and
6510 // |newer_version| is greater. Verify this:
6511 ASSERT_LT(older_version, ext->version());
6512 ASSERT_GT(newer_version, ext->version());
6513
6514 // An external install for the same location should fail if the version is
6515 // older, or the same, and succeed if the version is newer.
6516
6517 // Older than the installed version...
6518 info.version = older_version;
6519 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6520 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6521
6522 // Same version as the installed version...
6523 info.version = ext->version();
6524 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6525 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6526
6527 // Newer than the installed version...
6528 info.version = newer_version;
6529 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
6530 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6531
6532 // An external install for a higher priority install source should succeed
6533 // if the version is greater. |older_version| is not...
6534 info.version = older_version;
6535 info.crx_location = Manifest::EXTERNAL_PREF;
6536 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6537 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6538
6539 // |newer_version| is newer.
6540 info.version = newer_version;
6541 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
6542 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6543
6544 // An external install for an even higher priority install source should
6545 // succeed if the version is greater.
6546 info.crx_location = Manifest::EXTERNAL_REGISTRY;
6547 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
6548 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6549
6550 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
6551 // adding from external pref will now fail.
6552 info.crx_location = Manifest::EXTERNAL_PREF;
6553 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6554 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6555 }
6556
TEST_F(ExtensionServiceTest,ConcurrentExternalLocalFile)6557 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
6558 base::Version kVersion123("1.2.3");
6559 base::Version kVersion124("1.2.4");
6560 base::Version kVersion125("1.2.5");
6561 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
6562 const int kCreationFlags = 0;
6563 const bool kDontMarkAcknowledged = false;
6564 const bool kDontInstallImmediately = false;
6565
6566 InitializeEmptyExtensionService();
6567
6568 PendingExtensionManager* pending = service()->pending_extension_manager();
6569 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6570
6571 // An external provider starts installing from a local crx.
6572 ExternalInstallInfoFile info(kGoodId, kVersion123, kInvalidPathToCrx,
6573 Manifest::EXTERNAL_PREF, kCreationFlags,
6574 kDontMarkAcknowledged, kDontInstallImmediately);
6575 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
6576
6577 const PendingExtensionInfo* pending_info;
6578 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6579 EXPECT_TRUE(pending_info->version().IsValid());
6580 EXPECT_EQ(pending_info->version(), kVersion123);
6581
6582 // Adding a newer version overrides the currently pending version.
6583 info.version = base::Version(kVersion124);
6584 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
6585 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6586 EXPECT_TRUE(pending_info->version().IsValid());
6587 EXPECT_EQ(pending_info->version(), kVersion124);
6588
6589 // Adding an older version fails.
6590 info.version = kVersion123;
6591 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6592 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6593 EXPECT_TRUE(pending_info->version().IsValid());
6594 EXPECT_EQ(pending_info->version(), kVersion124);
6595
6596 // Adding an older version fails even when coming from a higher-priority
6597 // location.
6598 info.crx_location = Manifest::EXTERNAL_REGISTRY;
6599 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
6600 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6601 EXPECT_TRUE(pending_info->version().IsValid());
6602 EXPECT_EQ(pending_info->version(), kVersion124);
6603
6604 // Adding the latest version from the webstore overrides a specific version.
6605 GURL kUpdateUrl("http://example.com/update");
6606 ExternalInstallInfoUpdateUrl update_info(kGoodId, std::string(), kUpdateUrl,
6607 Manifest::EXTERNAL_POLICY_DOWNLOAD,
6608 Extension::NO_FLAGS, false);
6609 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(update_info, true));
6610 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6611 EXPECT_FALSE(pending_info->version().IsValid());
6612 }
6613
6614 // This makes sure we can package and install CRX files that use allowlisted
6615 // permissions.
TEST_F(ExtensionServiceTest,InstallAllowlistedExtension)6616 TEST_F(ExtensionServiceTest, InstallAllowlistedExtension) {
6617 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
6618 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6619 switches::kAllowlistedExtensionID, test_id);
6620
6621 InitializeEmptyExtensionService();
6622 base::FilePath path = data_dir().AppendASCII("permissions");
6623 base::FilePath pem_path = path.AppendASCII("allowlist.pem");
6624 path = path.AppendASCII("allowlist");
6625
6626 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
6627 EXPECT_EQ(0u, GetErrors().size());
6628 ASSERT_EQ(1u, registry()->enabled_extensions().size());
6629 EXPECT_EQ(test_id, extension->id());
6630 }
6631
6632 // Test that when multiple sources try to install an extension,
6633 // we consistently choose the right one. To make tests easy to read,
6634 // methods that fake requests to install crx files in several ways
6635 // are provided.
6636 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
6637 public:
SetUp()6638 void SetUp() override {
6639 ExtensionServiceTest::SetUp();
6640
6641 // All tests use a single extension. Put the id and path in member vars
6642 // that all methods can read.
6643 crx_id_ = kGoodId;
6644 crx_path_ = data_dir().AppendASCII("good.crx");
6645 }
6646
6647 // Fake an external source adding a URL to fetch an extension from.
AddPendingExternalPrefUrl()6648 bool AddPendingExternalPrefUrl() {
6649 return service()->pending_extension_manager()->AddFromExternalUpdateUrl(
6650 crx_id_,
6651 std::string(),
6652 GURL(),
6653 Manifest::EXTERNAL_PREF_DOWNLOAD,
6654 Extension::NO_FLAGS,
6655 false);
6656 }
6657
6658 // Fake an external file from external_extensions.json.
AddPendingExternalPrefFileInstall()6659 bool AddPendingExternalPrefFileInstall() {
6660 ExternalInstallInfoFile info(crx_id_, base::Version("1.0.0.0"), crx_path_,
6661 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS,
6662 false, false);
6663 return service()->OnExternalExtensionFileFound(info);
6664 }
6665
6666 // Fake a request from sync to install an extension.
AddPendingSyncInstall()6667 bool AddPendingSyncInstall() {
6668 return service()->pending_extension_manager()->AddFromSync(
6669 crx_id_,
6670 GURL(kGoodUpdateURL),
6671 base::Version(),
6672 &IsExtension,
6673 kGoodRemoteInstall);
6674 }
6675
6676 // Fake a policy install.
AddPendingPolicyInstall()6677 bool AddPendingPolicyInstall() {
6678 // Get path to the CRX with id |kGoodId|.
6679 ExternalInstallInfoUpdateUrl info(crx_id_, std::string(), GURL(),
6680 Manifest::EXTERNAL_POLICY_DOWNLOAD,
6681 Extension::NO_FLAGS, false);
6682 return service()->OnExternalExtensionUpdateUrlFound(info, true);
6683 }
6684
6685 // Get the install source of a pending extension.
GetPendingLocation()6686 Manifest::Location GetPendingLocation() {
6687 const PendingExtensionInfo* info;
6688 EXPECT_TRUE(
6689 (info = service()->pending_extension_manager()->GetById(crx_id_)));
6690 return info->install_source();
6691 }
6692
6693 // Is an extension pending from a sync request?
GetPendingIsFromSync()6694 bool GetPendingIsFromSync() {
6695 const PendingExtensionInfo* info;
6696 EXPECT_TRUE(
6697 (info = service()->pending_extension_manager()->GetById(crx_id_)));
6698 return info->is_from_sync();
6699 }
6700
6701 // Is the CRX id these tests use pending?
IsCrxPending()6702 bool IsCrxPending() {
6703 return service()->pending_extension_manager()->IsIdPending(crx_id_);
6704 }
6705
6706 // Is an extension installed?
IsCrxInstalled()6707 bool IsCrxInstalled() {
6708 return (registry()->GetExtensionById(
6709 crx_id_, ExtensionRegistry::EVERYTHING) != nullptr);
6710 }
6711
6712 protected:
6713 // All tests use a single extension. Making the id and path member
6714 // vars avoids pasing the same argument to every method.
6715 std::string crx_id_;
6716 base::FilePath crx_path_;
6717 };
6718
6719 // Test that a pending request for installation of an external CRX from
6720 // an update URL overrides a pending request to install the same extension
6721 // from sync.
TEST_F(ExtensionSourcePriorityTest,PendingExternalFileOverSync)6722 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
6723 InitializeEmptyExtensionService();
6724
6725 ASSERT_FALSE(IsCrxInstalled());
6726
6727 // Install pending extension from sync.
6728 content::WindowedNotificationObserver observer(
6729 NOTIFICATION_CRX_INSTALLER_DONE,
6730 content::NotificationService::AllSources());
6731 EXPECT_TRUE(AddPendingSyncInstall());
6732 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
6733 EXPECT_TRUE(GetPendingIsFromSync());
6734 ASSERT_FALSE(IsCrxInstalled());
6735
6736 // Install pending as external prefs json would.
6737 AddPendingExternalPrefFileInstall();
6738 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
6739 ASSERT_FALSE(IsCrxInstalled());
6740
6741 // Another request from sync should be ignored.
6742 EXPECT_FALSE(AddPendingSyncInstall());
6743 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
6744 ASSERT_FALSE(IsCrxInstalled());
6745
6746 observer.Wait();
6747 VerifyCrxInstall(crx_path_, INSTALL_NEW);
6748 ASSERT_TRUE(IsCrxInstalled());
6749 }
6750
6751 // Test that an install of an external CRX from an update overrides
6752 // an install of the same extension from sync.
TEST_F(ExtensionSourcePriorityTest,PendingExternalUrlOverSync)6753 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
6754 InitializeEmptyExtensionService();
6755 ASSERT_FALSE(IsCrxInstalled());
6756
6757 EXPECT_TRUE(AddPendingSyncInstall());
6758 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
6759 EXPECT_TRUE(GetPendingIsFromSync());
6760 ASSERT_FALSE(IsCrxInstalled());
6761
6762 ASSERT_TRUE(AddPendingExternalPrefUrl());
6763 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
6764 EXPECT_FALSE(GetPendingIsFromSync());
6765 ASSERT_FALSE(IsCrxInstalled());
6766
6767 EXPECT_FALSE(AddPendingSyncInstall());
6768 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
6769 EXPECT_FALSE(GetPendingIsFromSync());
6770 ASSERT_FALSE(IsCrxInstalled());
6771 }
6772
6773 // Test that an external install request stops sync from installing
6774 // the same extension.
TEST_F(ExtensionSourcePriorityTest,InstallExternalBlocksSyncRequest)6775 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
6776 InitializeEmptyExtensionService();
6777 ASSERT_FALSE(IsCrxInstalled());
6778
6779 // External prefs starts an install.
6780 AddPendingExternalPrefFileInstall();
6781
6782 // Crx installer was made, but has not yet run.
6783 ASSERT_FALSE(IsCrxInstalled());
6784
6785 // Before the CRX installer runs, Sync requests that the same extension
6786 // be installed. Should fail, because an external source is pending.
6787 content::WindowedNotificationObserver observer(
6788 NOTIFICATION_CRX_INSTALLER_DONE,
6789 content::NotificationService::AllSources());
6790 ASSERT_FALSE(AddPendingSyncInstall());
6791
6792 // Wait for the external source to install.
6793 observer.Wait();
6794 VerifyCrxInstall(crx_path_, INSTALL_NEW);
6795 ASSERT_TRUE(IsCrxInstalled());
6796
6797 // Now that the extension is installed, sync request should fail
6798 // because the extension is already installed.
6799 ASSERT_FALSE(AddPendingSyncInstall());
6800 }
6801
6802 // Test that the blocked pending external extension should be ignored until
6803 // it's unblocked. (crbug.com/797369)
TEST_F(ExtensionServiceTest,BlockedExternalExtension)6804 TEST_F(ExtensionServiceTest, BlockedExternalExtension) {
6805 FeatureSwitch::ScopedOverride prompt(
6806 FeatureSwitch::prompt_for_external_extensions(), true);
6807
6808 InitializeEmptyExtensionService();
6809 MockExternalProvider* provider =
6810 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
6811
6812 service()->external_install_manager()->UpdateExternalExtensionAlert();
6813 EXPECT_FALSE(HasExternalInstallErrors(service()));
6814
6815 service()->BlockAllExtensions();
6816
6817 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
6818 data_dir().AppendASCII("page_action.crx"));
6819
6820 WaitForExternalExtensionInstalled();
6821 EXPECT_FALSE(HasExternalInstallErrors(service()));
6822
6823 service()->UnblockAllExtensions();
6824 EXPECT_TRUE(HasExternalInstallErrors(service()));
6825 }
6826
6827 // Test that installing an external extension displays a GlobalError.
TEST_F(ExtensionServiceTest,ExternalInstallGlobalError)6828 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
6829 FeatureSwitch::ScopedOverride prompt(
6830 FeatureSwitch::prompt_for_external_extensions(), true);
6831
6832 InitializeEmptyExtensionService();
6833 MockExternalProvider* provider =
6834 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
6835
6836 service()->external_install_manager()->UpdateExternalExtensionAlert();
6837 // Should return false, meaning there aren't any extensions that the user
6838 // needs to know about.
6839 EXPECT_FALSE(HasExternalInstallErrors(service()));
6840
6841 // This is a normal extension, installed normally.
6842 // This should NOT trigger an alert.
6843 base::FilePath path = data_dir().AppendASCII("good.crx");
6844 InstallCRX(path, INSTALL_NEW);
6845
6846 service()->CheckForExternalUpdates();
6847 content::RunAllTasksUntilIdle();
6848 EXPECT_FALSE(HasExternalInstallErrors(service()));
6849
6850 // A hosted app, installed externally.
6851 // This should NOT trigger an alert.
6852 provider->UpdateOrAddExtension(
6853 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx"));
6854
6855 WaitForExternalExtensionInstalled();
6856 EXPECT_FALSE(HasExternalInstallErrors(service()));
6857
6858 // Another normal extension, but installed externally.
6859 // This SHOULD trigger an alert.
6860 provider->UpdateOrAddExtension(
6861 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
6862
6863 WaitForExternalExtensionInstalled();
6864 EXPECT_TRUE(HasExternalInstallErrors(service()));
6865 }
6866
6867 // Test that external extensions are initially disabled, and that enabling
6868 // them clears the prompt.
TEST_F(ExtensionServiceTest,ExternalInstallInitiallyDisabled)6869 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
6870 FeatureSwitch::ScopedOverride prompt(
6871 FeatureSwitch::prompt_for_external_extensions(), true);
6872
6873 InitializeEmptyExtensionService();
6874 MockExternalProvider* provider =
6875 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
6876
6877 provider->UpdateOrAddExtension(
6878 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
6879 WaitForExternalExtensionInstalled();
6880
6881 EXPECT_TRUE(HasExternalInstallErrors(service()));
6882 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
6883
6884 const Extension* extension =
6885 registry()->disabled_extensions().GetByID(page_action);
6886 EXPECT_TRUE(extension);
6887 EXPECT_EQ(page_action, extension->id());
6888
6889 service()->EnableExtension(page_action);
6890 EXPECT_FALSE(HasExternalInstallErrors(service()));
6891 EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
6892 }
6893
6894 // As for components, only external component extensions can be disabled.
TEST_F(ExtensionServiceTest,DisablingComponentExtensions)6895 TEST_F(ExtensionServiceTest, DisablingComponentExtensions) {
6896 InitializeEmptyExtensionService();
6897 service_->Init();
6898
6899 scoped_refptr<const Extension> external_component_extension = CreateExtension(
6900 "external_component_extension",
6901 base::FilePath(FILE_PATH_LITERAL("//external_component_extension")),
6902 Manifest::EXTERNAL_COMPONENT);
6903 service_->AddExtension(external_component_extension.get());
6904 EXPECT_TRUE(registry()->enabled_extensions().Contains(
6905 external_component_extension->id()));
6906 service_->DisableExtension(external_component_extension->id(),
6907 disable_reason::DISABLE_USER_ACTION);
6908 EXPECT_TRUE(registry()->disabled_extensions().Contains(
6909 external_component_extension->id()));
6910
6911 scoped_refptr<const Extension> component_extension = CreateExtension(
6912 "component_extension",
6913 base::FilePath(FILE_PATH_LITERAL("//component_extension")),
6914 Manifest::COMPONENT);
6915 service_->AddExtension(component_extension.get());
6916 EXPECT_TRUE(
6917 registry()->enabled_extensions().Contains(component_extension->id()));
6918 service_->DisableExtension(component_extension->id(),
6919 disable_reason::DISABLE_USER_ACTION);
6920 EXPECT_FALSE(
6921 registry()->disabled_extensions().Contains(component_extension->id()));
6922 }
6923
6924 // Test that installing multiple external extensions works.
6925 // Flaky on windows; http://crbug.com/295757 .
6926 // Causes race conditions with an in-process utility thread, so disable under
6927 // TSan: https://crbug.com/518957
6928 #if defined(OS_WIN) || defined(THREAD_SANITIZER)
6929 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
6930 #else
6931 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
6932 #endif
TEST_F(ExtensionServiceTest,MAYBE_ExternalInstallMultiple)6933 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
6934 FeatureSwitch::ScopedOverride prompt(
6935 FeatureSwitch::prompt_for_external_extensions(), true);
6936
6937 InitializeEmptyExtensionService();
6938 MockExternalProvider* provider =
6939 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
6940
6941 provider->UpdateOrAddExtension(
6942 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
6943 provider->UpdateOrAddExtension(
6944 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
6945 provider->UpdateOrAddExtension(
6946 theme_crx, "2.0", data_dir().AppendASCII("theme.crx"));
6947
6948 int count = 3;
6949 content::WindowedNotificationObserver observer(
6950 NOTIFICATION_CRX_INSTALLER_DONE,
6951 base::Bind(&WaitForCountNotificationsCallback, &count));
6952 service()->CheckForExternalUpdates();
6953 observer.Wait();
6954 EXPECT_TRUE(HasExternalInstallErrors(service()));
6955 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
6956 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6957 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx));
6958
6959 service()->EnableExtension(page_action);
6960 EXPECT_FALSE(GetError(page_action));
6961 EXPECT_TRUE(GetError(good_crx));
6962 EXPECT_TRUE(GetError(theme_crx));
6963 EXPECT_TRUE(HasExternalInstallErrors(service()));
6964 EXPECT_FALSE(HasExternalInstallBubble(service()));
6965
6966 service()->EnableExtension(theme_crx);
6967 EXPECT_FALSE(GetError(page_action));
6968 EXPECT_FALSE(GetError(theme_crx));
6969 EXPECT_TRUE(GetError(good_crx));
6970 EXPECT_TRUE(HasExternalInstallErrors(service()));
6971 EXPECT_FALSE(HasExternalInstallBubble(service()));
6972
6973 service()->EnableExtension(good_crx);
6974 EXPECT_FALSE(GetError(page_action));
6975 EXPECT_FALSE(GetError(good_crx));
6976 EXPECT_FALSE(GetError(theme_crx));
6977 EXPECT_FALSE(HasExternalInstallErrors(service()));
6978 EXPECT_FALSE(HasExternalInstallBubble(service()));
6979 }
6980
TEST_F(ExtensionServiceTest,MultipleExternalInstallErrors)6981 TEST_F(ExtensionServiceTest, MultipleExternalInstallErrors) {
6982 FeatureSwitch::ScopedOverride prompt(
6983 FeatureSwitch::prompt_for_external_extensions(), true);
6984 InitializeEmptyExtensionService();
6985
6986 MockExternalProvider* reg_provider =
6987 AddMockExternalProvider(Manifest::EXTERNAL_REGISTRY);
6988
6989 std::string extension_info[][3] = {
6990 // {id, path, version}
6991 {good_crx, "1.0.0.0", "good.crx"},
6992 {page_action, "1.0.0.0", "page_action.crx"},
6993 {minimal_platform_app_crx, "0.1", "minimal_platform_app.crx"}};
6994
6995 for (size_t i = 0; i < base::size(extension_info); ++i) {
6996 reg_provider->UpdateOrAddExtension(
6997 extension_info[i][0], extension_info[i][1],
6998 data_dir().AppendASCII(extension_info[i][2]));
6999 WaitForExternalExtensionInstalled();
7000 const size_t expected_error_count = i + 1u;
7001 EXPECT_EQ(
7002 expected_error_count,
7003 service()->external_install_manager()->GetErrorsForTesting().size());
7004 EXPECT_FALSE(service()->IsExtensionEnabled(extension_info[i][0]));
7005 }
7006
7007 std::string extension_ids[] = {
7008 extension_info[0][0], extension_info[1][0], extension_info[2][0]
7009 };
7010
7011 // Each extension should end up in error.
7012 ASSERT_TRUE(GetError(extension_ids[0]));
7013 EXPECT_TRUE(GetError(extension_ids[1]));
7014 EXPECT_TRUE(GetError(extension_ids[2]));
7015
7016 // Accept the first extension, this will remove the error associated with
7017 // this extension. Also verify the other errors still exist.
7018 GetError(extension_ids[0])->OnInstallPromptDone(
7019 ExtensionInstallPrompt::Result::ACCEPTED);
7020 EXPECT_FALSE(GetError(extension_ids[0]));
7021 ASSERT_TRUE(GetError(extension_ids[1]));
7022 EXPECT_TRUE(GetError(extension_ids[2]));
7023
7024 // Abort the second extension.
7025 GetError(extension_ids[1])->OnInstallPromptDone(
7026 ExtensionInstallPrompt::Result::USER_CANCELED);
7027 EXPECT_FALSE(GetError(extension_ids[0]));
7028 EXPECT_FALSE(GetError(extension_ids[1]));
7029 ASSERT_TRUE(GetError(extension_ids[2]));
7030
7031 // Finally, re-enable the third extension, all errors should be removed.
7032 service()->EnableExtension(extension_ids[2]);
7033 EXPECT_FALSE(GetError(extension_ids[0]));
7034 EXPECT_FALSE(GetError(extension_ids[1]));
7035 EXPECT_FALSE(GetError(extension_ids[2]));
7036
7037 EXPECT_FALSE(HasExternalInstallErrors(service_));
7038 }
7039
7040 // Regression test for crbug.com/739142. Verifies that no UAF occurs when
7041 // ExternalInstallError needs to be deleted asynchronously.
TEST_F(ExtensionServiceTest,InstallPromptAborted)7042 TEST_F(ExtensionServiceTest, InstallPromptAborted) {
7043 FeatureSwitch::ScopedOverride prompt(
7044 FeatureSwitch::prompt_for_external_extensions(), true);
7045 InitializeEmptyExtensionService();
7046
7047 MockExternalProvider* reg_provider =
7048 AddMockExternalProvider(Manifest::EXTERNAL_REGISTRY);
7049
7050 reg_provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
7051 data_dir().AppendASCII("good.crx"));
7052 WaitForExternalExtensionInstalled();
7053 EXPECT_EQ(
7054 1u, service()->external_install_manager()->GetErrorsForTesting().size());
7055 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
7056 EXPECT_TRUE(GetError(good_crx));
7057
7058 // Abort the extension install prompt. This should cause the
7059 // ExternalInstallError to be deleted asynchronously.
7060 GetError(good_crx)->OnInstallPromptDone(
7061 ExtensionInstallPrompt::Result::ABORTED);
7062 EXPECT_TRUE(GetError(good_crx));
7063 base::RunLoop().RunUntilIdle();
7064 EXPECT_FALSE(GetError(good_crx));
7065
7066 EXPECT_FALSE(HasExternalInstallErrors(service_));
7067 }
7068
TEST_F(ExtensionServiceTest,MultipleExternalInstallBubbleErrors)7069 TEST_F(ExtensionServiceTest, MultipleExternalInstallBubbleErrors) {
7070 FeatureSwitch::ScopedOverride prompt(
7071 FeatureSwitch::prompt_for_external_extensions(), true);
7072 // This sets up the ExtensionPrefs used by our ExtensionService to be
7073 // post-first run.
7074 ExtensionServiceInitParams params = CreateDefaultInitParams();
7075 params.is_first_run = false;
7076 InitializeExtensionService(params);
7077
7078 MockExternalProvider* provider =
7079 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
7080
7081 std::vector<BubbleErrorsTestData> data;
7082 data.push_back(BubbleErrorsTestData(
7083 updates_from_webstore, "1",
7084 temp_dir().GetPath().AppendASCII("webstore.crx"), 1u));
7085 data.push_back(BubbleErrorsTestData(
7086 updates_from_webstore2, "1",
7087 temp_dir().GetPath().AppendASCII("webstore2.crx"), 2u));
7088 data.push_back(BubbleErrorsTestData(good_crx, "1.0.0.0",
7089 data_dir().AppendASCII("good.crx"), 2u));
7090
7091 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7092 data_dir().AppendASCII("update_from_webstore.pem"), data[0].crx_path);
7093 PackCRX(data_dir().AppendASCII("update_from_webstore2"),
7094 data_dir().AppendASCII("update_from_webstore2.pem"),
7095 data[1].crx_path);
7096
7097 // Install extensions from |data| one by one and expect each of them to result
7098 // in an error. The first two extensions are from webstore, so they will
7099 // trigger BUBBLE_ALERT type errors. After each step, we verify that we got
7100 // the expected number of errors in external_install_manager(). We also verify
7101 // that only the first BUBBLE_ALERT error is shown.
7102 for (size_t i = 0; i < data.size(); ++i) {
7103 test::GlobalErrorWaiter error_waiter(profile());
7104 provider->UpdateOrAddExtension(data[i].id, data[i].version,
7105 data[i].crx_path);
7106 WaitForExternalExtensionInstalled();
7107 // Make sure ExternalInstallError::OnDialogReady() fires.
7108 error_waiter.Wait();
7109
7110 const size_t expected_error_count = i + 1u;
7111 std::vector<ExternalInstallError*> errors =
7112 service_->external_install_manager()->GetErrorsForTesting();
7113 EXPECT_EQ(expected_error_count, errors.size());
7114 EXPECT_EQ(data[i].expected_bubble_error_count,
7115 GetExternalInstallBubbleCount(service()));
7116 EXPECT_TRUE(service()
7117 ->external_install_manager()
7118 ->has_currently_visible_install_alert());
7119 // Make sure that the first error is only being shown.
7120 EXPECT_EQ(errors[0], service()
7121 ->external_install_manager()
7122 ->currently_visible_install_alert_for_testing());
7123 EXPECT_FALSE(service()->IsExtensionEnabled(data[i].id));
7124 }
7125
7126 // Cancel all the install prompts.
7127 for (size_t i = 0; i < data.size(); ++i) {
7128 const std::string& extension_id = data[i].id;
7129 EXPECT_TRUE(GetError(extension_id));
7130 GetError(extension_id)
7131 ->OnInstallPromptDone(ExtensionInstallPrompt::Result::USER_CANCELED);
7132 EXPECT_FALSE(GetError(extension_id));
7133 }
7134 EXPECT_FALSE(service()
7135 ->external_install_manager()
7136 ->has_currently_visible_install_alert());
7137 EXPECT_EQ(0u, GetExternalInstallBubbleCount(service()));
7138 EXPECT_FALSE(HasExternalInstallErrors(service()));
7139
7140 // Add a new webstore install. Verify that this shows an error bubble since
7141 // there are no error bubbles pending at this point. Also verify that the
7142 // error bubble is for this newly added extension.
7143 {
7144 base::FilePath webstore_crx_three =
7145 temp_dir().GetPath().AppendASCII("webstore3.crx");
7146 PackCRX(data_dir().AppendASCII("update_from_webstore3"),
7147 data_dir().AppendASCII("update_from_webstore3.pem"),
7148 webstore_crx_three);
7149
7150 test::GlobalErrorWaiter error_waiter(profile());
7151 provider->UpdateOrAddExtension(
7152 updates_from_webstore3, "1",
7153 temp_dir().GetPath().AppendASCII("webstore3.crx"));
7154 WaitForExternalExtensionInstalled();
7155 // Make sure ExternalInstallError::OnDialogReady() fires.
7156 error_waiter.Wait();
7157
7158 std::vector<ExternalInstallError*> errors =
7159 service_->external_install_manager()->GetErrorsForTesting();
7160 EXPECT_EQ(1u, errors.size());
7161 EXPECT_EQ(1u, GetExternalInstallBubbleCount(service()));
7162 EXPECT_TRUE(service()
7163 ->external_install_manager()
7164 ->has_currently_visible_install_alert());
7165 // Verify that the visible alert is for the current error.
7166 EXPECT_EQ(errors[0], service()
7167 ->external_install_manager()
7168 ->currently_visible_install_alert_for_testing());
7169 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore3));
7170 }
7171 }
7172
7173 // Verifies that an error alert of type BUBBLE_ALERT does not replace an
7174 // existing visible alert that was previously opened by clicking menu item.
TEST_F(ExtensionServiceTest,BubbleAlertDoesNotHideAnotherAlertFromMenu)7175 TEST_F(ExtensionServiceTest, BubbleAlertDoesNotHideAnotherAlertFromMenu) {
7176 FeatureSwitch::ScopedOverride prompt(
7177 FeatureSwitch::prompt_for_external_extensions(), true);
7178 // This sets up the ExtensionPrefs used by our ExtensionService to be
7179 // post-first run.
7180 ExtensionServiceInitParams params = CreateDefaultInitParams();
7181 params.is_first_run = false;
7182 InitializeExtensionService(params);
7183
7184 MockExternalProvider* provider =
7185 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
7186
7187 std::vector<BubbleErrorsTestData> data;
7188 data.push_back(BubbleErrorsTestData(
7189 updates_from_webstore, "1",
7190 temp_dir().GetPath().AppendASCII("webstore.crx"), 1u));
7191 data.push_back(BubbleErrorsTestData(
7192 updates_from_webstore2, "1",
7193 temp_dir().GetPath().AppendASCII("webstore2.crx"), 2u));
7194
7195 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7196 data_dir().AppendASCII("update_from_webstore.pem"), data[0].crx_path);
7197 PackCRX(data_dir().AppendASCII("update_from_webstore2"),
7198 data_dir().AppendASCII("update_from_webstore2.pem"),
7199 data[1].crx_path);
7200 {
7201 test::GlobalErrorWaiter error_waiter(profile());
7202 provider->UpdateOrAddExtension(data[0].id, data[0].version,
7203 data[0].crx_path);
7204 WaitForExternalExtensionInstalled();
7205 // Make sure ExternalInstallError::OnDialogReady() fires.
7206 error_waiter.Wait();
7207
7208 std::vector<ExternalInstallError*> errors =
7209 service_->external_install_manager()->GetErrorsForTesting();
7210 EXPECT_EQ(1u, errors.size());
7211 EXPECT_EQ(1u, GetExternalInstallBubbleCount(service()));
7212 EXPECT_TRUE(service()
7213 ->external_install_manager()
7214 ->has_currently_visible_install_alert());
7215 // Verify that the visible alert is for the current error.
7216 EXPECT_EQ(errors[0], service()
7217 ->external_install_manager()
7218 ->currently_visible_install_alert_for_testing());
7219 }
7220
7221 ExternalInstallError* first_extension_error = GetError(data[0].id);
7222
7223 // Close the bubble alert.
7224 GlobalError* global_error =
7225 GlobalErrorServiceFactory::GetForProfile(profile())
7226 ->GetHighestSeverityGlobalErrorWithAppMenuItem();
7227 first_extension_error->DidCloseBubbleView();
7228
7229 // Bring the bubble alert error again by clicking its menu item.
7230 global_error->ExecuteMenuItem(nullptr);
7231
7232 // Install another webstore extension that will trigger an erorr of type
7233 // BUBBLE_ALERT.
7234 // Make sure that this bubble alert does not replace the current bubble alert.
7235 {
7236 test::GlobalErrorWaiter error_waiter(profile());
7237 provider->UpdateOrAddExtension(data[1].id, data[1].version,
7238 data[1].crx_path);
7239 WaitForExternalExtensionInstalled();
7240 // Make sure ExternalInstallError::OnDialogReady() fires.
7241 error_waiter.Wait();
7242
7243 std::vector<ExternalInstallError*> errors =
7244 service_->external_install_manager()->GetErrorsForTesting();
7245 EXPECT_EQ(2u, errors.size());
7246 EXPECT_EQ(2u, GetExternalInstallBubbleCount(service()));
7247 EXPECT_TRUE(service()
7248 ->external_install_manager()
7249 ->has_currently_visible_install_alert());
7250 // Verify that the old bubble alert was *not* replaced by the new alert.
7251 EXPECT_EQ(first_extension_error,
7252 service()
7253 ->external_install_manager()
7254 ->currently_visible_install_alert_for_testing());
7255 }
7256 }
7257
7258 // Test that there is a bubble for external extensions that update
7259 // from the webstore if the profile is not new.
TEST_F(ExtensionServiceTest,ExternalInstallUpdatesFromWebstoreOldProfile)7260 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
7261 FeatureSwitch::ScopedOverride prompt(
7262 FeatureSwitch::prompt_for_external_extensions(), true);
7263
7264 // This sets up the ExtensionPrefs used by our ExtensionService to be
7265 // post-first run.
7266 ExtensionServiceInitParams params = CreateDefaultInitParams();
7267 params.is_first_run = false;
7268 InitializeExtensionService(params);
7269
7270 base::FilePath crx_path = temp_dir().GetPath().AppendASCII("webstore.crx");
7271 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7272 data_dir().AppendASCII("update_from_webstore.pem"),
7273 crx_path);
7274
7275 MockExternalProvider* provider =
7276 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
7277 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7278 WaitForExternalExtensionInstalled();
7279
7280 EXPECT_TRUE(HasExternalInstallErrors(service()));
7281 ASSERT_TRUE(GetError(updates_from_webstore));
7282 EXPECT_EQ(ExternalInstallError::BUBBLE_ALERT,
7283 GetError(updates_from_webstore)->alert_type());
7284 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7285 }
7286
7287 // Test that there is no bubble for external extensions if the profile is new.
TEST_F(ExtensionServiceTest,ExternalInstallUpdatesFromWebstoreNewProfile)7288 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
7289 FeatureSwitch::ScopedOverride prompt(
7290 FeatureSwitch::prompt_for_external_extensions(), true);
7291
7292 InitializeEmptyExtensionService();
7293
7294 base::FilePath crx_path = temp_dir().GetPath().AppendASCII("webstore.crx");
7295 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7296 data_dir().AppendASCII("update_from_webstore.pem"),
7297 crx_path);
7298
7299 MockExternalProvider* provider =
7300 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
7301 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7302 WaitForExternalExtensionInstalled();
7303
7304 EXPECT_TRUE(HasExternalInstallErrors(service()));
7305 ASSERT_TRUE(GetError(updates_from_webstore));
7306 EXPECT_NE(ExternalInstallError::BUBBLE_ALERT,
7307 GetError(updates_from_webstore)->alert_type());
7308 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7309 }
7310
7311 // Test that clicking to remove the extension on an external install warning
7312 // uninstalls the extension.
TEST_F(ExtensionServiceTest,ExternalInstallClickToRemove)7313 TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) {
7314 FeatureSwitch::ScopedOverride prompt(
7315 FeatureSwitch::prompt_for_external_extensions(), true);
7316
7317 ExtensionServiceInitParams params = CreateDefaultInitParams();
7318 params.is_first_run = false;
7319 InitializeExtensionService(params);
7320
7321 base::FilePath crx_path = temp_dir().GetPath().AppendASCII("webstore.crx");
7322 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7323 data_dir().AppendASCII("update_from_webstore.pem"),
7324 crx_path);
7325
7326 MockExternalProvider* provider =
7327 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
7328 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7329 WaitForExternalExtensionInstalled();
7330
7331 EXPECT_TRUE(HasExternalInstallErrors(service_));
7332
7333 // We check both enabled and disabled, since these are "eventually exclusive"
7334 // sets.
7335 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7336 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7337
7338 // Click the negative response.
7339 service_->external_install_manager()
7340 ->GetErrorsForTesting()[0]
7341 ->OnInstallPromptDone(ExtensionInstallPrompt::Result::USER_CANCELED);
7342 // The Extension should be uninstalled.
7343 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore,
7344 ExtensionRegistry::EVERYTHING));
7345 // The error should be removed.
7346 EXPECT_FALSE(HasExternalInstallErrors(service_));
7347 }
7348
7349 // Test that clicking to keep the extension on an external install warning
7350 // re-enables the extension.
TEST_F(ExtensionServiceTest,ExternalInstallClickToKeep)7351 TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) {
7352 FeatureSwitch::ScopedOverride prompt(
7353 FeatureSwitch::prompt_for_external_extensions(), true);
7354
7355 ExtensionServiceInitParams params = CreateDefaultInitParams();
7356 params.is_first_run = false;
7357 InitializeExtensionService(params);
7358
7359 base::FilePath crx_path = temp_dir().GetPath().AppendASCII("webstore.crx");
7360 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7361 data_dir().AppendASCII("update_from_webstore.pem"),
7362 crx_path);
7363
7364 MockExternalProvider* provider =
7365 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
7366 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7367 WaitForExternalExtensionInstalled();
7368
7369 EXPECT_TRUE(HasExternalInstallErrors(service_));
7370
7371 // We check both enabled and disabled, since these are "eventually exclusive"
7372 // sets.
7373 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7374 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7375
7376 // Accept the extension.
7377 service_->external_install_manager()
7378 ->GetErrorsForTesting()[0]
7379 ->OnInstallPromptDone(ExtensionInstallPrompt::Result::ACCEPTED);
7380
7381 // It should be enabled again.
7382 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7383 EXPECT_FALSE(
7384 registry()->disabled_extensions().GetByID(updates_from_webstore));
7385
7386 // The error should be removed.
7387 EXPECT_FALSE(HasExternalInstallErrors(service_));
7388 }
7389
7390 // Test that the external install bubble only takes disabled extensions into
7391 // account - enabled extensions, even those that weren't acknowledged, should
7392 // not be warned about. This lets us grandfather extensions in.
TEST_F(ExtensionServiceTest,ExternalInstallBubbleDoesntShowForEnabledExtensions)7393 TEST_F(ExtensionServiceTest,
7394 ExternalInstallBubbleDoesntShowForEnabledExtensions) {
7395 auto external_prompt_override =
7396 std::make_unique<FeatureSwitch::ScopedOverride>(
7397 FeatureSwitch::prompt_for_external_extensions(), false);
7398 InitializeEmptyExtensionService();
7399
7400 // Register and install an external extension.
7401 MockExternalProvider* provider =
7402 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
7403 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
7404 data_dir().AppendASCII("good.crx"));
7405
7406 WaitForExternalExtensionInstalled();
7407
7408 EXPECT_TRUE(registry()->enabled_extensions().Contains(good_crx));
7409 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7410 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
7411 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
7412
7413 // We explicitly reset the override first. ScopedOverrides reset the value
7414 // to the original value on destruction, but if we reset by passing a new
7415 // object, the new object is constructed (overriding the current value)
7416 // before the old is destructed (which will immediately reset to the
7417 // original).
7418 external_prompt_override.reset();
7419 external_prompt_override = std::make_unique<FeatureSwitch::ScopedOverride>(
7420 FeatureSwitch::prompt_for_external_extensions(), true);
7421
7422 ExternalInstallManager* external_manager =
7423 service()->external_install_manager();
7424 external_manager->UpdateExternalExtensionAlert();
7425 EXPECT_FALSE(external_manager->has_currently_visible_install_alert());
7426 EXPECT_TRUE(external_manager->GetErrorsForTesting().empty());
7427
7428 provider->UpdateOrAddExtension(good_crx, "1.0.0.1",
7429 data_dir().AppendASCII("good2.crx"));
7430
7431 WaitForExternalExtensionInstalled();
7432
7433 external_manager->UpdateExternalExtensionAlert();
7434 EXPECT_FALSE(external_manager->has_currently_visible_install_alert());
7435 EXPECT_TRUE(external_manager->GetErrorsForTesting().empty());
7436 }
7437
TEST_F(ExtensionServiceTest,InstallBlocklistedExtension)7438 TEST_F(ExtensionServiceTest, InstallBlocklistedExtension) {
7439 InitializeEmptyExtensionService();
7440
7441 scoped_refptr<const Extension> extension =
7442 ExtensionBuilder("extension").Build();
7443 ASSERT_TRUE(extension.get());
7444 const std::string& id = extension->id();
7445
7446 std::set<std::string> id_set;
7447 id_set.insert(id);
7448
7449 TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile()));
7450 // Installation should be allowed but the extension should never have been
7451 // loaded and it should be blocklisted in prefs.
7452 service()->OnExtensionInstalled(
7453 extension.get(), syncer::StringOrdinal(),
7454 (kInstallFlagIsBlocklistedForMalware | kInstallFlagInstallImmediately));
7455 content::RunAllTasksUntilIdle();
7456
7457 // Extension was installed but not loaded.
7458 observer.WaitForExtensionWillBeInstalled();
7459 EXPECT_TRUE(registry()->GetInstalledExtension(id));
7460
7461 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7462 EXPECT_TRUE(registry()->blocklisted_extensions().Contains(id));
7463
7464 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlocklisted(id));
7465 EXPECT_TRUE(
7466 ExtensionPrefs::Get(profile())->IsBlocklistedExtensionAcknowledged(id));
7467 }
7468
7469 // Test that we won't allow enabling a blocklisted extension.
TEST_F(ExtensionServiceTest,CannotEnableBlocklistedExtension)7470 TEST_F(ExtensionServiceTest, CannotEnableBlocklistedExtension) {
7471 InitializeGoodInstalledExtensionService();
7472 service()->Init();
7473 ASSERT_FALSE(registry()->enabled_extensions().is_empty());
7474
7475 // Blocklist the first extension; then try enabling it.
7476 std::string id = (*(registry()->enabled_extensions().begin()))->id();
7477 service()->BlocklistExtensionForTest(id);
7478 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7479 EXPECT_FALSE(registry()->disabled_extensions().Contains(id));
7480 service()->EnableExtension(id);
7481 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7482 EXPECT_FALSE(registry()->disabled_extensions().Contains(id));
7483 EXPECT_TRUE(registry()->blocklisted_extensions().Contains(id));
7484 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlocklisted(id));
7485
7486 service()->DisableExtension(id, disable_reason::DISABLE_USER_ACTION);
7487 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7488 EXPECT_FALSE(registry()->disabled_extensions().Contains(id));
7489 EXPECT_TRUE(registry()->blocklisted_extensions().Contains(id));
7490 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlocklisted(id));
7491 }
7492
7493 // Test that calls to disable Shared Modules do not work.
TEST_F(ExtensionServiceTest,CannotDisableSharedModules)7494 TEST_F(ExtensionServiceTest, CannotDisableSharedModules) {
7495 InitializeEmptyExtensionService();
7496 scoped_refptr<const Extension> extension =
7497 ExtensionBuilder("Shared Module")
7498 .SetManifestPath({"export", "resources"},
7499 ListBuilder().Append("foo.js").Build())
7500 .AddFlags(Extension::FROM_WEBSTORE)
7501 .Build();
7502
7503 service()->OnExtensionInstalled(extension.get(), syncer::StringOrdinal(),
7504 kInstallFlagInstallImmediately);
7505
7506 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7507 // Try to disable the extension.
7508 service()->DisableExtension(extension->id(),
7509 disable_reason::DISABLE_USER_ACTION);
7510 // Shared Module should still be enabled.
7511 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7512 }
7513
7514 // Make sure we can uninstall a blocklisted extension
TEST_F(ExtensionServiceTest,UninstallBlocklistedExtension)7515 TEST_F(ExtensionServiceTest, UninstallBlocklistedExtension) {
7516 InitializeGoodInstalledExtensionService();
7517 service()->Init();
7518 ASSERT_FALSE(registry()->enabled_extensions().is_empty());
7519
7520 // Blocklist the first extension; then try uninstalling it.
7521 std::string id = (*(registry()->enabled_extensions().begin()))->id();
7522 service()->BlocklistExtensionForTest(id);
7523 EXPECT_NE(nullptr, registry()->GetInstalledExtension(id));
7524 base::string16 error;
7525 EXPECT_TRUE(service()->UninstallExtension(id, UNINSTALL_REASON_USER_INITIATED,
7526 nullptr));
7527 EXPECT_EQ(nullptr, registry()->GetInstalledExtension(id));
7528 }
7529
7530 // Tests a profile being destroyed correctly disables extensions.
TEST_F(ExtensionServiceTest,DestroyingProfileClearsExtensions)7531 TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) {
7532 InitializeEmptyExtensionService();
7533
7534 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
7535 EXPECT_NE(UnloadedExtensionReason::PROFILE_SHUTDOWN, unloaded_reason_);
7536 EXPECT_EQ(1u, registry()->enabled_extensions().size());
7537 EXPECT_EQ(0u, registry()->disabled_extensions().size());
7538 EXPECT_EQ(0u, registry()->terminated_extensions().size());
7539 EXPECT_EQ(0u, registry()->blocklisted_extensions().size());
7540
7541 service()->OnProfileMarkedForPermanentDeletion(profile());
7542 EXPECT_EQ(UnloadedExtensionReason::PROFILE_SHUTDOWN, unloaded_reason_);
7543 EXPECT_EQ(0u, registry()->enabled_extensions().size());
7544 EXPECT_EQ(0u, registry()->disabled_extensions().size());
7545 EXPECT_EQ(0u, registry()->terminated_extensions().size());
7546 EXPECT_EQ(0u, registry()->blocklisted_extensions().size());
7547 }
7548
7549 // Test that updating a corrupt extension removes the DISABLE_CORRUPTED disable
7550 // reason.
TEST_F(ExtensionServiceTest,CorruptExtensionUpdate)7551 TEST_F(ExtensionServiceTest, CorruptExtensionUpdate) {
7552 InitializeEmptyExtensionService();
7553
7554 base::FilePath v1_path = data_dir().AppendASCII("good.crx");
7555 const Extension* v1 = InstallCRX(v1_path, INSTALL_NEW);
7556 std::string id = v1->id();
7557
7558 service()->DisableExtension(id, disable_reason::DISABLE_CORRUPTED);
7559
7560 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7561 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
7562 EXPECT_TRUE(prefs->HasDisableReason(id, disable_reason::DISABLE_CORRUPTED));
7563
7564 base::FilePath v2_path = data_dir().AppendASCII("good2.crx");
7565 UpdateExtension(id, v2_path, ENABLED);
7566
7567 EXPECT_FALSE(registry()->disabled_extensions().Contains(id));
7568 EXPECT_FALSE(prefs->HasDisableReason(id, disable_reason::DISABLE_CORRUPTED));
7569 }
7570
7571 // Try re-enabling a reloading extension. Regression test for crbug.com/676815.
TEST_F(ExtensionServiceTest,ReloadAndReEnableExtension)7572 TEST_F(ExtensionServiceTest, ReloadAndReEnableExtension) {
7573 InitializeEmptyExtensionService();
7574
7575 // Add an extension in an unpacked location.
7576 scoped_refptr<const Extension> extension =
7577 ChromeTestExtensionLoader(profile()).LoadExtension(
7578 data_dir().AppendASCII("simple_with_file"));
7579 const std::string kExtensionId = extension->id();
7580 ASSERT_TRUE(extension);
7581 ASSERT_TRUE(Manifest::IsUnpackedLocation(extension->location()));
7582 EXPECT_TRUE(registry()->enabled_extensions().Contains(kExtensionId));
7583
7584 // Begin the reload process.
7585 service()->ReloadExtension(extension->id());
7586 EXPECT_TRUE(registry()->disabled_extensions().Contains(kExtensionId));
7587
7588 // While the extension is reloading, try to re-enable it. This is the flow
7589 // that could happen if, e.g., the user hit the enable toggle in the
7590 // chrome://extensions page while it was reloading.
7591 service()->GrantPermissionsAndEnableExtension(extension.get());
7592 EXPECT_FALSE(registry()->enabled_extensions().Contains(kExtensionId));
7593
7594 // Wait for the reload to complete. This previously crashed (see
7595 // crbug.com/676815).
7596 content::RunAllTasksUntilIdle();
7597 // The extension should be enabled again...
7598 EXPECT_TRUE(registry()->enabled_extensions().Contains(kExtensionId));
7599 // ...and should have reloaded (for ease, we just compare the extension
7600 // objects).
7601 EXPECT_NE(extension, registry()->enabled_extensions().GetByID(kExtensionId));
7602 }
7603
7604 // Test reloading a shared module. Regression test for crbug.com/676815.
TEST_F(ExtensionServiceTest,ReloadSharedModule)7605 TEST_F(ExtensionServiceTest, ReloadSharedModule) {
7606 InitializeEmptyExtensionService();
7607
7608 // Add a shared module and an extension that depends on it (the latter is
7609 // important to ensure we don't remove the unused shared module).
7610 scoped_refptr<const Extension> shared_module =
7611 ChromeTestExtensionLoader(profile()).LoadExtension(
7612 data_dir().AppendASCII("api_test/shared_module/shared"));
7613 scoped_refptr<const Extension> dependent =
7614 ChromeTestExtensionLoader(profile()).LoadExtension(
7615 data_dir().AppendASCII("api_test/shared_module/import_pass"));
7616 ASSERT_TRUE(shared_module);
7617 ASSERT_TRUE(dependent);
7618 const std::string kExtensionId = shared_module->id();
7619 ASSERT_TRUE(Manifest::IsUnpackedLocation(shared_module->location()));
7620 ASSERT_EQ(Manifest::TYPE_SHARED_MODULE, shared_module->manifest()->type());
7621 EXPECT_TRUE(registry()->enabled_extensions().Contains(kExtensionId));
7622
7623 // Reload the extension and wait for it to complete. This previously crashed
7624 // (see crbug.com/676815).
7625 service()->ReloadExtension(kExtensionId);
7626 content::RunAllTasksUntilIdle();
7627 // The shared module should be enabled.
7628 EXPECT_TRUE(registry()->enabled_extensions().Contains(kExtensionId));
7629 }
7630
7631 // Tests that extensions that have been migrated to component extensions can be
7632 // uninstalled.
TEST_F(ExtensionServiceTest,UninstallMigratedExtensions)7633 TEST_F(ExtensionServiceTest, UninstallMigratedExtensions) {
7634 InitializeEmptyExtensionService();
7635
7636 scoped_refptr<const Extension> cast_extension =
7637 ExtensionBuilder("stable")
7638 .SetID(cast_stable)
7639 .SetLocation(Manifest::INTERNAL)
7640 .Build();
7641 scoped_refptr<const Extension> cast_beta_extension =
7642 ExtensionBuilder("beta")
7643 .SetID(cast_beta)
7644 .SetLocation(Manifest::INTERNAL)
7645 .Build();
7646 service()->AddExtension(cast_extension.get());
7647 service()->AddExtension(cast_beta_extension.get());
7648 ASSERT_TRUE(registry()->enabled_extensions().Contains(cast_stable));
7649 ASSERT_TRUE(registry()->enabled_extensions().Contains(cast_beta));
7650
7651 service()->UninstallMigratedExtensionsForTest();
7652 EXPECT_FALSE(registry()->GetInstalledExtension(cast_stable));
7653 EXPECT_FALSE(registry()->GetInstalledExtension(cast_beta));
7654 }
7655
7656 // Tests that extensions that have been migrated to component extensions can be
7657 // uninstalled even when they are disabled.
TEST_F(ExtensionServiceTest,UninstallDisabledMigratedExtension)7658 TEST_F(ExtensionServiceTest, UninstallDisabledMigratedExtension) {
7659 InitializeEmptyExtensionService();
7660
7661 scoped_refptr<const Extension> cast_extension =
7662 ExtensionBuilder("stable")
7663 .SetID(cast_stable)
7664 .SetLocation(Manifest::INTERNAL)
7665 .Build();
7666 service()->AddExtension(cast_extension.get());
7667 service()->DisableExtension(cast_stable, disable_reason::DISABLE_USER_ACTION);
7668 ASSERT_TRUE(registry()->disabled_extensions().Contains(cast_stable));
7669
7670 service()->UninstallMigratedExtensionsForTest();
7671 EXPECT_FALSE(registry()->GetInstalledExtension(cast_stable));
7672 }
7673
7674 // Tests that component extensions that have been migrated can be uninstalled.
TEST_F(ExtensionServiceTest,UninstallMigratedComponentExtensions)7675 TEST_F(ExtensionServiceTest, UninstallMigratedComponentExtensions) {
7676 InitializeEmptyExtensionServiceWithTestingPrefs();
7677 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7678 ASSERT_TRUE(prefs->ShouldInstallObsoleteComponentExtension(genius_app));
7679
7680 scoped_refptr<const Extension> genius_extension =
7681 ExtensionBuilder("genius")
7682 .SetID(genius_app)
7683 .SetLocation(Manifest::INTERNAL)
7684 .Build();
7685 service()->AddComponentExtension(genius_extension.get());
7686 ASSERT_TRUE(registry()->enabled_extensions().Contains(genius_app));
7687
7688 service()->UninstallMigratedExtensionsForTest();
7689 EXPECT_FALSE(registry()->GetInstalledExtension(genius_app));
7690 EXPECT_FALSE(prefs->ShouldInstallObsoleteComponentExtension(genius_app));
7691 }
7692
7693 // Tests that component extensions that are not marked as obsolete will not be
7694 // uninstalled.
TEST_F(ExtensionServiceTest,UninstallMigratedExtensionsKeepsGoodComponents)7695 TEST_F(ExtensionServiceTest, UninstallMigratedExtensionsKeepsGoodComponents) {
7696 InitializeEmptyExtensionServiceWithTestingPrefs();
7697 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7698
7699 scoped_refptr<const Extension> good_extension =
7700 ExtensionBuilder("good")
7701 .SetID(good0)
7702 .SetLocation(Manifest::INTERNAL)
7703 .Build();
7704 service()->AddComponentExtension(good_extension.get());
7705 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
7706
7707 service()->UninstallMigratedExtensionsForTest();
7708 // Because good0 is not a migrated component extension it should still be
7709 // currently installed, and should continue to be installed in the future.
7710 EXPECT_TRUE(registry()->GetInstalledExtension(good0));
7711 EXPECT_TRUE(prefs->ShouldInstallObsoleteComponentExtension(good0));
7712 }
7713
7714 // Tests that repeat calls to UninstallMigratedExtensions doesn't crash/fail.
TEST_F(ExtensionServiceTest,UninstallMigratedExtensionsMultipleCalls)7715 TEST_F(ExtensionServiceTest, UninstallMigratedExtensionsMultipleCalls) {
7716 InitializeEmptyExtensionServiceWithTestingPrefs();
7717
7718 scoped_refptr<const Extension> cast_extension =
7719 ExtensionBuilder("stable")
7720 .SetID(cast_stable)
7721 .SetLocation(Manifest::INTERNAL)
7722 .Build();
7723 scoped_refptr<const Extension> genius_extension =
7724 ExtensionBuilder("genius")
7725 .SetID(genius_app)
7726 .SetLocation(Manifest::INTERNAL)
7727 .Build();
7728 service()->AddExtension(cast_extension.get());
7729 service()->AddComponentExtension(genius_extension.get());
7730
7731 service()->UninstallMigratedExtensionsForTest();
7732 service()->UninstallMigratedExtensionsForTest();
7733 service()->UninstallMigratedExtensionsForTest();
7734 EXPECT_FALSE(registry()->GetInstalledExtension(cast_stable));
7735 EXPECT_FALSE(registry()->GetInstalledExtension(genius_app));
7736 }
7737
7738 // Tests the case of a user installing a non-policy extension (e.g. through the
7739 // webstore), and that extension later becoming required by policy.
7740 // Regression test for https://crbug.com/894184.
TEST_F(ExtensionServiceTest,UserInstalledExtensionThenRequiredByPolicy)7741 TEST_F(ExtensionServiceTest, UserInstalledExtensionThenRequiredByPolicy) {
7742 InitializeEmptyExtensionServiceWithTestingPrefs();
7743
7744 // Install an extension as if the user did it.
7745 base::FilePath path = data_dir().AppendASCII("good.crx");
7746 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7747 ASSERT_TRUE(extension);
7748 EXPECT_EQ(good_crx, extension->id());
7749 EXPECT_EQ(Manifest::INTERNAL, extension->location());
7750
7751 std::string kVersionStr = "1.0.0.0";
7752 EXPECT_EQ(kVersionStr, extension->VersionString());
7753
7754 {
7755 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
7756 // Mark good.crx for force-installation.
7757 pref.SetIndividualExtensionAutoInstalled(
7758 good_crx, "http://example.com/update_url", true);
7759 }
7760
7761 // Require good.crx by policy.
7762 MockExternalProvider* provider =
7763 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
7764 // TODO(devlin): Do we also need to check installing extensions with different
7765 // versions?
7766 provider->UpdateOrAddExtension(good_crx, kVersionStr,
7767 data_dir().AppendASCII("good.crx"));
7768 service()->CheckForExternalUpdates();
7769
7770 ExtensionManagement* management =
7771 ExtensionManagementFactory::GetForBrowserContext(profile());
7772 ExtensionManagement::InstallationMode installation_mode =
7773 management->GetInstallationMode(extension);
7774 EXPECT_EQ(ExtensionManagement::INSTALLATION_FORCED, installation_mode);
7775
7776 // Reload all extensions.
7777 service()->ReloadExtensionsForTest();
7778
7779 extension = registry()->GetInstalledExtension(good_crx);
7780 ASSERT_TRUE(extension);
7781 ManagementPolicy* policy =
7782 ExtensionSystem::Get(browser_context())->management_policy();
7783 // The extension should still be installed, and should be required to
7784 // remain installed.
7785 EXPECT_TRUE(policy->MustRemainInstalled(extension, nullptr));
7786 // TODO(devlin): This currently doesn't work, because the extension is still
7787 // installed with Manifest::Location INTERNAL.
7788 // EXPECT_FALSE(policy->UserMayModifySettings(extension, nullptr));
7789
7790 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
7791 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7792 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
7793 EXPECT_FALSE(prefs->IsExtensionDisabled(good_crx));
7794 }
7795
7796 // If the extension is first manually installed by the user, and then added to
7797 // the force installed list, on restarting, the extension should behave as a
7798 // force installed extension.
TEST_F(ExtensionServiceTest,UserInstalledExtensionThenRequiredByPolicyOnRestart)7799 TEST_F(ExtensionServiceTest,
7800 UserInstalledExtensionThenRequiredByPolicyOnRestart) {
7801 InitializeEmptyExtensionServiceWithTestingPrefs();
7802
7803 // Install an extension as if the user did it.
7804 base::FilePath path = data_dir().AppendASCII("good.crx");
7805 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7806 ASSERT_TRUE(extension);
7807 EXPECT_EQ(good_crx, extension->id());
7808 EXPECT_EQ(Manifest::INTERNAL, extension->location());
7809
7810 std::string kVersionStr = "1.0.0.0";
7811 EXPECT_EQ(kVersionStr, extension->VersionString());
7812
7813 {
7814 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
7815 // Mark good.crx for force-installation.
7816 pref.SetIndividualExtensionAutoInstalled(
7817 good_crx, "http://example.com/update_url", true);
7818 }
7819
7820 ExtensionManagement* management =
7821 ExtensionManagementFactory::GetForBrowserContext(profile());
7822 ExtensionManagement::InstallationMode installation_mode =
7823 management->GetInstallationMode(extension);
7824 EXPECT_EQ(ExtensionManagement::INSTALLATION_FORCED, installation_mode);
7825
7826 GURL good_update_url(kGoodUpdateURL);
7827 ExternalInstallInfoUpdateUrl info(
7828 good_crx, std::string(), std::move(good_update_url),
7829 Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS, false);
7830 service()->OnExternalExtensionUpdateUrlFound(info, true);
7831 base::RunLoop().RunUntilIdle();
7832
7833 extension = registry()->GetInstalledExtension(good_crx);
7834 ASSERT_TRUE(extension);
7835 ManagementPolicy* policy =
7836 ExtensionSystem::Get(browser_context())->management_policy();
7837
7838 // The extension should still be installed, and should be required to
7839 // remain installed.
7840 EXPECT_TRUE(policy->MustRemainInstalled(extension, nullptr));
7841 EXPECT_FALSE(policy->UserMayModifySettings(extension, nullptr));
7842 EXPECT_EQ(extension->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
7843
7844 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
7845 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7846 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
7847 EXPECT_FALSE(prefs->IsExtensionDisabled(good_crx));
7848
7849 // Simulate a chrome process restart.
7850 service()->ReloadExtensionsForTest();
7851 policy = ExtensionSystem::Get(browser_context())->management_policy();
7852 EXPECT_TRUE(registry()->enabled_extensions().Contains(good_crx));
7853 extension = registry()->GetInstalledExtension(good_crx);
7854 // The location should remain same on restart.
7855 EXPECT_EQ(extension->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
7856 // Extension should behave similar to force installed on restart.
7857 EXPECT_TRUE(policy->MustRemainInstalled(extension, nullptr));
7858 EXPECT_FALSE(policy->UserMayModifySettings(extension, nullptr));
7859 }
7860
TEST_F(ExtensionServiceTest,InstallingUnacknowledgedExternalExtension)7861 TEST_F(ExtensionServiceTest, InstallingUnacknowledgedExternalExtension) {
7862 InitializeEmptyExtensionServiceWithTestingPrefs();
7863 {
7864 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
7865 // Mark good.crx for recommended installation.
7866 pref.SetIndividualExtensionAutoInstalled(
7867 good_crx, "http://example.com/update_url", false);
7868 }
7869
7870 base::FilePath path = data_dir().AppendASCII("good.crx");
7871 std::string version_str = "1.0.0.0";
7872 // Install an external extension.
7873 std::unique_ptr<ExternalInstallInfoFile> info = CreateExternalExtension(
7874 good_crx, version_str, path, Manifest::EXTERNAL_PREF_DOWNLOAD,
7875 Extension::NO_FLAGS);
7876 MockExternalProvider* provider =
7877 AddMockExternalProvider(Manifest::EXTERNAL_PREF_DOWNLOAD);
7878 provider->UpdateOrAddExtension(std::move(info));
7879 WaitForExternalExtensionInstalled();
7880
7881 const Extension* extension =
7882 registry()->enabled_extensions().GetByID(good_crx);
7883 ASSERT_TRUE(extension);
7884 EXPECT_EQ(good_crx, extension->id());
7885 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, extension->location());
7886 EXPECT_EQ(version_str, extension->VersionString());
7887
7888 ExtensionManagement::InstallationMode installation_mode =
7889 ExtensionManagementFactory::GetForBrowserContext(profile())
7890 ->GetInstallationMode(extension);
7891 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7892
7893 EXPECT_EQ(ExtensionManagement::INSTALLATION_RECOMMENDED, installation_mode);
7894 EXPECT_TRUE(registry()->enabled_extensions().Contains(good_crx));
7895 EXPECT_TRUE(prefs->IsExternalExtensionAcknowledged(extension->id()));
7896 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
7897 EXPECT_FALSE(prefs->IsExtensionDisabled(good_crx));
7898 }
7899
7900 // Regression test for crbug.com/460699. Ensure PluginManager doesn't crash even
7901 // if OnExtensionUnloaded is invoked twice in succession.
TEST_F(ExtensionServiceTest,PluginManagerCrash)7902 TEST_F(ExtensionServiceTest, PluginManagerCrash) {
7903 InitializeEmptyExtensionService();
7904 PluginManager manager(profile());
7905
7906 // Load an extension using a NaCl module.
7907 const Extension* extension =
7908 PackAndInstallCRX(data_dir().AppendASCII("native_client"), INSTALL_NEW);
7909 service()->DisableExtension(extension->id(),
7910 disable_reason::DISABLE_USER_ACTION);
7911
7912 // crbug.com/708230: This will cause OnExtensionUnloaded to be called
7913 // redundantly for a disabled extension.
7914 service()->BlockAllExtensions();
7915 }
7916
7917 class ExternalExtensionPriorityTest
7918 : public ExtensionServiceTest,
7919 public testing::WithParamInterface<Manifest::Location> {};
7920
7921 // Policy-forced extensions should be fetched with FOREGROUND priority,
7922 // otherwise they may be throttled (web store sends “noupdate” response to
7923 // reduce load), which is OK for updates, but not for a new install. This is
7924 // a regression test for problems described in https://crbug.com/904600 and
7925 // https://crbug.com/917700.
TEST_P(ExternalExtensionPriorityTest,PolicyForegroundFetch)7926 TEST_P(ExternalExtensionPriorityTest, PolicyForegroundFetch) {
7927 ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_checks;
7928 ExtensionServiceInitParams params = CreateDefaultInitParams();
7929 params.autoupdate_enabled = true;
7930 InitializeExtensionService(params);
7931
7932 ExtensionDownloaderTestHelper helper;
7933 NullExtensionCache extension_cache;
7934 service()->updater()->SetExtensionDownloaderForTesting(
7935 helper.CreateDownloader());
7936 service()->updater()->SetExtensionCacheForTesting(&extension_cache);
7937 service()->updater()->Start();
7938
7939 GURL update_url(extension_urls::kChromeWebstoreUpdateURL);
7940 service()->OnExternalExtensionUpdateUrlFound(
7941 ExternalInstallInfoUpdateUrl(all_zero /* extension_id */,
7942 "" /* install_parameter */, update_url,
7943 GetParam() /* download_location */,
7944 Extension::NO_FLAGS /* creation_flag */,
7945 true /* mark_acknowledged */),
7946 true /* is_initial_load */);
7947
7948 MockExternalProvider provider(nullptr, Manifest::EXTERNAL_POLICY_DOWNLOAD);
7949 service()->OnExternalProviderReady(&provider);
7950
7951 content::RunAllTasksUntilIdle();
7952
7953 EXPECT_EQ(helper.test_url_loader_factory().NumPending(), 1);
7954 network::TestURLLoaderFactory::PendingRequest* pending_request =
7955 helper.test_url_loader_factory().GetPendingRequest(0);
7956 std::string header;
7957 EXPECT_TRUE(pending_request->request.headers.GetHeader(
7958 "X-Goog-Update-Interactivity", &header));
7959 bool is_high_priority = GetParam() == Manifest::EXTERNAL_POLICY_DOWNLOAD ||
7960 GetParam() == Manifest::EXTERNAL_COMPONENT;
7961 const char* expected_header = is_high_priority ? "fg" : "bg";
7962 EXPECT_EQ(expected_header, header);
7963
7964 // Destroy updater's downloader as it uses |helper|.
7965 service()->updater()->SetExtensionDownloaderForTesting(nullptr);
7966 }
7967
7968 INSTANTIATE_TEST_SUITE_P(All,
7969 ExternalExtensionPriorityTest,
7970 testing::Values(Manifest::EXTERNAL_POLICY_DOWNLOAD,
7971 Manifest::EXTERNAL_COMPONENT,
7972 Manifest::EXTERNAL_PREF_DOWNLOAD));
7973
7974 } // namespace extensions
7975