blob: e625986e35655809ad7a5c8437fd091eae4b5da2 [file] [log] [blame]
// Copyright 2018 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/policy/developer_tools_policy_handler.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/values.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/policy/core/browser/configuration_policy_pref_store.h"
#include "components/policy/core/browser/configuration_policy_pref_store_test.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/policy_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/user_manager/scoped_user_manager.h"
#include "content/public/test/browser_task_environment.h"
#endif
namespace policy {
using Availability = DeveloperToolsPolicyHandler::Availability;
class DeveloperToolsPolicyHandlerTest
: public ConfigurationPolicyPrefStoreTest {
public:
DeveloperToolsPolicyHandlerTest() {
handler_list_.AddHandler(std::make_unique<DeveloperToolsPolicyHandler>());
}
};
TEST_F(DeveloperToolsPolicyHandlerTest, NewPolicyOverridesLegacyPolicy) {
EXPECT_FALSE(store_->GetValue(prefs::kDevToolsAvailability, nullptr));
PolicyMap policy;
policy.Set(
key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(0 /*DeveloperToolsDisallowedForForceInstalledExtensions*/),
nullptr);
policy.Set(key::kDeveloperToolsDisabled, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(true),
nullptr);
UpdateProviderPolicy(policy);
const base::Value* value = nullptr;
ASSERT_TRUE(store_->GetValue(prefs::kDevToolsAvailability, &value));
EXPECT_EQ(
static_cast<int>(Availability::kDisallowedForForceInstalledExtensions),
value->GetInt());
#if BUILDFLAG(ENABLE_EXTENSIONS)
// No force-disabling of developer mode on extensions UI.
EXPECT_FALSE(store_->GetValue(prefs::kExtensionsUIDeveloperMode, nullptr));
#endif
}
TEST_F(DeveloperToolsPolicyHandlerTest, LegacyPolicyAppliesIfNewPolicyInvalid) {
EXPECT_FALSE(store_->GetValue(prefs::kDevToolsAvailability, nullptr));
PolicyMap policy;
policy.Set(key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(5 /*out of range*/), nullptr);
policy.Set(key::kDeveloperToolsDisabled, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(true),
nullptr);
UpdateProviderPolicy(policy);
const base::Value* value = nullptr;
ASSERT_TRUE(store_->GetValue(prefs::kDevToolsAvailability, &value));
EXPECT_EQ(static_cast<int>(Availability::kDisallowed), value->GetInt());
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Developer mode on extensions UI is also disabled.
const base::Value* extensions_ui_dev_mode_value = nullptr;
ASSERT_TRUE(store_->GetValue(prefs::kExtensionsUIDeveloperMode,
&extensions_ui_dev_mode_value));
EXPECT_FALSE(extensions_ui_dev_mode_value->GetBool());
#endif
}
TEST_F(DeveloperToolsPolicyHandlerTest, NewPolicyAppliesIfLegacyPolicyInvalid) {
EXPECT_FALSE(store_->GetValue(prefs::kDevToolsAvailability, nullptr));
PolicyMap policy;
policy.Set(key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(1 /*kAllowed*/), nullptr);
policy.Set(key::kDeveloperToolsDisabled, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(4 /*wrong type*/), nullptr);
UpdateProviderPolicy(policy);
const base::Value* value = nullptr;
ASSERT_TRUE(store_->GetValue(prefs::kDevToolsAvailability, &value));
EXPECT_EQ(static_cast<int>(Availability::kAllowed), value->GetInt());
}
TEST_F(DeveloperToolsPolicyHandlerTest, DisallowedForForceInstalledExtensions) {
EXPECT_FALSE(store_->GetValue(prefs::kDevToolsAvailability, nullptr));
PolicyMap policy;
policy.Set(
key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(0 /*DeveloperToolsDisallowedForForceInstalledExtensions*/),
nullptr);
UpdateProviderPolicy(policy);
const base::Value* value = nullptr;
ASSERT_TRUE(store_->GetValue(prefs::kDevToolsAvailability, &value));
EXPECT_EQ(
static_cast<int>(Availability::kDisallowedForForceInstalledExtensions),
value->GetInt());
#if BUILDFLAG(ENABLE_EXTENSIONS)
// No force-disabling of developer mode on extensions UI.
EXPECT_FALSE(store_->GetValue(prefs::kExtensionsUIDeveloperMode, nullptr));
#endif
}
TEST_F(DeveloperToolsPolicyHandlerTest, Allowed) {
EXPECT_FALSE(store_->GetValue(prefs::kDevToolsAvailability, nullptr));
PolicyMap policy;
policy.Set(key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(1 /*DeveloperToolsAllowed*/), nullptr);
UpdateProviderPolicy(policy);
const base::Value* value = nullptr;
ASSERT_TRUE(store_->GetValue(prefs::kDevToolsAvailability, &value));
EXPECT_EQ(static_cast<int>(Availability::kAllowed), value->GetInt());
#if BUILDFLAG(ENABLE_EXTENSIONS)
// No force-disabling of developer mode on extensions UI.
EXPECT_FALSE(store_->GetValue(prefs::kExtensionsUIDeveloperMode, nullptr));
#endif
}
TEST_F(DeveloperToolsPolicyHandlerTest, Disallowed) {
EXPECT_FALSE(store_->GetValue(prefs::kDevToolsAvailability, nullptr));
PolicyMap policy;
policy.Set(key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(2 /*Disallowed*/), nullptr);
UpdateProviderPolicy(policy);
const base::Value* value = nullptr;
ASSERT_TRUE(store_->GetValue(prefs::kDevToolsAvailability, &value));
EXPECT_EQ(static_cast<int>(Availability::kDisallowed), value->GetInt());
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Developer mode on extensions UI is also disabled.
const base::Value* extensions_ui_dev_mode_value = nullptr;
ASSERT_TRUE(store_->GetValue(prefs::kExtensionsUIDeveloperMode,
&extensions_ui_dev_mode_value));
EXPECT_FALSE(extensions_ui_dev_mode_value->GetBool());
#endif
}
TEST_F(DeveloperToolsPolicyHandlerTest, InvalidValue) {
EXPECT_FALSE(store_->GetValue(prefs::kDevToolsAvailability, nullptr));
PolicyMap policy;
policy.Set(key::kDeveloperToolsAvailability, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(5 /*out of range*/), nullptr);
UpdateProviderPolicy(policy);
EXPECT_FALSE(store_->GetValue(prefs::kDevToolsAvailability, nullptr));
#if BUILDFLAG(ENABLE_EXTENSIONS)
EXPECT_FALSE(store_->GetValue(prefs::kExtensionsUIDeveloperMode, nullptr));
#endif
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
struct TestParam {
Availability primary_profile_availability;
Availability secondary_profile_availability;
Availability expected_result;
};
// Tests static function of `DeveloperToolsPolicyHandler` requiring primary and
// secondary profiles.
class DeveloperToolsPolicyHandlerWithProfileTest
: public testing::TestWithParam<TestParam> {
public:
DeveloperToolsPolicyHandlerWithProfileTest()
: profile_manager_(TestingBrowserProcess::GetGlobal()) {}
void SetUp() override {
ASSERT_TRUE(profile_manager_.SetUp());
auto user_manager = std::make_unique<ash::FakeChromeUserManager>();
{
constexpr char kPrimaryProfileName[] = "primary_profile";
const AccountId account_id(AccountId::FromUserEmail(kPrimaryProfileName));
primary_profile_ = profile_manager_.CreateTestingProfile(
kPrimaryProfileName, /* is_main_profile= */ true);
user_manager->AddUserWithAffiliationAndTypeAndProfile(
account_id, /* is_affiliated= */ true,
user_manager::UserType::kRegular, primary_profile_);
user_manager->LoginUser(account_id);
}
{
constexpr char kSecondaryProfileName[] = "secondary_profile";
const AccountId account_id(
AccountId::FromUserEmail(kSecondaryProfileName));
secondary_profile_ =
profile_manager_.CreateTestingProfile(kSecondaryProfileName);
user_manager->AddUserWithAffiliationAndTypeAndProfile(
account_id, /* is_affiliated= */ true,
user_manager::UserType::kRegular, secondary_profile_);
}
scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>(
std::move(user_manager));
EXPECT_TRUE(ash::ProfileHelper::IsPrimaryProfile(primary_profile_));
EXPECT_FALSE(ash::ProfileHelper::IsPrimaryProfile(secondary_profile_));
}
void UpdatePrimaryProfileAvailability() {
primary_profile_->GetTestingPrefService()->SetManagedPref(
prefs::kDevToolsAvailability,
base::Value(static_cast<int>(GetParam().primary_profile_availability)));
}
void UpdateSecondaryProfileAvailability() {
secondary_profile_->GetTestingPrefService()->SetManagedPref(
prefs::kDevToolsAvailability,
base::Value(
static_cast<int>(GetParam().secondary_profile_availability)));
}
Availability expected_result() const { return GetParam().expected_result; }
protected:
content::BrowserTaskEnvironment task_environment_;
TestingProfileManager profile_manager_;
std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
raw_ptr<TestingProfile> primary_profile_;
raw_ptr<TestingProfile> secondary_profile_;
};
TEST_F(DeveloperToolsPolicyHandlerWithProfileTest,
GetEffectiveAvailabilityForced) {
EXPECT_EQ(
Availability::kDisallowedForForceInstalledExtensions,
DeveloperToolsPolicyHandler::GetEffectiveAvailability(primary_profile_));
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
command_line->AppendSwitch(switches::kForceDevToolsAvailable);
EXPECT_EQ(
Availability::kAllowed,
DeveloperToolsPolicyHandler::GetEffectiveAvailability(primary_profile_));
}
TEST_P(DeveloperToolsPolicyHandlerWithProfileTest,
GetEffectiveAvailabilityRestrictive) {
UpdatePrimaryProfileAvailability();
UpdateSecondaryProfileAvailability();
EXPECT_EQ(expected_result(),
DeveloperToolsPolicyHandler::GetEffectiveAvailability(
secondary_profile_));
}
INSTANTIATE_TEST_SUITE_P(
DeveloperToolsPolicyHandlerTest,
DeveloperToolsPolicyHandlerWithProfileTest,
::testing::Values(
TestParam(
/* primary_profile_availability= */ Availability::kAllowed,
/* secondary_profile_availability= */ Availability::kAllowed,
/* expected_result= */ Availability::kAllowed),
TestParam(
/* primary_profile_availability= */ Availability::kDisallowed,
/* secondary_profile_availability= */ Availability::kAllowed,
/* expected_result= */ Availability::kDisallowed),
TestParam(
/* primary_profile_availability= */ Availability::kAllowed,
/* secondary_profile_availability= */ Availability::kDisallowed,
/* expected_result= */ Availability::kDisallowed),
TestParam(
/* primary_profile_availability= */ Availability::kAllowed,
/* secondary_profile_availability= */
Availability::kDisallowedForForceInstalledExtensions,
/* expected_result= */
Availability::kDisallowedForForceInstalledExtensions),
TestParam(
/* primary_profile_availability= */ Availability::
kDisallowedForForceInstalledExtensions,
/* secondary_profile_availability= */ Availability::kAllowed,
/* expected_result= */
Availability::kDisallowedForForceInstalledExtensions),
TestParam(
/* primary_profile_availability= */ Availability::kDisallowed,
/* secondary_profile_availability= */
Availability::kDisallowedForForceInstalledExtensions,
/* expected_result= */ Availability::kDisallowed),
TestParam(
/* primary_profile_availability= */ Availability::
kDisallowedForForceInstalledExtensions,
/* secondary_profile_availability= */ Availability::kDisallowed,
/* expected_result= */ Availability::kDisallowed),
TestParam(
/* primary_profile_availability= */ Availability::kDisallowed,
/* secondary_profile_availability= */ Availability::kDisallowed,
/* expected_result= */ Availability::kDisallowed)));
#endif
} // namespace policy