1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/policy/lock_to_single_user_manager.h"
6
7 #include <memory>
8
9 #include "base/macros.h"
10 #include "base/memory/ptr_util.h"
11 #include "build/build_config.h"
12 #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
13 #include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
14 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
15 #include "chrome/browser/chromeos/settings/device_settings_service.h"
16 #include "chrome/browser/chromeos/settings/scoped_testing_cros_settings.h"
17 #include "chrome/browser/ui/app_list/arc/arc_app_test.h"
18 #include "chrome/test/base/browser_with_test_window_test.h"
19 #include "chromeos/dbus/cryptohome/fake_cryptohome_client.h"
20 #include "chromeos/dbus/dbus_thread_manager.h"
21 #include "chromeos/dbus/fake_concierge_client.h"
22 #include "chromeos/login/login_state/login_state.h"
23 #include "chromeos/login/session/session_termination_manager.h"
24 #include "chromeos/settings/cros_settings_names.h"
25 #include "components/account_id/account_id.h"
26 #include "components/arc/arc_service_manager.h"
27 #include "components/arc/arc_util.h"
28 #include "components/arc/test/fake_arc_session.h"
29 #include "components/policy/proto/chrome_device_policy.pb.h"
30 #include "components/user_manager/scoped_user_manager.h"
31
32 namespace policy {
33
34 class LockToSingleUserManagerTest : public BrowserWithTestWindowTest {
35 public:
36 LockToSingleUserManagerTest() = default;
37 ~LockToSingleUserManagerTest() override = default;
38
SetUp()39 void SetUp() override {
40 // This setter will initialize DBusThreadManager.
41 // This is required before ArcSessionManager's constructor calls
42 // DBusThreadManager::Get().
43 auto dbus_thread_manager_setter =
44 chromeos::DBusThreadManager::GetSetterForTesting();
45
46 arc::SetArcAvailableCommandLineForTesting(
47 base::CommandLine::ForCurrentProcess());
48 chromeos::LoginState::Initialize();
49 chromeos::CryptohomeClient::InitializeFake();
50 lock_to_single_user_manager_ = std::make_unique<LockToSingleUserManager>();
51
52 BrowserWithTestWindowTest::SetUp();
53
54 settings_helper_.ReplaceDeviceSettingsProviderWithStub();
55 arc::ArcSessionManager::SetUiEnabledForTesting(false);
56 arc_service_manager_ = std::make_unique<arc::ArcServiceManager>();
57 arc_session_manager_ = arc::CreateTestArcSessionManager(
58 std::make_unique<arc::ArcSessionRunner>(
59 base::BindRepeating(arc::FakeArcSession::Create)));
60
61 arc_service_manager_->set_browser_context(profile());
62
63 fake_concierge_client_ = new chromeos::FakeConciergeClient();
64 dbus_thread_manager_setter->SetConciergeClient(
65 base::WrapUnique(fake_concierge_client_));
66 }
67
TearDown()68 void TearDown() override {
69 // lock_to_single_user_manager has to be cleaned up first due to implicit
70 // dependency on ArcSessionManager.
71 lock_to_single_user_manager_.reset();
72
73 arc_session_manager_->Shutdown();
74 arc_session_manager_.reset();
75 arc_service_manager_->set_browser_context(nullptr);
76 arc_service_manager_.reset();
77 BrowserWithTestWindowTest::TearDown();
78 chromeos::CryptohomeClient::Shutdown();
79 chromeos::LoginState::Shutdown();
80 chromeos::DBusThreadManager::Shutdown();
81 }
82
LogInUser(bool is_affiliated)83 void LogInUser(bool is_affiliated) {
84 const AccountId account_id(AccountId::FromUserEmailGaiaId(
85 profile()->GetProfileUserName(), "1234567890"));
86 fake_user_manager_->AddUserWithAffiliation(account_id, is_affiliated);
87 fake_user_manager_->LoginUser(account_id);
88 // This step should be part of LoginUser(). There's a TODO to add it there,
89 // but it breaks many tests.
90 fake_user_manager_->SwitchActiveUser(account_id);
91
92 chromeos::LoginState::Get()->SetLoggedInState(
93 chromeos::LoginState::LOGGED_IN_ACTIVE,
94 chromeos::LoginState::LOGGED_IN_USER_REGULAR);
95
96 arc_session_manager_->SetProfile(profile());
97 arc_session_manager_->Initialize();
98 }
99
SetPolicyValue(int value)100 void SetPolicyValue(int value) {
101 settings_helper_.SetInteger(chromeos::kDeviceRebootOnUserSignout, value);
102 }
103
StartArc()104 void StartArc() { arc_session_manager_->StartArcForTesting(); }
StartedVm(bool expect_ok=true)105 void StartedVm(bool expect_ok = true) {
106 EXPECT_EQ(
107 expect_ok,
108 chromeos::SessionTerminationManager::Get()->IsLockedToSingleUser());
109
110 vm_tools::concierge::VmStartedSignal signal; // content is irrelevant
111 fake_concierge_client_->NotifyVmStarted(signal);
112 }
113
StartPluginVm()114 void StartPluginVm() {
115 base::RunLoop run_loop;
116 if (fake_concierge_client_->HasVmObservers())
117 lock_to_single_user_manager_->OnVmStarting();
118 run_loop.RunUntilIdle();
119 }
120
StartConciergeVm()121 void StartConciergeVm() {
122 base::RunLoop run_loop;
123 if (fake_concierge_client_->HasVmObservers())
124 lock_to_single_user_manager_->OnVmStarting();
125 run_loop.RunUntilIdle();
126 }
127
StartDbusVm()128 void StartDbusVm() {
129 base::RunLoop run_loop;
130 lock_to_single_user_manager_->DbusNotifyVmStarting();
131 run_loop.RunUntilIdle();
132 }
133
is_device_locked() const134 bool is_device_locked() const {
135 return chromeos::FakeCryptohomeClient::Get()
136 ->is_device_locked_to_single_user();
137 }
138
139 private:
140 chromeos::ScopedCrosSettingsTestHelper settings_helper_{
141 /* create_settings_service= */ false};
142 chromeos::FakeChromeUserManager* fake_user_manager_{
143 new chromeos::FakeChromeUserManager()};
144 user_manager::ScopedUserManager scoped_user_manager_{
145 base::WrapUnique(fake_user_manager_)};
146 std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
147 std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
148 // Required for initialization.
149 chromeos::SessionTerminationManager termination_manager_;
150 std::unique_ptr<LockToSingleUserManager> lock_to_single_user_manager_;
151 chromeos::FakeConciergeClient* fake_concierge_client_;
152
153 DISALLOW_COPY_AND_ASSIGN(LockToSingleUserManagerTest);
154 };
155
TEST_F(LockToSingleUserManagerTest,ArcSessionLockTest)156 TEST_F(LockToSingleUserManagerTest, ArcSessionLockTest) {
157 SetPolicyValue(
158 enterprise_management::DeviceRebootOnUserSignoutProto::ARC_SESSION);
159 LogInUser(false /* is_affiliated */);
160 EXPECT_FALSE(is_device_locked());
161 StartConciergeVm();
162 StartPluginVm();
163 StartDbusVm();
164 StartedVm(false);
165 EXPECT_FALSE(is_device_locked());
166 StartArc();
167 EXPECT_TRUE(is_device_locked());
168 }
169
TEST_F(LockToSingleUserManagerTest,ConciergeStartLockTest)170 TEST_F(LockToSingleUserManagerTest, ConciergeStartLockTest) {
171 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
172 VM_STARTED_OR_ARC_SESSION);
173 LogInUser(false /* is_affiliated */);
174 EXPECT_FALSE(is_device_locked());
175 StartConciergeVm();
176 StartedVm();
177 EXPECT_TRUE(is_device_locked());
178 }
179
TEST_F(LockToSingleUserManagerTest,PluginVmStartLockTest)180 TEST_F(LockToSingleUserManagerTest, PluginVmStartLockTest) {
181 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
182 VM_STARTED_OR_ARC_SESSION);
183 LogInUser(false /* is_affiliated */);
184 EXPECT_FALSE(is_device_locked());
185 StartPluginVm();
186 StartedVm();
187 EXPECT_TRUE(is_device_locked());
188 }
189
TEST_F(LockToSingleUserManagerTest,DbusVmStartLockTest)190 TEST_F(LockToSingleUserManagerTest, DbusVmStartLockTest) {
191 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
192 VM_STARTED_OR_ARC_SESSION);
193 LogInUser(false /* is_affiliated */);
194 EXPECT_FALSE(is_device_locked());
195 StartDbusVm();
196 StartedVm();
197 EXPECT_TRUE(is_device_locked());
198 }
199
TEST_F(LockToSingleUserManagerTest,UnexpectedVmStartLockTest)200 TEST_F(LockToSingleUserManagerTest, UnexpectedVmStartLockTest) {
201 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
202 VM_STARTED_OR_ARC_SESSION);
203 LogInUser(false /* is_affiliated */);
204 EXPECT_FALSE(is_device_locked());
205 StartedVm(false);
206 EXPECT_TRUE(is_device_locked());
207 }
208
TEST_F(LockToSingleUserManagerTest,ArcSessionOrVmLockTest)209 TEST_F(LockToSingleUserManagerTest, ArcSessionOrVmLockTest) {
210 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::
211 VM_STARTED_OR_ARC_SESSION);
212 LogInUser(false /* is_affiliated */);
213 EXPECT_FALSE(is_device_locked());
214 StartArc();
215 EXPECT_TRUE(is_device_locked());
216 }
217
TEST_F(LockToSingleUserManagerTest,AlwaysLockTest)218 TEST_F(LockToSingleUserManagerTest, AlwaysLockTest) {
219 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::ALWAYS);
220 LogInUser(false /* is_affiliated */);
221 EXPECT_TRUE(is_device_locked());
222 }
223
TEST_F(LockToSingleUserManagerTest,NeverLockTest)224 TEST_F(LockToSingleUserManagerTest, NeverLockTest) {
225 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::NEVER);
226 LogInUser(false /* is_affiliated */);
227 StartPluginVm();
228 StartConciergeVm();
229 StartArc();
230 StartDbusVm();
231 StartedVm(false);
232 EXPECT_FALSE(is_device_locked());
233 }
234
TEST_F(LockToSingleUserManagerTest,DbusCallErrorTest)235 TEST_F(LockToSingleUserManagerTest, DbusCallErrorTest) {
236 chromeos::FakeCryptohomeClient::Get()->set_cryptohome_error(
237 cryptohome::CRYPTOHOME_ERROR_KEY_NOT_FOUND);
238 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::ALWAYS);
239 LogInUser(false /* is_affiliated */);
240 EXPECT_FALSE(is_device_locked());
241 }
242
TEST_F(LockToSingleUserManagerTest,DoesNotAffectAffiliatedUsersTest)243 TEST_F(LockToSingleUserManagerTest, DoesNotAffectAffiliatedUsersTest) {
244 SetPolicyValue(enterprise_management::DeviceRebootOnUserSignoutProto::ALWAYS);
245 LogInUser(true /* is_affiliated */);
246 EXPECT_FALSE(is_device_locked());
247 }
248
TEST_F(LockToSingleUserManagerTest,FutureTest)249 TEST_F(LockToSingleUserManagerTest, FutureTest) {
250 // Unknown values should be the same as ALWAYS
251 SetPolicyValue(100);
252 LogInUser(false /* is_affiliated */);
253 EXPECT_TRUE(is_device_locked());
254 }
255
256 } // namespace policy
257