chromium/chrome/browser/extensions/policy_handlers_unittest.cc

// Copyright 2013 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/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) {}

// Only enterprise managed machines can auto install extensions from a location
// other than the webstore https://crbug.com/809004.
TEST(ExtensionSettingsPolicyHandlerTest, NonManagedOffWebstoreExtension) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
class PolicyHandlerAshTest : public ::testing::Test {
 public:
  PolicyHandlerAshTest() = default;
  ~PolicyHandlerAshTest() override = default;

  void SetUp() override {
    Test::SetUp();
    // A logged in user is required in order to enable Lacros.
    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(
        /*enabled_features=*/ash::standalone_browser::GetFeatureRefs(),
        /*disabled_features=*/{});
    scoped_command_line_.GetProcessCommandLine()->AppendSwitch(
        ash::switches::kEnableLacrosForTesting);
  }

  void DisableLacros() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/{},
        /*disabled_features=*/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()
                      // Add an arbitrary extension.
                      .Append(base::StrCat({"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                                            ";", "http://www.example.com/crx"}))
                      // Add an extension in keep list. Check
                      // `ExtensionRunsInOS()` for details.
                      .Append(base::StrCat(
                          {extension_misc::kAccessibilityCommonExtensionId, ";",
                           "http://www.access.com/crx"}))
                      // Add an extension app in keep list. Check
                      // `ExtensionAppRunsInOS()` for details.
                      .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());

  // The arbitrary extension should have been filtered out.
  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()
                      // Add an arbitrary extension.
                      .Append(base::StrCat({"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                                            ";", "http://www.example.com/crx"}))
                      // Add an extension in keep list. Check
                      // `ExtensionRunsInOS()` for details.
                      .Append(base::StrCat(
                          {extension_misc::kAccessibilityCommonExtensionId, ";",
                           "http://www.access.com/crx"}))
                      // Add an extension app in keep list. Check
                      // `ExtensionAppRunsInOS()` for details.
                      .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());

  // All extensions should be retained.
  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  // BUILDFLAG(IS_CHROMEOS_ASH)

}  // namespace extensions