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

#include "chrome/browser/extensions/webstore_installer.h"

#include <memory>
#include <utility>

#include "base/run_loop.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/scripting_permissions_modifier.h"
#include "chrome/browser/extensions/webstore_installer_test.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/permissions_manager.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_features.h"

namespace extensions {

namespace {

const char kWebstoreDomain[] = "cws.com";
const char kAppDomain[] = "app.com";
const char kNonAppDomain[] = "nonapp.com";
const char kTestExtensionId[] = "ecglahbcnmdpdciemllbhojghbkagdje";
const char kTestExtensionWithPermissionsId[] =
    "lpbboafeefjeccjhdhcfdibnjcecpmhd";
const char kTestDataPath[] = "extensions/api_test/webstore_inline_install";
const char kCrxFilename[] = "extension.crx";
const char kCrxWithPermissionsFilename[] =
    "extension_with_host_permissions.crx";

}  // namespace

// Test version of WebstoreInstaller that intercepts the destructor.
class TestWebstoreInstaller : public WebstoreInstaller {
 public:
  TestWebstoreInstaller(Profile* profile,
                        Delegate* delegate,
                        content::WebContents* web_contents,
                        const std::string& id,
                        std::unique_ptr<Approval> approval,
                        InstallSource source)
      : WebstoreInstaller(profile,
                          delegate,
                          web_contents,
                          id,
                          std::move(approval),
                          source) {}

  void SetDeletedClosure(base::OnceClosure cb) {
    deleted_closure_ = std::move(cb);
  }

 private:
  ~TestWebstoreInstaller() override {
    if (!deleted_closure_.is_null())
      std::move(deleted_closure_).Run();
  }

  base::OnceClosure deleted_closure_;
};

class WebstoreInstallerBrowserTest : public WebstoreInstallerTest,
                                     public WebstoreInstaller::Delegate {
 public:
  WebstoreInstallerBrowserTest(const std::string& webstore_domain,
                               const std::string& test_data_path,
                               const std::string& crx_filename,
                               const std::string& verified_domain,
                               const std::string& unverified_domain)
      : WebstoreInstallerTest(webstore_domain,
                              test_data_path,
                              crx_filename,
                              verified_domain,
                              unverified_domain) {}
  ~WebstoreInstallerBrowserTest() override = default;

  void SetDoneClosure(base::OnceClosure done_closure) {
    done_closure_ = std::move(done_closure);
  }

  bool success() const { return success_; }

  // Overridden from WebstoreInstaller::Delegate:
  void OnExtensionDownloadStarted(const std::string& id,
                                  download::DownloadItem* item) override {}
  void OnExtensionDownloadProgress(const std::string& id,
                                   download::DownloadItem* item) override {}
  void OnExtensionInstallSuccess(const std::string& id) override {
    success_ = true;
    std::move(done_closure_).Run();
  }
  void OnExtensionInstallFailure(
      const std::string& id,
      const std::string& error,
      WebstoreInstaller::FailureReason reason) override {
    success_ = false;
    std::move(done_closure_).Run();
  }

 private:
  base::OnceClosure done_closure_;
  bool success_;
};

class WebstoreInstallerMV2BrowserTest : public WebstoreInstallerBrowserTest {
 public:
  WebstoreInstallerMV2BrowserTest()
      : WebstoreInstallerBrowserTest(kWebstoreDomain,
                                     kTestDataPath,
                                     kCrxFilename,
                                     kAppDomain,
                                     kNonAppDomain) {}
  ~WebstoreInstallerMV2BrowserTest() override = default;

  // The manifest used by the test installer must match `kCrxFilename` manifest
  // in the test directory.
  base::Value::Dict GetManifest() {
    return base::Value::Dict()
        .Set("name", "Installer Extension")
        .Set("manifest_version", 2)
        .Set("version", "1.0")
        .Set("permissions", base::Value::List().Append("tabs"));
  }
};

IN_PROC_BROWSER_TEST_F(WebstoreInstallerMV2BrowserTest, WebstoreInstall) {
  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(active_web_contents);

  // Create an approval.
  std::unique_ptr<WebstoreInstaller::Approval> approval =
      WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
          browser()->profile(), kTestExtensionId, GetManifest(), false);

  // Create and run a WebstoreInstaller.
  base::RunLoop run_loop;
  SetDoneClosure(run_loop.QuitClosure());
  TestWebstoreInstaller* installer = new TestWebstoreInstaller(
      browser()->profile(), this, active_web_contents, kTestExtensionId,
      std::move(approval), WebstoreInstaller::INSTALL_SOURCE_OTHER);
  installer->Start();
  run_loop.Run();

  EXPECT_TRUE(success());
  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  ASSERT_TRUE(registry->enabled_extensions().GetByID(kTestExtensionId));
}

