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