This source file includes following definitions.
- allow_fallback_
- AddLoginImpl
- UpdateLoginImpl
- RemoveLoginImpl
- RemoveLoginsCreatedBetweenImpl
- SortLoginsByOrigin
- GetLoginsImpl
- GetAutofillableLoginsImpl
- GetBlacklistLoginsImpl
- FillAutofillableLogins
- FillBlacklistLogins
- CheckMigration
- allow_default_store
- MigrateLogins
#include "chrome/browser/password_manager/password_store_x.h"
#include <algorithm>
#include <map>
#include <vector>
#include "base/bind.h"
#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "base/stl_util.h"
#include "chrome/browser/chrome_notification_types.h"
#include "components/password_manager/core/browser/password_store_change.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
using autofill::PasswordForm;
using content::BrowserThread;
using std::vector;
PasswordStoreX::PasswordStoreX(
scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner,
LoginDatabase* login_db,
NativeBackend* backend)
: PasswordStoreDefault(main_thread_runner, db_thread_runner, login_db),
backend_(backend),
migration_checked_(!backend),
allow_fallback_(false) {}
PasswordStoreX::~PasswordStoreX() {}
PasswordStoreChangeList PasswordStoreX::AddLoginImpl(const PasswordForm& form) {
CheckMigration();
PasswordStoreChangeList changes;
if (use_native_backend() && backend_->AddLogin(form)) {
changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
allow_fallback_ = false;
} else if (allow_default_store()) {
changes = PasswordStoreDefault::AddLoginImpl(form);
}
return changes;
}
PasswordStoreChangeList PasswordStoreX::UpdateLoginImpl(
const PasswordForm& form) {
CheckMigration();
PasswordStoreChangeList changes;
if (use_native_backend() && backend_->UpdateLogin(form)) {
changes.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, form));
allow_fallback_ = false;
} else if (allow_default_store()) {
changes = PasswordStoreDefault::UpdateLoginImpl(form);
}
return changes;
}
PasswordStoreChangeList PasswordStoreX::RemoveLoginImpl(
const PasswordForm& form) {
CheckMigration();
PasswordStoreChangeList changes;
if (use_native_backend() && backend_->RemoveLogin(form)) {
changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
allow_fallback_ = false;
} else if (allow_default_store()) {
changes = PasswordStoreDefault::RemoveLoginImpl(form);
}
return changes;
}
PasswordStoreChangeList PasswordStoreX::RemoveLoginsCreatedBetweenImpl(
const base::Time& delete_begin,
const base::Time& delete_end) {
CheckMigration();
vector<PasswordForm*> forms;
PasswordStoreChangeList changes;
if (use_native_backend() &&
backend_->GetLoginsCreatedBetween(delete_begin, delete_end, &forms) &&
backend_->RemoveLoginsCreatedBetween(delete_begin, delete_end)) {
for (vector<PasswordForm*>::const_iterator it = forms.begin();
it != forms.end(); ++it) {
changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE,
**it));
}
LogStatsForBulkDeletion(changes.size());
allow_fallback_ = false;
} else if (allow_default_store()) {
changes = PasswordStoreDefault::RemoveLoginsCreatedBetweenImpl(delete_begin,
delete_end);
}
STLDeleteElements(&forms);
return changes;
}
namespace {
struct LoginLessThan {
bool operator()(const PasswordForm* a, const PasswordForm* b) {
return a->origin < b->origin;
}
};
}
void PasswordStoreX::SortLoginsByOrigin(NativeBackend::PasswordFormList* list) {
std::sort(list->begin(), list->end(), LoginLessThan());
}
void PasswordStoreX::GetLoginsImpl(
const autofill::PasswordForm& form,
AuthorizationPromptPolicy prompt_policy,
const ConsumerCallbackRunner& callback_runner) {
CheckMigration();
std::vector<autofill::PasswordForm*> matched_forms;
if (use_native_backend() && backend_->GetLogins(form, &matched_forms)) {
SortLoginsByOrigin(&matched_forms);
if (matched_forms.size() > 0)
allow_fallback_ = false;
} else if (allow_default_store()) {
DCHECK(matched_forms.empty());
PasswordStoreDefault::GetLoginsImpl(form, prompt_policy, callback_runner);
return;
}
callback_runner.Run(matched_forms);
}
void PasswordStoreX::GetAutofillableLoginsImpl(GetLoginsRequest* request) {
CheckMigration();
if (use_native_backend() &&
backend_->GetAutofillableLogins(request->result())) {
SortLoginsByOrigin(request->result());
if (request->result()->size() > 0)
allow_fallback_ = false;
} else if (allow_default_store()) {
PasswordStoreDefault::GetAutofillableLoginsImpl(request);
return;
}
ForwardLoginsResult(request);
}
void PasswordStoreX::GetBlacklistLoginsImpl(GetLoginsRequest* request) {
CheckMigration();
if (use_native_backend() &&
backend_->GetBlacklistLogins(request->result())) {
SortLoginsByOrigin(request->result());
if (request->result()->size() > 0)
allow_fallback_ = false;
} else if (allow_default_store()) {
PasswordStoreDefault::GetBlacklistLoginsImpl(request);
return;
}
ForwardLoginsResult(request);
}
bool PasswordStoreX::FillAutofillableLogins(vector<PasswordForm*>* forms) {
CheckMigration();
if (use_native_backend() && backend_->GetAutofillableLogins(forms)) {
if (forms->size() > 0)
allow_fallback_ = false;
return true;
}
if (allow_default_store())
return PasswordStoreDefault::FillAutofillableLogins(forms);
return false;
}
bool PasswordStoreX::FillBlacklistLogins(vector<PasswordForm*>* forms) {
CheckMigration();
if (use_native_backend() && backend_->GetBlacklistLogins(forms)) {
if (forms->size() > 0)
allow_fallback_ = false;
return true;
}
if (allow_default_store())
return PasswordStoreDefault::FillBlacklistLogins(forms);
return false;
}
void PasswordStoreX::CheckMigration() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
if (migration_checked_ || !backend_.get())
return;
migration_checked_ = true;
ssize_t migrated = MigrateLogins();
if (migrated > 0) {
VLOG(1) << "Migrated " << migrated << " passwords to native store.";
} else if (migrated == 0) {
allow_fallback_ = true;
} else {
LOG(WARNING) << "Native password store migration failed! " <<
"Falling back on default (unencrypted) store.";
backend_.reset(NULL);
}
}
bool PasswordStoreX::allow_default_store() {
if (allow_fallback_) {
LOG(WARNING) << "Native password store failed! " <<
"Falling back on default (unencrypted) store.";
backend_.reset(NULL);
allow_fallback_ = false;
}
return !backend_.get();
}
ssize_t PasswordStoreX::MigrateLogins() {
DCHECK(backend_.get());
vector<PasswordForm*> forms;
bool ok = PasswordStoreDefault::FillAutofillableLogins(&forms) &&
PasswordStoreDefault::FillBlacklistLogins(&forms);
if (ok) {
for (size_t i = 0; i < forms.size(); ++i) {
if (!backend_->AddLogin(*forms[i])) {
ok = false;
break;
}
}
if (ok) {
for (size_t i = 0; i < forms.size(); ++i) {
PasswordStoreDefault::RemoveLoginImpl(*forms[i]);
}
DeleteAndRecreateDatabaseFile();
}
}
ssize_t result = ok ? forms.size() : -1;
STLDeleteElements(&forms);
return result;
}