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
;
17 // Returns a vector containing the values of a map.
18 template <typename Map
>
19 std::vector
<typename
Map::mapped_type
> MapToVector(const Map
& map
) {
20 std::vector
<typename
Map::mapped_type
> ret
;
21 ret
.reserve(map
.size());
22 for (const auto& form_pair
: map
)
23 ret
.push_back(form_pair
.second
);
27 // Takes a ScopedPtrMap. Returns a vector of non-owned pointers to the elements
28 // inside the scoped_ptrs.
29 template <typename Map
>
30 std::vector
<const typename
Map::mapped_type::element_type
*>
31 ScopedPtrMapToVector(const Map
& map
) {
32 std::vector
<const typename
Map::mapped_type::element_type
*> ret
;
33 ret
.reserve(map
.size());
34 for (const auto& form_pair
: map
)
35 ret
.push_back(form_pair
.second
);
39 ScopedVector
<const autofill::PasswordForm
> DeepCopyMapToVector(
40 const PasswordFormMap
& password_form_map
) {
41 ScopedVector
<const autofill::PasswordForm
> ret
;
42 ret
.reserve(password_form_map
.size());
43 for (const auto& form_pair
: password_form_map
)
44 ret
.push_back(new autofill::PasswordForm(*form_pair
.second
));
48 ScopedVector
<const autofill::PasswordForm
> ConstifyVector(
49 ScopedVector
<autofill::PasswordForm
>* forms
) {
50 ScopedVector
<const autofill::PasswordForm
> ret
;
51 ret
.assign(forms
->begin(), forms
->end());
56 // Updates one form in |forms| that has the same unique key as |updated_form|.
57 // Returns true if the form was found and updated.
58 bool UpdateFormInVector(const autofill::PasswordForm
& updated_form
,
59 ScopedVector
<const autofill::PasswordForm
>* forms
) {
60 ScopedVector
<const autofill::PasswordForm
>::iterator it
= std::find_if(
61 forms
->begin(), forms
->end(),
62 [&updated_form
](const autofill::PasswordForm
* form
) {
63 return ArePasswordFormUniqueKeyEqual(*form
, updated_form
);
65 if (it
!= forms
->end()) {
67 *it
= new autofill::PasswordForm(updated_form
);
73 // Removes a form from |forms| that has the same unique key as |form_to_delete|.
74 template <class Vector
>
75 void RemoveFormFromVector(const autofill::PasswordForm
& form_to_delete
,
77 typename
Vector::iterator it
= std::find_if(
78 forms
->begin(), forms
->end(),
79 [&form_to_delete
](const autofill::PasswordForm
* form
) {
80 return ArePasswordFormUniqueKeyEqual(*form
, form_to_delete
);
82 if (it
!= forms
->end())
88 ManagePasswordsState::ManagePasswordsState()
89 : state_(password_manager::ui::INACTIVE_STATE
),
93 ManagePasswordsState::~ManagePasswordsState() {}
95 void ManagePasswordsState::OnPendingPassword(
96 scoped_ptr
<password_manager::PasswordFormManager
> form_manager
) {
98 form_manager_
= form_manager
.Pass();
99 current_forms_weak_
= ScopedPtrMapToVector(form_manager_
->best_matches());
100 origin_
= form_manager_
->pending_credentials().origin
;
101 SetState(password_manager::ui::PENDING_PASSWORD_STATE
);
104 void ManagePasswordsState::OnUpdatePassword(
105 scoped_ptr
<password_manager::PasswordFormManager
> form_manager
) {
107 form_manager_
= form_manager
.Pass();
108 current_forms_weak_
= ScopedPtrMapToVector(form_manager_
->best_matches());
109 origin_
= form_manager_
->pending_credentials().origin
;
110 SetState(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE
);
113 void ManagePasswordsState::OnRequestCredentials(
114 ScopedVector
<autofill::PasswordForm
> local_credentials
,
115 ScopedVector
<autofill::PasswordForm
> federated_credentials
,
116 const GURL
& origin
) {
118 local_credentials_forms_
= ConstifyVector(&local_credentials
);
119 federated_credentials_forms_
= ConstifyVector(&federated_credentials
);
121 SetState(password_manager::ui::CREDENTIAL_REQUEST_STATE
);
124 void ManagePasswordsState::OnAutoSignin(
125 ScopedVector
<autofill::PasswordForm
> local_forms
) {
126 DCHECK(!local_forms
.empty());
128 local_credentials_forms_
= ConstifyVector(&local_forms
);
129 origin_
= local_credentials_forms_
[0]->origin
;
130 SetState(password_manager::ui::AUTO_SIGNIN_STATE
);
133 void ManagePasswordsState::OnAutomaticPasswordSave(
134 scoped_ptr
<PasswordFormManager
> form_manager
) {
136 form_manager_
= form_manager
.Pass();
137 autofill::ConstPasswordFormMap current_forms
;
138 current_forms
.insert(form_manager_
->best_matches().begin(),
139 form_manager_
->best_matches().end());
140 current_forms
[form_manager_
->pending_credentials().username_value
] =
141 &form_manager_
->pending_credentials();
142 current_forms_weak_
= MapToVector(current_forms
);
143 origin_
= form_manager_
->pending_credentials().origin
;
144 SetState(password_manager::ui::CONFIRMATION_STATE
);
147 void ManagePasswordsState::OnPasswordAutofilled(
148 const PasswordFormMap
& password_form_map
) {
149 // TODO(vabr): Revert back to DCHECK once http://crbug.com/486931 is fixed.
150 CHECK(!password_form_map
.empty());
152 if (password_form_map
.begin()->second
->IsPublicSuffixMatch()) {
153 // Don't show the UI for PSL matched passwords. They are not stored for this
154 // page and cannot be deleted.
156 SetState(password_manager::ui::INACTIVE_STATE
);
158 local_credentials_forms_
= DeepCopyMapToVector(password_form_map
);
159 origin_
= local_credentials_forms_
.front()->origin
;
160 SetState(password_manager::ui::MANAGE_STATE
);
164 void ManagePasswordsState::OnInactive() {
167 SetState(password_manager::ui::INACTIVE_STATE
);
170 void ManagePasswordsState::TransitionToState(
171 password_manager::ui::State state
) {
172 DCHECK_NE(password_manager::ui::INACTIVE_STATE
, state_
);
173 DCHECK_EQ(password_manager::ui::MANAGE_STATE
, state
);
174 if (state_
== password_manager::ui::CREDENTIAL_REQUEST_STATE
) {
175 if (!credentials_callback_
.is_null()) {
176 credentials_callback_
.Run(password_manager::CredentialInfo());
177 credentials_callback_
.Reset();
179 federated_credentials_forms_
.clear();
184 void ManagePasswordsState::ProcessLoginsChanged(
185 const password_manager::PasswordStoreChangeList
& changes
) {
186 if (state() == password_manager::ui::INACTIVE_STATE
)
189 for (const password_manager::PasswordStoreChange
& change
: changes
) {
190 const autofill::PasswordForm
& changed_form
= change
.form();
191 if (changed_form
.blacklisted_by_user
)
193 if (change
.type() == password_manager::PasswordStoreChange::REMOVE
) {
194 DeleteForm(changed_form
);
196 if (change
.type() == password_manager::PasswordStoreChange::UPDATE
)
197 UpdateForm(changed_form
);
199 AddForm(changed_form
);
204 void ManagePasswordsState::ClearData() {
205 form_manager_
.reset();
206 current_forms_weak_
.clear();
207 local_credentials_forms_
.clear();
208 federated_credentials_forms_
.clear();
209 credentials_callback_
.Reset();
212 void ManagePasswordsState::AddForm(const autofill::PasswordForm
& form
) {
213 if (form
.origin
!= origin_
)
215 if (UpdateForm(form
))
218 local_credentials_forms_
.push_back(new autofill::PasswordForm(form
));
219 current_forms_weak_
.push_back(local_credentials_forms_
.back());
221 local_credentials_forms_
.push_back(new autofill::PasswordForm(form
));
225 bool ManagePasswordsState::UpdateForm(const autofill::PasswordForm
& form
) {
227 // |current_forms_weak_| contains the list of current passwords.
228 std::vector
<const autofill::PasswordForm
*>::iterator it
= std::find_if(
229 current_forms_weak_
.begin(), current_forms_weak_
.end(),
230 [&form
](const autofill::PasswordForm
* current_form
) {
231 return ArePasswordFormUniqueKeyEqual(form
, *current_form
);
233 if (it
!= current_forms_weak_
.end()) {
234 RemoveFormFromVector(form
, &local_credentials_forms_
);
235 local_credentials_forms_
.push_back(new autofill::PasswordForm(form
));
236 *it
= local_credentials_forms_
.back();
240 // |current_forms_weak_| isn't used.
241 bool updated_locals
= UpdateFormInVector(form
, &local_credentials_forms_
);
242 return (UpdateFormInVector(form
, &federated_credentials_forms_
) ||
248 void ManagePasswordsState::DeleteForm(const autofill::PasswordForm
& form
) {
249 RemoveFormFromVector(form
, ¤t_forms_weak_
);
250 RemoveFormFromVector(form
, &local_credentials_forms_
);
251 RemoveFormFromVector(form
, &federated_credentials_forms_
);
254 void ManagePasswordsState::SetState(password_manager::ui::State state
) {
256 if (client_
->IsLoggingActive()) {
257 password_manager::BrowserSavePasswordProgressLogger
logger(client_
);
259 autofill::SavePasswordProgressLogger::STRING_NEW_UI_STATE
,