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

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

Issue 866983003: GetLoginsRequest: Use ScopedVector to express ownership of forms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@324291_scopedvector
Patch Set: Second fix of the rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/password_manager/password_store_mac.h" 5 #include "chrome/browser/password_manager/password_store_mac.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/files/scoped_temp_dir.h" 8 #include "base/files/scoped_temp_dir.h"
9 #include "base/scoped_observer.h" 9 #include "base/scoped_observer.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
14 #include "chrome/browser/password_manager/password_store_mac_internal.h" 14 #include "chrome/browser/password_manager/password_store_mac_internal.h"
15 #include "chrome/common/chrome_paths.h" 15 #include "chrome/common/chrome_paths.h"
16 #include "components/password_manager/core/browser/login_database.h" 16 #include "components/password_manager/core/browser/login_database.h"
17 #include "components/password_manager/core/browser/password_form_data.h"
17 #include "components/password_manager/core/browser/password_store_consumer.h" 18 #include "components/password_manager/core/browser/password_store_consumer.h"
18 #include "content/public/test/test_browser_thread.h" 19 #include "content/public/test/test_browser_thread.h"
19 #include "crypto/mock_apple_keychain.h" 20 #include "crypto/mock_apple_keychain.h"
20 #include "testing/gmock/include/gmock/gmock.h" 21 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
22 23
23 using autofill::PasswordForm; 24 using autofill::PasswordForm;
24 using base::ASCIIToUTF16; 25 using base::ASCIIToUTF16;
25 using base::WideToUTF16; 26 using base::WideToUTF16;
26 using content::BrowserThread; 27 using content::BrowserThread;
27 using crypto::MockAppleKeychain; 28 using crypto::MockAppleKeychain;
28 using internal_keychain_helpers::FormsMatchForMerge; 29 using internal_keychain_helpers::FormsMatchForMerge;
29 using internal_keychain_helpers::STRICT_FORM_MATCH; 30 using internal_keychain_helpers::STRICT_FORM_MATCH;
30 using password_manager::LoginDatabase; 31 using password_manager::LoginDatabase;
31 using password_manager::PasswordStore; 32 using password_manager::PasswordStore;
32 using password_manager::PasswordStoreConsumer; 33 using password_manager::PasswordStoreConsumer;
33 using testing::_; 34 using testing::_;
34 using testing::DoAll; 35 using testing::DoAll;
35 using testing::Invoke; 36 using testing::Invoke;
37 using testing::IsEmpty;
38 using testing::SizeIs;
36 using testing::WithArg; 39 using testing::WithArg;
37 40
38 namespace { 41 namespace {
39 42
40 ACTION(STLDeleteElements0) {
41 STLDeleteContainerPointers(arg0.begin(), arg0.end());
42 }
43
44 ACTION(QuitUIMessageLoop) { 43 ACTION(QuitUIMessageLoop) {
45 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
46 base::MessageLoop::current()->Quit(); 45 base::MessageLoop::current()->Quit();
47 } 46 }
48 47
48 // From the mock's argument #0 of type const std::vector<PasswordForm*>& takes
49 // the first form and copies it to the form pointed to by |target_form_ptr|.
50 ACTION_P(SaveACopyOfFirstForm, target_form_ptr) {
51 ASSERT_FALSE(arg0.empty());
52 *target_form_ptr = *arg0[0];
53 }
54
49 class MockPasswordStoreConsumer : public PasswordStoreConsumer { 55 class MockPasswordStoreConsumer : public PasswordStoreConsumer {
50 public: 56 public:
51 MOCK_METHOD1(OnGetPasswordStoreResults, 57 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef,
52 void(const std::vector<autofill::PasswordForm*>&)); 58 void(const std::vector<PasswordForm*>&));
53 59
54 void CopyElements(const std::vector<autofill::PasswordForm*>& forms) { 60 // GMock cannot mock methods with move-only args.
55 last_result.clear(); 61 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override {
56 for (size_t i = 0; i < forms.size(); ++i) { 62 OnGetPasswordStoreResultsConstRef(results.get());
57 last_result.push_back(*forms[i]);
58 }
59 } 63 }
60
61 // Runs the current thread's message loop until OnGetPasswordStoreResults()
62 // is posted to it. This method should be called immediately after GetLogins,
63 // without pumping the message loop in-between.
64 void WaitOnGetPasswordStoreResults() {
65 EXPECT_CALL(*this, OnGetPasswordStoreResults(_)).WillOnce(DoAll(
66 WithArg<0>(Invoke(this, &MockPasswordStoreConsumer::CopyElements)),
67 WithArg<0>(STLDeleteElements0()),
68 QuitUIMessageLoop()));
69 base::MessageLoop::current()->Run();
70 }
71
72 std::vector<PasswordForm> last_result;
73 }; 64 };
74 65
75 class MockPasswordStoreObserver : public PasswordStore::Observer { 66 class MockPasswordStoreObserver : public PasswordStore::Observer {
76 public: 67 public:
77 MOCK_METHOD1(OnLoginsChanged, 68 MOCK_METHOD1(OnLoginsChanged,
78 void(const password_manager::PasswordStoreChangeList& changes)); 69 void(const password_manager::PasswordStoreChangeList& changes));
79 }; 70 };
80 71
81 // A mock LoginDatabase that simulates a failing Init() method. 72 // A mock LoginDatabase that simulates a failing Init() method.
82 class BadLoginDatabase : public password_manager::LoginDatabase { 73 class BadLoginDatabase : public password_manager::LoginDatabase {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 login_db.Pass()) {} 117 login_db.Pass()) {}
127 118
128 using PasswordStoreMac::GetBackgroundTaskRunner; 119 using PasswordStoreMac::GetBackgroundTaskRunner;
129 120
130 private: 121 private:
131 ~TestPasswordStoreMac() override {} 122 ~TestPasswordStoreMac() override {}
132 123
133 DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreMac); 124 DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreMac);
134 }; 125 };
135 126
136 } // namespace
137
138 #pragma mark -
139
140 class PasswordStoreMacInternalsTest : public testing::Test {
141 public:
142 void SetUp() override {
143 MockAppleKeychain::KeychainTestData test_data[] = {
144 // Basic HTML form.
145 { kSecAuthenticationTypeHTMLForm, "some.domain.com",
146 kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z",
147 "joe_user", "sekrit", false },
148 // HTML form with path.
149 { kSecAuthenticationTypeHTMLForm, "some.domain.com",
150 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "19991231235959Z",
151 "joe_user", "sekrit", false },
152 // Secure HTML form with path.
153 { kSecAuthenticationTypeHTMLForm, "some.domain.com",
154 kSecProtocolTypeHTTPS, "/secure.html", 0, NULL, "20100908070605Z",
155 "secure_user", "password", false },
156 // True negative item.
157 { kSecAuthenticationTypeHTMLForm, "dont.remember.com",
158 kSecProtocolTypeHTTP, NULL, 0, NULL, "20000101000000Z",
159 "", "", true },
160 // De-facto negative item, type one.
161 { kSecAuthenticationTypeHTMLForm, "dont.remember.com",
162 kSecProtocolTypeHTTP, NULL, 0, NULL, "20000101000000Z",
163 "Password Not Stored", "", false },
164 // De-facto negative item, type two.
165 { kSecAuthenticationTypeHTMLForm, "dont.remember.com",
166 kSecProtocolTypeHTTPS, NULL, 0, NULL, "20000101000000Z",
167 "Password Not Stored", " ", false },
168 // HTTP auth basic, with port and path.
169 { kSecAuthenticationTypeHTTPBasic, "some.domain.com",
170 kSecProtocolTypeHTTP, "/insecure.html", 4567, "low_security",
171 "19980330100000Z",
172 "basic_auth_user", "basic", false },
173 // HTTP auth digest, secure.
174 { kSecAuthenticationTypeHTTPDigest, "some.domain.com",
175 kSecProtocolTypeHTTPS, NULL, 0, "high_security", "19980330100000Z",
176 "digest_auth_user", "digest", false },
177 // An FTP password with an invalid date, for edge-case testing.
178 { kSecAuthenticationTypeDefault, "a.server.com",
179 kSecProtocolTypeFTP, NULL, 0, NULL, "20010203040",
180 "abc", "123", false },
181 };
182
183 keychain_ = new MockAppleKeychain();
184
185 for (unsigned int i = 0; i < arraysize(test_data); ++i) {
186 keychain_->AddTestItem(test_data[i]);
187 }
188 }
189
190 void TearDown() override {
191 ExpectCreatesAndFreesBalanced();
192 ExpectCreatorCodesSet();
193 delete keychain_;
194 }
195
196 protected:
197 // Causes a test failure unless everything returned from keychain_'s
198 // ItemCopyAttributesAndData, SearchCreateFromAttributes, and SearchCopyNext
199 // was correctly freed.
200 void ExpectCreatesAndFreesBalanced() {
201 EXPECT_EQ(0, keychain_->UnfreedSearchCount());
202 EXPECT_EQ(0, keychain_->UnfreedKeychainItemCount());
203 EXPECT_EQ(0, keychain_->UnfreedAttributeDataCount());
204 }
205
206 // Causes a test failure unless any Keychain items added during the test have
207 // their creator code set.
208 void ExpectCreatorCodesSet() {
209 EXPECT_TRUE(keychain_->CreatorCodesSetForAddedItems());
210 }
211
212 MockAppleKeychain* keychain_;
213 };
214
215 #pragma mark - 127 #pragma mark -
216 128
217 // Struct used for creation of PasswordForms from static arrays of data. 129 // Struct used for creation of PasswordForms from static arrays of data.
218 struct PasswordFormData { 130 struct PasswordFormData {
219 const PasswordForm::Scheme scheme; 131 const PasswordForm::Scheme scheme;
220 const char* signon_realm; 132 const char* signon_realm;
221 const char* origin; 133 const char* origin;
222 const char* action; 134 const char* action;
223 const wchar_t* submit_element; 135 const wchar_t* submit_element;
224 const wchar_t* username_element; 136 const wchar_t* username_element;
225 const wchar_t* password_element; 137 const wchar_t* password_element;
226 const wchar_t* username_value; // Set to NULL for a blacklist entry. 138 const wchar_t* username_value; // Set to NULL for a blacklist entry.
227 const wchar_t* password_value; 139 const wchar_t* password_value;
228 const bool preferred; 140 const bool preferred;
229 const bool ssl_valid; 141 const bool ssl_valid;
230 const double creation_time; 142 const double creation_time;
231 }; 143 };
232 144
233 // Creates and returns a new PasswordForm built from form_data. Caller is 145 // Creates and returns a new PasswordForm built from form_data.
234 // responsible for deleting the object when finished with it. 146 scoped_ptr<PasswordForm> CreatePasswordFormFromData(
235 static PasswordForm* CreatePasswordFormFromData(
236 const PasswordFormData& form_data) { 147 const PasswordFormData& form_data) {
237 PasswordForm* form = new PasswordForm(); 148 scoped_ptr<PasswordForm> form(new PasswordForm());
238 form->scheme = form_data.scheme; 149 form->scheme = form_data.scheme;
239 form->preferred = form_data.preferred; 150 form->preferred = form_data.preferred;
240 form->ssl_valid = form_data.ssl_valid; 151 form->ssl_valid = form_data.ssl_valid;
241 form->date_created = base::Time::FromDoubleT(form_data.creation_time); 152 form->date_created = base::Time::FromDoubleT(form_data.creation_time);
242 form->date_synced = form->date_created + base::TimeDelta::FromDays(1); 153 form->date_synced = form->date_created + base::TimeDelta::FromDays(1);
243 if (form_data.signon_realm) 154 if (form_data.signon_realm)
244 form->signon_realm = std::string(form_data.signon_realm); 155 form->signon_realm = std::string(form_data.signon_realm);
245 if (form_data.origin) 156 if (form_data.origin)
246 form->origin = GURL(form_data.origin); 157 form->origin = GURL(form_data.origin);
247 if (form_data.action) 158 if (form_data.action)
248 form->action = GURL(form_data.action); 159 form->action = GURL(form_data.action);
249 if (form_data.submit_element) 160 if (form_data.submit_element)
250 form->submit_element = WideToUTF16(form_data.submit_element); 161 form->submit_element = WideToUTF16(form_data.submit_element);
251 if (form_data.username_element) 162 if (form_data.username_element)
252 form->username_element = WideToUTF16(form_data.username_element); 163 form->username_element = WideToUTF16(form_data.username_element);
253 if (form_data.password_element) 164 if (form_data.password_element)
254 form->password_element = WideToUTF16(form_data.password_element); 165 form->password_element = WideToUTF16(form_data.password_element);
255 if (form_data.username_value) { 166 if (form_data.username_value) {
256 form->username_value = WideToUTF16(form_data.username_value); 167 form->username_value = WideToUTF16(form_data.username_value);
257 form->display_name = form->username_value; 168 form->display_name = form->username_value;
258 form->skip_zero_click = true; 169 form->skip_zero_click = true;
259 if (form_data.password_value) 170 if (form_data.password_value)
260 form->password_value = WideToUTF16(form_data.password_value); 171 form->password_value = WideToUTF16(form_data.password_value);
261 } else { 172 } else {
262 form->blacklisted_by_user = true; 173 form->blacklisted_by_user = true;
263 } 174 }
264 form->avatar_url = GURL("https://accounts.google.com/Avatar"); 175 form->avatar_url = GURL("https://accounts.google.com/Avatar");
265 form->federation_url = GURL("https://accounts.google.com/login"); 176 form->federation_url = GURL("https://accounts.google.com/login");
266 return form; 177 return form.Pass();
267 } 178 }
268 179
269 // Macro to simplify calling CheckFormsAgainstExpectations with a useful label. 180 // Macro to simplify calling CheckFormsAgainstExpectations with a useful label.
270 #define CHECK_FORMS(forms, expectations, i) \ 181 #define CHECK_FORMS(forms, expectations, i) \
271 CheckFormsAgainstExpectations(forms, expectations, #forms, i) 182 CheckFormsAgainstExpectations(forms, expectations, #forms, i)
272 183
273 // Ensures that the data in |forms| match |expectations|, causing test failures 184 // Ensures that the data in |forms| match |expectations|, causing test failures
274 // for any discrepencies. 185 // for any discrepencies.
275 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't 186 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't
276 // matter if |forms| and |expectations| are scrambled. 187 // matter if |forms| and |expectations| are scrambled.
277 static void CheckFormsAgainstExpectations( 188 void CheckFormsAgainstExpectations(
278 const std::vector<PasswordForm*>& forms, 189 const std::vector<PasswordForm*>& forms,
279 const std::vector<PasswordFormData*>& expectations, 190 const std::vector<PasswordFormData*>& expectations,
280 const char* forms_label, unsigned int test_number) { 191 const char* forms_label,
192 unsigned int test_number) {
281 const unsigned int kBufferSize = 128; 193 const unsigned int kBufferSize = 128;
282 char test_label[kBufferSize]; 194 char test_label[kBufferSize];
283 snprintf(test_label, kBufferSize, "%s in test %u", forms_label, test_number); 195 snprintf(test_label, kBufferSize, "%s in test %u", forms_label, test_number);
284 196
285 EXPECT_EQ(expectations.size(), forms.size()) << test_label; 197 EXPECT_EQ(expectations.size(), forms.size()) << test_label;
286 if (expectations.size() != forms.size()) 198 if (expectations.size() != forms.size())
287 return; 199 return;
288 200
289 for (unsigned int i = 0; i < expectations.size(); ++i) { 201 for (unsigned int i = 0; i < expectations.size(); ++i) {
290 snprintf(test_label, kBufferSize, "%s in test %u, item %u", 202 snprintf(test_label, kBufferSize, "%s in test %u, item %u",
(...skipping 27 matching lines...) Expand all
318 EXPECT_DOUBLE_EQ(expectation->creation_time, 230 EXPECT_DOUBLE_EQ(expectation->creation_time,
319 form->date_created.ToDoubleT()) << test_label; 231 form->date_created.ToDoubleT()) << test_label;
320 base::Time created = base::Time::FromDoubleT(expectation->creation_time); 232 base::Time created = base::Time::FromDoubleT(expectation->creation_time);
321 EXPECT_EQ(created + base::TimeDelta::FromDays(1), 233 EXPECT_EQ(created + base::TimeDelta::FromDays(1),
322 form->date_synced) << test_label; 234 form->date_synced) << test_label;
323 EXPECT_EQ(GURL("https://accounts.google.com/Avatar"), form->avatar_url); 235 EXPECT_EQ(GURL("https://accounts.google.com/Avatar"), form->avatar_url);
324 EXPECT_EQ(GURL("https://accounts.google.com/login"), form->federation_url); 236 EXPECT_EQ(GURL("https://accounts.google.com/login"), form->federation_url);
325 } 237 }
326 } 238 }
327 239
240 } // namespace
241
242 #pragma mark -
243
244 class PasswordStoreMacInternalsTest : public testing::Test {
245 public:
246 void SetUp() override {
247 MockAppleKeychain::KeychainTestData test_data[] = {
248 // Basic HTML form.
249 {kSecAuthenticationTypeHTMLForm,
250 "some.domain.com",
251 kSecProtocolTypeHTTP,
252 NULL,
253 0,
254 NULL,
255 "20020601171500Z",
256 "joe_user",
257 "sekrit",
258 false},
259 // HTML form with path.
260 {kSecAuthenticationTypeHTMLForm,
261 "some.domain.com",
262 kSecProtocolTypeHTTP,
263 "/insecure.html",
264 0,
265 NULL,
266 "19991231235959Z",
267 "joe_user",
268 "sekrit",
269 false},
270 // Secure HTML form with path.
271 {kSecAuthenticationTypeHTMLForm,
272 "some.domain.com",
273 kSecProtocolTypeHTTPS,
274 "/secure.html",
275 0,
276 NULL,
277 "20100908070605Z",
278 "secure_user",
279 "password",
280 false},
281 // True negative item.
282 {kSecAuthenticationTypeHTMLForm,
283 "dont.remember.com",
284 kSecProtocolTypeHTTP,
285 NULL,
286 0,
287 NULL,
288 "20000101000000Z",
289 "",
290 "",
291 true},
292 // De-facto negative item, type one.
293 {kSecAuthenticationTypeHTMLForm,
294 "dont.remember.com",
295 kSecProtocolTypeHTTP,
296 NULL,
297 0,
298 NULL,
299 "20000101000000Z",
300 "Password Not Stored",
301 "",
302 false},
303 // De-facto negative item, type two.
304 {kSecAuthenticationTypeHTMLForm,
305 "dont.remember.com",
306 kSecProtocolTypeHTTPS,
307 NULL,
308 0,
309 NULL,
310 "20000101000000Z",
311 "Password Not Stored",
312 " ",
313 false},
314 // HTTP auth basic, with port and path.
315 {kSecAuthenticationTypeHTTPBasic,
316 "some.domain.com",
317 kSecProtocolTypeHTTP,
318 "/insecure.html",
319 4567,
320 "low_security",
321 "19980330100000Z",
322 "basic_auth_user",
323 "basic",
324 false},
325 // HTTP auth digest, secure.
326 {kSecAuthenticationTypeHTTPDigest,
327 "some.domain.com",
328 kSecProtocolTypeHTTPS,
329 NULL,
330 0,
331 "high_security",
332 "19980330100000Z",
333 "digest_auth_user",
334 "digest",
335 false},
336 // An FTP password with an invalid date, for edge-case testing.
337 {kSecAuthenticationTypeDefault,
338 "a.server.com",
339 kSecProtocolTypeFTP,
340 NULL,
341 0,
342 NULL,
343 "20010203040",
344 "abc",
345 "123",
346 false},
347 };
348
349 keychain_ = new MockAppleKeychain();
350
351 for (unsigned int i = 0; i < arraysize(test_data); ++i) {
352 keychain_->AddTestItem(test_data[i]);
353 }
354 }
355
356 void TearDown() override {
357 ExpectCreatesAndFreesBalanced();
358 ExpectCreatorCodesSet();
359 delete keychain_;
360 }
361
362 protected:
363 // Causes a test failure unless everything returned from keychain_'s
364 // ItemCopyAttributesAndData, SearchCreateFromAttributes, and SearchCopyNext
365 // was correctly freed.
366 void ExpectCreatesAndFreesBalanced() {
367 EXPECT_EQ(0, keychain_->UnfreedSearchCount());
368 EXPECT_EQ(0, keychain_->UnfreedKeychainItemCount());
369 EXPECT_EQ(0, keychain_->UnfreedAttributeDataCount());
370 }
371
372 // Causes a test failure unless any Keychain items added during the test have
373 // their creator code set.
374 void ExpectCreatorCodesSet() {
375 EXPECT_TRUE(keychain_->CreatorCodesSetForAddedItems());
376 }
377
378 MockAppleKeychain* keychain_;
379 };
380
328 #pragma mark - 381 #pragma mark -
329 382
330 TEST_F(PasswordStoreMacInternalsTest, TestKeychainToFormTranslation) { 383 TEST_F(PasswordStoreMacInternalsTest, TestKeychainToFormTranslation) {
331 typedef struct { 384 typedef struct {
332 const PasswordForm::Scheme scheme; 385 const PasswordForm::Scheme scheme;
333 const char* signon_realm; 386 const char* signon_realm;
334 const char* origin; 387 const char* origin;
335 const wchar_t* username; // Set to NULL to check for a blacklist entry. 388 const wchar_t* username; // Set to NULL to check for a blacklist entry.
336 const wchar_t* password; 389 const wchar_t* password;
337 const bool ssl_valid; 390 const bool ssl_valid;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 0, 0 }, 523 0, 0 },
471 // Garbage forms should have no matches. 524 // Garbage forms should have no matches.
472 { { PasswordForm::SCHEME_HTML, "foo/bar/baz", 525 { { PasswordForm::SCHEME_HTML, "foo/bar/baz",
473 NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 }, 526 NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 },
474 }; 527 };
475 528
476 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 529 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
477 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 530 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
478 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 531 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
479 for (unsigned int i = 0; i < arraysize(test_data); ++i) { 532 for (unsigned int i = 0; i < arraysize(test_data); ++i) {
480 scoped_ptr<PasswordForm> query_form( 533 scoped_ptr<PasswordForm> query_form =
481 CreatePasswordFormFromData(test_data[i].data)); 534 CreatePasswordFormFromData(test_data[i].data);
482 535
483 // Check matches treating the form as a fill target. 536 // Check matches treating the form as a fill target.
484 ScopedVector<autofill::PasswordForm> matching_items = 537 ScopedVector<autofill::PasswordForm> matching_items =
485 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, 538 keychain_adapter.PasswordsFillingForm(query_form->signon_realm,
486 query_form->scheme); 539 query_form->scheme);
487 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); 540 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size());
488 matching_items.clear(); 541 matching_items.clear();
489 542
490 // Check matches treating the form as a merging target. 543 // Check matches treating the form as a merging target.
491 EXPECT_EQ(test_data[i].expected_merge_matches > 0, 544 EXPECT_EQ(test_data[i].expected_merge_matches > 0,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", 603 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security",
551 "http://some.domain.com:4567/insecure.html", 604 "http://some.domain.com:4567/insecure.html",
552 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, 605 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 },
553 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", 606 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security",
554 "https://some.domain.com", 607 "https://some.domain.com",
555 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, 608 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 },
556 }; 609 };
557 610
558 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { 611 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) {
559 // Create a base form and make sure we find a match. 612 // Create a base form and make sure we find a match.
560 scoped_ptr<PasswordForm> base_form(CreatePasswordFormFromData( 613 scoped_ptr<PasswordForm> base_form =
561 base_form_data[i])); 614 CreatePasswordFormFromData(base_form_data[i]);
562 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form)); 615 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form));
563 EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form)); 616 EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form));
564 617
565 // Make sure that the matching isn't looser than it should be by checking 618 // Make sure that the matching isn't looser than it should be by checking
566 // that slightly altered forms don't match. 619 // that slightly altered forms don't match.
567 ScopedVector<autofill::PasswordForm> modified_forms; 620 ScopedVector<autofill::PasswordForm> modified_forms;
568 621
569 modified_forms.push_back(new PasswordForm(*base_form)); 622 modified_forms.push_back(new PasswordForm(*base_form));
570 modified_forms.back()->username_value = ASCIIToUTF16("wrong_user"); 623 modified_forms.back()->username_value = ASCIIToUTF16("wrong_user");
571 624
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 // reported. 677 // reported.
625 { { PasswordForm::SCHEME_HTML, "http://some.domain.com", 678 { { PasswordForm::SCHEME_HTML, "http://some.domain.com",
626 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, 679 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL,
627 L"joe_user", L"fail_me", false, false, 0 }, false }, 680 L"joe_user", L"fail_me", false, false, 0 }, false },
628 }; 681 };
629 682
630 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 683 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
631 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 684 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
632 685
633 for (unsigned int i = 0; i < arraysize(test_data); ++i) { 686 for (unsigned int i = 0; i < arraysize(test_data); ++i) {
634 scoped_ptr<PasswordForm> in_form( 687 scoped_ptr<PasswordForm> in_form =
635 CreatePasswordFormFromData(test_data[i].data)); 688 CreatePasswordFormFromData(test_data[i].data);
636 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); 689 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form);
637 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); 690 EXPECT_EQ(test_data[i].should_succeed, add_succeeded);
638 if (add_succeeded) { 691 if (add_succeeded) {
639 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( 692 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm(
640 *in_form)); 693 *in_form));
641 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm( 694 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm(
642 *in_form)); 695 *in_form));
643 } 696 }
644 } 697 }
645 698
646 // Test that adding duplicate item updates the existing item. 699 // Test that adding duplicate item updates the existing item.
647 { 700 {
648 PasswordFormData data = { 701 PasswordFormData data = {
649 PasswordForm::SCHEME_HTML, "http://some.domain.com", 702 PasswordForm::SCHEME_HTML, "http://some.domain.com",
650 "http://some.domain.com/insecure.html", NULL, 703 "http://some.domain.com/insecure.html", NULL,
651 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 704 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0
652 }; 705 };
653 scoped_ptr<PasswordForm> update_form(CreatePasswordFormFromData(data)); 706 scoped_ptr<PasswordForm> update_form = CreatePasswordFormFromData(data);
654 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 707 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
655 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); 708 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form));
656 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); 709 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2);
657 PasswordForm stored_form; 710 PasswordForm stored_form;
658 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, 711 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_,
659 keychain_item, 712 keychain_item,
660 &stored_form, 713 &stored_form,
661 true); 714 true);
662 EXPECT_EQ(update_form->password_value, stored_form.password_value); 715 EXPECT_EQ(update_form->password_value, stored_form.password_value);
663 } 716 }
(...skipping 12 matching lines...) Expand all
676 // Make sure we don't delete items we don't own. 729 // Make sure we don't delete items we don't own.
677 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 730 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
678 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, 731 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL,
679 L"joe_user", NULL, true, false, 0 }, false }, 732 L"joe_user", NULL, true, false, 0 }, false },
680 }; 733 };
681 734
682 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 735 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
683 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 736 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
684 737
685 // Add our test item so that we can delete it. 738 // Add our test item so that we can delete it.
686 PasswordForm* add_form = CreatePasswordFormFromData(test_data[0].data); 739 scoped_ptr<PasswordForm> add_form =
740 CreatePasswordFormFromData(test_data[0].data);
687 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); 741 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form));
688 delete add_form;
689 742
690 for (unsigned int i = 0; i < arraysize(test_data); ++i) { 743 for (unsigned int i = 0; i < arraysize(test_data); ++i) {
691 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( 744 scoped_ptr<PasswordForm> form =
692 test_data[i].data)); 745 CreatePasswordFormFromData(test_data[i].data);
693 EXPECT_EQ(test_data[i].should_succeed, 746 EXPECT_EQ(test_data[i].should_succeed,
694 owned_keychain_adapter.RemovePassword(*form)); 747 owned_keychain_adapter.RemovePassword(*form));
695 748
696 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 749 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
697 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form); 750 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form);
698 EXPECT_EQ(test_data[i].should_succeed, !match); 751 EXPECT_EQ(test_data[i].should_succeed, !match);
699 } 752 }
700 } 753 }
701 754
702 TEST_F(PasswordStoreMacInternalsTest, TestFormMatch) { 755 TEST_F(PasswordStoreMacInternalsTest, TestFormMatch) {
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path); 936 test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path);
884 test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1); 937 test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1);
885 test_data[MERGE_OUTPUT][current_test].push_back( 938 test_data[MERGE_OUTPUT][current_test].push_back(
886 &merged_user_1_with_both_paths); 939 &merged_user_1_with_both_paths);
887 940
888 for (unsigned int test_case = 0; test_case <= current_test; ++test_case) { 941 for (unsigned int test_case = 0; test_case <= current_test; ++test_case) {
889 ScopedVector<autofill::PasswordForm> keychain_forms; 942 ScopedVector<autofill::PasswordForm> keychain_forms;
890 for (std::vector<PasswordFormData*>::iterator i = 943 for (std::vector<PasswordFormData*>::iterator i =
891 test_data[KEYCHAIN_INPUT][test_case].begin(); 944 test_data[KEYCHAIN_INPUT][test_case].begin();
892 i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) { 945 i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) {
893 keychain_forms.push_back(CreatePasswordFormFromData(*(*i))); 946 keychain_forms.push_back(CreatePasswordFormFromData(*(*i)).release());
894 } 947 }
895 ScopedVector<autofill::PasswordForm> database_forms; 948 ScopedVector<autofill::PasswordForm> database_forms;
896 for (std::vector<PasswordFormData*>::iterator i = 949 for (std::vector<PasswordFormData*>::iterator i =
897 test_data[DATABASE_INPUT][test_case].begin(); 950 test_data[DATABASE_INPUT][test_case].begin();
898 i != test_data[DATABASE_INPUT][test_case].end(); ++i) { 951 i != test_data[DATABASE_INPUT][test_case].end(); ++i) {
899 database_forms.push_back(CreatePasswordFormFromData(*(*i))); 952 database_forms.push_back(CreatePasswordFormFromData(*(*i)).release());
900 } 953 }
901 954
902 ScopedVector<autofill::PasswordForm> merged_forms; 955 ScopedVector<autofill::PasswordForm> merged_forms;
903 internal_keychain_helpers::MergePasswordForms(&keychain_forms, 956 internal_keychain_helpers::MergePasswordForms(&keychain_forms,
904 &database_forms, 957 &database_forms,
905 &merged_forms); 958 &merged_forms);
906 959
907 CHECK_FORMS(keychain_forms.get(), test_data[KEYCHAIN_OUTPUT][test_case], 960 CHECK_FORMS(keychain_forms.get(), test_data[KEYCHAIN_OUTPUT][test_case],
908 test_case); 961 test_case);
909 CHECK_FORMS(database_forms.get(), test_data[DATABASE_OUTPUT][test_case], 962 CHECK_FORMS(database_forms.get(), test_data[DATABASE_OUTPUT][test_case],
(...skipping 24 matching lines...) Expand all
934 "http://dont.remember.com/handlepage.cgi", 987 "http://dont.remember.com/handlepage.cgi",
935 L"submit", L"username", L"password", L"joe_user", L"", 988 L"submit", L"username", L"password", L"joe_user", L"",
936 true, false, 1240000000 }, 989 true, false, 1240000000 },
937 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 990 { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
938 "http://some.domain.com/path.html", "http://some.domain.com/action.cgi", 991 "http://some.domain.com/path.html", "http://some.domain.com/action.cgi",
939 L"submit", L"username", L"password", NULL, NULL, 992 L"submit", L"username", L"password", NULL, NULL,
940 true, false, 1212121212 }, 993 true, false, 1212121212 },
941 }; 994 };
942 ScopedVector<autofill::PasswordForm> database_forms; 995 ScopedVector<autofill::PasswordForm> database_forms;
943 for (unsigned int i = 0; i < arraysize(db_data); ++i) { 996 for (unsigned int i = 0; i < arraysize(db_data); ++i) {
944 database_forms.push_back(CreatePasswordFormFromData(db_data[i])); 997 database_forms.push_back(CreatePasswordFormFromData(db_data[i]).release());
945 } 998 }
946 ScopedVector<autofill::PasswordForm> merged_forms; 999 ScopedVector<autofill::PasswordForm> merged_forms;
947 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, 1000 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
948 &merged_forms); 1001 &merged_forms);
949 EXPECT_EQ(2U, database_forms.size()); 1002 EXPECT_EQ(2U, database_forms.size());
950 ASSERT_EQ(3U, merged_forms.size()); 1003 ASSERT_EQ(3U, merged_forms.size());
951 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value); 1004 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value);
952 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value); 1005 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value);
953 EXPECT_TRUE(merged_forms[2]->blacklisted_by_user); 1006 EXPECT_TRUE(merged_forms[2]->blacklisted_by_user);
954 } 1007 }
955 1008
956 TEST_F(PasswordStoreMacInternalsTest, TestBlacklistedFiltering) { 1009 TEST_F(PasswordStoreMacInternalsTest, TestBlacklistedFiltering) {
957 PasswordFormData db_data[] = { 1010 PasswordFormData db_data[] = {
958 { PasswordForm::SCHEME_HTML, "http://dont.remember.com/", 1011 { PasswordForm::SCHEME_HTML, "http://dont.remember.com/",
959 "http://dont.remember.com/", 1012 "http://dont.remember.com/",
960 "http://dont.remember.com/handlepage.cgi", 1013 "http://dont.remember.com/handlepage.cgi",
961 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", 1014 L"submit", L"username", L"password", L"joe_user", L"non_empty_password",
962 true, false, 1240000000 }, 1015 true, false, 1240000000 },
963 { PasswordForm::SCHEME_HTML, "https://dont.remember.com/", 1016 { PasswordForm::SCHEME_HTML, "https://dont.remember.com/",
964 "https://dont.remember.com/", 1017 "https://dont.remember.com/",
965 "https://dont.remember.com/handlepage_secure.cgi", 1018 "https://dont.remember.com/handlepage_secure.cgi",
966 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", 1019 L"submit", L"username", L"password", L"joe_user", L"non_empty_password",
967 true, false, 1240000000 }, 1020 true, false, 1240000000 },
968 }; 1021 };
969 ScopedVector<autofill::PasswordForm> database_forms; 1022 ScopedVector<autofill::PasswordForm> database_forms;
970 for (unsigned int i = 0; i < arraysize(db_data); ++i) { 1023 for (unsigned int i = 0; i < arraysize(db_data); ++i) {
971 database_forms.push_back(CreatePasswordFormFromData(db_data[i])); 1024 database_forms.push_back(CreatePasswordFormFromData(db_data[i]).release());
972 } 1025 }
973 ScopedVector<autofill::PasswordForm> merged_forms; 1026 ScopedVector<autofill::PasswordForm> merged_forms;
974 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, 1027 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
975 &merged_forms); 1028 &merged_forms);
976 EXPECT_EQ(2U, database_forms.size()); 1029 EXPECT_EQ(2U, database_forms.size());
977 ASSERT_EQ(0U, merged_forms.size()); 1030 ASSERT_EQ(0U, merged_forms.size());
978 } 1031 }
979 1032
980 TEST_F(PasswordStoreMacInternalsTest, TestFillPasswordFormFromKeychainItem) { 1033 TEST_F(PasswordStoreMacInternalsTest, TestFillPasswordFormFromKeychainItem) {
981 // When |extract_password_data| is false, the password field must be empty, 1034 // When |extract_password_data| is false, the password field must be empty,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 1115 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
1063 L"anonymous", L"knock-knock", false, false, 0 }, 1116 L"anonymous", L"knock-knock", false, false, 0 },
1064 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", 1117 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm",
1065 "http://a.site.com:2222/", NULL, NULL, NULL, NULL, 1118 "http://a.site.com:2222/", NULL, NULL, NULL, NULL,
1066 L"username", L"password", false, false, 0 }, 1119 L"username", L"password", false, false, 0 },
1067 { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", 1120 { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm",
1068 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, 1121 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL,
1069 L"testname", L"testpass", false, false, 0 }, 1122 L"testname", L"testpass", false, false, 0 },
1070 }; 1123 };
1071 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { 1124 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) {
1072 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( 1125 scoped_ptr<PasswordForm> form =
1073 owned_password_data[i])); 1126 CreatePasswordFormFromData(owned_password_data[i]);
1074 owned_keychain_adapter.AddPassword(*form); 1127 owned_keychain_adapter.AddPassword(*form);
1075 } 1128 }
1076 1129
1077 ScopedVector<autofill::PasswordForm> all_passwords = 1130 ScopedVector<autofill::PasswordForm> all_passwords =
1078 keychain_adapter.GetAllPasswordFormPasswords(); 1131 keychain_adapter.GetAllPasswordFormPasswords();
1079 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size()); 1132 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size());
1080 1133
1081 ScopedVector<autofill::PasswordForm> owned_passwords = 1134 ScopedVector<autofill::PasswordForm> owned_passwords =
1082 owned_keychain_adapter.GetAllPasswordFormPasswords(); 1135 owned_keychain_adapter.GetAllPasswordFormPasswords();
1083 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); 1136 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 1183
1131 MockAppleKeychain* keychain() { 1184 MockAppleKeychain* keychain() {
1132 return static_cast<MockAppleKeychain*>(store_->keychain()); 1185 return static_cast<MockAppleKeychain*>(store_->keychain());
1133 } 1186 }
1134 1187
1135 void FinishAsyncProcessing() { 1188 void FinishAsyncProcessing() {
1136 // Do a store-level query to wait for all the previously enqueued operations 1189 // Do a store-level query to wait for all the previously enqueued operations
1137 // to finish. 1190 // to finish.
1138 MockPasswordStoreConsumer consumer; 1191 MockPasswordStoreConsumer consumer;
1139 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer); 1192 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer);
1140 consumer.WaitOnGetPasswordStoreResults(); 1193 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(_))
1194 .WillOnce(QuitUIMessageLoop());
1195 base::MessageLoop::current()->Run();
1141 } 1196 }
1142 1197
1143 TestPasswordStoreMac* store() { return store_.get(); } 1198 TestPasswordStoreMac* store() { return store_.get(); }
1144 1199
1145 protected: 1200 protected:
1146 base::MessageLoopForUI message_loop_; 1201 base::MessageLoopForUI message_loop_;
1147 content::TestBrowserThread ui_thread_; 1202 content::TestBrowserThread ui_thread_;
1148 1203
1149 base::ScopedTempDir db_dir_; 1204 base::ScopedTempDir db_dir_;
1150 scoped_refptr<TestPasswordStoreMac> store_; 1205 scoped_refptr<TestPasswordStoreMac> store_;
1151 }; 1206 };
1152 1207
1153 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { 1208 TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
1154 // Insert a password into both the database and the keychain. 1209 // Insert a password into both the database and the keychain.
1155 // This is done manually, rather than through store_->AddLogin, because the 1210 // This is done manually, rather than through store_->AddLogin, because the
1156 // Mock Keychain isn't smart enough to be able to support update generically, 1211 // Mock Keychain isn't smart enough to be able to support update generically,
1157 // so some.domain.com triggers special handling to test it that make inserting 1212 // so some.domain.com triggers special handling to test it that make inserting
1158 // fail. 1213 // fail.
1159 PasswordFormData joint_data = { 1214 PasswordFormData joint_data = {
1160 PasswordForm::SCHEME_HTML, "http://some.domain.com/", 1215 PasswordForm::SCHEME_HTML, "http://some.domain.com/",
1161 "http://some.domain.com/insecure.html", "login.cgi", 1216 "http://some.domain.com/insecure.html", "login.cgi",
1162 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 1217 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1
1163 }; 1218 };
1164 scoped_ptr<PasswordForm> joint_form(CreatePasswordFormFromData(joint_data)); 1219 scoped_ptr<PasswordForm> joint_form = CreatePasswordFormFromData(joint_data);
1165 login_db()->AddLogin(*joint_form); 1220 login_db()->AddLogin(*joint_form);
1166 MockAppleKeychain::KeychainTestData joint_keychain_data = { 1221 MockAppleKeychain::KeychainTestData joint_keychain_data = {
1167 kSecAuthenticationTypeHTMLForm, "some.domain.com", 1222 kSecAuthenticationTypeHTMLForm, "some.domain.com",
1168 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", 1223 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z",
1169 "joe_user", "sekrit", false }; 1224 "joe_user", "sekrit", false };
1170 keychain()->AddTestItem(joint_keychain_data); 1225 keychain()->AddTestItem(joint_keychain_data);
1171 1226
1172 // Insert a password into the keychain only. 1227 // Insert a password into the keychain only.
1173 MockAppleKeychain::KeychainTestData keychain_only_data = { 1228 MockAppleKeychain::KeychainTestData keychain_only_data = {
1174 kSecAuthenticationTypeHTMLForm, "keychain.only.com", 1229 kSecAuthenticationTypeHTMLForm, "keychain.only.com",
(...skipping 28 matching lines...) Expand all
1203 // case where a form is filled, then the stored login is removed, then the 1258 // case where a form is filled, then the stored login is removed, then the
1204 // form is submitted. 1259 // form is submitted.
1205 { { PasswordForm::SCHEME_HTML, "http://different.com/", 1260 { { PasswordForm::SCHEME_HTML, "http://different.com/",
1206 "http://different.com/index.html", "login.cgi", 1261 "http://different.com/index.html", "login.cgi",
1207 L"username", L"password", L"submit", L"abc", L"123", 1262 L"username", L"password", L"submit", L"abc", L"123",
1208 true, false, 2 }, 1263 true, false, 2 },
1209 NULL, 1264 NULL,
1210 }, 1265 },
1211 }; 1266 };
1212 for (unsigned int i = 0; i < arraysize(updates); ++i) { 1267 for (unsigned int i = 0; i < arraysize(updates); ++i) {
1213 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( 1268 scoped_ptr<PasswordForm> form =
1214 updates[i].form_data)); 1269 CreatePasswordFormFromData(updates[i].form_data);
1215 store_->UpdateLogin(*form); 1270 store_->UpdateLogin(*form);
1216 } 1271 }
1217 1272
1218 FinishAsyncProcessing(); 1273 FinishAsyncProcessing();
1219 1274
1220 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); 1275 MacKeychainPasswordFormAdapter keychain_adapter(keychain());
1221 for (unsigned int i = 0; i < arraysize(updates); ++i) { 1276 for (unsigned int i = 0; i < arraysize(updates); ++i) {
1222 scoped_ptr<PasswordForm> query_form( 1277 scoped_ptr<PasswordForm> query_form =
1223 CreatePasswordFormFromData(updates[i].form_data)); 1278 CreatePasswordFormFromData(updates[i].form_data);
1224 1279
1225 ScopedVector<autofill::PasswordForm> matching_items = 1280 ScopedVector<autofill::PasswordForm> matching_items =
1226 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, 1281 keychain_adapter.PasswordsFillingForm(query_form->signon_realm,
1227 query_form->scheme); 1282 query_form->scheme);
1228 if (updates[i].password) { 1283 if (updates[i].password) {
1229 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; 1284 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i;
1230 if (matching_items.size() >= 1) 1285 if (matching_items.size() >= 1)
1231 EXPECT_EQ(ASCIIToUTF16(updates[i].password), 1286 EXPECT_EQ(ASCIIToUTF16(updates[i].password),
1232 matching_items[0]->password_value) << "iteration " << i; 1287 matching_items[0]->password_value) << "iteration " << i;
1233 } else { 1288 } else {
(...skipping 22 matching lines...) Expand all
1256 // www.facebook.com password from the login database, we should not be blocked 1311 // www.facebook.com password from the login database, we should not be blocked
1257 // from deleting it from the keystore just becaus the m.facebook.com password 1312 // from deleting it from the keystore just becaus the m.facebook.com password
1258 // fuzzy-matches the www.facebook.com one.) 1313 // fuzzy-matches the www.facebook.com one.)
1259 1314
1260 // 1. Add a password for www.facebook.com 1315 // 1. Add a password for www.facebook.com
1261 PasswordFormData www_form_data = { 1316 PasswordFormData www_form_data = {
1262 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1317 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1263 "http://www.facebook.com/index.html", "login", 1318 "http://www.facebook.com/index.html", "login",
1264 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 1319 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1
1265 }; 1320 };
1266 scoped_ptr<PasswordForm> www_form(CreatePasswordFormFromData(www_form_data)); 1321 scoped_ptr<PasswordForm> www_form = CreatePasswordFormFromData(www_form_data);
1267 login_db()->AddLogin(*www_form); 1322 login_db()->AddLogin(*www_form);
1268 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); 1323 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain());
1269 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 1324 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
1270 owned_keychain_adapter.AddPassword(*www_form); 1325 owned_keychain_adapter.AddPassword(*www_form);
1271 1326
1272 // 2. Get a password for m.facebook.com. 1327 // 2. Get a password for m.facebook.com.
1273 PasswordForm m_form(*www_form); 1328 PasswordForm m_form(*www_form);
1274 m_form.signon_realm = "http://m.facebook.com"; 1329 m_form.signon_realm = "http://m.facebook.com";
1275 m_form.origin = GURL("http://m.facebook.com/index.html"); 1330 m_form.origin = GURL("http://m.facebook.com/index.html");
1276 1331
1277 MockPasswordStoreConsumer consumer; 1332 MockPasswordStoreConsumer consumer;
1278 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); 1333 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer);
1279 consumer.WaitOnGetPasswordStoreResults(); 1334 PasswordForm returned_form;
1280 EXPECT_EQ(1u, consumer.last_result.size()); 1335 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
1336 .WillOnce(
1337 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
1338 base::MessageLoop::current()->Run();
1281 1339
1282 // 3. Add the returned password for m.facebook.com. 1340 // 3. Add the returned password for m.facebook.com.
1283 login_db()->AddLogin(consumer.last_result[0]); 1341 login_db()->AddLogin(returned_form);
1284 owned_keychain_adapter.AddPassword(m_form); 1342 owned_keychain_adapter.AddPassword(m_form);
1285 1343
1286 // 4. Remove both passwords. 1344 // 4. Remove both passwords.
1287 store_->RemoveLogin(*www_form); 1345 store_->RemoveLogin(*www_form);
1288 store_->RemoveLogin(m_form); 1346 store_->RemoveLogin(m_form);
1289 FinishAsyncProcessing(); 1347 FinishAsyncProcessing();
1290 1348
1291 // No trace of www.facebook.com. 1349 // No trace of www.facebook.com.
1292 ScopedVector<autofill::PasswordForm> matching_items = 1350 ScopedVector<autofill::PasswordForm> matching_items =
1293 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, 1351 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 L"password", L"joe_user", L"sekrit", true, false, 0 }; 1400 L"password", L"joe_user", L"sekrit", true, false, 0 };
1343 // The old form doesn't have elements names. 1401 // The old form doesn't have elements names.
1344 PasswordFormData www_form_data_facebook_old = { 1402 PasswordFormData www_form_data_facebook_old = {
1345 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1403 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1346 "http://www.facebook.com/index.html", "login", L"", L"", 1404 "http://www.facebook.com/index.html", "login", L"", L"",
1347 L"", L"joe_user", L"oldsekrit", true, false, 0 }; 1405 L"", L"joe_user", L"oldsekrit", true, false, 0 };
1348 PasswordFormData www_form_data_other = { 1406 PasswordFormData www_form_data_other = {
1349 PasswordForm::SCHEME_HTML, "http://different.com/", 1407 PasswordForm::SCHEME_HTML, "http://different.com/",
1350 "http://different.com/index.html", "login", L"submit", L"username", 1408 "http://different.com/index.html", "login", L"submit", L"username",
1351 L"password", L"different_joe_user", L"sekrit", true, false, 0 }; 1409 L"password", L"different_joe_user", L"sekrit", true, false, 0 };
1352 scoped_ptr<PasswordForm> form_facebook( 1410 scoped_ptr<PasswordForm> form_facebook =
1353 CreatePasswordFormFromData(www_form_data_facebook)); 1411 CreatePasswordFormFromData(www_form_data_facebook);
1354 scoped_ptr<PasswordForm> form_facebook_old( 1412 scoped_ptr<PasswordForm> form_facebook_old =
1355 CreatePasswordFormFromData(www_form_data_facebook_old)); 1413 CreatePasswordFormFromData(www_form_data_facebook_old);
1356 scoped_ptr<PasswordForm> form_other( 1414 scoped_ptr<PasswordForm> form_other =
1357 CreatePasswordFormFromData(www_form_data_other)); 1415 CreatePasswordFormFromData(www_form_data_other);
1358 base::Time now = base::Time::Now(); 1416 base::Time now = base::Time::Now();
1359 // TODO(vasilii): remove the next line once crbug/374132 is fixed. 1417 // TODO(vasilii): remove the next line once crbug/374132 is fixed.
1360 now = base::Time::FromTimeT(now.ToTimeT()); 1418 now = base::Time::FromTimeT(now.ToTimeT());
1361 base::Time next_day = now + base::TimeDelta::FromDays(1); 1419 base::Time next_day = now + base::TimeDelta::FromDays(1);
1362 if (check_created) { 1420 if (check_created) {
1363 form_facebook_old->date_created = now; 1421 form_facebook_old->date_created = now;
1364 form_facebook->date_created = next_day; 1422 form_facebook->date_created = next_day;
1365 form_other->date_created = next_day; 1423 form_other->date_created = next_day;
1366 } else { 1424 } else {
1367 form_facebook_old->date_synced = now; 1425 form_facebook_old->date_synced = now;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 keychain()->AddTestItem(keychain_data); 1504 keychain()->AddTestItem(keychain_data);
1447 1505
1448 // Add a password through the adapter. It has the "Chrome" creator tag. 1506 // Add a password through the adapter. It has the "Chrome" creator tag.
1449 // However, it's not referenced by the password database. 1507 // However, it's not referenced by the password database.
1450 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); 1508 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain());
1451 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 1509 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
1452 PasswordFormData www_form_data1 = { 1510 PasswordFormData www_form_data1 = {
1453 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1511 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1454 "http://www.facebook.com/index.html", "login", L"username", L"password", 1512 "http://www.facebook.com/index.html", "login", L"username", L"password",
1455 L"submit", L"joe_user", L"sekrit", true, false, 1 }; 1513 L"submit", L"joe_user", L"sekrit", true, false, 1 };
1456 scoped_ptr<PasswordForm> www_form(CreatePasswordFormFromData(www_form_data1)); 1514 scoped_ptr<PasswordForm> www_form =
1515 CreatePasswordFormFromData(www_form_data1);
1457 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); 1516 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form));
1458 1517
1459 // Add a password from the current profile. 1518 // Add a password from the current profile.
1460 PasswordFormData www_form_data2 = { 1519 PasswordFormData www_form_data2 = {
1461 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1520 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1462 "http://www.facebook.com/index.html", "login", L"username", L"password", 1521 "http://www.facebook.com/index.html", "login", L"username", L"password",
1463 L"submit", L"not_joe_user", L"12345", true, false, 1 }; 1522 L"submit", L"not_joe_user", L"12345", true, false, 1 };
1464 www_form.reset(CreatePasswordFormFromData(www_form_data2)); 1523 www_form = CreatePasswordFormFromData(www_form_data2);
1465 store_->AddLogin(*www_form); 1524 store_->AddLogin(*www_form);
1466 FinishAsyncProcessing(); 1525 FinishAsyncProcessing();
1467 1526
1468 ScopedVector<PasswordForm> matching_items; 1527 ScopedVector<PasswordForm> matching_items;
1469 login_db()->GetLogins(*www_form, &matching_items); 1528 login_db()->GetLogins(*www_form, &matching_items);
1470 EXPECT_EQ(1u, matching_items.size()); 1529 EXPECT_EQ(1u, matching_items.size());
1471 matching_items.clear(); 1530 matching_items.clear();
1472 1531
1473 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time()); 1532 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time());
1474 FinishAsyncProcessing(); 1533 FinishAsyncProcessing();
(...skipping 24 matching lines...) Expand all
1499 ClosePasswordStore(); 1558 ClosePasswordStore();
1500 1559
1501 base::WaitableEvent event(false, false); 1560 base::WaitableEvent event(false, false);
1502 CreateAndInitPasswordStore(make_scoped_ptr<password_manager::LoginDatabase>( 1561 CreateAndInitPasswordStore(make_scoped_ptr<password_manager::LoginDatabase>(
1503 new SlowToInitLoginDatabase(test_login_db_file_path(), &event))); 1562 new SlowToInitLoginDatabase(test_login_db_file_path(), &event)));
1504 1563
1505 PasswordFormData www_form_data = { 1564 PasswordFormData www_form_data = {
1506 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1565 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1507 "http://www.facebook.com/index.html", "login", L"username", L"password", 1566 "http://www.facebook.com/index.html", "login", L"username", L"password",
1508 L"submit", L"not_joe_user", L"12345", true, false, 1}; 1567 L"submit", L"not_joe_user", L"12345", true, false, 1};
1509 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(www_form_data)); 1568 scoped_ptr<PasswordForm> form = CreatePasswordFormFromData(www_form_data);
1510 store()->AddLogin(*form); 1569 store()->AddLogin(*form);
1511 1570
1512 MockPasswordStoreConsumer mock_consumer; 1571 MockPasswordStoreConsumer mock_consumer;
1513 store()->GetLogins(*form, PasswordStore::ALLOW_PROMPT, &mock_consumer); 1572 store()->GetLogins(*form, PasswordStore::ALLOW_PROMPT, &mock_consumer);
1514 1573
1515 // Now the read/write tasks are scheduled, let the DB initialization proceed. 1574 // Now the read/write tasks are scheduled, let the DB initialization proceed.
1516 event.Signal(); 1575 event.Signal();
1517 1576
1518 mock_consumer.WaitOnGetPasswordStoreResults(); 1577 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
1519 EXPECT_EQ(1u, mock_consumer.last_result.size()); 1578 .WillOnce(QuitUIMessageLoop());
1579 base::MessageLoop::current()->Run();
1520 EXPECT_TRUE(login_db()); 1580 EXPECT_TRUE(login_db());
1521 } 1581 }
1522 1582
1523 // Verify that operations on a PasswordStore with a bad database cause no 1583 // Verify that operations on a PasswordStore with a bad database cause no
1524 // explosions, but fail without side effect, return no data and trigger no 1584 // explosions, but fail without side effect, return no data and trigger no
1525 // notifications. 1585 // notifications.
1526 TEST_F(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) { 1586 TEST_F(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) {
1527 ClosePasswordStore(); 1587 ClosePasswordStore();
1528 CreateAndInitPasswordStore( 1588 CreateAndInitPasswordStore(
1529 make_scoped_ptr<password_manager::LoginDatabase>(new BadLoginDatabase)); 1589 make_scoped_ptr<password_manager::LoginDatabase>(new BadLoginDatabase));
1530 FinishAsyncProcessing(); 1590 FinishAsyncProcessing();
1531 EXPECT_FALSE(login_db()); 1591 EXPECT_FALSE(login_db());
1532 1592
1533 testing::StrictMock<MockPasswordStoreObserver> mock_observer; 1593 testing::StrictMock<MockPasswordStoreObserver> mock_observer;
1534 store()->AddObserver(&mock_observer); 1594 store()->AddObserver(&mock_observer);
1535 1595
1536 // Add a new autofillable login + a blacklisted login. 1596 // Add a new autofillable login + a blacklisted login.
1537 PasswordFormData www_form_data = { 1597 PasswordFormData www_form_data = {
1538 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1598 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1539 "http://www.facebook.com/index.html", "login", L"username", L"password", 1599 "http://www.facebook.com/index.html", "login", L"username", L"password",
1540 L"submit", L"not_joe_user", L"12345", true, false, 1}; 1600 L"submit", L"not_joe_user", L"12345", true, false, 1};
1541 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(www_form_data)); 1601 scoped_ptr<PasswordForm> form = CreatePasswordFormFromData(www_form_data);
1542 scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form)); 1602 scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form));
1543 blacklisted_form->signon_realm = "http://foo.example.com"; 1603 blacklisted_form->signon_realm = "http://foo.example.com";
1544 blacklisted_form->origin = GURL("http://foo.example.com/origin"); 1604 blacklisted_form->origin = GURL("http://foo.example.com/origin");
1545 blacklisted_form->action = GURL("http://foo.example.com/action"); 1605 blacklisted_form->action = GURL("http://foo.example.com/action");
1546 blacklisted_form->blacklisted_by_user = true; 1606 blacklisted_form->blacklisted_by_user = true;
1547 store()->AddLogin(*form); 1607 store()->AddLogin(*form);
1548 store()->AddLogin(*blacklisted_form); 1608 store()->AddLogin(*blacklisted_form);
1549 FinishAsyncProcessing(); 1609 FinishAsyncProcessing();
1550 1610
1551 // Get all logins; autofillable logins; blacklisted logins. 1611 // Get all logins; autofillable logins; blacklisted logins.
1552 MockPasswordStoreConsumer mock_consumer; 1612 MockPasswordStoreConsumer mock_consumer;
1553 store()->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &mock_consumer); 1613 store()->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &mock_consumer);
1554 mock_consumer.WaitOnGetPasswordStoreResults(); 1614 ON_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(_))
1555 EXPECT_TRUE(mock_consumer.last_result.empty()); 1615 .WillByDefault(QuitUIMessageLoop());
1616 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
1617 base::MessageLoop::current()->Run();
1618
1556 store()->GetAutofillableLogins(&mock_consumer); 1619 store()->GetAutofillableLogins(&mock_consumer);
1557 mock_consumer.WaitOnGetPasswordStoreResults(); 1620 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
1558 EXPECT_TRUE(mock_consumer.last_result.empty()); 1621 base::MessageLoop::current()->Run();
1622
1559 store()->GetBlacklistLogins(&mock_consumer); 1623 store()->GetBlacklistLogins(&mock_consumer);
1560 mock_consumer.WaitOnGetPasswordStoreResults(); 1624 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
1561 EXPECT_TRUE(mock_consumer.last_result.empty()); 1625 base::MessageLoop::current()->Run();
1562 1626
1563 // Report metrics. 1627 // Report metrics.
1564 store()->ReportMetrics("Test Username", true); 1628 store()->ReportMetrics("Test Username", true);
1565 FinishAsyncProcessing(); 1629 FinishAsyncProcessing();
1566 1630
1567 // Change the login. 1631 // Change the login.
1568 form->password_value = base::ASCIIToUTF16("a different password"); 1632 form->password_value = base::ASCIIToUTF16("a different password");
1569 store()->UpdateLogin(*form); 1633 store()->UpdateLogin(*form);
1570 FinishAsyncProcessing(); 1634 FinishAsyncProcessing();
1571 1635
1572 // Delete one login; a range of logins. 1636 // Delete one login; a range of logins.
1573 store()->RemoveLogin(*form); 1637 store()->RemoveLogin(*form);
1574 store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max()); 1638 store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max());
1575 store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max()); 1639 store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max());
1576 FinishAsyncProcessing(); 1640 FinishAsyncProcessing();
1577 1641
1578 // Verify no notifications are fired during shutdown either. 1642 // Verify no notifications are fired during shutdown either.
1579 ClosePasswordStore(); 1643 ClosePasswordStore();
1580 } 1644 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_store_mac.cc ('k') | chrome/browser/password_manager/password_store_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698