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/external_policy_loader.h" 13 #include "chrome/browser/extensions/external_provider_impl.h" 14 #include "chrome/common/pref_names.h" 15 #include "chrome/test/base/testing_pref_service_syncable.h" 16 #include "chrome/test/base/testing_profile.h" 17 #include "content/public/test/test_browser_thread.h" 18 #include "extensions/browser/external_provider_interface.h" 19 #include "extensions/common/extension.h" 20 #include "extensions/common/manifest.h" 21 #include "testing/gtest/include/gtest/gtest.h" 22 23 using content::BrowserThread; 24 25 namespace extensions { 26 27 class ExternalPolicyLoaderTest : public testing::Test { 28 public: 29 ExternalPolicyLoaderTest() 30 : loop_(base::MessageLoop::TYPE_IO), 31 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::MessageLoop 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 prefs::kExtensionInstallForceList, 56 policy_forcelist.DeepCopy()); 57 provider_.reset(new ExternalProviderImpl( 58 this, 59 new ExternalPolicyLoader(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, const GURL& update_url, 84 Manifest::Location location, int unused1, bool unused2) OVERRIDE { 85 // Extension has the correct location. 86 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, location); 87 88 // Provider returns the correct location when asked. 89 Manifest::Location location1; 90 scoped_ptr<Version> version1; 91 provider_->GetExtensionDetails(id, &location1, &version1); 92 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, location1); 93 EXPECT_FALSE(version1.get()); 94 95 // Remove the extension from our list. 96 EXPECT_EQ(1U, expected_extensions_.erase(id)); 97 return true; 98 } 99 100 virtual void OnExternalProviderReady( 101 const ExternalProviderInterface* provider) OVERRIDE { 102 EXPECT_EQ(provider, provider_.get()); 103 EXPECT_TRUE(provider->IsReady()); 104 } 105 106 private: 107 std::set<std::string> expected_extensions_; 108 109 scoped_ptr<TestingProfile> profile_; 110 111 scoped_ptr<ExternalProviderImpl> provider_; 112 113 DISALLOW_COPY_AND_ASSIGN(MockExternalPolicyProviderVisitor); 114 }; 115 116 TEST_F(ExternalPolicyLoaderTest, PolicyIsParsed) { 117 base::DictionaryValue forced_extensions; 118 std::set<std::string> expected_extensions; 119 extensions::ExternalPolicyLoader::AddExtension( 120 &forced_extensions, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 121 "http://www.example.com/crx?a=5;b=6"); 122 expected_extensions.insert("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 123 extensions::ExternalPolicyLoader::AddExtension( 124 &forced_extensions, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 125 "https://clients2.google.com/service/update2/crx"); 126 expected_extensions.insert("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); 127 128 MockExternalPolicyProviderVisitor mv; 129 mv.Visit(forced_extensions, expected_extensions); 130 } 131 132 TEST_F(ExternalPolicyLoaderTest, InvalidEntriesIgnored) { 133 base::DictionaryValue forced_extensions; 134 std::set<std::string> expected_extensions; 135 136 extensions::ExternalPolicyLoader::AddExtension( 137 &forced_extensions, "cccccccccccccccccccccccccccccccc", 138 "http://www.example.com/crx"); 139 expected_extensions.insert("cccccccccccccccccccccccccccccccc"); 140 141 // Add invalid entries. 142 forced_extensions.SetString("invalid", "http://www.example.com/crx"); 143 forced_extensions.SetString("dddddddddddddddddddddddddddddddd", 144 std::string()); 145 forced_extensions.SetString("invalid", "bad"); 146 147 MockExternalPolicyProviderVisitor mv; 148 mv.Visit(forced_extensions, expected_extensions); 149 } 150 151 } // namespace extensions 152