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

Side by Side Diff: components/autofill/content/renderer/password_form_conversion_utils.cc

Issue 356223002: PasswordForm: move from current/old password scheme to current/new. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix problems with discrepancies between |observed_form_| and |form|, and revert former to constref. Created 6 years, 5 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/autofill/content/renderer/password_form_conversion_utils.h" 5 #include "components/autofill/content/renderer/password_form_conversion_utils.h"
6 6
7 #include "base/strings/string_util.h" 7 #include "base/strings/string_util.h"
8 #include "components/autofill/content/renderer/form_autofill_util.h" 8 #include "components/autofill/content/renderer/form_autofill_util.h"
9 #include "components/autofill/core/common/password_form.h" 9 #include "components/autofill/core/common/password_form.h"
10 #include "third_party/WebKit/public/platform/WebString.h" 10 #include "third_party/WebKit/public/platform/WebString.h"
(...skipping 16 matching lines...) Expand all
27 static const size_t kMaxPasswords = 3; 27 static const size_t kMaxPasswords = 3;
28 28
29 // Checks in a case-insensitive way if the autocomplete attribute for the given 29 // Checks in a case-insensitive way if the autocomplete attribute for the given
30 // |element| is present and has the specified |value_in_lowercase|. 30 // |element| is present and has the specified |value_in_lowercase|.
31 bool HasAutocompleteAttributeValue(const WebInputElement* element, 31 bool HasAutocompleteAttributeValue(const WebInputElement* element,
32 const char* value_in_lowercase) { 32 const char* value_in_lowercase) {
33 return LowerCaseEqualsASCII(element->getAttribute("autocomplete"), 33 return LowerCaseEqualsASCII(element->getAttribute("autocomplete"),
34 value_in_lowercase); 34 value_in_lowercase);
35 } 35 }
36 36
37 // Helper to determine which password is the main one, and which is 37 // Helper to determine which password is the main (current) one, and which is
38 // an old password (e.g on a "make new password" form), if any. 38 // the new password (e.g., on a sign-up or change password form), if any.
39 bool LocateSpecificPasswords(std::vector<WebInputElement> passwords, 39 bool LocateSpecificPasswords(std::vector<WebInputElement> passwords,
40 WebInputElement* password, 40 WebInputElement* password,
41 WebInputElement* old_password) { 41 WebInputElement* new_password) {
42 switch (passwords.size()) { 42 switch (passwords.size()) {
43 case 1: 43 case 1:
44 // Single password, easy. 44 // Single password, easy.
45 *password = passwords[0]; 45 *password = passwords[0];
46 break; 46 break;
47 case 2: 47 case 2:
48 if (passwords[0].value() == passwords[1].value()) { 48 if (passwords[0].value() == passwords[1].value()) {
49 // Treat two identical passwords as a single password. 49 // Two identical passwords: assume we are seeing a new password with a
50 *password = passwords[0]; 50 // confirmation. This can be either a sign-up form or a password change
51 // form that does not ask for the old password.
52 *new_password = passwords[0];
51 } else { 53 } else {
52 // Assume first is old password, second is new (no choice but to guess). 54 // Assume first is old password, second is new (no choice but to guess).
53 *old_password = passwords[0]; 55 *password = passwords[0];
54 *password = passwords[1]; 56 *new_password = passwords[1];
55 } 57 }
56 break; 58 break;
57 case 3: 59 case 3:
58 if (passwords[0].value() == passwords[1].value() && 60 if (!passwords[0].value().isEmpty() &&
engedy 2014/07/03 13:34:19 We have found a problem here that the set of eleme
59 passwords[0].value() == passwords[2].value()) { 61 (passwords[0].value() == passwords[1].value() &&
60 // All three passwords the same? Just treat as one and hope. 62 passwords[0].value() == passwords[2].value())) {
63 // All three passwords are the same and non-empty? This does not make
64 // any sense, give up.
65 return false;
66 } else if (passwords[1].value() == passwords[2].value()) {
67 // New password is the duplicated one, and comes second; or empty form
68 // with 3 password fields, in which case we will assume this layout.
61 *password = passwords[0]; 69 *password = passwords[0];
70 *new_password = passwords[1];
62 } else if (passwords[0].value() == passwords[1].value()) { 71 } else if (passwords[0].value() == passwords[1].value()) {
engedy 2014/07/03 13:34:19 Note that this is also a behavior change.
63 // Two the same and one different -> old password is duplicated one. 72 // It is strange that the new password comes first, but trust more which
64 *old_password = passwords[0]; 73 // fields are duplicated than the ordering of fields.
65 *password = passwords[2]; 74 *password = passwords[2];
66 } else if (passwords[1].value() == passwords[2].value()) { 75 *new_password = passwords[0];
67 *old_password = passwords[0];
68 *password = passwords[1];
69 } else { 76 } else {
70 // Three different passwords, or first and last match with middle 77 // Three different passwords, or first and last match with middle
71 // different. No idea which is which, so no luck. 78 // different. No idea which is which, so no luck.
72 return false; 79 return false;
73 } 80 }
74 break; 81 break;
75 default: 82 default:
76 return false; 83 return false;
77 } 84 }
78 return true; 85 return true;
79 } 86 }
80 87
81 // Get information about a login form that encapsulated in the 88 // Get information about a login form encapsulated in a PasswordForm struct.
82 // PasswordForm struct.
83 void GetPasswordForm(const WebFormElement& form, PasswordForm* password_form) { 89 void GetPasswordForm(const WebFormElement& form, PasswordForm* password_form) {
84 WebInputElement latest_input_element; 90 WebInputElement latest_input_element;
85 WebInputElement username_element; 91 WebInputElement username_element;
86 // Caches whether |username_element| is marked with autocomplete='username'. 92 // Caches whether |username_element| is marked with autocomplete='username'.
87 // Needed for performance reasons to avoid recalculating this multiple times. 93 // Needed for performance reasons to avoid recalculating this multiple times.
88 bool has_seen_element_with_autocomplete_username_before = false; 94 bool has_seen_element_with_autocomplete_username_before = false;
89 std::vector<WebInputElement> passwords; 95 std::vector<WebInputElement> passwords;
90 std::vector<base::string16> other_possible_usernames; 96 std::vector<base::string16> other_possible_usernames;
91 97
92 WebVector<WebFormControlElement> control_elements; 98 WebVector<WebFormControlElement> control_elements;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 167 }
162 } 168 }
163 } 169 }
164 } 170 }
165 171
166 if (!username_element.isNull()) { 172 if (!username_element.isNull()) {
167 password_form->username_element = username_element.nameForAutofill(); 173 password_form->username_element = username_element.nameForAutofill();
168 password_form->username_value = username_element.value(); 174 password_form->username_value = username_element.value();
169 } 175 }
170 176
177 if (!username_element.isNull()) {
178 password_form->username_element = username_element.nameForAutofill();
179 password_form->username_value = username_element.value();
180 }
181
171 // Get the document URL 182 // Get the document URL
172 GURL full_origin(form.document().url()); 183 GURL full_origin(form.document().url());
173 184
174 // Calculate the canonical action URL 185 // Calculate the canonical action URL
175 WebString action = form.action(); 186 WebString action = form.action();
176 if (action.isNull()) 187 if (action.isNull())
177 action = WebString(""); // missing 'action' attribute implies current URL 188 action = WebString(""); // missing 'action' attribute implies current URL
178 GURL full_action(form.document().completeURL(action)); 189 GURL full_action(form.document().completeURL(action));
179 if (!full_action.is_valid()) 190 if (!full_action.is_valid())
180 return; 191 return;
181 192
182 WebInputElement password; 193 WebInputElement password;
183 WebInputElement old_password; 194 WebInputElement new_password;
184 if (!LocateSpecificPasswords(passwords, &password, &old_password)) 195 if (!LocateSpecificPasswords(passwords, &password, &new_password))
185 return; 196 return;
186 197
187 // We want to keep the path but strip any authentication data, as well as 198 // We want to keep the path but strip any authentication data, as well as
188 // query and ref portions of URL, for the form action and form origin. 199 // query and ref portions of URL, for the form action and form origin.
189 GURL::Replacements rep; 200 GURL::Replacements rep;
190 rep.ClearUsername(); 201 rep.ClearUsername();
191 rep.ClearPassword(); 202 rep.ClearPassword();
192 rep.ClearQuery(); 203 rep.ClearQuery();
193 rep.ClearRef(); 204 rep.ClearRef();
194 password_form->action = full_action.ReplaceComponents(rep); 205 password_form->action = full_action.ReplaceComponents(rep);
195 password_form->origin = full_origin.ReplaceComponents(rep); 206 password_form->origin = full_origin.ReplaceComponents(rep);
196 207
197 rep.SetPathStr(""); 208 rep.SetPathStr("");
198 password_form->signon_realm = full_origin.ReplaceComponents(rep).spec(); 209 password_form->signon_realm = full_origin.ReplaceComponents(rep).spec();
199 210
200 password_form->other_possible_usernames.swap(other_possible_usernames); 211 password_form->other_possible_usernames.swap(other_possible_usernames);
201 212
202 if (!password.isNull()) { 213 if (!password.isNull()) {
203 password_form->password_element = password.nameForAutofill(); 214 password_form->password_element = password.nameForAutofill();
204 password_form->password_value = password.value(); 215 password_form->password_value = password.value();
205 password_form->password_autocomplete_set = password.autoComplete(); 216 password_form->password_autocomplete_set = password.autoComplete();
206 } 217 }
207 if (!old_password.isNull()) { 218 if (!new_password.isNull()) {
208 password_form->old_password_element = old_password.nameForAutofill(); 219 password_form->new_password_element = new_password.nameForAutofill();
209 password_form->old_password_value = old_password.value(); 220 password_form->new_password_value = new_password.value();
210 } 221 }
211 222
212 password_form->scheme = PasswordForm::SCHEME_HTML; 223 password_form->scheme = PasswordForm::SCHEME_HTML;
213 password_form->ssl_valid = false; 224 password_form->ssl_valid = false;
214 password_form->preferred = false; 225 password_form->preferred = false;
215 password_form->blacklisted_by_user = false; 226 password_form->blacklisted_by_user = false;
216 password_form->type = PasswordForm::TYPE_MANUAL; 227 password_form->type = PasswordForm::TYPE_MANUAL;
217 password_form->use_additional_authentication = false; 228 password_form->use_additional_authentication = false;
218 } 229 }
219 230
(...skipping 13 matching lines...) Expand all
233 blink::WebFormControlElement(), 244 blink::WebFormControlElement(),
234 REQUIRE_NONE, 245 REQUIRE_NONE,
235 EXTRACT_NONE, 246 EXTRACT_NONE,
236 &password_form->form_data, 247 &password_form->form_data,
237 NULL /* FormFieldData */); 248 NULL /* FormFieldData */);
238 249
239 return password_form.Pass(); 250 return password_form.Pass();
240 } 251 }
241 252
242 } // namespace autofill 253 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698