1 // Copyright 2014 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 "chromeos/components/proximity_auth/proximity_auth_system.h"
6
7 #include "base/command_line.h"
8 #include "base/test/scoped_feature_list.h"
9 #include "base/test/test_simple_task_runner.h"
10 #include "base/threading/thread_task_runner_handle.h"
11 #include "chromeos/components/multidevice/logging/logging.h"
12 #include "chromeos/components/multidevice/remote_device_ref.h"
13 #include "chromeos/components/multidevice/remote_device_test_util.h"
14 #include "chromeos/components/multidevice/software_feature_state.h"
15 #include "chromeos/components/proximity_auth/fake_lock_handler.h"
16 #include "chromeos/components/proximity_auth/fake_remote_device_life_cycle.h"
17 #include "chromeos/components/proximity_auth/mock_proximity_auth_client.h"
18 #include "chromeos/components/proximity_auth/proximity_auth_profile_pref_manager.h"
19 #include "chromeos/components/proximity_auth/unlock_manager.h"
20 #include "chromeos/constants/chromeos_features.h"
21 #include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
22 #include "chromeos/services/secure_channel/public/cpp/client/fake_secure_channel_client.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 using testing::_;
27 using testing::AnyNumber;
28 using testing::AtLeast;
29 using testing::InSequence;
30 using testing::NiceMock;
31 using testing::NotNull;
32 using testing::Return;
33 using testing::SaveArg;
34
35 namespace proximity_auth {
36
37 namespace {
38
39 const char kUser1[] = "user1";
40 const char kUser2[] = "user2";
41
CompareRemoteDeviceRefLists(const chromeos::multidevice::RemoteDeviceRefList & list1,const chromeos::multidevice::RemoteDeviceRefList & list2)42 void CompareRemoteDeviceRefLists(
43 const chromeos::multidevice::RemoteDeviceRefList& list1,
44 const chromeos::multidevice::RemoteDeviceRefList& list2) {
45 ASSERT_EQ(list1.size(), list2.size());
46 for (size_t i = 0; i < list1.size(); ++i) {
47 chromeos::multidevice::RemoteDeviceRef device1 = list1[i];
48 chromeos::multidevice::RemoteDeviceRef device2 = list2[i];
49 EXPECT_EQ(device1.public_key(), device2.public_key());
50 }
51 }
52
53 // Creates a RemoteDeviceRef object for |user_id| with |name|.
CreateRemoteDevice(const std::string & user_email,const std::string & name)54 chromeos::multidevice::RemoteDeviceRef CreateRemoteDevice(
55 const std::string& user_email,
56 const std::string& name) {
57 return chromeos::multidevice::RemoteDeviceRefBuilder()
58 .SetUserEmail(user_email)
59 .SetName(name)
60 .Build();
61 }
62
63 // Mock implementation of UnlockManager.
64 class MockUnlockManager : public UnlockManager {
65 public:
MockUnlockManager()66 MockUnlockManager() {}
~MockUnlockManager()67 ~MockUnlockManager() override {}
68 MOCK_METHOD0(IsUnlockAllowed, bool());
69 MOCK_METHOD1(SetRemoteDeviceLifeCycle, void(RemoteDeviceLifeCycle*));
70 MOCK_METHOD1(OnAuthAttempted, void(mojom::AuthType));
71 MOCK_METHOD0(CancelConnectionAttempt, void());
72
73 private:
74 DISALLOW_COPY_AND_ASSIGN(MockUnlockManager);
75 };
76
77 // Mock implementation of ProximityAuthProfilePrefManager.
78 class MockProximityAuthPrefManager : public ProximityAuthProfilePrefManager {
79 public:
MockProximityAuthPrefManager(chromeos::multidevice_setup::FakeMultiDeviceSetupClient * fake_multidevice_setup_client)80 MockProximityAuthPrefManager(
81 chromeos::multidevice_setup::FakeMultiDeviceSetupClient*
82 fake_multidevice_setup_client)
83 : ProximityAuthProfilePrefManager(nullptr,
84 fake_multidevice_setup_client) {}
~MockProximityAuthPrefManager()85 ~MockProximityAuthPrefManager() override {}
86 MOCK_CONST_METHOD0(GetLastPasswordEntryTimestampMs, int64_t());
87
88 private:
89 DISALLOW_COPY_AND_ASSIGN(MockProximityAuthPrefManager);
90 };
91
92 // Harness for ProximityAuthSystem to make it testable.
93 class TestableProximityAuthSystem : public ProximityAuthSystem {
94 public:
TestableProximityAuthSystem(chromeos::secure_channel::SecureChannelClient * secure_channel_client,std::unique_ptr<UnlockManager> unlock_manager,ProximityAuthPrefManager * pref_manager)95 TestableProximityAuthSystem(
96 chromeos::secure_channel::SecureChannelClient* secure_channel_client,
97 std::unique_ptr<UnlockManager> unlock_manager,
98 ProximityAuthPrefManager* pref_manager)
99 : ProximityAuthSystem(secure_channel_client, std::move(unlock_manager)),
100 life_cycle_(nullptr) {}
~TestableProximityAuthSystem()101 ~TestableProximityAuthSystem() override {}
102
life_cycle()103 FakeRemoteDeviceLifeCycle* life_cycle() { return life_cycle_; }
104
105 private:
CreateRemoteDeviceLifeCycle(chromeos::multidevice::RemoteDeviceRef remote_device,base::Optional<chromeos::multidevice::RemoteDeviceRef> local_device)106 std::unique_ptr<RemoteDeviceLifeCycle> CreateRemoteDeviceLifeCycle(
107 chromeos::multidevice::RemoteDeviceRef remote_device,
108 base::Optional<chromeos::multidevice::RemoteDeviceRef> local_device)
109 override {
110 std::unique_ptr<FakeRemoteDeviceLifeCycle> life_cycle(
111 new FakeRemoteDeviceLifeCycle(remote_device, local_device));
112 life_cycle_ = life_cycle.get();
113 return std::move(life_cycle);
114 }
115
116 FakeRemoteDeviceLifeCycle* life_cycle_;
117
118 DISALLOW_COPY_AND_ASSIGN(TestableProximityAuthSystem);
119 };
120
121 } // namespace
122
123 class ProximityAuthSystemTest : public testing::Test {
124 protected:
ProximityAuthSystemTest()125 ProximityAuthSystemTest()
126 : user1_local_device_(CreateRemoteDevice(kUser1, "user1_local_device")),
127 user2_local_device_(CreateRemoteDevice(kUser2, "user2_local_device")),
128 task_runner_(new base::TestSimpleTaskRunner()),
129 thread_task_runner_handle_(task_runner_) {}
130
TearDown()131 void TearDown() override {
132 UnlockScreen();
133 pref_manager_.reset();
134 }
135
SetUp()136 void SetUp() override {
137 fake_multidevice_setup_client_ = std::make_unique<
138 chromeos::multidevice_setup::FakeMultiDeviceSetupClient>();
139 pref_manager_ = std::make_unique<NiceMock<MockProximityAuthPrefManager>>(
140 fake_multidevice_setup_client_.get());
141
142 user1_remote_devices_.push_back(
143 CreateRemoteDevice(kUser1, "user1_device1"));
144 user1_remote_devices_.push_back(
145 CreateRemoteDevice(kUser1, "user1_device2"));
146
147 user2_remote_devices_.push_back(
148 CreateRemoteDevice(kUser2, "user2_device1"));
149 user2_remote_devices_.push_back(
150 CreateRemoteDevice(kUser2, "user2_device2"));
151 user2_remote_devices_.push_back(
152 CreateRemoteDevice(kUser2, "user2_device3"));
153
154 std::unique_ptr<MockUnlockManager> unlock_manager(
155 new NiceMock<MockUnlockManager>());
156 unlock_manager_ = unlock_manager.get();
157
158 fake_secure_channel_client_ =
159 std::make_unique<chromeos::secure_channel::FakeSecureChannelClient>();
160
161 proximity_auth_system_.reset(new TestableProximityAuthSystem(
162 fake_secure_channel_client_.get(), std::move(unlock_manager),
163 pref_manager_.get()));
164
165 proximity_auth_system_->SetRemoteDevicesForUser(
166 AccountId::FromUserEmail(kUser1), user1_remote_devices_,
167 user1_local_device_);
168 proximity_auth_system_->Start();
169 LockScreen();
170 }
171
LockScreen()172 void LockScreen() {
173 ScreenlockBridge::Get()->SetFocusedUser(AccountId());
174 ScreenlockBridge::Get()->SetLockHandler(&lock_handler_);
175 }
176
FocusUser(const std::string & user_email)177 void FocusUser(const std::string& user_email) {
178 ScreenlockBridge::Get()->SetFocusedUser(
179 AccountId::FromUserEmail(user_email));
180 }
181
UnlockScreen()182 void UnlockScreen() { ScreenlockBridge::Get()->SetLockHandler(nullptr); }
183
SimulateSuspend()184 void SimulateSuspend() {
185 proximity_auth_system_->OnSuspend();
186 proximity_auth_system_->OnSuspendDone();
187 task_runner_->RunUntilIdle();
188 }
189
life_cycle()190 FakeRemoteDeviceLifeCycle* life_cycle() {
191 return proximity_auth_system_->life_cycle();
192 }
193
194 FakeLockHandler lock_handler_;
195 NiceMock<MockProximityAuthClient> proximity_auth_client_;
196 std::unique_ptr<chromeos::secure_channel::FakeSecureChannelClient>
197 fake_secure_channel_client_;
198 std::unique_ptr<TestableProximityAuthSystem> proximity_auth_system_;
199 MockUnlockManager* unlock_manager_;
200 std::unique_ptr<MockProximityAuthPrefManager> pref_manager_;
201 std::unique_ptr<chromeos::multidevice_setup::FakeMultiDeviceSetupClient>
202 fake_multidevice_setup_client_;
203
204 chromeos::multidevice::RemoteDeviceRef user1_local_device_;
205 chromeos::multidevice::RemoteDeviceRef user2_local_device_;
206
207 chromeos::multidevice::RemoteDeviceRefList user1_remote_devices_;
208 chromeos::multidevice::RemoteDeviceRefList user2_remote_devices_;
209
210 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
211 base::ThreadTaskRunnerHandle thread_task_runner_handle_;
212
213 private:
214 chromeos::multidevice::ScopedDisableLoggingForTesting disable_logging_;
215 base::test::ScopedFeatureList scoped_feature_list_;
216
217 DISALLOW_COPY_AND_ASSIGN(ProximityAuthSystemTest);
218 };
219
TEST_F(ProximityAuthSystemTest,SetRemoteDevicesForUser_NotStarted)220 TEST_F(ProximityAuthSystemTest, SetRemoteDevicesForUser_NotStarted) {
221 AccountId account1 = AccountId::FromUserEmail(kUser1);
222 AccountId account2 = AccountId::FromUserEmail(kUser2);
223 proximity_auth_system_->SetRemoteDevicesForUser(
224 account1, user1_remote_devices_, user1_local_device_);
225 proximity_auth_system_->SetRemoteDevicesForUser(
226 account2, user2_remote_devices_, user1_local_device_);
227
228 CompareRemoteDeviceRefLists(
229 user1_remote_devices_,
230 proximity_auth_system_->GetRemoteDevicesForUser(account1));
231
232 CompareRemoteDeviceRefLists(
233 user2_remote_devices_,
234 proximity_auth_system_->GetRemoteDevicesForUser(account2));
235
236 CompareRemoteDeviceRefLists(
237 chromeos::multidevice::RemoteDeviceRefList(),
238 proximity_auth_system_->GetRemoteDevicesForUser(
239 AccountId::FromUserEmail("non_existent_user@google.com")));
240 }
241
TEST_F(ProximityAuthSystemTest,SetRemoteDevicesForUser_Started)242 TEST_F(ProximityAuthSystemTest, SetRemoteDevicesForUser_Started) {
243 AccountId account1 = AccountId::FromUserEmail(kUser1);
244 AccountId account2 = AccountId::FromUserEmail(kUser2);
245 proximity_auth_system_->SetRemoteDevicesForUser(
246 account1, user1_remote_devices_, user1_local_device_);
247 proximity_auth_system_->Start();
248 proximity_auth_system_->SetRemoteDevicesForUser(
249 account2, user2_remote_devices_, user2_local_device_);
250
251 CompareRemoteDeviceRefLists(
252 user1_remote_devices_,
253 proximity_auth_system_->GetRemoteDevicesForUser(account1));
254
255 CompareRemoteDeviceRefLists(
256 user2_remote_devices_,
257 proximity_auth_system_->GetRemoteDevicesForUser(account2));
258 }
259
TEST_F(ProximityAuthSystemTest,FocusRegisteredUser)260 TEST_F(ProximityAuthSystemTest, FocusRegisteredUser) {
261 EXPECT_FALSE(life_cycle());
262 EXPECT_EQ(std::string(),
263 ScreenlockBridge::Get()->focused_account_id().GetUserEmail());
264
265 RemoteDeviceLifeCycle* unlock_manager_life_cycle = nullptr;
266 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
267 .WillOnce(SaveArg<0>(&unlock_manager_life_cycle));
268 FocusUser(kUser1);
269
270 EXPECT_EQ(life_cycle(), unlock_manager_life_cycle);
271 EXPECT_TRUE(life_cycle());
272 EXPECT_FALSE(life_cycle()->started());
273 EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_email());
274
275 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
276 .Times(AtLeast(1));
277 }
278
TEST_F(ProximityAuthSystemTest,FocusUnregisteredUser)279 TEST_F(ProximityAuthSystemTest, FocusUnregisteredUser) {
280 EXPECT_FALSE(life_cycle());
281 EXPECT_EQ(std::string(),
282 ScreenlockBridge::Get()->focused_account_id().GetUserEmail());
283 EXPECT_FALSE(life_cycle());
284
285 FocusUser(kUser2);
286 EXPECT_FALSE(life_cycle());
287 }
288
TEST_F(ProximityAuthSystemTest,ToggleFocus_RegisteredUsers)289 TEST_F(ProximityAuthSystemTest, ToggleFocus_RegisteredUsers) {
290 proximity_auth_system_->SetRemoteDevicesForUser(
291 AccountId::FromUserEmail(kUser1), user1_remote_devices_,
292 user1_local_device_);
293 proximity_auth_system_->SetRemoteDevicesForUser(
294 AccountId::FromUserEmail(kUser2), user2_remote_devices_,
295 user2_local_device_);
296
297 RemoteDeviceLifeCycle* life_cycle1 = nullptr;
298 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
299 .WillOnce(SaveArg<0>(&life_cycle1));
300 FocusUser(kUser1);
301 EXPECT_EQ(kUser1, life_cycle1->GetRemoteDevice().user_email());
302 EXPECT_EQ(user1_local_device_, life_cycle()->local_device());
303
304 RemoteDeviceLifeCycle* life_cycle2 = nullptr;
305 {
306 InSequence sequence;
307 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
308 .Times(AtLeast(1));
309 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
310 .WillOnce(SaveArg<0>(&life_cycle2));
311 }
312 FocusUser(kUser2);
313 EXPECT_EQ(kUser2, life_cycle2->GetRemoteDevice().user_email());
314 EXPECT_EQ(user2_local_device_, life_cycle()->local_device());
315
316 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
317 .Times(AtLeast(1));
318 }
319
TEST_F(ProximityAuthSystemTest,ToggleFocus_UnregisteredUsers)320 TEST_F(ProximityAuthSystemTest, ToggleFocus_UnregisteredUsers) {
321 FocusUser(kUser2);
322 EXPECT_FALSE(life_cycle());
323
324 FocusUser("unregistered-user");
325 EXPECT_FALSE(life_cycle());
326
327 FocusUser(kUser2);
328 EXPECT_FALSE(life_cycle());
329 }
330
TEST_F(ProximityAuthSystemTest,ToggleFocus_RegisteredAndUnregisteredUsers)331 TEST_F(ProximityAuthSystemTest, ToggleFocus_RegisteredAndUnregisteredUsers) {
332 // Focus User 1, who is registered. This should create a new life cycle.
333 RemoteDeviceLifeCycle* life_cycle = nullptr;
334 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
335 .WillOnce(SaveArg<0>(&life_cycle));
336 FocusUser(kUser1);
337 EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_email());
338
339 // User 2 has not been registered yet, so focusing them should not create a
340 // new life cycle.
341 life_cycle = nullptr;
342 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr));
343 FocusUser(kUser2);
344 EXPECT_FALSE(life_cycle);
345
346 // Focusing back to User 1 should recreate a new life cycle.
347 life_cycle = nullptr;
348 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
349 .WillOnce(SaveArg<0>(&life_cycle));
350 FocusUser(kUser1);
351 EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_email());
352
353 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
354 .Times(AtLeast(1));
355 }
356
TEST_F(ProximityAuthSystemTest,ToggleFocus_SameUserRefocused)357 TEST_F(ProximityAuthSystemTest, ToggleFocus_SameUserRefocused) {
358 RemoteDeviceLifeCycle* life_cycle = nullptr;
359 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
360 .WillOnce(SaveArg<0>(&life_cycle));
361 FocusUser(kUser1);
362 EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_email());
363
364 // Focusing the user again should be idempotent. The screenlock UI may call
365 // focus on the same user multiple times.
366 // SetRemoteDeviceLifeCycle() is only expected to be called once.
367 FocusUser(kUser1);
368
369 // The RemoteDeviceLifeCycle should be nulled upon destruction.
370 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
371 .Times(AtLeast(1));
372 }
373
TEST_F(ProximityAuthSystemTest,RestartSystem_UnregisteredUserFocused)374 TEST_F(ProximityAuthSystemTest, RestartSystem_UnregisteredUserFocused) {
375 FocusUser(kUser2);
376
377 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
378 .Times(AnyNumber());
379 proximity_auth_system_->Stop();
380 proximity_auth_system_->Start();
381 EXPECT_FALSE(life_cycle());
382 }
383
TEST_F(ProximityAuthSystemTest,StopSystem_RegisteredUserFocused)384 TEST_F(ProximityAuthSystemTest, StopSystem_RegisteredUserFocused) {
385 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
386 FocusUser(kUser1);
387
388 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
389 .Times(AtLeast(1));
390 proximity_auth_system_->Stop();
391
392 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
393 proximity_auth_system_->Start();
394 EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_email());
395 }
396
TEST_F(ProximityAuthSystemTest,OnAuthAttempted)397 TEST_F(ProximityAuthSystemTest, OnAuthAttempted) {
398 FocusUser(kUser1);
399 EXPECT_CALL(*unlock_manager_, OnAuthAttempted(_));
400 proximity_auth_system_->OnAuthAttempted();
401 }
402
TEST_F(ProximityAuthSystemTest,Suspend_ScreenUnlocked)403 TEST_F(ProximityAuthSystemTest, Suspend_ScreenUnlocked) {
404 UnlockScreen();
405 EXPECT_FALSE(life_cycle());
406 SimulateSuspend();
407 EXPECT_FALSE(life_cycle());
408 }
409
TEST_F(ProximityAuthSystemTest,Suspend_UnregisteredUserFocused)410 TEST_F(ProximityAuthSystemTest, Suspend_UnregisteredUserFocused) {
411 SimulateSuspend();
412 EXPECT_FALSE(life_cycle());
413 }
414
TEST_F(ProximityAuthSystemTest,Suspend_RegisteredUserFocused)415 TEST_F(ProximityAuthSystemTest, Suspend_RegisteredUserFocused) {
416 FocusUser(kUser1);
417
418 {
419 InSequence sequence;
420 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
421 .Times(AtLeast(1));
422 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
423 SimulateSuspend();
424 }
425
426 EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_email());
427
428 EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
429 .Times(AtLeast(1));
430 }
431
432 } // namespace proximity_auth
433