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