// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "base/command_line.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/extensions/extension_test_util.h"
#include "chrome/common/extensions/features/feature_channel.h"
#include "content/public/common/socket_permission_request.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/id_util.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/permissions/socket_permission.h"
#include "extensions/common/switches.h"
#include "extensions/common/url_pattern_set.h"
#include "extensions/common/value_builder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using base::UTF16ToUTF8;
using content::SocketPermissionRequest;
using extension_test_util::LoadManifest;
using extension_test_util::LoadManifestUnchecked;
using extension_test_util::LoadManifestStrict;

namespace extensions {

namespace {

const char kAllHostsPermission[] = "*://*/*";

bool CheckSocketPermission(
    scoped_refptr<Extension> extension,
    SocketPermissionRequest::OperationType type,
    const char* host,
    int port) {
  SocketPermission::CheckParam param(type, host, port);
  return extension->permissions_data()->CheckAPIPermissionWithParam(
      APIPermission::kSocket, &param);
}

// Creates and returns an extension with the given |id|, |host_permissions|, and
// manifest |location|.
scoped_refptr<const Extension> GetExtensionWithHostPermission(
    const std::string& id,
    const std::string& host_permissions,
    Manifest::Location location) {
  ListBuilder permissions;
  if (!host_permissions.empty())
    permissions.Append(host_permissions);

  return ExtensionBuilder()
      .SetManifest(
          DictionaryBuilder()
              .Set("name", id)
              .Set("description", "an extension")
              .Set("manifest_version", 2)
              .Set("version", "1.0.0")
              .Set("permissions", permissions.Pass())
              .Build())
      .SetLocation(location)
      .SetID(id)
      .Build();
}

bool RequiresActionForScriptExecution(const std::string& extension_id,
                                      const std::string& host_permissions,
                                      Manifest::Location location) {
  scoped_refptr<const Extension> extension =
      GetExtensionWithHostPermission(extension_id,
                                     host_permissions,
                                     location);
  return extension->permissions_data()->RequiresActionForScriptExecution(
      extension,
      -1,  // Ignore tab id for these.
      GURL::EmptyGURL());
}

// Checks that urls are properly restricted for the given extension.
void CheckRestrictedUrls(const Extension* extension,
                         bool block_chrome_urls) {
  // We log the name so we know _which_ extension failed here.
  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,
                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,
                chrome_extension_url,
                extension,
                &error)) << name;
  if (block_chrome_urls)
    EXPECT_EQ(manifest_errors::kCannotAccessExtensionUrl, error) << name;
  else
    EXPECT_TRUE(error.empty()) << name;

  // Google should never be a restricted url.
  error.clear();
  EXPECT_FALSE(PermissionsData::IsRestrictedUrl(
      google_url, google_url, extension, &error)) << name;
  EXPECT_TRUE(error.empty()) << name;

  // We should always be able to access our own extension pages.
  error.clear();
  EXPECT_FALSE(PermissionsData::IsRestrictedUrl(
      self_url, self_url, extension, &error)) << name;
  EXPECT_TRUE(error.empty()) << name;

  // We should only allow other schemes for extensions when it's a whitelisted
  // extension.
  error.clear();
  bool allow_on_other_schemes =
      PermissionsData::CanExecuteScriptEverywhere(extension);
  EXPECT_EQ(!allow_on_other_schemes,
            PermissionsData::IsRestrictedUrl(
                invalid_url, 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());
  }
}

}  // namespace

