OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdarg.h> | 5 #include <stdarg.h> |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 mock_keyring_items.clear(); | 275 mock_keyring_items.clear(); |
276 mock_keyring_reject_local_ids = false; | 276 mock_keyring_reject_local_ids = false; |
277 return true; | 277 return true; |
278 } | 278 } |
279 }; | 279 }; |
280 | 280 |
281 } // anonymous namespace | 281 } // anonymous namespace |
282 | 282 |
283 class NativeBackendGnomeTest : public testing::Test { | 283 class NativeBackendGnomeTest : public testing::Test { |
284 protected: | 284 protected: |
| 285 enum UpdateType { // Used in CheckPSLUpdate(). |
| 286 UPDATE_BY_UPDATELOGIN, |
| 287 UPDATE_BY_ADDLOGIN, |
| 288 }; |
| 289 |
285 NativeBackendGnomeTest() | 290 NativeBackendGnomeTest() |
286 : ui_thread_(BrowserThread::UI, &message_loop_), | 291 : ui_thread_(BrowserThread::UI, &message_loop_), |
287 db_thread_(BrowserThread::DB) { | 292 db_thread_(BrowserThread::DB) { |
288 } | 293 } |
289 | 294 |
290 virtual void SetUp() { | 295 virtual void SetUp() { |
291 ASSERT_TRUE(db_thread_.Start()); | 296 ASSERT_TRUE(db_thread_.Start()); |
292 | 297 |
293 ASSERT_TRUE(MockGnomeKeyringLoader::LoadMockGnomeKeyring()); | 298 ASSERT_TRUE(MockGnomeKeyringLoader::LoadMockGnomeKeyring()); |
294 | 299 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 CheckUint32Attribute(item, "ssl_valid", form.ssl_valid); | 394 CheckUint32Attribute(item, "ssl_valid", form.ssl_valid); |
390 CheckUint32Attribute(item, "preferred", form.preferred); | 395 CheckUint32Attribute(item, "preferred", form.preferred); |
391 // We don't check the date created. It varies. | 396 // We don't check the date created. It varies. |
392 CheckUint32Attribute(item, "blacklisted_by_user", form.blacklisted_by_user); | 397 CheckUint32Attribute(item, "blacklisted_by_user", form.blacklisted_by_user); |
393 CheckUint32Attribute(item, "type", form.type); | 398 CheckUint32Attribute(item, "type", form.type); |
394 CheckUint32Attribute(item, "times_used", form.times_used); | 399 CheckUint32Attribute(item, "times_used", form.times_used); |
395 CheckUint32Attribute(item, "scheme", form.scheme); | 400 CheckUint32Attribute(item, "scheme", form.scheme); |
396 CheckStringAttribute(item, "application", app_string); | 401 CheckStringAttribute(item, "application", app_string); |
397 } | 402 } |
398 | 403 |
399 // Checks (using EXPECT_* macros), that |credentials| are accessible for | 404 // Saves |credentials| and then gets login for origin and realm |url|. Returns |
400 // filling in for a page with |origin| iff | 405 // true when something is found, and in such case copies the result to |
401 // |should_credential_be_available_to_url| is true. | 406 // |result| when |result| is not NULL. (Note that there can be max. 1 result, |
402 void CheckCredentialAvailability(const PasswordForm& credentials, | 407 // derived from |credentials|.) |
403 const std::string& url, | 408 bool CheckCredentialAvailability(const PasswordForm& credentials, |
404 bool should_credential_be_available_to_url) { | 409 const GURL& url, |
405 password_manager::PSLMatchingHelper helper; | 410 PasswordForm* result) { |
406 ASSERT_TRUE(helper.IsMatchingEnabled()) | |
407 << "PSL matching needs to be enabled."; | |
408 | |
409 NativeBackendGnome backend(321); | 411 NativeBackendGnome backend(321); |
410 backend.Init(); | 412 backend.Init(); |
411 | 413 |
412 BrowserThread::PostTask( | 414 BrowserThread::PostTask( |
413 BrowserThread::DB, | 415 BrowserThread::DB, |
414 FROM_HERE, | 416 FROM_HERE, |
415 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), | 417 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), |
416 base::Unretained(&backend), | 418 base::Unretained(&backend), |
417 credentials)); | 419 credentials)); |
418 | 420 |
419 PasswordForm target_form; | 421 PasswordForm target_form; |
420 target_form.origin = GURL(url); | 422 target_form.origin = url; |
421 target_form.signon_realm = url; | 423 target_form.signon_realm = url.spec(); |
422 std::vector<PasswordForm*> form_list; | 424 std::vector<PasswordForm*> form_list; |
423 BrowserThread::PostTask( | 425 BrowserThread::PostTask( |
424 BrowserThread::DB, | 426 BrowserThread::DB, |
425 FROM_HERE, | 427 FROM_HERE, |
426 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), | 428 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), |
427 base::Unretained(&backend), | 429 base::Unretained(&backend), |
428 target_form, | 430 target_form, |
429 &form_list)); | 431 &form_list)); |
430 | 432 |
431 RunBothThreads(); | 433 RunBothThreads(); |
432 | 434 |
433 EXPECT_EQ(1u, mock_keyring_items.size()); | 435 EXPECT_EQ(1u, mock_keyring_items.size()); |
434 if (mock_keyring_items.size() > 0) | 436 if (mock_keyring_items.size() > 0) |
435 CheckMockKeyringItem(&mock_keyring_items[0], credentials, "chrome-321"); | 437 CheckMockKeyringItem(&mock_keyring_items[0], credentials, "chrome-321"); |
436 | 438 |
437 if (should_credential_be_available_to_url) | 439 if (form_list.empty()) |
438 EXPECT_EQ(1u, form_list.size()); | 440 return false; |
439 else | 441 EXPECT_EQ(1u, form_list.size()); |
440 EXPECT_EQ(0u, form_list.size()); | 442 if (result) |
| 443 *result = *form_list[0]; |
| 444 STLDeleteElements(&form_list); |
| 445 return true; |
| 446 } |
| 447 |
| 448 // Test that updating does not use PSL matching: Add a www.facebook.com |
| 449 // password, then use PSL matching to get a copy of it for m.facebook.com, and |
| 450 // add that copy as well. Now update the www.facebook.com password -- the |
| 451 // m.facebook.com password should not get updated. Depending on the argument, |
| 452 // the credential update is done via UpdateLogin or AddLogin. |
| 453 void CheckPSLUpdate(UpdateType update_type) { |
| 454 password_manager::PSLMatchingHelper helper; |
| 455 ASSERT_TRUE(helper.IsMatchingEnabled()); |
| 456 |
| 457 NativeBackendGnome backend(321); |
| 458 backend.Init(); |
| 459 |
| 460 // Add |form_facebook_| to saved logins. |
| 461 BrowserThread::PostTask( |
| 462 BrowserThread::DB, |
| 463 FROM_HERE, |
| 464 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), |
| 465 base::Unretained(&backend), |
| 466 form_facebook_)); |
| 467 |
| 468 // Get the PSL-matched copy of the saved login for m.facebook. |
| 469 const GURL kMobileURL("http://m.facebook.com/"); |
| 470 PasswordForm m_facebook_lookup; |
| 471 m_facebook_lookup.origin = kMobileURL; |
| 472 m_facebook_lookup.signon_realm = kMobileURL.spec(); |
| 473 std::vector<PasswordForm*> form_list; |
| 474 BrowserThread::PostTask( |
| 475 BrowserThread::DB, |
| 476 FROM_HERE, |
| 477 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), |
| 478 base::Unretained(&backend), |
| 479 m_facebook_lookup, |
| 480 &form_list)); |
| 481 RunBothThreads(); |
| 482 EXPECT_EQ(1u, mock_keyring_items.size()); |
| 483 EXPECT_EQ(1u, form_list.size()); |
| 484 PasswordForm m_facebook = *form_list[0]; |
| 485 STLDeleteElements(&form_list); |
| 486 EXPECT_EQ(kMobileURL, m_facebook.origin); |
| 487 EXPECT_EQ(kMobileURL.spec(), m_facebook.signon_realm); |
| 488 |
| 489 // Add the PSL-matched copy to saved logins. |
| 490 BrowserThread::PostTask( |
| 491 BrowserThread::DB, |
| 492 FROM_HERE, |
| 493 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), |
| 494 base::Unretained(&backend), |
| 495 m_facebook)); |
| 496 RunBothThreads(); |
| 497 EXPECT_EQ(2u, mock_keyring_items.size()); |
| 498 |
| 499 // Update www.facebook.com login. |
| 500 PasswordForm new_facebook(form_facebook_); |
| 501 const base::string16 kOldPassword(form_facebook_.password_value); |
| 502 const base::string16 kNewPassword(UTF8ToUTF16("new_b")); |
| 503 EXPECT_NE(kOldPassword, kNewPassword); |
| 504 new_facebook.password_value = kNewPassword; |
| 505 switch (update_type) { |
| 506 case UPDATE_BY_UPDATELOGIN: |
| 507 BrowserThread::PostTask( |
| 508 BrowserThread::DB, |
| 509 FROM_HERE, |
| 510 base::Bind(base::IgnoreResult(&NativeBackendGnome::UpdateLogin), |
| 511 base::Unretained(&backend), |
| 512 new_facebook)); |
| 513 break; |
| 514 case UPDATE_BY_ADDLOGIN: |
| 515 BrowserThread::PostTask( |
| 516 BrowserThread::DB, |
| 517 FROM_HERE, |
| 518 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), |
| 519 base::Unretained(&backend), |
| 520 new_facebook)); |
| 521 break; |
| 522 } |
| 523 |
| 524 RunBothThreads(); |
| 525 EXPECT_EQ(2u, mock_keyring_items.size()); |
| 526 |
| 527 // Check that m.facebook.com login was not modified by the update. |
| 528 BrowserThread::PostTask( |
| 529 BrowserThread::DB, |
| 530 FROM_HERE, |
| 531 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), |
| 532 base::Unretained(&backend), |
| 533 m_facebook_lookup, |
| 534 &form_list)); |
| 535 RunBothThreads(); |
| 536 // There should be two results -- the exact one, and the PSL-matched one. |
| 537 EXPECT_EQ(2u, form_list.size()); |
| 538 size_t index_non_psl = 0; |
| 539 if (!form_list[index_non_psl]->original_signon_realm.empty()) |
| 540 index_non_psl = 1; |
| 541 EXPECT_EQ(kMobileURL, form_list[index_non_psl]->origin); |
| 542 EXPECT_EQ(kMobileURL.spec(), form_list[index_non_psl]->signon_realm); |
| 543 EXPECT_EQ(kOldPassword, form_list[index_non_psl]->password_value); |
| 544 STLDeleteElements(&form_list); |
| 545 |
| 546 // Check that www.facebook.com login was modified by the update. |
| 547 BrowserThread::PostTask( |
| 548 BrowserThread::DB, |
| 549 FROM_HERE, |
| 550 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), |
| 551 base::Unretained(&backend), |
| 552 form_facebook_, |
| 553 &form_list)); |
| 554 RunBothThreads(); |
| 555 // There should be two results -- the exact one, and the PSL-matched one. |
| 556 EXPECT_EQ(2u, form_list.size()); |
| 557 index_non_psl = 0; |
| 558 if (!form_list[index_non_psl]->original_signon_realm.empty()) |
| 559 index_non_psl = 1; |
| 560 EXPECT_EQ(form_facebook_.origin, form_list[index_non_psl]->origin); |
| 561 EXPECT_EQ(form_facebook_.signon_realm, |
| 562 form_list[index_non_psl]->signon_realm); |
| 563 EXPECT_EQ(kNewPassword, form_list[index_non_psl]->password_value); |
441 STLDeleteElements(&form_list); | 564 STLDeleteElements(&form_list); |
442 } | 565 } |
443 | 566 |
444 base::MessageLoopForUI message_loop_; | 567 base::MessageLoopForUI message_loop_; |
445 content::TestBrowserThread ui_thread_; | 568 content::TestBrowserThread ui_thread_; |
446 content::TestBrowserThread db_thread_; | 569 content::TestBrowserThread db_thread_; |
447 | 570 |
448 // Provide some test forms to avoid having to set them up in each test. | 571 // Provide some test forms to avoid having to set them up in each test. |
449 PasswordForm form_google_; | 572 PasswordForm form_google_; |
450 PasswordForm form_facebook_; | 573 PasswordForm form_facebook_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 EXPECT_EQ(1u, form_list.size()); | 612 EXPECT_EQ(1u, form_list.size()); |
490 STLDeleteElements(&form_list); | 613 STLDeleteElements(&form_list); |
491 | 614 |
492 EXPECT_EQ(1u, mock_keyring_items.size()); | 615 EXPECT_EQ(1u, mock_keyring_items.size()); |
493 if (mock_keyring_items.size() > 0) | 616 if (mock_keyring_items.size() > 0) |
494 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); | 617 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); |
495 } | 618 } |
496 | 619 |
497 // Save a password for www.facebook.com and see it suggested for m.facebook.com. | 620 // Save a password for www.facebook.com and see it suggested for m.facebook.com. |
498 TEST_F(NativeBackendGnomeTest, PSLMatchingPositive) { | 621 TEST_F(NativeBackendGnomeTest, PSLMatchingPositive) { |
499 CheckCredentialAvailability(form_facebook_, | 622 PasswordForm result; |
500 "http://m.facebook.com/", | 623 const GURL kMobileURL("http://m.facebook.com/"); |
501 /*should_credential_be_available_to_url=*/true); | 624 password_manager::PSLMatchingHelper helper; |
| 625 ASSERT_TRUE(helper.IsMatchingEnabled()); |
| 626 EXPECT_TRUE(CheckCredentialAvailability(form_facebook_, kMobileURL, &result)); |
| 627 EXPECT_EQ(kMobileURL, result.origin); |
| 628 EXPECT_EQ(kMobileURL.spec(), result.signon_realm); |
502 } | 629 } |
503 | 630 |
504 // Save a password for www.facebook.com and see it not suggested for | 631 // Save a password for www.facebook.com and see it not suggested for |
505 // m-facebook.com. | 632 // m-facebook.com. |
506 TEST_F(NativeBackendGnomeTest, PSLMatchingNegativeDomainMismatch) { | 633 TEST_F(NativeBackendGnomeTest, PSLMatchingNegativeDomainMismatch) { |
507 CheckCredentialAvailability(form_facebook_, | 634 password_manager::PSLMatchingHelper helper; |
508 "http://m-facebook.com/", | 635 ASSERT_TRUE(helper.IsMatchingEnabled()); |
509 /*should_credential_be_available_to_url=*/false); | 636 EXPECT_FALSE(CheckCredentialAvailability( |
| 637 form_facebook_, GURL("http://m-facebook.com/"), NULL)); |
510 } | 638 } |
511 | 639 |
512 // Test PSL matching is off for domains excluded from it. | 640 // Test PSL matching is off for domains excluded from it. |
513 TEST_F(NativeBackendGnomeTest, PSLMatchingDisabledDomains) { | 641 TEST_F(NativeBackendGnomeTest, PSLMatchingDisabledDomains) { |
514 CheckCredentialAvailability(form_google_, | 642 password_manager::PSLMatchingHelper helper; |
515 "http://one.google.com/", | 643 ASSERT_TRUE(helper.IsMatchingEnabled()); |
516 /*should_credential_be_available_to_url=*/false); | 644 EXPECT_FALSE(CheckCredentialAvailability( |
| 645 form_google_, GURL("http://one.google.com/"), NULL)); |
| 646 } |
| 647 |
| 648 TEST_F(NativeBackendGnomeTest, PSLUpdatingStrictUpdateLogin) { |
| 649 CheckPSLUpdate(UPDATE_BY_UPDATELOGIN); |
| 650 } |
| 651 |
| 652 TEST_F(NativeBackendGnomeTest, PSLUpdatingStrictAddLogin) { |
| 653 // TODO(vabr): if AddLogin becomes no longer valid for existing logins, then |
| 654 // just delete this test. |
| 655 CheckPSLUpdate(UPDATE_BY_ADDLOGIN); |
517 } | 656 } |
518 | 657 |
519 TEST_F(NativeBackendGnomeTest, BasicUpdateLogin) { | 658 TEST_F(NativeBackendGnomeTest, BasicUpdateLogin) { |
520 NativeBackendGnome backend(42); | 659 NativeBackendGnome backend(42); |
521 backend.Init(); | 660 backend.Init(); |
522 | 661 |
523 // First add google login. | 662 // First add google login. |
524 BrowserThread::PostTask( | 663 BrowserThread::PostTask( |
525 BrowserThread::DB, FROM_HERE, | 664 BrowserThread::DB, FROM_HERE, |
526 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), | 665 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 // Quick check that we got two results back. | 801 // Quick check that we got two results back. |
663 EXPECT_EQ(2u, form_list.size()); | 802 EXPECT_EQ(2u, form_list.size()); |
664 STLDeleteElements(&form_list); | 803 STLDeleteElements(&form_list); |
665 | 804 |
666 EXPECT_EQ(1u, mock_keyring_items.size()); | 805 EXPECT_EQ(1u, mock_keyring_items.size()); |
667 if (mock_keyring_items.size() > 0) | 806 if (mock_keyring_items.size() > 0) |
668 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); | 807 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); |
669 } | 808 } |
670 | 809 |
671 // TODO(mdm): add more basic tests here at some point. | 810 // TODO(mdm): add more basic tests here at some point. |
OLD | NEW |