Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / passwords / manage_passwords_state.cc
blob457b6ecc6838898f95ed668a2acb4e70abe49a58
1 // Copyright 2015 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/manage_passwords_state.h"
7 #include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
8 #include "components/password_manager/core/browser/password_form_manager.h"
9 #include "components/password_manager/core/browser/password_manager_client.h"
10 #include "components/password_manager/core/common/credential_manager_types.h"
12 using password_manager::PasswordFormManager;
13 using autofill::PasswordFormMap;
15 namespace {
17 // Converts the map with pointers or const pointers to the vector of const
18 // pointers.
19 template <typename T>
20 std::vector<const T*> MapToVector(
21 const std::map<base::string16, T*>& map) {
22 std::vector<const autofill::PasswordForm*> ret;
23 ret.reserve(map.size());
24 for (const auto& form_pair : map)
25 ret.push_back(form_pair.second);
26 return ret;
29 ScopedVector<const autofill::PasswordForm> DeepCopyMapToVector(
30 const PasswordFormMap& password_form_map) {
31 ScopedVector<const autofill::PasswordForm> ret;
32 ret.reserve(password_form_map.size());
33 for (const auto& form_pair : password_form_map)
34 ret.push_back(new autofill::PasswordForm(*form_pair.second));
35 return ret.Pass();
38 ScopedVector<const autofill::PasswordForm> ConstifyVector(
39 ScopedVector<autofill::PasswordForm>* forms) {
40 ScopedVector<const autofill::PasswordForm> ret;
41 ret.assign(forms->begin(), forms->end());
42 forms->weak_clear();
43 return ret.Pass();
46 // True if the unique keys for the forms are the same. The unique key is
47 // (origin, username_element, username_value, password_element, signon_realm).
48 bool IsEqualUniqueKey(const autofill::PasswordForm& left,
49 const autofill::PasswordForm& right) {
50 return left.signon_realm == right.signon_realm &&
51 left.origin == right.origin &&
52 left.username_element == right.username_element &&
53 left.username_value == right.username_value &&
54 left.password_element == right.password_element;
57 // Updates one form in |forms| that has the same unique key as |updated_form|.
58 // Returns true if the form was found and updated.
59 bool UpdateFormInVector(const autofill::PasswordForm& updated_form,
60 ScopedVector<const autofill::PasswordForm>* forms) {
61 ScopedVector<const autofill::PasswordForm>::iterator it = std::find_if(
62 forms->begin(), forms->end(),
63 [&updated_form](const autofill::PasswordForm* form) {
64 return IsEqualUniqueKey(*form, updated_form);
65 });
66 if (it != forms->end()) {
67 delete *it;
68 *it = new autofill::PasswordForm(updated_form);
69 return true;
71 return false;
74 // Removes a form from |forms| that has the same unique key as |form_to_delete|.
75 template <class Vector>
76 void RemoveFormFromVector(const autofill::PasswordForm& form_to_delete,
77 Vector* forms) {
78 typename Vector::iterator it = std::find_if(
79 forms->begin(), forms->end(),
80 [&form_to_delete](const autofill::PasswordForm* form) {
81 return IsEqualUniqueKey(*form, form_to_delete);
82 });
83 if (it != forms->end())
84 forms->erase(it);
87 // Inserts |form| to the beginning of |forms| if it's blacklisted or to the end
88 // otherwise. UnblacklistSite() expects the first saved password to be the
89 // blacklisted credential.
90 template <class Vector>
91 void InsertFormToVector(const autofill::PasswordForm* form,
92 Vector* forms) {
93 typename Vector::iterator it = form->blacklisted_by_user ? forms->begin()
94 : forms->end();
95 forms->insert(it, form);
98 } // namespace
100 ManagePasswordsState::ManagePasswordsState()
101 : state_(password_manager::ui::INACTIVE_STATE),
102 client_(nullptr) {
105 ManagePasswordsState::~ManagePasswordsState() {}
107 void ManagePasswordsState::OnPendingPassword(
108 scoped_ptr<password_manager::PasswordFormManager> form_manager) {
109 ClearData();
110 form_manager_ = form_manager.Pass();
111 current_forms_weak_ = MapToVector(form_manager_->best_matches());
112 origin_ = form_manager_->pending_credentials().origin;
113 SetState(password_manager::ui::PENDING_PASSWORD_STATE);
116 void ManagePasswordsState::OnRequestCredentials(
117 ScopedVector<autofill::PasswordForm> local_credentials,
118 ScopedVector<autofill::PasswordForm> federated_credentials,
119 const GURL& origin) {
120 ClearData();
121 local_credentials_forms_ = ConstifyVector(&local_credentials);
122 federated_credentials_forms_ = ConstifyVector(&federated_credentials);
123 origin_ = origin;
124 SetState(password_manager::ui::CREDENTIAL_REQUEST_STATE);
127 void ManagePasswordsState::OnAutoSignin(
128 ScopedVector<autofill::PasswordForm> local_forms) {
129 DCHECK(!local_forms.empty());
130 ClearData();
131 local_credentials_forms_ = ConstifyVector(&local_forms);
132 origin_ = local_credentials_forms_[0]->origin;
133 SetState(password_manager::ui::AUTO_SIGNIN_STATE);
136 void ManagePasswordsState::OnAutomaticPasswordSave(
137 scoped_ptr<PasswordFormManager> form_manager) {
138 ClearData();
139 form_manager_ = form_manager.Pass();
140 autofill::ConstPasswordFormMap current_forms;
141 current_forms.insert(form_manager_->best_matches().begin(),
142 form_manager_->best_matches().end());
143 current_forms[form_manager_->associated_username()] =
144 &form_manager_->pending_credentials();
145 current_forms_weak_ = MapToVector(current_forms);
146 origin_ = form_manager_->pending_credentials().origin;
147 SetState(password_manager::ui::CONFIRMATION_STATE);
150 void ManagePasswordsState::OnPasswordAutofilled(
151 const PasswordFormMap& password_form_map) {
152 DCHECK(!password_form_map.empty());
153 ClearData();
154 if (password_form_map.begin()->second->IsPublicSuffixMatch()) {
155 // Don't show the UI for PSL matched passwords. They are not stored for this
156 // page and cannot be deleted.
157 origin_ = GURL();
158 SetState(password_manager::ui::INACTIVE_STATE);
159 } else {
160 local_credentials_forms_ = DeepCopyMapToVector(password_form_map);
161 origin_ = local_credentials_forms_.front()->origin;
162 SetState(password_manager::ui::MANAGE_STATE);
166 void ManagePasswordsState::OnBlacklistBlockedAutofill(
167 const autofill::PasswordFormMap& password_form_map) {
168 DCHECK(!password_form_map.empty());
169 ClearData();
170 local_credentials_forms_ = DeepCopyMapToVector(password_form_map);
171 origin_ = local_credentials_forms_.front()->origin;
172 DCHECK(local_credentials_forms_.front()->blacklisted_by_user);
173 SetState(password_manager::ui::BLACKLIST_STATE);
176 void ManagePasswordsState::OnInactive() {
177 ClearData();
178 origin_ = GURL();
179 SetState(password_manager::ui::INACTIVE_STATE);
182 void ManagePasswordsState::TransitionToState(
183 password_manager::ui::State state) {
184 DCHECK_NE(password_manager::ui::INACTIVE_STATE, state_);
185 DCHECK(state == password_manager::ui::BLACKLIST_STATE ||
186 state == password_manager::ui::MANAGE_STATE);
187 if (state_ == password_manager::ui::CREDENTIAL_REQUEST_STATE) {
188 if (!credentials_callback_.is_null()) {
189 credentials_callback_.Run(password_manager::CredentialInfo());
190 credentials_callback_.Reset();
192 federated_credentials_forms_.clear();
194 SetState(state);
197 void ManagePasswordsState::ProcessLoginsChanged(
198 const password_manager::PasswordStoreChangeList& changes) {
199 if (state() == password_manager::ui::INACTIVE_STATE)
200 return;
202 for (const password_manager::PasswordStoreChange& change : changes) {
203 const autofill::PasswordForm& changed_form = change.form();
204 if (change.type() == password_manager::PasswordStoreChange::REMOVE) {
205 DeleteForm(changed_form);
206 if (changed_form.blacklisted_by_user &&
207 state() == password_manager::ui::BLACKLIST_STATE &&
208 changed_form.origin == origin_) {
209 TransitionToState(password_manager::ui::MANAGE_STATE);
211 } else {
212 if (change.type() == password_manager::PasswordStoreChange::UPDATE)
213 UpdateForm(changed_form);
214 else
215 AddForm(changed_form);
216 if (changed_form.blacklisted_by_user &&
217 changed_form.origin == origin_) {
218 TransitionToState(password_manager::ui::BLACKLIST_STATE);
224 void ManagePasswordsState::ClearData() {
225 form_manager_.reset();
226 current_forms_weak_.clear();
227 local_credentials_forms_.clear();
228 federated_credentials_forms_.clear();
229 credentials_callback_.Reset();
232 void ManagePasswordsState::AddForm(const autofill::PasswordForm& form) {
233 if (form.origin != origin_)
234 return;
235 if (UpdateForm(form))
236 return;
237 if (form_manager_) {
238 local_credentials_forms_.push_back(new autofill::PasswordForm(form));
239 InsertFormToVector(local_credentials_forms_.back(), &current_forms_weak_);
240 } else {
241 InsertFormToVector(new autofill::PasswordForm(form),
242 &local_credentials_forms_);
246 bool ManagePasswordsState::UpdateForm(const autofill::PasswordForm& form) {
247 if (form_manager_) {
248 // |current_forms_weak_| contains the list of current passwords.
249 std::vector<const autofill::PasswordForm*>::iterator it = std::find_if(
250 current_forms_weak_.begin(), current_forms_weak_.end(),
251 [&form](const autofill::PasswordForm* current_form) {
252 return IsEqualUniqueKey(form, *current_form);
254 if (it != current_forms_weak_.end()) {
255 RemoveFormFromVector(form, &local_credentials_forms_);
256 local_credentials_forms_.push_back(new autofill::PasswordForm(form));
257 *it = local_credentials_forms_.back();
258 return true;
260 } else {
261 // |current_forms_weak_| isn't used.
262 bool updated_locals = UpdateFormInVector(form, &local_credentials_forms_);
263 return (UpdateFormInVector(form, &federated_credentials_forms_) ||
264 updated_locals);
266 return false;
269 void ManagePasswordsState::DeleteForm(const autofill::PasswordForm& form) {
270 RemoveFormFromVector(form, &current_forms_weak_);
271 RemoveFormFromVector(form, &local_credentials_forms_);
272 RemoveFormFromVector(form, &federated_credentials_forms_);
275 void ManagePasswordsState::SetState(password_manager::ui::State state) {
276 DCHECK(client_);
277 if (client_->IsLoggingActive()) {
278 password_manager::BrowserSavePasswordProgressLogger logger(client_);
279 logger.LogNumber(
280 autofill::SavePasswordProgressLogger::STRING_NEW_UI_STATE,
281 state);
283 state_ = state;