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(&notification_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(&notification_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