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 <vector> 6 7 #include "chrome/browser/extensions/webstore_inline_installer.h" 8 #include "chrome/common/extensions/webstore_install_result.h" 9 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 10 #include "content/public/browser/web_contents.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "url/gurl.h" 13 14 namespace extensions { 15 16 namespace { 17 18 // Wraps WebstoreInlineInstaller to provide access to domain verification 19 // methods for testing. 20 class TestWebstoreInlineInstaller : public WebstoreInlineInstaller { 21 public: 22 explicit TestWebstoreInlineInstaller(content::WebContents* contents, 23 const std::string& requestor_url); 24 25 bool TestCheckRequestorPermitted(const base::DictionaryValue& webstore_data) { 26 std::string error; 27 return CheckRequestorPermitted(webstore_data, &error); 28 } 29 30 protected: 31 virtual ~TestWebstoreInlineInstaller(); 32 }; 33 34 void TestInstallerCallback(bool success, 35 const std::string& error, 36 webstore_install::Result result) {} 37 38 TestWebstoreInlineInstaller::TestWebstoreInlineInstaller( 39 content::WebContents* contents, 40 const std::string& requestor_url) 41 : WebstoreInlineInstaller(contents, 42 "", 43 GURL(requestor_url), 44 base::Bind(&TestInstallerCallback)) { 45 } 46 47 TestWebstoreInlineInstaller::~TestWebstoreInlineInstaller() {} 48 49 // We inherit from ChromeRenderViewHostTestHarness only for 50 // CreateTestWebContents, because we need a mock WebContents to support the 51 // underlying WebstoreInlineInstaller in each test case. 52 class WebstoreInlineInstallerTest : public ChromeRenderViewHostTestHarness { 53 public: 54 // testing::Test 55 virtual void SetUp() OVERRIDE; 56 virtual void TearDown() OVERRIDE; 57 58 bool TestSingleVerifiedSite(const std::string& requestor_url, 59 const std::string& verified_site); 60 61 bool TestMultipleVerifiedSites( 62 const std::string& requestor_url, 63 const std::vector<std::string>& verified_sites); 64 65 protected: 66 scoped_ptr<content::WebContents> web_contents_; 67 }; 68 69 void WebstoreInlineInstallerTest::SetUp() { 70 ChromeRenderViewHostTestHarness::SetUp(); 71 web_contents_.reset(CreateTestWebContents()); 72 } 73 74 void WebstoreInlineInstallerTest::TearDown() { 75 web_contents_.reset(NULL); 76 ChromeRenderViewHostTestHarness::TearDown(); 77 } 78 79 // Simulates a test against the verified site string from a Webstore item's 80 // "verified_site" manifest entry. 81 bool WebstoreInlineInstallerTest::TestSingleVerifiedSite( 82 const std::string& requestor_url, 83 const std::string& verified_site) { 84 base::DictionaryValue webstore_data; 85 webstore_data.SetString("verified_site", verified_site); 86 87 scoped_refptr<TestWebstoreInlineInstaller> installer = 88 new TestWebstoreInlineInstaller(web_contents_.get(), requestor_url); 89 return installer->TestCheckRequestorPermitted(webstore_data); 90 } 91 92 // Simulates a test against a list of verified site strings from a Webstore 93 // item's "verified_sites" manifest entry. 94 bool WebstoreInlineInstallerTest::TestMultipleVerifiedSites( 95 const std::string& requestor_url, 96 const std::vector<std::string>& verified_sites) { 97 base::ListValue* sites = new base::ListValue(); 98 for (std::vector<std::string>::const_iterator it = verified_sites.begin(); 99 it != verified_sites.end(); ++it) { 100 sites->Append(new base::StringValue(*it)); 101 } 102 base::DictionaryValue webstore_data; 103 webstore_data.Set("verified_sites", sites); 104 105 scoped_refptr<TestWebstoreInlineInstaller> installer = 106 new TestWebstoreInlineInstaller(web_contents_.get(), requestor_url); 107 return installer->TestCheckRequestorPermitted(webstore_data); 108 } 109 110 } // namespace 111 112 TEST_F(WebstoreInlineInstallerTest, DomainVerification) { 113 // Exact domain match. 114 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com", "example.com")); 115 116 // The HTTPS scheme is allowed. 117 EXPECT_TRUE(TestSingleVerifiedSite("https://example.com", "example.com")); 118 119 // The file: scheme is not allowed. 120 EXPECT_FALSE(TestSingleVerifiedSite("file:///example.com", "example.com")); 121 122 // Trailing slash in URL. 123 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com/", "example.com")); 124 125 // Page on the domain. 126 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com/page.html", 127 "example.com")); 128 129 // Page on a subdomain. 130 EXPECT_TRUE(TestSingleVerifiedSite("http://sub.example.com/page.html", 131 "example.com")); 132 133 // Root domain when only a subdomain is verified. 134 EXPECT_FALSE(TestSingleVerifiedSite("http://example.com/", 135 "sub.example.com")); 136 137 // Different subdomain when only a subdomain is verified. 138 EXPECT_FALSE(TestSingleVerifiedSite("http://www.example.com/", 139 "sub.example.com")); 140 141 // Port matches. 142 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com:123/", 143 "example.com:123")); 144 145 // Port doesn't match. 146 EXPECT_FALSE(TestSingleVerifiedSite("http://example.com:456/", 147 "example.com:123")); 148 149 // Port is missing in the requestor URL. 150 EXPECT_FALSE(TestSingleVerifiedSite("http://example.com/", 151 "example.com:123")); 152 153 // Port is missing in the verified site (any port matches). 154 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com:123/", "example.com")); 155 156 // Path matches. 157 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com/path", 158 "example.com/path")); 159 160 // Path doesn't match. 161 EXPECT_FALSE(TestSingleVerifiedSite("http://example.com/foo", 162 "example.com/path")); 163 164 // Path is missing. 165 EXPECT_FALSE(TestSingleVerifiedSite("http://example.com", 166 "example.com/path")); 167 168 // Path matches (with trailing slash). 169 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com/path/", 170 "example.com/path")); 171 172 // Path matches (is a file under the path). 173 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com/path/page.html", 174 "example.com/path")); 175 176 // Path and port match. 177 EXPECT_TRUE(TestSingleVerifiedSite( 178 "http://example.com:123/path/page.html", "example.com:123/path")); 179 180 // Match specific valid schemes 181 EXPECT_TRUE(TestSingleVerifiedSite("http://example.com", 182 "http://example.com")); 183 EXPECT_TRUE(TestSingleVerifiedSite("https://example.com", 184 "https://example.com")); 185 186 // Mismatch specific vaild schemes 187 EXPECT_FALSE(TestSingleVerifiedSite("https://example.com", 188 "http://example.com")); 189 EXPECT_FALSE(TestSingleVerifiedSite("http://example.com", 190 "https://example.com")); 191 192 // Invalid scheme spec 193 EXPECT_FALSE(TestSingleVerifiedSite("file://example.com", 194 "file://example.com")); 195 196 std::vector<std::string> verified_sites; 197 verified_sites.push_back("foo.example.com"); 198 verified_sites.push_back("bar.example.com:123"); 199 verified_sites.push_back("example.com/unicorns"); 200 201 // Test valid examples against the site list. 202 203 EXPECT_TRUE(TestMultipleVerifiedSites("http://foo.example.com", 204 verified_sites)); 205 206 EXPECT_TRUE(TestMultipleVerifiedSites("http://bar.example.com:123", 207 verified_sites)); 208 209 EXPECT_TRUE(TestMultipleVerifiedSites( 210 "http://cooking.example.com/unicorns/bacon.html", verified_sites)); 211 212 // Test invalid examples against the site list. 213 214 EXPECT_FALSE(TestMultipleVerifiedSites("http://example.com", 215 verified_sites)); 216 217 EXPECT_FALSE(TestMultipleVerifiedSites("file://foo.example.com", 218 verified_sites)); 219 220 EXPECT_FALSE(TestMultipleVerifiedSites("http://baz.example.com", 221 verified_sites)); 222 223 EXPECT_FALSE(TestMultipleVerifiedSites("http://bar.example.com:456", 224 verified_sites)); 225 } 226 227 } // namespace extensions 228