| Index: chrome/browser/password_manager/password_store_mac.cc
|
| diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc
|
| index f35d5ba200c02c031aabf598c054d97e792f4ed0..c48ea233f60e36989066475bc51b705b13f67813 100644
|
| --- a/chrome/browser/password_manager/password_store_mac.cc
|
| +++ b/chrome/browser/password_manager/password_store_mac.cc
|
| @@ -13,9 +13,11 @@
|
| #include "base/mac_util.h"
|
| #include "base/stl_util-inl.h"
|
| #include "base/string_util.h"
|
| +#include "base/task.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/browser/keychain_mac.h"
|
| #include "chrome/browser/password_manager/login_database.h"
|
| +#include "chrome/browser/password_manager/password_store_change.h"
|
|
|
| using webkit_glue::PasswordForm;
|
|
|
| @@ -716,6 +718,11 @@ PasswordStoreMac::PasswordStoreMac(MacKeychain* keychain,
|
| }
|
|
|
| PasswordStoreMac::~PasswordStoreMac() {
|
| + if (thread_.get()) {
|
| + thread_->message_loop()->DeleteSoon(FROM_HERE,
|
| + notification_service_.release());
|
| + thread_->message_loop()->RunAllPending();
|
| + }
|
| }
|
|
|
| bool PasswordStoreMac::Init() {
|
| @@ -725,6 +732,8 @@ bool PasswordStoreMac::Init() {
|
| thread_.reset(NULL);
|
| return false;
|
| }
|
| + ScheduleTask(NewRunnableMethod(this,
|
| + &PasswordStoreMac::CreateNotificationService));
|
| return PasswordStore::Init();
|
| }
|
|
|
| @@ -736,7 +745,14 @@ void PasswordStoreMac::ScheduleTask(Task* task) {
|
|
|
| void PasswordStoreMac::AddLoginImpl(const PasswordForm& form) {
|
| if (AddToKeychainIfNecessary(form)) {
|
| - login_metadata_db_->AddLogin(form);
|
| + if (login_metadata_db_->AddLogin(form)) {
|
| + PasswordStoreChangeList changes;
|
| + changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
|
| + NotificationService::current()->Notify(
|
| + NotificationType::LOGINS_CHANGED,
|
| + NotificationService::AllSources(),
|
| + Details<PasswordStoreChangeList>(&changes));
|
| + }
|
| }
|
| }
|
|
|
| @@ -745,51 +761,93 @@ void PasswordStoreMac::UpdateLoginImpl(const PasswordForm& form) {
|
| // isn't, which is the behavior we want, so there's no separate update call.
|
| if (AddToKeychainIfNecessary(form)) {
|
| int update_count = 0;
|
| - login_metadata_db_->UpdateLogin(form, &update_count);
|
| - // Update will catch any database entries that we already had, but we could
|
| - // also be updating a keychain-only form, in which case we need to add.
|
| - if (update_count == 0) {
|
| - login_metadata_db_->AddLogin(form);
|
| + if (login_metadata_db_->UpdateLogin(form, &update_count)) {
|
| + // Update will catch any database entries that we already had, but we
|
| + // could also be updating a keychain-only form, in which case we need to
|
| + // add.
|
| + PasswordStoreChangeList changes;
|
| + if (update_count == 0) {
|
| + if (login_metadata_db_->AddLogin(form)) {
|
| + changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD,
|
| + form));
|
| + }
|
| + } else {
|
| + changes.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE,
|
| + form));
|
| + }
|
| + if (!changes.empty()) {
|
| + NotificationService::current()->Notify(
|
| + NotificationType::LOGINS_CHANGED,
|
| + NotificationService::AllSources(),
|
| + Details<PasswordStoreChangeList>(&changes));
|
| + }
|
| }
|
| }
|
| }
|
|
|
| void PasswordStoreMac::RemoveLoginImpl(const PasswordForm& form) {
|
| - login_metadata_db_->RemoveLogin(form);
|
| -
|
| - // See if we own a Keychain item associated with this item. We can do an exact
|
| - // search rather than messing around with trying to do fuzzy matching because
|
| - // passwords that we created will always have an exact-match database entry.
|
| - // (If a user does lose their profile but not their keychain we'll treat the
|
| - // entries we find like other imported entries anyway, so it's reasonable to
|
| - // handle deletes on them the way we would for an imported item.)
|
| - MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get());
|
| - owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
|
| - PasswordForm* owned_password_form =
|
| - owned_keychain_adapter.PasswordExactlyMatchingForm(form);
|
| - if (owned_password_form) {
|
| - // If we don't have other forms using it (i.e., a form differing only by
|
| - // the names of the form elements), delete the keychain entry.
|
| - if (!DatabaseHasFormMatchingKeychainForm(form)) {
|
| - owned_keychain_adapter.RemovePassword(form);
|
| + if (login_metadata_db_->RemoveLogin(form)) {
|
| + // See if we own a Keychain item associated with this item. We can do an
|
| + // exact search rather than messing around with trying to do fuzzy matching
|
| + // because passwords that we created will always have an exact-match
|
| + // database entry.
|
| + // (If a user does lose their profile but not their keychain we'll treat the
|
| + // entries we find like other imported entries anyway, so it's reasonable to
|
| + // handle deletes on them the way we would for an imported item.)
|
| + MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get());
|
| + owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
|
| + PasswordForm* owned_password_form =
|
| + owned_keychain_adapter.PasswordExactlyMatchingForm(form);
|
| + if (owned_password_form) {
|
| + // If we don't have other forms using it (i.e., a form differing only by
|
| + // the names of the form elements), delete the keychain entry.
|
| + if (!DatabaseHasFormMatchingKeychainForm(form)) {
|
| + owned_keychain_adapter.RemovePassword(form);
|
| + }
|
| }
|
| +
|
| + PasswordStoreChangeList changes;
|
| + changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
|
| + NotificationService::current()->Notify(
|
| + NotificationType::LOGINS_CHANGED,
|
| + NotificationService::AllSources(),
|
| + Details<PasswordStoreChangeList>(&changes));
|
| }
|
| }
|
|
|
| void PasswordStoreMac::RemoveLoginsCreatedBetweenImpl(
|
| const base::Time& delete_begin, const base::Time& delete_end) {
|
| - login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin, delete_end);
|
| -
|
| - // We can't delete from the Keychain by date because we may be sharing items
|
| - // with database entries that weren't in the delete range. Instead, we find
|
| - // all the Keychain items we own but aren't using any more and delete those.
|
| - std::vector<PasswordForm*> orphan_keychain_forms = GetUnusedKeychainForms();
|
| - // This is inefficient, since we have to re-look-up each keychain item one at
|
| - // a time to delete it even though the search step already had a list of
|
| - // Keychain item references. If this turns out to be noticeably slow we'll
|
| - // need to rearchitect to allow the search and deletion steps to share.
|
| - RemoveKeychainForms(orphan_keychain_forms);
|
| - STLDeleteElements(&orphan_keychain_forms);
|
| + std::vector<PasswordForm*> forms;
|
| + if (login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end,
|
| + &forms)) {
|
| + if (login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin,
|
| + delete_end)) {
|
| + // We can't delete from the Keychain by date because we may be sharing
|
| + // items with database entries that weren't in the delete range. Instead,
|
| + // we find all the Keychain items we own but aren't using any more and
|
| + // delete those.
|
| + std::vector<PasswordForm*> orphan_keychain_forms =
|
| + GetUnusedKeychainForms();
|
| + // This is inefficient, since we have to re-look-up each keychain item
|
| + // one at a time to delete it even though the search step already had a
|
| + // list of Keychain item references. If this turns out to be noticeably
|
| + // slow we'll need to rearchitect to allow the search and deletion steps
|
| + // to share.
|
| + RemoveKeychainForms(orphan_keychain_forms);
|
| + STLDeleteElements(&orphan_keychain_forms);
|
| +
|
| + PasswordStoreChangeList changes;
|
| + for (std::vector<PasswordForm*>::const_iterator it = forms.begin();
|
| + it != forms.end(); ++it) {
|
| + changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE,
|
| + **it));
|
| + }
|
| + NotificationService::current()->Notify(
|
| + NotificationType::LOGINS_CHANGED,
|
| + NotificationService::AllSources(),
|
| + Details<PasswordStoreChangeList>(&changes));
|
| + }
|
| + }
|
| }
|
|
|
| void PasswordStoreMac::GetLoginsImpl(GetLoginsRequest* request,
|
| @@ -906,3 +964,7 @@ void PasswordStoreMac::RemoveKeychainForms(
|
| owned_keychain_adapter.RemovePassword(**i);
|
| }
|
| }
|
| +
|
| +void PasswordStoreMac::CreateNotificationService() {
|
| + notification_service_.reset(new NotificationService);
|
| +}
|
|
|