1// Copyright (c) 2012 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 "base/bind.h" 6#include "base/bind_helpers.h" 7#include "base/memory/ref_counted.h" 8#include "base/prefs/scoped_user_pref_update.h" 9#include "base/run_loop.h" 10#include "base/stl_util.h" 11#include "base/strings/stringprintf.h" 12#include "chrome/browser/extensions/extension_browsertest.h" 13#include "chrome/browser/extensions/extension_management.h" 14#include "chrome/browser/extensions/extension_service.h" 15#include "chrome/browser/extensions/updater/extension_downloader.h" 16#include "chrome/browser/extensions/updater/extension_updater.h" 17#include "chrome/browser/profiles/profile.h" 18#include "chrome/browser/ui/browser.h" 19#include "chrome/common/pref_names.h" 20#include "chrome/common/url_constants.h" 21#include "chrome/test/base/ui_test_utils.h" 22#include "components/policy/core/browser/browser_policy_connector.h" 23#include "components/policy/core/common/mock_configuration_policy_provider.h" 24#include "components/policy/core/common/policy_map.h" 25#include "content/public/browser/browser_thread.h" 26#include "content/public/browser/notification_service.h" 27#include "content/public/browser/render_view_host.h" 28#include "content/public/test/browser_test_utils.h" 29#include "extensions/browser/extension_host.h" 30#include "extensions/browser/extension_prefs.h" 31#include "extensions/browser/extension_registry.h" 32#include "extensions/browser/extension_system.h" 33#include "extensions/browser/notification_types.h" 34#include "extensions/test/extension_test_message_listener.h" 35#include "net/url_request/test_url_request_interceptor.h" 36#include "net/url_request/url_fetcher.h" 37#include "policy/policy_constants.h" 38#include "testing/gmock/include/gmock/gmock.h" 39 40using content::BrowserThread; 41using extensions::Extension; 42using extensions::ExtensionRegistry; 43using extensions::Manifest; 44using policy::PolicyMap; 45using testing::Return; 46using testing::_; 47 48namespace { 49 50std::string BuildForceInstallPolicyValue(const char* extension_id, 51 const char* update_url) { 52 return base::StringPrintf("%s;%s", extension_id, update_url); 53} 54 55} // namespace 56 57class ExtensionManagementTest : public ExtensionBrowserTest { 58 public: 59 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 60 EXPECT_CALL(policy_provider_, IsInitializationComplete(_)) 61 .WillRepeatedly(Return(true)); 62 policy::BrowserPolicyConnector::SetPolicyProviderForTesting( 63 &policy_provider_); 64 } 65 66 protected: 67 void UpdateProviderPolicy(const PolicyMap& policy) { 68 policy_provider_.UpdateChromePolicy(policy); 69 base::RunLoop().RunUntilIdle(); 70 } 71 72 // Helper method that returns whether the extension is at the given version. 73 // This calls version(), which must be defined in the extension's bg page, 74 // as well as asking the extension itself. 75 // 76 // Note that 'version' here means something different than the version field 77 // in the extension's manifest. We use the version as reported by the 78 // background page to test how overinstalling crx files with the same 79 // manifest version works. 80 bool IsExtensionAtVersion(const Extension* extension, 81 const std::string& expected_version) { 82 // Test that the extension's version from the manifest and reported by the 83 // background page is correct. This is to ensure that the processes are in 84 // sync with the Extension. 85 extensions::ProcessManager* manager = 86 extensions::ExtensionSystem::Get(browser()->profile())-> 87 process_manager(); 88 extensions::ExtensionHost* ext_host = 89 manager->GetBackgroundHostForExtension(extension->id()); 90 EXPECT_TRUE(ext_host); 91 if (!ext_host) 92 return false; 93 94 std::string version_from_bg; 95 bool exec = content::ExecuteScriptAndExtractString( 96 ext_host->render_view_host(), "version()", &version_from_bg); 97 EXPECT_TRUE(exec); 98 if (!exec) 99 return false; 100 101 if (version_from_bg != expected_version || 102 extension->VersionString() != expected_version) 103 return false; 104 return true; 105 } 106 107 private: 108 policy::MockConfigurationPolicyProvider policy_provider_; 109}; 110 111#if defined(OS_LINUX) 112// Times out sometimes on Linux. http://crbug.com/89727 113#define MAYBE_InstallSameVersion DISABLED_InstallSameVersion 114#else 115#define MAYBE_InstallSameVersion InstallSameVersion 116#endif 117 118// Tests that installing the same version overwrites. 119IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_InstallSameVersion) { 120 const Extension* extension = InstallExtension( 121 test_data_dir_.AppendASCII("install/install.crx"), 1); 122 ASSERT_TRUE(extension); 123 base::FilePath old_path = extension->path(); 124 125 // Install an extension with the same version. The previous install should be 126 // overwritten. 127 extension = InstallExtension( 128 test_data_dir_.AppendASCII("install/install_same_version.crx"), 0); 129 ASSERT_TRUE(extension); 130 base::FilePath new_path = extension->path(); 131 132 EXPECT_FALSE(IsExtensionAtVersion(extension, "1.0")); 133 EXPECT_NE(old_path.value(), new_path.value()); 134} 135 136IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) { 137 const Extension* extension = InstallExtension( 138 test_data_dir_.AppendASCII("install/install.crx"), 1); 139 ASSERT_TRUE(extension); 140 ASSERT_FALSE(InstallExtension( 141 test_data_dir_.AppendASCII("install/install_older_version.crx"), 0)); 142 EXPECT_TRUE(IsExtensionAtVersion(extension, "1.0")); 143} 144 145IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallThenCancel) { 146 const Extension* extension = InstallExtension( 147 test_data_dir_.AppendASCII("install/install.crx"), 1); 148 ASSERT_TRUE(extension); 149 150 // Cancel this install. 151 ASSERT_FALSE(StartInstallButCancel( 152 test_data_dir_.AppendASCII("install/install_v2.crx"))); 153 EXPECT_TRUE(IsExtensionAtVersion(extension, "1.0")); 154} 155 156#if defined(OS_WIN) 157// http://crbug.com/141913 158#define MAYBE_InstallRequiresConfirm DISABLED_InstallRequiresConfirm 159#else 160#define MAYBE_InstallRequiresConfirm InstallRequiresConfirm 161#endif 162IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_InstallRequiresConfirm) { 163 // Installing the extension without an auto confirming UI should result in 164 // it being disabled, since good.crx has permissions that require approval. 165 ExtensionService* service = extensions::ExtensionSystem::Get( 166 browser()->profile())->extension_service(); 167 std::string id = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 168 ASSERT_FALSE(InstallExtension(test_data_dir_.AppendASCII("good.crx"), 0)); 169 ASSERT_TRUE(service->GetExtensionById(id, true)); 170 UninstallExtension(id); 171 172 // And the install should succeed when the permissions are accepted. 173 ASSERT_TRUE(InstallExtensionWithUIAutoConfirm( 174 test_data_dir_.AppendASCII("good.crx"), 1, browser())); 175 UninstallExtension(id); 176} 177 178// Tests that disabling and re-enabling an extension works. 179IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) { 180 extensions::ProcessManager* manager = 181 extensions::ExtensionSystem::Get(browser()->profile())->process_manager(); 182 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 183 const size_t size_before = registry->enabled_extensions().size(); 184 185 // Load an extension, expect the background page to be available. 186 std::string extension_id = "bjafgdebaacbbbecmhlhpofkepfkgcpa"; 187 ASSERT_TRUE(LoadExtension( 188 test_data_dir_.AppendASCII("good").AppendASCII("Extensions") 189 .AppendASCII(extension_id) 190 .AppendASCII("1.0"))); 191 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 192 EXPECT_EQ(0u, registry->disabled_extensions().size()); 193 EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id)); 194 195 // After disabling, the background page should go away. 196 DisableExtension(extension_id); 197 EXPECT_EQ(size_before, registry->enabled_extensions().size()); 198 EXPECT_EQ(1u, registry->disabled_extensions().size()); 199 EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension_id)); 200 201 // And bring it back. 202 EnableExtension(extension_id); 203 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); 204 EXPECT_EQ(0u, registry->disabled_extensions().size()); 205 EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id)); 206} 207 208// Used for testing notifications sent during extension updates. 209class NotificationListener : public content::NotificationObserver { 210 public: 211 NotificationListener() : started_(false), finished_(false) { 212 int types[] = {extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED, 213 extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND}; 214 for (size_t i = 0; i < arraysize(types); i++) { 215 registrar_.Add( 216 this, types[i], content::NotificationService::AllSources()); 217 } 218 } 219 virtual ~NotificationListener() {} 220 221 bool started() { return started_; } 222 223 bool finished() { return finished_; } 224 225 const std::set<std::string>& updates() { return updates_; } 226 227 void Reset() { 228 started_ = false; 229 finished_ = false; 230 updates_.clear(); 231 } 232 233 // Implements content::NotificationObserver interface. 234 virtual void Observe(int type, 235 const content::NotificationSource& source, 236 const content::NotificationDetails& details) OVERRIDE { 237 switch (type) { 238 case extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED: { 239 EXPECT_FALSE(started_); 240 started_ = true; 241 break; 242 } 243 case extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND: { 244 const std::string& id = 245 content::Details<extensions::UpdateDetails>(details)->id; 246 updates_.insert(id); 247 break; 248 } 249 default: 250 NOTREACHED(); 251 } 252 } 253 254 void OnFinished() { 255 EXPECT_FALSE(finished_); 256 finished_ = true; 257 } 258 259 private: 260 content::NotificationRegistrar registrar_; 261 262 // Did we see EXTENSION_UPDATING_STARTED? 263 bool started_; 264 265 // Did we see EXTENSION_UPDATING_FINISHED? 266 bool finished_; 267 268 // The set of extension id's we've seen via EXTENSION_UPDATE_FOUND. 269 std::set<std::string> updates_; 270}; 271 272#if defined(OS_WIN) 273// Fails consistently on Windows XP, see: http://crbug.com/120640. 274#define MAYBE_AutoUpdate DISABLED_AutoUpdate 275#else 276// See http://crbug.com/103371 and http://crbug.com/120640. 277#if defined(ADDRESS_SANITIZER) 278#define MAYBE_AutoUpdate DISABLED_AutoUpdate 279#else 280#define MAYBE_AutoUpdate AutoUpdate 281#endif 282#endif 283 284// Tests extension autoupdate. 285IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_AutoUpdate) { 286 NotificationListener notification_listener; 287 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 288 289 // Note: This interceptor gets requests on the IO thread. 290 net::LocalHostTestURLRequestInterceptor interceptor( 291 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 292 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 293 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 294 net::URLFetcher::SetEnableInterceptionForTests(true); 295 296 interceptor.SetResponseIgnoreQuery( 297 GURL("http://localhost/autoupdate/manifest"), 298 basedir.AppendASCII("manifest_v2.xml")); 299 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 300 basedir.AppendASCII("v2.crx")); 301 302 // Install version 1 of the extension. 303 ExtensionTestMessageListener listener1("v1 installed", false); 304 ExtensionService* service = extensions::ExtensionSystem::Get( 305 browser()->profile())->extension_service(); 306 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 307 const size_t size_before = registry->enabled_extensions().size(); 308 ASSERT_TRUE(registry->disabled_extensions().is_empty()); 309 const Extension* extension = 310 InstallExtension(basedir.AppendASCII("v1.crx"), 1); 311 ASSERT_TRUE(extension); 312 listener1.WaitUntilSatisfied(); 313 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 314 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id()); 315 ASSERT_EQ("1.0", extension->VersionString()); 316 317 extensions::ExtensionUpdater::CheckParams params; 318 params.callback = 319 base::Bind(&NotificationListener::OnFinished, 320 base::Unretained(¬ification_listener)); 321 322 // Run autoupdate and make sure version 2 of the extension was installed. 323 ExtensionTestMessageListener listener2("v2 installed", false); 324 service->updater()->CheckNow(params); 325 ASSERT_TRUE(WaitForExtensionInstall()); 326 listener2.WaitUntilSatisfied(); 327 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 328 extension = service->GetExtensionById( 329 "ogjcoiohnmldgjemafoockdghcjciccf", false); 330 ASSERT_TRUE(extension); 331 ASSERT_EQ("2.0", extension->VersionString()); 332 ASSERT_TRUE(notification_listener.started()); 333 ASSERT_TRUE(notification_listener.finished()); 334 ASSERT_TRUE(ContainsKey(notification_listener.updates(), 335 "ogjcoiohnmldgjemafoockdghcjciccf")); 336 notification_listener.Reset(); 337 338 // Now try doing an update to version 3, which has been incorrectly 339 // signed. This should fail. 340 interceptor.SetResponseIgnoreQuery( 341 GURL("http://localhost/autoupdate/manifest"), 342 basedir.AppendASCII("manifest_v3.xml")); 343 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v3.crx"), 344 basedir.AppendASCII("v3.crx")); 345 346 service->updater()->CheckNow(params); 347 ASSERT_TRUE(WaitForExtensionInstallError()); 348 ASSERT_TRUE(notification_listener.started()); 349 ASSERT_TRUE(notification_listener.finished()); 350 ASSERT_TRUE(ContainsKey(notification_listener.updates(), 351 "ogjcoiohnmldgjemafoockdghcjciccf")); 352 353 // Make sure the extension state is the same as before. 354 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 355 extension = service->GetExtensionById( 356 "ogjcoiohnmldgjemafoockdghcjciccf", false); 357 ASSERT_TRUE(extension); 358 ASSERT_EQ("2.0", extension->VersionString()); 359} 360 361#if defined(OS_WIN) 362// Fails consistently on Windows XP, see: http://crbug.com/120640. 363#define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions 364#else 365#if defined(ADDRESS_SANITIZER) 366#define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions 367#else 368#define MAYBE_AutoUpdateDisabledExtensions AutoUpdateDisabledExtensions 369#endif 370#endif 371 372// Tests extension autoupdate. 373IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, 374 MAYBE_AutoUpdateDisabledExtensions) { 375 NotificationListener notification_listener; 376 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 377 378 // Note: This interceptor gets requests on the IO thread. 379 net::LocalHostTestURLRequestInterceptor interceptor( 380 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 381 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 382 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 383 net::URLFetcher::SetEnableInterceptionForTests(true); 384 385 interceptor.SetResponseIgnoreQuery( 386 GURL("http://localhost/autoupdate/manifest"), 387 basedir.AppendASCII("manifest_v2.xml")); 388 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 389 basedir.AppendASCII("v2.crx")); 390 391 // Install version 1 of the extension. 392 ExtensionTestMessageListener listener1("v1 installed", false); 393 ExtensionService* service = extensions::ExtensionSystem::Get( 394 browser()->profile())->extension_service(); 395 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 396 const size_t enabled_size_before = registry->enabled_extensions().size(); 397 const size_t disabled_size_before = registry->disabled_extensions().size(); 398 const Extension* extension = 399 InstallExtension(basedir.AppendASCII("v1.crx"), 1); 400 ASSERT_TRUE(extension); 401 listener1.WaitUntilSatisfied(); 402 DisableExtension(extension->id()); 403 ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size()); 404 ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size()); 405 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id()); 406 ASSERT_EQ("1.0", extension->VersionString()); 407 408 extensions::ExtensionUpdater::CheckParams params; 409 params.callback = 410 base::Bind(&NotificationListener::OnFinished, 411 base::Unretained(¬ification_listener)); 412 413 ExtensionTestMessageListener listener2("v2 installed", false); 414 // Run autoupdate and make sure version 2 of the extension was installed but 415 // is still disabled. 416 service->updater()->CheckNow(params); 417 ASSERT_TRUE(WaitForExtensionInstall()); 418 ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size()); 419 ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size()); 420 extension = service->GetExtensionById( 421 "ogjcoiohnmldgjemafoockdghcjciccf", true); 422 ASSERT_TRUE(extension); 423 ASSERT_FALSE(service->GetExtensionById( 424 "ogjcoiohnmldgjemafoockdghcjciccf", false)); 425 ASSERT_EQ("2.0", extension->VersionString()); 426 427 // The extension should have not made the callback because it is disabled. 428 // When we enabled it, it should then make the callback. 429 ASSERT_FALSE(listener2.was_satisfied()); 430 EnableExtension(extension->id()); 431 listener2.WaitUntilSatisfied(); 432 ASSERT_TRUE(notification_listener.started()); 433 ASSERT_TRUE(notification_listener.finished()); 434 ASSERT_TRUE(ContainsKey(notification_listener.updates(), 435 "ogjcoiohnmldgjemafoockdghcjciccf")); 436 notification_listener.Reset(); 437} 438 439IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) { 440 ExtensionService* service = extensions::ExtensionSystem::Get( 441 browser()->profile())->extension_service(); 442 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; 443 extensions::ExtensionUpdater::CheckParams params; 444 445 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 446 447 // Note: This interceptor gets requests on the IO thread. 448 net::LocalHostTestURLRequestInterceptor interceptor( 449 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 450 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 451 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 452 net::URLFetcher::SetEnableInterceptionForTests(true); 453 454 interceptor.SetResponseIgnoreQuery( 455 GURL("http://localhost/autoupdate/manifest"), 456 basedir.AppendASCII("manifest_v2.xml")); 457 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 458 basedir.AppendASCII("v2.crx")); 459 460 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 461 const size_t size_before = registry->enabled_extensions().size(); 462 ASSERT_TRUE(registry->disabled_extensions().is_empty()); 463 464 extensions::PendingExtensionManager* pending_extension_manager = 465 service->pending_extension_manager(); 466 467 // The code that reads external_extensions.json uses this method to inform 468 // the ExtensionService of an extension to download. Using the real code 469 // is race-prone, because instantating the ExtensionService starts a read 470 // of external_extensions.json before this test function starts. 471 472 EXPECT_TRUE(pending_extension_manager->AddFromExternalUpdateUrl( 473 kExtensionId, 474 std::string(), 475 GURL("http://localhost/autoupdate/manifest"), 476 Manifest::EXTERNAL_PREF_DOWNLOAD, 477 Extension::NO_FLAGS, 478 false)); 479 480 // Run autoupdate and make sure version 2 of the extension was installed. 481 service->updater()->CheckNow(params); 482 ASSERT_TRUE(WaitForExtensionInstall()); 483 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 484 const Extension* extension = service->GetExtensionById(kExtensionId, false); 485 ASSERT_TRUE(extension); 486 ASSERT_EQ("2.0", extension->VersionString()); 487 488 // Uninstalling the extension should set a pref that keeps the extension from 489 // being installed again the next time external_extensions.json is read. 490 491 UninstallExtension(kExtensionId); 492 493 extensions::ExtensionPrefs* extension_prefs = 494 extensions::ExtensionPrefs::Get(browser()->profile()); 495 EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) 496 << "Uninstalling should set kill bit on externaly installed extension."; 497 498 // Try to install the extension again from an external source. It should fail 499 // because of the killbit. 500 EXPECT_FALSE(pending_extension_manager->AddFromExternalUpdateUrl( 501 kExtensionId, 502 std::string(), 503 GURL("http://localhost/autoupdate/manifest"), 504 Manifest::EXTERNAL_PREF_DOWNLOAD, 505 Extension::NO_FLAGS, 506 false)); 507 EXPECT_FALSE(pending_extension_manager->IsIdPending(kExtensionId)) 508 << "External reinstall of a killed extension shouldn't work."; 509 EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) 510 << "External reinstall of a killed extension should leave it killed."; 511 512 // Installing from non-external source. 513 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); 514 515 EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) 516 << "Reinstalling should clear the kill bit."; 517 518 // Uninstalling from a non-external source should not set the kill bit. 519 UninstallExtension(kExtensionId); 520 521 EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) 522 << "Uninstalling non-external extension should not set kill bit."; 523} 524 525namespace { 526 527const char* kForceInstallNotEmptyHelp = 528 "A policy may already be controlling the list of force-installed " 529 "extensions. Please remove all policy settings from your computer " 530 "before running tests. E.g. from /etc/chromium/policies Linux or " 531 "from the registry on Windows, etc."; 532 533} 534 535// See http://crbug.com/57378 for flakiness details. 536IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) { 537 ExtensionService* service = extensions::ExtensionSystem::Get( 538 browser()->profile())->extension_service(); 539 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; 540 541 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 542 543 // Note: This interceptor gets requests on the IO thread. 544 net::LocalHostTestURLRequestInterceptor interceptor( 545 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 546 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 547 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 548 net::URLFetcher::SetEnableInterceptionForTests(true); 549 550 interceptor.SetResponseIgnoreQuery( 551 GURL("http://localhost/autoupdate/manifest"), 552 basedir.AppendASCII("manifest_v2.xml")); 553 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 554 basedir.AppendASCII("v2.crx")); 555 556 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 557 const size_t size_before = registry->enabled_extensions().size(); 558 ASSERT_TRUE(registry->disabled_extensions().is_empty()); 559 560 ASSERT_TRUE(extensions::ExtensionManagementFactory::GetForBrowserContext( 561 browser()->profile()) 562 ->GetForceInstallList() 563 ->empty()) 564 << kForceInstallNotEmptyHelp; 565 566 base::ListValue forcelist; 567 forcelist.AppendString(BuildForceInstallPolicyValue( 568 kExtensionId, "http://localhost/autoupdate/manifest")); 569 PolicyMap policies; 570 policies.Set(policy::key::kExtensionInstallForcelist, 571 policy::POLICY_LEVEL_MANDATORY, 572 policy::POLICY_SCOPE_USER, 573 forcelist.DeepCopy(), 574 NULL); 575 UpdateProviderPolicy(policies); 576 577 // Check if the extension got installed. 578 ASSERT_TRUE(WaitForExtensionInstall()); 579 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 580 const Extension* extension = service->GetExtensionById(kExtensionId, false); 581 ASSERT_TRUE(extension); 582 ASSERT_EQ("2.0", extension->VersionString()); 583 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); 584 585 // Try to disable and uninstall the extension which should fail. 586 DisableExtension(kExtensionId); 587 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); 588 EXPECT_EQ(0u, registry->disabled_extensions().size()); 589 UninstallExtension(kExtensionId); 590 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); 591 EXPECT_EQ(0u, registry->disabled_extensions().size()); 592 593 // Now try to disable it through the management api, again failing. 594 ExtensionTestMessageListener listener1("ready", false); 595 ASSERT_TRUE(LoadExtension( 596 test_data_dir_.AppendASCII("management/uninstall_extension"))); 597 ASSERT_TRUE(listener1.WaitUntilSatisfied()); 598 EXPECT_EQ(size_before + 2, registry->enabled_extensions().size()); 599 EXPECT_EQ(0u, registry->disabled_extensions().size()); 600 601 // Check that emptying the list triggers uninstall. 602 policies.Erase(policy::key::kExtensionInstallForcelist); 603 UpdateProviderPolicy(policies); 604 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); 605 EXPECT_FALSE(service->GetExtensionById(kExtensionId, true)); 606} 607 608// See http://crbug.com/103371 and http://crbug.com/120640. 609#if defined(ADDRESS_SANITIZER) || defined(OS_WIN) 610#define MAYBE_PolicyOverridesUserInstall DISABLED_PolicyOverridesUserInstall 611#else 612#define MAYBE_PolicyOverridesUserInstall PolicyOverridesUserInstall 613#endif 614 615IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, 616 MAYBE_PolicyOverridesUserInstall) { 617 ExtensionService* service = extensions::ExtensionSystem::Get( 618 browser()->profile())->extension_service(); 619 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 620 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; 621 extensions::ExtensionUpdater::CheckParams params; 622 service->updater()->set_default_check_params(params); 623 const size_t size_before = registry->enabled_extensions().size(); 624 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 625 ASSERT_TRUE(registry->disabled_extensions().is_empty()); 626 627 // Note: This interceptor gets requests on the IO thread. 628 net::LocalHostTestURLRequestInterceptor interceptor( 629 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 630 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 631 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 632 net::URLFetcher::SetEnableInterceptionForTests(true); 633 634 interceptor.SetResponseIgnoreQuery( 635 GURL("http://localhost/autoupdate/manifest"), 636 basedir.AppendASCII("manifest_v2.xml")); 637 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 638 basedir.AppendASCII("v2.crx")); 639 640 // Check that the policy is initially empty. 641 ASSERT_TRUE(extensions::ExtensionManagementFactory::GetForBrowserContext( 642 browser()->profile()) 643 ->GetForceInstallList() 644 ->empty()) 645 << kForceInstallNotEmptyHelp; 646 647 // User install of the extension. 648 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); 649 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 650 const Extension* extension = service->GetExtensionById(kExtensionId, false); 651 ASSERT_TRUE(extension); 652 EXPECT_EQ(Manifest::INTERNAL, extension->location()); 653 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); 654 655 // Setup the force install policy. It should override the location. 656 base::ListValue forcelist; 657 forcelist.AppendString(BuildForceInstallPolicyValue( 658 kExtensionId, "http://localhost/autoupdate/manifest")); 659 PolicyMap policies; 660 policies.Set(policy::key::kExtensionInstallForcelist, 661 policy::POLICY_LEVEL_MANDATORY, 662 policy::POLICY_SCOPE_USER, 663 forcelist.DeepCopy(), 664 NULL); 665 UpdateProviderPolicy(policies); 666 667 ASSERT_TRUE(WaitForExtensionInstall()); 668 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 669 extension = service->GetExtensionById(kExtensionId, false); 670 ASSERT_TRUE(extension); 671 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); 672 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); 673 674 // Remove the policy, and verify that the extension was uninstalled. 675 // TODO(joaodasilva): it would be nicer if the extension was kept instead, 676 // and reverted location to INTERNAL or whatever it was before the policy 677 // was applied. 678 policies.Erase(policy::key::kExtensionInstallForcelist); 679 UpdateProviderPolicy(policies); 680 ASSERT_EQ(size_before, registry->enabled_extensions().size()); 681 extension = service->GetExtensionById(kExtensionId, true); 682 EXPECT_FALSE(extension); 683 684 // User install again, but have it disabled too before setting the policy. 685 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); 686 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 687 extension = service->GetExtensionById(kExtensionId, false); 688 ASSERT_TRUE(extension); 689 EXPECT_EQ(Manifest::INTERNAL, extension->location()); 690 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); 691 EXPECT_TRUE(registry->disabled_extensions().is_empty()); 692 693 DisableExtension(kExtensionId); 694 EXPECT_EQ(1u, registry->disabled_extensions().size()); 695 extension = service->GetExtensionById(kExtensionId, true); 696 EXPECT_TRUE(extension); 697 EXPECT_FALSE(service->IsExtensionEnabled(kExtensionId)); 698 699 // Install the policy again. It should overwrite the extension's location, 700 // and force enable it too. 701 policies.Set(policy::key::kExtensionInstallForcelist, 702 policy::POLICY_LEVEL_MANDATORY, 703 policy::POLICY_SCOPE_USER, 704 forcelist.DeepCopy(), 705 NULL); 706 UpdateProviderPolicy(policies); 707 708 ASSERT_TRUE(WaitForExtensionInstall()); 709 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 710 extension = service->GetExtensionById(kExtensionId, false); 711 ASSERT_TRUE(extension); 712 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); 713 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); 714 EXPECT_TRUE(registry->disabled_extensions().is_empty()); 715} 716