// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <utility>

#include "base/functional/callback_helpers.h"
#include "base/strings/stringprintf.h"
#include "base/test/values_test_util.h"
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_with_install.h"
#include "chrome/browser/extensions/permissions_test_util.h"
#include "chrome/browser/extensions/permissions_updater.h"
#include "chrome/browser/extensions/scripting_permissions_modifier.h"
#include "chrome/test/base/testing_profile.h"
#include "components/crx_file/id_util.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_util.h"
#include "extensions/browser/permissions_manager.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/manifest_handlers/permissions_parser.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/url_pattern.h"
#include "extensions/common/url_pattern_set.h"
#include "extensions/common/user_script.h"
#include "extensions/test/test_extension_dir.h"
#include "testing/gmock/include/gmock/gmock.h"

using extensions::mojom::ManifestLocation;

namespace extensions {

namespace {

using permissions_test_util::GetPatternsAsStrings;

std::vector<std::string> GetEffectivePatternsAsStrings(
    const Extension& extension) {
  return GetPatternsAsStrings(
      extension.permissions_data()->active_permissions().effective_hosts());
}

std::vector<std::string> GetScriptablePatternsAsStrings(
    const Extension& extension) {
  return GetPatternsAsStrings(
      extension.permissions_data()->active_permissions().scriptable_hosts());
}

std::vector<std::string> GetExplicitPatternsAsStrings(
    const Extension& extension) {
  return GetPatternsAsStrings(
      extension.permissions_data()->active_permissions().explicit_hosts());
}

void InitializeExtensionPermissions(Profile* profile,
                                    const Extension& extension) {
  PermissionsUpdater updater(profile);
  updater.InitializePermissions(&extension);
  updater.GrantActivePermissions(&extension);
}

void CheckActiveHostPermissions(
    const Extension& extension,
    const std::vector<std::string>& explicit_hosts,
    const std::vector<std::string>& scriptable_hosts) {
  EXPECT_THAT(GetExplicitPatternsAsStrings(extension),
              testing::UnorderedElementsAreArray(explicit_hosts));
  EXPECT_THAT(GetScriptablePatternsAsStrings(extension),
              testing::UnorderedElementsAreArray(scriptable_hosts));
}

void CheckWithheldHostPermissions(
    const Extension& extension,
    const std::vector<std::string>& explicit_hosts,
    const std::vector<std::string>& scriptable_hosts) {
  const PermissionsData* permissions_data = extension.permissions_data();
  EXPECT_THAT(GetPatternsAsStrings(
                  permissions_data->withheld_permissions().explicit_hosts()),
              testing::UnorderedElementsAreArray(explicit_hosts));
  EXPECT_THAT(GetPatternsAsStrings(
                  permissions_data->withheld_permissions().scriptable_hosts()),
              testing::UnorderedElementsAreArray(scriptable_hosts));
}

using ScriptingPermissionsModifierUnitTest = ExtensionServiceTestWithInstall;

}  // namespace

TEST_F(ScriptingPermissionsModifierUnitTest, GrantAndWithholdHostPermissions) {
  InitializeEmptyExtensionService();

  std::vector<std::string> test_cases[] = {
      {"http://www.google.com/*"},
      {"http://*/*"},
      {"<all_urls>"},
      {"http://*.com/*"},
      {"http://google.com/*", "<all_urls>"},
  };

  for (const auto& test_case : test_cases) {
    std::string test_case_name = base::JoinString(test_case, ",");
    SCOPED_TRACE(test_case_name);
    scoped_refptr<const Extension> extension =
        ExtensionBuilder(test_case_name)
            .AddPermissions(test_case)
            .AddContentScript("foo.js", test_case)
            .SetLocation(ManifestLocation::kInternal)
            .Build();

    PermissionsUpdater(profile()).InitializePermissions(extension.get());
    ASSERT_TRUE(
        PermissionsManager::Get(profile())->CanAffectExtension(*extension));

    // By default, all permissions are granted.
    {
      SCOPED_TRACE("Initial state");
      CheckActiveHostPermissions(*extension, test_case, test_case);
      CheckWithheldHostPermissions(*extension, {}, {});
    }

    // Then, withhold host permissions.
    ScriptingPermissionsModifier modifier(profile(), extension);
    modifier.SetWithholdHostPermissions(true);
    {
      SCOPED_TRACE("After setting to withhold");
      CheckActiveHostPermissions(*extension, {}, {});
      CheckWithheldHostPermissions(*extension, test_case, test_case);
    }

    // Finally, re-grant the withheld permissions.
    modifier.SetWithholdHostPermissions(false);

    // We should be back to our initial state - all requested permissions are
    // granted.
    {
      SCOPED_TRACE("After setting to not withhold");
      CheckActiveHostPermissions(*extension, test_case, test_case);
      CheckWithheldHostPermissions(*extension, {}, {});
    }
  }
}

// Tests that with the creation flag present, requested host permissions are
// withheld on installation, but still allow for individual permissions to be
// granted, or all permissions be set back to not being withheld by default.
TEST_F(ScriptingPermissionsModifierUnitTest, WithholdHostPermissionsOnInstall) {
  InitializeEmptyExtensionService();

  constexpr char kHostGoogle[] = "https://google.com/*";
  constexpr char kHostChromium[] = "https://chromium.org/*";
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("a")
          .AddPermissions({kHostGoogle, kHostChromium})
          .AddContentScript("foo.js", {kHostGoogle})
          .SetLocation(ManifestLocation::kInternal)
          .AddFlags(Extension::WITHHOLD_PERMISSIONS)
          .Build();

  // Initialize the permissions and have the prefs built and stored.
  PermissionsUpdater(profile()).InitializePermissions(extension.get());
  ExtensionPrefs::Get(profile())->OnExtensionInstalled(
      extension.get(), Extension::State::ENABLED, syncer::StringOrdinal(), "");

  ASSERT_TRUE(
      PermissionsManager::Get(profile())->CanAffectExtension(*extension));

  // With the flag present, permissions should have been withheld.
  {
    SCOPED_TRACE("Initial state");
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium},
                                 {kHostGoogle});
  }

  // Grant one of the permissions manually.
  ScriptingPermissionsModifier modifier(profile(), extension);
  modifier.GrantHostPermission(GURL(kHostChromium));

  {
    SCOPED_TRACE("After granting single");
    CheckActiveHostPermissions(*extension, {kHostChromium}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle}, {kHostGoogle});
  }

  // Finally, re-grant the withheld permissions.
  modifier.SetWithholdHostPermissions(false);

  // All requested permissions should now be granted granted.
  {
    SCOPED_TRACE("After setting to not withhold");
    CheckActiveHostPermissions(*extension, {kHostGoogle, kHostChromium},
                               {kHostGoogle});
    CheckWithheldHostPermissions(*extension, {}, {});
  }
}

