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