Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/password_manager/password_form_manager.h" | 5 #include "chrome/browser/password_manager/password_form_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/string_split.h" | 10 #include "base/string_split.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 UMA_HISTOGRAM_ENUMERATION("PasswordManager.ActionsTaken", | 50 UMA_HISTOGRAM_ENUMERATION("PasswordManager.ActionsTaken", |
| 51 GetActionsTaken(), | 51 GetActionsTaken(), |
| 52 kMaxNumActionsTaken); | 52 kMaxNumActionsTaken); |
| 53 } | 53 } |
| 54 | 54 |
| 55 int PasswordFormManager::GetActionsTaken() { | 55 int PasswordFormManager::GetActionsTaken() { |
| 56 return user_action_ + kUserActionMax * (manager_action_ + | 56 return user_action_ + kUserActionMax * (manager_action_ + |
| 57 kManagerActionMax * submit_result_); | 57 kManagerActionMax * submit_result_); |
| 58 }; | 58 }; |
| 59 | 59 |
| 60 bool PasswordFormManager::DoesManage(const PasswordForm& form) const { | |
| 61 return PasswordFormManager::DoesManage(form, true); | |
| 62 } | |
| 63 | |
| 60 // TODO(timsteele): use a hash of some sort in the future? | 64 // TODO(timsteele): use a hash of some sort in the future? |
| 61 bool PasswordFormManager::DoesManage(const PasswordForm& form) const { | 65 bool PasswordFormManager::DoesManage(const PasswordForm& form, |
| 66 bool require_action_match) const { | |
|
tim (not reviewing)
2012/09/05 20:43:37
nit - please use an enum instead of bool here, e.g
guohui
2012/09/05 21:30:14
Done.
| |
| 62 if (form.scheme != PasswordForm::SCHEME_HTML) | 67 if (form.scheme != PasswordForm::SCHEME_HTML) |
| 63 return observed_form_.signon_realm == form.signon_realm; | 68 return observed_form_.signon_realm == form.signon_realm; |
| 64 | 69 |
| 65 // HTML form case. | 70 // HTML form case. |
| 66 // At a minimum, username and password element must match. | 71 // At a minimum, username and password element must match. |
| 67 if (!((form.username_element == observed_form_.username_element) && | 72 if (!((form.username_element == observed_form_.username_element) && |
| 68 (form.password_element == observed_form_.password_element))) { | 73 (form.password_element == observed_form_.password_element))) { |
| 69 return false; | 74 return false; |
| 70 } | 75 } |
| 71 | 76 |
| 72 // The action URL must also match, but the form is allowed to have an empty | 77 // When require_action_match is set to true, the action URL must match, but |
| 73 // action URL (See bug 1107719). | 78 // the form is allowed to have an empty action URL (See bug 1107719). |
| 74 if (form.action.is_valid() && (form.action != observed_form_.action)) | 79 // Otherwise ignore action URL, this is to allow saving password form with |
| 75 return false; | 80 // dynamically changed action URL (See bug 27246). |
| 81 if (form.action.is_valid() && (form.action != observed_form_.action)) { | |
| 82 if (require_action_match) | |
| 83 return false; | |
| 84 } | |
| 76 | 85 |
| 77 // If this is a replay of the same form in the case a user entered an invalid | 86 // If this is a replay of the same form in the case a user entered an invalid |
| 78 // password, the origin of the new form may equal the action of the "first" | 87 // password, the origin of the new form may equal the action of the "first" |
| 79 // form. | 88 // form. |
| 80 if (!((form.origin == observed_form_.origin) || | 89 if (!((form.origin == observed_form_.origin) || |
| 81 (form.origin == observed_form_.action))) { | 90 (form.origin == observed_form_.action))) { |
| 82 if (form.origin.SchemeIsSecure() && | 91 if (form.origin.SchemeIsSecure() && |
| 83 !observed_form_.origin.SchemeIsSecure()) { | 92 !observed_form_.origin.SchemeIsSecure()) { |
| 84 // Compare origins, ignoring scheme. There is no easy way to do this | 93 // Compare origins, ignoring scheme. There is no easy way to do this |
| 85 // with GURL because clearing the scheme would result in an invalid url. | 94 // with GURL because clearing the scheme would result in an invalid url. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 // Non-HTML password forms (primarily HTTP and FTP autentication) | 173 // Non-HTML password forms (primarily HTTP and FTP autentication) |
| 165 // do not contain username_element and password_element values. | 174 // do not contain username_element and password_element values. |
| 166 if (observed_form_.scheme != PasswordForm::SCHEME_HTML) | 175 if (observed_form_.scheme != PasswordForm::SCHEME_HTML) |
| 167 return true; | 176 return true; |
| 168 return !observed_form_.username_element.empty() && | 177 return !observed_form_.username_element.empty() && |
| 169 !observed_form_.password_element.empty(); | 178 !observed_form_.password_element.empty(); |
| 170 } | 179 } |
| 171 | 180 |
| 172 void PasswordFormManager::ProvisionallySave(const PasswordForm& credentials) { | 181 void PasswordFormManager::ProvisionallySave(const PasswordForm& credentials) { |
| 173 DCHECK_EQ(state_, POST_MATCHING_PHASE); | 182 DCHECK_EQ(state_, POST_MATCHING_PHASE); |
| 174 DCHECK(DoesManage(credentials)); | 183 DCHECK(DoesManage(credentials, false)); |
| 175 | 184 |
| 176 // Make sure the important fields stay the same as the initially observed or | 185 // Make sure the important fields stay the same as the initially observed or |
| 177 // autofilled ones, as they may have changed if the user experienced a login | 186 // autofilled ones, as they may have changed if the user experienced a login |
| 178 // failure. | 187 // failure. |
| 179 // Look for these credentials in the list containing auto-fill entries. | 188 // Look for these credentials in the list containing auto-fill entries. |
| 180 PasswordFormMap::const_iterator it = | 189 PasswordFormMap::const_iterator it = |
| 181 best_matches_.find(credentials.username_value); | 190 best_matches_.find(credentials.username_value); |
| 182 if (it != best_matches_.end()) { | 191 if (it != best_matches_.end()) { |
| 183 // The user signed in with a login we autofilled. | 192 // The user signed in with a login we autofilled. |
| 184 pending_credentials_ = *it->second; | 193 pending_credentials_ = *it->second; |
| 185 is_new_login_ = false; | 194 is_new_login_ = false; |
| 186 // If the user selected credentials we autofilled from a PasswordForm | |
| 187 // that contained no action URL (IE6/7 imported passwords, for example), | |
| 188 // bless it with the action URL from the observed form. See bug 1107719. | |
| 189 if (pending_credentials_.action.is_empty()) | |
| 190 pending_credentials_.action = observed_form_.action; | |
| 191 | 195 |
| 192 // Check to see if we're using a known username but a new password. | 196 // Check to see if we're using a known username but a new password. |
| 193 if (pending_credentials_.password_value != credentials.password_value) | 197 if (pending_credentials_.password_value != credentials.password_value) |
| 194 user_action_ = kUserActionOverride; | 198 user_action_ = kUserActionOverride; |
| 195 } else { | 199 } else { |
| 196 // User typed in a new, unknown username. | 200 // User typed in a new, unknown username. |
| 197 user_action_ = kUserActionOverride; | 201 user_action_ = kUserActionOverride; |
| 198 pending_credentials_ = observed_form_; | 202 pending_credentials_ = observed_form_; |
| 199 pending_credentials_.username_value = credentials.username_value; | 203 pending_credentials_.username_value = credentials.username_value; |
| 200 } | 204 } |
| 201 | 205 |
| 206 pending_credentials_.action = credentials.action; | |
| 207 // If the user selected credentials we autofilled from a PasswordForm | |
| 208 // that contained no action URL (IE6/7 imported passwords, for example), | |
| 209 // bless it with the action URL from the observed form. See bug 1107719. | |
| 210 if (pending_credentials_.action.is_empty()) | |
| 211 pending_credentials_.action = observed_form_.action; | |
| 212 | |
| 202 pending_credentials_.password_value = credentials.password_value; | 213 pending_credentials_.password_value = credentials.password_value; |
| 203 pending_credentials_.preferred = credentials.preferred; | 214 pending_credentials_.preferred = credentials.preferred; |
| 204 } | 215 } |
| 205 | 216 |
| 206 void PasswordFormManager::Save() { | 217 void PasswordFormManager::Save() { |
| 207 DCHECK_EQ(state_, POST_MATCHING_PHASE); | 218 DCHECK_EQ(state_, POST_MATCHING_PHASE); |
| 208 DCHECK(!profile_->IsOffTheRecord()); | 219 DCHECK(!profile_->IsOffTheRecord()); |
| 209 | 220 |
| 210 if (IsNewLogin()) | 221 if (IsNewLogin()) |
| 211 SaveAsNewLogin(true); | 222 SaveAsNewLogin(true); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 | 516 |
| 506 void PasswordFormManager::SubmitFailed() { | 517 void PasswordFormManager::SubmitFailed() { |
| 507 submit_result_ = kSubmitResultFailed; | 518 submit_result_ = kSubmitResultFailed; |
| 508 } | 519 } |
| 509 | 520 |
| 510 void PasswordFormManager::SendNotBlacklistedToRenderer() { | 521 void PasswordFormManager::SendNotBlacklistedToRenderer() { |
| 511 content::RenderViewHost* host = web_contents_->GetRenderViewHost(); | 522 content::RenderViewHost* host = web_contents_->GetRenderViewHost(); |
| 512 host->Send(new AutofillMsg_FormNotBlacklisted(host->GetRoutingID(), | 523 host->Send(new AutofillMsg_FormNotBlacklisted(host->GetRoutingID(), |
| 513 observed_form_)); | 524 observed_form_)); |
| 514 } | 525 } |
| OLD | NEW |