IN_PROC_BROWSER_TEST_F(WebstoreInstallerMV2BrowserTest, SimultaneousInstall) {
  base::Value::Dict manifest = GetManifest();

  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(active_web_contents);

  // Create an approval.
  std::unique_ptr<WebstoreInstaller::Approval> approval =
      WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
          browser()->profile(), kTestExtensionId, manifest.Clone(), false);

  // Create and run a WebstoreInstaller.
  base::RunLoop run_loop;
  SetDoneClosure(run_loop.QuitClosure());
  scoped_refptr<TestWebstoreInstaller> installer = new TestWebstoreInstaller(
      browser()->profile(), this, active_web_contents, kTestExtensionId,
      std::move(approval), WebstoreInstaller::INSTALL_SOURCE_OTHER);
  installer->Start();

  // Simulate another mechanism installing the same extension.
  scoped_refptr<const Extension> extension =
      ExtensionBuilder()
          .SetLocation(mojom::ManifestLocation::kInternal)
          .SetID(kTestExtensionId)
          .SetManifest(std::move(manifest))
          .Build();
  extension_service()->OnExtensionInstalled(extension.get(),
                                            syncer::StringOrdinal(), 0);

  run_loop.Run();

  // Wait for the WebstoreInstaller to be destroyed. Bad things happen if we
  // don't wait for this.
  base::RunLoop run_loop2;
  installer->SetDeletedClosure(run_loop2.QuitClosure());
  installer = nullptr;
  run_loop2.Run();

  EXPECT_TRUE(success());
  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  // Extension ends up as disabled because of permissions.
  ASSERT_TRUE(registry->disabled_extensions().GetByID(kTestExtensionId));
}

class WebstoreInstallerWithWithholdingUIBrowserTest
    : public WebstoreInstallerBrowserTest,
      public testing::WithParamInterface<bool> {
 public:
  WebstoreInstallerWithWithholdingUIBrowserTest()
      : WebstoreInstallerBrowserTest(kWebstoreDomain,
                                     kTestDataPath,
                                     kCrxWithPermissionsFilename,
                                     kAppDomain,
                                     kNonAppDomain) {
    feature_list_.InitAndEnableFeature(
        extensions_features::kAllowWithholdingExtensionPermissionsOnInstall);
  }
  ~WebstoreInstallerWithWithholdingUIBrowserTest() override = default;

  // Th manifest used by the test installer must match
  // `kCrxWithPermissionsFilename` manifest in the test directory.
  base::Value::Dict GetManifest() {
    return base::Value::Dict()
        .Set("name", "Installer Extension")
        .Set("manifest_version", 3)
        .Set("version", "1.0")
        .Set("host_permissions", base::Value::List().Append("<all_urls>"));
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

// Tests host permissions are withheld at installation only when the checkbox is
// selected.
IN_PROC_BROWSER_TEST_P(WebstoreInstallerWithWithholdingUIBrowserTest,
                       WithholdingHostsOnInstall) {
  bool shoud_withhold_permissions = GetParam();

  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(active_web_contents);

  // Create an approval that withhelds permissions when the checkbox is not
  // selected.
  std::unique_ptr<WebstoreInstaller::Approval> approval =
      WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
          browser()->profile(), kTestExtensionWithPermissionsId, GetManifest(),
          false);
  approval->withhold_permissions = shoud_withhold_permissions;

  // Create and run a WebstoreInstaller.
  base::RunLoop run_loop;
  SetDoneClosure(run_loop.QuitClosure());
  TestWebstoreInstaller* installer = new TestWebstoreInstaller(
      browser()->profile(), this, active_web_contents,
      kTestExtensionWithPermissionsId, std::move(approval),
      WebstoreInstaller::INSTALL_SOURCE_OTHER);
  installer->Start();
  run_loop.Run();

  // Verify extension was installed.
  EXPECT_TRUE(success());
  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  const Extension* extension =
      registry->enabled_extensions().GetByID(kTestExtensionWithPermissionsId);
  ASSERT_TRUE(extension);

  // Host permissions should be withheld only when the params indicate so.
  PermissionsManager* permissions_manager =
      PermissionsManager::Get(browser()->profile());
  EXPECT_EQ(permissions_manager->HasWithheldHostPermissions(*extension),
            shoud_withhold_permissions);

  // Access to google.com should be withheld only when the params indicate so.
  const PermissionsManager::ExtensionSiteAccess site_access =
      permissions_manager->GetSiteAccess(*extension,
                                         GURL("https://www.google.com"));
  EXPECT_EQ(site_access.withheld_site_access, shoud_withhold_permissions);
  EXPECT_EQ(site_access.has_site_access, !shoud_withhold_permissions);
}

INSTANTIATE_TEST_SUITE_P(All,
                         WebstoreInstallerWithWithholdingUIBrowserTest,
                         testing::Bool());

}  // namespace extensions
