[go: nahoru, domu]

blob: a33d867d7a73d428bcf368c817d6eacaea45fc8f [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/browsing_data/core/counters/passwords_counter.h"
#include <algorithm>
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/time/time.h"
#include "components/browsing_data/core/pref_names.h"
#include "components/password_manager/core/browser/password_manager_util.h"
#include "components/password_manager/core/browser/password_store_change.h"
#include "components/password_manager/core/browser/password_store_interface.h"
#include "components/sync/driver/sync_service.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "url/gurl.h"
namespace browsing_data {
namespace {
bool IsPasswordSyncEnabled(const syncer::SyncService* sync_service) {
if (!sync_service)
return false;
switch (password_manager_util::GetPasswordSyncState(sync_service)) {
case password_manager::SyncState::kNotSyncing:
case password_manager::SyncState::kAccountPasswordsActiveNormalEncryption:
return false;
case password_manager::SyncState::kSyncingNormalEncryption:
case password_manager::SyncState::kSyncingWithCustomPassphrase:
return true;
}
}
// PasswordStoreFetcher ----------------------------------
// Fetches passswords and observes a PasswordStoreInterface.
class PasswordStoreFetcher
: public password_manager::PasswordStoreConsumer,
public password_manager::PasswordStoreInterface::Observer {
public:
PasswordStoreFetcher(
scoped_refptr<password_manager::PasswordStoreInterface> store,
base::RepeatingClosure logins_changed_closure);
~PasswordStoreFetcher() override;
void Fetch(base::Time start,
base::Time end,
base::OnceClosure fetch_complete);
void OnGetPasswordStoreResults(
std::vector<std::unique_ptr<password_manager::PasswordForm>> results)
override;
// Called when the contents of the password store change. Triggers new
// counting.
// PasswordStoreInterface::Observer:
void OnLoginsChanged(
password_manager::PasswordStoreInterface* store,
const password_manager::PasswordStoreChangeList& changes) override;
void OnLoginsRetained(password_manager::PasswordStoreInterface* store,
const std::vector<password_manager::PasswordForm>&
retained_passwords) override;
int num_passwords() { return num_passwords_; }
const std::vector<std::string>& domain_examples() { return domain_examples_; }
private:
void CancelAllRequests();
scoped_refptr<password_manager::PasswordStoreInterface> store_;
base::RepeatingClosure logins_changed_closure_;
base::OnceClosure fetch_complete_;
base::Time start_;
base::Time end_;
int num_passwords_ = 0;
std::vector<std::string> domain_examples_;
base::WeakPtrFactory<PasswordStoreFetcher> weak_ptr_factory_{this};
};
PasswordStoreFetcher::PasswordStoreFetcher(
scoped_refptr<password_manager::PasswordStoreInterface> store,
base::RepeatingClosure logins_changed_closure)
: store_(store), logins_changed_closure_(logins_changed_closure) {
if (store_)
store_->AddObserver(this);
}
PasswordStoreFetcher::~PasswordStoreFetcher() {
if (store_)
store_->RemoveObserver(this);
}
void PasswordStoreFetcher::OnLoginsChanged(
password_manager::PasswordStoreInterface* /*store*/,
const password_manager::PasswordStoreChangeList& /*changes*/) {
logins_changed_closure_.Run();
}
void PasswordStoreFetcher::OnLoginsRetained(
password_manager::PasswordStoreInterface* /*store*/,
const std::vector<password_manager::PasswordForm>& /*retained_passwords*/) {
logins_changed_closure_.Run();
}
void PasswordStoreFetcher::Fetch(base::Time start,
base::Time end,
base::OnceClosure fetch_complete) {
CancelAllRequests();
start_ = start;
end_ = end;
fetch_complete_ = std::move(fetch_complete);
if (store_) {
store_->GetAutofillableLogins(weak_ptr_factory_.GetWeakPtr());
} else {
std::move(fetch_complete_).Run();
}
}
void PasswordStoreFetcher::OnGetPasswordStoreResults(
std::vector<std::unique_ptr<password_manager::PasswordForm>> results) {
domain_examples_.clear();
results.erase(
std::remove_if(
results.begin(), results.end(),
[this](const std::unique_ptr<password_manager::PasswordForm>& form) {
return (form->date_created < start_ || form->date_created >= end_);
}),
results.end());
num_passwords_ = results.size();
std::sort(results.begin(), results.end(),
[](const std::unique_ptr<password_manager::PasswordForm>& a,
const std::unique_ptr<password_manager::PasswordForm>& b) {
return a->times_used > b->times_used;
});
std::vector<std::string> sorted_domains;
for (const auto& result : results) {
std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
result->url,
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
if (domain.empty())
domain = result->url.host();
sorted_domains.emplace_back(domain);
}
// Only consecutive duplicates are removed below. Since we're only listing two
// example domains, this guarantees that the two examples given will not be
// the same, but there may still be duplicate domains stored in the
// sorted_domains vector.
sorted_domains.erase(
std::unique(sorted_domains.begin(), sorted_domains.end()),
sorted_domains.end());
if (sorted_domains.size() > 0)
domain_examples_.emplace_back(sorted_domains[0]);
if (sorted_domains.size() > 1)
domain_examples_.emplace_back(sorted_domains[1]);
std::move(fetch_complete_).Run();
}
void PasswordStoreFetcher::CancelAllRequests() {
cancelable_task_tracker()->TryCancelAll();
weak_ptr_factory_.InvalidateWeakPtrs();
}
} // namespace
// PasswordsCounter::PasswordsResult ----------------------------------
PasswordsCounter::PasswordsResult::PasswordsResult(
const BrowsingDataCounter* source,
ResultInt profile_passwords,
ResultInt account_passwords,
bool sync_enabled,
std::vector<std::string> domain_examples,
std::vector<std::string> account_domain_examples)
: SyncResult(source, profile_passwords, sync_enabled),
account_passwords_(account_passwords),
domain_examples_(std::move(domain_examples)),
account_domain_examples_(std::move(account_domain_examples)) {}
PasswordsCounter::PasswordsResult::~PasswordsResult() = default;
// PasswordsCounter ----------------------------------
PasswordsCounter::PasswordsCounter(
scoped_refptr<password_manager::PasswordStoreInterface> profile_store,
scoped_refptr<password_manager::PasswordStoreInterface> account_store,
syncer::SyncService* sync_service)
: sync_tracker_(this, sync_service) {
profile_store_fetcher_ = std::make_unique<PasswordStoreFetcher>(
profile_store,
base::BindRepeating(&PasswordsCounter::Restart, base::Unretained(this))),
account_store_fetcher_ = std::make_unique<PasswordStoreFetcher>(
account_store,
base::BindRepeating(&PasswordsCounter::Restart, base::Unretained(this)));
DCHECK(profile_store);
// |account_store| may be null.
}
PasswordsCounter::~PasswordsCounter() = default;
int PasswordsCounter::num_passwords() {
return profile_store_fetcher_->num_passwords();
}
int PasswordsCounter::num_account_passwords() {
return account_store_fetcher_->num_passwords();
}
const std::vector<std::string>& PasswordsCounter::domain_examples() {
return profile_store_fetcher_->domain_examples();
}
const std::vector<std::string>& PasswordsCounter::account_domain_examples() {
return account_store_fetcher_->domain_examples();
}
void PasswordsCounter::OnInitialized() {
sync_tracker_.OnInitialized(base::BindRepeating(&IsPasswordSyncEnabled));
}
const char* PasswordsCounter::GetPrefName() const {
return browsing_data::prefs::kDeletePasswords;
}
void PasswordsCounter::Count() {
remaining_tasks_ = 2;
profile_store_fetcher_->Fetch(
GetPeriodStart(), GetPeriodEnd(),
base::BindOnce(&PasswordsCounter::OnFetchDone, base::Unretained(this)));
account_store_fetcher_->Fetch(
GetPeriodStart(), GetPeriodEnd(),
base::BindOnce(&PasswordsCounter::OnFetchDone, base::Unretained(this)));
}
void PasswordsCounter::OnPasswordsFetchDone() {
ReportResult(MakeResult());
}
std::unique_ptr<PasswordsCounter::PasswordsResult>
PasswordsCounter::MakeResult() {
DCHECK(!(is_sync_active() && num_account_passwords() > 0));
return std::make_unique<PasswordsCounter::PasswordsResult>(
this, num_passwords(), num_account_passwords(), is_sync_active(),
domain_examples(), account_domain_examples());
}
void PasswordsCounter::OnFetchDone() {
if (--remaining_tasks_ == 0)
OnPasswordsFetchDone();
}
} // namespace browsing_data