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

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

Issue 225823006: Rewrite functions from WebPasswordFormData and WebPasswordFormUtils in (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Put check on "isActivatedSumbit" back Created 6 years, 8 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
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/logging.h"
Garrett Casto 2014/04/16 22:56:55 I think that this is unnecessary.
7 #include "components/autofill/content/renderer/form_autofill_util.h" 8 #include "components/autofill/content/renderer/form_autofill_util.h"
8 #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"
11 #include "third_party/WebKit/public/web/WebDocument.h"
9 #include "third_party/WebKit/public/web/WebFormControlElement.h" 12 #include "third_party/WebKit/public/web/WebFormControlElement.h"
10 #include "third_party/WebKit/public/web/WebPasswordFormData.h" 13 #include "third_party/WebKit/public/web/WebInputElement.h"
11 14
15 using blink::WebDocument;
16 using blink::WebFormControlElement;
12 using blink::WebFormElement; 17 using blink::WebFormElement;
13 using blink::WebPasswordFormData; 18 using blink::WebInputElement;
19 using blink::WebString;
20 using blink::WebVector;
14 21
15 namespace autofill { 22 namespace autofill {
16 namespace { 23 namespace {
17 24
25 // Maximum number of password fields we will observe before throwing our
26 // hands in the air and giving up with a given form.
27 static const size_t kMaxPasswords = 3;
28
18 scoped_ptr<PasswordForm> InitPasswordFormFromWebPasswordForm( 29 scoped_ptr<PasswordForm> InitPasswordFormFromWebPasswordForm(
19 const WebFormElement& web_form, 30 const WebFormElement& web_form,
20 const blink::WebPasswordFormData& web_password_form) { 31 PasswordForm* password_form) {
21 PasswordForm* password_form = new PasswordForm(); 32 GetPasswordForm(web_form, password_form);
22 password_form->signon_realm = web_password_form.signonRealm.utf8(); 33
23 password_form->origin = web_password_form.origin; 34 if (!password_form->action.is_valid())
24 password_form->action = web_password_form.action; 35 return scoped_ptr<PasswordForm>();
25 password_form->submit_element = web_password_form.submitElement; 36
26 password_form->username_element = web_password_form.userNameElement;
27 password_form->username_value = web_password_form.userNameValue;
28 password_form->other_possible_usernames.insert(
29 password_form->other_possible_usernames.begin(),
30 web_password_form.possibleUserNames.data(),
31 web_password_form.possibleUserNames.data() +
32 web_password_form.possibleUserNames.size());
33 password_form->password_element = web_password_form.passwordElement;
34 password_form->password_value = web_password_form.passwordValue;
35 password_form->password_autocomplete_set =
36 web_password_form.passwordShouldAutocomplete;
37 password_form->old_password_element = web_password_form.oldPasswordElement;
38 password_form->old_password_value = web_password_form.oldPasswordValue;
39 password_form->scheme = PasswordForm::SCHEME_HTML;
40 password_form->ssl_valid = false;
41 password_form->preferred = false;
42 password_form->blacklisted_by_user = false;
43 password_form->type = PasswordForm::TYPE_MANUAL;
44 password_form->use_additional_authentication = false;
45 WebFormElementToFormData(web_form, 37 WebFormElementToFormData(web_form,
46 blink::WebFormControlElement(), 38 blink::WebFormControlElement(),
47 REQUIRE_NONE, 39 REQUIRE_NONE,
48 EXTRACT_NONE, 40 EXTRACT_NONE,
49 &password_form->form_data, 41 &password_form->form_data,
50 NULL /* FormFieldData */); 42 NULL /* FormFieldData */);
51 return scoped_ptr<PasswordForm>(password_form); 43 return scoped_ptr<PasswordForm>(password_form);
52 } 44 }
53 45
46 // Helper to determine which password is the main one, and which is
47 // an old password (e.g on a "make new password" form), if any.
48 bool LocateSpecificPasswords(std::vector<WebInputElement> passwords,
49 WebInputElement* password,
50 WebInputElement* old_password)
51 {
Garrett Casto 2014/04/16 22:56:55 In Chromium, starting braces don't get their own l
52 switch (passwords.size()) {
53 case 1:
54 // Single password, easy.
55 *password = passwords[0];
56 break;
57 case 2:
58 if (passwords[0].value() == passwords[1].value()) {
59 // Treat two identical passwords as a single password.
60 *password = passwords[0];
61 } else {
62 // Assume first is old password, second is new (no choice but to guess).
63 *old_password = passwords[0];
64 *password = passwords[1];
65 }
66 break;
67 case 3:
68 if (passwords[0].value() == passwords[1].value() &&
69 passwords[0].value() == passwords[2].value()) {
70 // All three passwords the same? Just treat as one and hope.
71 *password = passwords[0];
72 } else if (passwords[0].value() == passwords[1].value()) {
73 // Two the same and one different -> old password is duplicated one.
74 *old_password = passwords[0];
75 *password = passwords[2];
76 } else if (passwords[1].value() == passwords[2].value()) {
77 *old_password = passwords[0];
78 *password = passwords[1];
79 } else {
80 // Three different passwords, or first and last match with middle
81 // different. No idea which is which, so no luck.
82 return false;
83 }
84 break;
85 default:
86 return false;
87 }
88 return true;
89 }
90
54 } // namespace 91 } // namespace
55 92
56 scoped_ptr<PasswordForm> CreatePasswordForm(const WebFormElement& webform) { 93 void GetPasswordForm(const WebFormElement& form, PasswordForm* password_form)
57 WebPasswordFormData web_password_form(webform); 94 {
58 if (web_password_form.isValid()) 95 WebInputElement latest_input_element;
59 return InitPasswordFormFromWebPasswordForm(webform, web_password_form); 96 std::vector<WebInputElement> passwords;
60 return scoped_ptr<PasswordForm>(); 97 std::vector<base::string16> other_possible_usernames;
98
99 WebVector<WebFormControlElement> control_elements;
100 form.getFormControlElements(control_elements);
101
102 for (size_t i = 0; i < control_elements.size(); ++i) {
103 WebFormControlElement control_element = control_elements[i];
104 if (control_element.isActivatedSubmit())
105 password_form->submit_element = control_element.formControlName();
106
107 WebInputElement* input_element = toWebInputElement(&control_element);
108 if (!input_element)
109 continue;
110
111 if (!input_element->isEnabled())
Garrett Casto 2014/04/16 22:56:55 Nit: Can you merge this with the previous if state
112 continue;
113
114 if ((passwords.size() < kMaxPasswords) &&
115 input_element->isPasswordField()) {
116 // We assume that the username element is the input element before the
117 // first password element.
118 if (passwords.empty() && !latest_input_element.isNull()) {
119 password_form->username_element =
120 latest_input_element.nameForAutofill();
121 password_form->username_value = latest_input_element.value();
122 // Remove the selected username from other_possible_usernames.
123 if (!other_possible_usernames.empty() &&
124 !latest_input_element.value().isEmpty())
125 other_possible_usernames.resize(other_possible_usernames.size() - 1);
126 }
127 passwords.push_back(*input_element);
128 }
129
130 // Various input types such as text, url, email can be a username field.
131 if (input_element->isTextField() && !input_element->isPasswordField()) {
132 latest_input_element = *input_element;
133 // We ignore elements that have no value. Unlike username_element,
134 // other_possible_usernames is used only for autofill, not for form
135 // identification, and blank autofill entries are not useful.
136 if (!input_element->value().isEmpty())
137 other_possible_usernames.push_back(input_element->value());
138 }
139 }
140
141 // Get the document URL
142 GURL full_origin(form.document().url());
143
144 // Calculate the canonical action URL
145 WebString action = form.action();
146 if (action.isNull())
147 action = WebString(""); // missing 'action' attribute implies current URL
148 GURL full_action(form.document().completeURL(action));
149 if (!full_action.is_valid())
150 return;
151
152 // We want to keep the path but strip any authentication data, as well as
153 // query and ref portions of URL, for the form action and form origin.
154 GURL::Replacements rep;
155 rep.ClearUsername();
156 rep.ClearPassword();
157 rep.ClearQuery();
158 rep.ClearRef();
159 password_form->action = full_action.ReplaceComponents(rep);
Garrett Casto 2014/04/16 22:56:55 You don't want to do that here. Checking to see if
160 password_form->origin = full_origin.ReplaceComponents(rep);
161
162 rep.SetPathStr("");
163 password_form->signon_realm = full_origin.ReplaceComponents(rep).spec();
164
165 password_form->other_possible_usernames.insert(
Garrett Casto 2014/04/16 22:56:55 Inserting in this way was only necessary because t
166 password_form->other_possible_usernames.begin(),
167 other_possible_usernames.data(),
168 other_possible_usernames.data() +
169 other_possible_usernames.size());
170
171 WebInputElement password;
172 WebInputElement old_password;
173 if (!LocateSpecificPasswords(passwords, &password, &old_password))
174 return;
175
176 if (!password.isNull()) {
177 password_form->password_element = password.nameForAutofill();
178 password_form->password_value = password.value();
179 password_form->password_autocomplete_set = password.autoComplete();
180 }
181 if (!old_password.isNull()) {
182 password_form->old_password_element = old_password.nameForAutofill();
183 password_form->old_password_value = old_password.value();
184 }
185
186 password_form->scheme = PasswordForm::SCHEME_HTML;
187 password_form->ssl_valid = false;
188 password_form->preferred = false;
189 password_form->blacklisted_by_user = false;
190 password_form->type = PasswordForm::TYPE_MANUAL;
191 password_form->use_additional_authentication = false;
61 } 192 }
62 193
63 } // namespace autofill 194 scoped_ptr<PasswordForm> CreatePasswordForm(const WebFormElement& web_form) {
195 if (web_form.isNull())
196 return scoped_ptr<PasswordForm>();
197
198 PasswordForm* password_form = new PasswordForm();
199 return InitPasswordFormFromWebPasswordForm(web_form, password_form);
200 }
201
202 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698