// Tests that reloading an extension after withholding host permissions on
// installation retains the correct state and any changes that have been made
// since installation.
TEST_F(ScriptingPermissionsModifierUnitTest,
       WithholdOnInstallPreservedOnReload) {
  InitializeEmptyExtensionService();

  constexpr char kHostGoogle[] = "https://google.com/*";
  constexpr char kHostChromium[] = "https://chromium.org/*";
  TestExtensionDir test_extension_dir;
  test_extension_dir.WriteManifest(
      R"({
           "name": "foo",
           "manifest_version": 2,
           "version": "1",
           "permissions": ["https://google.com/*", "https://chromium.org/*"]
         })");
  ChromeTestExtensionLoader loader(profile());
  loader.add_creation_flag(Extension::WITHHOLD_PERMISSIONS);
  loader.set_pack_extension(true);
  scoped_refptr<const Extension> extension =
      loader.LoadExtension(test_extension_dir.UnpackedPath());
  // Cache the ID, since the extension will be invalidated across reloads.
  ExtensionId extension_id = extension->id();

  auto reload_extension = [this, &extension_id]() {
    TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile()));
    service()->ReloadExtension(extension_id);
    return observer.WaitForExtensionLoaded();
  };

  // Permissions start withheld due to creation flag and remain withheld after
  // reload.
  {
    SCOPED_TRACE("Initial state");
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
  }

  {
    SCOPED_TRACE("Reload after initial state");
    extension = reload_extension();
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
  }

  // Grant one of the permissions and check it persists after reload.
  ScriptingPermissionsModifier(profile(), extension)
      .GrantHostPermission(GURL(kHostGoogle));
  {
    SCOPED_TRACE("Granting single");
    CheckActiveHostPermissions(*extension, {kHostGoogle}, {});
    CheckWithheldHostPermissions(*extension, {kHostChromium}, {});
  }

  {
    SCOPED_TRACE("Reload after granting single");
    extension = reload_extension();
    CheckActiveHostPermissions(*extension, {kHostGoogle}, {});
    CheckWithheldHostPermissions(*extension, {kHostChromium}, {});
  }

  // Set permissions not to be withheld at all and check it persists after
  // reload.
  ScriptingPermissionsModifier(profile(), extension)
      .SetWithholdHostPermissions(false);
  {
    SCOPED_TRACE("Setting to not withhold");
    CheckActiveHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
    CheckWithheldHostPermissions(*extension, {}, {});
  }

  {
    SCOPED_TRACE("Reload after setting to not withhold");
    extension = reload_extension();
    CheckActiveHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
    CheckWithheldHostPermissions(*extension, {}, {});
  }

  // Finally, set permissions to be withheld again and check it persists after
  // reload.
  ScriptingPermissionsModifier(profile(), extension)
      .SetWithholdHostPermissions(true);
  {
    SCOPED_TRACE("Setting back to withhold");
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
  }

  {
    SCOPED_TRACE("Reload after setting back to withhold");
    extension = reload_extension();
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
  }
}

