| OLD | NEW |
| 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_gnome_x.h" | 5 #include "chrome/browser/password_manager/native_backend_gnome_x.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 108 } |
| 109 return form; | 109 return form; |
| 110 } | 110 } |
| 111 | 111 |
| 112 // Converts native credentials in |found| to PasswordForms. If not NULL, | 112 // Converts native credentials in |found| to PasswordForms. If not NULL, |
| 113 // |lookup_form| is used to filter out results -- only credentials with signon | 113 // |lookup_form| is used to filter out results -- only credentials with signon |
| 114 // realms passing the PSL matching against |lookup_form->signon_realm| will be | 114 // realms passing the PSL matching against |lookup_form->signon_realm| will be |
| 115 // kept. PSL matched results get their signon_realm, origin, and action | 115 // kept. PSL matched results get their signon_realm, origin, and action |
| 116 // rewritten to those of |lookup_form_|, with the original signon_realm saved | 116 // rewritten to those of |lookup_form_|, with the original signon_realm saved |
| 117 // into the result's original_signon_realm data member. | 117 // into the result's original_signon_realm data member. |
| 118 ScopedVector<PasswordForm> ConvertFormList( | 118 std::vector<std::unique_ptr<PasswordForm>> ConvertFormList( |
| 119 GList* found, | 119 GList* found, |
| 120 const PasswordStore::FormDigest* lookup_form) { | 120 const PasswordStore::FormDigest* lookup_form) { |
| 121 ScopedVector<PasswordForm> forms; | 121 std::vector<std::unique_ptr<PasswordForm>> forms; |
| 122 password_manager::PSLDomainMatchMetric psl_domain_match_metric = | 122 password_manager::PSLDomainMatchMetric psl_domain_match_metric = |
| 123 password_manager::PSL_DOMAIN_MATCH_NONE; | 123 password_manager::PSL_DOMAIN_MATCH_NONE; |
| 124 const bool allow_psl_match = | 124 const bool allow_psl_match = |
| 125 lookup_form && password_manager::ShouldPSLDomainMatchingApply( | 125 lookup_form && password_manager::ShouldPSLDomainMatchingApply( |
| 126 password_manager::GetRegistryControlledDomain( | 126 password_manager::GetRegistryControlledDomain( |
| 127 GURL(lookup_form->signon_realm))); | 127 GURL(lookup_form->signon_realm))); |
| 128 for (GList* element = g_list_first(found); element; | 128 for (GList* element = g_list_first(found); element; |
| 129 element = g_list_next(element)) { | 129 element = g_list_next(element)) { |
| 130 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); | 130 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); |
| 131 GnomeKeyringAttributeList* attrs = data->attributes; | 131 GnomeKeyringAttributeList* attrs = data->attributes; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 void RemoveLogin(const PasswordForm& form, const char* app_string); | 226 void RemoveLogin(const PasswordForm& form, const char* app_string); |
| 227 void GetLogins(const PasswordStore::FormDigest& form, const char* app_string); | 227 void GetLogins(const PasswordStore::FormDigest& form, const char* app_string); |
| 228 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); | 228 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); |
| 229 void GetAllLogins(const char* app_string); | 229 void GetAllLogins(const char* app_string); |
| 230 | 230 |
| 231 // Use after AddLogin, RemoveLogin. | 231 // Use after AddLogin, RemoveLogin. |
| 232 GnomeKeyringResult WaitResult(); | 232 GnomeKeyringResult WaitResult(); |
| 233 | 233 |
| 234 // Use after LoginSearch, GetLogins, GetLoginsList, GetAllLogins. Replaces the | 234 // Use after LoginSearch, GetLogins, GetLoginsList, GetAllLogins. Replaces the |
| 235 // content of |forms| with found logins. | 235 // content of |forms| with found logins. |
| 236 GnomeKeyringResult WaitResult(ScopedVector<PasswordForm>* forms); | 236 GnomeKeyringResult WaitResult( |
| 237 std::vector<std::unique_ptr<PasswordForm>>* forms); |
| 237 | 238 |
| 238 private: | 239 private: |
| 239 struct GnomeKeyringAttributeListFreeDeleter { | 240 struct GnomeKeyringAttributeListFreeDeleter { |
| 240 inline void operator()(void* list) const { | 241 inline void operator()(void* list) const { |
| 241 gnome_keyring_attribute_list_free_ptr( | 242 gnome_keyring_attribute_list_free_ptr( |
| 242 static_cast<GnomeKeyringAttributeList*>(list)); | 243 static_cast<GnomeKeyringAttributeList*>(list)); |
| 243 } | 244 } |
| 244 }; | 245 }; |
| 245 | 246 |
| 246 typedef std::unique_ptr<GnomeKeyringAttributeList, | 247 typedef std::unique_ptr<GnomeKeyringAttributeList, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 262 static void OnOperationDone(GnomeKeyringResult result, gpointer data); | 263 static void OnOperationDone(GnomeKeyringResult result, gpointer data); |
| 263 | 264 |
| 264 // This is marked as static, but acts on the GKRMethod instance that |data| | 265 // This is marked as static, but acts on the GKRMethod instance that |data| |
| 265 // points to. Saves |result| to |result_|. If the result is OK, overwrites | 266 // points to. Saves |result| to |result_|. If the result is OK, overwrites |
| 266 // |forms_| with the found credentials. Clears |forms_| otherwise. | 267 // |forms_| with the found credentials. Clears |forms_| otherwise. |
| 267 static void OnOperationGetList(GnomeKeyringResult result, GList* list, | 268 static void OnOperationGetList(GnomeKeyringResult result, GList* list, |
| 268 gpointer data); | 269 gpointer data); |
| 269 | 270 |
| 270 base::WaitableEvent event_; | 271 base::WaitableEvent event_; |
| 271 GnomeKeyringResult result_; | 272 GnomeKeyringResult result_; |
| 272 ScopedVector<PasswordForm> forms_; | 273 std::vector<std::unique_ptr<PasswordForm>> forms_; |
| 273 // If the credential search is specified by a single form and needs to use | 274 // If the credential search is specified by a single form and needs to use |
| 274 // PSL matching, then the specifying form is stored in |lookup_form_|. If | 275 // PSL matching, then the specifying form is stored in |lookup_form_|. If |
| 275 // PSL matching is used to find a result, then the results signon realm and | 276 // PSL matching is used to find a result, then the results signon realm and |
| 276 // origin are stored are replaced by those of |lookup_form_|. Additionally, | 277 // origin are stored are replaced by those of |lookup_form_|. Additionally, |
| 277 // |lookup_form_->signon_realm| is also used to narrow down the found logins | 278 // |lookup_form_->signon_realm| is also used to narrow down the found logins |
| 278 // to those which indeed PSL-match the look-up. And finally, |lookup_form_| | 279 // to those which indeed PSL-match the look-up. And finally, |lookup_form_| |
| 279 // set to NULL means that PSL matching is not required. | 280 // set to NULL means that PSL matching is not required. |
| 280 std::unique_ptr<const PasswordStore::FormDigest> lookup_form_; | 281 std::unique_ptr<const PasswordStore::FormDigest> lookup_form_; |
| 281 }; | 282 }; |
| 282 | 283 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 /*data=*/this, | 409 /*data=*/this, |
| 409 /*destroy_data=*/nullptr); | 410 /*destroy_data=*/nullptr); |
| 410 } | 411 } |
| 411 | 412 |
| 412 GnomeKeyringResult GKRMethod::WaitResult() { | 413 GnomeKeyringResult GKRMethod::WaitResult() { |
| 413 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 414 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 414 event_.Wait(); | 415 event_.Wait(); |
| 415 return result_; | 416 return result_; |
| 416 } | 417 } |
| 417 | 418 |
| 418 GnomeKeyringResult GKRMethod::WaitResult(ScopedVector<PasswordForm>* forms) { | 419 GnomeKeyringResult GKRMethod::WaitResult( |
| 420 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 419 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 421 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 420 event_.Wait(); | 422 event_.Wait(); |
| 421 *forms = std::move(forms_); | 423 *forms = std::move(forms_); |
| 422 return result_; | 424 return result_; |
| 423 } | 425 } |
| 424 | 426 |
| 425 // static | 427 // static |
| 426 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, | 428 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, |
| 427 const char* name, | 429 const char* name, |
| 428 const char* value) { | 430 const char* value) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 // on origin_url, username_element, username_value, password_element, submit | 509 // on origin_url, username_element, username_value, password_element, submit |
| 508 // element, and signon_realm first, remove that, and then add the new entry. | 510 // element, and signon_realm first, remove that, and then add the new entry. |
| 509 // We'd add the new one first, and then delete the original, but then the | 511 // We'd add the new one first, and then delete the original, but then the |
| 510 // delete might actually delete the newly-added entry! | 512 // delete might actually delete the newly-added entry! |
| 511 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 513 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 512 GKRMethod method; | 514 GKRMethod method; |
| 513 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 515 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 514 base::Bind(&GKRMethod::LoginSearch, | 516 base::Bind(&GKRMethod::LoginSearch, |
| 515 base::Unretained(&method), | 517 base::Unretained(&method), |
| 516 form, app_string_.c_str())); | 518 form, app_string_.c_str())); |
| 517 ScopedVector<PasswordForm> forms; | 519 std::vector<std::unique_ptr<PasswordForm>> forms; |
| 518 GnomeKeyringResult result = method.WaitResult(&forms); | 520 GnomeKeyringResult result = method.WaitResult(&forms); |
| 519 if (result != GNOME_KEYRING_RESULT_OK && | 521 if (result != GNOME_KEYRING_RESULT_OK && |
| 520 result != GNOME_KEYRING_RESULT_NO_MATCH) { | 522 result != GNOME_KEYRING_RESULT_NO_MATCH) { |
| 521 LOG(ERROR) << "Keyring find failed: " | 523 LOG(ERROR) << "Keyring find failed: " |
| 522 << gnome_keyring_result_to_message_ptr(result); | 524 << gnome_keyring_result_to_message_ptr(result); |
| 523 return password_manager::PasswordStoreChangeList(); | 525 return password_manager::PasswordStoreChangeList(); |
| 524 } | 526 } |
| 525 password_manager::PasswordStoreChangeList changes; | 527 password_manager::PasswordStoreChangeList changes; |
| 526 if (forms.size() > 0) { | 528 if (forms.size() > 0) { |
| 527 password_manager::PasswordStoreChangeList temp_changes; | 529 password_manager::PasswordStoreChangeList temp_changes; |
| 528 if (forms.size() > 1) { | 530 if (forms.size() > 1) { |
| 529 LOG(WARNING) << "Adding login when there are " << forms.size() | 531 LOG(WARNING) << "Adding login when there are " << forms.size() |
| 530 << " matching logins already!"; | 532 << " matching logins already!"; |
| 531 } | 533 } |
| 532 for (const PasswordForm* old_form : forms) { | 534 for (const auto& old_form : forms) { |
| 533 if (!RemoveLogin(*old_form, &temp_changes)) | 535 if (!RemoveLogin(*old_form, &temp_changes)) |
| 534 return changes; | 536 return changes; |
| 535 } | 537 } |
| 536 changes.push_back(password_manager::PasswordStoreChange( | 538 changes.push_back(password_manager::PasswordStoreChange( |
| 537 password_manager::PasswordStoreChange::REMOVE, *forms[0])); | 539 password_manager::PasswordStoreChange::REMOVE, *forms[0])); |
| 538 } | 540 } |
| 539 if (RawAddLogin(form)) { | 541 if (RawAddLogin(form)) { |
| 540 changes.push_back(password_manager::PasswordStoreChange( | 542 changes.push_back(password_manager::PasswordStoreChange( |
| 541 password_manager::PasswordStoreChange::ADD, form)); | 543 password_manager::PasswordStoreChange::ADD, form)); |
| 542 } | 544 } |
| 543 return changes; | 545 return changes; |
| 544 } | 546 } |
| 545 | 547 |
| 546 bool NativeBackendGnome::UpdateLogin( | 548 bool NativeBackendGnome::UpdateLogin( |
| 547 const PasswordForm& form, | 549 const PasswordForm& form, |
| 548 password_manager::PasswordStoreChangeList* changes) { | 550 password_manager::PasswordStoreChangeList* changes) { |
| 549 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by | 551 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by |
| 550 // origin_url, username_element, username_value, password_element, and | 552 // origin_url, username_element, username_value, password_element, and |
| 551 // signon_realm. We then compare the result to the updated form. If they | 553 // signon_realm. We then compare the result to the updated form. If they |
| 552 // differ in any of the mutable fields, then we remove the original, and | 554 // differ in any of the mutable fields, then we remove the original, and |
| 553 // then add the new entry. We'd add the new one first, and then delete the | 555 // then add the new entry. We'd add the new one first, and then delete the |
| 554 // original, but then the delete might actually delete the newly-added entry! | 556 // original, but then the delete might actually delete the newly-added entry! |
| 555 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 557 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 556 DCHECK(changes); | 558 DCHECK(changes); |
| 557 GKRMethod method; | 559 GKRMethod method; |
| 558 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 560 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 559 base::Bind(&GKRMethod::LoginSearch, | 561 base::Bind(&GKRMethod::LoginSearch, |
| 560 base::Unretained(&method), | 562 base::Unretained(&method), |
| 561 form, app_string_.c_str())); | 563 form, app_string_.c_str())); |
| 562 ScopedVector<PasswordForm> forms; | 564 std::vector<std::unique_ptr<PasswordForm>> forms; |
| 563 GnomeKeyringResult result = method.WaitResult(&forms); | 565 GnomeKeyringResult result = method.WaitResult(&forms); |
| 564 if (result == GNOME_KEYRING_RESULT_NO_MATCH) | 566 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
| 565 return true; | 567 return true; |
| 566 if (result != GNOME_KEYRING_RESULT_OK) { | 568 if (result != GNOME_KEYRING_RESULT_OK) { |
| 567 LOG(ERROR) << "Keyring find failed: " | 569 LOG(ERROR) << "Keyring find failed: " |
| 568 << gnome_keyring_result_to_message_ptr(result); | 570 << gnome_keyring_result_to_message_ptr(result); |
| 569 return false; | 571 return false; |
| 570 } | 572 } |
| 571 if (forms.size() == 1 && *forms.front() == form) | 573 if (forms.size() == 1 && *forms.front() == form) |
| 572 return true; | 574 return true; |
| 573 | 575 |
| 574 password_manager::PasswordStoreChangeList temp_changes; | 576 password_manager::PasswordStoreChangeList temp_changes; |
| 575 for (const PasswordForm* keychain_form : forms) { | 577 for (const auto& keychain_form : forms) { |
| 576 // Remove all the obsolete forms. Note that RemoveLogin can remove any form | 578 // Remove all the obsolete forms. Note that RemoveLogin can remove any form |
| 577 // matching the unique key. Thus, it's important to call it the right number | 579 // matching the unique key. Thus, it's important to call it the right number |
| 578 // of times. | 580 // of times. |
| 579 if (!RemoveLogin(*keychain_form, &temp_changes)) | 581 if (!RemoveLogin(*keychain_form, &temp_changes)) |
| 580 return false; | 582 return false; |
| 581 } | 583 } |
| 582 | 584 |
| 583 if (RawAddLogin(form)) { | 585 if (RawAddLogin(form)) { |
| 584 password_manager::PasswordStoreChange change( | 586 password_manager::PasswordStoreChange change( |
| 585 password_manager::PasswordStoreChange::UPDATE, form); | 587 password_manager::PasswordStoreChange::UPDATE, form); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 bool NativeBackendGnome::RemoveLoginsSyncedBetween( | 626 bool NativeBackendGnome::RemoveLoginsSyncedBetween( |
| 625 base::Time delete_begin, | 627 base::Time delete_begin, |
| 626 base::Time delete_end, | 628 base::Time delete_end, |
| 627 password_manager::PasswordStoreChangeList* changes) { | 629 password_manager::PasswordStoreChangeList* changes) { |
| 628 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); | 630 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); |
| 629 } | 631 } |
| 630 | 632 |
| 631 bool NativeBackendGnome::DisableAutoSignInForOrigins( | 633 bool NativeBackendGnome::DisableAutoSignInForOrigins( |
| 632 const base::Callback<bool(const GURL&)>& origin_filter, | 634 const base::Callback<bool(const GURL&)>& origin_filter, |
| 633 password_manager::PasswordStoreChangeList* changes) { | 635 password_manager::PasswordStoreChangeList* changes) { |
| 634 ScopedVector<PasswordForm> forms; | 636 std::vector<std::unique_ptr<PasswordForm>> forms; |
| 635 if (!GetAllLogins(&forms)) | 637 if (!GetAllLogins(&forms)) |
| 636 return false; | 638 return false; |
| 637 | 639 |
| 638 for (auto* form : forms) { | 640 for (const std::unique_ptr<PasswordForm>& form : forms) { |
| 639 if (origin_filter.Run(form->origin) && !form->skip_zero_click) { | 641 if (origin_filter.Run(form->origin) && !form->skip_zero_click) { |
| 640 form->skip_zero_click = true; | 642 form->skip_zero_click = true; |
| 641 if (!UpdateLogin(*form, changes)) | 643 if (!UpdateLogin(*form, changes)) |
| 642 return false; | 644 return false; |
| 643 } | 645 } |
| 644 } | 646 } |
| 645 | 647 |
| 646 return true; | 648 return true; |
| 647 } | 649 } |
| 648 | 650 |
| 649 bool NativeBackendGnome::GetLogins(const PasswordStore::FormDigest& form, | 651 bool NativeBackendGnome::GetLogins( |
| 650 ScopedVector<PasswordForm>* forms) { | 652 const PasswordStore::FormDigest& form, |
| 653 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 651 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 654 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 652 GKRMethod method; | 655 GKRMethod method; |
| 653 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 656 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 654 base::Bind(&GKRMethod::GetLogins, | 657 base::Bind(&GKRMethod::GetLogins, |
| 655 base::Unretained(&method), | 658 base::Unretained(&method), |
| 656 form, app_string_.c_str())); | 659 form, app_string_.c_str())); |
| 657 GnomeKeyringResult result = method.WaitResult(forms); | 660 GnomeKeyringResult result = method.WaitResult(forms); |
| 658 if (result == GNOME_KEYRING_RESULT_NO_MATCH) | 661 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
| 659 return true; | 662 return true; |
| 660 if (result != GNOME_KEYRING_RESULT_OK) { | 663 if (result != GNOME_KEYRING_RESULT_OK) { |
| 661 LOG(ERROR) << "Keyring find failed: " | 664 LOG(ERROR) << "Keyring find failed: " |
| 662 << gnome_keyring_result_to_message_ptr(result); | 665 << gnome_keyring_result_to_message_ptr(result); |
| 663 return false; | 666 return false; |
| 664 } | 667 } |
| 665 return true; | 668 return true; |
| 666 } | 669 } |
| 667 | 670 |
| 668 bool NativeBackendGnome::GetAutofillableLogins( | 671 bool NativeBackendGnome::GetAutofillableLogins( |
| 669 ScopedVector<PasswordForm>* forms) { | 672 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 670 return GetLoginsList(true, forms); | 673 return GetLoginsList(true, forms); |
| 671 } | 674 } |
| 672 | 675 |
| 673 bool NativeBackendGnome::GetBlacklistLogins(ScopedVector<PasswordForm>* forms) { | 676 bool NativeBackendGnome::GetBlacklistLogins( |
| 677 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 674 return GetLoginsList(false, forms); | 678 return GetLoginsList(false, forms); |
| 675 } | 679 } |
| 676 | 680 |
| 677 bool NativeBackendGnome::GetLoginsList(bool autofillable, | 681 bool NativeBackendGnome::GetLoginsList( |
| 678 ScopedVector<PasswordForm>* forms) { | 682 bool autofillable, |
| 683 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 679 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 684 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 680 | 685 |
| 681 uint32_t blacklisted_by_user = !autofillable; | 686 uint32_t blacklisted_by_user = !autofillable; |
| 682 | 687 |
| 683 GKRMethod method; | 688 GKRMethod method; |
| 684 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 689 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 685 base::Bind(&GKRMethod::GetLoginsList, | 690 base::Bind(&GKRMethod::GetLoginsList, |
| 686 base::Unretained(&method), | 691 base::Unretained(&method), |
| 687 blacklisted_by_user, app_string_.c_str())); | 692 blacklisted_by_user, app_string_.c_str())); |
| 688 GnomeKeyringResult result = method.WaitResult(forms); | 693 GnomeKeyringResult result = method.WaitResult(forms); |
| 689 if (result == GNOME_KEYRING_RESULT_NO_MATCH) | 694 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
| 690 return true; | 695 return true; |
| 691 if (result != GNOME_KEYRING_RESULT_OK) { | 696 if (result != GNOME_KEYRING_RESULT_OK) { |
| 692 LOG(ERROR) << "Keyring find failed: " | 697 LOG(ERROR) << "Keyring find failed: " |
| 693 << gnome_keyring_result_to_message_ptr(result); | 698 << gnome_keyring_result_to_message_ptr(result); |
| 694 return false; | 699 return false; |
| 695 } | 700 } |
| 696 | 701 |
| 697 // Get rid of the forms with the same sync tags. | 702 // Get rid of the forms with the same sync tags. |
| 698 ScopedVector<autofill::PasswordForm> duplicates; | 703 std::vector<std::unique_ptr<PasswordForm>> duplicates; |
| 699 std::vector<std::vector<autofill::PasswordForm*>> tag_groups; | 704 std::vector<std::vector<autofill::PasswordForm*>> tag_groups; |
| 700 password_manager_util::FindDuplicates(forms, &duplicates, &tag_groups); | 705 password_manager_util::FindDuplicates(forms, &duplicates, &tag_groups); |
| 701 if (duplicates.empty()) | 706 if (duplicates.empty()) |
| 702 return true; | 707 return true; |
| 703 for (const auto& group : tag_groups) { | 708 for (const auto& group : tag_groups) { |
| 704 if (group.size() > 1) { | 709 if (group.size() > 1) { |
| 705 // There are duplicates. Readd the first form. AddLogin() is smart enough | 710 // There are duplicates. Readd the first form. AddLogin() is smart enough |
| 706 // to clean the previous ones. | 711 // to clean the previous ones. |
| 707 password_manager::PasswordStoreChangeList changes = AddLogin(*group[0]); | 712 password_manager::PasswordStoreChangeList changes = AddLogin(*group[0]); |
| 708 if (changes.empty() || | 713 if (changes.empty() || |
| 709 changes.back().type() != password_manager::PasswordStoreChange::ADD) | 714 changes.back().type() != password_manager::PasswordStoreChange::ADD) |
| 710 return false; | 715 return false; |
| 711 } | 716 } |
| 712 } | 717 } |
| 713 return true; | 718 return true; |
| 714 } | 719 } |
| 715 | 720 |
| 716 bool NativeBackendGnome::GetAllLogins(ScopedVector<PasswordForm>* forms) { | 721 bool NativeBackendGnome::GetAllLogins( |
| 722 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 717 GKRMethod method; | 723 GKRMethod method; |
| 718 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 724 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 719 base::Bind(&GKRMethod::GetAllLogins, | 725 base::Bind(&GKRMethod::GetAllLogins, |
| 720 base::Unretained(&method), | 726 base::Unretained(&method), |
| 721 app_string_.c_str())); | 727 app_string_.c_str())); |
| 722 GnomeKeyringResult result = method.WaitResult(forms); | 728 GnomeKeyringResult result = method.WaitResult(forms); |
| 723 if (result == GNOME_KEYRING_RESULT_NO_MATCH) | 729 if (result == GNOME_KEYRING_RESULT_NO_MATCH) |
| 724 return true; | 730 return true; |
| 725 if (result != GNOME_KEYRING_RESULT_OK) { | 731 if (result != GNOME_KEYRING_RESULT_OK) { |
| 726 LOG(ERROR) << "Keyring find failed: " | 732 LOG(ERROR) << "Keyring find failed: " |
| 727 << gnome_keyring_result_to_message_ptr(result); | 733 << gnome_keyring_result_to_message_ptr(result); |
| 728 return false; | 734 return false; |
| 729 } | 735 } |
| 730 return true; | 736 return true; |
| 731 } | 737 } |
| 732 | 738 |
| 733 bool NativeBackendGnome::GetLoginsBetween(base::Time get_begin, | 739 bool NativeBackendGnome::GetLoginsBetween( |
| 734 base::Time get_end, | 740 base::Time get_begin, |
| 735 TimestampToCompare date_to_compare, | 741 base::Time get_end, |
| 736 ScopedVector<PasswordForm>* forms) { | 742 TimestampToCompare date_to_compare, |
| 743 std::vector<std::unique_ptr<PasswordForm>>* forms) { |
| 737 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 744 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 738 forms->clear(); | 745 forms->clear(); |
| 739 // We could walk the list and add items as we find them, but it is much | 746 // We could walk the list and add items as we find them, but it is much |
| 740 // easier to build the list and then filter the results. | 747 // easier to build the list and then filter the results. |
| 741 ScopedVector<PasswordForm> all_forms; | 748 std::vector<std::unique_ptr<PasswordForm>> all_forms; |
| 742 if (!GetAllLogins(&all_forms)) | 749 if (!GetAllLogins(&all_forms)) |
| 743 return false; | 750 return false; |
| 744 | 751 |
| 745 base::Time PasswordForm::*date_member = date_to_compare == CREATION_TIMESTAMP | 752 base::Time PasswordForm::*date_member = date_to_compare == CREATION_TIMESTAMP |
| 746 ? &PasswordForm::date_created | 753 ? &PasswordForm::date_created |
| 747 : &PasswordForm::date_synced; | 754 : &PasswordForm::date_synced; |
| 748 for (auto*& saved_form : all_forms) { | 755 for (std::unique_ptr<PasswordForm>& saved_form : all_forms) { |
| 749 if (get_begin <= saved_form->*date_member && | 756 if (get_begin <= saved_form.get()->*date_member && |
| 750 (get_end.is_null() || saved_form->*date_member < get_end)) { | 757 (get_end.is_null() || saved_form.get()->*date_member < get_end)) { |
| 751 forms->push_back(saved_form); | 758 forms->push_back(std::move(saved_form)); |
| 752 saved_form = nullptr; | |
| 753 } | 759 } |
| 754 } | 760 } |
| 755 | 761 |
| 756 return true; | 762 return true; |
| 757 } | 763 } |
| 758 | 764 |
| 759 bool NativeBackendGnome::RemoveLoginsBetween( | 765 bool NativeBackendGnome::RemoveLoginsBetween( |
| 760 base::Time get_begin, | 766 base::Time get_begin, |
| 761 base::Time get_end, | 767 base::Time get_end, |
| 762 TimestampToCompare date_to_compare, | 768 TimestampToCompare date_to_compare, |
| 763 password_manager::PasswordStoreChangeList* changes) { | 769 password_manager::PasswordStoreChangeList* changes) { |
| 764 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 770 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 765 DCHECK(changes); | 771 DCHECK(changes); |
| 766 changes->clear(); | 772 changes->clear(); |
| 767 // We could walk the list and delete items as we find them, but it is much | 773 // We could walk the list and delete items as we find them, but it is much |
| 768 // easier to build the list and use RemoveLogin() to delete them. | 774 // easier to build the list and use RemoveLogin() to delete them. |
| 769 ScopedVector<PasswordForm> forms; | 775 std::vector<std::unique_ptr<PasswordForm>> forms; |
| 770 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms)) | 776 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms)) |
| 771 return false; | 777 return false; |
| 772 | 778 |
| 773 for (size_t i = 0; i < forms.size(); ++i) { | 779 for (size_t i = 0; i < forms.size(); ++i) { |
| 774 if (!RemoveLogin(*forms[i], changes)) | 780 if (!RemoveLogin(*forms[i], changes)) |
| 775 return false; | 781 return false; |
| 776 } | 782 } |
| 777 return true; | 783 return true; |
| 778 } | 784 } |
| OLD | NEW |