blob: 34f76403b40c8657c1b032dd316935497aaa68f9 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/crostini/crostini_features.h"
#include "ash/constants/ash_features.h"
#include "base/callback.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/ash/crostini/crostini_pref_names.h"
#include "chrome/browser/ash/crostini/fake_crostini_features.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/testing_profile.h"
#include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/prefs/pref_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/user_manager/fake_user_manager.h"
#include "components/user_manager/scoped_user_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace crostini {
TEST(CrostiniFeaturesTest, TestFakeReplaces) {
CrostiniFeatures* original = CrostiniFeatures::Get();
{
FakeCrostiniFeatures crostini_features;
EXPECT_NE(original, CrostiniFeatures::Get());
EXPECT_EQ(&crostini_features, CrostiniFeatures::Get());
}
EXPECT_EQ(original, CrostiniFeatures::Get());
}
TEST(CrostiniFeaturesTest, TestExportImportUIAllowed) {
content::BrowserTaskEnvironment task_environment;
TestingProfile profile;
FakeCrostiniFeatures crostini_features;
// Set up for success.
crostini_features.set_is_allowed_now(true);
profile.GetPrefs()->SetBoolean(
crostini::prefs::kUserCrostiniExportImportUIAllowedByPolicy, true);
// Success.
EXPECT_TRUE(crostini_features.IsExportImportUIAllowed(&profile));
// Crostini UI not allowed.
crostini_features.set_is_allowed_now(false);
EXPECT_FALSE(crostini_features.IsExportImportUIAllowed(&profile));
crostini_features.set_is_allowed_now(true);
// Pref off.
profile.GetPrefs()->SetBoolean(
crostini::prefs::kUserCrostiniExportImportUIAllowedByPolicy, false);
EXPECT_FALSE(crostini_features.IsExportImportUIAllowed(&profile));
}
TEST(CrostiniFeaturesTest, TestRootAccessAllowed) {
content::BrowserTaskEnvironment task_environment;
TestingProfile profile;
FakeCrostiniFeatures crostini_features;
base::test::ScopedFeatureList scoped_feature_list;
// Set up for success.
crostini_features.set_is_allowed_now(true);
scoped_feature_list.InitWithFeatures(
{features::kCrostiniAdvancedAccessControls}, {});
profile.GetPrefs()->SetBoolean(
crostini::prefs::kUserCrostiniRootAccessAllowedByPolicy, true);
// Success.
EXPECT_TRUE(crostini_features.IsRootAccessAllowed(&profile));
// Pref off.
profile.GetPrefs()->SetBoolean(
crostini::prefs::kUserCrostiniRootAccessAllowedByPolicy, false);
EXPECT_FALSE(crostini_features.IsRootAccessAllowed(&profile));
// Feature disabled.
{
base::test::ScopedFeatureList feature_list_disabled;
feature_list_disabled.InitWithFeatures(
{}, {features::kCrostiniAdvancedAccessControls});
EXPECT_TRUE(crostini_features.IsRootAccessAllowed(&profile));
}
}
class CrostiniFeaturesAllowedTest : public testing::Test {
protected:
CrostiniFeaturesAllowedTest()
: user_manager_(new ash::FakeChromeUserManager()),
scoped_user_manager_(base::WrapUnique(user_manager_)) {}
void SetUp() override {
scoped_feature_list_.InitWithFeatures({features::kCrostini}, {});
}
void AddUserWithAffiliation(bool is_affiliated) {
AccountId account_id =
AccountId::FromUserEmail(profile_.GetProfileUserName());
user_manager_->AddUserWithAffiliation(account_id, is_affiliated);
user_manager_->LoginUser(account_id);
}
content::BrowserTaskEnvironment task_environment_;
TestingProfile profile_;
FakeCrostiniFeatures crostini_features_;
base::test::ScopedFeatureList scoped_feature_list_;
ash::FakeChromeUserManager* user_manager_;
user_manager::ScopedUserManager scoped_user_manager_;
};
TEST_F(CrostiniFeaturesAllowedTest, TestDefaultUnmanagedBehaviour) {
AddUserWithAffiliation(false);
std::string reason;
bool crostini_is_allowed_now =
crostini_features_.IsAllowedNow(&profile_, &reason);
EXPECT_TRUE(crostini_is_allowed_now);
}
TEST_F(CrostiniFeaturesAllowedTest, TestDefaultAffiliatedUserBehaviour) {
AddUserWithAffiliation(true);
std::string reason;
bool crostini_is_allowed_now =
crostini_features_.IsAllowedNow(&profile_, &reason);
EXPECT_FALSE(crostini_is_allowed_now);
EXPECT_EQ(reason,
"Affiliated user is not allowed to run Crostini by default.");
}
TEST_F(CrostiniFeaturesAllowedTest, TestPolicyAffiliatedUserBehaviour) {
AddUserWithAffiliation(true);
profile_.GetTestingPrefService()->SetManagedPref(
crostini::prefs::kUserCrostiniAllowedByPolicy,
std::make_unique<base::Value>(true));
std::string reason;
bool crostini_is_allowed_now =
crostini_features_.IsAllowedNow(&profile_, &reason);
EXPECT_TRUE(crostini_is_allowed_now);
}
class CrostiniFeaturesAdbSideloadingTest : public testing::Test {
protected:
CrostiniFeaturesAdbSideloadingTest()
: user_manager_(new ash::FakeChromeUserManager()),
scoped_user_manager_(base::WrapUnique(user_manager_)) {}
void SetFeatureFlag(bool is_enabled) {
if (is_enabled) {
scoped_feature_list_.InitWithFeatures(
{chromeos::features::kArcManagedAdbSideloadingSupport}, {});
} else {
scoped_feature_list_.InitWithFeatures(
{}, {chromeos::features::kArcManagedAdbSideloadingSupport});
}
}
void AddChildUser() {
AccountId account_id =
AccountId::FromUserEmail(profile_.GetProfileUserName());
auto* const user = user_manager_->AddChildUser(account_id);
user_manager_->UserLoggedIn(account_id, user->username_hash(),
/*browser_restart=*/false,
/*is_child=*/true);
}
void AddOwnerUser() {
AccountId account_id =
AccountId::FromUserEmail(profile_.GetProfileUserName());
user_manager_->AddUser(account_id);
user_manager_->LoginUser(account_id);
user_manager_->SetOwnerId(account_id);
}
void AddUserWithAffiliation(bool is_affiliated) {
AccountId account_id =
AccountId::FromUserEmail(profile_.GetProfileUserName());
user_manager_->AddUserWithAffiliation(account_id, is_affiliated);
user_manager_->LoginUser(account_id);
}
void SetManagedUser(bool is_managed) {
profile_.GetProfilePolicyConnector()->OverrideIsManagedForTesting(
is_managed);
}
void SetDeviceToConsumerOwned() {
profile_.ScopedCrosSettingsTestHelper()
->InstallAttributes()
->SetConsumerOwned();
}
void SetDeviceToEnterpriseManaged() {
profile_.ScopedCrosSettingsTestHelper()
->InstallAttributes()
->SetCloudManaged("domain.com", "device_id");
}
void AllowAdbSideloadingByDevicePolicy() {
scoped_settings_helper_.ReplaceDeviceSettingsProviderWithStub();
scoped_settings_helper_.SetInteger(
chromeos::kDeviceCrostiniArcAdbSideloadingAllowed,
enterprise_management::DeviceCrostiniArcAdbSideloadingAllowedProto::
ALLOW_FOR_AFFILIATED_USERS);
}
void DisallowAdbSideloadingByDevicePolicy() {
scoped_settings_helper_.ReplaceDeviceSettingsProviderWithStub();
scoped_settings_helper_.SetInteger(
chromeos::kDeviceCrostiniArcAdbSideloadingAllowed,
enterprise_management::DeviceCrostiniArcAdbSideloadingAllowedProto::
DISALLOW);
}
void AllowAdbSideloadingByUserPolicy() {
profile_.GetPrefs()->SetInteger(
crostini::prefs::kCrostiniArcAdbSideloadingUserPref,
static_cast<int>(CrostiniArcAdbSideloadingUserAllowanceMode::kAllow));
}
void DisallowAdbSideloadingByUserPolicy() {
profile_.GetPrefs()->SetInteger(
crostini::prefs::kCrostiniArcAdbSideloadingUserPref,
static_cast<int>(
CrostiniArcAdbSideloadingUserAllowanceMode::kDisallow));
}
void AssertCanChangeAdbSideloading(bool expected_can_change) {
base::RunLoop run_loop;
crostini_features_.CanChangeAdbSideloading(
&profile_, base::BindLambdaForTesting([&](bool callback_can_change) {
EXPECT_EQ(callback_can_change, expected_can_change);
run_loop.Quit();
}));
run_loop.Run();
}
content::BrowserTaskEnvironment task_environment_;
TestingProfile profile_;
FakeCrostiniFeatures crostini_features_;
base::test::ScopedFeatureList scoped_feature_list_;
ash::ScopedCrosSettingsTestHelper scoped_settings_helper_{
/* create_settings_service=*/false};
ash::FakeChromeUserManager* user_manager_;
user_manager::ScopedUserManager scoped_user_manager_;
};
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingChildUser) {
AddChildUser();
AssertCanChangeAdbSideloading(false);
}
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingManagedDisabledFeatureFlag) {
SetFeatureFlag(false);
AssertCanChangeAdbSideloading(false);
}
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingManagedDisallowedDevicePolicy) {
SetFeatureFlag(true);
SetDeviceToEnterpriseManaged();
SetManagedUser(true);
DisallowAdbSideloadingByDevicePolicy();
AssertCanChangeAdbSideloading(false);
}
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingManagedUnaffiliatedUser) {
SetFeatureFlag(true);
SetDeviceToEnterpriseManaged();
SetManagedUser(true);
AllowAdbSideloadingByDevicePolicy();
AddUserWithAffiliation(false);
AssertCanChangeAdbSideloading(false);
}
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingManagedDisallowedUserPolicy) {
SetFeatureFlag(true);
SetDeviceToEnterpriseManaged();
SetManagedUser(true);
AllowAdbSideloadingByDevicePolicy();
AddUserWithAffiliation(true);
DisallowAdbSideloadingByUserPolicy();
AssertCanChangeAdbSideloading(false);
}
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingManagedAllowedUserPolicy) {
SetFeatureFlag(true);
SetDeviceToEnterpriseManaged();
SetManagedUser(true);
AllowAdbSideloadingByDevicePolicy();
AddUserWithAffiliation(true);
AllowAdbSideloadingByUserPolicy();
AssertCanChangeAdbSideloading(true);
}
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingOwnerProfile) {
SetDeviceToConsumerOwned();
SetManagedUser(false);
AddOwnerUser();
AssertCanChangeAdbSideloading(true);
}
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingOwnerProfileManagedUserDisallowed) {
SetFeatureFlag(true);
SetDeviceToConsumerOwned();
SetManagedUser(true);
AddOwnerUser();
DisallowAdbSideloadingByUserPolicy();
AssertCanChangeAdbSideloading(false);
}
TEST_F(CrostiniFeaturesAdbSideloadingTest,
TestCanChangeAdbSideloadingOwnerProfileManagedUserAllowed) {
SetFeatureFlag(true);
SetDeviceToConsumerOwned();
SetManagedUser(true);
AddOwnerUser();
AllowAdbSideloadingByUserPolicy();
AssertCanChangeAdbSideloading(true);
}
TEST(CrostiniFeaturesTest, TestPortForwardingAllowed) {
content::BrowserTaskEnvironment task_environment;
TestingProfile profile;
FakeCrostiniFeatures crostini_features;
// Default case.
EXPECT_TRUE(crostini_features.IsPortForwardingAllowed(&profile));
// Set pref to true.
profile.GetTestingPrefService()->SetManagedPref(
crostini::prefs::kCrostiniPortForwardingAllowedByPolicy,
std::make_unique<base::Value>(true));
// Allowed.
EXPECT_TRUE(crostini_features.IsPortForwardingAllowed(&profile));
}
TEST(CrostiniFeaturesTest, TestPortForwardingDisallowed) {
content::BrowserTaskEnvironment task_environment;
TestingProfile profile;
FakeCrostiniFeatures crostini_features;
// Set pref to false.
profile.GetTestingPrefService()->SetManagedPref(
crostini::prefs::kCrostiniPortForwardingAllowedByPolicy,
std::make_unique<base::Value>(false));
// Disallowed.
EXPECT_FALSE(crostini_features.IsPortForwardingAllowed(&profile));
}
} // namespace crostini