1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/passwords/password_manager_presenter.h"
8 #include "base/command_line.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/time/time.h"
11 #include "base/values.h"
12 #include "chrome/browser/password_manager/password_manager_util.h"
13 #include "chrome/browser/password_manager/password_store_factory.h"
14 #include "chrome/browser/ui/passwords/password_ui_view.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/common/url_constants.h"
18 #include "components/autofill/core/common/password_form.h"
19 #include "content/public/browser/user_metrics.h"
20 #include "content/public/browser/web_contents.h"
22 PasswordManagerPresenter::PasswordManagerPresenter(
23 PasswordUIView* password_view)
25 exception_populater_(this),
26 password_view_(password_view) {
27 DCHECK(password_view_);
28 require_reauthentication_ = !CommandLine::ForCurrentProcess()->HasSwitch(
29 switches::kDisablePasswordManagerReauthentication);
32 PasswordManagerPresenter::~PasswordManagerPresenter() {
33 PasswordStore* store = GetPasswordStore();
35 store->RemoveObserver(this);
38 void PasswordManagerPresenter::Initialize() {
39 // Due to the way that handlers are (re)initialized under certain types of
40 // navigation, the presenter may already be initialized. (See bugs 88986
41 // and 86448). If this is the case, return immediately. This is a hack.
42 // TODO(mdm): remove this hack once it is no longer necessary.
43 if (!show_passwords_.GetPrefName().empty())
47 prefs::kPasswordManagerAllowShowPasswords,
48 password_view_->GetProfile()->GetPrefs(),
49 base::Bind(&PasswordManagerPresenter::UpdatePasswordLists,
50 base::Unretained(this)));
51 // TODO(jhawkins) We should not cache web_ui()->GetProfile().See
53 PasswordStore* store = GetPasswordStore();
55 store->AddObserver(this);
58 void PasswordManagerPresenter::OnLoginsChanged(
59 const PasswordStoreChangeList& changes) {
60 // Entire list is updated for convenience.
61 UpdatePasswordLists();
64 PasswordStore* PasswordManagerPresenter::GetPasswordStore() {
65 return PasswordStoreFactory::GetForProfile(password_view_->GetProfile(),
66 Profile::EXPLICIT_ACCESS).get();
69 void PasswordManagerPresenter::UpdatePasswordLists() {
70 // Reset so that showing a password will require re-authentication.
71 last_authentication_time_ = base::TimeTicks();
73 // Reset the current lists.
74 password_list_.clear();
75 password_exception_list_.clear();
77 populater_.Populate();
78 exception_populater_.Populate();
81 void PasswordManagerPresenter::RemoveSavedPassword(size_t index) {
82 DCHECK_LT(index, password_list_.size());
83 PasswordStore* store = GetPasswordStore();
86 store->RemoveLogin(*password_list_[index]);
87 content::RecordAction(
88 base::UserMetricsAction("PasswordManager_RemoveSavedPassword"));
91 void PasswordManagerPresenter::RemovePasswordException(size_t index) {
92 DCHECK_LT(index, password_exception_list_.size());
93 PasswordStore* store = GetPasswordStore();
96 store->RemoveLogin(*password_exception_list_[index]);
97 content::RecordAction(
98 base::UserMetricsAction("PasswordManager_RemovePasswordException"));
101 void PasswordManagerPresenter::RequestShowPassword(size_t index) {
102 #if !defined(OS_ANDROID) // This is never called on Android.
103 DCHECK_LT(index, password_list_.size());
104 if (IsAuthenticationRequired()) {
105 if (password_manager_util::AuthenticateUser(
106 password_view_->GetNativeWindow()))
107 last_authentication_time_ = base::TimeTicks::Now();
111 // Call back the front end to reveal the password.
112 password_view_->ShowPassword(index, password_list_[index]->password_value);
116 const autofill::PasswordForm& PasswordManagerPresenter::GetPassword(
118 DCHECK_LT(index, password_list_.size());
119 return *password_list_[index];
122 const autofill::PasswordForm& PasswordManagerPresenter::GetPasswordException(
124 DCHECK_LT(index, password_exception_list_.size());
125 return *password_exception_list_[index];
128 void PasswordManagerPresenter::SetPasswordList() {
129 // Due to the way that handlers are (re)initialized under certain types of
130 // navigation, the presenter may already be initialized. (See bugs 88986
131 // and 86448). If this is the case, return immediately. This is a hack.
132 // If this is the case, initialize on demand. This is a hack.
133 // TODO(mdm): remove this hack once it is no longer necessary.
134 if (show_passwords_.GetPrefName().empty())
137 bool show_passwords = *show_passwords_ && !require_reauthentication_;
138 password_view_->SetPasswordList(password_list_, show_passwords);
141 void PasswordManagerPresenter::SetPasswordExceptionList() {
142 password_view_->SetPasswordExceptionList(password_exception_list_);
145 bool PasswordManagerPresenter::IsAuthenticationRequired() {
146 base::TimeDelta delta = base::TimeDelta::FromSeconds(60);
147 return require_reauthentication_ &&
148 (base::TimeTicks::Now() - last_authentication_time_) > delta;
151 PasswordManagerPresenter::ListPopulater::ListPopulater(
152 PasswordManagerPresenter* page) : page_(page) {
155 PasswordManagerPresenter::ListPopulater::~ListPopulater() {
158 PasswordManagerPresenter::PasswordListPopulater::PasswordListPopulater(
159 PasswordManagerPresenter* page) : ListPopulater(page) {
162 void PasswordManagerPresenter::PasswordListPopulater::Populate() {
163 PasswordStore* store = page_->GetPasswordStore();
165 cancelable_task_tracker()->TryCancelAll();
166 store->GetAutofillableLogins(this);
168 LOG(ERROR) << "No password store! Cannot display passwords.";
172 void PasswordManagerPresenter::PasswordListPopulater::OnGetPasswordStoreResults(
173 const std::vector<autofill::PasswordForm*>& results) {
174 page_->password_list_.clear();
175 page_->password_list_.insert(page_->password_list_.end(),
176 results.begin(), results.end());
177 page_->SetPasswordList();
180 PasswordManagerPresenter::PasswordExceptionListPopulater::
181 PasswordExceptionListPopulater(PasswordManagerPresenter* page)
182 : ListPopulater(page) {
185 void PasswordManagerPresenter::PasswordExceptionListPopulater::Populate() {
186 PasswordStore* store = page_->GetPasswordStore();
188 cancelable_task_tracker()->TryCancelAll();
189 store->GetBlacklistLogins(this);
191 LOG(ERROR) << "No password store! Cannot display exceptions.";
195 void PasswordManagerPresenter::PasswordExceptionListPopulater::
196 OnGetPasswordStoreResults(
197 const std::vector<autofill::PasswordForm*>& results) {
198 page_->password_exception_list_.clear();
199 page_->password_exception_list_.insert(page_->password_exception_list_.end(),
200 results.begin(), results.end());
201 page_->SetPasswordExceptionList();