chromium/chrome/browser/extensions/crx_installer_browsertest.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

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

#include <stddef.h>

#include <memory>
#include <optional>
#include <utility>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_future.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/extension_install_prompt_show_params.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
#include "chrome/browser/extensions/forced_extensions/install_stage_tracker.h"
#include "chrome/browser/extensions/permissions/scripting_permissions_modifier.h"
#include "chrome/browser/extensions/scoped_database_manager_for_test.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/safe_browsing/buildflags.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_dialog_auto_confirm.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/install/crx_install_error.h"
#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
#include "extensions/browser/management_policy.h"
#include "extensions/browser/permissions_manager.h"
#include "extensions/browser/renderer_startup_helper.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/file_util.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/switches.h"
#include "extensions/test/test_extension_dir.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/l10n/l10n_util.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_switches.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
#include "components/user_manager/scoped_user_manager.h"
#endif

namespace extensions {

namespace {

class MockInstallPrompt;

// This class holds information about things that happen with a
// MockInstallPrompt. We create the MockInstallPrompt but need to pass
// ownership of it to CrxInstaller, so it isn't safe to hang this data on
// MockInstallPrompt itself because we can't guarantee it's lifetime.
class MockPromptProxy {};

class MockInstallPrompt : public ExtensionInstallPrompt {};

MockPromptProxy::MockPromptProxy(
    content::WebContents* web_contents,
    ScopedTestDialogAutoConfirm::AutoConfirm confirm_mode)
    :{}

MockPromptProxy::~MockPromptProxy() = default;

std::unique_ptr<ExtensionInstallPrompt> MockPromptProxy::CreatePrompt() {}

std::unique_ptr<MockPromptProxy> CreateMockPromptProxyForBrowserWithConfirmMode(
    Browser* browser,
    ScopedTestDialogAutoConfirm::AutoConfirm confirm_mode) {}

std::unique_ptr<MockPromptProxy> CreateMockPromptProxyForBrowser(
    Browser* browser) {}

class ManagementPolicyMock : public ManagementPolicy::Provider {};

}  // namespace

class ExtensionCrxInstallerTest : public ExtensionBrowserTest {};

class ExtensionCrxInstallerTestWithExperimentalApis
    : public ExtensionCrxInstallerTest {};

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       ExperimentalExtensionFromGallery) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       ExperimentalExtensionFromOutsideGallery) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       ExperimentalExtensionFromOutsideGalleryWithFlag) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       PlatformAppCrx) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, BlockedFileTypes) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowedThemeFileTypes) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       PackAndInstallExtensionFromDownload) {}

// Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is
// true.
IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       GrantScopes) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       GrantScopes_WithCallback) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       DoNotGrantScopes) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       DoNotGrantScopes_WithCallback) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowOffStore) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallDelayedUntilNextUpdate) {}

#if BUILDFLAG(FULL_SAFE_BROWSING)
IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blocklist) {}
#endif

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       NonStrictManifestCheck_WithCallback) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallUnpackedCrx_FolderDoesNotExist) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallUnpackedCrx_EmptyFolder) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallUnpackedCrx_InvalidPublicKey) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallUnpackedCrx_Success) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       UpdateExtensionFromUnpackedCrx_NewExtension) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       UpdateExtensionFromUnpackedCrx_UpdateExistingExtension) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       UpdateExtensionFromUnpackedCrx_InvalidPublicKey) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       UpdateExtensionFromUnpackedCrx_WrongPublicKey) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) {
  base::ScopedAllowBlockingForTesting allow_io;
  // kiosk_only is allowlisted from non-chromeos.
  base::FilePath crx_path = test_data_dir_.AppendASCII("kiosk/kiosk_only.crx");
  EXPECT_FALSE(InstallExtension(crx_path, 0));
  // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over
  // lifetime of |user_manager|.
  auto* fake_user_manager = new ash::FakeChromeUserManager();
  const AccountId account_id(AccountId::FromUserEmail("[email protected]"));
  fake_user_manager->AddKioskAppUser(account_id);
  fake_user_manager->LoginUser(account_id);
  user_manager::ScopedUserManager scoped_user_manager(
      base::WrapUnique(fake_user_manager));
  EXPECT_TRUE(InstallExtension(crx_path, 1));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallToSharedLocation) {
  base::ScopedAllowBlockingForTesting allow_io;
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      ash::switches::kEnableExtensionAssetsSharing);
  base::ScopedTempDir cache_dir;
  ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
  ExtensionAssetsManagerChromeOS::SetSharedInstallDirForTesting(
      cache_dir.GetPath());

  base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
  const Extension* extension =
      InstallExtension(crx_path, 1, mojom::ManifestLocation::kExternalPref);
  base::FilePath extension_path = extension->path();
  EXPECT_TRUE(cache_dir.GetPath().IsParent(extension_path));
  EXPECT_TRUE(base::PathExists(extension_path));

  extensions::ExtensionId extension_id = extension->id();
  UninstallExtension(extension_id);
  ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
  EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id));

  content::RunAllTasksUntilIdle();

  EXPECT_FALSE(base::PathExists(extension_path));
}
#endif

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotSync) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) {}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, UpdateWithFileAccess) {}

class ExtensionCrxInstallerTestWithWithholdingUI
    : public ExtensionCrxInstallerTest,
      public testing::WithParamInterface<bool> {};

IN_PROC_BROWSER_TEST_P(ExtensionCrxInstallerTestWithWithholdingUI,
                       WithholdingHostsOnInstall) {}

INSTANTIATE_TEST_SUITE_P();

}  // namespace extensions