TEST(ExtensionPermissionsTest, EffectiveHostPermissions) {
  scoped_refptr<Extension> extension;
  URLPatternSet hosts;

  extension = LoadManifest("effective_host_permissions", "empty.json");
  EXPECT_EQ(0u,
            extension->permissions_data()
                ->GetEffectiveHostPermissions()
                .patterns()
                .size());
  EXPECT_FALSE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "one_host.json");
  hosts = extension->permissions_data()->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_FALSE(hosts.MatchesURL(GURL("https://www.google.com")));
  EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions",
                           "one_host_wildcard.json");
  hosts = extension->permissions_data()->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://foo.google.com")));
  EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "two_hosts.json");
  hosts = extension->permissions_data()->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
  EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions",
                           "https_not_considered.json");
  hosts = extension->permissions_data()->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("https://google.com")));
  EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions",
                           "two_content_scripts.json");
  hosts = extension->permissions_data()->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
  EXPECT_TRUE(extension->permissions_data()
                  ->active_permissions()
                  ->HasEffectiveAccessToURL(GURL("http://www.reddit.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://news.ycombinator.com")));
  EXPECT_TRUE(
      extension->permissions_data()
          ->active_permissions()
          ->HasEffectiveAccessToURL(GURL("http://news.ycombinator.com")));
  EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "all_hosts.json");
  hosts = extension->permissions_data()->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
  EXPECT_FALSE(hosts.MatchesURL(GURL("https://test/")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
  hosts = extension->permissions_data()->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
  hosts = extension->permissions_data()->GetEffectiveHostPermissions();
  EXPECT_FALSE(hosts.MatchesURL(GURL("http://test/")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("https://test/")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
}

TEST(ExtensionPermissionsTest, SocketPermissions) {
  // Set feature current channel to appropriate value.
  ScopedCurrentChannel scoped_channel(chrome::VersionInfo::CHANNEL_DEV);
  scoped_refptr<Extension> extension;
  std::string error;

  extension = LoadManifest("socket_permissions", "empty.json");
  EXPECT_FALSE(CheckSocketPermission(extension,
      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));

  extension = LoadManifestUnchecked("socket_permissions",
                                    "socket1.json",
                                    Manifest::INTERNAL, Extension::NO_FLAGS,
                                    &error);
  EXPECT_TRUE(extension.get() == NULL);
  std::string expected_error_msg_header = ErrorUtils::FormatErrorMessage(
      manifest_errors::kInvalidPermissionWithDetail,
      "socket",
      "NULL or empty permission list");
  EXPECT_EQ(expected_error_msg_header, error);

  extension = LoadManifest("socket_permissions", "socket2.json");
  EXPECT_TRUE(CheckSocketPermission(extension,
      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
  EXPECT_FALSE(CheckSocketPermission(
        extension, SocketPermissionRequest::UDP_BIND, "", 80));
  EXPECT_TRUE(CheckSocketPermission(
        extension, SocketPermissionRequest::UDP_BIND, "", 8888));

  EXPECT_FALSE(CheckSocketPermission(
        extension, SocketPermissionRequest::UDP_SEND_TO, "example.com", 1900));
  EXPECT_TRUE(CheckSocketPermission(
        extension,
        SocketPermissionRequest::UDP_SEND_TO,
        "239.255.255.250", 1900));
}

TEST(ExtensionPermissionsTest, RequiresActionForScriptExecution) {
  // Extensions with all_hosts should require action.
  EXPECT_TRUE(RequiresActionForScriptExecution(
      "all_hosts_permissions", kAllHostsPermission, Manifest::INTERNAL));
  // Extensions with nearly all hosts are treated the same way.
  EXPECT_TRUE(RequiresActionForScriptExecution(
      "pseudo_all_hosts_permissions", "*://*.com/*", Manifest::INTERNAL));
  // Extensions with explicit permissions shouldn't require action.
  EXPECT_FALSE(RequiresActionForScriptExecution(
      "explicit_permissions", "https://www.google.com/*", Manifest::INTERNAL));
  // Policy extensions are exempt...
  EXPECT_FALSE(RequiresActionForScriptExecution(
      "policy", kAllHostsPermission, Manifest::EXTERNAL_POLICY));
  // ... as are component extensions.
  EXPECT_FALSE(RequiresActionForScriptExecution(
      "component", kAllHostsPermission, Manifest::COMPONENT));
  // Throw in an external pref extension to make sure that it's not just working
  // for everything non-internal.
  EXPECT_TRUE(RequiresActionForScriptExecution(
      "external_pref", kAllHostsPermission, Manifest::EXTERNAL_PREF));

  // If we grant an extension tab permissions, then it should no longer require
  // action.
  scoped_refptr<const Extension> extension =
      GetExtensionWithHostPermission("all_hosts_permissions",
                                     kAllHostsPermission,
                                     Manifest::INTERNAL);
  URLPatternSet allowed_hosts;
  allowed_hosts.AddPattern(
      URLPattern(URLPattern::SCHEME_HTTPS, "https://www.google.com/*"));
  scoped_refptr<PermissionSet> tab_permissions(
      new PermissionSet(APIPermissionSet(),
                        ManifestPermissionSet(),
                        allowed_hosts,
                        URLPatternSet()));
  extension->permissions_data()->UpdateTabSpecificPermissions(0,
                                                              tab_permissions);
  EXPECT_FALSE(extension->permissions_data()->RequiresActionForScriptExecution(
      extension, 0, GURL("https://www.google.com/")));
}

TEST(ExtensionPermissionsTest, IsRestrictedUrl) {
  scoped_refptr<const Extension> extension =
      GetExtensionWithHostPermission("normal_extension",
                                     kAllHostsPermission,
                                     Manifest::INTERNAL);
  // Chrome urls should be blocked for normal extensions.
  CheckRestrictedUrls(extension, true);

  scoped_refptr<const Extension> component =
      GetExtensionWithHostPermission("component",
                                     kAllHostsPermission,
                                     Manifest::COMPONENT);
  // Chrome urls should be accessible by component extensions.
  CheckRestrictedUrls(component, false);

  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kExtensionsOnChromeURLs);
  // Enabling the switch should allow all extensions to access chrome urls.
  CheckRestrictedUrls(extension, false);

}

TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyAPIPermissions) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("permissions", "many-apis.json");
  std::vector<base::string16> warnings =
      extension->permissions_data()->GetPermissionMessageStrings();
  // Warning for "tabs" is suppressed by "history" permission.
  ASSERT_EQ(5u, warnings.size());
  EXPECT_EQ("Read and modify your data on api.flickr.com",
            UTF16ToUTF8(warnings[0]));
  EXPECT_EQ("Read and modify your bookmarks", UTF16ToUTF8(warnings[1]));
  EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[2]));
  EXPECT_EQ("Read and modify your browsing history", UTF16ToUTF8(warnings[3]));
  EXPECT_EQ("Manage your apps, extensions, and themes",
            UTF16ToUTF8(warnings[4]));
}

TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHostsPermissions) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("permissions", "more-than-3-hosts.json");
  std::vector<base::string16> warnings =
      extension->permissions_data()->GetPermissionMessageStrings();
  std::vector<base::string16> warnings_details =
      extension->permissions_data()->GetPermissionMessageDetailsStrings();
  ASSERT_EQ(1u, warnings.size());
  ASSERT_EQ(1u, warnings_details.size());
  EXPECT_EQ("Read and modify your data on 5 websites",
            UTF16ToUTF8(warnings[0]));
  EXPECT_EQ("- www.a.com\n- www.b.com\n- www.c.com\n- www.d.com\n- www.e.com",
            UTF16ToUTF8(warnings_details[0]));
}

TEST(ExtensionPermissionsTest, GetPermissionMessages_LocationApiPermission) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("permissions",
                           "location-api.json",
                           Manifest::COMPONENT,
                           Extension::NO_FLAGS);
  std::vector<base::string16> warnings =
      extension->permissions_data()->GetPermissionMessageStrings();
  ASSERT_EQ(1u, warnings.size());
  EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[0]));
}

TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHosts) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("permissions", "many-hosts.json");
  std::vector<base::string16> warnings =
      extension->permissions_data()->GetPermissionMessageStrings();
  ASSERT_EQ(1u, warnings.size());
  EXPECT_EQ(
      "Read and modify your data on encrypted.google.com and www.google.com",
      UTF16ToUTF8(warnings[0]));
}

