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

Side by Side Diff: chrome/browser/password_manager/password_store_mac_unittest.cc

Issue 2818035: Don't re-store deleted passwords on form submit on the Mac (Closed)
Patch Set: Address comments Created 10 years, 5 months 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
« no previous file with comments | « chrome/browser/password_manager/password_store_mac_internal.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "testing/gmock/include/gmock/gmock.h"
5 #include "testing/gtest/include/gtest/gtest.h" 6 #include "testing/gtest/include/gtest/gtest.h"
6 7
7 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/file_util.h"
10 #include "base/path_service.h"
11 #include "base/scoped_temp_dir.h"
8 #include "base/stl_util-inl.h" 12 #include "base/stl_util-inl.h"
9 #include "base/string_util.h" 13 #include "base/string_util.h"
10 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "chrome/browser/chrome_thread.h"
11 #include "chrome/browser/keychain_mock_mac.h" 16 #include "chrome/browser/keychain_mock_mac.h"
12 #include "chrome/browser/password_manager/password_store_mac.h" 17 #include "chrome/browser/password_manager/password_store_mac.h"
13 #include "chrome/browser/password_manager/password_store_mac_internal.h" 18 #include "chrome/browser/password_manager/password_store_mac_internal.h"
19 #include "chrome/common/chrome_paths.h"
14 20
15 using webkit_glue::PasswordForm; 21 using webkit_glue::PasswordForm;
22 using testing::_;
23 using testing::DoAll;
24 using testing::WithArg;
16 25
17 class PasswordStoreMacTest : public testing::Test { 26 namespace {
27
28 class MockPasswordStoreConsumer : public PasswordStoreConsumer {
29 public:
30 MOCK_METHOD2(OnPasswordStoreRequestDone,
31 void(int, const std::vector<webkit_glue::PasswordForm*>&));
32 };
33
34 ACTION(STLDeleteElements0) {
35 STLDeleteContainerPointers(arg0.begin(), arg0.end());
36 }
37
38 ACTION(QuitUIMessageLoop) {
39 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
40 MessageLoop::current()->Quit();
41 }
42
43 } // namespace
44
45 #pragma mark -
46
47 class PasswordStoreMacInternalsTest : public testing::Test {
18 public: 48 public:
19 virtual void SetUp() { 49 virtual void SetUp() {
20 MockKeychain::KeychainTestData test_data[] = { 50 MockKeychain::KeychainTestData test_data[] = {
21 // Basic HTML form. 51 // Basic HTML form.
22 { kSecAuthenticationTypeHTMLForm, "some.domain.com", 52 { kSecAuthenticationTypeHTMLForm, "some.domain.com",
23 kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z", 53 kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z",
24 "joe_user", "sekrit", false }, 54 "joe_user", "sekrit", false },
25 // HTML form with path. 55 // HTML form with path.
26 { kSecAuthenticationTypeHTMLForm, "some.domain.com", 56 { kSecAuthenticationTypeHTMLForm, "some.domain.com",
27 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "19991231235959Z", 57 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "19991231235959Z",
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 } 216 }
187 EXPECT_EQ(expectation->preferred, form->preferred) << test_label; 217 EXPECT_EQ(expectation->preferred, form->preferred) << test_label;
188 EXPECT_EQ(expectation->ssl_valid, form->ssl_valid) << test_label; 218 EXPECT_EQ(expectation->ssl_valid, form->ssl_valid) << test_label;
189 EXPECT_DOUBLE_EQ(expectation->creation_time, 219 EXPECT_DOUBLE_EQ(expectation->creation_time,
190 form->date_created.ToDoubleT()) << test_label; 220 form->date_created.ToDoubleT()) << test_label;
191 } 221 }
192 } 222 }
193 223
194 #pragma mark - 224 #pragma mark -
195 225
196 TEST_F(PasswordStoreMacTest, TestKeychainToFormTranslation) { 226 TEST_F(PasswordStoreMacInternalsTest, TestKeychainToFormTranslation) {
197 typedef struct { 227 typedef struct {
198 const PasswordForm::Scheme scheme; 228 const PasswordForm::Scheme scheme;
199 const char* signon_realm; 229 const char* signon_realm;
200 const char* origin; 230 const char* origin;
201 const wchar_t* username; // Set to NULL to check for a blacklist entry. 231 const wchar_t* username; // Set to NULL to check for a blacklist entry.
202 const wchar_t* password; 232 const wchar_t* password;
203 const bool ssl_valid; 233 const bool ssl_valid;
204 const int creation_year; 234 const int creation_year;
205 const int creation_month; 235 const int creation_month;
206 const int creation_day; 236 const int creation_day;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 { 314 {
285 // Use an invalid ref, to make sure errors are reported. 315 // Use an invalid ref, to make sure errors are reported.
286 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(99); 316 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(99);
287 PasswordForm form; 317 PasswordForm form;
288 bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem( 318 bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
289 *keychain_, keychain_item, &form); 319 *keychain_, keychain_item, &form);
290 EXPECT_FALSE(parsed); 320 EXPECT_FALSE(parsed);
291 } 321 }
292 } 322 }
293 323
294 TEST_F(PasswordStoreMacTest, TestKeychainSearch) { 324 TEST_F(PasswordStoreMacInternalsTest, TestKeychainSearch) {
295 struct TestDataAndExpectation { 325 struct TestDataAndExpectation {
296 const PasswordFormData data; 326 const PasswordFormData data;
297 const size_t expected_fill_matches; 327 const size_t expected_fill_matches;
298 const size_t expected_merge_matches; 328 const size_t expected_merge_matches;
299 }; 329 };
300 // Most fields are left blank because we don't care about them for searching. 330 // Most fields are left blank because we don't care about them for searching.
301 TestDataAndExpectation test_data[] = { 331 TestDataAndExpectation test_data[] = {
302 // An HTML form we've seen. 332 // An HTML form we've seen.
303 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 333 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
304 NULL, NULL, NULL, NULL, NULL, L"joe_user", NULL, false, false, 0 }, 334 NULL, NULL, NULL, NULL, NULL, L"joe_user", NULL, false, false, 0 },
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 375 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
346 scoped_ptr<PasswordForm> query_form( 376 scoped_ptr<PasswordForm> query_form(
347 CreatePasswordFormFromData(test_data[i].data)); 377 CreatePasswordFormFromData(test_data[i].data));
348 378
349 // Check matches treating the form as a fill target. 379 // Check matches treating the form as a fill target.
350 std::vector<PasswordForm*> matching_items = 380 std::vector<PasswordForm*> matching_items =
351 keychain_adapter.PasswordsFillingForm(*query_form); 381 keychain_adapter.PasswordsFillingForm(*query_form);
352 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); 382 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size());
353 STLDeleteElements(&matching_items); 383 STLDeleteElements(&matching_items);
354 384
355 // Check matches teating the form as a merging target. 385 // Check matches treating the form as a merging target.
386 EXPECT_EQ(test_data[i].expected_merge_matches > 0,
387 keychain_adapter.HasPasswordsMergeableWithForm(*query_form));
356 matching_items = keychain_adapter.PasswordsMergeableWithForm(*query_form); 388 matching_items = keychain_adapter.PasswordsMergeableWithForm(*query_form);
357 EXPECT_EQ(test_data[i].expected_merge_matches, matching_items.size()); 389 EXPECT_EQ(test_data[i].expected_merge_matches, matching_items.size());
358 STLDeleteElements(&matching_items); 390 STLDeleteElements(&matching_items);
359 391
360 // None of the pre-seeded items are owned by us, so none should match an 392 // None of the pre-seeded items are owned by us, so none should match an
361 // owned-passwords-only search. 393 // owned-passwords-only search.
362 matching_items = owned_keychain_adapter.PasswordsFillingForm(*query_form); 394 matching_items = owned_keychain_adapter.PasswordsFillingForm(*query_form);
363 EXPECT_EQ(0U, matching_items.size()); 395 EXPECT_EQ(0U, matching_items.size());
364 STLDeleteElements(&matching_items); 396 STLDeleteElements(&matching_items);
365 } 397 }
(...skipping 18 matching lines...) Expand all
384 416
385 // Changes just the signon_ream auth realm of |form|. 417 // Changes just the signon_ream auth realm of |form|.
386 static void SetPasswordFormRealm(PasswordForm* form, const char* realm) { 418 static void SetPasswordFormRealm(PasswordForm* form, const char* realm) {
387 GURL::Replacements replacement; 419 GURL::Replacements replacement;
388 std::string new_value(realm); 420 std::string new_value(realm);
389 replacement.SetPathStr(new_value); 421 replacement.SetPathStr(new_value);
390 GURL signon_gurl = GURL(form->signon_realm); 422 GURL signon_gurl = GURL(form->signon_realm);
391 form->signon_realm = signon_gurl.ReplaceComponents(replacement).spec(); 423 form->signon_realm = signon_gurl.ReplaceComponents(replacement).spec();
392 } 424 }
393 425
394 TEST_F(PasswordStoreMacTest, TestKeychainExactSearch) { 426 TEST_F(PasswordStoreMacInternalsTest, TestKeychainExactSearch) {
395 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 427 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
396 428
397 PasswordFormData base_form_data[] = { 429 PasswordFormData base_form_data[] = {
398 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 430 { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
399 "http://some.domain.com/insecure.html", 431 "http://some.domain.com/insecure.html",
400 NULL, NULL, NULL, NULL, L"joe_user", NULL, true, false, 0 }, 432 NULL, NULL, NULL, NULL, L"joe_user", NULL, true, false, 0 },
401 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", 433 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security",
402 "http://some.domain.com:4567/insecure.html", 434 "http://some.domain.com:4567/insecure.html",
403 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, 435 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 },
404 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", 436 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security",
405 "https://some.domain.com", 437 "https://some.domain.com",
406 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, 438 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 },
407 }; 439 };
408 440
409 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { 441 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) {
410 // Create a base form and make sure we find a match. 442 // Create a base form and make sure we find a match.
411 scoped_ptr<PasswordForm> base_form(CreatePasswordFormFromData( 443 scoped_ptr<PasswordForm> base_form(CreatePasswordFormFromData(
412 base_form_data[i])); 444 base_form_data[i]));
445 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form));
413 PasswordForm* match = 446 PasswordForm* match =
414 keychain_adapter.PasswordExactlyMatchingForm(*base_form); 447 keychain_adapter.PasswordExactlyMatchingForm(*base_form);
415 EXPECT_TRUE(match != NULL); 448 EXPECT_TRUE(match != NULL);
416 if (match) { 449 if (match) {
417 EXPECT_EQ(base_form->scheme, match->scheme); 450 EXPECT_EQ(base_form->scheme, match->scheme);
418 EXPECT_EQ(base_form->origin, match->origin); 451 EXPECT_EQ(base_form->origin, match->origin);
419 EXPECT_EQ(base_form->username_value, match->username_value); 452 EXPECT_EQ(base_form->username_value, match->username_value);
420 delete match; 453 delete match;
421 } 454 }
422 455
(...skipping 25 matching lines...) Expand all
448 for (unsigned int j = 0; j < modified_forms.size(); ++j) { 481 for (unsigned int j = 0; j < modified_forms.size(); ++j) {
449 PasswordForm* match = 482 PasswordForm* match =
450 keychain_adapter.PasswordExactlyMatchingForm(*modified_forms[j]); 483 keychain_adapter.PasswordExactlyMatchingForm(*modified_forms[j]);
451 EXPECT_EQ(NULL, match) << "In modified version " << j << " of base form " 484 EXPECT_EQ(NULL, match) << "In modified version " << j << " of base form "
452 << i; 485 << i;
453 } 486 }
454 STLDeleteElements(&modified_forms); 487 STLDeleteElements(&modified_forms);
455 } 488 }
456 } 489 }
457 490
458 TEST_F(PasswordStoreMacTest, TestKeychainAdd) { 491 TEST_F(PasswordStoreMacInternalsTest, TestKeychainAdd) {
459 struct TestDataAndExpectation { 492 struct TestDataAndExpectation {
460 PasswordFormData data; 493 PasswordFormData data;
461 bool should_succeed; 494 bool should_succeed;
462 }; 495 };
463 TestDataAndExpectation test_data[] = { 496 TestDataAndExpectation test_data[] = {
464 // Test a variety of scheme/port/protocol/path variations. 497 // Test a variety of scheme/port/protocol/path variations.
465 { { PasswordForm::SCHEME_HTML, "http://web.site.com/", 498 { { PasswordForm::SCHEME_HTML, "http://web.site.com/",
466 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 499 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
467 L"anonymous", L"knock-knock", false, false, 0 }, true }, 500 L"anonymous", L"knock-knock", false, false, 0 }, true },
468 { { PasswordForm::SCHEME_HTML, "https://web.site.com/", 501 { { PasswordForm::SCHEME_HTML, "https://web.site.com/",
(...skipping 18 matching lines...) Expand all
487 520
488 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 521 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
489 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 522 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
490 523
491 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 524 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
492 scoped_ptr<PasswordForm> in_form( 525 scoped_ptr<PasswordForm> in_form(
493 CreatePasswordFormFromData(test_data[i].data)); 526 CreatePasswordFormFromData(test_data[i].data));
494 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); 527 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form);
495 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); 528 EXPECT_EQ(test_data[i].should_succeed, add_succeeded);
496 if (add_succeeded) { 529 if (add_succeeded) {
530 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm(
531 *in_form));
497 scoped_ptr<PasswordForm> out_form( 532 scoped_ptr<PasswordForm> out_form(
498 owned_keychain_adapter.PasswordExactlyMatchingForm(*in_form)); 533 owned_keychain_adapter.PasswordExactlyMatchingForm(*in_form));
499 EXPECT_TRUE(out_form.get() != NULL); 534 EXPECT_TRUE(out_form.get() != NULL);
500 EXPECT_EQ(out_form->scheme, in_form->scheme); 535 EXPECT_EQ(out_form->scheme, in_form->scheme);
501 EXPECT_EQ(out_form->signon_realm, in_form->signon_realm); 536 EXPECT_EQ(out_form->signon_realm, in_form->signon_realm);
502 EXPECT_EQ(out_form->origin, in_form->origin); 537 EXPECT_EQ(out_form->origin, in_form->origin);
503 EXPECT_EQ(out_form->username_value, in_form->username_value); 538 EXPECT_EQ(out_form->username_value, in_form->username_value);
504 EXPECT_EQ(out_form->password_value, in_form->password_value); 539 EXPECT_EQ(out_form->password_value, in_form->password_value);
505 } 540 }
506 } 541 }
(...skipping 10 matching lines...) Expand all
517 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); 552 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form));
518 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); 553 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2);
519 PasswordForm stored_form; 554 PasswordForm stored_form;
520 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, 555 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_,
521 keychain_item, 556 keychain_item,
522 &stored_form); 557 &stored_form);
523 EXPECT_EQ(update_form->password_value, stored_form.password_value); 558 EXPECT_EQ(update_form->password_value, stored_form.password_value);
524 } 559 }
525 } 560 }
526 561
527 TEST_F(PasswordStoreMacTest, TestKeychainRemove) { 562 TEST_F(PasswordStoreMacInternalsTest, TestKeychainRemove) {
528 struct TestDataAndExpectation { 563 struct TestDataAndExpectation {
529 PasswordFormData data; 564 PasswordFormData data;
530 bool should_succeed; 565 bool should_succeed;
531 }; 566 };
532 TestDataAndExpectation test_data[] = { 567 TestDataAndExpectation test_data[] = {
533 // Test deletion of an item that we add. 568 // Test deletion of an item that we add.
534 { { PasswordForm::SCHEME_HTML, "http://web.site.com/", 569 { { PasswordForm::SCHEME_HTML, "http://web.site.com/",
535 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 570 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
536 L"anonymous", L"knock-knock", false, false, 0 }, true }, 571 L"anonymous", L"knock-knock", false, false, 0 }, true },
537 // Make sure we don't delete items we don't own. 572 // Make sure we don't delete items we don't own.
(...skipping 18 matching lines...) Expand all
556 591
557 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 592 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
558 PasswordForm* match = keychain_adapter.PasswordExactlyMatchingForm(*form); 593 PasswordForm* match = keychain_adapter.PasswordExactlyMatchingForm(*form);
559 EXPECT_EQ(test_data[i].should_succeed, match == NULL); 594 EXPECT_EQ(test_data[i].should_succeed, match == NULL);
560 if (match) { 595 if (match) {
561 delete match; 596 delete match;
562 } 597 }
563 } 598 }
564 } 599 }
565 600
566 TEST_F(PasswordStoreMacTest, TestFormMatch) { 601 TEST_F(PasswordStoreMacInternalsTest, TestFormMatch) {
567 PasswordForm base_form; 602 PasswordForm base_form;
568 base_form.signon_realm = std::string("http://some.domain.com/"); 603 base_form.signon_realm = std::string("http://some.domain.com/");
569 base_form.origin = GURL("http://some.domain.com/page.html"); 604 base_form.origin = GURL("http://some.domain.com/page.html");
570 base_form.username_value = ASCIIToUTF16("joe_user"); 605 base_form.username_value = ASCIIToUTF16("joe_user");
571 606
572 { 607 {
573 // Check that everything unimportant can be changed. 608 // Check that everything unimportant can be changed.
574 PasswordForm different_form(base_form); 609 PasswordForm different_form(base_form);
575 different_form.username_element = ASCIIToUTF16("username"); 610 different_form.username_element = ASCIIToUTF16("username");
576 different_form.submit_element = ASCIIToUTF16("submit"); 611 different_form.submit_element = ASCIIToUTF16("submit");
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 // Blacklist forms should *never* match for merging, even when identical 653 // Blacklist forms should *never* match for merging, even when identical
619 // (and certainly not when only one is a blacklist entry). 654 // (and certainly not when only one is a blacklist entry).
620 { 655 {
621 PasswordForm form_a(base_form); 656 PasswordForm form_a(base_form);
622 form_a.blacklisted_by_user = true; 657 form_a.blacklisted_by_user = true;
623 PasswordForm form_b(form_a); 658 PasswordForm form_b(form_a);
624 EXPECT_FALSE(internal_keychain_helpers::FormsMatchForMerge(form_a, form_b)); 659 EXPECT_FALSE(internal_keychain_helpers::FormsMatchForMerge(form_a, form_b));
625 } 660 }
626 } 661 }
627 662
628 TEST_F(PasswordStoreMacTest, TestFormMerge) { 663 TEST_F(PasswordStoreMacInternalsTest, TestFormMerge) {
629 // Set up a bunch of test data to use in varying combinations. 664 // Set up a bunch of test data to use in varying combinations.
630 PasswordFormData keychain_user_1 = 665 PasswordFormData keychain_user_1 =
631 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 666 { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
632 "http://some.domain.com/", "", L"", L"", L"", L"joe_user", L"sekrit", 667 "http://some.domain.com/", "", L"", L"", L"", L"joe_user", L"sekrit",
633 false, false, 1010101010 }; 668 false, false, 1010101010 };
634 PasswordFormData keychain_user_1_with_path = 669 PasswordFormData keychain_user_1_with_path =
635 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 670 { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
636 "http://some.domain.com/page.html", 671 "http://some.domain.com/page.html",
637 "", L"", L"", L"", L"joe_user", L"otherpassword", 672 "", L"", L"", L"", L"joe_user", L"otherpassword",
638 false, false, 1010101010 }; 673 false, false, 1010101010 };
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 CHECK_FORMS(database_forms, test_data[DATABASE_OUTPUT][test_case], 808 CHECK_FORMS(database_forms, test_data[DATABASE_OUTPUT][test_case],
774 test_case); 809 test_case);
775 CHECK_FORMS(merged_forms, test_data[MERGE_OUTPUT][test_case], test_case); 810 CHECK_FORMS(merged_forms, test_data[MERGE_OUTPUT][test_case], test_case);
776 811
777 STLDeleteElements(&keychain_forms); 812 STLDeleteElements(&keychain_forms);
778 STLDeleteElements(&database_forms); 813 STLDeleteElements(&database_forms);
779 STLDeleteElements(&merged_forms); 814 STLDeleteElements(&merged_forms);
780 } 815 }
781 } 816 }
782 817
783 TEST_F(PasswordStoreMacTest, TestPasswordBulkLookup) { 818 TEST_F(PasswordStoreMacInternalsTest, TestPasswordBulkLookup) {
784 PasswordFormData db_data[] = { 819 PasswordFormData db_data[] = {
785 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 820 { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
786 "http://some.domain.com/", "http://some.domain.com/action.cgi", 821 "http://some.domain.com/", "http://some.domain.com/action.cgi",
787 L"submit", L"username", L"password", L"joe_user", L"", 822 L"submit", L"username", L"password", L"joe_user", L"",
788 true, false, 1212121212 }, 823 true, false, 1212121212 },
789 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 824 { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
790 "http://some.domain.com/page.html", 825 "http://some.domain.com/page.html",
791 "http://some.domain.com/handlepage.cgi", 826 "http://some.domain.com/handlepage.cgi",
792 L"submit", L"username", L"password", L"joe_user", L"", 827 L"submit", L"username", L"password", L"joe_user", L"",
793 true, false, 1234567890 }, 828 true, false, 1234567890 },
(...skipping 22 matching lines...) Expand all
816 EXPECT_EQ(2U, database_forms.size()); 851 EXPECT_EQ(2U, database_forms.size());
817 ASSERT_EQ(3U, merged_forms.size()); 852 ASSERT_EQ(3U, merged_forms.size());
818 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value); 853 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value);
819 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value); 854 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value);
820 EXPECT_EQ(true, merged_forms[2]->blacklisted_by_user); 855 EXPECT_EQ(true, merged_forms[2]->blacklisted_by_user);
821 856
822 STLDeleteElements(&database_forms); 857 STLDeleteElements(&database_forms);
823 STLDeleteElements(&merged_forms); 858 STLDeleteElements(&merged_forms);
824 } 859 }
825 860
826 TEST_F(PasswordStoreMacTest, TestPasswordGetAll) { 861 TEST_F(PasswordStoreMacInternalsTest, TestPasswordGetAll) {
827 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 862 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
828 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 863 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
829 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 864 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
830 865
831 // Add a few passwords of various types so that we own some. 866 // Add a few passwords of various types so that we own some.
832 PasswordFormData owned_password_data[] = { 867 PasswordFormData owned_password_data[] = {
833 { PasswordForm::SCHEME_HTML, "http://web.site.com/", 868 { PasswordForm::SCHEME_HTML, "http://web.site.com/",
834 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 869 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
835 L"anonymous", L"knock-knock", false, false, 0 }, 870 L"anonymous", L"knock-knock", false, false, 0 },
836 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", 871 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm",
(...skipping 12 matching lines...) Expand all
849 std::vector<PasswordForm*> all_passwords = 884 std::vector<PasswordForm*> all_passwords =
850 keychain_adapter.GetAllPasswordFormPasswords(); 885 keychain_adapter.GetAllPasswordFormPasswords();
851 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size()); 886 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size());
852 STLDeleteElements(&all_passwords); 887 STLDeleteElements(&all_passwords);
853 888
854 std::vector<PasswordForm*> owned_passwords = 889 std::vector<PasswordForm*> owned_passwords =
855 owned_keychain_adapter.GetAllPasswordFormPasswords(); 890 owned_keychain_adapter.GetAllPasswordFormPasswords();
856 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); 891 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size());
857 STLDeleteElements(&owned_passwords); 892 STLDeleteElements(&owned_passwords);
858 } 893 }
894
895 #pragma mark -
896
897 class PasswordStoreMacTest : public testing::Test {
898 public:
899 PasswordStoreMacTest() : ui_thread_(ChromeThread::UI, &message_loop_) {}
900
901 virtual void SetUp() {
902 login_db_ = new LoginDatabase();
903 ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
904 FilePath db_file = db_dir_.path().AppendASCII("login.db");
905 ASSERT_TRUE(login_db_->Init(db_file));
906
907 keychain_ = new MockKeychain(3);
908
909 store_ = new PasswordStoreMac(keychain_, login_db_);
910 ASSERT_TRUE(store_->Init());
911 }
912
913 virtual void TearDown() {
914 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask);
915 MessageLoop::current()->Run();
916 }
917
918 protected:
919 MessageLoopForUI message_loop_;
920 ChromeThread ui_thread_;
921
922 MockKeychain* keychain_; // Owned by store_.
923 LoginDatabase* login_db_; // Owned by store_.
924 scoped_refptr<PasswordStoreMac> store_;
925 ScopedTempDir db_dir_;
926 };
927
928 TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
929 // Insert a password into both the database and the keychain.
930 // This is done manually, rather than through store_->AddLogin, because the
931 // Mock Keychain isn't smart enough to be able to support update generically,
932 // so some.domain.com triggers special handling to test it that make inserting
933 // fail.
934 PasswordFormData joint_data = {
935 PasswordForm::SCHEME_HTML, "http://some.domain.com/",
936 "http://some.domain.com/insecure.html", "login.cgi",
937 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1
938 };
939 scoped_ptr<PasswordForm> joint_form(CreatePasswordFormFromData(joint_data));
940 login_db_->AddLogin(*joint_form);
941 MockKeychain::KeychainTestData joint_keychain_data = {
942 kSecAuthenticationTypeHTMLForm, "some.domain.com",
943 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z",
944 "joe_user", "sekrit", false };
945 keychain_->AddTestItem(joint_keychain_data);
946
947 // Insert a password into the keychain only.
948 MockKeychain::KeychainTestData keychain_only_data = {
949 kSecAuthenticationTypeHTMLForm, "keychain.only.com",
950 kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z",
951 "keychain", "only", false
952 };
953 keychain_->AddTestItem(keychain_only_data);
954
955 struct UpdateData {
956 PasswordFormData form_data;
957 const char* password; // NULL indicates no entry should be present.
958 };
959
960 // Make a series of update calls.
961 UpdateData updates[] = {
962 // Update the keychain+db passwords (the normal password update case).
963 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
964 "http://some.domain.com/insecure.html", "login.cgi",
965 L"username", L"password", L"submit", L"joe_user", L"53krit",
966 true, false, 2 },
967 "53krit",
968 },
969 // Update the keychain-only password; this simulates the initial use of a
970 // password stored by another browsers.
971 { { PasswordForm::SCHEME_HTML, "http://keychain.only.com/",
972 "http://keychain.only.com/login.html", "login.cgi",
973 L"username", L"password", L"submit", L"keychain", L"only",
974 true, false, 2 },
975 "only",
976 },
977 // Update a password that doesn't exist in either location. This tests the
978 // case where a form is filled, then the stored login is removed, then the
979 // form is submitted.
980 { { PasswordForm::SCHEME_HTML, "http://different.com/",
981 "http://different.com/index.html", "login.cgi",
982 L"username", L"password", L"submit", L"abc", L"123",
983 true, false, 2 },
984 NULL,
985 },
986 };
987 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(updates); ++i) {
988 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(
989 updates[i].form_data));
990 store_->UpdateLogin(*form);
991 }
992
993 // Do a store-level query to wait for all the operations above to be done.
994 MockPasswordStoreConsumer consumer;
995 ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)).WillByDefault(
996 QuitUIMessageLoop());
997 EXPECT_CALL(consumer, OnPasswordStoreRequestDone(_, _)).WillOnce(
998 DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
999 store_->GetLogins(*joint_form, &consumer);
1000 MessageLoop::current()->Run();
1001
1002 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
1003 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(updates); ++i) {
1004 scoped_ptr<PasswordForm> query_form(
1005 CreatePasswordFormFromData(updates[i].form_data));
1006
1007 std::vector<PasswordForm*> matching_items =
1008 keychain_adapter.PasswordsFillingForm(*query_form);
1009 if (updates[i].password) {
1010 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i;
1011 if (matching_items.size() >= 1)
1012 EXPECT_EQ(ASCIIToUTF16(updates[i].password),
1013 matching_items[0]->password_value) << "iteration " << i;
1014 } else {
1015 EXPECT_EQ(0U, matching_items.size()) << "iteration " << i;
1016 }
1017 STLDeleteElements(&matching_items);
1018
1019 login_db_->GetLogins(*query_form, &matching_items);
1020 EXPECT_EQ(updates[i].password ? 1U : 0U, matching_items.size())
1021 << "iteration " << i;
1022 STLDeleteElements(&matching_items);
1023 }
1024 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_store_mac_internal.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698