15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/version.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/extension_management.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/external_policy_loader.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/external_provider_impl.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/testing_pref_service_syncable.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/external_provider_interface.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/pref_names.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ExternalPolicyLoaderTest : public testing::Test {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExternalPolicyLoaderTest() : ui_thread_(BrowserThread::UI, &loop_) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ExternalPolicyLoaderTest() {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need these to satisfy BrowserThread::CurrentlyOn(BrowserThread::UI)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks in ExternalProviderImpl.
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO loop_;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestBrowserThread ui_thread_;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockExternalPolicyProviderVisitor
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ExternalProviderInterface::VisitorInterface {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExternalPolicyProviderVisitor() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Initialize a provider with |policy_forcelist|, and check that it installs
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // exactly the extensions specified in |expected_extensions|.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Visit(const base::DictionaryValue& policy_forcelist,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             const std::set<std::string>& expected_extensions) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_.reset(new TestingProfile);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_->GetTestingPrefService()->SetManagedPref(
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        pref_names::kInstallForceList, policy_forcelist.DeepCopy());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider_.reset(new ExternalProviderImpl(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this,
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new ExternalPolicyLoader(
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ExtensionManagementFactory::GetForBrowserContext(profile_.get())),
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        profile_.get(),
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Manifest::INVALID_LOCATION,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Manifest::EXTERNAL_POLICY_DOWNLOAD,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Extension::NO_FLAGS));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Extensions will be removed from this list as they visited,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // so it should be emptied by the end.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_extensions_ = expected_extensions;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider_->VisitRegisteredExtension();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(expected_extensions_.empty());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnExternalExtensionFileFound(const std::string& id,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const Version* version,
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            const base::FilePath& path,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            Manifest::Location unused,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int unused2,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            bool unused3) OVERRIDE {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE() << "There should be no external extensions from files.";
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnExternalExtensionUpdateUrlFound(
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      const std::string& id,
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      const std::string& install_parameter,
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      const GURL& update_url,
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      Manifest::Location location,
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      int unused1,
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      bool unused2) OVERRIDE {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Extension has the correct location.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, location);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Provider returns the correct location when asked.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Manifest::Location location1;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<Version> version1;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider_->GetExtensionDetails(id, &location1, &version1);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, location1);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(version1.get());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Remove the extension from our list.
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1U, expected_extensions_.erase(id));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnExternalProviderReady(
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const ExternalProviderInterface* provider) OVERRIDE {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(provider, provider_.get());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(provider->IsReady());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<std::string> expected_extensions_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestingProfile> profile_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExternalProviderImpl> provider_;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockExternalPolicyProviderVisitor);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ExternalPolicyLoaderTest, PolicyIsParsed) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue forced_extensions;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<std::string> expected_extensions;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ExternalPolicyLoader::AddExtension(
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &forced_extensions, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http://www.example.com/crx?a=5;b=6");
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_extensions.insert("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ExternalPolicyLoader::AddExtension(
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &forced_extensions, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://clients2.google.com/service/update2/crx");
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_extensions.insert("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExternalPolicyProviderVisitor mv;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mv.Visit(forced_extensions, expected_extensions);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ExternalPolicyLoaderTest, InvalidEntriesIgnored) {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue forced_extensions;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<std::string> expected_extensions;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ExternalPolicyLoader::AddExtension(
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &forced_extensions, "cccccccccccccccccccccccccccccccc",
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http://www.example.com/crx");
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_extensions.insert("cccccccccccccccccccccccccccccccc");
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add invalid entries.
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  forced_extensions.SetString("invalid", "http://www.example.com/crx");
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  forced_extensions.SetString("dddddddddddddddddddddddddddddddd",
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              std::string());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  forced_extensions.SetString("invalid", "bad");
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExternalPolicyProviderVisitor mv;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mv.Visit(forced_extensions, expected_extensions);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
156