TEST(ExtensionPermissionsTest, GetPermissionMessages_Plugins) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("permissions", "plugins.json");
  std::vector<base::string16> warnings =
      extension->permissions_data()->GetPermissionMessageStrings();
// We don't parse the plugins key on Chrome OS, so it should not ask for any
// permissions.
#if defined(OS_CHROMEOS)
  ASSERT_EQ(0u, warnings.size());
#else
  ASSERT_EQ(1u, warnings.size());
  EXPECT_EQ(
      "Read and modify all your data on your computer and the websites you "
      "visit",
      UTF16ToUTF8(warnings[0]));
#endif
}

// Base class for testing the CanAccessPage and CanCaptureVisiblePage
// methods of Extension for extensions with various permissions.
class ExtensionScriptAndCaptureVisibleTest : public testing::Test {
 protected:
  ExtensionScriptAndCaptureVisibleTest()
      : http_url("http://www.google.com"),
        http_url_with_path("http://www.google.com/index.html"),
        https_url("https://www.google.com"),
        file_url("file:///foo/bar"),
        favicon_url("chrome://favicon/http://www.google.com"),
        extension_url("chrome-extension://" +
            id_util::GenerateIdForPath(
                base::FilePath(FILE_PATH_LITERAL("foo")))),
        settings_url("chrome://settings"),
        about_url("about:flags") {
    urls_.insert(http_url);
    urls_.insert(http_url_with_path);
    urls_.insert(https_url);
    urls_.insert(file_url);
    urls_.insert(favicon_url);
    urls_.insert(extension_url);
    urls_.insert(settings_url);
    urls_.insert(about_url);
    // Ignore the policy delegate for this test.
    PermissionsData::SetPolicyDelegate(NULL);
  }

  bool AllowedScript(const Extension* extension, const GURL& url,
                     const GURL& top_url) {
    return AllowedScript(extension, url, top_url, -1);
  }

  bool AllowedScript(const Extension* extension, const GURL& url,
                     const GURL& top_url, int tab_id) {
    return extension->permissions_data()->CanAccessPage(
        extension, url, top_url, tab_id, -1, NULL);
  }

  bool BlockedScript(const Extension* extension, const GURL& url,
                     const GURL& top_url) {
    return !extension->permissions_data()->CanAccessPage(
        extension, url, top_url, -1, -1, NULL);
  }

  bool Allowed(const Extension* extension, const GURL& url) {
    return Allowed(extension, url, -1);
  }

  bool Allowed(const Extension* extension, const GURL& url, int tab_id) {
    return (extension->permissions_data()->CanAccessPage(
                extension, url, url, tab_id, -1, NULL) &&
            extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL));
  }

  bool CaptureOnly(const Extension* extension, const GURL& url) {
    return CaptureOnly(extension, url, -1);
  }

  bool CaptureOnly(const Extension* extension, const GURL& url, int tab_id) {
    return !extension->permissions_data()->CanAccessPage(
               extension, url, url, tab_id, -1, NULL) &&
           extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL);
  }

  bool ScriptOnly(const Extension* extension, const GURL& url,
                  const GURL& top_url) {
    return ScriptOnly(extension, url, top_url, -1);
  }

  bool ScriptOnly(const Extension* extension, const GURL& url,
                  const GURL& top_url, int tab_id) {
    return AllowedScript(extension, url, top_url, tab_id) &&
           !extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL);
  }

  bool Blocked(const Extension* extension, const GURL& url) {
    return Blocked(extension, url, -1);
  }

  bool Blocked(const Extension* extension, const GURL& url, int tab_id) {
    return !(extension->permissions_data()->CanAccessPage(
                 extension, url, url, tab_id, -1, NULL) ||
             extension->permissions_data()->CanCaptureVisiblePage(tab_id,
                                                                  NULL));
  }

  bool ScriptAllowedExclusivelyOnTab(
      const Extension* extension,
      const std::set<GURL>& allowed_urls,
      int tab_id) {
    bool result = true;
    for (std::set<GURL>::iterator it = urls_.begin(); it != urls_.end(); ++it) {
      const GURL& url = *it;
      if (allowed_urls.count(url))
        result &= AllowedScript(extension, url, url, tab_id);
      else
        result &= Blocked(extension, url, tab_id);
    }
    return result;
  }

  // URLs that are "safe" to provide scripting and capture visible tab access
  // to if the permissions allow it.
  const GURL http_url;
  const GURL http_url_with_path;
  const GURL https_url;
  const GURL file_url;

  // We should allow host permission but not scripting permission for favicon
  // urls.
  const GURL favicon_url;

  // URLs that regular extensions should never get access to.
  const GURL extension_url;
  const GURL settings_url;
  const GURL about_url;

 private:
  // The set of all URLs above.
  std::set<GURL> urls_;
};

