blob: c0cda287084e13f9fb656dbe9835cf0985e06fc1 [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/chromeos/policy/lock_to_single_user_manager.h"
#include <memory>
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
#include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#include "chrome/browser/chromeos/settings/scoped_testing_cros_settings.h"
#include "chrome/browser/ui/app_list/arc/arc_app_test.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chromeos/dbus/cryptohome/fake_cryptohome_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_concierge_client.h"
#include "chromeos/login/login_state/login_state.h"
#include "chromeos/login/session/session_termination_manager.h"
#include "chromeos/settings/cros_settings_names.h"
#include "components/account_id/account_id.h"
#include "components/arc/arc_service_manager.h"
#include "components/arc/arc_util.h"
#include "components/arc/test/fake_arc_session.h"
#include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/user_manager/scoped_user_manager.h"
namespace policy {
class LockToSingleUserManagerTest : public BrowserWithTestWindowTest {
public:
LockToSingleUserManagerTest() = default;
~LockToSingleUserManagerTest() override = default;
void SetUp() override {
// This setter will initialize DBusThreadManager.
// This is required before ArcSessionManager's constructor calls
// DBusThreadManager::Get().
auto dbus_thread_manager_setter =
chromeos::DBusThreadManager::GetSetterForTesting();
arc::SetArcAvailableCommandLineForTesting(
base::CommandLine::ForCurrentProcess());
chromeos::LoginState::Initialize();
chromeos::CryptohomeClient::InitializeFake();
lock_to_single_user_manager_ = std::make_unique<LockToSingleUserManager>();
BrowserWithTestWindowTest::SetUp();
settings_helper_.ReplaceDeviceSettingsProviderWithStub();
arc::ArcSessionManager::SetUiEnabledForTesting(false);
arc_service_manager_ = std::make_unique<arc::ArcServiceManager>();
arc_session_manager_ = arc::CreateTestArcSessionManager(
std::make_unique<arc::ArcSessionRunner>(
base::BindRepeating(arc::FakeArcSession::Create)));
arc_service_manager_->set_browser_context(profile());
fake_concierge_client_ = new chromeos::FakeConciergeClient();
dbus_thread_manager_setter->SetConciergeClient(
base::WrapUnique(fake_concierge_client_));
}
void TearDown() override {
// lock_to_single_user_manager has to be cleaned up first due to implicit
// dependency on ArcSessionManager.
lock_to_single_user_manager_.reset();
arc_session_manager_->Shutdown();
arc_session_manager_.reset();
arc_service_manager_->set_browser_context(nullptr);
arc_service_manager_.reset();
BrowserWithTestWindowTest::TearDown();
chromeos::CryptohomeClient::Shutdown();
chromeos::LoginState::Shutdown();
chromeos::DBusThreadManager::Shutdown();
}
void LogInUser(bool is_affiliated) {
const AccountId account_id(AccountId::FromUserEmailGaiaId(
profile()->GetProfileUserName(), "1234567890"));
fake_user_manager_->AddUserWithAffiliation(account_id, is_affiliated);
fake_user_manager_->LoginUser(account_id);
// This step should be part of LoginUser(). There's a TODO to add it there,
// but it breaks many tests.
fake_user_manager_->SwitchActiveUser(account_id);
chromeos::LoginState::Get()->SetLoggedInState(
chromeos::LoginState::LOGGED_IN_ACTIVE,
chromeos::LoginState::LOGGED_IN_USER_REGULAR);
arc_session_manager_->SetProfile(profile());
arc_session_manager_->Initialize();
}
void SetPolicyValue(int value) {
settings_helper_.SetInteger(chromeos::kDeviceRebootOnUserSignout, value);
}
void StartArc() { arc_session_manager_->StartArcForTesting(); }
void StartedVm(bool expect_ok = true) {
EXPECT_EQ(
expect_ok,
chromeos::SessionTerminationManager::Get()->IsLockedToSingleUser());
vm_tools::concierge::VmStartedSignal signal; // content is irrelevant
fake_concierge_client_->NotifyVmStarted(signal);
}
void StartPluginVm() {
base::RunLoop run_loop;
if (fake_concierge_client_->HasVmObservers())
lock_to_single_user_manager_->OnVmStarting();
run_loop.RunUntilIdle();
}
void StartConciergeVm() {
base::RunLoop run_loop;
if (fake_concierge_client_->HasVmObservers())
lock_to_single_user_manager_->OnVmStarting();
run_loop.RunUntilIdle();
}
void StartDbusVm() {
base::RunLoop run_loop;
lock_to_single_user_manager_->DbusNotifyVmStarting();
run_loop.RunUntilIdle();
}
bool is_device_locked() const {
return chromeos::FakeCryptohomeClient::Get()
->is_device_locked_to_single_user();
}
private:
chromeos::ScopedCrosSettingsTestHelper settings_helper_{
/* create_settings_service= */ false};
chromeos::FakeChromeUserManager* fake_user_manager_{
new chromeos::FakeChromeUserManager()};
user_manager::ScopedUserManager scoped_user_manager_{
base::WrapUnique(fake_user_manager_)};
std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
// Required for initialization.
chromeos::SessionTerminationManager termination_manager_;
std::unique_ptr<LockToSingleUserManager> lock_to_single_user_manager_;
chromeos::FakeConciergeClient* fake_concierge_client_;
DISALLOW_COPY_AND_ASSIGN(LockToSingleUserManagerTest);
};
TEST_F(LockToSingleUserManagerTest, ArcSessionLockTest) {
SetPolicyValue(
enterprise_management::DeviceRebootOnUserSignoutProto::ARC_SESSION);
LogInUser(false /* is_affiliated */);
EXPECT_FALSE(is_device_locked());
StartConciergeVm();
StartPluginVm();
StartDbusVm();
StartedVm(false);
EXPECT_FALSE(is_device_locked());
StartArc();
EXPECT_TRUE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, ConciergeStartLockTest) {
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
VM_STARTED_OR_ARC_SESSION);
LogInUser(false /* is_affiliated */);
EXPECT_FALSE(is_device_locked());
StartConciergeVm();
StartedVm();
EXPECT_TRUE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, PluginVmStartLockTest) {
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
VM_STARTED_OR_ARC_SESSION);
LogInUser(false /* is_affiliated */);
EXPECT_FALSE(is_device_locked());
StartPluginVm();
StartedVm();
EXPECT_TRUE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, DbusVmStartLockTest) {
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
VM_STARTED_OR_ARC_SESSION);
LogInUser(false /* is_affiliated */);
EXPECT_FALSE(is_device_locked());
StartDbusVm();
StartedVm();
EXPECT_TRUE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, UnexpectedVmStartLockTest) {
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
VM_STARTED_OR_ARC_SESSION);
LogInUser(false /* is_affiliated */);
EXPECT_FALSE(is_device_locked());
StartedVm(false);
EXPECT_TRUE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, ArcSessionOrVmLockTest) {
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
VM_STARTED_OR_ARC_SESSION);
LogInUser(false /* is_affiliated */);
EXPECT_FALSE(is_device_locked());
StartArc();
EXPECT_TRUE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, AlwaysLockTest) {
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::ALWAYS);
LogInUser(false /* is_affiliated */);
EXPECT_TRUE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, NeverLockTest) {
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::NEVER);
LogInUser(false /* is_affiliated */);
StartPluginVm();
StartConciergeVm();
StartArc();
StartDbusVm();
StartedVm(false);
EXPECT_FALSE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, DbusCallErrorTest) {
chromeos::FakeCryptohomeClient::Get()->set_cryptohome_error(
cryptohome::CRYPTOHOME_ERROR_KEY_NOT_FOUND);
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::ALWAYS);
LogInUser(false /* is_affiliated */);
EXPECT_FALSE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, DoesNotAffectAffiliatedUsersTest) {
SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::ALWAYS);
LogInUser(true /* is_affiliated */);
EXPECT_FALSE(is_device_locked());
}
TEST_F(LockToSingleUserManagerTest, FutureTest) {
// Unknown values should be the same as ALWAYS
SetPolicyValue(100);
LogInUser(false /* is_affiliated */);
EXPECT_TRUE(is_device_locked());
}
} // namespace policy