app_shell: Add version number in user agent
[chromium-blink-merge.git] / chrome / browser / ui / passwords / password_manager_presenter.cc
blob52d2eb80ef518a453732bff1da87088fde0da24f
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"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/metrics/user_metrics_action.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
13 #include "base/values.h"
14 #include "chrome/browser/password_manager/password_manager_util.h"
15 #include "chrome/browser/password_manager/password_store_factory.h"
16 #include "chrome/browser/password_manager/sync_metrics.h"
17 #include "chrome/browser/ui/passwords/password_ui_view.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/url_constants.h"
20 #include "components/autofill/core/common/password_form.h"
21 #include "components/password_manager/core/common/password_manager_pref_names.h"
22 #include "content/public/browser/user_metrics.h"
23 #include "content/public/browser/web_contents.h"
25 using password_manager::PasswordStore;
27 PasswordManagerPresenter::PasswordManagerPresenter(
28 PasswordUIView* password_view)
29 : populater_(this),
30 exception_populater_(this),
31 password_view_(password_view) {
32 DCHECK(password_view_);
33 require_reauthentication_ = !CommandLine::ForCurrentProcess()->HasSwitch(
34 switches::kDisablePasswordManagerReauthentication);
37 PasswordManagerPresenter::~PasswordManagerPresenter() {
38 PasswordStore* store = GetPasswordStore();
39 if (store)
40 store->RemoveObserver(this);
43 void PasswordManagerPresenter::Initialize() {
44 // Due to the way that handlers are (re)initialized under certain types of
45 // navigation, the presenter may already be initialized. (See bugs 88986
46 // and 86448). If this is the case, return immediately. This is a hack.
47 // TODO(mdm): remove this hack once it is no longer necessary.
48 if (!show_passwords_.GetPrefName().empty())
49 return;
51 show_passwords_.Init(
52 password_manager::prefs::kPasswordManagerAllowShowPasswords,
53 password_view_->GetProfile()->GetPrefs(),
54 base::Bind(&PasswordManagerPresenter::UpdatePasswordLists,
55 base::Unretained(this)));
56 // TODO(jhawkins) We should not cache web_ui()->GetProfile().See
57 // crosbug.com/6304.
58 PasswordStore* store = GetPasswordStore();
59 if (store)
60 store->AddObserver(this);
63 void PasswordManagerPresenter::OnLoginsChanged(
64 const password_manager::PasswordStoreChangeList& changes) {
65 // Entire list is updated for convenience.
66 UpdatePasswordLists();
69 PasswordStore* PasswordManagerPresenter::GetPasswordStore() {
70 return PasswordStoreFactory::GetForProfile(password_view_->GetProfile(),
71 Profile::EXPLICIT_ACCESS).get();
74 void PasswordManagerPresenter::UpdatePasswordLists() {
75 // Reset so that showing a password will require re-authentication.
76 last_authentication_time_ = base::TimeTicks();
78 // Reset the current lists.
79 password_list_.clear();
80 password_exception_list_.clear();
82 populater_.Populate();
83 exception_populater_.Populate();
86 void PasswordManagerPresenter::RemoveSavedPassword(size_t index) {
87 if (index >= password_list_.size()) {
88 // |index| out of bounds might come from a compromised renderer, don't let
89 // it crash the browser. http://crbug.com/362054
90 NOTREACHED();
91 return;
93 PasswordStore* store = GetPasswordStore();
94 if (!store)
95 return;
96 store->RemoveLogin(*password_list_[index]);
97 content::RecordAction(
98 base::UserMetricsAction("PasswordManager_RemoveSavedPassword"));
101 void PasswordManagerPresenter::RemovePasswordException(size_t index) {
102 if (index >= password_exception_list_.size()) {
103 // |index| out of bounds might come from a compromised renderer, don't let
104 // it crash the browser. http://crbug.com/362054
105 NOTREACHED();
106 return;
108 PasswordStore* store = GetPasswordStore();
109 if (!store)
110 return;
111 store->RemoveLogin(*password_exception_list_[index]);
112 content::RecordAction(
113 base::UserMetricsAction("PasswordManager_RemovePasswordException"));
116 void PasswordManagerPresenter::RequestShowPassword(size_t index) {
117 #if !defined(OS_ANDROID) // This is never called on Android.
118 if (index >= password_list_.size()) {
119 // |index| out of bounds might come from a compromised renderer, don't let
120 // it crash the browser. http://crbug.com/362054
121 NOTREACHED();
122 return;
124 if (IsAuthenticationRequired()) {
125 if (password_manager_util::AuthenticateUser(
126 password_view_->GetNativeWindow()))
127 last_authentication_time_ = base::TimeTicks::Now();
128 else
129 return;
132 if (password_manager_sync_metrics::IsSyncAccountCredential(
133 password_view_->GetProfile(),
134 base::UTF16ToUTF8(password_list_[index]->username_value),
135 password_list_[index]->signon_realm)) {
136 content::RecordAction(
137 base::UserMetricsAction("PasswordManager_SyncCredentialShown"));
140 // Call back the front end to reveal the password.
141 password_view_->ShowPassword(index, password_list_[index]->password_value);
142 #endif
145 const autofill::PasswordForm* PasswordManagerPresenter::GetPassword(
146 size_t index) {
147 if (index >= password_list_.size()) {
148 // |index| out of bounds might come from a compromised renderer, don't let
149 // it crash the browser. http://crbug.com/362054
150 NOTREACHED();
151 return NULL;
153 return password_list_[index];
156 const autofill::PasswordForm* PasswordManagerPresenter::GetPasswordException(
157 size_t index) {
158 if (index >= password_exception_list_.size()) {
159 // |index| out of bounds might come from a compromised renderer, don't let
160 // it crash the browser. http://crbug.com/362054
161 NOTREACHED();
162 return NULL;
164 return password_exception_list_[index];
167 void PasswordManagerPresenter::SetPasswordList() {
168 // Due to the way that handlers are (re)initialized under certain types of
169 // navigation, the presenter may already be initialized. (See bugs 88986
170 // and 86448). If this is the case, return immediately. This is a hack.
171 // If this is the case, initialize on demand. This is a hack.
172 // TODO(mdm): remove this hack once it is no longer necessary.
173 if (show_passwords_.GetPrefName().empty())
174 Initialize();
176 bool show_passwords = *show_passwords_ && !require_reauthentication_;
177 password_view_->SetPasswordList(password_list_, show_passwords);
180 void PasswordManagerPresenter::SetPasswordExceptionList() {
181 password_view_->SetPasswordExceptionList(password_exception_list_);
184 bool PasswordManagerPresenter::IsAuthenticationRequired() {
185 base::TimeDelta delta = base::TimeDelta::FromSeconds(60);
186 return require_reauthentication_ &&
187 (base::TimeTicks::Now() - last_authentication_time_) > delta;
190 PasswordManagerPresenter::ListPopulater::ListPopulater(
191 PasswordManagerPresenter* page) : page_(page) {
194 PasswordManagerPresenter::ListPopulater::~ListPopulater() {
197 PasswordManagerPresenter::PasswordListPopulater::PasswordListPopulater(
198 PasswordManagerPresenter* page) : ListPopulater(page) {
201 void PasswordManagerPresenter::PasswordListPopulater::Populate() {
202 PasswordStore* store = page_->GetPasswordStore();
203 if (store != NULL) {
204 cancelable_task_tracker()->TryCancelAll();
205 store->GetAutofillableLogins(this);
206 } else {
207 LOG(ERROR) << "No password store! Cannot display passwords.";
211 void PasswordManagerPresenter::PasswordListPopulater::OnGetPasswordStoreResults(
212 const std::vector<autofill::PasswordForm*>& results) {
213 page_->password_list_.clear();
214 page_->password_list_.insert(page_->password_list_.end(),
215 results.begin(), results.end());
216 page_->SetPasswordList();
219 PasswordManagerPresenter::PasswordExceptionListPopulater::
220 PasswordExceptionListPopulater(PasswordManagerPresenter* page)
221 : ListPopulater(page) {
224 void PasswordManagerPresenter::PasswordExceptionListPopulater::Populate() {
225 PasswordStore* store = page_->GetPasswordStore();
226 if (store != NULL) {
227 cancelable_task_tracker()->TryCancelAll();
228 store->GetBlacklistLogins(this);
229 } else {
230 LOG(ERROR) << "No password store! Cannot display exceptions.";
234 void PasswordManagerPresenter::PasswordExceptionListPopulater::
235 OnGetPasswordStoreResults(
236 const std::vector<autofill::PasswordForm*>& results) {
237 page_->password_exception_list_.clear();
238 page_->password_exception_list_.insert(page_->password_exception_list_.end(),
239 results.begin(), results.end());
240 page_->SetPasswordExceptionList();