Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / passwords / password_manager_presenter.cc
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/passwords/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/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"
21
22 PasswordManagerPresenter::PasswordManagerPresenter(
23     PasswordUIView* password_view)
24     : populater_(this),
25       exception_populater_(this),
26       password_view_(password_view) {
27   DCHECK(password_view_);
28   require_reauthentication_ = !CommandLine::ForCurrentProcess()->HasSwitch(
29       switches::kDisablePasswordManagerReauthentication);
30 }
31
32 PasswordManagerPresenter::~PasswordManagerPresenter() {
33   PasswordStore* store = GetPasswordStore();
34   if (store)
35     store->RemoveObserver(this);
36 }
37
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())
44     return;
45
46   show_passwords_.Init(
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
52   // crosbug.com/6304.
53   PasswordStore* store = GetPasswordStore();
54   if (store)
55     store->AddObserver(this);
56 }
57
58 void PasswordManagerPresenter::OnLoginsChanged(
59     const PasswordStoreChangeList& changes) {
60   // Entire list is updated for convenience.
61   UpdatePasswordLists();
62 }
63
64 PasswordStore* PasswordManagerPresenter::GetPasswordStore() {
65   return PasswordStoreFactory::GetForProfile(password_view_->GetProfile(),
66                                              Profile::EXPLICIT_ACCESS).get();
67 }
68
69 void PasswordManagerPresenter::UpdatePasswordLists() {
70   // Reset so that showing a password will require re-authentication.
71   last_authentication_time_ = base::TimeTicks();
72
73   // Reset the current lists.
74   password_list_.clear();
75   password_exception_list_.clear();
76
77   populater_.Populate();
78   exception_populater_.Populate();
79 }
80
81 void PasswordManagerPresenter::RemoveSavedPassword(size_t index) {
82   DCHECK_LT(index, password_list_.size());
83   PasswordStore* store = GetPasswordStore();
84   if (!store)
85     return;
86   store->RemoveLogin(*password_list_[index]);
87   content::RecordAction(
88       base::UserMetricsAction("PasswordManager_RemoveSavedPassword"));
89 }
90
91 void PasswordManagerPresenter::RemovePasswordException(size_t index) {
92   DCHECK_LT(index, password_exception_list_.size());
93   PasswordStore* store = GetPasswordStore();
94   if (!store)
95     return;
96   store->RemoveLogin(*password_exception_list_[index]);
97   content::RecordAction(
98       base::UserMetricsAction("PasswordManager_RemovePasswordException"));
99 }
100
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();
108     else
109       return;
110   }
111   // Call back the front end to reveal the password.
112   password_view_->ShowPassword(index, password_list_[index]->password_value);
113 #endif
114 }
115
116 const autofill::PasswordForm& PasswordManagerPresenter::GetPassword(
117     size_t index) {
118   DCHECK_LT(index, password_list_.size());
119   return *password_list_[index];
120 }
121
122 const autofill::PasswordForm& PasswordManagerPresenter::GetPasswordException(
123     size_t index) {
124   DCHECK_LT(index, password_exception_list_.size());
125   return *password_exception_list_[index];
126 }
127
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())
135     Initialize();
136
137   bool show_passwords = *show_passwords_ && !require_reauthentication_;
138   password_view_->SetPasswordList(password_list_, show_passwords);
139 }
140
141 void PasswordManagerPresenter::SetPasswordExceptionList() {
142   password_view_->SetPasswordExceptionList(password_exception_list_);
143 }
144
145 bool PasswordManagerPresenter::IsAuthenticationRequired() {
146   base::TimeDelta delta = base::TimeDelta::FromSeconds(60);
147   return require_reauthentication_ &&
148       (base::TimeTicks::Now() - last_authentication_time_) > delta;
149 }
150
151 PasswordManagerPresenter::ListPopulater::ListPopulater(
152     PasswordManagerPresenter* page) : page_(page) {
153 }
154
155 PasswordManagerPresenter::ListPopulater::~ListPopulater() {
156 }
157
158 PasswordManagerPresenter::PasswordListPopulater::PasswordListPopulater(
159     PasswordManagerPresenter* page) : ListPopulater(page) {
160 }
161
162 void PasswordManagerPresenter::PasswordListPopulater::Populate() {
163   PasswordStore* store = page_->GetPasswordStore();
164   if (store != NULL) {
165     cancelable_task_tracker()->TryCancelAll();
166     store->GetAutofillableLogins(this);
167   } else {
168     LOG(ERROR) << "No password store! Cannot display passwords.";
169   }
170 }
171
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();
178 }
179
180 PasswordManagerPresenter::PasswordExceptionListPopulater::
181     PasswordExceptionListPopulater(PasswordManagerPresenter* page)
182         : ListPopulater(page) {
183 }
184
185 void PasswordManagerPresenter::PasswordExceptionListPopulater::Populate() {
186   PasswordStore* store = page_->GetPasswordStore();
187   if (store != NULL) {
188     cancelable_task_tracker()->TryCancelAll();
189     store->GetBlacklistLogins(this);
190   } else {
191     LOG(ERROR) << "No password store! Cannot display exceptions.";
192   }
193 }
194
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();
202 }