TEST_F(ExtensionScriptAndCaptureVisibleTest, Permissions) {
  // Test <all_urls> for regular extensions.
  scoped_refptr<Extension> extension = LoadManifestStrict("script_and_capture",
      "extension_regular_all.json");

  EXPECT_TRUE(Allowed(extension.get(), http_url));
  EXPECT_TRUE(Allowed(extension.get(), https_url));
  EXPECT_TRUE(CaptureOnly(extension.get(), file_url));
  EXPECT_TRUE(CaptureOnly(extension.get(), settings_url));
  EXPECT_TRUE(CaptureOnly(extension.get(), favicon_url));
  EXPECT_TRUE(CaptureOnly(extension.get(), about_url));
  EXPECT_TRUE(CaptureOnly(extension.get(), extension_url));

  // Test access to iframed content.
  GURL within_extension_url = extension->GetResourceURL("page.html");
  EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path));
  EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path));
  EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url));
  EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url));
  EXPECT_TRUE(BlockedScript(extension.get(), http_url, extension_url));
  EXPECT_TRUE(BlockedScript(extension.get(), https_url, extension_url));

  EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url));
  EXPECT_FALSE(extension->permissions_data()->HasHostPermission(about_url));
  EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));

  // Test * for scheme, which implies just the http/https schemes.
  extension = LoadManifestStrict("script_and_capture",
      "extension_wildcard.json");
  EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url));
  EXPECT_TRUE(ScriptOnly(extension.get(), https_url, https_url));
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(Blocked(extension.get(), about_url));
  EXPECT_TRUE(Blocked(extension.get(), file_url));
  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
  extension =
      LoadManifest("script_and_capture", "extension_wildcard_settings.json");
  EXPECT_TRUE(Blocked(extension.get(), settings_url));

  // Having chrome://*/ should not work for regular extensions. Note that
  // for favicon access, we require the explicit pattern chrome://favicon/*.
  std::string error;
  extension = LoadManifestUnchecked("script_and_capture",
                                    "extension_wildcard_chrome.json",
                                    Manifest::INTERNAL, Extension::NO_FLAGS,
                                    &error);
  std::vector<InstallWarning> warnings = extension->install_warnings();
  EXPECT_FALSE(warnings.empty());
  EXPECT_EQ(ErrorUtils::FormatErrorMessage(
                manifest_errors::kInvalidPermissionScheme,
                "chrome://*/"),
            warnings[0].message);
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
  EXPECT_TRUE(Blocked(extension.get(), about_url));

  // Having chrome://favicon/* should not give you chrome://*
  extension = LoadManifestStrict("script_and_capture",
      "extension_chrome_favicon_wildcard.json");
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
  EXPECT_TRUE(Blocked(extension.get(), about_url));
  EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));

  // Having http://favicon should not give you chrome://favicon
  extension = LoadManifestStrict("script_and_capture",
      "extension_http_favicon.json");
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(Blocked(extension.get(), favicon_url));

  // Component extensions with <all_urls> should get everything.
  extension = LoadManifest("script_and_capture", "extension_component_all.json",
      Manifest::COMPONENT, Extension::NO_FLAGS);
  EXPECT_TRUE(Allowed(extension.get(), http_url));
  EXPECT_TRUE(Allowed(extension.get(), https_url));
  EXPECT_TRUE(Allowed(extension.get(), settings_url));
  EXPECT_TRUE(Allowed(extension.get(), about_url));
  EXPECT_TRUE(Allowed(extension.get(), favicon_url));
  EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));

  // Component extensions should only get access to what they ask for.
  extension = LoadManifest("script_and_capture",
      "extension_component_google.json", Manifest::COMPONENT,
      Extension::NO_FLAGS);
  EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url));
  EXPECT_TRUE(Blocked(extension.get(), https_url));
  EXPECT_TRUE(Blocked(extension.get(), file_url));
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
  EXPECT_TRUE(Blocked(extension.get(), about_url));
  EXPECT_TRUE(Blocked(extension.get(), extension_url));
  EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url));
}

