Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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. | |
| 4 | |
| 5 #include "chrome/browser/ui/passwords/manage_passwords_state.h" | |
| 6 | |
| 7 #include "components/password_manager/content/common/credential_manager_types.h" | |
| 8 #include "components/password_manager/core/browser/browser_save_password_progres s_logger.h" | |
| 9 #include "components/password_manager/core/browser/password_form_manager.h" | |
| 10 #include "components/password_manager/core/browser/password_manager_client.h" | |
| 11 | |
| 12 using password_manager::PasswordFormManager; | |
| 13 using autofill::PasswordFormMap; | |
| 14 | |
| 15 namespace { | |
| 16 | |
| 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; | |
| 27 } | |
| 28 | |
| 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(); | |
| 36 } | |
| 37 | |
| 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(); | |
| 44 } | |
| 45 | |
| 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; | |
| 55 } | |
| 56 | |
| 57 void UpdateFormInVector(const autofill::PasswordForm& updated_form, | |
|
vabr (Chromium)
2015/03/10 10:39:57
This function seems to assume that there is at mos
vasilii
2015/03/10 11:34:48
Done.
| |
| 58 ScopedVector<const autofill::PasswordForm>* forms) { | |
| 59 ScopedVector<const autofill::PasswordForm>::iterator it = std::find_if( | |
| 60 forms->begin(), forms->end(), | |
| 61 [&updated_form](const autofill::PasswordForm* form) { | |
| 62 return IsEqualUniqueKey(*form, updated_form); | |
| 63 }); | |
| 64 if (it != forms->end()) { | |
| 65 delete *it; | |
| 66 *it = new autofill::PasswordForm(updated_form); | |
| 67 } | |
| 68 } | |
| 69 | |
| 70 // Removes |form_to_delete| from std::vector or ScopedVector. | |
| 71 template <class Vector> | |
| 72 void RemoveFormFromVector(const autofill::PasswordForm& form_to_delete, | |
| 73 Vector* forms) { | |
| 74 typename Vector::iterator it = std::find_if( | |
| 75 forms->begin(), forms->end(), | |
| 76 [&form_to_delete](const autofill::PasswordForm* form) { | |
| 77 return IsEqualUniqueKey(*form, form_to_delete); | |
| 78 }); | |
| 79 if (it != forms->end()) | |
| 80 forms->erase(it); | |
| 81 } | |
| 82 | |
| 83 } // namespace | |
| 84 | |
| 85 ManagePasswordsState::ManagePasswordsState() | |
| 86 : state_(password_manager::ui::INACTIVE_STATE), | |
| 87 client_(nullptr) { | |
| 88 } | |
| 89 | |
| 90 ManagePasswordsState::~ManagePasswordsState() {} | |
| 91 | |
| 92 void ManagePasswordsState::OnPendingPassword( | |
| 93 scoped_ptr<password_manager::PasswordFormManager> form_manager) { | |
| 94 ClearData(); | |
| 95 form_manager_ = form_manager.Pass(); | |
| 96 current_forms_weak_ = MapToVector(form_manager_->best_matches()); | |
| 97 origin_ = form_manager_->pending_credentials().origin; | |
| 98 SetState(password_manager::ui::PENDING_PASSWORD_STATE); | |
| 99 } | |
| 100 | |
| 101 void ManagePasswordsState::OnRequestCredentials( | |
| 102 ScopedVector<autofill::PasswordForm> local_credentials, | |
| 103 ScopedVector<autofill::PasswordForm> federated_credentials, | |
| 104 const GURL& origin) { | |
| 105 ClearData(); | |
| 106 local_credentials_forms_ = ConstifyVector(&local_credentials); | |
| 107 federated_credentials_forms_ = ConstifyVector(&federated_credentials); | |
| 108 origin_ = origin; | |
| 109 SetState(password_manager::ui::CREDENTIAL_REQUEST_STATE); | |
| 110 } | |
| 111 | |
| 112 void ManagePasswordsState::OnAutoSignin( | |
| 113 ScopedVector<autofill::PasswordForm> local_forms) { | |
| 114 DCHECK(!local_forms.empty()); | |
| 115 ClearData(); | |
| 116 local_credentials_forms_ = ConstifyVector(&local_forms); | |
| 117 origin_ = local_credentials_forms_[0]->origin; | |
| 118 SetState(password_manager::ui::AUTO_SIGNIN_STATE); | |
| 119 } | |
| 120 | |
| 121 void ManagePasswordsState::OnAutomaticPasswordSave( | |
| 122 scoped_ptr<PasswordFormManager> form_manager) { | |
| 123 ClearData(); | |
| 124 form_manager_ = form_manager.Pass(); | |
| 125 autofill::ConstPasswordFormMap current_forms; | |
| 126 current_forms.insert(form_manager_->best_matches().begin(), | |
| 127 form_manager_->best_matches().end()); | |
| 128 current_forms[form_manager_->associated_username()] = | |
| 129 &form_manager_->pending_credentials(); | |
| 130 current_forms_weak_ = MapToVector(current_forms); | |
| 131 origin_ = form_manager_->pending_credentials().origin; | |
| 132 SetState(password_manager::ui::CONFIRMATION_STATE); | |
| 133 } | |
| 134 | |
| 135 void ManagePasswordsState::OnPasswordAutofilled( | |
| 136 const PasswordFormMap& password_form_map) { | |
| 137 DCHECK(!password_form_map.empty()); | |
| 138 ClearData(); | |
| 139 if (password_form_map.begin()->second->IsPublicSuffixMatch()) { | |
| 140 // Don't show the UI for PSL matched passwords. They are not stored for this | |
| 141 // page and cannot be deleted. | |
| 142 origin_ = GURL(); | |
| 143 SetState(password_manager::ui::INACTIVE_STATE); | |
| 144 } else { | |
| 145 local_credentials_forms_ = DeepCopyMapToVector(password_form_map); | |
| 146 origin_ = local_credentials_forms_.front()->origin; | |
| 147 SetState(password_manager::ui::MANAGE_STATE); | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 void ManagePasswordsState::OnBlacklistBlockedAutofill( | |
| 152 const autofill::PasswordFormMap& password_form_map) { | |
| 153 DCHECK(!password_form_map.empty()); | |
| 154 ClearData(); | |
| 155 local_credentials_forms_ = DeepCopyMapToVector(password_form_map); | |
| 156 origin_ = local_credentials_forms_.front()->origin; | |
| 157 SetState(password_manager::ui::BLACKLIST_STATE); | |
| 158 } | |
| 159 | |
| 160 void ManagePasswordsState::OnInactive() { | |
| 161 ClearData(); | |
| 162 origin_ = GURL(); | |
| 163 SetState(password_manager::ui::INACTIVE_STATE); | |
| 164 } | |
| 165 | |
| 166 void ManagePasswordsState::TransitionToState( | |
|
vabr (Chromium)
2015/03/10 10:39:56
The declaration comment lists the allowed transiti
vasilii
2015/03/10 11:34:48
Done.
| |
| 167 password_manager::ui::State state) { | |
| 168 DCHECK_NE(password_manager::ui::INACTIVE_STATE, state); | |
| 169 DCHECK_NE(password_manager::ui::INACTIVE_STATE, state_); | |
| 170 if (state_ == password_manager::ui::CREDENTIAL_REQUEST_STATE && | |
| 171 !credentials_callback_.is_null()) { | |
| 172 credentials_callback_.Run(password_manager::CredentialInfo()); | |
| 173 credentials_callback_.Reset(); | |
| 174 } | |
| 175 SetState(state); | |
| 176 } | |
| 177 | |
| 178 void ManagePasswordsState::ProcessLoginsChanged( | |
| 179 const password_manager::PasswordStoreChangeList& changes) { | |
| 180 if (state() == password_manager::ui::INACTIVE_STATE) | |
| 181 return; | |
| 182 | |
| 183 for (const password_manager::PasswordStoreChange& change : changes) { | |
| 184 const autofill::PasswordForm& changed_form = change.form(); | |
| 185 if (change.type() == password_manager::PasswordStoreChange::REMOVE) { | |
| 186 DeleteForm(changed_form); | |
| 187 if (changed_form.blacklisted_by_user && | |
|
vabr (Chromium)
2015/03/10 10:39:57
The style guide weakly suggests braces for this if
vasilii
2015/03/10 11:34:48
Done.
| |
| 188 state() == password_manager::ui::BLACKLIST_STATE && | |
| 189 changed_form.origin == origin_) | |
| 190 TransitionToState(password_manager::ui::MANAGE_STATE); | |
| 191 } else { | |
| 192 if (change.type() == password_manager::PasswordStoreChange::UPDATE) | |
| 193 UpdateForm(changed_form); | |
| 194 else | |
| 195 AddForm(changed_form); | |
| 196 if (changed_form.blacklisted_by_user && | |
| 197 changed_form.origin == origin_) | |
| 198 TransitionToState(password_manager::ui::BLACKLIST_STATE); | |
| 199 } | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 void ManagePasswordsState::ClearData() { | |
| 204 form_manager_.reset(); | |
| 205 current_forms_weak_.clear(); | |
| 206 local_credentials_forms_.clear(); | |
| 207 federated_credentials_forms_.clear(); | |
| 208 credentials_callback_.Reset(); | |
| 209 } | |
| 210 | |
| 211 void ManagePasswordsState::AddForm(const autofill::PasswordForm& form) { | |
| 212 if (form.origin != origin_) | |
| 213 return; | |
| 214 local_credentials_forms_.push_back(new autofill::PasswordForm(form)); | |
|
vabr (Chromium)
2015/03/10 10:39:56
Should we check that a form with the same unique k
vasilii
2015/03/10 11:34:48
OK. Let's be on the safe side.
| |
| 215 if (form_manager_) | |
| 216 current_forms_weak_.push_back(local_credentials_forms_.back()); | |
| 217 } | |
| 218 | |
| 219 void ManagePasswordsState::UpdateForm(const autofill::PasswordForm& form) { | |
| 220 if (form_manager_) { | |
| 221 // |current_forms_weak_| contains the list of current passwords. | |
| 222 std::vector<const autofill::PasswordForm*>::iterator it = std::find_if( | |
| 223 current_forms_weak_.begin(), current_forms_weak_.end(), | |
| 224 [&form](const autofill::PasswordForm* current_form) { | |
| 225 return IsEqualUniqueKey(form, *current_form); | |
| 226 }); | |
| 227 if (it != current_forms_weak_.end()) { | |
| 228 RemoveFormFromVector(form, &local_credentials_forms_); | |
| 229 local_credentials_forms_.push_back(new autofill::PasswordForm(form)); | |
| 230 *it = local_credentials_forms_.back(); | |
| 231 } | |
| 232 } else { | |
| 233 // |current_forms_weak_| isn't used. | |
| 234 UpdateFormInVector(form, &local_credentials_forms_); | |
| 235 UpdateFormInVector(form, &federated_credentials_forms_); | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 void ManagePasswordsState::DeleteForm(const autofill::PasswordForm& form) { | |
| 240 RemoveFormFromVector(form, ¤t_forms_weak_); | |
| 241 RemoveFormFromVector(form, &local_credentials_forms_); | |
| 242 RemoveFormFromVector(form, &federated_credentials_forms_); | |
| 243 } | |
| 244 | |
| 245 void ManagePasswordsState::SetState(password_manager::ui::State state) { | |
| 246 if (client_ && client_->IsLoggingActive()) { | |
| 247 password_manager::BrowserSavePasswordProgressLogger logger(client_); | |
| 248 logger.LogNumber( | |
| 249 autofill::SavePasswordProgressLogger::STRING_NEW_UI_STATE, | |
| 250 state); | |
| 251 } | |
| 252 state_ = state; | |
| 253 } | |
| OLD | NEW |