[Extensions] Restrict tabs.captureVisibleTab()

Modify the permissions for tabs.captureVisibleTab(). Instead of just
checking for <all_urls> and assuming its safe, do the following:
- If the page is a "normal" web page (e.g., http/https), allow the
  capture if the extension has activeTab granted or <all_urls>.
- If the page is a file page (file:///), allow the capture if the
  extension has file access *and* either of the <all_urls> or
  activeTab permissions.
- If the page is a chrome:// page, allow the capture only if the
  extension has activeTab granted.

Bug: 810220

Change-Id: I1e2f71281e2f331d641ba0e435df10d66d721304
Reviewed-on: https://chromium-review.googlesource.com/981195
Commit-Queue: Devlin <rdevlin.cronin@chromium.org>
Reviewed-by: Karan Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548891}
void CheckRestrictedUrls(const Extension* extension,
                         bool block_chrome_urls) {
  const std::string& name = extension->name();
  const GURL chrome_settings_url("chrome://settings/");
  const GURL chrome_extension_url("chrome-extension://foo/bar.html");
  const GURL google_url("https://www.google.com/");
  const GURL self_url("chrome-extension://" + extension->id() + "/foo.html");
  const GURL invalid_url("chrome-debugger://foo/bar.html");

  std::string error;
  EXPECT_EQ(block_chrome_urls,
            PermissionsData::IsRestrictedUrl(
                chrome_settings_url,
                extension,
                &error)) << name;
  if (block_chrome_urls)
    EXPECT_EQ(manifest_errors::kCannotAccessChromeUrl, error) << name;
  else
    EXPECT_TRUE(error.empty()) << name;

  error.clear();
  EXPECT_EQ(block_chrome_urls,
            PermissionsData::IsRestrictedUrl(
                chrome_extension_url,
                extension,
                &error)) << name;
  if (block_chrome_urls)
    EXPECT_EQ(manifest_errors::kCannotAccessExtensionUrl, error) << name;
  else
    EXPECT_TRUE(error.empty()) << name;

  error.clear();
  EXPECT_FALSE(PermissionsData::IsRestrictedUrl(
      google_url, extension, &error)) << name;
  EXPECT_TRUE(error.empty()) << name;

  error.clear();
  EXPECT_FALSE(PermissionsData::IsRestrictedUrl(
      self_url, extension, &error)) << name;
  EXPECT_TRUE(error.empty()) << name;

  error.clear();
  bool allow_on_other_schemes =
      PermissionsData::CanExecuteScriptEverywhere(extension);
  EXPECT_EQ(!allow_on_other_schemes,
            PermissionsData::IsRestrictedUrl(
                invalid_url, extension, &error)) << name;
  if (!allow_on_other_schemes) {
    EXPECT_EQ(ErrorUtils::FormatErrorMessage(
                  manifest_errors::kCannotAccessPage,
                  invalid_url.spec()),
              error) << name;
  } else {
    EXPECT_TRUE(error.empty());
  }
}

void CheckRestrictedUrls(const Extension* extension,
                         bool block_chrome_urls) {
  const std::string& name = extension->name();
  const GURL chrome_settings_url("chrome://settings/");
  const GURL chrome_extension_url("chrome-extension://foo/bar.html");
  const GURL google_url("https://www.google.com/");
  const GURL self_url("chrome-extension://" + extension->id() + "/foo.html");
  const GURL invalid_url("chrome-debugger://foo/bar.html");

  std::string error;
  EXPECT_EQ(block_chrome_urls,
            PermissionsData::IsRestrictedUrl(
                chrome_settings_url,
                extension,
                &error)) << name;
  if (block_chrome_urls)
    EXPECT_EQ(manifest_errors::kCannotAccessChromeUrl, error) << name;
  else
    EXPECT_TRUE(error.empty()) << name;

  error.clear();
  EXPECT_EQ(block_chrome_urls,
            PermissionsData::IsRestrictedUrl(
                chrome_extension_url,
                extension,
                &error)) << name;
  if (block_chrome_urls)
    EXPECT_EQ(manifest_errors::kCannotAccessExtensionUrl, error) << name;
  else
    EXPECT_TRUE(error.empty()) << name;

  error.clear();
  EXPECT_FALSE(PermissionsData::IsRestrictedUrl(
      google_url, extension, &error)) << name;
  EXPECT_TRUE(error.empty()) << name;

  error.clear();
  EXPECT_FALSE(PermissionsData::IsRestrictedUrl(
      self_url, extension, &error)) << name;
  EXPECT_TRUE(error.empty()) << name;

  error.clear();
  bool allow_on_other_schemes =
      PermissionsData::CanExecuteScriptEverywhere(extension);
  EXPECT_EQ(!allow_on_other_schemes,
            PermissionsData::IsRestrictedUrl(
                invalid_url, extension, &error)) << name;
  if (!allow_on_other_schemes) {
    EXPECT_EQ(ErrorUtils::FormatErrorMessage(
                  manifest_errors::kCannotAccessPage,
                  invalid_url.spec()),
              error) << name;
  } else {
    EXPECT_TRUE(error.empty());
  }
}
