| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "chrome/browser/ui/webui/options/password_manager_presenter.h" | |
| 6 | |
| 7 #include "base/bind.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/password/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 | |
| 21 namespace options { | |
| 22 | |
| 23 PasswordManagerPresenter::PasswordManagerPresenter( | |
| 24 passwords_ui::PasswordUIView* password_view) | |
| 25 : populater_(this), | |
| 26 exception_populater_(this), | |
| 27 password_view_(password_view) { | |
| 28 DCHECK(password_view_); | |
| 29 require_reauthentication_ = CommandLine::ForCurrentProcess()->HasSwitch( | |
| 30 switches::kEnablePasswordManagerReauthentication); | |
| 31 } | |
| 32 | |
| 33 PasswordManagerPresenter::~PasswordManagerPresenter() { | |
| 34 PasswordStore* store = GetPasswordStore(); | |
| 35 if (store) | |
| 36 store->RemoveObserver(this); | |
| 37 } | |
| 38 | |
| 39 void PasswordManagerPresenter::Initialize() { | |
| 40 // Due to the way that handlers are (re)initialized under certain types of | |
| 41 // navigation, the presenter may already be initialized. (See bugs 88986 | |
| 42 // and 86448). If this is the case, return immediately. This is a hack. | |
| 43 // TODO(mdm): remove this hack once it is no longer necessary. | |
| 44 if (!show_passwords_.GetPrefName().empty()) | |
| 45 return; | |
| 46 | |
| 47 show_passwords_.Init( | |
| 48 prefs::kPasswordManagerAllowShowPasswords, | |
| 49 password_view_->GetProfile()->GetPrefs(), | |
| 50 base::Bind(&PasswordManagerPresenter::UpdatePasswordLists, | |
| 51 base::Unretained(this))); | |
| 52 // TODO(jhawkins) We should not cache web_ui()->GetProfile().See | |
| 53 // crosbug.com/6304. | |
| 54 PasswordStore* store = GetPasswordStore(); | |
| 55 if (store) | |
| 56 store->AddObserver(this); | |
| 57 } | |
| 58 | |
| 59 void PasswordManagerPresenter::OnLoginsChanged() { | |
| 60 UpdatePasswordLists(); | |
| 61 } | |
| 62 | |
| 63 PasswordStore* PasswordManagerPresenter::GetPasswordStore() { | |
| 64 return PasswordStoreFactory::GetForProfile(password_view_->GetProfile(), | |
| 65 Profile::EXPLICIT_ACCESS).get(); | |
| 66 } | |
| 67 | |
| 68 void PasswordManagerPresenter::UpdatePasswordLists() { | |
| 69 // Reset the current lists. | |
| 70 password_list_.clear(); | |
| 71 password_exception_list_.clear(); | |
| 72 | |
| 73 populater_.Populate(); | |
| 74 exception_populater_.Populate(); | |
| 75 } | |
| 76 | |
| 77 void PasswordManagerPresenter::HandleRemoveSavedPassword(size_t index) { | |
| 78 DCHECK_LT(index, password_list_.size()); | |
| 79 PasswordStore* store = GetPasswordStore(); | |
| 80 if (!store) | |
| 81 return; | |
| 82 store->RemoveLogin(*password_list_[index]); | |
| 83 content::RecordAction( | |
| 84 content::UserMetricsAction("PasswordManager_HandleRemoveSavedPassword")); | |
| 85 } | |
| 86 | |
| 87 void PasswordManagerPresenter::HandleRemovePasswordException(size_t index) { | |
| 88 DCHECK_LT(index, password_exception_list_.size()); | |
| 89 PasswordStore* store = GetPasswordStore(); | |
| 90 if (!store) | |
| 91 return; | |
| 92 store->RemoveLogin(*password_exception_list_[index]); | |
| 93 content::RecordAction( | |
| 94 content::UserMetricsAction( | |
| 95 "PasswordManager_HandleRemovePasswordException")); | |
| 96 } | |
| 97 | |
| 98 void PasswordManagerPresenter::HandleRequestShowPassword(size_t index) { | |
| 99 DCHECK_LT(index, password_list_.size()); | |
| 100 if (IsAuthenticationRequired()) { | |
| 101 if (password_manager_util::AuthenticateUser()) | |
| 102 last_authentication_time_ = base::TimeTicks::Now(); | |
| 103 else | |
| 104 return; | |
| 105 } | |
| 106 // Call back the front end to reveal the password. | |
| 107 password_view_->ShowPassword(index, password_list_[index]->password_value); | |
| 108 } | |
| 109 | |
| 110 const autofill::PasswordForm& PasswordManagerPresenter::GetPassword( | |
| 111 size_t index) { | |
| 112 DCHECK_LT(index, password_list_.size()); | |
| 113 return *password_list_[index]; | |
| 114 } | |
| 115 | |
| 116 const autofill::PasswordForm& PasswordManagerPresenter::GetPasswordException( | |
| 117 size_t index) { | |
| 118 DCHECK_LT(index, password_exception_list_.size()); | |
| 119 return *password_exception_list_[index]; | |
| 120 } | |
| 121 | |
| 122 void PasswordManagerPresenter::SetPasswordList() { | |
| 123 // Due to the way that handlers are (re)initialized under certain types of | |
| 124 // navigation, the presenter may already be initialized. (See bugs 88986 | |
| 125 // and 86448). If this is the case, return immediately. This is a hack. | |
| 126 // If this is the case, initialize on demand. This is a hack. | |
| 127 // TODO(mdm): remove this hack once it is no longer necessary. | |
| 128 if (show_passwords_.GetPrefName().empty()) | |
| 129 Initialize(); | |
| 130 | |
| 131 bool show_passwords = *show_passwords_ && !require_reauthentication_; | |
| 132 password_view_->SetPasswordList(password_list_, show_passwords); | |
| 133 } | |
| 134 | |
| 135 void PasswordManagerPresenter::SetPasswordExceptionList() { | |
| 136 password_view_->SetPasswordExceptionList(password_exception_list_); | |
| 137 } | |
| 138 | |
| 139 bool PasswordManagerPresenter::IsAuthenticationRequired() { | |
| 140 base::TimeDelta delta = base::TimeDelta::FromSeconds(60); | |
| 141 return require_reauthentication_ && | |
| 142 (base::TimeTicks::Now() - last_authentication_time_) > delta; | |
| 143 } | |
| 144 | |
| 145 PasswordManagerPresenter::ListPopulater::ListPopulater( | |
| 146 PasswordManagerPresenter* page) | |
| 147 : page_(page), | |
| 148 pending_login_query_(0) { | |
| 149 } | |
| 150 | |
| 151 PasswordManagerPresenter::ListPopulater::~ListPopulater() { | |
| 152 } | |
| 153 | |
| 154 PasswordManagerPresenter::PasswordListPopulater::PasswordListPopulater( | |
| 155 PasswordManagerPresenter* page) : ListPopulater(page) { | |
| 156 } | |
| 157 | |
| 158 void PasswordManagerPresenter::PasswordListPopulater::Populate() { | |
| 159 PasswordStore* store = page_->GetPasswordStore(); | |
| 160 if (store != NULL) { | |
| 161 if (pending_login_query_) | |
| 162 store->CancelRequest(pending_login_query_); | |
| 163 | |
| 164 pending_login_query_ = store->GetAutofillableLogins(this); | |
| 165 } else { | |
| 166 LOG(ERROR) << "No password store! Cannot display passwords."; | |
| 167 } | |
| 168 } | |
| 169 | |
| 170 void PasswordManagerPresenter::PasswordListPopulater:: | |
| 171 OnPasswordStoreRequestDone( | |
| 172 CancelableRequestProvider::Handle handle, | |
| 173 const std::vector<autofill::PasswordForm*>& result) { | |
| 174 DCHECK_EQ(pending_login_query_, handle); | |
| 175 pending_login_query_ = 0; | |
| 176 page_->password_list_.clear(); | |
| 177 page_->password_list_.insert(page_->password_list_.end(), | |
| 178 result.begin(), result.end()); | |
| 179 page_->SetPasswordList(); | |
| 180 } | |
| 181 | |
| 182 void PasswordManagerPresenter::PasswordListPopulater::OnGetPasswordStoreResults( | |
| 183 const std::vector<autofill::PasswordForm*>& results) { | |
| 184 // TODO(kaiwang): Implement when I refactor | |
| 185 // PasswordStore::GetAutofillableLogins and PasswordStore::GetBlacklistLogins. | |
| 186 NOTIMPLEMENTED(); | |
| 187 } | |
| 188 | |
| 189 PasswordManagerPresenter::PasswordExceptionListPopulater:: | |
| 190 PasswordExceptionListPopulater(PasswordManagerPresenter* page) | |
| 191 : ListPopulater(page) { | |
| 192 } | |
| 193 | |
| 194 void PasswordManagerPresenter::PasswordExceptionListPopulater::Populate() { | |
| 195 PasswordStore* store = page_->GetPasswordStore(); | |
| 196 if (store != NULL) { | |
| 197 if (pending_login_query_) | |
| 198 store->CancelRequest(pending_login_query_); | |
| 199 | |
| 200 pending_login_query_ = store->GetBlacklistLogins(this); | |
| 201 } else { | |
| 202 LOG(ERROR) << "No password store! Cannot display exceptions."; | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 void PasswordManagerPresenter::PasswordExceptionListPopulater:: | |
| 207 OnPasswordStoreRequestDone( | |
| 208 CancelableRequestProvider::Handle handle, | |
| 209 const std::vector<autofill::PasswordForm*>& result) { | |
| 210 DCHECK_EQ(pending_login_query_, handle); | |
| 211 pending_login_query_ = 0; | |
| 212 page_->password_exception_list_.clear(); | |
| 213 page_->password_exception_list_.insert(page_->password_exception_list_.end(), | |
| 214 result.begin(), result.end()); | |
| 215 page_->SetPasswordExceptionList(); | |
| 216 } | |
| 217 | |
| 218 void PasswordManagerPresenter::PasswordExceptionListPopulater:: | |
| 219 OnGetPasswordStoreResults( | |
| 220 const std::vector<autofill::PasswordForm*>& results) { | |
| 221 // TODO(kaiwang): Implement when I refactor | |
| 222 // PasswordStore::GetAutofillableLogins and PasswordStore::GetBlacklistLogins. | |
| 223 NOTIMPLEMENTED(); | |
| 224 } | |
| 225 | |
| 226 } // namespace options | |
| OLD | NEW |