TEST_F(ExtensionScriptAndCaptureVisibleTest, PermissionsWithChromeURLsEnabled) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kExtensionsOnChromeURLs);

  scoped_refptr<Extension> extension;

  // Test <all_urls> for regular extensions.
  extension = LoadManifestStrict("script_and_capture",
      "extension_regular_all.json");
  EXPECT_TRUE(Allowed(extension.get(), http_url));
  EXPECT_TRUE(Allowed(extension.get(), https_url));
  EXPECT_TRUE(CaptureOnly(extension.get(), file_url));
  EXPECT_TRUE(CaptureOnly(extension.get(), settings_url));
  EXPECT_TRUE(Allowed(extension.get(), favicon_url));  // chrome:// requested
  EXPECT_TRUE(CaptureOnly(extension.get(), about_url));
  EXPECT_TRUE(CaptureOnly(extension.get(), extension_url));

  // Test access to iframed content.
  GURL within_extension_url = extension->GetResourceURL("page.html");
  EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path));
  EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path));
  EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url));
  EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url));
  EXPECT_TRUE(AllowedScript(extension.get(), http_url, extension_url));
  EXPECT_TRUE(AllowedScript(extension.get(), https_url, extension_url));

  const PermissionsData* permissions_data = extension->permissions_data();
  EXPECT_FALSE(permissions_data->HasHostPermission(settings_url));
  EXPECT_FALSE(permissions_data->HasHostPermission(about_url));
  EXPECT_TRUE(permissions_data->HasHostPermission(favicon_url));

  // Test * for scheme, which implies just the http/https schemes.
  extension = LoadManifestStrict("script_and_capture",
      "extension_wildcard.json");
  EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url));
  EXPECT_TRUE(ScriptOnly(extension.get(), https_url, https_url));
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(Blocked(extension.get(), about_url));
  EXPECT_TRUE(Blocked(extension.get(), file_url));
  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
  extension =
      LoadManifest("script_and_capture", "extension_wildcard_settings.json");
  EXPECT_TRUE(Blocked(extension.get(), settings_url));

  // Having chrome://*/ should work for regular extensions with the flag
  // enabled.
  std::string error;
  extension = LoadManifestUnchecked("script_and_capture",
                                    "extension_wildcard_chrome.json",
                                    Manifest::INTERNAL, Extension::NO_FLAGS,
                                    &error);
  EXPECT_FALSE(extension.get() == NULL);
  EXPECT_TRUE(Blocked(extension.get(), http_url));
  EXPECT_TRUE(Blocked(extension.get(), https_url));
  EXPECT_TRUE(ScriptOnly(extension.get(), settings_url, settings_url));
  EXPECT_TRUE(Blocked(extension.get(), about_url));
  EXPECT_TRUE(Blocked(extension.get(), file_url));
  EXPECT_TRUE(ScriptOnly(extension.get(), favicon_url, favicon_url));

  // Having chrome://favicon/* should not give you chrome://*
  extension = LoadManifestStrict("script_and_capture",
      "extension_chrome_favicon_wildcard.json");
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(ScriptOnly(extension.get(), favicon_url, favicon_url));
  EXPECT_TRUE(Blocked(extension.get(), about_url));
  EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));

  // Having http://favicon should not give you chrome://favicon
  extension = LoadManifestStrict("script_and_capture",
      "extension_http_favicon.json");
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(Blocked(extension.get(), favicon_url));

  // Component extensions with <all_urls> should get everything.
  extension = LoadManifest("script_and_capture", "extension_component_all.json",
      Manifest::COMPONENT, Extension::NO_FLAGS);
  EXPECT_TRUE(Allowed(extension.get(), http_url));
  EXPECT_TRUE(Allowed(extension.get(), https_url));
  EXPECT_TRUE(Allowed(extension.get(), settings_url));
  EXPECT_TRUE(Allowed(extension.get(), about_url));
  EXPECT_TRUE(Allowed(extension.get(), favicon_url));
  EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));

  // Component extensions should only get access to what they ask for.
  extension = LoadManifest("script_and_capture",
      "extension_component_google.json", Manifest::COMPONENT,
      Extension::NO_FLAGS);
  EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url));
  EXPECT_TRUE(Blocked(extension.get(), https_url));
  EXPECT_TRUE(Blocked(extension.get(), file_url));
  EXPECT_TRUE(Blocked(extension.get(), settings_url));
  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
  EXPECT_TRUE(Blocked(extension.get(), about_url));
  EXPECT_TRUE(Blocked(extension.get(), extension_url));
  EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url));
}