// Tests that updating an extension after withholding host permissions on
// installation retains the correct state and any changes that have been made
// since installation.
TEST_F(ScriptingPermissionsModifierUnitTest,
       WithholdOnInstallPreservedOnUpdate) {
  InitializeEmptyExtensionService();

  constexpr char kHostGoogle[] = "https://google.com/*";
  constexpr char kHostChromium[] = "https://chromium.org/*";
  TestExtensionDir test_extension_dir;
  constexpr char kManifestTemplate[] =
      R"({
           "name": "foo",
           "manifest_version": 2,
           "version": "%s",
           "permissions": ["https://google.com/*", "https://chromium.org/*"]
         })";

  test_extension_dir.WriteManifest(base::StringPrintf(kManifestTemplate, "1"));
  // We need to use a pem file here for consistent update IDs.
  const base::FilePath pem_path =
      data_dir().AppendASCII("permissions/update.pem");
  scoped_refptr<const Extension> extension = PackAndInstallCRX(
      test_extension_dir.UnpackedPath(), pem_path, INSTALL_NEW,
      Extension::WITHHOLD_PERMISSIONS, mojom::ManifestLocation::kInternal);
  // Cache the ID, since the extension will be invalidated across updates.
  ExtensionId extension_id = extension->id();
  // Hold onto references for the extension dirs so they don't get deleted
  // outside the lambda.
  std::vector<TestExtensionDir> extension_dirs;

  auto update_extension = [this, &extension_id, &pem_path, &kManifestTemplate,
                           &extension_dirs](const char* version) {
    TestExtensionDir update_version;
    update_version.WriteManifest(
        base::StringPrintf(kManifestTemplate, version));
    PackCRXAndUpdateExtension(extension_id, update_version.UnpackedPath(),
                              pem_path, ENABLED);
    scoped_refptr<const Extension> updated_extension =
        registry()->GetInstalledExtension(extension_id);

    EXPECT_EQ(version, updated_extension->version().GetString());
    extension_dirs.push_back(std::move(update_version));
    return updated_extension;
  };

  // Permissions start withheld due to creation flag and remain withheld after
  // update.
  {
    SCOPED_TRACE("Initial state");
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
  }

  {
    SCOPED_TRACE("Update after initial state");
    extension = update_extension("2");
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
  }

  // Grant one of the permissions and check it persists after update.
  ScriptingPermissionsModifier(profile(), extension)
      .GrantHostPermission(GURL(kHostGoogle));
  {
    SCOPED_TRACE("Granting single");
    CheckActiveHostPermissions(*extension, {kHostGoogle}, {});
    CheckWithheldHostPermissions(*extension, {kHostChromium}, {});
  }

  {
    SCOPED_TRACE("Update after granting single");
    extension = update_extension("3");
    CheckActiveHostPermissions(*extension, {kHostGoogle}, {});
    CheckWithheldHostPermissions(*extension, {kHostChromium}, {});
  }

  // Set permissions not to be withheld at all and check it persists after
  // update.
  ScriptingPermissionsModifier(profile(), extension)
      .SetWithholdHostPermissions(false);
  {
    SCOPED_TRACE("Setting to not withhold");
    CheckActiveHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
    CheckWithheldHostPermissions(*extension, {}, {});
  }

  {
    SCOPED_TRACE("Update after setting to not withhold");
    extension = update_extension("4");
    CheckActiveHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
    CheckWithheldHostPermissions(*extension, {}, {});
  }

  // Finally, set permissions to be withheld again and check it persists after
  // update.
  ScriptingPermissionsModifier(profile(), extension)
      .SetWithholdHostPermissions(true);
  {
    SCOPED_TRACE("Setting back to withhold");
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
  }

  {
    SCOPED_TRACE("Update after setting back to withhold");
    extension = update_extension("5");
    CheckActiveHostPermissions(*extension, {}, {});
    CheckWithheldHostPermissions(*extension, {kHostGoogle, kHostChromium}, {});
  }
}

TEST_F(ScriptingPermissionsModifierUnitTest, SwitchBehavior) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("a")
          .AddPermission(URLPattern::kAllUrlsPattern)
          .AddContentScript("foo.js", {URLPattern::kAllUrlsPattern})
          .SetLocation(ManifestLocation::kInternal)
          .Build();
  PermissionsUpdater updater(profile());
  updater.InitializePermissions(extension.get());
  const PermissionsData* permissions_data = extension->permissions_data();

  // By default, the extension should have all its permissions.
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension),
              testing::UnorderedElementsAre(URLPattern::kAllUrlsPattern));
  EXPECT_TRUE(
      permissions_data->withheld_permissions().effective_hosts().is_empty());
  PermissionsManager* permissions_manager = PermissionsManager::Get(profile());
  EXPECT_FALSE(permissions_manager->HasWithheldHostPermissions(*extension));

  // Revoke access.
  ScriptingPermissionsModifier modifier(profile(), extension);
  modifier.SetWithholdHostPermissions(true);
  EXPECT_TRUE(permissions_manager->HasWithheldHostPermissions(*extension));
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());
  EXPECT_THAT(GetPatternsAsStrings(
                  permissions_data->withheld_permissions().effective_hosts()),
              testing::UnorderedElementsAre(URLPattern::kAllUrlsPattern));
}

