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

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

Issue 2866023: Linux: delete the unencrypted login database file after a successful password migration. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/password_manager/password_store_x.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "base/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/scoped_temp_dir.h" 6 #include "base/scoped_temp_dir.h"
7 #include "base/stl_util-inl.h" 7 #include "base/stl_util-inl.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "base/waitable_event.h" 10 #include "base/waitable_event.h"
11 #include "chrome/browser/password_manager/password_form_data.h" 11 #include "chrome/browser/password_manager/password_form_data.h"
12 #include "chrome/browser/password_manager/password_store_change.h" 12 #include "chrome/browser/password_manager/password_store_change.h"
13 #include "chrome/browser/password_manager/password_store_x.h" 13 #include "chrome/browser/password_manager/password_store_x.h"
14 #include "chrome/browser/webdata/web_data_service.h" 14 #include "chrome/browser/webdata/web_data_service.h"
15 #include "chrome/common/notification_service.h" 15 #include "chrome/common/notification_service.h"
16 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/testing_profile.h" 17 #include "chrome/test/testing_profile.h"
18 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
20 20
21 using base::WaitableEvent; 21 using base::WaitableEvent;
22 using testing::_; 22 using testing::_;
23 using testing::DoAll; 23 using testing::DoAll;
24 using testing::ElementsAreArray; 24 using testing::ElementsAreArray;
25 using testing::Pointee; 25 using testing::Pointee;
26 using testing::Property; 26 using testing::Property;
27 using testing::WithArg; 27 using testing::WithArg;
28 using webkit_glue::PasswordForm; 28 using webkit_glue::PasswordForm;
29 29
30 typedef std::vector<PasswordForm*> VectorOfForms;
31
30 namespace { 32 namespace {
31 33
32 class MockPasswordStoreConsumer : public PasswordStoreConsumer { 34 class MockPasswordStoreConsumer : public PasswordStoreConsumer {
33 public: 35 public:
34 MOCK_METHOD2(OnPasswordStoreRequestDone, 36 MOCK_METHOD2(OnPasswordStoreRequestDone,
35 void(int, const std::vector<PasswordForm*>&)); 37 void(int, const std::vector<PasswordForm*>&));
36 }; 38 };
37 39
38 class MockWebDataServiceConsumer : public WebDataServiceConsumer { 40 class MockWebDataServiceConsumer : public WebDataServiceConsumer {
39 public: 41 public:
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 login_db_->GetBlacklistLogins(&forms); 238 login_db_->GetBlacklistLogins(&forms);
237 mock_return_->OnLoginDatabaseQueryDone(forms); 239 mock_return_->OnLoginDatabaseQueryDone(forms);
238 } 240 }
239 241
240 private: 242 private:
241 LoginDatabase* login_db_; 243 LoginDatabase* login_db_;
242 bool autofillable_; 244 bool autofillable_;
243 MockLoginDatabaseReturn* mock_return_; 245 MockLoginDatabaseReturn* mock_return_;
244 }; 246 };
245 247
246 const PasswordFormData g_autofillable_data[] = { 248 // Generate |count| expected logins, either autofillable or blacklisted.
247 { PasswordForm::SCHEME_HTML, 249 void InitExpectedForms(bool autofillable, size_t count, VectorOfForms* forms) {
248 "http://foo.example.com", 250 const char* domain = autofillable ? "example" : "blacklisted";
249 "http://foo.example.com/origin", 251 for (size_t i = 0; i < count; ++i) {
250 "http://foo.example.com/action", 252 std::string realm = StringPrintf("http://%zu.%s.com", i, domain);
251 L"submit_element", 253 std::string origin = StringPrintf("http://%zu.%s.com/origin", i, domain);
252 L"username_element", 254 std::string action = StringPrintf("http://%zu.%s.com/action", i, domain);
253 L"password_element", 255 PasswordFormData data = {
254 L"username_value", 256 PasswordForm::SCHEME_HTML,
255 L"password_value", 257 realm.c_str(),
256 true, false, 1 }, 258 origin.c_str(),
257 { PasswordForm::SCHEME_HTML, 259 action.c_str(),
258 "http://bar.example.com", 260 L"submit_element",
259 "http://bar.example.com/origin", 261 L"username_element",
260 "http://bar.example.com/action", 262 L"password_element",
261 L"submit_element", 263 autofillable ? L"username_value" : NULL,
262 L"username_element", 264 autofillable ? L"password_value" : NULL,
263 L"password_element", 265 autofillable, false, i + 1 };
264 L"username_value", 266 forms->push_back(CreatePasswordFormFromData(data));
265 L"password_value", 267 }
266 true, false, 2 }, 268 }
267 { PasswordForm::SCHEME_HTML,
268 "http://baz.example.com",
269 "http://baz.example.com/origin",
270 "http://baz.example.com/action",
271 L"submit_element",
272 L"username_element",
273 L"password_element",
274 L"username_value",
275 L"password_value",
276 true, false, 3 },
277 };
278 const PasswordFormData g_blacklisted_data[] = {
279 { PasswordForm::SCHEME_HTML,
280 "http://blacklisted.example.com",
281 "http://blacklisted.example.com/origin",
282 "http://blacklisted.example.com/action",
283 L"submit_element",
284 L"username_element",
285 L"password_element",
286 NULL,
287 NULL,
288 false, false, 1 },
289 { PasswordForm::SCHEME_HTML,
290 "http://blacklisted2.example.com",
291 "http://blacklisted2.example.com/origin",
292 "http://blacklisted2.example.com/action",
293 L"submit_element",
294 L"username_element",
295 L"password_element",
296 NULL,
297 NULL,
298 false, false, 2 },
299 };
300 269
301 } // anonymous namespace 270 } // anonymous namespace
302 271
303 typedef std::vector<PasswordForm*> VectorOfForms;
304
305 // LoginDatabase isn't reference counted, but in these unit tests that won't be 272 // LoginDatabase isn't reference counted, but in these unit tests that won't be
306 // a problem as it always outlives the threads we post tasks to. 273 // a problem as it always outlives the threads we post tasks to.
307 template<> 274 template<>
308 struct RunnableMethodTraits<LoginDatabase> { 275 struct RunnableMethodTraits<LoginDatabase> {
309 void RetainCallee(LoginDatabase*) {} 276 void RetainCallee(LoginDatabase*) {}
310 void ReleaseCallee(LoginDatabase*) {} 277 void ReleaseCallee(LoginDatabase*) {}
311 }; 278 };
312 279
313 enum BackendType { 280 enum BackendType {
314 NO_BACKEND, 281 NO_BACKEND,
315 FAILING_BACKEND, 282 FAILING_BACKEND,
316 WORKING_BACKEND 283 WORKING_BACKEND
317 }; 284 };
318 285
319 class PasswordStoreXTest : public testing::TestWithParam<BackendType> { 286 class PasswordStoreXTest : public testing::TestWithParam<BackendType> {
320 protected: 287 protected:
321 PasswordStoreXTest() 288 PasswordStoreXTest()
322 : ui_thread_(ChromeThread::UI, &message_loop_), 289 : ui_thread_(ChromeThread::UI, &message_loop_),
323 db_thread_(ChromeThread::DB) { 290 db_thread_(ChromeThread::DB) {
324 } 291 }
325 292
326 virtual void SetUp() { 293 virtual void SetUp() {
327 ASSERT_TRUE(db_thread_.Start()); 294 ASSERT_TRUE(db_thread_.Start());
328 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 295 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
329 296
330 profile_.reset(new TestingProfile()); 297 profile_.reset(new TestingProfile());
331 298
332 login_db_.reset(new LoginDatabase()); 299 login_db_.reset(new LoginDatabase());
333 ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append( 300 ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append("login_test")));
334 FILE_PATH_LITERAL("login_test"))));
335 301
336 wds_ = new WebDataService(); 302 wds_ = new WebDataService();
337 ASSERT_TRUE(wds_->Init(temp_dir_.path())); 303 ASSERT_TRUE(wds_->Init(temp_dir_.path()));
338 } 304 }
339 305
340 virtual void TearDown() { 306 virtual void TearDown() {
341 wds_->Shutdown(); 307 wds_->Shutdown();
342 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask); 308 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask);
343 MessageLoop::current()->Run(); 309 MessageLoop::current()->Run();
344 db_thread_.Stop(); 310 db_thread_.Stop();
(...skipping 29 matching lines...) Expand all
374 MessageLoop::current()->Quit(); 340 MessageLoop::current()->Quit();
375 } 341 }
376 342
377 MATCHER(EmptyWDResult, "") { 343 MATCHER(EmptyWDResult, "") {
378 return static_cast<const WDResult<std::vector<PasswordForm*> >*>( 344 return static_cast<const WDResult<std::vector<PasswordForm*> >*>(
379 arg)->GetValue().empty(); 345 arg)->GetValue().empty();
380 } 346 }
381 347
382 TEST_P(PasswordStoreXTest, WDSMigration) { 348 TEST_P(PasswordStoreXTest, WDSMigration) {
383 VectorOfForms expected_autofillable; 349 VectorOfForms expected_autofillable;
384 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(g_autofillable_data); ++i) { 350 InitExpectedForms(true, 5, &expected_autofillable);
385 expected_autofillable.push_back(
386 CreatePasswordFormFromData(g_autofillable_data[i]));
387 }
388 351
389 VectorOfForms expected_blacklisted; 352 VectorOfForms expected_blacklisted;
390 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(g_blacklisted_data); ++i) { 353 InitExpectedForms(false, 5, &expected_blacklisted);
391 expected_blacklisted.push_back(
392 CreatePasswordFormFromData(g_blacklisted_data[i]));
393 }
394 354
395 // Populate the WDS with logins that should be migrated. 355 // Populate the WDS with logins that should be migrated.
396 for (VectorOfForms::iterator it = expected_autofillable.begin(); 356 for (VectorOfForms::iterator it = expected_autofillable.begin();
397 it != expected_autofillable.end(); ++it) { 357 it != expected_autofillable.end(); ++it) {
398 wds_->AddLogin(**it); 358 wds_->AddLogin(**it);
399 } 359 }
400 for (VectorOfForms::iterator it = expected_blacklisted.begin(); 360 for (VectorOfForms::iterator it = expected_blacklisted.begin();
401 it != expected_blacklisted.end(); ++it) { 361 it != expected_blacklisted.end(); ++it) {
402 wds_->AddLogin(**it); 362 wds_->AddLogin(**it);
403 } 363 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 // Deleting the login should trigger a notification. 595 // Deleting the login should trigger a notification.
636 store->RemoveLogin(*form); 596 store->RemoveLogin(*form);
637 597
638 // Wait for PasswordStore to send the notification. 598 // Wait for PasswordStore to send the notification.
639 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); 599 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
640 done.Wait(); 600 done.Wait();
641 } 601 }
642 602
643 TEST_P(PasswordStoreXTest, NativeMigration) { 603 TEST_P(PasswordStoreXTest, NativeMigration) {
644 VectorOfForms expected_autofillable; 604 VectorOfForms expected_autofillable;
645 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(g_autofillable_data); ++i) { 605 InitExpectedForms(true, 50, &expected_autofillable);
646 expected_autofillable.push_back(
647 CreatePasswordFormFromData(g_autofillable_data[i]));
648 }
649 606
650 VectorOfForms expected_blacklisted; 607 VectorOfForms expected_blacklisted;
651 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(g_blacklisted_data); ++i) { 608 InitExpectedForms(false, 50, &expected_blacklisted);
652 expected_blacklisted.push_back( 609
653 CreatePasswordFormFromData(g_blacklisted_data[i])); 610 // Get the initial size of the login DB file, before we populate it.
654 } 611 // This will be used later to make sure it gets back to this size.
612 const FilePath login_db_file = temp_dir_.path().Append("login_test");
613 file_util::FileInfo db_file_start_info;
614 ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_start_info));
655 615
656 LoginDatabase* login_db = login_db_.get(); 616 LoginDatabase* login_db = login_db_.get();
657 617
658 // Populate the login DB with logins that should be migrated. 618 // Populate the login DB with logins that should be migrated.
659 for (VectorOfForms::iterator it = expected_autofillable.begin(); 619 for (VectorOfForms::iterator it = expected_autofillable.begin();
660 it != expected_autofillable.end(); ++it) { 620 it != expected_autofillable.end(); ++it) {
661 ChromeThread::PostTask(ChromeThread::DB, 621 ChromeThread::PostTask(ChromeThread::DB,
662 FROM_HERE, 622 FROM_HERE,
663 NewRunnableMethod(login_db, 623 NewRunnableMethod(login_db,
664 &LoginDatabase::AddLogin, 624 &LoginDatabase::AddLogin,
665 **it)); 625 **it));
666 } 626 }
667 for (VectorOfForms::iterator it = expected_blacklisted.begin(); 627 for (VectorOfForms::iterator it = expected_blacklisted.begin();
668 it != expected_blacklisted.end(); ++it) { 628 it != expected_blacklisted.end(); ++it) {
669 ChromeThread::PostTask(ChromeThread::DB, 629 ChromeThread::PostTask(ChromeThread::DB,
670 FROM_HERE, 630 FROM_HERE,
671 NewRunnableMethod(login_db, 631 NewRunnableMethod(login_db,
672 &LoginDatabase::AddLogin, 632 &LoginDatabase::AddLogin,
673 **it)); 633 **it));
674 } 634 }
675 635
676 // Schedule another task on the DB thread to notify us that it's safe to 636 // Schedule another task on the DB thread to notify us that it's safe to
677 // carry on with the test. 637 // carry on with the test.
678 WaitableEvent done(false, false); 638 WaitableEvent done(false, false);
679 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); 639 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
680 done.Wait(); 640 done.Wait();
681 641
642 // Get the new size of the login DB file. We expect it to be larger.
643 file_util::FileInfo db_file_full_info;
644 ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_full_info));
645 EXPECT_GT(db_file_full_info.size, db_file_start_info.size);
646
682 // Pretend that the WDS migration has already taken place. 647 // Pretend that the WDS migration has already taken place.
683 profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated, 648 profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
684 true); 649 true);
685 650
686 // Initializing the PasswordStore shouldn't trigger a native migration (yet). 651 // Initializing the PasswordStore shouldn't trigger a native migration (yet).
687 scoped_refptr<PasswordStoreX> store( 652 scoped_refptr<PasswordStoreX> store(
688 new PasswordStoreX(login_db_.release(), 653 new PasswordStoreX(login_db_.release(),
689 profile_.get(), 654 profile_.get(),
690 wds_.get(), 655 wds_.get(),
691 GetBackend())); 656 GetBackend()));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 .WillOnce(WithArg<0>(STLDeleteElements0())); 714 .WillOnce(WithArg<0>(STLDeleteElements0()));
750 } 715 }
751 716
752 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, 717 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE,
753 new LoginDatabaseQueryTask(login_db, false, &ld_return)); 718 new LoginDatabaseQueryTask(login_db, false, &ld_return));
754 719
755 // Wait for the login DB methods to execute on the DB thread. 720 // Wait for the login DB methods to execute on the DB thread.
756 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); 721 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
757 done.Wait(); 722 done.Wait();
758 723
724 if (GetParam() == WORKING_BACKEND) {
725 // If the migration succeeded, then not only should there be no logins left
726 // in the login DB, but also the file should have been deleted and then
727 // recreated. We approximate checking for this by checking that the file
728 // size is equal to the size before we populated it, even though it was
729 // larger after populating it.
730 file_util::FileInfo db_file_end_info;
731 ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_end_info));
732 EXPECT_EQ(db_file_start_info.size, db_file_end_info.size);
733 }
734
759 STLDeleteElements(&expected_autofillable); 735 STLDeleteElements(&expected_autofillable);
760 STLDeleteElements(&expected_blacklisted); 736 STLDeleteElements(&expected_blacklisted);
761 } 737 }
762 738
763 INSTANTIATE_TEST_CASE_P(NoBackend, 739 INSTANTIATE_TEST_CASE_P(NoBackend,
764 PasswordStoreXTest, 740 PasswordStoreXTest,
765 testing::Values(NO_BACKEND)); 741 testing::Values(NO_BACKEND));
766 INSTANTIATE_TEST_CASE_P(FailingBackend, 742 INSTANTIATE_TEST_CASE_P(FailingBackend,
767 PasswordStoreXTest, 743 PasswordStoreXTest,
768 testing::Values(FAILING_BACKEND)); 744 testing::Values(FAILING_BACKEND));
769 INSTANTIATE_TEST_CASE_P(WorkingBackend, 745 INSTANTIATE_TEST_CASE_P(WorkingBackend,
770 PasswordStoreXTest, 746 PasswordStoreXTest,
771 testing::Values(WORKING_BACKEND)); 747 testing::Values(WORKING_BACKEND));
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_store_x.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698