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 <set> 6 #include <string> 7 8 #include "base/logging.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/values.h" 11 #include "base/version.h" 12 #include "chrome/browser/extensions/extension_management.h" 13 #include "chrome/browser/extensions/external_policy_loader.h" 14 #include "chrome/browser/extensions/external_provider_impl.h" 15 #include "chrome/common/pref_names.h" 16 #include "chrome/test/base/testing_pref_service_syncable.h" 17 #include "chrome/test/base/testing_profile.h" 18 #include "content/public/test/test_browser_thread.h" 19 #include "extensions/browser/external_provider_interface.h" 20 #include "extensions/browser/pref_names.h" 21 #include "extensions/common/extension.h" 22 #include "extensions/common/manifest.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 25 using content::BrowserThread; 26 27 namespace extensions { 28 29 class ExternalPolicyLoaderTest : public testing::Test { 30 public: 31 ExternalPolicyLoaderTest() : ui_thread_(BrowserThread::UI, &loop_) { 32 } 33 34 virtual ~ExternalPolicyLoaderTest() {} 35 36 private: 37 // We need these to satisfy BrowserThread::CurrentlyOn(BrowserThread::UI) 38 // checks in ExternalProviderImpl. 39 base::MessageLoopForIO loop_; 40 content::TestBrowserThread ui_thread_; 41 }; 42 43 class MockExternalPolicyProviderVisitor 44 : public ExternalProviderInterface::VisitorInterface { 45 public: 46 MockExternalPolicyProviderVisitor() { 47 } 48 49 // Initialize a provider with |policy_forcelist|, and check that it installs 50 // exactly the extensions specified in |expected_extensions|. 51 void Visit(const base::DictionaryValue& policy_forcelist, 52 const std::set<std::string>& expected_extensions) { 53 profile_.reset(new TestingProfile); 54 profile_->GetTestingPrefService()->SetManagedPref( 55 pref_names::kInstallForceList, policy_forcelist.DeepCopy()); 56 provider_.reset(new ExternalProviderImpl( 57 this, 58 new ExternalPolicyLoader( 59 ExtensionManagementFactory::GetForBrowserContext(profile_.get())), 60 profile_.get(), 61 Manifest::INVALID_LOCATION, 62 Manifest::EXTERNAL_POLICY_DOWNLOAD, 63 Extension::NO_FLAGS)); 64 65 // Extensions will be removed from this list as they visited, 66 // so it should be emptied by the end. 67 expected_extensions_ = expected_extensions; 68 provider_->VisitRegisteredExtension(); 69 EXPECT_TRUE(expected_extensions_.empty()); 70 } 71 72 virtual bool OnExternalExtensionFileFound(const std::string& id, 73 const Version* version, 74 const base::FilePath& path, 75 Manifest::Location unused, 76 int unused2, 77 bool unused3) OVERRIDE { 78 ADD_FAILURE() << "There should be no external extensions from files."; 79 return false; 80 } 81 82 virtual bool OnExternalExtensionUpdateUrlFound( 83 const std::string& id, 84 const std::string& install_parameter, 85 const GURL& update_url, 86 Manifest::Location location, 87 int unused1, 88 bool unused2) OVERRIDE { 89 // Extension has the correct location. 90 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, location); 91 92 // Provider returns the correct location when asked. 93 Manifest::Location location1; 94 scoped_ptr<Version> version1; 95 provider_->GetExtensionDetails(id, &location1, &version1); 96 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, location1); 97 EXPECT_FALSE(version1.get()); 98 99 // Remove the extension from our list. 100 EXPECT_EQ(1U, expected_extensions_.erase(id)); 101 return true; 102 } 103 104 virtual void OnExternalProviderReady( 105 const ExternalProviderInterface* provider) OVERRIDE { 106 EXPECT_EQ(provider, provider_.get()); 107 EXPECT_TRUE(provider->IsReady()); 108 } 109 110 private: 111 std::set<std::string> expected_extensions_; 112 113 scoped_ptr<TestingProfile> profile_; 114 115 scoped_ptr<ExternalProviderImpl> provider_; 116 117 DISALLOW_COPY_AND_ASSIGN(MockExternalPolicyProviderVisitor); 118 }; 119 120 TEST_F(ExternalPolicyLoaderTest, PolicyIsParsed) { 121 base::DictionaryValue forced_extensions; 122 std::set<std::string> expected_extensions; 123 extensions::ExternalPolicyLoader::AddExtension( 124 &forced_extensions, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 125 "http://www.example.com/crx?a=5;b=6"); 126 expected_extensions.insert("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 127 extensions::ExternalPolicyLoader::AddExtension( 128 &forced_extensions, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 129 "https://clients2.google.com/service/update2/crx"); 130 expected_extensions.insert("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); 131 132 MockExternalPolicyProviderVisitor mv; 133 mv.Visit(forced_extensions, expected_extensions); 134 } 135 136 TEST_F(ExternalPolicyLoaderTest, InvalidEntriesIgnored) { 137 base::DictionaryValue forced_extensions; 138 std::set<std::string> expected_extensions; 139 140 extensions::ExternalPolicyLoader::AddExtension( 141 &forced_extensions, "cccccccccccccccccccccccccccccccc", 142 "http://www.example.com/crx"); 143 expected_extensions.insert("cccccccccccccccccccccccccccccccc"); 144 145 // Add invalid entries. 146 forced_extensions.SetString("invalid", "http://www.example.com/crx"); 147 forced_extensions.SetString("dddddddddddddddddddddddddddddddd", 148 std::string()); 149 forced_extensions.SetString("invalid", "bad"); 150 151 MockExternalPolicyProviderVisitor mv; 152 mv.Visit(forced_extensions, expected_extensions); 153 } 154 155 } // namespace extensions 156