#include "chrome/browser/extensions/policy_handlers.h"
#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "base/json/json_reader.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/ash/crosapi/browser_util.h"
#include "chrome/browser/extensions/extension_management_constants.h"
#include "chrome/browser/extensions/external_policy_loader.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chromeos/ash/components/standalone_browser/feature_refs.h"
#include "components/account_id/account_id.h"
#include "components/policy/core/browser/policy_error_map.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/core/common/schema.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_value_map.h"
#include "components/strings/grit/components_strings.h"
#include "components/user_manager/scoped_user_manager.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/mojom/manifest.mojom-shared.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#if BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_switches.h"
#include "base/test/scoped_command_line.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#endif
ManifestLocation;
namespace extensions {
const char kTestPref[] = …;
const char kTestManagementPolicy1[] = …;
const char kTestManagementPolicy2[] = …;
const char kSensitiveTestManagementPolicy[] = …;
const char kSanitizedTestManagementPolicy[] = …;
constexpr char kTestManagementPolicy3[] = …;
constexpr char kTestManagementPolicy4[] = …;
const char kTestManagementPolicy5[] = …;
const char kSanitizedTestManagementPolicy5[] = …;
constexpr int kJsonParseOptions = …;
TEST(ExtensionListPolicyHandlerTest, CheckPolicySettings) { … }
TEST(ExtensionSettingsPolicyHandlerTest, CheckPolicySettingsURL) { … }
TEST(ExtensionListPolicyHandlerTest, ApplyPolicySettings) { … }
TEST(ExtensionInstallForceListPolicyHandlerTest, CheckPolicySettings) { … }
TEST(ExtensionInstallForceListPolicyHandlerTest, ApplyPolicySettings) { … }
TEST(ExtensionURLPatternListPolicyHandlerTest, CheckPolicySettings) { … }
TEST(ExtensionURLPatternListPolicyHandlerTest, ApplyPolicySettings) { … }
TEST(ExtensionSettingsPolicyHandlerTest, CheckPolicySettings) { … }
TEST(ExtensionSettingsPolicyHandlerTest, CheckPolicySettingsTooManyHosts) { … }
TEST(ExtensionSettingsPolicyHandlerTest, ApplyPolicySettings) { … }
TEST(ExtensionSettingsPolicyHandlerTest, DropInvalidKeys) { … }
TEST(ExtensionSettingsPolicyHandlerTest, NonManagedOffWebstoreExtension) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
class PolicyHandlerAshTest : public ::testing::Test {
public:
PolicyHandlerAshTest() = default;
~PolicyHandlerAshTest() override = default;
void SetUp() override {
Test::SetUp();
scoped_user_manager_.Reset(std::make_unique<ash::FakeChromeUserManager>());
AccountId account_id = AccountId::FromUserEmail("[email protected]");
scoped_user_manager_->AddUser(account_id);
scoped_user_manager_->LoginUser(account_id);
}
void TearDown() override {
scoped_user_manager_.Reset();
Test::TearDown();
}
void EnableLacros() {
feature_list_.InitWithFeatures(
ash::standalone_browser::GetFeatureRefs(),
{});
scoped_command_line_.GetProcessCommandLine()->AppendSwitch(
ash::switches::kEnableLacrosForTesting);
}
void DisableLacros() {
feature_list_.InitWithFeatures(
{},
ash::standalone_browser::GetFeatureRefs());
}
private:
user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
scoped_user_manager_;
base::test::ScopedFeatureList feature_list_;
base::test::ScopedCommandLine scoped_command_line_;
};
class ExtensionInstallBlockListPolicyHandlerAshTest
: public PolicyHandlerAshTest {
public:
const char* pref_name() const {
return pref_names::kInstallDenyList;
}
const char* policy_key() const {
return policy::key::kExtensionInstallBlocklist;
}
};
class ExtensionInstallForceListPolicyHandlerAshTest
: public PolicyHandlerAshTest {
public:
const char* pref_name() const {
return pref_names::kInstallForceList;
}
const char* policy_key() const {
return policy::key::kExtensionInstallForcelist;
}
};
TEST_F(ExtensionInstallBlockListPolicyHandlerAshTest,
ShouldClearBlockListIfAshBrowserIsDisabled) {
EnableLacros();
policy::PolicyMap policy_map;
PrefValueMap prefs;
policy_map.Set(policy_key(), policy::POLICY_LEVEL_MANDATORY,
policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
base::Value(base::Value::List()
.Append("abcdefghijklmnopabcdefghijklmnop")
.Append("*")),
nullptr);
ExtensionInstallBlockListPolicyHandler handler;
handler.ApplyPolicySettings(policy_map, &prefs);
base::Value* value = nullptr;
EXPECT_FALSE(prefs.GetValue(pref_name(), &value));
}
TEST_F(ExtensionInstallBlockListPolicyHandlerAshTest,
ShouldKeepBlockListIfAshBrowserIsEnabled) {
DisableLacros();
policy::PolicyMap policy_map;
PrefValueMap prefs;
policy_map.Set(policy_key(), policy::POLICY_LEVEL_MANDATORY,
policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
base::Value(base::Value::List()
.Append("abcdefghijklmnopabcdefghijklmnop")
.Append("*")),
nullptr);
ExtensionInstallBlockListPolicyHandler handler{};
handler.ApplyPolicySettings(policy_map, &prefs);
base::Value* value = nullptr;
EXPECT_TRUE(prefs.GetValue(pref_name(), &value));
ASSERT_TRUE(value->is_list());
auto expected = base::Value::List()
.Append("abcdefghijklmnopabcdefghijklmnop")
.Append("*");
ASSERT_EQ(value->GetList(), expected);
}
TEST_F(ExtensionInstallForceListPolicyHandlerAshTest,
BlockNonOSExtensionsIfAshBrowserDisabled) {
EnableLacros();
policy::PolicyMap policy_map;
PrefValueMap prefs;
policy_map.Set(
policy_key(), policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
policy::POLICY_SOURCE_CLOUD,
base::Value(base::Value::List()
.Append(base::StrCat({"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
";", "http://www.example.com/crx"}))
.Append(base::StrCat(
{extension_misc::kAccessibilityCommonExtensionId, ";",
"http://www.access.com/crx"}))
.Append(base::StrCat({extension_misc::kGnubbyAppId, ";",
"http://www.gnubby.com/crx"}))),
nullptr);
ExtensionInstallForceListPolicyHandler handler{};
handler.ApplyPolicySettings(policy_map, &prefs);
base::Value* value;
EXPECT_TRUE(prefs.GetValue(pref_name(), &value));
ASSERT_TRUE(value->is_dict());
auto expected =
base::Value::Dict()
.Set(extension_misc::kAccessibilityCommonExtensionId,
base::Value::Dict().Set(ExternalProviderImpl::kExternalUpdateUrl,
"http://www.access.com/crx"))
.Set(extension_misc::kGnubbyAppId,
base::Value::Dict().Set(ExternalProviderImpl::kExternalUpdateUrl,
"http://www.gnubby.com/crx"));
ASSERT_EQ(value->GetDict(), expected);
}
TEST_F(ExtensionInstallForceListPolicyHandlerAshTest,
AllowNonOSExtensionsIfAshBrowserEnabled) {
DisableLacros();
policy::PolicyMap policy_map;
PrefValueMap prefs;
policy_map.Set(
policy_key(), policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
policy::POLICY_SOURCE_CLOUD,
base::Value(base::Value::List()
.Append(base::StrCat({"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
";", "http://www.example.com/crx"}))
.Append(base::StrCat(
{extension_misc::kAccessibilityCommonExtensionId, ";",
"http://www.access.com/crx"}))
.Append(base::StrCat({extension_misc::kGnubbyAppId, ";",
"http://www.gnubby.com/crx"}))),
nullptr);
ExtensionInstallForceListPolicyHandler handler{};
handler.ApplyPolicySettings(policy_map, &prefs);
base::Value* value;
EXPECT_TRUE(prefs.GetValue(pref_name(), &value));
ASSERT_TRUE(value->is_dict());
auto expected =
base::Value::Dict()
.Set("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
base::Value::Dict().Set(ExternalProviderImpl::kExternalUpdateUrl,
"http://www.example.com/crx"))
.Set(extension_misc::kAccessibilityCommonExtensionId,
base::Value::Dict().Set(ExternalProviderImpl::kExternalUpdateUrl,
"http://www.access.com/crx"))
.Set(extension_misc::kGnubbyAppId,
base::Value::Dict().Set(ExternalProviderImpl::kExternalUpdateUrl,
"http://www.gnubby.com/crx"));
ASSERT_EQ(value->GetDict(), expected);
}
#endif
}