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 // Updates a form in |forms| that has the same unique key as |updated_form|. | |
|
vabr (Chromium)
2015/03/10 12:26:22
Maybe there was a misunderstanding -- the point I
| |
| 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 IsEqualUniqueKey(*form, updated_form); | |
| 64 }); | |
| 65 if (it != forms->end()) { | |
| 66 delete *it; | |
| 67 *it = new autofill::PasswordForm(updated_form); | |
| 68 return true; | |
| 69 } | |
| 70 return false; | |
| 71 } | |
| 72 | |
| 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, | |
| 76 Vector* forms) { | |
| 77 typename Vector::iterator it = std::find_if( | |
| 78 forms->begin(), forms->end(), | |
| 79 [&form_to_delete](const autofill::PasswordForm* form) { | |
| 80 return IsEqualUniqueKey(*form, form_to_delete); | |
| 81 }); | |
| 82 if (it != forms->end()) | |
| 83 forms->erase(it); | |
| 84 } | |
| 85 | |
| 86 } // namespace | |
| 87 | |
| 88 ManagePasswordsState::ManagePasswordsState() | |
| 89 : state_(password_manager::ui::INACTIVE_STATE), | |
| 90 client_(nullptr) { | |
| 91 } | |
| 92 | |
| 93 ManagePasswordsState::~ManagePasswordsState() {} | |
| 94 | |
| 95 void ManagePasswordsState::OnPendingPassword( | |
| 96 scoped_ptr<password_manager::PasswordFormManager> form_manager) { | |
| 97 ClearData(); | |
| 98 form_manager_ = form_manager.Pass(); | |
| 99 current_forms_weak_ = MapToVector(form_manager_->best_matches()); | |
| 100 origin_ = form_manager_->pending_credentials().origin; | |
| 101 SetState(password_manager::ui::PENDING_PASSWORD_STATE); | |
| 102 } | |
| 103 | |
| 104 void ManagePasswordsState::OnRequestCredentials( | |
| 105 ScopedVector<autofill::PasswordForm> local_credentials, | |
| 106 ScopedVector<autofill::PasswordForm> federated_credentials, | |
| 107 const GURL& origin) { | |
| 108 ClearData(); | |
| 109 local_credentials_forms_ = ConstifyVector(&local_credentials); | |
| 110 federated_credentials_forms_ = ConstifyVector(&federated_credentials); | |
| 111 origin_ = origin; | |
| 112 SetState(password_manager::ui::CREDENTIAL_REQUEST_STATE); | |
| 113 } | |
| 114 | |
| 115 void ManagePasswordsState::OnAutoSignin( | |
| 116 ScopedVector<autofill::PasswordForm> local_forms) { | |
| 117 DCHECK(!local_forms.empty()); | |
| 118 ClearData(); | |
| 119 local_credentials_forms_ = ConstifyVector(&local_forms); | |
| 120 origin_ = local_credentials_forms_[0]->origin; | |
| 121 SetState(password_manager::ui::AUTO_SIGNIN_STATE); | |
| 122 } | |
| 123 | |
| 124 void ManagePasswordsState::OnAutomaticPasswordSave( | |
| 125 scoped_ptr<PasswordFormManager> form_manager) { | |
| 126 ClearData(); | |
| 127 form_manager_ = form_manager.Pass(); | |
| 128 autofill::ConstPasswordFormMap current_forms; | |
| 129 current_forms.insert(form_manager_->best_matches().begin(), | |
| 130 form_manager_->best_matches().end()); | |
| 131 current_forms[form_manager_->associated_username()] = | |
| 132 &form_manager_->pending_credentials(); | |
| 133 current_forms_weak_ = MapToVector(current_forms); | |
| 134 origin_ = form_manager_->pending_credentials().origin; | |
| 135 SetState(password_manager::ui::CONFIRMATION_STATE); | |
| 136 } | |
| 137 | |
| 138 void ManagePasswordsState::OnPasswordAutofilled( | |
| 139 const PasswordFormMap& password_form_map) { | |
| 140 DCHECK(!password_form_map.empty()); | |
| 141 ClearData(); | |
| 142 if (password_form_map.begin()->second->IsPublicSuffixMatch()) { | |
| 143 // Don't show the UI for PSL matched passwords. They are not stored for this | |
| 144 // page and cannot be deleted. | |
| 145 origin_ = GURL(); | |
| 146 SetState(password_manager::ui::INACTIVE_STATE); | |
| 147 } else { | |
| 148 local_credentials_forms_ = DeepCopyMapToVector(password_form_map); | |
| 149 origin_ = local_credentials_forms_.front()->origin; | |
| 150 SetState(password_manager::ui::MANAGE_STATE); | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 void ManagePasswordsState::OnBlacklistBlockedAutofill( | |
| 155 const autofill::PasswordFormMap& password_form_map) { | |
| 156 DCHECK(!password_form_map.empty()); | |
| 157 ClearData(); | |
| 158 local_credentials_forms_ = DeepCopyMapToVector(password_form_map); | |
| 159 origin_ = local_credentials_forms_.front()->origin; | |
| 160 SetState(password_manager::ui::BLACKLIST_STATE); | |
| 161 } | |
| 162 | |
| 163 void ManagePasswordsState::OnInactive() { | |
| 164 ClearData(); | |
| 165 origin_ = GURL(); | |
| 166 SetState(password_manager::ui::INACTIVE_STATE); | |
| 167 } | |
| 168 | |
| 169 void ManagePasswordsState::TransitionToState( | |
| 170 password_manager::ui::State state) { | |
| 171 DCHECK_NE(password_manager::ui::INACTIVE_STATE, state_); | |
| 172 DCHECK(state == password_manager::ui::BLACKLIST_STATE || | |
| 173 state == password_manager::ui::MANAGE_STATE); | |
| 174 if (state_ == password_manager::ui::CREDENTIAL_REQUEST_STATE && | |
| 175 !credentials_callback_.is_null()) { | |
| 176 credentials_callback_.Run(password_manager::CredentialInfo()); | |
| 177 credentials_callback_.Reset(); | |
| 178 } | |
| 179 SetState(state); | |
| 180 } | |
| 181 | |
| 182 void ManagePasswordsState::ProcessLoginsChanged( | |
| 183 const password_manager::PasswordStoreChangeList& changes) { | |
| 184 if (state() == password_manager::ui::INACTIVE_STATE) | |
| 185 return; | |
| 186 | |
| 187 for (const password_manager::PasswordStoreChange& change : changes) { | |
| 188 const autofill::PasswordForm& changed_form = change.form(); | |
| 189 if (change.type() == password_manager::PasswordStoreChange::REMOVE) { | |
| 190 DeleteForm(changed_form); | |
| 191 if (changed_form.blacklisted_by_user && | |
| 192 state() == password_manager::ui::BLACKLIST_STATE && | |
| 193 changed_form.origin == origin_) { | |
| 194 TransitionToState(password_manager::ui::MANAGE_STATE); | |
| 195 } | |
| 196 } else { | |
| 197 if (change.type() == password_manager::PasswordStoreChange::UPDATE) | |
| 198 UpdateForm(changed_form); | |
| 199 else | |
| 200 AddForm(changed_form); | |
| 201 if (changed_form.blacklisted_by_user && | |
| 202 changed_form.origin == origin_) { | |
| 203 TransitionToState(password_manager::ui::BLACKLIST_STATE); | |
| 204 } | |
| 205 } | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 void ManagePasswordsState::ClearData() { | |
| 210 form_manager_.reset(); | |
| 211 current_forms_weak_.clear(); | |
| 212 local_credentials_forms_.clear(); | |
| 213 federated_credentials_forms_.clear(); | |
| 214 credentials_callback_.Reset(); | |
| 215 } | |
| 216 | |
| 217 void ManagePasswordsState::AddForm(const autofill::PasswordForm& form) { | |
| 218 if (form.origin != origin_) | |
| 219 return; | |
| 220 if (UpdateForm(form)) | |
| 221 return; | |
| 222 local_credentials_forms_.push_back(new autofill::PasswordForm(form)); | |
| 223 if (form_manager_) | |
| 224 current_forms_weak_.push_back(local_credentials_forms_.back()); | |
| 225 } | |
| 226 | |
| 227 bool ManagePasswordsState::UpdateForm(const autofill::PasswordForm& form) { | |
| 228 if (form_manager_) { | |
| 229 // |current_forms_weak_| contains the list of current passwords. | |
| 230 std::vector<const autofill::PasswordForm*>::iterator it = std::find_if( | |
| 231 current_forms_weak_.begin(), current_forms_weak_.end(), | |
| 232 [&form](const autofill::PasswordForm* current_form) { | |
| 233 return IsEqualUniqueKey(form, *current_form); | |
| 234 }); | |
| 235 if (it != current_forms_weak_.end()) { | |
| 236 RemoveFormFromVector(form, &local_credentials_forms_); | |
| 237 local_credentials_forms_.push_back(new autofill::PasswordForm(form)); | |
| 238 *it = local_credentials_forms_.back(); | |
| 239 return true; | |
| 240 } | |
| 241 } else { | |
| 242 // |current_forms_weak_| isn't used. | |
| 243 bool updated_locals = UpdateFormInVector(form, &local_credentials_forms_); | |
| 244 return (UpdateFormInVector(form, &federated_credentials_forms_) || | |
| 245 updated_locals); | |
| 246 } | |
| 247 return false; | |
| 248 } | |
| 249 | |
| 250 void ManagePasswordsState::DeleteForm(const autofill::PasswordForm& form) { | |
| 251 RemoveFormFromVector(form, ¤t_forms_weak_); | |
| 252 RemoveFormFromVector(form, &local_credentials_forms_); | |
| 253 RemoveFormFromVector(form, &federated_credentials_forms_); | |
| 254 } | |
| 255 | |
| 256 void ManagePasswordsState::SetState(password_manager::ui::State state) { | |
| 257 if (client_ && client_->IsLoggingActive()) { | |
| 258 password_manager::BrowserSavePasswordProgressLogger logger(client_); | |
| 259 logger.LogNumber( | |
| 260 autofill::SavePasswordProgressLogger::STRING_NEW_UI_STATE, | |
| 261 state); | |
| 262 } | |
| 263 state_ = state; | |
| 264 } | |
| OLD | NEW |