Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: components/proximity_auth/cryptauth/cryptauth_enrollment_manager_unittest.cc

Issue 2502343003: Moved //components/proximity_auth/cryptauth to //components/cryptauth. (Closed)
Patch Set: Fixed proto #includes. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_enrollment_manager.h"
6
7 #include <utility>
8
9 #include "base/base64url.h"
10 #include "base/macros.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/test/simple_test_clock.h"
14 #include "base/time/clock.h"
15 #include "base/time/time.h"
16 #include "components/prefs/testing_pref_service.h"
17 #include "components/proximity_auth/cryptauth/cryptauth_enroller.h"
18 #include "components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h"
19 #include "components/proximity_auth/cryptauth/fake_secure_message_delegate.h"
20 #include "components/proximity_auth/cryptauth/mock_sync_scheduler.h"
21 #include "components/proximity_auth/cryptauth/pref_names.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 using ::testing::_;
26 using ::testing::NiceMock;
27 using ::testing::Return;
28 using ::testing::SaveArg;
29
30 namespace proximity_auth {
31
32 namespace {
33
34 // The GCM registration id from a successful registration.
35 const char kGCMRegistrationId[] = "new gcm registration id";
36
37 // The user's persistent public key identifying the local device.
38 const char kUserPublicKey[] = "user public key";
39
40 // The initial "Now" time for testing.
41 const double kInitialTimeNowSeconds = 20000000;
42
43 // A later "Now" time for testing.
44 const double kLaterTimeNow = kInitialTimeNowSeconds + 30;
45
46 // The timestamp of a last successful enrollment that is still valid.
47 const double kLastEnrollmentTimeSeconds =
48 kInitialTimeNowSeconds - (60 * 60 * 24 * 15);
49
50 // The timestamp of a last successful enrollment that is expired.
51 const double kLastExpiredEnrollmentTimeSeconds =
52 kInitialTimeNowSeconds - (60 * 60 * 24 * 100);
53
54 // Mocks out the actual enrollment flow.
55 class MockCryptAuthEnroller : public CryptAuthEnroller {
56 public:
57 MockCryptAuthEnroller() {}
58 ~MockCryptAuthEnroller() override {}
59
60 MOCK_METHOD5(Enroll,
61 void(const std::string& user_public_key,
62 const std::string& user_private_key,
63 const cryptauth::GcmDeviceInfo& device_info,
64 cryptauth::InvocationReason invocation_reason,
65 const EnrollmentFinishedCallback& callback));
66
67 private:
68 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthEnroller);
69 };
70
71 // Creates MockCryptAuthEnroller instances, and allows expecations to be set
72 // before they are returned.
73 class MockCryptAuthEnrollerFactory : public CryptAuthEnrollerFactory {
74 public:
75 MockCryptAuthEnrollerFactory()
76 : next_cryptauth_enroller_(new NiceMock<MockCryptAuthEnroller>()) {}
77 ~MockCryptAuthEnrollerFactory() override {}
78
79 // CryptAuthEnrollerFactory:
80 std::unique_ptr<CryptAuthEnroller> CreateInstance() override {
81 auto passed_cryptauth_enroller = std::move(next_cryptauth_enroller_);
82 next_cryptauth_enroller_.reset(new NiceMock<MockCryptAuthEnroller>());
83 return std::move(passed_cryptauth_enroller);
84 }
85
86 MockCryptAuthEnroller* next_cryptauth_enroller() {
87 return next_cryptauth_enroller_.get();
88 }
89
90 private:
91 // Stores the next CryptAuthEnroller to be created.
92 // Ownership is passed to the caller of |CreateInstance()|.
93 std::unique_ptr<MockCryptAuthEnroller> next_cryptauth_enroller_;
94
95 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthEnrollerFactory);
96 };
97
98 // Harness for testing CryptAuthEnrollmentManager.
99 class TestCryptAuthEnrollmentManager : public CryptAuthEnrollmentManager {
100 public:
101 TestCryptAuthEnrollmentManager(
102 std::unique_ptr<base::Clock> clock,
103 std::unique_ptr<CryptAuthEnrollerFactory> enroller_factory,
104 std::unique_ptr<SecureMessageDelegate> secure_message_delegate,
105 const cryptauth::GcmDeviceInfo& device_info,
106 CryptAuthGCMManager* gcm_manager,
107 PrefService* pref_service)
108 : CryptAuthEnrollmentManager(std::move(clock),
109 std::move(enroller_factory),
110 std::move(secure_message_delegate),
111 device_info,
112 gcm_manager,
113 pref_service),
114 scoped_sync_scheduler_(new NiceMock<MockSyncScheduler>()),
115 weak_sync_scheduler_factory_(scoped_sync_scheduler_.get()) {}
116
117 ~TestCryptAuthEnrollmentManager() override {}
118
119 std::unique_ptr<SyncScheduler> CreateSyncScheduler() override {
120 EXPECT_TRUE(scoped_sync_scheduler_);
121 return std::move(scoped_sync_scheduler_);
122 }
123
124 base::WeakPtr<MockSyncScheduler> GetSyncScheduler() {
125 return weak_sync_scheduler_factory_.GetWeakPtr();
126 }
127
128 private:
129 // Ownership is passed to |CryptAuthEnrollmentManager| super class when
130 // |CreateSyncScheduler()| is called.
131 std::unique_ptr<MockSyncScheduler> scoped_sync_scheduler_;
132
133 // Stores the pointer of |scoped_sync_scheduler_| after ownership is passed to
134 // the super class.
135 // This should be safe because the life-time this SyncScheduler will always be
136 // within the life of the TestCryptAuthEnrollmentManager object.
137 base::WeakPtrFactory<MockSyncScheduler> weak_sync_scheduler_factory_;
138
139 DISALLOW_COPY_AND_ASSIGN(TestCryptAuthEnrollmentManager);
140 };
141
142 } // namespace
143
144 class ProximityAuthCryptAuthEnrollmentManagerTest
145 : public testing::Test,
146 public CryptAuthEnrollmentManager::Observer {
147 protected:
148 ProximityAuthCryptAuthEnrollmentManagerTest()
149 : public_key_(kUserPublicKey),
150 clock_(new base::SimpleTestClock()),
151 enroller_factory_(new MockCryptAuthEnrollerFactory()),
152 secure_message_delegate_(new FakeSecureMessageDelegate()),
153 gcm_manager_(kGCMRegistrationId),
154 enrollment_manager_(base::WrapUnique(clock_),
155 base::WrapUnique(enroller_factory_),
156 base::WrapUnique(secure_message_delegate_),
157 device_info_,
158 &gcm_manager_,
159 &pref_service_) {}
160
161 // testing::Test:
162 void SetUp() override {
163 clock_->SetNow(base::Time::FromDoubleT(kInitialTimeNowSeconds));
164 enrollment_manager_.AddObserver(this);
165
166 private_key_ =
167 secure_message_delegate_->GetPrivateKeyForPublicKey(public_key_);
168 secure_message_delegate_->set_next_public_key(public_key_);
169
170 CryptAuthEnrollmentManager::RegisterPrefs(pref_service_.registry());
171 pref_service_.SetUserPref(
172 prefs::kCryptAuthEnrollmentIsRecoveringFromFailure,
173 new base::FundamentalValue(false));
174 pref_service_.SetUserPref(
175 prefs::kCryptAuthEnrollmentLastEnrollmentTimeSeconds,
176 new base::FundamentalValue(kLastEnrollmentTimeSeconds));
177 pref_service_.SetUserPref(
178 prefs::kCryptAuthEnrollmentReason,
179 new base::FundamentalValue(cryptauth::INVOCATION_REASON_UNKNOWN));
180
181 std::string public_key_b64, private_key_b64;
182 base::Base64UrlEncode(public_key_,
183 base::Base64UrlEncodePolicy::INCLUDE_PADDING,
184 &public_key_b64);
185 base::Base64UrlEncode(private_key_,
186 base::Base64UrlEncodePolicy::INCLUDE_PADDING,
187 &private_key_b64);
188 pref_service_.SetString(prefs::kCryptAuthEnrollmentUserPublicKey,
189 public_key_b64);
190 pref_service_.SetString(prefs::kCryptAuthEnrollmentUserPrivateKey,
191 private_key_b64);
192
193 ON_CALL(*sync_scheduler(), GetStrategy())
194 .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
195 }
196
197 void TearDown() override { enrollment_manager_.RemoveObserver(this); }
198
199 // CryptAuthEnrollmentManager::Observer:
200 void OnEnrollmentStarted() override { OnEnrollmentStartedProxy(); }
201
202 void OnEnrollmentFinished(bool success) override {
203 // Simulate the scheduler changing strategies based on success or failure.
204 SyncScheduler::Strategy new_strategy =
205 SyncScheduler::Strategy::AGGRESSIVE_RECOVERY;
206 ON_CALL(*sync_scheduler(), GetStrategy())
207 .WillByDefault(Return(new_strategy));
208
209 OnEnrollmentFinishedProxy(success);
210 }
211
212 MOCK_METHOD0(OnEnrollmentStartedProxy, void());
213 MOCK_METHOD1(OnEnrollmentFinishedProxy, void(bool success));
214
215 // Simulates firing the SyncScheduler to trigger an enrollment attempt.
216 CryptAuthEnroller::EnrollmentFinishedCallback FireSchedulerForEnrollment(
217 cryptauth::InvocationReason expected_invocation_reason) {
218 CryptAuthEnroller::EnrollmentFinishedCallback completion_callback;
219 EXPECT_CALL(
220 *next_cryptauth_enroller(),
221 Enroll(public_key_, private_key_, _, expected_invocation_reason, _))
222 .WillOnce(SaveArg<4>(&completion_callback));
223
224 auto sync_request = base::MakeUnique<SyncScheduler::SyncRequest>(
225 enrollment_manager_.GetSyncScheduler());
226 EXPECT_CALL(*this, OnEnrollmentStartedProxy());
227
228 SyncScheduler::Delegate* delegate =
229 static_cast<SyncScheduler::Delegate*>(&enrollment_manager_);
230 delegate->OnSyncRequested(std::move(sync_request));
231
232 return completion_callback;
233 }
234
235 MockSyncScheduler* sync_scheduler() {
236 return enrollment_manager_.GetSyncScheduler().get();
237 }
238
239 MockCryptAuthEnroller* next_cryptauth_enroller() {
240 return enroller_factory_->next_cryptauth_enroller();
241 }
242
243 // The expected persistent keypair.
244 std::string public_key_;
245 std::string private_key_;
246
247 // Owned by |enrollment_manager_|.
248 base::SimpleTestClock* clock_;
249
250 // Owned by |enrollment_manager_|.
251 MockCryptAuthEnrollerFactory* enroller_factory_;
252
253 // Ownered by |enrollment_manager_|.
254 FakeSecureMessageDelegate* secure_message_delegate_;
255
256 cryptauth::GcmDeviceInfo device_info_;
257
258 TestingPrefServiceSimple pref_service_;
259
260 FakeCryptAuthGCMManager gcm_manager_;
261
262 TestCryptAuthEnrollmentManager enrollment_manager_;
263
264 DISALLOW_COPY_AND_ASSIGN(ProximityAuthCryptAuthEnrollmentManagerTest);
265 };
266
267 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, RegisterPrefs) {
268 TestingPrefServiceSimple pref_service;
269 CryptAuthEnrollmentManager::RegisterPrefs(pref_service.registry());
270 EXPECT_TRUE(pref_service.FindPreference(
271 prefs::kCryptAuthEnrollmentLastEnrollmentTimeSeconds));
272 EXPECT_TRUE(pref_service.FindPreference(
273 prefs::kCryptAuthEnrollmentIsRecoveringFromFailure));
274 EXPECT_TRUE(pref_service.FindPreference(prefs::kCryptAuthEnrollmentReason));
275 }
276
277 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, GetEnrollmentState) {
278 enrollment_manager_.Start();
279
280 ON_CALL(*sync_scheduler(), GetStrategy())
281 .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
282 EXPECT_FALSE(enrollment_manager_.IsRecoveringFromFailure());
283
284 ON_CALL(*sync_scheduler(), GetStrategy())
285 .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY));
286 EXPECT_TRUE(enrollment_manager_.IsRecoveringFromFailure());
287
288 base::TimeDelta time_to_next_sync = base::TimeDelta::FromMinutes(60);
289 ON_CALL(*sync_scheduler(), GetTimeToNextSync())
290 .WillByDefault(Return(time_to_next_sync));
291 EXPECT_EQ(time_to_next_sync, enrollment_manager_.GetTimeToNextAttempt());
292
293 ON_CALL(*sync_scheduler(), GetSyncState())
294 .WillByDefault(Return(SyncScheduler::SyncState::SYNC_IN_PROGRESS));
295 EXPECT_TRUE(enrollment_manager_.IsEnrollmentInProgress());
296
297 ON_CALL(*sync_scheduler(), GetSyncState())
298 .WillByDefault(Return(SyncScheduler::SyncState::WAITING_FOR_REFRESH));
299 EXPECT_FALSE(enrollment_manager_.IsEnrollmentInProgress());
300 }
301
302 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, InitWithDefaultPrefs) {
303 std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
304 clock->SetNow(base::Time::FromDoubleT(kInitialTimeNowSeconds));
305 base::TimeDelta elapsed_time = clock->Now() - base::Time::FromDoubleT(0);
306
307 TestingPrefServiceSimple pref_service;
308 CryptAuthEnrollmentManager::RegisterPrefs(pref_service.registry());
309
310 TestCryptAuthEnrollmentManager enrollment_manager(
311 std::move(clock), base::MakeUnique<MockCryptAuthEnrollerFactory>(),
312 base::MakeUnique<FakeSecureMessageDelegate>(), device_info_,
313 &gcm_manager_, &pref_service);
314
315 EXPECT_CALL(
316 *enrollment_manager.GetSyncScheduler(),
317 Start(elapsed_time, SyncScheduler::Strategy::AGGRESSIVE_RECOVERY));
318 enrollment_manager.Start();
319
320 EXPECT_FALSE(enrollment_manager.IsEnrollmentValid());
321 EXPECT_TRUE(enrollment_manager.GetLastEnrollmentTime().is_null());
322 }
323
324 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, InitWithExistingPrefs) {
325 EXPECT_CALL(
326 *sync_scheduler(),
327 Start(clock_->Now() - base::Time::FromDoubleT(kLastEnrollmentTimeSeconds),
328 SyncScheduler::Strategy::PERIODIC_REFRESH));
329
330 enrollment_manager_.Start();
331 EXPECT_TRUE(enrollment_manager_.IsEnrollmentValid());
332 EXPECT_EQ(base::Time::FromDoubleT(kLastEnrollmentTimeSeconds),
333 enrollment_manager_.GetLastEnrollmentTime());
334 }
335
336 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, InitWithExpiredEnrollment) {
337 pref_service_.SetUserPref(
338 prefs::kCryptAuthEnrollmentLastEnrollmentTimeSeconds,
339 new base::FundamentalValue(kLastExpiredEnrollmentTimeSeconds));
340
341 EXPECT_CALL(*sync_scheduler(),
342 Start(clock_->Now() - base::Time::FromDoubleT(
343 kLastExpiredEnrollmentTimeSeconds),
344 SyncScheduler::Strategy::AGGRESSIVE_RECOVERY));
345
346 enrollment_manager_.Start();
347 EXPECT_FALSE(enrollment_manager_.IsEnrollmentValid());
348 EXPECT_EQ(base::Time::FromDoubleT(kLastExpiredEnrollmentTimeSeconds),
349 enrollment_manager_.GetLastEnrollmentTime());
350 }
351
352 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, ForceEnrollment) {
353 enrollment_manager_.Start();
354
355 EXPECT_CALL(*sync_scheduler(), ForceSync());
356 enrollment_manager_.ForceEnrollmentNow(
357 cryptauth::INVOCATION_REASON_SERVER_INITIATED);
358
359 auto completion_callback =
360 FireSchedulerForEnrollment(cryptauth::INVOCATION_REASON_SERVER_INITIATED);
361
362 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNow));
363 EXPECT_CALL(*this, OnEnrollmentFinishedProxy(true));
364 completion_callback.Run(true);
365 EXPECT_EQ(clock_->Now(), enrollment_manager_.GetLastEnrollmentTime());
366 }
367
368 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest,
369 EnrollmentFailsThenSucceeds) {
370 enrollment_manager_.Start();
371 base::Time old_enrollment_time = enrollment_manager_.GetLastEnrollmentTime();
372
373 // The first periodic enrollment fails.
374 ON_CALL(*sync_scheduler(), GetStrategy())
375 .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
376 auto completion_callback =
377 FireSchedulerForEnrollment(cryptauth::INVOCATION_REASON_PERIODIC);
378 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNow));
379 EXPECT_CALL(*this, OnEnrollmentFinishedProxy(false));
380 completion_callback.Run(false);
381 EXPECT_EQ(old_enrollment_time, enrollment_manager_.GetLastEnrollmentTime());
382 EXPECT_TRUE(pref_service_.GetBoolean(
383 prefs::kCryptAuthEnrollmentIsRecoveringFromFailure));
384
385 // The second recovery enrollment succeeds.
386 ON_CALL(*sync_scheduler(), GetStrategy())
387 .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY));
388 completion_callback =
389 FireSchedulerForEnrollment(cryptauth::INVOCATION_REASON_FAILURE_RECOVERY);
390 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNow + 30));
391 EXPECT_CALL(*this, OnEnrollmentFinishedProxy(true));
392 completion_callback.Run(true);
393 EXPECT_EQ(clock_->Now(), enrollment_manager_.GetLastEnrollmentTime());
394 EXPECT_FALSE(pref_service_.GetBoolean(
395 prefs::kCryptAuthEnrollmentIsRecoveringFromFailure));
396 }
397
398 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest,
399 EnrollmentSucceedsForFirstTime) {
400 // Initialize |enrollment_manager_|.
401 ON_CALL(*sync_scheduler(), GetStrategy())
402 .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
403 gcm_manager_.set_registration_id(std::string());
404 pref_service_.ClearPref(prefs::kCryptAuthEnrollmentUserPublicKey);
405 pref_service_.ClearPref(prefs::kCryptAuthEnrollmentUserPrivateKey);
406 pref_service_.ClearPref(prefs::kCryptAuthEnrollmentLastEnrollmentTimeSeconds);
407 enrollment_manager_.Start();
408 EXPECT_FALSE(enrollment_manager_.IsEnrollmentValid());
409
410 // Trigger a sync request.
411 EXPECT_CALL(*this, OnEnrollmentStartedProxy());
412 auto sync_request = base::MakeUnique<SyncScheduler::SyncRequest>(
413 enrollment_manager_.GetSyncScheduler());
414 static_cast<SyncScheduler::Delegate*>(&enrollment_manager_)
415 ->OnSyncRequested(std::move(sync_request));
416
417 // Complete GCM registration successfully, and expect an enrollment.
418 CryptAuthEnroller::EnrollmentFinishedCallback enrollment_callback;
419 EXPECT_CALL(*next_cryptauth_enroller(),
420 Enroll(public_key_, private_key_, _,
421 cryptauth::INVOCATION_REASON_INITIALIZATION, _))
422 .WillOnce(SaveArg<4>(&enrollment_callback));
423 ASSERT_TRUE(gcm_manager_.registration_in_progress());
424 gcm_manager_.CompleteRegistration(kGCMRegistrationId);
425
426 // Complete CryptAuth enrollment.
427 ASSERT_FALSE(enrollment_callback.is_null());
428 clock_->SetNow(base::Time::FromDoubleT(kLaterTimeNow));
429 EXPECT_CALL(*this, OnEnrollmentFinishedProxy(true));
430 enrollment_callback.Run(true);
431 EXPECT_EQ(clock_->Now(), enrollment_manager_.GetLastEnrollmentTime());
432 EXPECT_TRUE(enrollment_manager_.IsEnrollmentValid());
433
434 // Check that CryptAuthEnrollmentManager returns the expected key-pair.
435 EXPECT_EQ(public_key_, enrollment_manager_.GetUserPublicKey());
436 EXPECT_EQ(private_key_, enrollment_manager_.GetUserPrivateKey());
437 }
438
439 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, GCMRegistrationFails) {
440 // Initialize |enrollment_manager_|.
441 ON_CALL(*sync_scheduler(), GetStrategy())
442 .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
443 gcm_manager_.set_registration_id(std::string());
444 enrollment_manager_.Start();
445
446 // Trigger a sync request.
447 EXPECT_CALL(*this, OnEnrollmentStartedProxy());
448 auto sync_request = base::MakeUnique<SyncScheduler::SyncRequest>(
449 enrollment_manager_.GetSyncScheduler());
450 static_cast<SyncScheduler::Delegate*>(&enrollment_manager_)
451 ->OnSyncRequested(std::move(sync_request));
452
453 // Complete GCM registration with failure.
454 EXPECT_CALL(*this, OnEnrollmentFinishedProxy(false));
455 gcm_manager_.CompleteRegistration(std::string());
456 }
457
458 TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, ReenrollOnGCMPushMessage) {
459 enrollment_manager_.Start();
460
461 // Simulate receiving a GCM push message, forcing the device to re-enroll.
462 gcm_manager_.PushReenrollMessage();
463 auto completion_callback =
464 FireSchedulerForEnrollment(cryptauth::INVOCATION_REASON_SERVER_INITIATED);
465
466 EXPECT_CALL(*this, OnEnrollmentFinishedProxy(true));
467 completion_callback.Run(true);
468 }
469
470 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698