1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gmock/include/gmock/gmock.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_temp_dir.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/keychain_mock_mac.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/password_manager/password_store_consumer.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_store_mac.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_store_mac_internal.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::PasswordForm; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::_; 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::DoAll; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::WithArg; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockPasswordStoreConsumer : public PasswordStoreConsumer { 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochpublic: 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD2(OnPasswordStoreRequestDone, 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void(CancelableRequestProvider::Handle, 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<webkit_glue::PasswordForm*>&)); 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochACTION(STLDeleteElements0) { 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteContainerPointers(arg0.begin(), arg0.end()); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochACTION(QuitUIMessageLoop) { 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Quit(); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma mark - 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass PasswordStoreMacInternalsTest : public testing::Test { 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockKeychain::KeychainTestData test_data[] = { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Basic HTML form. 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeHTMLForm, "some.domain.com", 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z", 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "joe_user", "sekrit", false }, 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // HTML form with path. 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeHTMLForm, "some.domain.com", 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "19991231235959Z", 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "joe_user", "sekrit", false }, 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Secure HTML form with path. 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeHTMLForm, "some.domain.com", 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTPS, "/secure.html", 0, NULL, "20100908070605Z", 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "secure_user", "password", false }, 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // True negative item. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeHTMLForm, "dont.remember.com", 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTP, NULL, 0, NULL, "20000101000000Z", 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "", "", true }, 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // De-facto negative item, type one. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeHTMLForm, "dont.remember.com", 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTP, NULL, 0, NULL, "20000101000000Z", 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Password Not Stored", "", false }, 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // De-facto negative item, type two. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeHTMLForm, "dont.remember.com", 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTPS, NULL, 0, NULL, "20000101000000Z", 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Password Not Stored", " ", false }, 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // HTTP auth basic, with port and path. 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeHTTPBasic, "some.domain.com", 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTP, "/insecure.html", 4567, "low_security", 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "19980330100000Z", 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "basic_auth_user", "basic", false }, 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // HTTP auth digest, secure. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeHTTPDigest, "some.domain.com", 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTPS, NULL, 0, "high_security", "19980330100000Z", 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "digest_auth_user", "digest", false }, 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // An FTP password with an invalid date, for edge-case testing. 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { kSecAuthenticationTypeDefault, "a.server.com", 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeFTP, NULL, 0, NULL, "20010203040", 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "abc", "123", false }, 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Save some extra slots for use by AddInternetPassword. 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int capacity = arraysize(test_data) + 3; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_ = new MockKeychain(capacity); 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < arraysize(test_data); ++i) { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_->AddTestItem(test_data[i]); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void TearDown() { 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExpectCreatesAndFreesBalanced(); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExpectCreatorCodesSet(); 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete keychain_; 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Causes a test failure unless everything returned from keychain_'s 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ItemCopyAttributesAndData, SearchCreateFromAttributes, and SearchCopyNext 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // was correctly freed. 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ExpectCreatesAndFreesBalanced() { 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, keychain_->UnfreedSearchCount()); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, keychain_->UnfreedKeychainItemCount()); 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, keychain_->UnfreedAttributeDataCount()); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Causes a test failure unless any Keychain items added during the test have 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // their creator code set. 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ExpectCreatorCodesSet() { 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(keychain_->CreatorCodesSetForAddedItems()); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockKeychain* keychain_; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma mark - 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Struct used for creation of PasswordForms from static arrays of data. 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct PasswordFormData { 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const PasswordForm::Scheme scheme; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* signon_realm; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* origin; 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* action; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const wchar_t* submit_element; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const wchar_t* username_element; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const wchar_t* password_element; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const wchar_t* username_value; // Set to NULL for a blacklist entry. 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const wchar_t* password_value; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool preferred; 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool ssl_valid; 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const double creation_time; 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates and returns a new PasswordForm built from form_data. Caller is 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// responsible for deleting the object when finished with it. 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic PasswordForm* CreatePasswordFormFromData( 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const PasswordFormData& form_data) { 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* form = new PasswordForm(); 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->scheme = form_data.scheme; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->preferred = form_data.preferred; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->ssl_valid = form_data.ssl_valid; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->date_created = base::Time::FromDoubleT(form_data.creation_time); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_data.signon_realm) 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->signon_realm = std::string(form_data.signon_realm); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_data.origin) 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->origin = GURL(form_data.origin); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_data.action) 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->action = GURL(form_data.action); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_data.submit_element) 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->submit_element = WideToUTF16(form_data.submit_element); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_data.username_element) 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->username_element = WideToUTF16(form_data.username_element); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_data.password_element) 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->password_element = WideToUTF16(form_data.password_element); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_data.username_value) { 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->username_value = WideToUTF16(form_data.username_value); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_data.password_value) 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->password_value = WideToUTF16(form_data.password_value); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->blacklisted_by_user = true; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return form; 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Macro to simplify calling CheckFormsAgainstExpectations with a useful label. 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHECK_FORMS(forms, expectations, i) \ 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckFormsAgainstExpectations(forms, expectations, #forms, i) 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Ensures that the data in |forms| match |expectations|, causing test failures 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// for any discrepencies. 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// matter if |forms| and |expectations| are scrambled. 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void CheckFormsAgainstExpectations( 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<PasswordForm*>& forms, 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<PasswordFormData*>& expectations, 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* forms_label, unsigned int test_number) { 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const unsigned int kBufferSize = 128; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char test_label[kBufferSize]; 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snprintf(test_label, kBufferSize, "%s in test %u", forms_label, test_number); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expectations.size(), forms.size()) << test_label; 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (expectations.size() != forms.size()) 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < expectations.size(); ++i) { 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snprintf(test_label, kBufferSize, "%s in test %u, item %u", 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms_label, test_number, i); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* form = forms[i]; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData* expectation = expectations[i]; 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expectation->scheme, form->scheme) << test_label; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(expectation->signon_realm), form->signon_realm) 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << test_label; 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(GURL(expectation->origin), form->origin) << test_label; 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(GURL(expectation->action), form->action) << test_label; 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(WideToUTF16(expectation->submit_element), form->submit_element) 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << test_label; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(WideToUTF16(expectation->username_element), 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->username_element) << test_label; 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(WideToUTF16(expectation->password_element), 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->password_element) << test_label; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (expectation->username_value) { 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(WideToUTF16(expectation->username_value), 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->username_value) << test_label; 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(WideToUTF16(expectation->password_value), 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->password_value) << test_label; 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(form->blacklisted_by_user) << test_label; 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expectation->preferred, form->preferred) << test_label; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expectation->ssl_valid, form->ssl_valid) << test_label; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_DOUBLE_EQ(expectation->creation_time, 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->date_created.ToDoubleT()) << test_label; 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma mark - 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestKeychainToFormTranslation) { 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef struct { 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const PasswordForm::Scheme scheme; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* signon_realm; 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* origin; 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const wchar_t* username; // Set to NULL to check for a blacklist entry. 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const wchar_t* password; 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool ssl_valid; 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int creation_year; 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int creation_month; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int creation_day; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int creation_hour; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int creation_minute; 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int creation_second; 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } TestExpectations; 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestExpectations expected[] = { 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/", L"joe_user", L"sekrit", false, 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2002, 6, 1, 17, 15, 0 }, 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/insecure.html", L"joe_user", L"sekrit", false, 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1999, 12, 31, 23, 59, 59 }, 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "https://some.domain.com/", 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://some.domain.com/secure.html", L"secure_user", L"password", true, 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2010, 9, 8, 7, 6, 5 }, 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://dont.remember.com/", 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://dont.remember.com/", NULL, NULL, false, 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2000, 1, 1, 0, 0, 0 }, 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://dont.remember.com/", 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://dont.remember.com/", NULL, NULL, false, 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2000, 1, 1, 0, 0, 0 }, 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "https://dont.remember.com/", 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://dont.remember.com/", NULL, NULL, true, 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2000, 1, 1, 0, 0, 0 }, 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com:4567/insecure.html", L"basic_auth_user", L"basic", 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 1998, 03, 30, 10, 00, 00 }, 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://some.domain.com/", L"digest_auth_user", L"digest", true, 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1998, 3, 30, 10, 0, 0 }, 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This one gives us an invalid date, which we will treat as a "NULL" date 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // which is 1601. 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_OTHER, "http://a.server.com/", 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://a.server.com/", L"abc", L"123", false, 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1601, 1, 1, 0, 0, 0 }, 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(expected); ++i) { 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create our fake KeychainItemRef; see MockKeychain docs. 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecKeychainItemRef keychain_item = 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<SecKeychainItemRef>(i + 1); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form; 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem( 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *keychain_, keychain_item, &form); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(parsed) << "In iteration " << i; 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expected[i].scheme, form.scheme) << "In iteration " << i; 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(GURL(expected[i].origin), form.origin) << "In iteration " << i; 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expected[i].ssl_valid, form.ssl_valid) << "In iteration " << i; 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(expected[i].signon_realm), form.signon_realm) 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (expected[i].username) { 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(WideToUTF16(expected[i].username), form.username_value) 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(WideToUTF16(expected[i].password), form.password_value) 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(form.blacklisted_by_user) << "In iteration " << i; 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(form.blacklisted_by_user) << "In iteration " << i; 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::Exploded exploded_time; 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.date_created.UTCExplode(&exploded_time); 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expected[i].creation_year, exploded_time.year) 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expected[i].creation_month, exploded_time.month) 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expected[i].creation_day, exploded_time.day_of_month) 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expected[i].creation_hour, exploded_time.hour) 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expected[i].creation_minute, exploded_time.minute) 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(expected[i].creation_second, exploded_time.second) 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "In iteration " << i; 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use an invalid ref, to make sure errors are reported. 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(99); 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form; 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem( 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *keychain_, keychain_item, &form); 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(parsed); 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestKeychainSearch) { 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TestDataAndExpectation { 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const PasswordFormData data; 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t expected_fill_matches; 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t expected_merge_matches; 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Most fields are left blank because we don't care about them for searching. 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestDataAndExpectation test_data[] = { 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // An HTML form we've seen. 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, L"joe_user", NULL, false, false, 0 }, 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2, 2 }, 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, L"wrong_user", NULL, false, false, 0 }, 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2, 0 }, 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // An HTML form we haven't seen 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://www.unseendomain.com/", 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, L"joe_user", NULL, false, false, 0 }, 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0 }, 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Basic auth that should match. 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, false, false, 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0 }, 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, 1 }, 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Basic auth with the wrong port. 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_BASIC, "http://some.domain.com:1111/low_security", 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, false, false, 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0 }, 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0 }, 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Digest auth we've saved under https, visited with http. 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_DIGEST, "http://some.domain.com/high_security", 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, false, false, 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0 }, 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0 }, 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Digest auth that should match. 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, L"wrong_user", NULL, false, true, 0 }, 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, 0 }, 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Digest auth with the wrong domain. 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/other_domain", 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, false, true, 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0 }, 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0 }, 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Garbage forms should have no matches. 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "foo/bar/baz", 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 }, 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> query_form( 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreatePasswordFormFromData(test_data[i].data)); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check matches treating the form as a fill target. 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> matching_items = 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_adapter.PasswordsFillingForm(*query_form); 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&matching_items); 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check matches treating the form as a merging target. 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(test_data[i].expected_merge_matches > 0, 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_adapter.HasPasswordsMergeableWithForm(*query_form)); 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch matching_items = keychain_adapter.PasswordsMergeableWithForm(*query_form); 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(test_data[i].expected_merge_matches, matching_items.size()); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&matching_items); 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // None of the pre-seeded items are owned by us, so none should match an 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // owned-passwords-only search. 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch matching_items = owned_keychain_adapter.PasswordsFillingForm(*query_form); 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0U, matching_items.size()); 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&matching_items); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Changes just the origin path of |form|. 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void SetPasswordFormPath(PasswordForm* form, const char* path) { 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL::Replacements replacement; 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string new_value(path); 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacement.SetPathStr(new_value); 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->origin = form->origin.ReplaceComponents(replacement); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Changes just the signon_realm port of |form|. 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void SetPasswordFormPort(PasswordForm* form, const char* port) { 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL::Replacements replacement; 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string new_value(port); 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacement.SetPortStr(new_value); 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL signon_gurl = GURL(form->signon_realm); 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->signon_realm = signon_gurl.ReplaceComponents(replacement).spec(); 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Changes just the signon_ream auth realm of |form|. 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void SetPasswordFormRealm(PasswordForm* form, const char* realm) { 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL::Replacements replacement; 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string new_value(realm); 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacement.SetPathStr(new_value); 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL signon_gurl = GURL(form->signon_realm); 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->signon_realm = signon_gurl.ReplaceComponents(replacement).spec(); 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestKeychainExactSearch) { 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData base_form_data[] = { 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/insecure.html", 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, L"joe_user", NULL, true, false, 0 }, 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com:4567/insecure.html", 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://some.domain.com", 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a base form and make sure we find a match. 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> base_form(CreatePasswordFormFromData( 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base_form_data[i])); 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form)); 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* match = 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_adapter.PasswordExactlyMatchingForm(*base_form); 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(match != NULL); 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (match) { 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(base_form->scheme, match->scheme); 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(base_form->origin, match->origin); 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(base_form->username_value, match->username_value); 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete match; 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure that the matching isn't looser than it should be by checking 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that slightly altered forms don't match. 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> modified_forms; 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.push_back(new PasswordForm(*base_form)); 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.back()->username_value = ASCIIToUTF16("wrong_user"); 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.push_back(new PasswordForm(*base_form)); 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetPasswordFormPath(modified_forms.back(), "elsewhere.html"); 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.push_back(new PasswordForm(*base_form)); 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.back()->scheme = PasswordForm::SCHEME_OTHER; 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.push_back(new PasswordForm(*base_form)); 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetPasswordFormPort(modified_forms.back(), "1234"); 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.push_back(new PasswordForm(*base_form)); 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.back()->blacklisted_by_user = true; 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (base_form->scheme == PasswordForm::SCHEME_BASIC || 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base_form->scheme == PasswordForm::SCHEME_DIGEST) { 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch modified_forms.push_back(new PasswordForm(*base_form)); 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetPasswordFormRealm(modified_forms.back(), "incorrect"); 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int j = 0; j < modified_forms.size(); ++j) { 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* match = 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_adapter.PasswordExactlyMatchingForm(*modified_forms[j]); 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(NULL, match) << "In modified version " << j << " of base form " 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << i; 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&modified_forms); 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestKeychainAdd) { 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TestDataAndExpectation { 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData data; 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool should_succeed; 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestDataAndExpectation test_data[] = { 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test a variety of scheme/port/protocol/path variations. 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://web.site.com/", 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"anonymous", L"knock-knock", false, false, 0 }, true }, 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "https://web.site.com/", 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://web.site.com/", NULL, NULL, NULL, NULL, 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"admin", L"p4ssw0rd", false, false, 0 }, true }, 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://a.site.com:2222/", NULL, NULL, NULL, NULL, 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"username", L"password", false, false, 0 }, true }, 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"testname", L"testpass", false, false, 0 }, true }, 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure that garbage forms are rejected. 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "gobbledygook", 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gobbledygook", NULL, NULL, NULL, NULL, 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"anonymous", L"knock-knock", false, false, 0 }, false }, 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test that failing to update a duplicate (forced using the magic failure 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // password; see MockKeychain::ItemModifyAttributesAndData) is reported. 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://some.domain.com", 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"joe_user", L"fail_me", false, false, 0 }, false }, 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> in_form( 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreatePasswordFormFromData(test_data[i].data)); 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(test_data[i].should_succeed, add_succeeded); 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (add_succeeded) { 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *in_form)); 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> out_form( 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_keychain_adapter.PasswordExactlyMatchingForm(*in_form)); 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(out_form.get() != NULL); 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out_form->scheme, in_form->scheme); 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out_form->signon_realm, in_form->signon_realm); 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out_form->origin, in_form->origin); 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out_form->username_value, in_form->username_value); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(out_form->password_value, in_form->password_value); 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test that adding duplicate item updates the existing item. 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData data = { 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm::SCHEME_HTML, "http://some.domain.com", 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/insecure.html", NULL, 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> update_form(CreatePasswordFormFromData(data)); 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm stored_form; 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_item, 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &stored_form); 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(update_form->password_value, stored_form.password_value); 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestKeychainRemove) { 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TestDataAndExpectation { 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData data; 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool should_succeed; 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestDataAndExpectation test_data[] = { 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test deletion of an item that we add. 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://web.site.com/", 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"anonymous", L"knock-knock", false, false, 0 }, true }, 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we don't delete items we don't own. 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"joe_user", NULL, true, false, 0 }, false }, 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add our test item so that we can delete it. 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* add_form = CreatePasswordFormFromData(test_data[0].data); 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete add_form; 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[i].data)); 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(test_data[i].should_succeed, 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_keychain_adapter.RemovePassword(*form)); 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* match = keychain_adapter.PasswordExactlyMatchingForm(*form); 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(test_data[i].should_succeed, match == NULL); 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (match) { 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete match; 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestFormMatch) { 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm base_form; 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base_form.signon_realm = std::string("http://some.domain.com/"); 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base_form.origin = GURL("http://some.domain.com/page.html"); 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base_form.username_value = ASCIIToUTF16("joe_user"); 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check that everything unimportant can be changed. 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm different_form(base_form); 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.username_element = ASCIIToUTF16("username"); 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.submit_element = ASCIIToUTF16("submit"); 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.username_element = ASCIIToUTF16("password"); 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.password_value = ASCIIToUTF16("sekrit"); 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.action = GURL("http://some.domain.com/action.cgi"); 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.ssl_valid = true; 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.preferred = true; 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.date_created = base::Time::Now(); 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(internal_keychain_helpers::FormsMatchForMerge(base_form, 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form)); 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check that path differences don't prevent a match. 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base_form.origin = GURL("http://some.domain.com/other_page.html"); 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(internal_keychain_helpers::FormsMatchForMerge(base_form, 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form)); 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check that any one primary key changing is enough to prevent matching. 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm different_form(base_form); 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.scheme = PasswordForm::SCHEME_DIGEST; 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(internal_keychain_helpers::FormsMatchForMerge(base_form, 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form)); 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm different_form(base_form); 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.signon_realm = std::string("http://some.domain.com:8080/"); 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(internal_keychain_helpers::FormsMatchForMerge(base_form, 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form)); 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm different_form(base_form); 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.username_value = ASCIIToUTF16("john.doe"); 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(internal_keychain_helpers::FormsMatchForMerge(base_form, 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form)); 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm different_form(base_form); 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form.blacklisted_by_user = true; 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(internal_keychain_helpers::FormsMatchForMerge(base_form, 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different_form)); 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Blacklist forms should *never* match for merging, even when identical 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (and certainly not when only one is a blacklist entry). 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form_a(base_form); 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form_a.blacklisted_by_user = true; 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form_b(form_a); 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(internal_keychain_helpers::FormsMatchForMerge(form_a, form_b)); 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestFormMerge) { 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up a bunch of test data to use in varying combinations. 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData keychain_user_1 = 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/", "", L"", L"", L"", L"joe_user", L"sekrit", 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, false, 1010101010 }; 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData keychain_user_1_with_path = 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/page.html", 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "", L"", L"", L"", L"joe_user", L"otherpassword", 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, false, 1010101010 }; 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData keychain_user_2 = 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/", "", L"", L"", L"", L"john.doe", L"sesame", 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, false, 958739876 }; 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData keychain_blacklist = 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/", "", L"", L"", L"", NULL, NULL, 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, false, 1010101010 }; 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData db_user_1 = 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/", "http://some.domain.com/action.cgi", 688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"joe_user", L"", 689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1212121212 }; 690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData db_user_1_with_path = 691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/page.html", 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/handlepage.cgi", 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"joe_user", L"", 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1234567890 }; 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData db_user_3_with_path = 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/page.html", 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/handlepage.cgi", 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"second-account", L"", 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1240000000 }; 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData database_blacklist_with_path = 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/path.html", "http://some.domain.com/action.cgi", 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", NULL, NULL, 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1212121212 }; 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData merged_user_1 = 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/", "http://some.domain.com/action.cgi", 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"joe_user", L"sekrit", 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1212121212 }; 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData merged_user_1_with_db_path = 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/page.html", 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/handlepage.cgi", 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"joe_user", L"sekrit", 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1234567890 }; 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData merged_user_1_with_both_paths = 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/page.html", 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/handlepage.cgi", 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"joe_user", L"otherpassword", 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1234567890 }; 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Build up the big multi-dimensional array of data sets that will actually 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // drive the test. Use vectors rather than arrays so that initialization is 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // simple. 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum { 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KEYCHAIN_INPUT = 0, 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DATABASE_INPUT, 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MERGE_OUTPUT, 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KEYCHAIN_OUTPUT, 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DATABASE_OUTPUT, 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MERGE_IO_ARRAY_COUNT // termination marker 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const unsigned int kTestCount = 4; 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector< std::vector< std::vector<PasswordFormData*> > > test_data( 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MERGE_IO_ARRAY_COUNT, std::vector< std::vector<PasswordFormData*> >( 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTestCount, std::vector<PasswordFormData*>())); 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned int current_test = 0; 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test a merge with a few accounts in both systems, with partial overlap. 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(current_test < kTestCount); 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1); 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_2); 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_INPUT][current_test].push_back(&db_user_1); 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path); 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_INPUT][current_test].push_back(&db_user_3_with_path); 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1); 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1_with_db_path); 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_OUTPUT][current_test].push_back(&keychain_user_2); 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_OUTPUT][current_test].push_back(&db_user_3_with_path); 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test a merge where Chrome has a blacklist entry, and the keychain has 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a stored account. 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++current_test; 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(current_test < kTestCount); 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1); 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_INPUT][current_test].push_back( 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &database_blacklist_with_path); 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We expect both to be present because a blacklist could be specific to a 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // subpath, and we want access to the password on other paths. 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[MERGE_OUTPUT][current_test].push_back( 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &database_blacklist_with_path); 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_OUTPUT][current_test].push_back(&keychain_user_1); 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test a merge where Chrome has an account, and Keychain has a blacklist 769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (from another browser) and the Chrome password data. 770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++current_test; 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(current_test < kTestCount); 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_blacklist); 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1); 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_INPUT][current_test].push_back(&db_user_1); 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1); 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_OUTPUT][current_test].push_back(&keychain_blacklist); 777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test that matches are done using exact path when possible. 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++current_test; 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(current_test < kTestCount); 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1); 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1_with_path); 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_INPUT][current_test].push_back(&db_user_1); 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path); 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1); 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[MERGE_OUTPUT][current_test].push_back( 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &merged_user_1_with_both_paths); 788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int test_case = 0; test_case <= current_test; ++test_case) { 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> keychain_forms; 791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<PasswordFormData*>::iterator i = 792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[KEYCHAIN_INPUT][test_case].begin(); 793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) { 794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_forms.push_back(CreatePasswordFormFromData(*(*i))); 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> database_forms; 797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<PasswordFormData*>::iterator i = 798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_data[DATABASE_INPUT][test_case].begin(); 799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != test_data[DATABASE_INPUT][test_case].end(); ++i) { 800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch database_forms.push_back(CreatePasswordFormFromData(*(*i))); 801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> merged_forms; 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch internal_keychain_helpers::MergePasswordForms(&keychain_forms, 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &database_forms, 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &merged_forms); 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK_FORMS(keychain_forms, test_data[KEYCHAIN_OUTPUT][test_case], 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_case); 810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK_FORMS(database_forms, test_data[DATABASE_OUTPUT][test_case], 811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_case); 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK_FORMS(merged_forms, test_data[MERGE_OUTPUT][test_case], test_case); 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&keychain_forms); 815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&database_forms); 816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&merged_forms); 817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestPasswordBulkLookup) { 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData db_data[] = { 822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/", "http://some.domain.com/action.cgi", 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"joe_user", L"", 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1212121212 }, 826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/page.html", 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/handlepage.cgi", 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"joe_user", L"", 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1234567890 }, 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/page.html", 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/handlepage.cgi", 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"second-account", L"", 835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1240000000 }, 836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://dont.remember.com/", 837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://dont.remember.com/", 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://dont.remember.com/handlepage.cgi", 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", L"joe_user", L"", 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1240000000 }, 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/path.html", "http://some.domain.com/action.cgi", 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"submit", L"username", L"password", NULL, NULL, 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 1212121212 }, 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> database_forms; 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(db_data); ++i) { 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch database_forms.push_back(CreatePasswordFormFromData(db_data[i])); 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> merged_forms = 851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch internal_keychain_helpers::GetPasswordsForForms(*keychain_, 852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &database_forms); 853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2U, database_forms.size()); 854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(3U, merged_forms.size()); 855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value); 856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value); 85772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(merged_forms[2]->blacklisted_by_user); 858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&database_forms); 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&merged_forms); 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacInternalsTest, TestPasswordGetAll) { 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a few passwords of various types so that we own some. 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData owned_password_data[] = { 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_HTML, "http://web.site.com/", 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"anonymous", L"knock-knock", false, false, 0 }, 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://a.site.com:2222/", NULL, NULL, NULL, NULL, 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"username", L"password", false, false, 0 }, 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", 877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"testname", L"testpass", false, false, 0 }, 879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { 881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_password_data[i])); 883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_keychain_adapter.AddPassword(*form); 884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> all_passwords = 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_adapter.GetAllPasswordFormPasswords(); 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size()); 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&all_passwords); 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> owned_passwords = 892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owned_keychain_adapter.GetAllPasswordFormPasswords(); 893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); 894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&owned_passwords); 895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma mark - 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass PasswordStoreMacTest : public testing::Test { 900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 901731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {} 902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch login_db_ = new LoginDatabase(); 905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath db_file = db_dir_.path().AppendASCII("login.db"); 907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(login_db_->Init(db_file)); 908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_ = new MockKeychain(3); 910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch store_ = new PasswordStoreMac(keychain_, login_db_); 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(store_->Init()); 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void TearDown() { 9163dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen store_->Shutdown(); 917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask); 918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Run(); 919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoopForUI message_loop_; 923731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread ui_thread_; 924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockKeychain* keychain_; // Owned by store_. 926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LoginDatabase* login_db_; // Owned by store_. 927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<PasswordStoreMac> store_; 928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedTempDir db_dir_; 929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 931c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordStoreMacTest, TestStoreUpdate) { 932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Insert a password into both the database and the keychain. 933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is done manually, rather than through store_->AddLogin, because the 934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Mock Keychain isn't smart enough to be able to support update generically, 935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // so some.domain.com triggers special handling to test it that make inserting 936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // fail. 937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData joint_data = { 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm::SCHEME_HTML, "http://some.domain.com/", 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/insecure.html", "login.cgi", 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> joint_form(CreatePasswordFormFromData(joint_data)); 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch login_db_->AddLogin(*joint_form); 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockKeychain::KeychainTestData joint_keychain_data = { 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecAuthenticationTypeHTMLForm, "some.domain.com", 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "joe_user", "sekrit", false }; 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_->AddTestItem(joint_keychain_data); 949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Insert a password into the keychain only. 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockKeychain::KeychainTestData keychain_only_data = { 952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecAuthenticationTypeHTMLForm, "keychain.only.com", 953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z", 954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "keychain", "only", false 955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_->AddTestItem(keychain_only_data); 957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct UpdateData { 959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordFormData form_data; 960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* password; // NULL indicates no entry should be present. 961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make a series of update calls. 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateData updates[] = { 965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Update the keychain+db passwords (the normal password update case). 966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://some.domain.com/insecure.html", "login.cgi", 968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"username", L"password", L"submit", L"joe_user", L"53krit", 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 2 }, 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "53krit", 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Update the keychain-only password; this simulates the initial use of a 973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // password stored by another browsers. 974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://keychain.only.com/", 975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://keychain.only.com/login.html", "login.cgi", 976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"username", L"password", L"submit", L"keychain", L"only", 977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 2 }, 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "only", 979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Update a password that doesn't exist in either location. This tests the 981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // case where a form is filled, then the stored login is removed, then the 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // form is submitted. 983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { { PasswordForm::SCHEME_HTML, "http://different.com/", 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "http://different.com/index.html", "login.cgi", 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"username", L"password", L"submit", L"abc", L"123", 986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, false, 2 }, 987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }, 989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(updates); ++i) { 991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( 992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch updates[i].form_data)); 993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch store_->UpdateLogin(*form); 994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do a store-level query to wait for all the operations above to be done. 997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockPasswordStoreConsumer consumer; 998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)).WillByDefault( 999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QuitUIMessageLoop()); 1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(consumer, OnPasswordStoreRequestDone(_, _)).WillOnce( 1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop())); 1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch store_->GetLogins(*joint_form, &consumer); 1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Run(); 1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(updates); ++i) { 1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordForm> query_form( 1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreatePasswordFormFromData(updates[i].form_data)); 1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> matching_items = 1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keychain_adapter.PasswordsFillingForm(*query_form); 1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (updates[i].password) { 1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; 1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (matching_items.size() >= 1) 1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ASCIIToUTF16(updates[i].password), 1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch matching_items[0]->password_value) << "iteration " << i; 1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0U, matching_items.size()) << "iteration " << i; 1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&matching_items); 1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch login_db_->GetLogins(*query_form, &matching_items); 1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(updates[i].password ? 1U : 0U, matching_items.size()) 1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "iteration " << i; 1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&matching_items); 1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1028