TEST_F(ExtensionScriptAndCaptureVisibleTest, TabSpecific) {
  scoped_refptr<Extension> extension =
      LoadManifestStrict("script_and_capture", "tab_specific.json");

  const PermissionsData* permissions_data = extension->permissions_data();
  EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0));
  EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(1));
  EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(2));

  std::set<GURL> no_urls;

  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));

  URLPatternSet allowed_hosts;
  allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
                                      http_url.spec()));
  std::set<GURL> allowed_urls;
  allowed_urls.insert(http_url);
  // http_url_with_path() will also be allowed, because Extension should be
  // considering the security origin of the URL not the URL itself, and
  // http_url is in allowed_hosts.
  allowed_urls.insert(http_url_with_path);

  {
    scoped_refptr<PermissionSet> permissions(
        new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
                          allowed_hosts, URLPatternSet()));
    permissions_data->UpdateTabSpecificPermissions(0, permissions);
    EXPECT_EQ(permissions->explicit_hosts(),
              permissions_data->GetTabSpecificPermissionsForTesting(0)
                  ->explicit_hosts());
  }

  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), allowed_urls, 0));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));

  permissions_data->ClearTabSpecificPermissions(0);
  EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0));

  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));

  std::set<GURL> more_allowed_urls = allowed_urls;
  more_allowed_urls.insert(https_url);
  URLPatternSet more_allowed_hosts = allowed_hosts;
  more_allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
                                           https_url.spec()));

  {
    scoped_refptr<PermissionSet> permissions(
        new PermissionSet(APIPermissionSet(),  ManifestPermissionSet(),
                          allowed_hosts, URLPatternSet()));
    permissions_data->UpdateTabSpecificPermissions(0, permissions);
    EXPECT_EQ(permissions->explicit_hosts(),
              permissions_data->GetTabSpecificPermissionsForTesting(0)
                  ->explicit_hosts());

    permissions = new PermissionSet(APIPermissionSet(),
                                    ManifestPermissionSet(),
                                    more_allowed_hosts,
                                    URLPatternSet());
    permissions_data->UpdateTabSpecificPermissions(1, permissions);
    EXPECT_EQ(permissions->explicit_hosts(),
              permissions_data->GetTabSpecificPermissionsForTesting(1)
                  ->explicit_hosts());
  }

  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), allowed_urls, 0));
  EXPECT_TRUE(
      ScriptAllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));

  permissions_data->ClearTabSpecificPermissions(0);
  EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0));

  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0));
  EXPECT_TRUE(
      ScriptAllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));

  permissions_data->ClearTabSpecificPermissions(1);
  EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(1));

  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1));
  EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));
}

}  // namespace extensions