TEST_F(ScriptingPermissionsModifierUnitTest, GrantHostPermission) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension")
          .AddPermission(URLPattern::kAllUrlsPattern)
          .AddContentScript("foo.js", {URLPattern::kAllUrlsPattern})
          .SetLocation(ManifestLocation::kInternal)
          .Build();
  PermissionsUpdater(profile()).InitializePermissions(extension.get());

  ScriptingPermissionsModifier modifier(profile(), extension);
  modifier.SetWithholdHostPermissions(true);

  const GURL kUrl("https://www.google.com/");
  const GURL kUrl2("https://www.chromium.org/");

  PermissionsManager* permissions_manager = PermissionsManager::Get(profile());
  EXPECT_FALSE(permissions_manager->HasGrantedHostPermission(*extension, kUrl));
  EXPECT_FALSE(
      permissions_manager->HasGrantedHostPermission(*extension, kUrl2));

  const PermissionsData* permissions_data = extension->permissions_data();
  auto get_page_access = [&permissions_data](const GURL& url) {
    return permissions_data->GetPageAccess(url, 0, nullptr);
  };

  EXPECT_EQ(PermissionsData::PageAccess::kWithheld, get_page_access(kUrl));
  EXPECT_EQ(PermissionsData::PageAccess::kWithheld, get_page_access(kUrl2));

  ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
  {
    std::unique_ptr<const PermissionSet> permissions =
        prefs->GetRuntimeGrantedPermissions(extension->id());
    EXPECT_FALSE(permissions->effective_hosts().MatchesURL(kUrl));
    EXPECT_FALSE(permissions->effective_hosts().MatchesURL(kUrl2));
  }

  modifier.GrantHostPermission(kUrl);
  EXPECT_TRUE(permissions_manager->HasGrantedHostPermission(*extension, kUrl));
  EXPECT_FALSE(
      permissions_manager->HasGrantedHostPermission(*extension, kUrl2));
  EXPECT_EQ(PermissionsData::PageAccess::kAllowed, get_page_access(kUrl));
  EXPECT_EQ(PermissionsData::PageAccess::kWithheld, get_page_access(kUrl2));
  {
    std::unique_ptr<const PermissionSet> permissions =
        prefs->GetRuntimeGrantedPermissions(extension->id());
    EXPECT_TRUE(permissions->effective_hosts().MatchesURL(kUrl));
    EXPECT_FALSE(permissions->effective_hosts().MatchesURL(kUrl2));
  }

  modifier.RemoveGrantedHostPermission(kUrl);
  EXPECT_FALSE(permissions_manager->HasGrantedHostPermission(*extension, kUrl));
  EXPECT_FALSE(
      permissions_manager->HasGrantedHostPermission(*extension, kUrl2));
  EXPECT_EQ(PermissionsData::PageAccess::kWithheld, get_page_access(kUrl));
  EXPECT_EQ(PermissionsData::PageAccess::kWithheld, get_page_access(kUrl2));
  {
    std::unique_ptr<const PermissionSet> permissions =
        prefs->GetRuntimeGrantedPermissions(extension->id());
    EXPECT_FALSE(permissions->effective_hosts().MatchesURL(kUrl));
    EXPECT_FALSE(permissions->effective_hosts().MatchesURL(kUrl2));
  }
}

