
It basically works out-of-the-box. I added ExtensionGarbageCollector to the build (a dependency) and ifdef'd out MV2Enabler. I added the garbage collector's unit test and InstallVerifierTest to unit_tests to demonstrate that ExtensionServiceTestBase works. I'll port other subclasses like ExtensionServiceTestWithInstall in follow-up CLs. Bug: 414398434 Change-Id: I4a8eb120fc6e514d2bf41a41c5f93e1eae48f499 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6496206 Reviewed-by: Devlin Cronin <rdevlin.cronin@chromium.org> Commit-Queue: James Cook <jamescook@chromium.org> Cr-Commit-Position: refs/heads/main@{#1452984}
176 lines
7.1 KiB
C++
176 lines
7.1 KiB
C++
// Copyright 2017 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/install_verifier.h"
|
|
|
|
#include "base/values.h"
|
|
#include "chrome/browser/extensions/extension_management.h"
|
|
#include "chrome/browser/extensions/extension_service_test_base.h"
|
|
#include "chrome/browser/extensions/external_policy_loader.h"
|
|
#include "chrome/browser/policy/policy_test_utils.h"
|
|
#include "chrome/browser/profiles/profile.h"
|
|
#include "components/sync_preferences/testing_pref_service_syncable.h"
|
|
#include "extensions/browser/pref_names.h"
|
|
#include "extensions/buildflags/buildflags.h"
|
|
#include "extensions/common/extension.h"
|
|
#include "extensions/common/extension_builder.h"
|
|
#include "extensions/common/extension_urls.h"
|
|
#include "extensions/common/manifest.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
|
|
|
|
using extensions::mojom::ManifestLocation;
|
|
|
|
namespace extensions {
|
|
|
|
class InstallVerifierTest : public ExtensionServiceTestBase {
|
|
public:
|
|
InstallVerifierTest() = default;
|
|
|
|
InstallVerifierTest(const InstallVerifierTest&) = delete;
|
|
InstallVerifierTest& operator=(const InstallVerifierTest&) = delete;
|
|
|
|
~InstallVerifierTest() override = default;
|
|
|
|
void SetUp() override {
|
|
ExtensionServiceTestBase::SetUp();
|
|
|
|
InitializeExtensionService(ExtensionServiceInitParams());
|
|
}
|
|
|
|
// Adds an extension as being allowed by policy.
|
|
void AddExtensionAsPolicyInstalled(const ExtensionId& id) {
|
|
base::Value::Dict extension_entry =
|
|
base::Value::Dict().Set("installation_mode", "allowed");
|
|
testing_pref_service()->SetManagedPref(
|
|
pref_names::kExtensionManagement,
|
|
base::Value::Dict().Set(id, std::move(extension_entry)));
|
|
EXPECT_TRUE(ExtensionManagementFactory::GetForBrowserContext(profile())
|
|
->IsInstallationExplicitlyAllowed(id));
|
|
}
|
|
|
|
private:
|
|
ScopedInstallVerifierBypassForTest force_install_verification{
|
|
ScopedInstallVerifierBypassForTest::kForceOn};
|
|
std::unique_ptr<ExtensionManagement> extension_management_;
|
|
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
|
|
};
|
|
|
|
// Test the behavior of the InstallVerifier for various extensions.
|
|
TEST_F(InstallVerifierTest, TestIsFromStoreAndMustRemainDisabled) {
|
|
enum FromStoreStatus {
|
|
FROM_STORE,
|
|
NOT_FROM_STORE,
|
|
};
|
|
|
|
enum MustRemainDisabledStatus {
|
|
MUST_REMAIN_DISABLED,
|
|
CAN_BE_ENABLED,
|
|
};
|
|
|
|
GURL store_update_url = extension_urls::GetWebstoreUpdateUrl();
|
|
GURL non_store_update_url("https://example.com");
|
|
struct {
|
|
const char* test_name;
|
|
ManifestLocation location;
|
|
std::optional<GURL> update_url;
|
|
FromStoreStatus expected_from_store_status;
|
|
MustRemainDisabledStatus expected_must_remain_disabled_status;
|
|
} test_cases[] = {
|
|
{"internal from store", ManifestLocation::kInternal, store_update_url,
|
|
FROM_STORE, CAN_BE_ENABLED},
|
|
{"internal non-store update url", ManifestLocation::kInternal,
|
|
non_store_update_url, NOT_FROM_STORE, MUST_REMAIN_DISABLED},
|
|
{"internal no update url", ManifestLocation::kInternal, std::nullopt,
|
|
NOT_FROM_STORE, MUST_REMAIN_DISABLED},
|
|
{"unpacked from store", ManifestLocation::kUnpacked, store_update_url,
|
|
FROM_STORE, CAN_BE_ENABLED},
|
|
{"unpacked non-store update url", ManifestLocation::kUnpacked,
|
|
non_store_update_url, NOT_FROM_STORE, CAN_BE_ENABLED},
|
|
{"unpacked no update url", ManifestLocation::kUnpacked, std::nullopt,
|
|
NOT_FROM_STORE, CAN_BE_ENABLED},
|
|
{"external from store", ManifestLocation::kExternalPolicyDownload,
|
|
store_update_url, FROM_STORE, CAN_BE_ENABLED},
|
|
{"external non-store update url",
|
|
ManifestLocation::kExternalPolicyDownload, non_store_update_url,
|
|
NOT_FROM_STORE, CAN_BE_ENABLED},
|
|
};
|
|
|
|
InstallVerifier* install_verifier = InstallVerifier::Get(profile());
|
|
for (const auto& test_case : test_cases) {
|
|
SCOPED_TRACE(test_case.test_name);
|
|
ExtensionBuilder extension_builder(test_case.test_name);
|
|
extension_builder.SetLocation(test_case.location);
|
|
if (test_case.update_url) {
|
|
extension_builder.SetManifestKey("update_url",
|
|
test_case.update_url->spec());
|
|
}
|
|
scoped_refptr<const Extension> extension = extension_builder.Build();
|
|
|
|
if (Manifest::IsPolicyLocation(test_case.location))
|
|
AddExtensionAsPolicyInstalled(extension->id());
|
|
|
|
EXPECT_EQ(test_case.expected_from_store_status == FROM_STORE,
|
|
InstallVerifier::IsFromStore(*extension, profile()));
|
|
disable_reason::DisableReason disable_reason;
|
|
EXPECT_EQ(
|
|
test_case.expected_must_remain_disabled_status == MUST_REMAIN_DISABLED,
|
|
install_verifier->MustRemainDisabled(extension.get(), &disable_reason));
|
|
}
|
|
}
|
|
|
|
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
|
|
// Test the behavior of the InstallVerifier when an extension is
|
|
// force-installed in different trust environments.
|
|
TEST_F(InstallVerifierTest, ForceInstalledExtensionBehaviorWithTrustLevels) {
|
|
InstallVerifier* install_verifier = InstallVerifier::Get(profile());
|
|
scoped_refptr<const Extension> forced_extension =
|
|
ExtensionBuilder("Force Installed Extension")
|
|
.SetLocation(ManifestLocation::kExternalPolicyDownload)
|
|
.Build();
|
|
base::Value::Dict forced_list_pref;
|
|
ExternalPolicyLoader::AddExtension(forced_list_pref, forced_extension->id(),
|
|
"http://example.com/update_url");
|
|
testing_pref_service()->SetManagedPref(pref_names::kInstallForceList,
|
|
forced_list_pref.Clone());
|
|
|
|
{
|
|
// Set up a low-trust environment.
|
|
policy::ScopedManagementServiceOverrideForTesting browser_management(
|
|
policy::ManagementServiceFactory::GetForPlatform(),
|
|
policy::EnterpriseManagementAuthority::NONE);
|
|
|
|
EXPECT_TRUE(ExtensionManagementFactory::GetForBrowserContext(profile())
|
|
->IsForceInstalledInLowTrustEnvironment(*forced_extension));
|
|
|
|
// In a low-trust environment, the extension should remain disabled.
|
|
disable_reason::DisableReason disable_reason = disable_reason::DISABLE_NONE;
|
|
EXPECT_TRUE(install_verifier->MustRemainDisabled(forced_extension.get(),
|
|
&disable_reason));
|
|
EXPECT_EQ(disable_reason::DISABLE_NOT_VERIFIED, disable_reason);
|
|
}
|
|
|
|
{
|
|
// Set up a high-trust environment.
|
|
policy::ScopedManagementServiceOverrideForTesting browser_management(
|
|
policy::ManagementServiceFactory::GetForPlatform(),
|
|
policy::EnterpriseManagementAuthority::CLOUD_DOMAIN);
|
|
|
|
EXPECT_FALSE(
|
|
ExtensionManagementFactory::GetForBrowserContext(profile())
|
|
->IsForceInstalledInLowTrustEnvironment(*forced_extension));
|
|
|
|
// In a high-trust environment, the extension should not remain disabled.
|
|
disable_reason::DisableReason disable_reason = disable_reason::DISABLE_NONE;
|
|
EXPECT_FALSE(install_verifier->MustRemainDisabled(forced_extension.get(),
|
|
&disable_reason));
|
|
// Verify that disable_reason is still DISABLE_NONE.
|
|
EXPECT_EQ(disable_reason::DISABLE_NONE, disable_reason);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
} // namespace extensions
|