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