blob: a766b01c03aabe2bddc35097eb9a037ded487be5 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include "base/check.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/ash/app_mode/test/kiosk_mixin.h"
#include "chrome/browser/ash/app_mode/test/kiosk_test_utils.h"
#include "chrome/browser/ash/login/test/scoped_policy_update.h"
#include "chrome/browser/ash/policy/core/device_local_account.h"
#include "chrome/test/base/mixin_based_in_process_browser_test.h"
#include "chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.h"
#include "components/policy/proto/chrome_device_policy.pb.h"
#include "content/public/test/browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ash {
using kiosk::test::CachePolicy;
using kiosk::test::TheKioskApp;
using kiosk::test::WaitKioskLaunched;
using KioskEphemeralMode = policy::DeviceLocalAccount::EphemeralMode;
namespace {
// Possible values of the `EphemeralUsersEnabled` policy.
enum class DeviceEphemeralUsersPolicy { kUnset, kEnabled, kDisabled };
// Whether the Kiosk session should be ephemeral based on the given policies.
bool KioskShouldBeEphemeral(DeviceEphemeralUsersPolicy device_ephemeral,
KioskEphemeralMode kiosk_ephemeral) {
switch (kiosk_ephemeral) {
case KioskEphemeralMode::kUnset:
case KioskEphemeralMode::kFollowDeviceWidePolicy:
return device_ephemeral == DeviceEphemeralUsersPolicy::kEnabled;
case KioskEphemeralMode::kDisable:
return false;
case KioskEphemeralMode::kEnable:
return true;
}
}
auto ToPolicyProtoValue(KioskEphemeralMode kiosk_ephemeral) {
switch (kiosk_ephemeral) {
case KioskEphemeralMode::kUnset:
return enterprise_management::
DeviceLocalAccountInfoProto_EphemeralMode_EPHEMERAL_MODE_UNSET;
case KioskEphemeralMode::kFollowDeviceWidePolicy:
return enterprise_management::
DeviceLocalAccountInfoProto_EphemeralMode_EPHEMERAL_MODE_FOLLOW_DEVICE_WIDE_POLICY;
case KioskEphemeralMode::kDisable:
return enterprise_management::
DeviceLocalAccountInfoProto_EphemeralMode_EPHEMERAL_MODE_DISABLE;
case KioskEphemeralMode::kEnable:
return enterprise_management::
DeviceLocalAccountInfoProto_EphemeralMode_EPHEMERAL_MODE_ENABLE;
}
}
// Sets the `DeviceEphemeralUsersEnabled` policy in `scoped_update`.
void UpdateDevicePolicy(ScopedDevicePolicyUpdate& scoped_update,
DeviceEphemeralUsersPolicy device_ephemeral) {
if (device_ephemeral == DeviceEphemeralUsersPolicy::kUnset) {
return;
}
scoped_update.policy_payload()
->mutable_ephemeral_users_enabled()
->set_ephemeral_users_enabled(device_ephemeral ==
DeviceEphemeralUsersPolicy::kEnabled);
}
// Sets the `EphemeralMode` policy of device local accounts in `scoped_update`
// for the given `account_id`.
void UpdateDeviceLocalAccountPolicy(ScopedDevicePolicyUpdate& scoped_update,
std::string_view account_id,
KioskEphemeralMode kiosk_ephemeral) {
if (kiosk_ephemeral == KioskEphemeralMode::kUnset) {
return;
}
auto* accounts = scoped_update.policy_payload()
->mutable_device_local_accounts()
->mutable_account();
auto account =
std::ranges::find_if(*accounts, [&account_id](const auto& account) {
return account.account_id() == account_id;
});
CHECK(account != accounts->end());
account->set_ephemeral_mode(ToPolicyProtoValue(kiosk_ephemeral));
}
std::string_view ToString(DeviceEphemeralUsersPolicy device_ephemeral) {
switch (device_ephemeral) {
case DeviceEphemeralUsersPolicy::kUnset:
return "Unset";
case DeviceEphemeralUsersPolicy::kEnabled:
return "Enabled";
case DeviceEphemeralUsersPolicy::kDisabled:
return "Disabled";
}
}
std::string_view ToString(KioskEphemeralMode kiosk_ephemeral) {
switch (kiosk_ephemeral) {
case policy::DeviceLocalAccount::EphemeralMode::kUnset:
return "Unset";
case policy::DeviceLocalAccount::EphemeralMode::kFollowDeviceWidePolicy:
return "FollowDeviceWidePolicy";
case policy::DeviceLocalAccount::EphemeralMode::kDisable:
return "Disable";
case policy::DeviceLocalAccount::EphemeralMode::kEnable:
return "Enable";
}
}
// Helper alias for the tuple used to combine test parameters.
using TestParam = std::
tuple<KioskMixin::Config, DeviceEphemeralUsersPolicy, KioskEphemeralMode>;
// Returns the `TestParam` name to be used in gtest.
std::string ParamName(const testing::TestParamInfo<TestParam>& info) {
auto [config, device_ephemeral, kiosk_ephemeral] = info.param;
auto config_name =
config.name.value_or(base::StringPrintf("%zu", info.index));
return base::StrCat({config_name, "WithDeviceEphemeralUsers",
ToString(device_ephemeral), "AndKioskEphemeralMode",
ToString(kiosk_ephemeral)});
}
} // namespace
class EphemeralKioskTest : public MixinBasedInProcessBrowserTest,
public testing::WithParamInterface<TestParam> {
public:
EphemeralKioskTest(const EphemeralKioskTest&) = delete;
EphemeralKioskTest& operator=(const EphemeralKioskTest&) = delete;
EphemeralKioskTest() = default;
DeviceEphemeralUsersPolicy DeviceEphemeralUsersParam() const {
return std::get<DeviceEphemeralUsersPolicy>(GetParam());
}
KioskEphemeralMode KioskEphemeralModeParam() const {
return std::get<KioskEphemeralMode>(GetParam());
}
const KioskMixin::Config& ConfigParam() const {
return std::get<KioskMixin::Config>(GetParam());
}
void SetUpInProcessBrowserTestFixture() override {
MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
std::string_view kiosk_account_id =
ConfigParam().auto_launch_account_id.value().value();
auto update = kiosk_.device_state_mixin().RequestDevicePolicyUpdate();
UpdateDevicePolicy(*update, DeviceEphemeralUsersParam());
UpdateDeviceLocalAccountPolicy(*update, kiosk_account_id,
KioskEphemeralModeParam());
}
void SetUpOnMainThread() override {
MixinBasedInProcessBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(WaitKioskLaunched());
}
KioskMixin kiosk_{&mixin_host_,
/*cached_configuration=*/ConfigParam()};
};
IN_PROC_BROWSER_TEST_P(EphemeralKioskTest,
KioskIsEphemeralWhenPoliciesConfigureIt) {
bool kiosk_should_be_ephemeral = KioskShouldBeEphemeral(
DeviceEphemeralUsersParam(), KioskEphemeralModeParam());
EXPECT_EQ(
kiosk_should_be_ephemeral,
FakeUserDataAuthClient::TestApi::Get()->IsCurrentSessionEphemeral());
}
INSTANTIATE_TEST_SUITE_P(
All,
EphemeralKioskTest,
testing::Combine(
testing::ValuesIn(KioskMixin::ConfigsToAutoLaunchEachAppType()),
testing::Values(DeviceEphemeralUsersPolicy::kUnset,
DeviceEphemeralUsersPolicy::kEnabled,
DeviceEphemeralUsersPolicy::kDisabled),
testing::Values(KioskEphemeralMode::kUnset,
KioskEphemeralMode::kFollowDeviceWidePolicy,
KioskEphemeralMode::kDisable,
KioskEphemeralMode::kEnable)),
ParamName);
} // namespace ash