TEST_F(ScriptingPermissionsModifierUnitTest,
       ExtensionsInitializedWithSavedRuntimeGrantedHostPermissionsAcrossLoad) {
  InitializeEmptyExtensionService();

  const GURL kExampleCom("https://example.com/");
  const GURL kChromiumOrg("https://chromium.org/");
  const URLPatternSet kExampleComPatternSet({URLPattern(
      Extension::kValidHostPermissionSchemes, "https://example.com/")});

  TestExtensionDir test_extension_dir;
  test_extension_dir.WriteManifest(
      R"({
           "name": "foo",
           "manifest_version": 2,
           "version": "1",
           "permissions": ["<all_urls>"]
         })");
  ChromeTestExtensionLoader loader(profile());
  loader.set_grant_permissions(true);
  scoped_refptr<const Extension> extension =
      loader.LoadExtension(test_extension_dir.UnpackedPath());

  EXPECT_TRUE(extension->permissions_data()
                  ->active_permissions()
                  .explicit_hosts()
                  .MatchesURL(kExampleCom));
  EXPECT_TRUE(extension->permissions_data()
                  ->active_permissions()
                  .explicit_hosts()
                  .MatchesURL(kChromiumOrg));

  ScriptingPermissionsModifier(profile(), extension)
      .SetWithholdHostPermissions(true);
  EXPECT_FALSE(extension->permissions_data()
                   ->active_permissions()
                   .explicit_hosts()
                   .MatchesURL(kExampleCom));
  EXPECT_FALSE(extension->permissions_data()
                   ->active_permissions()
                   .explicit_hosts()
                   .MatchesURL(kChromiumOrg));

  ScriptingPermissionsModifier(profile(), extension)
      .GrantHostPermission(kExampleCom);
  EXPECT_TRUE(extension->permissions_data()
                  ->active_permissions()
                  .explicit_hosts()
                  .MatchesURL(kExampleCom));
  EXPECT_FALSE(extension->permissions_data()
                   ->active_permissions()
                   .explicit_hosts()
                   .MatchesURL(kChromiumOrg));

  {
    TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile()));
    service()->ReloadExtension(extension->id());
    extension = observer.WaitForExtensionLoaded();
  }
  EXPECT_TRUE(extension->permissions_data()
                  ->active_permissions()
                  .explicit_hosts()
                  .MatchesURL(kExampleCom));
  EXPECT_FALSE(extension->permissions_data()
                   ->active_permissions()
                   .explicit_hosts()
                   .MatchesURL(kChromiumOrg));
}

// Test ScriptingPermissionsModifier::RemoveAllGrantedHostPermissions() revokes
// hosts granted through the ScriptingPermissionsModifier.
TEST_F(ScriptingPermissionsModifierUnitTest,
       RemoveAllGrantedHostPermissions_GrantedHosts) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("test").AddPermission("<all_urls>").Build();
  ScriptingPermissionsModifier modifier(profile(), extension.get());

  modifier.SetWithholdHostPermissions(true);

  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());

  modifier.GrantHostPermission(GURL("https://example.com"));
  modifier.GrantHostPermission(GURL("https://chromium.org"));

  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension),
              testing::UnorderedElementsAre("https://example.com/*",
                                            "https://chromium.org/*"));

  modifier.RemoveAllGrantedHostPermissions();
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());
}

// Test ScriptingPermissionsModifier::RemoveAllGrantedHostPermissions() revokes
// hosts granted through the ScriptingPermissionsModifier for extensions that
// don't request <all_urls>.
TEST_F(ScriptingPermissionsModifierUnitTest,
       RemoveAllGrantedHostPermissions_GrantedHostsForNonAllUrlsExtension) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("test")
          .AddPermissions({"https://example.com/*", "https://chromium.org/*"})
          .Build();
  ScriptingPermissionsModifier modifier(profile(), extension.get());

  modifier.SetWithholdHostPermissions(true);

  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());

  modifier.GrantHostPermission(GURL("https://example.com"));
  modifier.GrantHostPermission(GURL("https://chromium.org"));

  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension),
              testing::UnorderedElementsAre("https://example.com/*",
                                            "https://chromium.org/*"));

  modifier.RemoveAllGrantedHostPermissions();
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());
}

// Test ScriptingPermissionsModifier::RemoveAllGrantedHostPermissions() revokes
// granted optional host permissions.
TEST_F(ScriptingPermissionsModifierUnitTest,
       RemoveAllGrantedHostPermissions_GrantedOptionalPermissions) {
  InitializeEmptyExtensionService();

  static constexpr char kOptionalPermissions[] = R"(["https://example.com/*"])";
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("test")
          .SetManifestKey("optional_permissions",
                          base::test::ParseJsonList(kOptionalPermissions))
          .Build();

  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());

  {
    // Simulate adding an optional permission, which should also be revokable.
    URLPatternSet patterns;
    patterns.AddPattern(URLPattern(Extension::kValidHostPermissionSchemes,
                                   "https://example.com/*"));
    permissions_test_util::GrantOptionalPermissionsAndWaitForCompletion(
        profile(), *extension,
        PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
                      std::move(patterns), URLPatternSet()));
  }

  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension),
              testing::UnorderedElementsAre("https://example.com/*"));

  ScriptingPermissionsModifier modifier(profile(), extension.get());
  modifier.RemoveAllGrantedHostPermissions();
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());
}

