OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 "components/proximity_auth/cryptauth/cryptauth_device_manager.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include <utility> | |
10 | |
11 #include "base/base64url.h" | |
12 #include "base/macros.h" | |
13 #include "base/memory/ptr_util.h" | |
14 #include "base/memory/weak_ptr.h" | |
15 #include "base/strings/stringprintf.h" | |
16 #include "base/test/simple_test_clock.h" | |
17 #include "components/prefs/scoped_user_pref_update.h" | |
18 #include "components/prefs/testing_pref_service.h" | |
19 #include "components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h" | |
20 #include "components/proximity_auth/cryptauth/mock_cryptauth_client.h" | |
21 #include "components/proximity_auth/cryptauth/mock_sync_scheduler.h" | |
22 #include "components/proximity_auth/cryptauth/pref_names.h" | |
23 #include "testing/gmock/include/gmock/gmock.h" | |
24 #include "testing/gtest/include/gtest/gtest.h" | |
25 | |
26 using ::testing::_; | |
27 using ::testing::DoAll; | |
28 using ::testing::NiceMock; | |
29 using ::testing::Return; | |
30 using ::testing::SaveArg; | |
31 | |
32 namespace proximity_auth { | |
33 namespace { | |
34 | |
35 // The initial "Now" time for testing. | |
36 const double kInitialTimeNowSeconds = 20000000; | |
37 | |
38 // A later "Now" time for testing. | |
39 const double kLaterTimeNowSeconds = kInitialTimeNowSeconds + 30; | |
40 | |
41 // The timestamp of a last successful sync in seconds. | |
42 const double kLastSyncTimeSeconds = kInitialTimeNowSeconds - (60 * 60 * 5); | |
43 | |
44 // Unlock key fields originally stored in the user prefs. | |
45 const char kStoredPublicKey[] = "AAPL"; | |
46 const char kStoredDeviceName[] = "iPhone 6"; | |
47 const char kStoredBluetoothAddress[] = "12:34:56:78:90:AB"; | |
48 | |
49 // ExternalDeviceInfo fields for the synced unlock key. | |
50 const char kPublicKey1[] = "GOOG"; | |
51 const char kDeviceName1[] = "Nexus 5"; | |
52 const char kBluetoothAddress1[] = "aa:bb:cc:ee:dd:ff"; | |
53 | |
54 // ExternalDeviceInfo fields for a non-synced unlockable device. | |
55 const char kPublicKey2[] = "MSFT"; | |
56 const char kDeviceName2[] = "Surface Pro 3"; | |
57 | |
58 // Validates that |unlock_keys| and the corresponding preferences stored by | |
59 // |pref_service| are equal to |expected_unlock_keys|. | |
60 void ExpectUnlockKeysAndPrefAreEqual( | |
61 const std::vector<cryptauth::ExternalDeviceInfo>& expected_unlock_keys, | |
62 const std::vector<cryptauth::ExternalDeviceInfo>& unlock_keys, | |
63 const PrefService& pref_service) { | |
64 ASSERT_EQ(expected_unlock_keys.size(), unlock_keys.size()); | |
65 for (size_t i = 0; i < unlock_keys.size(); ++i) { | |
66 SCOPED_TRACE( | |
67 base::StringPrintf("Compare protos at index=%d", static_cast<int>(i))); | |
68 const auto& expected_unlock_key = expected_unlock_keys[i]; | |
69 const auto& unlock_key = unlock_keys.at(i); | |
70 EXPECT_EQ(expected_unlock_key.public_key(), unlock_key.public_key()); | |
71 EXPECT_EQ(expected_unlock_key.friendly_device_name(), | |
72 unlock_key.friendly_device_name()); | |
73 EXPECT_EQ(expected_unlock_key.bluetooth_address(), | |
74 unlock_key.bluetooth_address()); | |
75 EXPECT_TRUE(expected_unlock_key.unlock_key()); | |
76 EXPECT_FALSE(expected_unlock_key.unlockable()); | |
77 } | |
78 | |
79 const base::ListValue* unlock_keys_pref = | |
80 pref_service.GetList(prefs::kCryptAuthDeviceSyncUnlockKeys); | |
81 ASSERT_EQ(expected_unlock_keys.size(), unlock_keys_pref->GetSize()); | |
82 for (size_t i = 0; i < unlock_keys_pref->GetSize(); ++i) { | |
83 SCOPED_TRACE(base::StringPrintf("Compare pref dictionary at index=%d", | |
84 static_cast<int>(i))); | |
85 const base::DictionaryValue* unlock_key_dictionary; | |
86 EXPECT_TRUE(unlock_keys_pref->GetDictionary(i, &unlock_key_dictionary)); | |
87 std::string public_key_b64, device_name_b64, bluetooth_address_b64; | |
88 ASSERT_TRUE( | |
89 unlock_key_dictionary->GetString("public_key", &public_key_b64)); | |
90 ASSERT_TRUE( | |
91 unlock_key_dictionary->GetString("device_name", &device_name_b64)); | |
92 ASSERT_TRUE(unlock_key_dictionary->GetString("bluetooth_address", | |
93 &bluetooth_address_b64)); | |
94 | |
95 std::string public_key, device_name, bluetooth_address; | |
96 ASSERT_TRUE(base::Base64UrlDecode( | |
97 public_key_b64, base::Base64UrlDecodePolicy::REQUIRE_PADDING, | |
98 &public_key)); | |
99 ASSERT_TRUE(base::Base64UrlDecode( | |
100 device_name_b64, base::Base64UrlDecodePolicy::REQUIRE_PADDING, | |
101 &device_name)); | |
102 ASSERT_TRUE(base::Base64UrlDecode( | |
103 bluetooth_address_b64, base::Base64UrlDecodePolicy::REQUIRE_PADDING, | |
104 &bluetooth_address)); | |
105 | |
106 const auto& expected_unlock_key = expected_unlock_keys[i]; | |
107 EXPECT_EQ(expected_unlock_key.public_key(), public_key); | |
108 EXPECT_EQ(expected_unlock_key.friendly_device_name(), device_name); | |
109 EXPECT_EQ(expected_unlock_key.bluetooth_address(), bluetooth_address); | |
110 EXPECT_TRUE(expected_unlock_key.unlock_key()); | |
111 EXPECT_FALSE(expected_unlock_key.unlockable()); | |
112 } | |
113 } | |
114 | |
115 // Harness for testing CryptAuthDeviceManager. | |
116 class TestCryptAuthDeviceManager : public CryptAuthDeviceManager { | |
117 public: | |
118 TestCryptAuthDeviceManager( | |
119 std::unique_ptr<base::Clock> clock, | |
120 std::unique_ptr<CryptAuthClientFactory> client_factory, | |
121 CryptAuthGCMManager* gcm_manager, | |
122 PrefService* pref_service) | |
123 : CryptAuthDeviceManager(std::move(clock), | |
124 std::move(client_factory), | |
125 gcm_manager, | |
126 pref_service), | |
127 scoped_sync_scheduler_(new NiceMock<MockSyncScheduler>()), | |
128 weak_sync_scheduler_factory_(scoped_sync_scheduler_.get()) {} | |
129 | |
130 ~TestCryptAuthDeviceManager() override {} | |
131 | |
132 std::unique_ptr<SyncScheduler> CreateSyncScheduler() override { | |
133 EXPECT_TRUE(scoped_sync_scheduler_); | |
134 return std::move(scoped_sync_scheduler_); | |
135 } | |
136 | |
137 base::WeakPtr<MockSyncScheduler> GetSyncScheduler() { | |
138 return weak_sync_scheduler_factory_.GetWeakPtr(); | |
139 } | |
140 | |
141 private: | |
142 // Ownership is passed to |CryptAuthDeviceManager| super class when | |
143 // |CreateSyncScheduler()| is called. | |
144 std::unique_ptr<MockSyncScheduler> scoped_sync_scheduler_; | |
145 | |
146 // Stores the pointer of |scoped_sync_scheduler_| after ownership is passed to | |
147 // the super class. | |
148 // This should be safe because the life-time this SyncScheduler will always be | |
149 // within the life of the TestCryptAuthDeviceManager object. | |
150 base::WeakPtrFactory<MockSyncScheduler> weak_sync_scheduler_factory_; | |
151 | |
152 DISALLOW_COPY_AND_ASSIGN(TestCryptAuthDeviceManager); | |
153 }; | |
154 | |
155 } // namespace | |
156 | |
157 class ProximityAuthCryptAuthDeviceManagerTest | |
158 : public testing::Test, | |
159 public CryptAuthDeviceManager::Observer, | |
160 public MockCryptAuthClientFactory::Observer { | |
161 protected: | |
162 ProximityAuthCryptAuthDeviceManagerTest() | |
163 : clock_(new base::SimpleTestClock()), | |
164 client_factory_(new MockCryptAuthClientFactory( | |
165 MockCryptAuthClientFactory::MockType::MAKE_STRICT_MOCKS)), | |
166 gcm_manager_("existing gcm registration id") { | |
167 client_factory_->AddObserver(this); | |
168 } | |
169 | |
170 ~ProximityAuthCryptAuthDeviceManagerTest() { | |
171 client_factory_->RemoveObserver(this); | |
172 } | |
173 | |
174 // testing::Test: | |
175 void SetUp() override { | |
176 clock_->SetNow(base::Time::FromDoubleT(kInitialTimeNowSeconds)); | |
177 | |
178 CryptAuthDeviceManager::RegisterPrefs(pref_service_.registry()); | |
179 pref_service_.SetUserPref( | |
180 prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure, | |
181 new base::FundamentalValue(false)); | |
182 pref_service_.SetUserPref(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds, | |
183 new base::FundamentalValue(kLastSyncTimeSeconds)); | |
184 pref_service_.SetUserPref( | |
185 prefs::kCryptAuthDeviceSyncReason, | |
186 new base::FundamentalValue(cryptauth::INVOCATION_REASON_UNKNOWN)); | |
187 | |
188 std::unique_ptr<base::DictionaryValue> unlock_key_dictionary( | |
189 new base::DictionaryValue()); | |
190 | |
191 std::string public_key_b64, device_name_b64, bluetooth_address_b64; | |
192 base::Base64UrlEncode(kStoredPublicKey, | |
193 base::Base64UrlEncodePolicy::INCLUDE_PADDING, | |
194 &public_key_b64); | |
195 base::Base64UrlEncode(kStoredDeviceName, | |
196 base::Base64UrlEncodePolicy::INCLUDE_PADDING, | |
197 &device_name_b64); | |
198 base::Base64UrlEncode(kStoredBluetoothAddress, | |
199 base::Base64UrlEncodePolicy::INCLUDE_PADDING, | |
200 &bluetooth_address_b64); | |
201 | |
202 unlock_key_dictionary->SetString("public_key", public_key_b64); | |
203 unlock_key_dictionary->SetString("device_name", device_name_b64); | |
204 unlock_key_dictionary->SetString("bluetooth_address", | |
205 bluetooth_address_b64); | |
206 { | |
207 ListPrefUpdate update(&pref_service_, | |
208 prefs::kCryptAuthDeviceSyncUnlockKeys); | |
209 update.Get()->Append(std::move(unlock_key_dictionary)); | |
210 } | |
211 | |
212 device_manager_.reset(new TestCryptAuthDeviceManager( | |
213 base::WrapUnique(clock_), base::WrapUnique(client_factory_), | |
214 &gcm_manager_, &pref_service_)); | |
215 device_manager_->AddObserver(this); | |
216 | |
217 cryptauth::ExternalDeviceInfo unlock_key; | |
218 unlock_key.set_public_key(kPublicKey1); | |
219 unlock_key.set_friendly_device_name(kDeviceName1); | |
220 unlock_key.set_bluetooth_address(kBluetoothAddress1); | |
221 unlock_key.set_unlock_key(true); | |
222 unlock_key.set_unlockable(false); | |
223 | |
224 cryptauth::ExternalDeviceInfo unlockable_device; | |
225 unlockable_device.set_public_key(kPublicKey2); | |
226 unlockable_device.set_friendly_device_name(kDeviceName2); | |
227 unlockable_device.set_unlock_key(false); | |
228 unlockable_device.set_unlockable(true); | |
229 | |
230 get_my_devices_response_.add_devices()->CopyFrom(unlock_key); | |
231 get_my_devices_response_.add_devices()->CopyFrom(unlockable_device); | |
232 | |
233 ON_CALL(*sync_scheduler(), GetStrategy()) | |
234 .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH)); | |
235 } | |
236 | |
237 void TearDown() override { device_manager_->RemoveObserver(this); } | |
238 | |
239 // CryptAuthDeviceManager::Observer: | |
240 void OnSyncStarted() override { OnSyncStartedProxy(); } | |
241 | |
242 void OnSyncFinished(CryptAuthDeviceManager::SyncResult sync_result, | |
243 CryptAuthDeviceManager::DeviceChangeResult | |
244 device_change_result) override { | |
245 OnSyncFinishedProxy(sync_result, device_change_result); | |
246 } | |
247 | |
248 MOCK_METHOD0(OnSyncStartedProxy, void()); | |
249 MOCK_METHOD2(OnSyncFinishedProxy, | |
250 void(CryptAuthDeviceManager::SyncResult, | |
251 CryptAuthDeviceManager::DeviceChangeResult)); | |
252 | |
253 // Simulates firing the SyncScheduler to trigger a device sync attempt. | |
254 void FireSchedulerForSync( | |
255 cryptauth::InvocationReason expected_invocation_reason) { | |
256 SyncScheduler::Delegate* delegate = | |
257 static_cast<SyncScheduler::Delegate*>(device_manager_.get()); | |
258 | |
259 std::unique_ptr<SyncScheduler::SyncRequest> sync_request = | |
260 base::MakeUnique<SyncScheduler::SyncRequest>( | |
261 device_manager_->GetSyncScheduler()); | |
262 EXPECT_CALL(*this, OnSyncStartedProxy()); | |
263 delegate->OnSyncRequested(std::move(sync_request)); | |
264 | |
265 EXPECT_EQ(expected_invocation_reason, | |
266 get_my_devices_request_.invocation_reason()); | |
267 | |
268 // The allow_stale_read flag is set if the sync was not forced. | |
269 bool allow_stale_read = | |
270 pref_service_.GetInteger(prefs::kCryptAuthDeviceSyncReason) != | |
271 cryptauth::INVOCATION_REASON_UNKNOWN; | |
272 EXPECT_EQ(allow_stale_read, get_my_devices_request_.allow_stale_read()); | |
273 } | |
274 | |
275 // MockCryptAuthClientFactory::Observer: | |
276 void OnCryptAuthClientCreated(MockCryptAuthClient* client) override { | |
277 EXPECT_CALL(*client, GetMyDevices(_, _, _)) | |
278 .WillOnce(DoAll(SaveArg<0>(&get_my_devices_request_), | |
279 SaveArg<1>(&success_callback_), | |
280 SaveArg<2>(&error_callback_))); | |
281 } | |
282 | |
283 MockSyncScheduler* sync_scheduler() { | |
284 return device_manager_->GetSyncScheduler().get(); | |
285 } | |
286 | |
287 // Owned by |device_manager_|. | |
288 base::SimpleTestClock* clock_; | |
289 | |
290 // Owned by |device_manager_|. | |
291 MockCryptAuthClientFactory* client_factory_; | |
292 | |
293 TestingPrefServiceSimple pref_service_; | |
294 | |
295 FakeCryptAuthGCMManager gcm_manager_; | |
296 | |
297 std::unique_ptr<TestCryptAuthDeviceManager> device_manager_; | |
298 | |
299 cryptauth::GetMyDevicesResponse get_my_devices_response_; | |
300 | |
301 cryptauth::GetMyDevicesRequest get_my_devices_request_; | |
302 | |
303 CryptAuthClient::GetMyDevicesCallback success_callback_; | |
304 | |
305 CryptAuthClient::ErrorCallback error_callback_; | |
306 | |
307 DISALLOW_COPY_AND_ASSIGN(ProximityAuthCryptAuthDeviceManagerTest); | |
308 }; | |
309 | |
310 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, RegisterPrefs) { | |
311 TestingPrefServiceSimple pref_service; | |
312 CryptAuthDeviceManager::RegisterPrefs(pref_service.registry()); | |
313 EXPECT_TRUE(pref_service.FindPreference( | |
314 prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds)); | |
315 EXPECT_TRUE(pref_service.FindPreference( | |
316 prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); | |
317 EXPECT_TRUE(pref_service.FindPreference(prefs::kCryptAuthDeviceSyncReason)); | |
318 EXPECT_TRUE( | |
319 pref_service.FindPreference(prefs::kCryptAuthDeviceSyncUnlockKeys)); | |
320 } | |
321 | |
322 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, GetSyncState) { | |
323 device_manager_->Start(); | |
324 | |
325 ON_CALL(*sync_scheduler(), GetStrategy()) | |
326 .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH)); | |
327 EXPECT_FALSE(device_manager_->IsRecoveringFromFailure()); | |
328 | |
329 ON_CALL(*sync_scheduler(), GetStrategy()) | |
330 .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY)); | |
331 EXPECT_TRUE(device_manager_->IsRecoveringFromFailure()); | |
332 | |
333 base::TimeDelta time_to_next_sync = base::TimeDelta::FromMinutes(60); | |
334 ON_CALL(*sync_scheduler(), GetTimeToNextSync()) | |
335 .WillByDefault(Return(time_to_next_sync)); | |
336 EXPECT_EQ(time_to_next_sync, device_manager_->GetTimeToNextAttempt()); | |
337 | |
338 ON_CALL(*sync_scheduler(), GetSyncState()) | |
339 .WillByDefault(Return(SyncScheduler::SyncState::SYNC_IN_PROGRESS)); | |
340 EXPECT_TRUE(device_manager_->IsSyncInProgress()); | |
341 | |
342 ON_CALL(*sync_scheduler(), GetSyncState()) | |
343 .WillByDefault(Return(SyncScheduler::SyncState::WAITING_FOR_REFRESH)); | |
344 EXPECT_FALSE(device_manager_->IsSyncInProgress()); | |
345 } | |
346 | |
347 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, InitWithDefaultPrefs) { | |
348 std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock); | |
349 clock->SetNow(base::Time::FromDoubleT(kInitialTimeNowSeconds)); | |
350 base::TimeDelta elapsed_time = clock->Now() - base::Time::FromDoubleT(0); | |
351 | |
352 TestingPrefServiceSimple pref_service; | |
353 CryptAuthDeviceManager::RegisterPrefs(pref_service.registry()); | |
354 | |
355 TestCryptAuthDeviceManager device_manager( | |
356 std::move(clock), | |
357 base::MakeUnique<MockCryptAuthClientFactory>( | |
358 MockCryptAuthClientFactory::MockType::MAKE_STRICT_MOCKS), | |
359 &gcm_manager_, &pref_service); | |
360 | |
361 EXPECT_CALL( | |
362 *(device_manager.GetSyncScheduler()), | |
363 Start(elapsed_time, SyncScheduler::Strategy::AGGRESSIVE_RECOVERY)); | |
364 device_manager.Start(); | |
365 EXPECT_TRUE(device_manager.GetLastSyncTime().is_null()); | |
366 EXPECT_EQ(0u, device_manager.unlock_keys().size()); | |
367 } | |
368 | |
369 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, InitWithExistingPrefs) { | |
370 EXPECT_CALL( | |
371 *sync_scheduler(), | |
372 Start(clock_->Now() - base::Time::FromDoubleT(kLastSyncTimeSeconds), | |
373 SyncScheduler::Strategy::PERIODIC_REFRESH)); | |
374 | |
375 device_manager_->Start(); | |
376 EXPECT_EQ(base::Time::FromDoubleT(kLastSyncTimeSeconds), | |
377 device_manager_->GetLastSyncTime()); | |
378 | |
379 auto unlock_keys = device_manager_->unlock_keys(); | |
380 ASSERT_EQ(1u, unlock_keys.size()); | |
381 EXPECT_EQ(kStoredPublicKey, unlock_keys[0].public_key()); | |
382 EXPECT_EQ(kStoredDeviceName, unlock_keys[0].friendly_device_name()); | |
383 EXPECT_EQ(kStoredBluetoothAddress, unlock_keys[0].bluetooth_address()); | |
384 EXPECT_TRUE(unlock_keys[0].unlock_key()); | |
385 } | |
386 | |
387 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncSucceedsForFirstTime) { | |
388 pref_service_.ClearPref(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds); | |
389 device_manager_->Start(); | |
390 | |
391 FireSchedulerForSync(cryptauth::INVOCATION_REASON_INITIALIZATION); | |
392 ASSERT_FALSE(success_callback_.is_null()); | |
393 | |
394 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds)); | |
395 EXPECT_CALL(*this, OnSyncFinishedProxy( | |
396 CryptAuthDeviceManager::SyncResult::SUCCESS, | |
397 CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); | |
398 | |
399 success_callback_.Run(get_my_devices_response_); | |
400 EXPECT_EQ(clock_->Now(), device_manager_->GetLastSyncTime()); | |
401 | |
402 ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>( | |
403 1, get_my_devices_response_.devices(0)), | |
404 device_manager_->unlock_keys(), | |
405 pref_service_); | |
406 } | |
407 | |
408 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, ForceSync) { | |
409 device_manager_->Start(); | |
410 | |
411 EXPECT_CALL(*sync_scheduler(), ForceSync()); | |
412 device_manager_->ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL); | |
413 | |
414 FireSchedulerForSync(cryptauth::INVOCATION_REASON_MANUAL); | |
415 | |
416 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds)); | |
417 EXPECT_CALL(*this, OnSyncFinishedProxy( | |
418 CryptAuthDeviceManager::SyncResult::SUCCESS, | |
419 CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); | |
420 success_callback_.Run(get_my_devices_response_); | |
421 EXPECT_EQ(clock_->Now(), device_manager_->GetLastSyncTime()); | |
422 | |
423 ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>( | |
424 1, get_my_devices_response_.devices(0)), | |
425 device_manager_->unlock_keys(), | |
426 pref_service_); | |
427 } | |
428 | |
429 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, ForceSyncFailsThenSucceeds) { | |
430 device_manager_->Start(); | |
431 EXPECT_FALSE(pref_service_.GetBoolean( | |
432 prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); | |
433 base::Time old_sync_time = device_manager_->GetLastSyncTime(); | |
434 | |
435 // The first force sync fails. | |
436 EXPECT_CALL(*sync_scheduler(), ForceSync()); | |
437 device_manager_->ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL); | |
438 FireSchedulerForSync(cryptauth::INVOCATION_REASON_MANUAL); | |
439 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds)); | |
440 EXPECT_CALL(*this, | |
441 OnSyncFinishedProxy( | |
442 CryptAuthDeviceManager::SyncResult::FAILURE, | |
443 CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED)); | |
444 error_callback_.Run("404"); | |
445 EXPECT_EQ(old_sync_time, device_manager_->GetLastSyncTime()); | |
446 EXPECT_TRUE(pref_service_.GetBoolean( | |
447 prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); | |
448 EXPECT_EQ(static_cast<int>(cryptauth::INVOCATION_REASON_MANUAL), | |
449 pref_service_.GetInteger(prefs::kCryptAuthDeviceSyncReason)); | |
450 | |
451 // The second recovery sync succeeds. | |
452 ON_CALL(*sync_scheduler(), GetStrategy()) | |
453 .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY)); | |
454 FireSchedulerForSync(cryptauth::INVOCATION_REASON_MANUAL); | |
455 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds + 30)); | |
456 EXPECT_CALL(*this, OnSyncFinishedProxy( | |
457 CryptAuthDeviceManager::SyncResult::SUCCESS, | |
458 CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); | |
459 success_callback_.Run(get_my_devices_response_); | |
460 EXPECT_EQ(clock_->Now(), device_manager_->GetLastSyncTime()); | |
461 | |
462 ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>( | |
463 1, get_my_devices_response_.devices(0)), | |
464 device_manager_->unlock_keys(), | |
465 pref_service_); | |
466 | |
467 EXPECT_FLOAT_EQ( | |
468 clock_->Now().ToDoubleT(), | |
469 pref_service_.GetDouble(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds)); | |
470 EXPECT_EQ(static_cast<int>(cryptauth::INVOCATION_REASON_UNKNOWN), | |
471 pref_service_.GetInteger(prefs::kCryptAuthDeviceSyncReason)); | |
472 EXPECT_FALSE(pref_service_.GetBoolean( | |
473 prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); | |
474 } | |
475 | |
476 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, PeriodicSyncFailsThenSucceeds) { | |
477 device_manager_->Start(); | |
478 base::Time old_sync_time = device_manager_->GetLastSyncTime(); | |
479 | |
480 // The first periodic sync fails. | |
481 FireSchedulerForSync(cryptauth::INVOCATION_REASON_PERIODIC); | |
482 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds)); | |
483 EXPECT_CALL(*this, | |
484 OnSyncFinishedProxy( | |
485 CryptAuthDeviceManager::SyncResult::FAILURE, | |
486 CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED)); | |
487 error_callback_.Run("401"); | |
488 EXPECT_EQ(old_sync_time, device_manager_->GetLastSyncTime()); | |
489 EXPECT_TRUE(pref_service_.GetBoolean( | |
490 prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); | |
491 | |
492 // The second recovery sync succeeds. | |
493 ON_CALL(*sync_scheduler(), GetStrategy()) | |
494 .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY)); | |
495 FireSchedulerForSync(cryptauth::INVOCATION_REASON_FAILURE_RECOVERY); | |
496 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds + 30)); | |
497 EXPECT_CALL(*this, OnSyncFinishedProxy( | |
498 CryptAuthDeviceManager::SyncResult::SUCCESS, | |
499 CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); | |
500 success_callback_.Run(get_my_devices_response_); | |
501 EXPECT_EQ(clock_->Now(), device_manager_->GetLastSyncTime()); | |
502 | |
503 ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>( | |
504 1, get_my_devices_response_.devices(0)), | |
505 device_manager_->unlock_keys(), | |
506 pref_service_); | |
507 | |
508 EXPECT_FLOAT_EQ( | |
509 clock_->Now().ToDoubleT(), | |
510 pref_service_.GetDouble(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds)); | |
511 EXPECT_FALSE(pref_service_.GetBoolean( | |
512 prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure)); | |
513 } | |
514 | |
515 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncSameDevice) { | |
516 device_manager_->Start(); | |
517 auto original_unlock_keys = device_manager_->unlock_keys(); | |
518 | |
519 // Sync new devices. | |
520 FireSchedulerForSync(cryptauth::INVOCATION_REASON_PERIODIC); | |
521 ASSERT_FALSE(success_callback_.is_null()); | |
522 EXPECT_CALL(*this, | |
523 OnSyncFinishedProxy( | |
524 CryptAuthDeviceManager::SyncResult::SUCCESS, | |
525 CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED)); | |
526 | |
527 // Sync the same device. | |
528 cryptauth::ExternalDeviceInfo synced_unlock_key; | |
529 synced_unlock_key.set_public_key(kStoredPublicKey); | |
530 synced_unlock_key.set_friendly_device_name(kStoredDeviceName); | |
531 synced_unlock_key.set_bluetooth_address(kStoredBluetoothAddress); | |
532 synced_unlock_key.set_unlock_key(true); | |
533 synced_unlock_key.set_unlockable(false); | |
534 cryptauth::GetMyDevicesResponse get_my_devices_response; | |
535 get_my_devices_response.add_devices()->CopyFrom(synced_unlock_key); | |
536 success_callback_.Run(get_my_devices_response); | |
537 | |
538 // Check that unlock keys are still the same after sync. | |
539 ExpectUnlockKeysAndPrefAreEqual( | |
540 original_unlock_keys, device_manager_->unlock_keys(), pref_service_); | |
541 } | |
542 | |
543 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncEmptyDeviceList) { | |
544 cryptauth::GetMyDevicesResponse empty_response; | |
545 | |
546 device_manager_->Start(); | |
547 EXPECT_EQ(1u, device_manager_->unlock_keys().size()); | |
548 | |
549 FireSchedulerForSync(cryptauth::INVOCATION_REASON_PERIODIC); | |
550 ASSERT_FALSE(success_callback_.is_null()); | |
551 EXPECT_CALL(*this, OnSyncFinishedProxy( | |
552 CryptAuthDeviceManager::SyncResult::SUCCESS, | |
553 CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); | |
554 success_callback_.Run(empty_response); | |
555 | |
556 ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>(), | |
557 device_manager_->unlock_keys(), | |
558 pref_service_); | |
559 } | |
560 | |
561 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncTwoUnlockKeys) { | |
562 cryptauth::GetMyDevicesResponse response(get_my_devices_response_); | |
563 cryptauth::ExternalDeviceInfo unlock_key2; | |
564 unlock_key2.set_public_key("new public key"); | |
565 unlock_key2.set_friendly_device_name("new device name"); | |
566 unlock_key2.set_bluetooth_address("aa:bb:cc:dd:ee:ff"); | |
567 unlock_key2.set_unlock_key(true); | |
568 response.add_devices()->CopyFrom(unlock_key2); | |
569 | |
570 std::vector<cryptauth::ExternalDeviceInfo> expected_unlock_keys; | |
571 expected_unlock_keys.push_back(get_my_devices_response_.devices(0)); | |
572 expected_unlock_keys.push_back(unlock_key2); | |
573 | |
574 device_manager_->Start(); | |
575 EXPECT_EQ(1u, device_manager_->unlock_keys().size()); | |
576 EXPECT_EQ(1u, pref_service_.GetList(prefs::kCryptAuthDeviceSyncUnlockKeys) | |
577 ->GetSize()); | |
578 | |
579 FireSchedulerForSync(cryptauth::INVOCATION_REASON_PERIODIC); | |
580 ASSERT_FALSE(success_callback_.is_null()); | |
581 EXPECT_CALL(*this, OnSyncFinishedProxy( | |
582 CryptAuthDeviceManager::SyncResult::SUCCESS, | |
583 CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); | |
584 success_callback_.Run(response); | |
585 | |
586 ExpectUnlockKeysAndPrefAreEqual( | |
587 expected_unlock_keys, device_manager_->unlock_keys(), pref_service_); | |
588 } | |
589 | |
590 TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncOnGCMPushMessage) { | |
591 device_manager_->Start(); | |
592 | |
593 EXPECT_CALL(*sync_scheduler(), ForceSync()); | |
594 gcm_manager_.PushResyncMessage(); | |
595 | |
596 FireSchedulerForSync(cryptauth::INVOCATION_REASON_SERVER_INITIATED); | |
597 | |
598 EXPECT_CALL(*this, OnSyncFinishedProxy( | |
599 CryptAuthDeviceManager::SyncResult::SUCCESS, | |
600 CryptAuthDeviceManager::DeviceChangeResult::CHANGED)); | |
601 success_callback_.Run(get_my_devices_response_); | |
602 | |
603 ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>( | |
604 1, get_my_devices_response_.devices(0)), | |
605 device_manager_->unlock_keys(), | |
606 pref_service_); | |
607 } | |
608 | |
609 } // namespace proximity_auth | |
OLD | NEW |