permissions_data_unittest.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
1// Copyright (c) 2013 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 "base/command_line.h"
8#include "base/memory/ref_counted.h"
9#include "base/strings/string16.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/common/chrome_version_info.h"
12#include "chrome/common/extensions/extension.h"
13#include "chrome/common/extensions/extension_manifest_constants.h"
14#include "chrome/common/extensions/extension_test_util.h"
15#include "chrome/common/extensions/features/feature.h"
16#include "chrome/common/extensions/permissions/api_permission.h"
17#include "chrome/common/extensions/permissions/permission_set.h"
18#include "chrome/common/extensions/permissions/permissions_data.h"
19#include "chrome/common/extensions/permissions/socket_permission.h"
20#include "content/public/common/socket_permission_request.h"
21#include "extensions/common/error_utils.h"
22#include "extensions/common/id_util.h"
23#include "extensions/common/switches.h"
24#include "extensions/common/url_pattern_set.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
27using content::SocketPermissionRequest;
28using extension_test_util::LoadManifest;
29using extension_test_util::LoadManifestUnchecked;
30using extension_test_util::LoadManifestStrict;
31
32namespace extensions {
33
34namespace {
35
36bool CheckSocketPermission(
37    scoped_refptr<Extension> extension,
38    SocketPermissionRequest::OperationType type,
39    const char* host,
40    int port) {
41  SocketPermission::CheckParam param(type, host, port);
42  return PermissionsData::CheckAPIPermissionWithParam(
43      extension.get(), APIPermission::kSocket, &param);
44}
45
46}  // namespace
47
48TEST(ExtensionPermissionsTest, EffectiveHostPermissions) {
49  scoped_refptr<Extension> extension;
50  URLPatternSet hosts;
51
52  extension = LoadManifest("effective_host_permissions", "empty.json");
53  EXPECT_EQ(0u,
54            PermissionsData::GetEffectiveHostPermissions(extension.get())
55                .patterns().size());
56  EXPECT_FALSE(hosts.MatchesURL(GURL("http://www.google.com")));
57  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
58
59  extension = LoadManifest("effective_host_permissions", "one_host.json");
60  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
61  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
62  EXPECT_FALSE(hosts.MatchesURL(GURL("https://www.google.com")));
63  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
64
65  extension = LoadManifest("effective_host_permissions",
66                           "one_host_wildcard.json");
67  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
68  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
69  EXPECT_TRUE(hosts.MatchesURL(GURL("http://foo.google.com")));
70  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
71
72  extension = LoadManifest("effective_host_permissions", "two_hosts.json");
73  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
74  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
75  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
76  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
77
78  extension = LoadManifest("effective_host_permissions",
79                           "https_not_considered.json");
80  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
81  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
82  EXPECT_TRUE(hosts.MatchesURL(GURL("https://google.com")));
83  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
84
85  extension = LoadManifest("effective_host_permissions",
86                           "two_content_scripts.json");
87  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
88  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
89  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
90  EXPECT_TRUE(extension->GetActivePermissions()->HasEffectiveAccessToURL(
91      GURL("http://www.reddit.com")));
92  EXPECT_TRUE(hosts.MatchesURL(GURL("http://news.ycombinator.com")));
93  EXPECT_TRUE(extension->GetActivePermissions()->HasEffectiveAccessToURL(
94      GURL("http://news.ycombinator.com")));
95  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
96
97  extension = LoadManifest("effective_host_permissions", "all_hosts.json");
98  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
99  EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
100  EXPECT_FALSE(hosts.MatchesURL(GURL("https://test/")));
101  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
102  EXPECT_TRUE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
103
104  extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
105  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
106  EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
107  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
108  EXPECT_TRUE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
109
110  extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
111  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
112  EXPECT_FALSE(hosts.MatchesURL(GURL("http://test/")));
113  EXPECT_TRUE(hosts.MatchesURL(GURL("https://test/")));
114  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
115  EXPECT_TRUE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
116}
117
118TEST(ExtensionPermissionsTest, SocketPermissions) {
119  // Set feature current channel to appropriate value.
120  Feature::ScopedCurrentChannel scoped_channel(
121      chrome::VersionInfo::CHANNEL_DEV);
122  scoped_refptr<Extension> extension;
123  std::string error;
124
125  extension = LoadManifest("socket_permissions", "empty.json");
126  EXPECT_FALSE(CheckSocketPermission(extension,
127      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
128
129  extension = LoadManifestUnchecked("socket_permissions",
130                                    "socket1.json",
131                                    Manifest::INTERNAL, Extension::NO_FLAGS,
132                                    &error);
133  EXPECT_TRUE(extension.get() == NULL);
134  ASSERT_EQ(ErrorUtils::FormatErrorMessage(
135                extension_manifest_errors::kInvalidPermission, "socket"),
136            error);
137
138  extension = LoadManifest("socket_permissions", "socket2.json");
139  EXPECT_TRUE(CheckSocketPermission(extension,
140      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
141  EXPECT_FALSE(CheckSocketPermission(
142        extension, SocketPermissionRequest::UDP_BIND, "", 80));
143  EXPECT_TRUE(CheckSocketPermission(
144        extension, SocketPermissionRequest::UDP_BIND, "", 8888));
145
146  EXPECT_FALSE(CheckSocketPermission(
147        extension, SocketPermissionRequest::UDP_SEND_TO, "example.com", 1900));
148  EXPECT_TRUE(CheckSocketPermission(
149        extension,
150        SocketPermissionRequest::UDP_SEND_TO,
151        "239.255.255.250", 1900));
152}
153
154TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyAPIPermissions) {
155  scoped_refptr<Extension> extension;
156  extension = LoadManifest("permissions", "many-apis.json");
157  std::vector<string16> warnings =
158      PermissionsData::GetPermissionMessageStrings(extension.get());
159  ASSERT_EQ(6u, warnings.size());
160  EXPECT_EQ("Access your data on api.flickr.com",
161            UTF16ToUTF8(warnings[0]));
162  EXPECT_EQ("Read and modify your bookmarks", UTF16ToUTF8(warnings[1]));
163  EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[2]));
164  EXPECT_EQ("Read and modify your browsing history", UTF16ToUTF8(warnings[3]));
165  EXPECT_EQ("Access your tabs and browsing activity", UTF16ToUTF8(warnings[4]));
166  EXPECT_EQ("Manage your apps, extensions, and themes",
167            UTF16ToUTF8(warnings[5]));
168}
169
170TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHostsPermissions) {
171  scoped_refptr<Extension> extension;
172  extension = LoadManifest("permissions", "more-than-3-hosts.json");
173  std::vector<string16> warnings =
174      PermissionsData::GetPermissionMessageStrings(extension.get());
175  std::vector<string16> warnings_details =
176      PermissionsData::GetPermissionMessageDetailsStrings(extension.get());
177  ASSERT_EQ(1u, warnings.size());
178  ASSERT_EQ(1u, warnings_details.size());
179#if defined(TOOLKIT_VIEWS)
180  EXPECT_EQ("Access your data on 5 website(s)", UTF16ToUTF8(warnings[0]));
181  EXPECT_EQ("- www.a.com\n- www.b.com\n- www.c.com\n- www.d.com\n- www.e.com",
182            UTF16ToUTF8(warnings_details[0]));
183#else
184  // TODO(finnur): Remove once other platforms support expandable sections.
185  EXPECT_EQ("Access your data on www.a.com, www.b.com, and 3 other websites",
186            UTF16ToUTF8(warnings[0]));
187  EXPECT_TRUE(warnings_details[0].empty());
188#endif
189}
190
191TEST(ExtensionPermissionsTest, GetPermissionMessages_LocationApiPermission) {
192  scoped_refptr<Extension> extension;
193  extension = LoadManifest("permissions",
194                           "location-api.json",
195                           Manifest::COMPONENT,
196                           Extension::NO_FLAGS);
197  std::vector<string16> warnings =
198      PermissionsData::GetPermissionMessageStrings(extension.get());
199  ASSERT_EQ(1u, warnings.size());
200  EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[0]));
201}
202
203TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHosts) {
204  scoped_refptr<Extension> extension;
205  extension = LoadManifest("permissions", "many-hosts.json");
206  std::vector<string16> warnings =
207      PermissionsData::GetPermissionMessageStrings(extension.get());
208  ASSERT_EQ(1u, warnings.size());
209  EXPECT_EQ("Access your data on encrypted.google.com and www.google.com",
210            UTF16ToUTF8(warnings[0]));
211}
212
213TEST(ExtensionPermissionsTest, GetPermissionMessages_Plugins) {
214  scoped_refptr<Extension> extension;
215  extension = LoadManifest("permissions", "plugins.json");
216  std::vector<string16> warnings =
217      PermissionsData::GetPermissionMessageStrings(extension.get());
218// We don't parse the plugins key on Chrome OS, so it should not ask for any
219// permissions.
220#if defined(OS_CHROMEOS)
221  ASSERT_EQ(0u, warnings.size());
222#else
223  ASSERT_EQ(1u, warnings.size());
224  EXPECT_EQ("Access all data on your computer and the websites you visit",
225            UTF16ToUTF8(warnings[0]));
226#endif
227}
228
229// Base class for testing the CanExecuteScriptOnPage and CanCaptureVisiblePage
230// methods of Extension for extensions with various permissions.
231class ExtensionScriptAndCaptureVisibleTest : public testing::Test {
232 protected:
233  ExtensionScriptAndCaptureVisibleTest()
234      : http_url("http://www.google.com"),
235        http_url_with_path("http://www.google.com/index.html"),
236        https_url("https://www.google.com"),
237        file_url("file:///foo/bar"),
238        favicon_url("chrome://favicon/http://www.google.com"),
239        extension_url("chrome-extension://" +
240            id_util::GenerateIdForPath(
241                base::FilePath(FILE_PATH_LITERAL("foo")))),
242        settings_url("chrome://settings"),
243        about_url("about:flags") {
244    urls_.insert(http_url);
245    urls_.insert(http_url_with_path);
246    urls_.insert(https_url);
247    urls_.insert(file_url);
248    urls_.insert(favicon_url);
249    urls_.insert(extension_url);
250    urls_.insert(settings_url);
251    urls_.insert(about_url);
252    // Ignore the policy delegate for this test.
253    PermissionsData::SetPolicyDelegate(NULL);
254  }
255
256  bool AllowedScript(const Extension* extension, const GURL& url,
257                     const GURL& top_url) {
258    return PermissionsData::CanExecuteScriptOnPage(
259        extension, url, top_url, -1, NULL, -1, NULL);
260  }
261
262  bool BlockedScript(const Extension* extension, const GURL& url,
263                     const GURL& top_url) {
264    return !PermissionsData::CanExecuteScriptOnPage(
265        extension, url, top_url, -1, NULL, -1, NULL);
266  }
267
268  bool Allowed(const Extension* extension, const GURL& url) {
269    return Allowed(extension, url, -1);
270  }
271
272  bool Allowed(const Extension* extension, const GURL& url, int tab_id) {
273    return (PermissionsData::CanExecuteScriptOnPage(
274                extension, url, url, tab_id, NULL, -1, NULL) &&
275            PermissionsData::CanCaptureVisiblePage(
276                extension, url, tab_id, NULL));
277  }
278
279  bool CaptureOnly(const Extension* extension, const GURL& url) {
280    return CaptureOnly(extension, url, -1);
281  }
282
283  bool CaptureOnly(const Extension* extension, const GURL& url, int tab_id) {
284    return !PermissionsData::CanExecuteScriptOnPage(
285                extension, url, url, tab_id, NULL, -1, NULL) &&
286           PermissionsData::CanCaptureVisiblePage(extension, url, tab_id, NULL);
287  }
288
289  bool Blocked(const Extension* extension, const GURL& url) {
290    return Blocked(extension, url, -1);
291  }
292
293  bool Blocked(const Extension* extension, const GURL& url, int tab_id) {
294    return !(PermissionsData::CanExecuteScriptOnPage(
295                 extension, url, url, tab_id, NULL, -1, NULL) ||
296             PermissionsData::CanCaptureVisiblePage(
297                 extension, url, tab_id, NULL));
298  }
299
300  bool AllowedExclusivelyOnTab(
301      const Extension* extension,
302      const std::set<GURL>& allowed_urls,
303      int tab_id) {
304    bool result = true;
305    for (std::set<GURL>::iterator it = urls_.begin(); it != urls_.end(); ++it) {
306      const GURL& url = *it;
307      if (allowed_urls.count(url))
308        result &= Allowed(extension, url, tab_id);
309      else
310        result &= Blocked(extension, url, tab_id);
311    }
312    return result;
313  }
314
315  // URLs that are "safe" to provide scripting and capture visible tab access
316  // to if the permissions allow it.
317  const GURL http_url;
318  const GURL http_url_with_path;
319  const GURL https_url;
320  const GURL file_url;
321
322  // We should allow host permission but not scripting permission for favicon
323  // urls.
324  const GURL favicon_url;
325
326  // URLs that regular extensions should never get access to.
327  const GURL extension_url;
328  const GURL settings_url;
329  const GURL about_url;
330
331 private:
332  // The set of all URLs above.
333  std::set<GURL> urls_;
334};
335
336TEST_F(ExtensionScriptAndCaptureVisibleTest, Permissions) {
337  // Test <all_urls> for regular extensions.
338  scoped_refptr<Extension> extension = LoadManifestStrict("script_and_capture",
339      "extension_regular_all.json");
340
341  EXPECT_TRUE(Allowed(extension.get(), http_url));
342  EXPECT_TRUE(Allowed(extension.get(), https_url));
343  EXPECT_TRUE(Blocked(extension.get(), file_url));
344  EXPECT_TRUE(Blocked(extension.get(), settings_url));
345  EXPECT_TRUE(CaptureOnly(extension.get(), favicon_url));
346  EXPECT_TRUE(Blocked(extension.get(), about_url));
347  EXPECT_TRUE(Blocked(extension.get(), extension_url));
348
349  // Test access to iframed content.
350  GURL within_extension_url = extension->GetResourceURL("page.html");
351  EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path));
352  EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path));
353  EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url));
354  EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url));
355  EXPECT_TRUE(BlockedScript(extension.get(), http_url, extension_url));
356  EXPECT_TRUE(BlockedScript(extension.get(), https_url, extension_url));
357
358  EXPECT_FALSE(
359      PermissionsData::HasHostPermission(extension.get(), settings_url));
360  EXPECT_FALSE(PermissionsData::HasHostPermission(extension.get(), about_url));
361  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
362
363  // Test * for scheme, which implies just the http/https schemes.
364  extension = LoadManifestStrict("script_and_capture",
365      "extension_wildcard.json");
366  EXPECT_TRUE(Allowed(extension.get(), http_url));
367  EXPECT_TRUE(Allowed(extension.get(), https_url));
368  EXPECT_TRUE(Blocked(extension.get(), settings_url));
369  EXPECT_TRUE(Blocked(extension.get(), about_url));
370  EXPECT_TRUE(Blocked(extension.get(), file_url));
371  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
372  extension =
373      LoadManifest("script_and_capture", "extension_wildcard_settings.json");
374  EXPECT_TRUE(Blocked(extension.get(), settings_url));
375
376  // Having chrome://*/ should not work for regular extensions. Note that
377  // for favicon access, we require the explicit pattern chrome://favicon/*.
378  std::string error;
379  extension = LoadManifestUnchecked("script_and_capture",
380                                    "extension_wildcard_chrome.json",
381                                    Manifest::INTERNAL, Extension::NO_FLAGS,
382                                    &error);
383  EXPECT_TRUE(extension.get() == NULL);
384  EXPECT_EQ(
385      ErrorUtils::FormatErrorMessage(
386          extension_manifest_errors::kInvalidPermissionScheme, "chrome://*/"),
387      error);
388
389  // Having chrome://favicon/* should not give you chrome://*
390  extension = LoadManifestStrict("script_and_capture",
391      "extension_chrome_favicon_wildcard.json");
392  EXPECT_TRUE(Blocked(extension.get(), settings_url));
393  EXPECT_TRUE(CaptureOnly(extension.get(), favicon_url));
394  EXPECT_TRUE(Blocked(extension.get(), about_url));
395  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
396
397  // Having http://favicon should not give you chrome://favicon
398  extension = LoadManifestStrict("script_and_capture",
399      "extension_http_favicon.json");
400  EXPECT_TRUE(Blocked(extension.get(), settings_url));
401  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
402
403  // Component extensions with <all_urls> should get everything.
404  extension = LoadManifest("script_and_capture", "extension_component_all.json",
405      Manifest::COMPONENT, Extension::NO_FLAGS);
406  EXPECT_TRUE(Allowed(extension.get(), http_url));
407  EXPECT_TRUE(Allowed(extension.get(), https_url));
408  EXPECT_TRUE(Allowed(extension.get(), settings_url));
409  EXPECT_TRUE(Allowed(extension.get(), about_url));
410  EXPECT_TRUE(Allowed(extension.get(), favicon_url));
411  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
412
413  // Component extensions should only get access to what they ask for.
414  extension = LoadManifest("script_and_capture",
415      "extension_component_google.json", Manifest::COMPONENT,
416      Extension::NO_FLAGS);
417  EXPECT_TRUE(Allowed(extension.get(), http_url));
418  EXPECT_TRUE(Blocked(extension.get(), https_url));
419  EXPECT_TRUE(Blocked(extension.get(), file_url));
420  EXPECT_TRUE(Blocked(extension.get(), settings_url));
421  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
422  EXPECT_TRUE(Blocked(extension.get(), about_url));
423  EXPECT_TRUE(Blocked(extension.get(), extension_url));
424  EXPECT_FALSE(
425      PermissionsData::HasHostPermission(extension.get(), settings_url));
426}
427
428TEST_F(ExtensionScriptAndCaptureVisibleTest, PermissionsWithChromeURLsEnabled) {
429  CommandLine::ForCurrentProcess()->AppendSwitch(
430      switches::kExtensionsOnChromeURLs);
431
432  scoped_refptr<Extension> extension;
433
434  // Test <all_urls> for regular extensions.
435  extension = LoadManifestStrict("script_and_capture",
436      "extension_regular_all.json");
437  EXPECT_TRUE(Allowed(extension.get(), http_url));
438  EXPECT_TRUE(Allowed(extension.get(), https_url));
439  EXPECT_TRUE(Blocked(extension.get(), file_url));
440  EXPECT_TRUE(Blocked(extension.get(), settings_url));
441  EXPECT_TRUE(Allowed(extension.get(), favicon_url));  // chrome:// requested
442  EXPECT_TRUE(Blocked(extension.get(), about_url));
443  EXPECT_TRUE(Blocked(extension.get(), extension_url));
444
445  // Test access to iframed content.
446  GURL within_extension_url = extension->GetResourceURL("page.html");
447  EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path));
448  EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path));
449  EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url));
450  EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url));
451  EXPECT_TRUE(BlockedScript(extension.get(), http_url, extension_url));
452  EXPECT_TRUE(BlockedScript(extension.get(), https_url, extension_url));
453
454  EXPECT_FALSE(
455      PermissionsData::HasHostPermission(extension.get(), settings_url));
456  EXPECT_FALSE(PermissionsData::HasHostPermission(extension.get(), about_url));
457  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
458
459  // Test * for scheme, which implies just the http/https schemes.
460  extension = LoadManifestStrict("script_and_capture",
461      "extension_wildcard.json");
462  EXPECT_TRUE(Allowed(extension.get(), http_url));
463  EXPECT_TRUE(Allowed(extension.get(), https_url));
464  EXPECT_TRUE(Blocked(extension.get(), settings_url));
465  EXPECT_TRUE(Blocked(extension.get(), about_url));
466  EXPECT_TRUE(Blocked(extension.get(), file_url));
467  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
468  extension =
469      LoadManifest("script_and_capture", "extension_wildcard_settings.json");
470  EXPECT_TRUE(Blocked(extension.get(), settings_url));
471
472  // Having chrome://*/ should work for regular extensions with the flag
473  // enabled.
474  std::string error;
475  extension = LoadManifestUnchecked("script_and_capture",
476                                    "extension_wildcard_chrome.json",
477                                    Manifest::INTERNAL, Extension::NO_FLAGS,
478                                    &error);
479  EXPECT_FALSE(extension.get() == NULL);
480  EXPECT_TRUE(Blocked(extension.get(), http_url));
481  EXPECT_TRUE(Blocked(extension.get(), https_url));
482  EXPECT_TRUE(Allowed(extension.get(), settings_url));
483  EXPECT_TRUE(Blocked(extension.get(), about_url));
484  EXPECT_TRUE(Blocked(extension.get(), file_url));
485  EXPECT_TRUE(Allowed(extension.get(), favicon_url));  // chrome:// requested
486
487  // Having chrome://favicon/* should not give you chrome://*
488  extension = LoadManifestStrict("script_and_capture",
489      "extension_chrome_favicon_wildcard.json");
490  EXPECT_TRUE(Blocked(extension.get(), settings_url));
491  EXPECT_TRUE(Allowed(extension.get(), favicon_url));  // chrome:// requested
492  EXPECT_TRUE(Blocked(extension.get(), about_url));
493  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
494
495  // Having http://favicon should not give you chrome://favicon
496  extension = LoadManifestStrict("script_and_capture",
497      "extension_http_favicon.json");
498  EXPECT_TRUE(Blocked(extension.get(), settings_url));
499  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
500
501  // Component extensions with <all_urls> should get everything.
502  extension = LoadManifest("script_and_capture", "extension_component_all.json",
503      Manifest::COMPONENT, Extension::NO_FLAGS);
504  EXPECT_TRUE(Allowed(extension.get(), http_url));
505  EXPECT_TRUE(Allowed(extension.get(), https_url));
506  EXPECT_TRUE(Allowed(extension.get(), settings_url));
507  EXPECT_TRUE(Allowed(extension.get(), about_url));
508  EXPECT_TRUE(Allowed(extension.get(), favicon_url));
509  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
510
511  // Component extensions should only get access to what they ask for.
512  extension = LoadManifest("script_and_capture",
513      "extension_component_google.json", Manifest::COMPONENT,
514      Extension::NO_FLAGS);
515  EXPECT_TRUE(Allowed(extension.get(), http_url));
516  EXPECT_TRUE(Blocked(extension.get(), https_url));
517  EXPECT_TRUE(Blocked(extension.get(), file_url));
518  EXPECT_TRUE(Blocked(extension.get(), settings_url));
519  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
520  EXPECT_TRUE(Blocked(extension.get(), about_url));
521  EXPECT_TRUE(Blocked(extension.get(), extension_url));
522  EXPECT_FALSE(
523      PermissionsData::HasHostPermission(extension.get(), settings_url));
524}
525
526TEST_F(ExtensionScriptAndCaptureVisibleTest, TabSpecific) {
527  scoped_refptr<Extension> extension =
528      LoadManifestStrict("script_and_capture", "tab_specific.json");
529
530  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
531                   .get());
532  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 1)
533                   .get());
534  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 2)
535                   .get());
536
537  std::set<GURL> no_urls;
538
539  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 0));
540  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 1));
541  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
542
543  URLPatternSet allowed_hosts;
544  allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
545                                      http_url.spec()));
546  std::set<GURL> allowed_urls;
547  allowed_urls.insert(http_url);
548  // http_url_with_path() will also be allowed, because Extension should be
549  // considering the security origin of the URL not the URL itself, and
550  // http_url is in allowed_hosts.
551  allowed_urls.insert(http_url_with_path);
552
553  {
554    scoped_refptr<PermissionSet> permissions(
555        new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet()));
556    PermissionsData::UpdateTabSpecificPermissions(
557        extension.get(), 0, permissions);
558    EXPECT_EQ(permissions->explicit_hosts(),
559              PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
560                  ->explicit_hosts());
561  }
562
563  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), allowed_urls, 0));
564  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 1));
565  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
566
567  PermissionsData::ClearTabSpecificPermissions(extension.get(), 0);
568  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
569                   .get());
570
571  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 0));
572  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 1));
573  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
574
575  std::set<GURL> more_allowed_urls = allowed_urls;
576  more_allowed_urls.insert(https_url);
577  URLPatternSet more_allowed_hosts = allowed_hosts;
578  more_allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
579                                           https_url.spec()));
580
581  {
582    scoped_refptr<PermissionSet> permissions(
583        new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet()));
584    PermissionsData::UpdateTabSpecificPermissions(
585        extension.get(), 0, permissions);
586    EXPECT_EQ(permissions->explicit_hosts(),
587              PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
588                  ->explicit_hosts());
589
590    permissions = new PermissionSet(APIPermissionSet(),
591                                    more_allowed_hosts,
592                                    URLPatternSet());
593    PermissionsData::UpdateTabSpecificPermissions(
594        extension.get(), 1, permissions);
595    EXPECT_EQ(permissions->explicit_hosts(),
596              PermissionsData::GetTabSpecificPermissions(extension.get(), 1)
597                  ->explicit_hosts());
598  }
599
600  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), allowed_urls, 0));
601  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1));
602  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
603
604  PermissionsData::ClearTabSpecificPermissions(extension.get(), 0);
605  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
606                   .get());
607
608  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 0));
609  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1));
610  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
611
612  PermissionsData::ClearTabSpecificPermissions(extension.get(), 1);
613  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 1)
614                   .get());
615
616  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 0));
617  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 1));
618  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
619}
620
621}  // namespace extensions
622