// Tests that HasBroadGrantedHostPermissions detects cases where there is a
// granted permission that is sufficiently broad enough to be counted as akin to
// <all_urls> type permissions.
TEST_F(ScriptingPermissionsModifierUnitTest, HasBroadGrantedHostPermissions) {
  InitializeEmptyExtensionService();

  struct {
    std::vector<std::string> hosts;
    bool expected_broad_permissions;
  } test_cases[] = {{{}, false},
                    {{"https://www.google.com/*"}, false},
                    {{"https://www.google.com/*", "*://chromium.org/*"}, false},
                    {{"*://*.google.*/*"}, false},
                    {{"<all_urls>"}, true},
                    {{"https://*/*"}, true},
                    {{"*://*/*"}, true},
                    {{"https://www.google.com/*", "<all_urls>"}, true}};

  for (const auto& test_case : test_cases) {
    std::string test_case_name = base::JoinString(test_case.hosts, ",");
    SCOPED_TRACE(test_case_name);
    scoped_refptr<const Extension> extension =
        ExtensionBuilder("test: " + test_case_name)
            .AddPermission("<all_urls>")
            .Build();

    ScriptingPermissionsModifier modifier(profile(), extension.get());
    modifier.SetWithholdHostPermissions(true);

    PermissionsManager* permissions_manager =
        PermissionsManager::Get(profile());
    EXPECT_FALSE(
        permissions_manager->HasBroadGrantedHostPermissions(*extension));

    std::string error;
    bool allow_file_access = false;
    URLPatternSet patterns;
    patterns.Populate(test_case.hosts, Extension::kValidHostPermissionSchemes,
                      allow_file_access, &error);
    permissions_test_util::GrantRuntimePermissionsAndWaitForCompletion(
        profile(), *extension,
        PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
                      std::move(patterns), URLPatternSet()));

    EXPECT_EQ(test_case.expected_broad_permissions,
              permissions_manager->HasBroadGrantedHostPermissions(*extension));
  }
}

// Tests RemoveBroadGrantedHostPermissions only removes the broad permissions
// and leaves others intact.
TEST_F(ScriptingPermissionsModifierUnitTest,
       RemoveBroadGrantedHostPermissions) {
  InitializeEmptyExtensionService();

  const GURL google_com = GURL("https://google.com/*");
  const GURL example_com = GURL("https://example.com/*");

  // Define a list of broad patters that should give access to both URLs.
  std::string broad_patterns[] = {"https://*/*", "<all_urls>",
                                  "https://*.com/*"};

  for (const auto& broad_pattern : broad_patterns) {
    SCOPED_TRACE(broad_pattern);
    scoped_refptr<const Extension> extension =
        ExtensionBuilder("test: " + broad_pattern)
            .AddPermission("<all_urls>")
            .Build();
    ScriptingPermissionsModifier modifier(profile(), extension.get());

    modifier.SetWithholdHostPermissions(true);

    // Explicitly grant google.com and the broad pattern.
    modifier.GrantHostPermission(google_com);
    const URLPattern pattern(Extension::kValidHostPermissionSchemes,
                             broad_pattern);
    permissions_test_util::GrantRuntimePermissionsAndWaitForCompletion(
        profile(), *extension,
        PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
                      URLPatternSet({pattern}), URLPatternSet()));

    PermissionsManager* permissions_manager =
        PermissionsManager::Get(profile());
    EXPECT_TRUE(
        permissions_manager->HasGrantedHostPermission(*extension, google_com));
    EXPECT_TRUE(
        permissions_manager->HasGrantedHostPermission(*extension, example_com));

    // Now removing the broad patterns should leave it only with the explicit
    // google permission.
    modifier.RemoveBroadGrantedHostPermissions();
    EXPECT_TRUE(
        permissions_manager->HasGrantedHostPermission(*extension, google_com));
    EXPECT_FALSE(
        permissions_manager->HasGrantedHostPermission(*extension, example_com));
    EXPECT_FALSE(
        permissions_manager->HasBroadGrantedHostPermissions(*extension));
  }
}

// Tests granting runtime permissions for a full host when the extension only
// wants to run on a subset of that host.
TEST_F(ScriptingPermissionsModifierUnitTest,
       GrantingHostPermissionsBeyondRequested) {
  InitializeEmptyExtensionService();

  static constexpr char kContentScripts[] = R"([
    {
      "matches": ["https://google.com/maps"],
      "js": ["foo.js"]
    }
  ])";
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("test")
          .SetManifestKey("content_scripts",
                          base::test::ParseJsonList(kContentScripts))
          .Build();

  // At installation, all permissions granted.
  ScriptingPermissionsModifier modifier(profile(), extension);
  PermissionsManager* manager = PermissionsManager::Get(profile());
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension),
              testing::UnorderedElementsAre("https://google.com/maps"));

  // Withhold host permissions.
  modifier.SetWithholdHostPermissions(true);
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());

  // Grant the requested host permission. We grant origins (rather than just
  // paths), but we don't over-grant permissions to the actual extension object.
  // The active permissions on the extension should be restricted to the
  // permissions explicitly requested (google.com/maps), but the granted
  // permissions in preferences will be the full host (google.com).
  modifier.GrantHostPermission(GURL("https://google.com/maps"));
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension),
              testing::UnorderedElementsAre("https://google.com/maps"));
  EXPECT_THAT(
      GetPatternsAsStrings(
          manager->GetRevokablePermissions(*extension)->effective_hosts()),
      // Subtle: revokable permissions include permissions either in
      // the runtime granted permissions preference or active on the
      // extension object. In this case, that includes both google.com/*
      // and google.com/maps.
      testing::UnorderedElementsAre("https://google.com/maps",
                                    "https://google.com/*"));

  // Remove the granted permission. This should remove the permission from both
  // the active permissions on the extension object and the entry in the
  // preferences.
  modifier.RemoveAllGrantedHostPermissions();
  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());
  EXPECT_THAT(
      GetPatternsAsStrings(
          manager->GetRevokablePermissions(*extension)->effective_hosts()),
      testing::IsEmpty());
}

