Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: chrome/browser/password_manager/password_form_manager.cc

Issue 10892011: Fix for no password save when action URL is modified (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_form_manager.h ('k') | chrome/browser/password_manager/password_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698