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
14namespace extensions {
15
16namespace {
17
18// Wraps WebstoreInlineInstaller to provide access to domain verification
19// methods for testing.
20class 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
34void TestInstallerCallback(bool success,
35                           const std::string& error,
36                           webstore_install::Result result) {}
37
38TestWebstoreInlineInstaller::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
47TestWebstoreInlineInstaller::~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.
52class 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
69void WebstoreInlineInstallerTest::SetUp() {
70  ChromeRenderViewHostTestHarness::SetUp();
71  web_contents_.reset(CreateTestWebContents());
72}
73
74void 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.
81bool 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.
94bool 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
112TEST_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