// TODO(crbug.com/1289441): Move test to PermissionsManager once permissions can
// be withheld in the extensions directory since this test checks important part
// of the PermissionsManager logic.
TEST_F(ScriptingPermissionsModifierUnitTest, ChangeHostPermissions_AllHosts) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").AddPermission("<all_urls>").Build();
  InitializeExtensionPermissions(profile(), *extension);
  auto* manager = PermissionsManager::Get(profile());

  ScriptingPermissionsModifier modifier(profile(), extension.get());
  modifier.SetWithholdHostPermissions(true);

  // Verify a non-restricted site has wihthheld both site access and all sites
  // access.
  const GURL example_com("https://www.example.com");
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        manager->GetSiteAccess(*extension, example_com);
    EXPECT_FALSE(site_access.has_site_access);
    EXPECT_TRUE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_TRUE(site_access.withheld_all_sites_access);
  }

  // Verify a restricted site does not have site access withheld, but it has all
  // sites withheld.
  const GURL chrome_extensions("chrome://extensions");
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        manager->GetSiteAccess(*extension, chrome_extensions);
    EXPECT_FALSE(site_access.has_site_access);
    EXPECT_FALSE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_TRUE(site_access.withheld_all_sites_access);
  }

  modifier.GrantHostPermission(example_com);

  // Verify the granted url has site access but all sites are still withheld.
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        manager->GetSiteAccess(*extension, example_com);
    EXPECT_TRUE(site_access.has_site_access);
    EXPECT_FALSE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_TRUE(site_access.withheld_all_sites_access);
  }

  // Verify the non-granted url has withheld both sites access and all sites
  // access.
  const GURL google_com("https://google.com");
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        manager->GetSiteAccess(*extension, google_com);
    EXPECT_FALSE(site_access.has_site_access);
    EXPECT_TRUE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_TRUE(site_access.withheld_all_sites_access);
  }
}

// TODO(crbug.com/1289441): Move test to PermissionsManager once permissions can
// be withheld in the extensions directory since this test checks important part
// of the PermissionsManager logic.
TEST_F(ScriptingPermissionsModifierUnitTest,
       ChangeHostPermissions_AllHostsLike) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").AddPermission("*://*.com/*").Build();
  InitializeExtensionPermissions(profile(), *extension);

  ScriptingPermissionsModifier(profile(), extension.get())
      .SetWithholdHostPermissions(true);

  // Verify a non-restricted site has wihtheld both site access and all sites
  // access.
  const GURL example_com("https://www.example.com");
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        PermissionsManager::Get(profile())->GetSiteAccess(*extension,
                                                          example_com);
    EXPECT_FALSE(site_access.has_site_access);
    EXPECT_TRUE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_TRUE(site_access.withheld_all_sites_access);
  }
}

// TODO(crbug.com/1289441): Move test to PermissionsManager once permissions can
// be withheld in the extensions directory since this test checks important part
// of the PermissionsManager logic
TEST_F(ScriptingPermissionsModifierUnitTest,
       ChangeHostPermissions_SpecificSite) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension")
          .AddPermission("*://*.example.com/*")
          .Build();
  InitializeExtensionPermissions(profile(), *extension);

  ScriptingPermissionsModifier(profile(), extension.get())
      .SetWithholdHostPermissions(true);

  // Verify a requested sited has wihtheld both site access and all sites
  // access.
  const GURL example_com("https://www.example.com");
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        PermissionsManager::Get(profile())->GetSiteAccess(*extension,
                                                          example_com);
    EXPECT_FALSE(site_access.has_site_access);
    EXPECT_TRUE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_FALSE(site_access.withheld_all_sites_access);
  }
}

