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

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

Issue 335893002: Support to remove passwords by date_synced timestamp. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync integration tests Created 6 years, 6 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
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/native_backend_kwallet_x.h" 5 #include "chrome/browser/password_manager/native_backend_kwallet_x.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 kept_forms.push_back(all_forms[i]); 349 kept_forms.push_back(all_forms[i]);
350 } 350 }
351 351
352 // Update the entry in the wallet, possibly deleting it. 352 // Update the entry in the wallet, possibly deleting it.
353 bool ok = SetLoginsList(kept_forms, form.signon_realm, wallet_handle); 353 bool ok = SetLoginsList(kept_forms, form.signon_realm, wallet_handle);
354 354
355 STLDeleteElements(&kept_forms); 355 STLDeleteElements(&kept_forms);
356 return ok; 356 return ok;
357 } 357 }
358 358
359 bool NativeBackendKWallet::RemoveLoginsCreatedBetween( 359 bool NativeBackendKWallet::RemoveLoginsCreatedBetween(base::Time delete_begin,
360 const base::Time& delete_begin, 360 base::Time delete_end) {
361 const base::Time& delete_end) { 361 password_manager::PasswordStoreChangeList changes;
362 int wallet_handle = WalletHandle(); 362 return RemoveLoginsBetween(delete_begin, delete_end, true, &changes);
363 if (wallet_handle == kInvalidKWalletHandle) 363 }
364 return false;
365 364
366 // We could probably also use readEntryList here. 365 bool NativeBackendKWallet::RemoveLoginsSyncedBetween(
367 std::vector<std::string> realm_list; 366 base::Time delete_begin,
368 { 367 base::Time delete_end,
369 dbus::MethodCall method_call(kKWalletInterface, "entryList"); 368 password_manager::PasswordStoreChangeList* changes) {
370 dbus::MessageWriter builder(&method_call); 369 return RemoveLoginsBetween(delete_begin, delete_end, false, changes);
371 builder.AppendInt32(wallet_handle); // handle
372 builder.AppendString(folder_name_); // folder
373 builder.AppendString(app_name_); // appid
374 scoped_ptr<dbus::Response> response(
375 kwallet_proxy_->CallMethodAndBlock(
376 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
377 if (!response.get()) {
378 LOG(ERROR) << "Error contacting kwalletd (entryList)";
379 return false;
380 }
381 dbus::MessageReader reader(response.get());
382 dbus::MessageReader array(response.get());
383 if (!reader.PopArray(&array)) {
384 LOG(ERROR) << "Error reading response from kwalletd (entryList): "
385 << response->ToString();
386 return false;
387 }
388 while (array.HasMoreData()) {
389 std::string realm;
390 if (!array.PopString(&realm)) {
391 LOG(ERROR) << "Error reading response from kwalletd (entryList): "
392 << response->ToString();
393 return false;
394 }
395 realm_list.push_back(realm);
396 }
397 }
398
399 bool ok = true;
400 for (size_t i = 0; i < realm_list.size(); ++i) {
401 const std::string& signon_realm = realm_list[i];
402 dbus::MethodCall method_call(kKWalletInterface, "readEntry");
403 dbus::MessageWriter builder(&method_call);
404 builder.AppendInt32(wallet_handle); // handle
405 builder.AppendString(folder_name_); // folder
406 builder.AppendString(signon_realm); // key
407 builder.AppendString(app_name_); // appid
408 scoped_ptr<dbus::Response> response(
409 kwallet_proxy_->CallMethodAndBlock(
410 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
411 if (!response.get()) {
412 LOG(ERROR) << "Error contacting kwalletd (readEntry)";
413 continue;
414 }
415 dbus::MessageReader reader(response.get());
416 const uint8_t* bytes = NULL;
417 size_t length = 0;
418 if (!reader.PopArrayOfBytes(&bytes, &length)) {
419 LOG(ERROR) << "Error reading response from kwalletd (readEntry): "
420 << response->ToString();
421 continue;
422 }
423 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm))
424 continue;
425
426 // Can't we all just agree on whether bytes are signed or not? Please?
427 Pickle pickle(reinterpret_cast<const char*>(bytes), length);
428 PasswordFormList all_forms;
429 DeserializeValue(signon_realm, pickle, &all_forms);
430
431 PasswordFormList kept_forms;
432 kept_forms.reserve(all_forms.size());
433 for (size_t i = 0; i < all_forms.size(); ++i) {
434 if (delete_begin <= all_forms[i]->date_created &&
435 (delete_end.is_null() || all_forms[i]->date_created < delete_end)) {
436 delete all_forms[i];
437 } else {
438 kept_forms.push_back(all_forms[i]);
439 }
440 }
441
442 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle))
443 ok = false;
444 STLDeleteElements(&kept_forms);
445 }
446 return ok;
447 } 370 }
448 371
449 bool NativeBackendKWallet::GetLogins(const PasswordForm& form, 372 bool NativeBackendKWallet::GetLogins(const PasswordForm& form,
450 PasswordFormList* forms) { 373 PasswordFormList* forms) {
451 int wallet_handle = WalletHandle(); 374 int wallet_handle = WalletHandle();
452 if (wallet_handle == kInvalidKWalletHandle) 375 if (wallet_handle == kInvalidKWalletHandle)
453 return false; 376 return false;
454 return GetLoginsList(forms, form.signon_realm, wallet_handle); 377 return GetLoginsList(forms, form.signon_realm, wallet_handle);
455 } 378 }
456 379
457 bool NativeBackendKWallet::GetLoginsCreatedBetween(const base::Time& get_begin, 380 bool NativeBackendKWallet::GetLoginsCreatedBetween(base::Time get_begin,
458 const base::Time& get_end, 381 base::Time get_end,
459 PasswordFormList* forms) { 382 PasswordFormList* forms) {
460 int wallet_handle = WalletHandle(); 383 int wallet_handle = WalletHandle();
461 if (wallet_handle == kInvalidKWalletHandle) 384 if (wallet_handle == kInvalidKWalletHandle)
462 return false; 385 return false;
463 return GetLoginsList(forms, get_begin, get_end, wallet_handle); 386 return GetLoginsList(forms, get_begin, get_end, wallet_handle, true);
464 } 387 }
465 388
466 bool NativeBackendKWallet::GetAutofillableLogins(PasswordFormList* forms) { 389 bool NativeBackendKWallet::GetAutofillableLogins(PasswordFormList* forms) {
467 int wallet_handle = WalletHandle(); 390 int wallet_handle = WalletHandle();
468 if (wallet_handle == kInvalidKWalletHandle) 391 if (wallet_handle == kInvalidKWalletHandle)
469 return false; 392 return false;
470 return GetLoginsList(forms, true, wallet_handle); 393 return GetLoginsList(forms, true, wallet_handle);
471 } 394 }
472 395
473 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) { 396 bool NativeBackendKWallet::GetBlacklistLogins(PasswordFormList* forms) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 for (size_t i = 0; i < all_forms.size(); ++i) { 484 for (size_t i = 0; i < all_forms.size(); ++i) {
562 if (all_forms[i]->blacklisted_by_user == !autofillable) 485 if (all_forms[i]->blacklisted_by_user == !autofillable)
563 forms->push_back(all_forms[i]); 486 forms->push_back(all_forms[i]);
564 else 487 else
565 delete all_forms[i]; 488 delete all_forms[i];
566 } 489 }
567 490
568 return true; 491 return true;
569 } 492 }
570 493
571 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms, 494 bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms,
vabr (Chromium) 2014/06/17 15:28:40 This method looks sufficiently similar to NativeBa
vasilii 2014/06/17 17:24:14 PasswordStoreX::NativeBackend is an interface. It
572 const base::Time& begin, 495 const base::Time& begin,
573 const base::Time& end, 496 const base::Time& end,
574 int wallet_handle) { 497 int wallet_handle,
498 bool date_is_creation) {
575 PasswordFormList all_forms; 499 PasswordFormList all_forms;
576 if (!GetAllLogins(&all_forms, wallet_handle)) 500 if (!GetAllLogins(&all_forms, wallet_handle))
577 return false; 501 return false;
578 502
579 // We have to read all the entries, and then filter them here. 503 // We have to read all the entries, and then filter them here.
504 base::Time autofill::PasswordForm::*date_member = date_is_creation ?
505 &autofill::PasswordForm::date_created :
506 &autofill::PasswordForm::date_synced;
580 forms->reserve(forms->size() + all_forms.size()); 507 forms->reserve(forms->size() + all_forms.size());
581 for (size_t i = 0; i < all_forms.size(); ++i) { 508 for (size_t i = 0; i < all_forms.size(); ++i) {
582 if (begin <= all_forms[i]->date_created && 509 if (begin <= all_forms[i]->*date_member &&
583 (end.is_null() || all_forms[i]->date_created < end)) { 510 (end.is_null() || all_forms[i]->*date_member < end)) {
584 forms->push_back(all_forms[i]); 511 forms->push_back(all_forms[i]);
585 } else { 512 } else {
586 delete all_forms[i]; 513 delete all_forms[i];
587 } 514 }
588 } 515 }
589 516
590 return true; 517 return true;
591 } 518 }
592 519
593 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms, 520 bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms,
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 if (!reader.PopInt32(&ret)) { 629 if (!reader.PopInt32(&ret)) {
703 LOG(ERROR) << "Error reading response from kwalletd (writeEntry): " 630 LOG(ERROR) << "Error reading response from kwalletd (writeEntry): "
704 << response->ToString(); 631 << response->ToString();
705 return false; 632 return false;
706 } 633 }
707 if (ret != 0) 634 if (ret != 0)
708 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry"; 635 LOG(ERROR) << "Bad return code " << ret << " from KWallet writeEntry";
709 return ret == 0; 636 return ret == 0;
710 } 637 }
711 638
639 bool NativeBackendKWallet::RemoveLoginsBetween(
640 base::Time delete_begin,
641 base::Time delete_end,
642 bool date_is_creation,
643 password_manager::PasswordStoreChangeList* changes) {
644 DCHECK(changes);
645 changes->clear();
646 int wallet_handle = WalletHandle();
647 if (wallet_handle == kInvalidKWalletHandle)
648 return false;
649
650 // We could probably also use readEntryList here.
651 std::vector<std::string> realm_list;
652 {
653 dbus::MethodCall method_call(kKWalletInterface, "entryList");
654 dbus::MessageWriter builder(&method_call);
655 builder.AppendInt32(wallet_handle); // handle
656 builder.AppendString(folder_name_); // folder
657 builder.AppendString(app_name_); // appid
658 scoped_ptr<dbus::Response> response(
659 kwallet_proxy_->CallMethodAndBlock(
660 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
661 if (!response.get()) {
662 LOG(ERROR) << "Error contacting kwalletd (entryList)";
663 return false;
664 }
665 dbus::MessageReader reader(response.get());
666 dbus::MessageReader array(response.get());
667 if (!reader.PopArray(&array)) {
668 LOG(ERROR) << "Error reading response from kwalletd (entryList): "
669 << response->ToString();
670 return false;
671 }
672 while (array.HasMoreData()) {
673 std::string realm;
674 if (!array.PopString(&realm)) {
675 LOG(ERROR) << "Error reading response from kwalletd (entryList): "
676 << response->ToString();
677 return false;
678 }
679 realm_list.push_back(realm);
680 }
681 }
682
683 bool ok = true;
684 for (size_t i = 0; i < realm_list.size(); ++i) {
685 const std::string& signon_realm = realm_list[i];
686 dbus::MethodCall method_call(kKWalletInterface, "readEntry");
687 dbus::MessageWriter builder(&method_call);
688 builder.AppendInt32(wallet_handle); // handle
689 builder.AppendString(folder_name_); // folder
690 builder.AppendString(signon_realm); // key
691 builder.AppendString(app_name_); // appid
692 scoped_ptr<dbus::Response> response(
693 kwallet_proxy_->CallMethodAndBlock(
694 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
695 if (!response.get()) {
696 LOG(ERROR) << "Error contacting kwalletd (readEntry)";
697 continue;
698 }
699 dbus::MessageReader reader(response.get());
700 const uint8_t* bytes = NULL;
701 size_t length = 0;
702 if (!reader.PopArrayOfBytes(&bytes, &length)) {
703 LOG(ERROR) << "Error reading response from kwalletd (readEntry): "
704 << response->ToString();
705 continue;
706 }
707 if (!bytes || !CheckSerializedValue(bytes, length, signon_realm))
708 continue;
709
710 // Can't we all just agree on whether bytes are signed or not? Please?
711 Pickle pickle(reinterpret_cast<const char*>(bytes), length);
712 PasswordFormList all_forms;
713 DeserializeValue(signon_realm, pickle, &all_forms);
714
715 PasswordFormList kept_forms;
716 kept_forms.reserve(all_forms.size());
717 base::Time autofill::PasswordForm::*date_member = date_is_creation ?
718 &autofill::PasswordForm::date_created :
719 &autofill::PasswordForm::date_synced;
720 for (size_t i = 0; i < all_forms.size(); ++i) {
721 if (delete_begin <= all_forms[i]->*date_member &&
722 (delete_end.is_null() || all_forms[i]->*date_member < delete_end)) {
723 changes->push_back(password_manager::PasswordStoreChange(
724 password_manager::PasswordStoreChange::REMOVE, *all_forms[i]));
725 delete all_forms[i];
726 } else {
727 kept_forms.push_back(all_forms[i]);
728 }
729 }
730
731 if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) {
732 ok = false;
733 changes->clear();
734 }
735 STLDeleteElements(&kept_forms);
736 }
737 return ok;
738 }
739
712 // static 740 // static
713 void NativeBackendKWallet::SerializeValue(const PasswordFormList& forms, 741 void NativeBackendKWallet::SerializeValue(const PasswordFormList& forms,
714 Pickle* pickle) { 742 Pickle* pickle) {
715 pickle->WriteInt(kPickleVersion); 743 pickle->WriteInt(kPickleVersion);
716 pickle->WriteUInt64(forms.size()); 744 pickle->WriteUInt64(forms.size());
717 for (PasswordFormList::const_iterator it = forms.begin(); 745 for (PasswordFormList::const_iterator it = forms.begin();
718 it != forms.end(); ++it) { 746 it != forms.end(); ++it) {
719 const PasswordForm* form = *it; 747 const PasswordForm* form = *it;
720 pickle->WriteInt(form->scheme); 748 pickle->WriteInt(form->scheme);
721 pickle->WriteString(form->origin.spec()); 749 pickle->WriteString(form->origin.spec());
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 } 972 }
945 973
946 return handle; 974 return handle;
947 } 975 }
948 976
949 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const { 977 std::string NativeBackendKWallet::GetProfileSpecificFolderName() const {
950 // Originally, the folder name was always just "Chrome Form Data". 978 // Originally, the folder name was always just "Chrome Form Data".
951 // Now we use it to distinguish passwords for different profiles. 979 // Now we use it to distinguish passwords for different profiles.
952 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_); 980 return base::StringPrintf("%s (%d)", kKWalletFolder, profile_id_);
953 } 981 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698