OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2010 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/login/parallel_authenticator.h" | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
10 #include "base/file_path.h" | |
11 #include "base/file_util.h" | |
12 #include "base/message_loop.h" | |
13 #include "base/path_service.h" | |
14 #include "base/scoped_ptr.h" | |
15 #include "base/string_util.h" | |
16 #include "base/stringprintf.h" | |
17 #include "chrome/browser/chrome_thread.h" | |
18 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" | |
19 #include "chrome/browser/chromeos/cros/mock_library_loader.h" | |
20 #include "chrome/browser/chromeos/login/mock_auth_response_handler.h" | |
21 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h" | |
22 #include "chrome/browser/chromeos/login/mock_url_fetchers.h" | |
23 #include "chrome/browser/chromeos/login/test_attempt_state.h" | |
24 #include "chrome/common/chrome_paths.h" | |
25 #include "chrome/common/net/gaia/gaia_authenticator2_unittest.h" | |
26 #include "chrome/common/net/url_fetcher.h" | |
27 #include "chrome/test/testing_profile.h" | |
28 #include "googleurl/src/gurl.h" | |
29 #include "net/base/net_errors.h" | |
30 #include "net/url_request/url_request_status.h" | |
31 #include "testing/gmock/include/gmock/gmock.h" | |
32 #include "testing/gtest/include/gtest/gtest.h" | |
33 | |
34 using namespace file_util; | |
35 using ::testing::AnyNumber; | |
36 using ::testing::DoAll; | |
37 using ::testing::Invoke; | |
38 using ::testing::Return; | |
39 using ::testing::SetArgumentPointee; | |
40 using ::testing::_; | |
41 | |
42 namespace chromeos { | |
43 | |
44 class ParallelAuthenticatorTest : public ::testing::Test { | |
45 public: | |
46 ParallelAuthenticatorTest() | |
47 : message_loop_(MessageLoop::TYPE_UI), | |
48 ui_thread_(ChromeThread::UI, &message_loop_), | |
49 file_thread_(ChromeThread::FILE), | |
50 io_thread_(ChromeThread::IO), | |
51 username_("me@nowhere.org") { | |
52 hash_ascii_.assign("0a010000000000a0"); | |
53 hash_ascii_.append(std::string(16, '0')); | |
54 } | |
55 | |
56 ~ParallelAuthenticatorTest() {} | |
57 | |
58 virtual void SetUp() { | |
59 chromeos::CrosLibrary::TestApi* test_api = | |
60 chromeos::CrosLibrary::Get()->GetTestApi(); | |
61 | |
62 loader_ = new MockLibraryLoader(); | |
63 ON_CALL(*loader_, Load(_)) | |
64 .WillByDefault(Return(true)); | |
65 EXPECT_CALL(*loader_, Load(_)) | |
66 .Times(AnyNumber()); | |
67 | |
68 test_api->SetLibraryLoader(loader_, true); | |
69 | |
70 mock_library_ = new MockCryptohomeLibrary(); | |
71 test_api->SetCryptohomeLibrary(mock_library_, true); | |
72 file_thread_.Start(); | |
73 io_thread_.Start(); | |
74 | |
75 auth_ = new ParallelAuthenticator(&consumer_); | |
76 state_ = new TestAttemptState(username_, "", hash_ascii_, "", ""); | |
77 } | |
78 | |
79 // Tears down the test fixture. | |
80 virtual void TearDown() { | |
81 // Prevent bogus gMock leak check from firing. | |
82 chromeos::CrosLibrary::TestApi* test_api = | |
83 chromeos::CrosLibrary::Get()->GetTestApi(); | |
84 test_api->SetLibraryLoader(NULL, false); | |
85 test_api->SetCryptohomeLibrary(NULL, false); | |
86 } | |
87 | |
88 FilePath PopulateTempFile(const char* data, int data_len) { | |
89 FilePath out; | |
90 FILE* tmp_file = CreateAndOpenTemporaryFile(&out); | |
91 EXPECT_NE(tmp_file, reinterpret_cast<FILE*>(NULL)); | |
92 EXPECT_EQ(WriteFile(out, data, data_len), data_len); | |
93 EXPECT_TRUE(CloseFile(tmp_file)); | |
94 return out; | |
95 } | |
96 | |
97 FilePath FakeLocalaccountFile(const std::string& ascii) { | |
98 FilePath exe_dir; | |
99 FilePath local_account_file; | |
100 PathService::Get(base::DIR_EXE, &exe_dir); | |
101 FILE* tmp_file = CreateAndOpenTemporaryFileInDir(exe_dir, | |
102 &local_account_file); | |
103 int ascii_len = ascii.length(); | |
104 EXPECT_NE(tmp_file, reinterpret_cast<FILE*>(NULL)); | |
105 EXPECT_EQ(WriteFile(local_account_file, ascii.c_str(), ascii_len), | |
106 ascii_len); | |
107 EXPECT_TRUE(CloseFile(tmp_file)); | |
108 return local_account_file; | |
109 } | |
110 | |
111 void ReadLocalaccountFile(ParallelAuthenticator* auth, | |
112 const std::string& filename) { | |
113 ChromeThread::PostTask( | |
114 ChromeThread::FILE, FROM_HERE, | |
115 NewRunnableMethod(auth, | |
116 &ParallelAuthenticator::LoadLocalaccount, | |
117 filename)); | |
118 file_thread_.Stop(); | |
119 file_thread_.Start(); | |
120 } | |
121 | |
122 // Allow test to fail and exit gracefully, even if OnLoginFailure() | |
123 // wasn't supposed to happen. | |
124 void FailOnLoginFailure() { | |
125 ON_CALL(consumer_, OnLoginFailure(_)) | |
126 .WillByDefault(Invoke(MockConsumer::OnFailQuitAndFail)); | |
127 } | |
128 | |
129 // Allow test to fail and exit gracefully, even if OnLoginSuccess() | |
130 // wasn't supposed to happen. | |
131 void FailOnLoginSuccess() { | |
132 ON_CALL(consumer_, OnLoginSuccess(_, _, _)) | |
133 .WillByDefault(Invoke(MockConsumer::OnSuccessQuitAndFail)); | |
134 } | |
135 | |
136 // Allow test to fail and exit gracefully, even if | |
137 // OnOffTheRecordLoginSuccess() wasn't supposed to happen. | |
138 void FailOnGuestLoginSuccess() { | |
139 ON_CALL(consumer_, OnOffTheRecordLoginSuccess()) | |
140 .WillByDefault(Invoke(MockConsumer::OnGuestSuccessQuitAndFail)); | |
141 } | |
142 | |
143 void ExpectLoginFailure(const LoginFailure& failure) { | |
144 EXPECT_CALL(consumer_, OnLoginFailure(failure)) | |
145 .WillOnce(Invoke(MockConsumer::OnFailQuit)) | |
146 .RetiresOnSaturation(); | |
147 } | |
148 | |
149 void ExpectLoginSuccess(const std::string& username, | |
150 const GaiaAuthConsumer::ClientLoginResult& result, | |
151 bool pending) { | |
152 EXPECT_CALL(consumer_, OnLoginSuccess(username, result, pending)) | |
153 .WillOnce(Invoke(MockConsumer::OnSuccessQuit)) | |
154 .RetiresOnSaturation(); | |
155 } | |
156 | |
157 void ExpectGuestLoginSuccess() { | |
158 EXPECT_CALL(consumer_, OnOffTheRecordLoginSuccess()) | |
159 .WillOnce(Invoke(MockConsumer::OnGuestSuccessQuit)) | |
160 .RetiresOnSaturation(); | |
161 } | |
162 | |
163 void ExpectPasswordChange() { | |
164 EXPECT_CALL(consumer_, OnPasswordChangeDetected(result_)) | |
165 .WillOnce(Invoke(MockConsumer::OnMigrateQuit)) | |
166 .RetiresOnSaturation(); | |
167 } | |
168 | |
169 void RunResolve(ParallelAuthenticator* auth, MessageLoop* loop) { | |
170 ChromeThread::PostTask( | |
171 ChromeThread::IO, FROM_HERE, | |
172 NewRunnableMethod(auth, &ParallelAuthenticator::Resolve)); | |
173 loop->Run(); | |
174 } | |
175 | |
176 void SetAttemptState(ParallelAuthenticator* auth, TestAttemptState* state) { | |
177 auth->set_attempt_state(state); | |
178 } | |
179 | |
180 static void CheckResolve(TestAttemptState* state, | |
181 ParallelAuthenticator* auth, | |
182 ParallelAuthenticator::AuthState expected) { | |
183 auth->set_attempt_state(state); | |
184 EXPECT_EQ(expected, auth->ResolveState()); | |
185 } | |
186 | |
187 MessageLoop message_loop_; | |
188 ChromeThread ui_thread_; | |
189 ChromeThread file_thread_; | |
190 ChromeThread io_thread_; | |
191 | |
192 std::string username_; | |
193 std::string hash_ascii_; | |
194 GaiaAuthConsumer::ClientLoginResult result_; | |
195 | |
196 // Mocks, destroyed by CrosLibrary class. | |
197 MockCryptohomeLibrary* mock_library_; | |
198 MockLibraryLoader* loader_; | |
199 | |
200 MockConsumer consumer_; | |
201 scoped_refptr<ParallelAuthenticator> auth_; | |
202 TestAttemptState* state_; | |
203 }; | |
204 | |
205 TEST_F(ParallelAuthenticatorTest, SaltToAscii) { | |
206 unsigned char fake_salt[8] = { 0 }; | |
207 fake_salt[0] = 10; | |
208 fake_salt[1] = 1; | |
209 fake_salt[7] = 10 << 4; | |
210 std::vector<unsigned char> salt_v(fake_salt, fake_salt + sizeof(fake_salt)); | |
211 | |
212 ON_CALL(*mock_library_, GetSystemSalt()) | |
213 .WillByDefault(Return(salt_v)); | |
214 EXPECT_CALL(*mock_library_, GetSystemSalt()) | |
215 .Times(1) | |
216 .RetiresOnSaturation(); | |
217 | |
218 EXPECT_EQ("0a010000000000a0", auth_->SaltAsAscii()); | |
219 } | |
220 | |
221 TEST_F(ParallelAuthenticatorTest, ReadLocalaccount) { | |
222 FilePath tmp_file_path = FakeLocalaccountFile(username_); | |
223 | |
224 ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); | |
225 EXPECT_EQ(auth_->localaccount_, username_); | |
226 Delete(tmp_file_path, false); | |
227 } | |
228 | |
229 TEST_F(ParallelAuthenticatorTest, ReadLocalaccountTrailingWS) { | |
230 FilePath tmp_file_path = | |
231 FakeLocalaccountFile(base::StringPrintf("%s\n", username_.c_str())); | |
232 | |
233 ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); | |
234 EXPECT_EQ(auth_->localaccount_, username_); | |
235 Delete(tmp_file_path, false); | |
236 } | |
237 | |
238 TEST_F(ParallelAuthenticatorTest, ReadNoLocalaccount) { | |
239 FilePath tmp_file_path = FakeLocalaccountFile(username_); | |
240 EXPECT_TRUE(Delete(tmp_file_path, false)); // Ensure non-existent file. | |
241 | |
242 ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); | |
243 EXPECT_EQ(auth_->localaccount_, std::string()); | |
244 } | |
245 | |
246 TEST_F(ParallelAuthenticatorTest, OnLoginSuccess) { | |
247 EXPECT_CALL(consumer_, OnLoginSuccess(username_, result_, false)) | |
248 .Times(1) | |
249 .RetiresOnSaturation(); | |
250 | |
251 SetAttemptState(auth_, state_); | |
252 auth_->OnLoginSuccess(result_, false); | |
253 } | |
254 | |
255 TEST_F(ParallelAuthenticatorTest, OnPasswordChangeDetected) { | |
256 EXPECT_CALL(consumer_, OnPasswordChangeDetected(result_)) | |
257 .Times(1) | |
258 .RetiresOnSaturation(); | |
259 SetAttemptState(auth_, state_); | |
260 auth_->OnPasswordChangeDetected(result_); | |
261 } | |
262 | |
263 TEST_F(ParallelAuthenticatorTest, ResolveNothingDone) { | |
264 ChromeThread::PostTask( | |
265 ChromeThread::IO, FROM_HERE, | |
266 NewRunnableFunction(&ParallelAuthenticatorTest::CheckResolve, | |
267 state_, | |
268 auth_.get(), | |
269 ParallelAuthenticator::CONTINUE)); | |
270 } | |
271 | |
272 TEST_F(ParallelAuthenticatorTest, ResolvePossiblePwChange) { | |
273 // Set up state as though a cryptohome mount attempt has occurred | |
274 // and been rejected. | |
275 state_->PresetCryptohomeStatus(false, | |
276 chromeos::kCryptohomeMountErrorKeyFailure); | |
277 ChromeThread::PostTask( | |
278 ChromeThread::IO, FROM_HERE, | |
279 NewRunnableFunction(&ParallelAuthenticatorTest::CheckResolve, | |
280 state_, | |
281 auth_.get(), | |
282 ParallelAuthenticator::POSSIBLE_PW_CHANGE)); | |
283 } | |
284 | |
285 TEST_F(ParallelAuthenticatorTest, DriveFailedMount) { | |
286 FailOnLoginSuccess(); | |
287 ExpectLoginFailure(LoginFailure(LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME)); | |
288 | |
289 // Set up state as though a cryptohome mount attempt has occurred | |
290 // and failed. | |
291 state_->PresetCryptohomeStatus(false, 0); | |
292 SetAttemptState(auth_, state_); | |
293 | |
294 RunResolve(auth_.get(), &message_loop_); | |
295 } | |
296 | |
297 TEST_F(ParallelAuthenticatorTest, DriveGuestLogin) { | |
298 ExpectGuestLoginSuccess(); | |
299 FailOnLoginFailure(); | |
300 | |
301 // Set up mock cryptohome library to respond as though a tmpfs mount | |
302 // attempt has occurred and succeeded. | |
303 mock_library_->SetUp(true, 0); | |
304 EXPECT_CALL(*mock_library_, AsyncMountForBwsi(_)) | |
305 .Times(1) | |
306 .RetiresOnSaturation(); | |
307 | |
308 auth_->LoginOffTheRecord(); | |
309 message_loop_.Run(); | |
310 } | |
311 | |
312 TEST_F(ParallelAuthenticatorTest, DriveGuestLoginButFail) { | |
313 FailOnGuestLoginSuccess(); | |
314 ExpectLoginFailure(LoginFailure(LoginFailure::COULD_NOT_MOUNT_TMPFS)); | |
315 | |
316 // Set up mock cryptohome library to respond as though a tmpfs mount | |
317 // attempt has occurred and failed. | |
318 mock_library_->SetUp(false, 0); | |
319 EXPECT_CALL(*mock_library_, AsyncMountForBwsi(_)) | |
320 .Times(1) | |
321 .RetiresOnSaturation(); | |
322 | |
323 auth_->LoginOffTheRecord(); | |
324 message_loop_.Run(); | |
325 } | |
326 | |
327 TEST_F(ParallelAuthenticatorTest, DriveDataResync) { | |
328 ExpectLoginSuccess(username_, result_, false); | |
329 FailOnLoginFailure(); | |
330 | |
331 // Set up mock cryptohome library to respond successfully to a cryptohome | |
332 // remove attempt and a cryptohome create attempt (specified by the |true| | |
333 // argument to AsyncMount). | |
334 mock_library_->SetUp(true, 0); | |
335 EXPECT_CALL(*mock_library_, AsyncRemove(username_, _)) | |
336 .Times(1) | |
337 .RetiresOnSaturation(); | |
338 EXPECT_CALL(*mock_library_, AsyncMount(username_, hash_ascii_, true, _)) | |
339 .Times(1) | |
340 .RetiresOnSaturation(); | |
341 | |
342 state_->PresetOnlineLoginStatus(result_, LoginFailure::None()); | |
343 SetAttemptState(auth_, state_); | |
344 | |
345 auth_->ResyncEncryptedData(result_); | |
346 message_loop_.Run(); | |
347 } | |
348 | |
349 TEST_F(ParallelAuthenticatorTest, DriveResyncFail) { | |
350 FailOnLoginSuccess(); | |
351 ExpectLoginFailure(LoginFailure(LoginFailure::DATA_REMOVAL_FAILED)); | |
352 | |
353 // Set up mock cryptohome library to fail a cryptohome remove attempt. | |
354 mock_library_->SetUp(false, 0); | |
355 EXPECT_CALL(*mock_library_, AsyncRemove(username_, _)) | |
356 .Times(1) | |
357 .RetiresOnSaturation(); | |
358 | |
359 SetAttemptState(auth_, state_); | |
360 | |
361 auth_->ResyncEncryptedData(result_); | |
362 message_loop_.Run(); | |
363 } | |
364 | |
365 TEST_F(ParallelAuthenticatorTest, DriveRequestOldPassword) { | |
366 FailOnLoginSuccess(); | |
367 ExpectPasswordChange(); | |
368 | |
369 state_->PresetCryptohomeStatus(false, | |
370 chromeos::kCryptohomeMountErrorKeyFailure); | |
Nikita (slow)
2010/10/07 22:43:06
nit: indent
| |
371 state_->PresetOnlineLoginStatus(result_, LoginFailure::None()); | |
372 SetAttemptState(auth_, state_); | |
373 | |
374 RunResolve(auth_.get(), &message_loop_); | |
375 } | |
376 | |
377 TEST_F(ParallelAuthenticatorTest, DriveDataRecover) { | |
378 ExpectLoginSuccess(username_, result_, false); | |
379 FailOnLoginFailure(); | |
380 | |
381 // Set up mock cryptohome library to respond successfully to a key migration. | |
382 mock_library_->SetUp(true, 0); | |
383 EXPECT_CALL(*mock_library_, AsyncMigrateKey(username_, _, hash_ascii_, _)) | |
Nikita (slow)
2010/10/07 22:43:06
It's possible to test correct sequence of calls to
| |
384 .Times(1) | |
385 .RetiresOnSaturation(); | |
386 EXPECT_CALL(*mock_library_, AsyncMount(username_, hash_ascii_, false, _)) | |
387 .Times(1) | |
388 .RetiresOnSaturation(); | |
389 EXPECT_CALL(*mock_library_, GetSystemSalt()) | |
390 .WillOnce(Return(CryptohomeBlob(2, 0))) | |
391 .RetiresOnSaturation(); | |
392 | |
393 state_->PresetOnlineLoginStatus(result_, LoginFailure::None()); | |
394 SetAttemptState(auth_, state_); | |
395 | |
396 auth_->RecoverEncryptedData(std::string(), result_); | |
397 message_loop_.Run(); | |
398 } | |
399 | |
400 TEST_F(ParallelAuthenticatorTest, DriveDataRecoverButFail) { | |
401 FailOnLoginSuccess(); | |
402 ExpectPasswordChange(); | |
403 | |
404 // Set up mock cryptohome library to fail a key migration attempt, | |
405 // asserting that the wrong password was used. | |
406 mock_library_->SetUp(false, chromeos::kCryptohomeMountErrorKeyFailure); | |
407 EXPECT_CALL(*mock_library_, AsyncMigrateKey(username_, _, hash_ascii_, _)) | |
408 .Times(1) | |
409 .RetiresOnSaturation(); | |
410 EXPECT_CALL(*mock_library_, GetSystemSalt()) | |
411 .WillOnce(Return(CryptohomeBlob(2, 0))) | |
412 .RetiresOnSaturation(); | |
413 | |
414 SetAttemptState(auth_, state_); | |
415 | |
416 auth_->RecoverEncryptedData(std::string(), result_); | |
417 message_loop_.Run(); | |
418 } | |
419 | |
420 TEST_F(ParallelAuthenticatorTest, ResolveNoMount) { | |
421 // Set up state as though a cryptohome mount attempt has occurred | |
422 // and been rejected because the user doesn't exist. | |
423 state_->PresetCryptohomeStatus( | |
424 false, | |
425 chromeos::kCryptohomeMountErrorUserDoesNotExist); | |
426 | |
427 ChromeThread::PostTask( | |
428 ChromeThread::IO, FROM_HERE, | |
429 NewRunnableFunction(&ParallelAuthenticatorTest::CheckResolve, | |
430 state_, | |
431 auth_.get(), | |
432 ParallelAuthenticator::NO_MOUNT)); | |
433 } | |
434 | |
435 TEST_F(ParallelAuthenticatorTest, ResolveCreateNew) { | |
436 // Set up state as though a cryptohome mount attempt has occurred | |
437 // and been rejected because the user doesn't exist; additionally, | |
438 // an online auth attempt has completed successfully. | |
439 state_->PresetCryptohomeStatus( | |
440 false, | |
441 chromeos::kCryptohomeMountErrorUserDoesNotExist); | |
442 state_->PresetOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), | |
443 LoginFailure::None()); | |
Nikita (slow)
2010/10/07 22:43:06
nit: indent
| |
444 | |
445 ChromeThread::PostTask( | |
446 ChromeThread::IO, FROM_HERE, | |
447 NewRunnableFunction(&ParallelAuthenticatorTest::CheckResolve, | |
448 state_, | |
449 auth_.get(), | |
450 ParallelAuthenticator::CREATE_NEW)); | |
451 } | |
452 | |
453 TEST_F(ParallelAuthenticatorTest, DriveCreateForNewUser) { | |
454 ExpectLoginSuccess(username_, result_, false); | |
455 FailOnLoginFailure(); | |
456 | |
457 // Set up mock cryptohome library to respond successfully to a cryptohome | |
458 // create attempt (specified by the |true| argument to AsyncMount). | |
459 mock_library_->SetUp(true, 0); | |
460 EXPECT_CALL(*mock_library_, AsyncMount(username_, hash_ascii_, true, _)) | |
461 .Times(1) | |
462 .RetiresOnSaturation(); | |
463 | |
464 // Set up state as though a cryptohome mount attempt has occurred | |
465 // and been rejected because the user doesn't exist; additionally, | |
466 // an online auth attempt has completed successfully. | |
467 state_->PresetCryptohomeStatus( | |
468 false, | |
469 chromeos::kCryptohomeMountErrorUserDoesNotExist); | |
470 state_->PresetOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), | |
471 LoginFailure::None()); | |
Nikita (slow)
2010/10/07 22:43:06
nit: indent
| |
472 SetAttemptState(auth_, state_); | |
473 | |
474 RunResolve(auth_.get(), &message_loop_); | |
475 } | |
476 | |
477 TEST_F(ParallelAuthenticatorTest, DriveOfflineLogin) { | |
478 ExpectLoginSuccess(username_, result_, false); | |
479 FailOnLoginFailure(); | |
480 | |
481 // Set up state as though a cryptohome mount attempt has occurred and | |
482 // succeeded. | |
483 state_->PresetCryptohomeStatus(true, 0); | |
484 GoogleServiceAuthError error = | |
485 GoogleServiceAuthError::FromConnectionError(net::ERR_CONNECTION_RESET); | |
486 state_->PresetOnlineLoginStatus(result_, | |
487 LoginFailure::FromNetworkAuthFailure(error)); | |
Nikita (slow)
2010/10/07 22:43:06
nit: indent
| |
488 SetAttemptState(auth_, state_); | |
489 | |
490 RunResolve(auth_.get(), &message_loop_); | |
491 } | |
492 | |
493 TEST_F(ParallelAuthenticatorTest, DriveOfflineLoginDelayedOnline) { | |
494 ExpectLoginSuccess(username_, result_, true); | |
495 FailOnLoginFailure(); | |
496 | |
497 // Set up state as though a cryptohome mount attempt has occurred and | |
498 // succeeded. | |
499 state_->PresetCryptohomeStatus(true, 0); | |
500 SetAttemptState(auth_, state_); | |
501 RunResolve(auth_.get(), &message_loop_); | |
502 | |
503 // Offline login has completed, so now we "complete" the online request. | |
504 GoogleServiceAuthError error( | |
505 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | |
506 LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error); | |
507 state_->PresetOnlineLoginStatus(result_, failure); | |
508 ExpectLoginFailure(failure); | |
509 | |
510 RunResolve(auth_.get(), &message_loop_); | |
511 } | |
512 | |
513 TEST_F(ParallelAuthenticatorTest, DriveOfflineLoginGetNewPassword) { | |
514 ExpectLoginSuccess(username_, result_, true); | |
515 FailOnLoginFailure(); | |
516 | |
517 // Set up mock cryptohome library to respond successfully to a key migration. | |
518 mock_library_->SetUp(true, 0); | |
519 EXPECT_CALL(*mock_library_, AsyncMigrateKey(username_, _, _, _)) | |
520 .Times(1) | |
521 .RetiresOnSaturation(); | |
522 EXPECT_CALL(*mock_library_, GetSystemSalt()) | |
523 .WillOnce(Return(CryptohomeBlob(2, 0))) | |
524 .RetiresOnSaturation(); | |
525 | |
526 // Set up state as though a cryptohome mount attempt has occurred and | |
527 // succeeded; also, an online request that never made it. | |
528 state_->PresetCryptohomeStatus(true, 0); | |
529 SetAttemptState(auth_, state_); | |
530 RunResolve(auth_.get(), &message_loop_); | |
531 | |
532 // Offline login has completed, so now we "complete" the online request. | |
533 GoogleServiceAuthError error( | |
534 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | |
535 LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error); | |
536 state_->PresetOnlineLoginStatus(result_, failure); | |
537 ExpectLoginFailure(failure); | |
538 | |
539 RunResolve(auth_.get(), &message_loop_); | |
540 | |
541 // After the request below completes, OnLoginSuccess gets called again. | |
542 ExpectLoginSuccess(username_, result_, false); | |
543 | |
544 MockFactory<SuccessFetcher> factory; | |
545 URLFetcher::set_factory(&factory); | |
546 TestingProfile profile; | |
547 | |
548 auth_->RetryAuth(&profile, | |
Nikita (slow)
2010/10/07 22:43:06
I'd add here another failure and then finally Logi
Chris Masone
2010/10/07 22:45:37
As in, do a RetryAuth, make it fail, do another on
| |
549 username_, | |
550 std::string(), | |
551 std::string(), | |
552 std::string()); | |
553 message_loop_.Run(); | |
554 } | |
555 | |
556 TEST_F(ParallelAuthenticatorTest, DriveOnlineLogin) { | |
557 GaiaAuthConsumer::ClientLoginResult success("sid", "lsid", "", ""); | |
558 ExpectLoginSuccess(username_, success, false); | |
559 FailOnLoginFailure(); | |
560 | |
561 // Set up state as though a cryptohome mount attempt has occurred and | |
562 // succeeded. | |
563 state_->PresetCryptohomeStatus(true, 0); | |
564 state_->PresetOnlineLoginStatus(success, LoginFailure::None()); | |
565 SetAttemptState(auth_, state_); | |
566 | |
567 RunResolve(auth_.get(), &message_loop_); | |
568 } | |
569 | |
570 TEST_F(ParallelAuthenticatorTest, DriveNeedNewPassword) { | |
571 FailOnLoginSuccess(); // Set failing on success as the default... | |
572 // ...but expect ONE successful login first. | |
573 ExpectLoginSuccess(username_, result_, true); | |
574 GoogleServiceAuthError error( | |
575 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | |
576 LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error); | |
577 ExpectLoginFailure(failure); | |
578 | |
579 // Set up state as though a cryptohome mount attempt has occurred and | |
580 // succeeded. | |
581 state_->PresetCryptohomeStatus(true, 0); | |
582 state_->PresetOnlineLoginStatus(result_, failure); | |
583 SetAttemptState(auth_, state_); | |
584 | |
585 RunResolve(auth_.get(), &message_loop_); | |
586 } | |
587 | |
588 TEST_F(ParallelAuthenticatorTest, DriveLocalLogin) { | |
589 ExpectGuestLoginSuccess(); | |
590 FailOnLoginFailure(); | |
591 | |
592 // Set up mock cryptohome library to respond as though a tmpfs mount | |
593 // attempt has occurred and succeeded. | |
594 mock_library_->SetUp(true, 0); | |
595 EXPECT_CALL(*mock_library_, AsyncMountForBwsi(_)) | |
596 .Times(1) | |
597 .RetiresOnSaturation(); | |
598 | |
599 // Pre-set test state as though an online login attempt failed to complete, | |
600 // and that a cryptohome mount attempt failed because the user doesn't exist. | |
601 GoogleServiceAuthError error = | |
602 GoogleServiceAuthError::FromConnectionError(net::ERR_CONNECTION_RESET); | |
603 LoginFailure failure = | |
604 LoginFailure::FromNetworkAuthFailure(error); | |
605 state_->PresetOnlineLoginStatus(result_, failure); | |
606 state_->PresetCryptohomeStatus( | |
607 false, | |
608 chromeos::kCryptohomeMountErrorUserDoesNotExist); | |
609 SetAttemptState(auth_, state_); | |
610 | |
611 // Deal with getting the localaccount file | |
612 FilePath tmp_file_path = FakeLocalaccountFile(username_); | |
613 ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); | |
614 | |
615 RunResolve(auth_.get(), &message_loop_); | |
616 | |
617 Delete(tmp_file_path, false); | |
618 } | |
619 | |
620 TEST_F(ParallelAuthenticatorTest, DriveUnlock) { | |
621 ExpectLoginSuccess(username_, result_, false); | |
622 FailOnLoginFailure(); | |
623 | |
624 // Set up mock cryptohome library to respond successfully to a cryptohome | |
625 // key-check attempt. | |
626 mock_library_->SetUp(true, 0); | |
627 EXPECT_CALL(*mock_library_, AsyncCheckKey(username_, _, _)) | |
628 .Times(1) | |
629 .RetiresOnSaturation(); | |
630 EXPECT_CALL(*mock_library_, GetSystemSalt()) | |
631 .WillOnce(Return(CryptohomeBlob(2, 0))) | |
632 .RetiresOnSaturation(); | |
633 | |
634 auth_->AuthenticateToUnlock(username_, ""); | |
635 message_loop_.Run(); | |
636 } | |
637 | |
638 TEST_F(ParallelAuthenticatorTest, DriveLocalUnlock) { | |
639 ExpectLoginSuccess(username_, result_, false); | |
640 FailOnLoginFailure(); | |
641 | |
642 // Set up mock cryptohome library to fail a cryptohome key-check | |
643 // attempt. | |
644 mock_library_->SetUp(false, 0); | |
645 EXPECT_CALL(*mock_library_, AsyncCheckKey(username_, _, _)) | |
646 .Times(1) | |
647 .RetiresOnSaturation(); | |
648 EXPECT_CALL(*mock_library_, GetSystemSalt()) | |
649 .WillOnce(Return(CryptohomeBlob(2, 0))) | |
650 .RetiresOnSaturation(); | |
651 | |
652 // Deal with getting the localaccount file | |
653 FilePath tmp_file_path = FakeLocalaccountFile(username_); | |
654 ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); | |
655 | |
656 auth_->AuthenticateToUnlock(username_, ""); | |
657 message_loop_.Run(); | |
658 | |
659 Delete(tmp_file_path, false); | |
660 } | |
661 | |
662 } // namespace chromeos | |
OLD | NEW |