// TODO(crbug.com/1289441): Move test to PermissionsManager once permissions can
// be withheld in the extensions directory since this test checks important part
// of the PermissionsManager logic
TEST_F(ScriptingPermissionsModifierUnitTest, AddRuntimeGrantedHostPermission) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension")
          .AddPermission("*://*.example.com/*")
          .Build();
  InitializeExtensionPermissions(profile(), *extension);
  ScriptingPermissionsModifier modifier(profile(), extension.get());
  modifier.SetWithholdHostPermissions(true);

  const URLPatternSet google_com_pattern({URLPattern(
      Extension::kValidHostPermissionSchemes, "https://google.com/*")});
  ExtensionPrefs::Get(profile())->AddRuntimeGrantedPermissions(
      extension->id(),
      PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
                    google_com_pattern.Clone(), google_com_pattern.Clone()));

  const GURL google_com("https://google.com");
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        PermissionsManager(profile()).GetSiteAccess(*extension, google_com);
    // The has_access and withheld_access bits should be set appropriately, even
    // if the extension has access to a site it didn't request.
    EXPECT_TRUE(site_access.has_site_access);
    EXPECT_FALSE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_FALSE(site_access.withheld_all_sites_access);
  }
}

// Tests that for the purposes of displaying an extension's site access to the
// user (or granting/revoking permissions), we ignore paths in the URL.
// TODO(crbug.com/1289441): Move test to PermissionsManager once permissions can
// be withheld in the extensions directory since this test checks important part
// of the PermissionsManager logic
TEST_F(ScriptingPermissionsModifierUnitTest,
       ChangeHostPermissions_IgnorePaths) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension")
          .AddContentScript("foo.js", {"https://www.example.com/foo"})
          .SetLocation(ManifestLocation::kInternal)
          .Build();
  InitializeExtensionPermissions(profile(), *extension);

  auto* manager = PermissionsManager::Get(profile());

  const GURL example_com("https://www.example.com/bar");
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        manager->GetSiteAccess(*extension, example_com);
    // Even though the path doesn't exactly match one in the content scripts,
    // the domain is requested, and thus we treat it as if the site was
    // requested.
    EXPECT_TRUE(site_access.has_site_access);
    EXPECT_FALSE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_FALSE(site_access.withheld_all_sites_access);
  }

  ScriptingPermissionsModifier(profile(), extension.get())
      .SetWithholdHostPermissions(true);
  {
    const PermissionsManager::ExtensionSiteAccess site_access =
        manager->GetSiteAccess(*extension, example_com);
    EXPECT_FALSE(site_access.has_site_access);
    EXPECT_TRUE(site_access.withheld_site_access);
    EXPECT_FALSE(site_access.has_all_sites_access);
    EXPECT_FALSE(site_access.withheld_all_sites_access);
  }
}

// Tests that removing access for a host removes all patterns that grant access
// to that host.
TEST_F(ScriptingPermissionsModifierUnitTest,
       RemoveHostAccess_RemovesOverlappingPatterns) {
  InitializeEmptyExtensionService();

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").AddPermission("*://*/*").Build();
  InitializeExtensionPermissions(profile(), *extension);
  ScriptingPermissionsModifier modifier(profile(), extension.get());
  modifier.SetWithholdHostPermissions(true);

  const URLPattern all_com_pattern(Extension::kValidHostPermissionSchemes,
                                   "https://*.com/*");
  permissions_test_util::GrantRuntimePermissionsAndWaitForCompletion(
      profile(), *extension,
      PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
                    URLPatternSet({all_com_pattern}), URLPatternSet()));

  // Removing example.com access should result in *.com access being revoked,
  // since that is the pattern that grants access to example.com.
  const GURL example_com("https://www.example.com");
  PermissionsManager* permissions_manager = PermissionsManager::Get(profile());
  EXPECT_TRUE(
      permissions_manager->HasGrantedHostPermission(*extension, example_com));
  modifier.RemoveGrantedHostPermission(example_com);
  EXPECT_FALSE(
      permissions_manager->HasGrantedHostPermission(*extension, example_com));
  EXPECT_TRUE(ExtensionPrefs::Get(profile())
                  ->GetRuntimeGrantedPermissions(extension->id())
                  ->explicit_hosts()
                  .is_empty());
}

// Test that granting <all_urls> as an optional permission, and then revoking
// it, behaves properly. Regression test for https://crbug.com/930062.
TEST_F(ScriptingPermissionsModifierUnitTest,
       RemoveAllURLsGrantedOptionalPermission) {
  InitializeEmptyExtensionService();

  static constexpr char kOptionalPermissions[] = R"(["<all_urls>"])";
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension")
          .SetManifestKey("optional_permissions",
                          base::test::ParseJsonList(kOptionalPermissions))
          .Build();
  InitializeExtensionPermissions(profile(), *extension);

  // Also verify the extension doesn't have file access, so that <all_urls>
  // shouldn't match file URLs either.
  EXPECT_FALSE(util::AllowFileAccess(extension->id(), profile()));

  {
    PermissionsUpdater updater(profile());
    updater.GrantOptionalPermissions(
        *extension, PermissionsParser::GetOptionalPermissions(extension.get()),
        base::DoNothing());
  }

  ScriptingPermissionsModifier(profile(), extension.get())
      .SetWithholdHostPermissions(true);

  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());
}

}  // namespace extensions
