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

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

Issue 149160: Add an exact search method to the Keychain adapter, and modify unit tests to ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 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 | Annotate | Revision Log
« 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/gtest/include/gtest/gtest.h" 5 #include "testing/gtest/include/gtest/gtest.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
9 #include "chrome/browser/keychain_mock_mac.h" 9 #include "chrome/browser/keychain_mock_mac.h"
10 #include "chrome/browser/password_manager/password_store_mac.h" 10 #include "chrome/browser/password_manager/password_store_mac.h"
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 324 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
325 scoped_ptr<PasswordForm> query_form( 325 scoped_ptr<PasswordForm> query_form(
326 CreatePasswordFormFromData(test_data[i].data)); 326 CreatePasswordFormFromData(test_data[i].data));
327 std::vector<PasswordForm*> matching_items = 327 std::vector<PasswordForm*> matching_items =
328 keychainAdapter.PasswordsMatchingForm(*query_form); 328 keychainAdapter.PasswordsMatchingForm(*query_form);
329 EXPECT_EQ(test_data[i].expected_matches, matching_items.size()); 329 EXPECT_EQ(test_data[i].expected_matches, matching_items.size());
330 STLDeleteElements(&matching_items); 330 STLDeleteElements(&matching_items);
331 } 331 }
332 } 332 }
333 333
334 // Changes just the origin path of |form|.
335 static void SetPasswordFormPath(PasswordForm* form, const char* path) {
336 GURL::Replacements replacement;
337 std::string new_value(path);
338 replacement.SetPathStr(new_value);
339 form->origin = form->origin.ReplaceComponents(replacement);
340 }
341
342 // Changes just the signon_realm port of |form|.
343 static void SetPasswordFormPort(PasswordForm* form, const char* port) {
344 GURL::Replacements replacement;
345 std::string new_value(port);
346 replacement.SetPortStr(new_value);
347 GURL signon_gurl = GURL(form->signon_realm);
348 form->signon_realm = signon_gurl.ReplaceComponents(replacement).spec();
349 }
350
351 // Changes just the signon_ream auth realm of |form|.
352 static void SetPasswordFormRealm(PasswordForm* form, const char* realm) {
353 GURL::Replacements replacement;
354 std::string new_value(realm);
355 replacement.SetPathStr(new_value);
356 GURL signon_gurl = GURL(form->signon_realm);
357 form->signon_realm = signon_gurl.ReplaceComponents(replacement).spec();
358 }
359
334 TEST_F(PasswordStoreMacTest, TestKeychainExactSearch) { 360 TEST_F(PasswordStoreMacTest, TestKeychainExactSearch) {
335 // Test a web form entry (SCHEME_HTML). 361 MacKeychainPasswordFormAdapter keychainAdapter(keychain_);
336 {
337 PasswordForm search_form;
338 search_form.signon_realm = std::string("http://some.domain.com/");
339 search_form.origin = GURL("http://some.domain.com/insecure.html");
340 search_form.action = GURL("http://some.domain.com/submit.cgi");
341 search_form.username_element = std::wstring(L"username");
342 search_form.username_value = std::wstring(L"joe_user");
343 search_form.password_element = std::wstring(L"password");
344 search_form.preferred = true;
345 SecKeychainItemRef match;
346 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_,
347 search_form);
348 EXPECT_EQ(reinterpret_cast<SecKeychainItemRef>(2), match);
349 keychain_->Free(match);
350 362
351 // Make sure that the matching isn't looser than it should be. 363 PasswordFormData base_form_data[] = {
352 PasswordForm wrong_username(search_form); 364 { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
353 wrong_username.username_value = std::wstring(L"wrong_user"); 365 "http://some.domain.com/insecure.html",
354 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_, 366 NULL, NULL, NULL, NULL, L"joe_user", NULL, true, false, 0 },
355 wrong_username); 367 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security",
356 EXPECT_EQ(NULL, match); 368 "http://some.domain.com:4567/insecure.html",
369 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 },
370 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security",
371 "https://some.domain.com",
372 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 },
373 };
357 374
358 PasswordForm wrong_path(search_form); 375 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) {
359 wrong_path.origin = GURL("http://some.domain.com/elsewhere.html"); 376 // Create a base form and make sure we find a match.
360 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_, 377 scoped_ptr<PasswordForm> base_form(CreatePasswordFormFromData(
361 wrong_path); 378 base_form_data[i]));
362 EXPECT_EQ(NULL, match); 379 PasswordForm* match =
380 keychainAdapter.PasswordExactlyMatchingForm(*base_form);
381 EXPECT_TRUE(match != NULL);
382 if (match) {
383 EXPECT_EQ(base_form->scheme, match->scheme);
384 EXPECT_EQ(base_form->origin, match->origin);
385 EXPECT_EQ(base_form->username_value, match->username_value);
386 delete match;
387 }
363 388
364 PasswordForm wrong_scheme(search_form); 389 // Make sure that the matching isn't looser than it should be by checking
365 wrong_scheme.scheme = PasswordForm::SCHEME_BASIC; 390 // that slightly altered forms don't match.
366 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_, 391 std::vector<PasswordForm*> modified_forms;
367 wrong_scheme);
368 EXPECT_EQ(NULL, match);
369 392
370 // With no path, we should match the pathless Keychain entry. 393 modified_forms.push_back(new PasswordForm(*base_form));
371 PasswordForm no_path(search_form); 394 modified_forms.back()->username_value = std::wstring(L"wrong_user");
372 no_path.origin = GURL("http://some.domain.com/");
373 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_,
374 no_path);
375 EXPECT_EQ(reinterpret_cast<SecKeychainItemRef>(1), match);
376 keychain_->Free(match);
377 395
378 // We don't store blacklist entries in the keychain, and we want to ignore 396 modified_forms.push_back(new PasswordForm(*base_form));
379 // those stored by other browsers. 397 SetPasswordFormPath(modified_forms.back(), "elsewhere.html");
380 PasswordForm blacklist(search_form);
381 blacklist.blacklisted_by_user = true;
382 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_,
383 blacklist);
384 EXPECT_EQ(NULL, match);
385 }
386 398
387 // Test an http auth entry (SCHEME_BASIC, but SCHEME_DIGEST works is searched 399 modified_forms.push_back(new PasswordForm(*base_form));
388 // the same way, so this gives sufficient coverage of both). 400 modified_forms.back()->scheme = PasswordForm::SCHEME_OTHER;
389 {
390 PasswordForm search_form;
391 search_form.signon_realm =
392 std::string("http://some.domain.com:4567/low_security");
393 search_form.origin = GURL("http://some.domain.com:4567/insecure.html");
394 search_form.username_value = std::wstring(L"basic_auth_user");
395 search_form.scheme = PasswordForm::SCHEME_BASIC;
396 SecKeychainItemRef match;
397 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_,
398 search_form);
399 EXPECT_EQ(reinterpret_cast<SecKeychainItemRef>(7), match);
400 keychain_->Free(match);
401 401
402 // Make sure that the matching isn't looser than it should be. 402 modified_forms.push_back(new PasswordForm(*base_form));
403 PasswordForm wrong_username(search_form); 403 SetPasswordFormPort(modified_forms.back(), "1234");
404 wrong_username.username_value = std::wstring(L"wrong_user");
405 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_,
406 wrong_username);
407 EXPECT_EQ(NULL, match);
408 404
409 PasswordForm wrong_path(search_form); 405 modified_forms.push_back(new PasswordForm(*base_form));
410 wrong_path.origin = GURL("http://some.domain.com:4567/elsewhere.html"); 406 modified_forms.back()->blacklisted_by_user = true;
411 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_,
412 wrong_path);
413 EXPECT_EQ(NULL, match);
414 407
415 PasswordForm wrong_scheme(search_form); 408 if (base_form->scheme == PasswordForm::SCHEME_BASIC ||
416 wrong_scheme.scheme = PasswordForm::SCHEME_DIGEST; 409 base_form->scheme == PasswordForm::SCHEME_DIGEST) {
417 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_, 410 modified_forms.push_back(new PasswordForm(*base_form));
418 wrong_scheme); 411 SetPasswordFormRealm(modified_forms.back(), "incorrect");
419 EXPECT_EQ(NULL, match); 412 }
420 413
421 PasswordForm wrong_port(search_form); 414 for (unsigned int j = 0; j < modified_forms.size(); ++j) {
422 wrong_port.signon_realm = 415 PasswordForm* match =
423 std::string("http://some.domain.com:1234/low_security"); 416 keychainAdapter.PasswordExactlyMatchingForm(*modified_forms[j]);
424 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_, 417 EXPECT_EQ(NULL, match) << "In modified version " << j << " of base form "
425 wrong_port); 418 << i;
426 EXPECT_EQ(NULL, match); 419 }
427 420 STLDeleteElements(&modified_forms);
428 PasswordForm wrong_realm(search_form);
429 wrong_realm.signon_realm =
430 std::string("http://some.domain.com:4567/incorrect");
431 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_,
432 wrong_realm);
433 EXPECT_EQ(NULL, match);
434
435 // We don't store blacklist entries in the keychain, and we want to ignore
436 // those stored by other browsers.
437 PasswordForm blacklist(search_form);
438 blacklist.blacklisted_by_user = true;
439 match = internal_keychain_helpers::MatchingKeychainItem(*keychain_,
440 blacklist);
441 EXPECT_EQ(NULL, match);
442 } 421 }
443 } 422 }
444 423
445 TEST_F(PasswordStoreMacTest, TestKeychainAdd) { 424 TEST_F(PasswordStoreMacTest, TestKeychainAdd) {
446 struct TestDataAndExpectation { 425 struct TestDataAndExpectation {
447 PasswordFormData data; 426 PasswordFormData data;
448 bool should_succeed; 427 bool should_succeed;
449 }; 428 };
450 TestDataAndExpectation test_data[] = { 429 TestDataAndExpectation test_data[] = {
451 // Test a variety of scheme/port/protocol/path variations. 430 // Test a variety of scheme/port/protocol/path variations.
(...skipping 20 matching lines...) Expand all
472 L"joe_user", L"fail_me", false, false, 0 }, false }, 451 L"joe_user", L"fail_me", false, false, 0 }, false },
473 }; 452 };
474 453
475 MacKeychainPasswordFormAdapter keychainAdapter(keychain_); 454 MacKeychainPasswordFormAdapter keychainAdapter(keychain_);
476 455
477 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 456 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
478 PasswordForm* in_form = CreatePasswordFormFromData(test_data[i].data); 457 PasswordForm* in_form = CreatePasswordFormFromData(test_data[i].data);
479 bool add_succeeded = keychainAdapter.AddLogin(*in_form); 458 bool add_succeeded = keychainAdapter.AddLogin(*in_form);
480 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); 459 EXPECT_EQ(test_data[i].should_succeed, add_succeeded);
481 if (add_succeeded) { 460 if (add_succeeded) {
482 SecKeychainItemRef matching_item; 461 scoped_ptr<PasswordForm> out_form(
483 matching_item = internal_keychain_helpers::MatchingKeychainItem( 462 keychainAdapter.PasswordExactlyMatchingForm(*in_form));
484 *keychain_, *in_form); 463 EXPECT_TRUE(out_form.get() != NULL);
485 EXPECT_TRUE(matching_item != NULL); 464 EXPECT_EQ(out_form->scheme, in_form->scheme);
486 PasswordForm out_form; 465 EXPECT_EQ(out_form->signon_realm, in_form->signon_realm);
487 internal_keychain_helpers::FillPasswordFormFromKeychainItem( 466 EXPECT_EQ(out_form->origin, in_form->origin);
488 *keychain_, matching_item, &out_form); 467 EXPECT_EQ(out_form->username_value, in_form->username_value);
489 EXPECT_EQ(out_form.scheme, in_form->scheme); 468 EXPECT_EQ(out_form->password_value, in_form->password_value);
490 EXPECT_EQ(out_form.signon_realm, in_form->signon_realm);
491 EXPECT_EQ(out_form.origin, in_form->origin);
492 EXPECT_EQ(out_form.username_value, in_form->username_value);
493 EXPECT_EQ(out_form.password_value, in_form->password_value);
494 keychain_->Free(matching_item);
495 } 469 }
496 delete in_form; 470 delete in_form;
497 } 471 }
498 472
499 // Test that adding duplicate item updates the existing item. 473 // Test that adding duplicate item updates the existing item.
500 { 474 {
501 PasswordFormData data = { 475 PasswordFormData data = {
502 PasswordForm::SCHEME_HTML, "http://some.domain.com", 476 PasswordForm::SCHEME_HTML, "http://some.domain.com",
503 "http://some.domain.com/insecure.html", NULL, 477 "http://some.domain.com/insecure.html", NULL,
504 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 478 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 test_case); 708 test_case);
735 CHECK_FORMS(database_forms, test_data[DATABASE_OUTPUT][test_case], 709 CHECK_FORMS(database_forms, test_data[DATABASE_OUTPUT][test_case],
736 test_case); 710 test_case);
737 CHECK_FORMS(merged_forms, test_data[MERGE_OUTPUT][test_case], test_case); 711 CHECK_FORMS(merged_forms, test_data[MERGE_OUTPUT][test_case], test_case);
738 712
739 STLDeleteElements(&keychain_forms); 713 STLDeleteElements(&keychain_forms);
740 STLDeleteElements(&database_forms); 714 STLDeleteElements(&database_forms);
741 STLDeleteElements(&merged_forms); 715 STLDeleteElements(&merged_forms);
742 } 716 }
743 } 717 }
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