// 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,
                        SuccessCallback success_callback,
                        FailureCallback failure_callback,
                        content::WebContents* web_contents,
                        const std::string& id,
                        std::unique_ptr<Approval> approval,
                        InstallSource source)
      : WebstoreInstaller(profile,
                          std::move(success_callback),
                          std::move(failure_callback),
                          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:
  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_; }

  void OnExtensionInstallSuccess(const std::string& id) {
    success_ = true;
    std::move(done_closure_).Run();
  }

  void OnExtensionInstallFailure(const std::string& id,
                                 const std::string& error,
                                 WebstoreInstaller::FailureReason reason) {
    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(),
      base::BindOnce(&WebstoreInstallerBrowserTest::OnExtensionInstallSuccess,
                     base::Unretained(this)),
      base::BindOnce(&WebstoreInstallerBrowserTest::OnExtensionInstallFailure,
                     base::Unretained(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(),
      base::BindOnce(&WebstoreInstallerBrowserTest::OnExtensionInstallSuccess,
                     base::Unretained(this)),
      base::BindOnce(&WebstoreInstallerBrowserTest::OnExtensionInstallFailure,
                     base::Unretained(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(),
      base::BindOnce(&WebstoreInstallerBrowserTest::OnExtensionInstallSuccess,
                     base::Unretained(this)),
      base::BindOnce(&WebstoreInstallerBrowserTest::OnExtensionInstallFailure,
                     base::Unretained(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
