OLD | NEW |
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_generation_agent.h" | 5 #include "components/autofill/content/renderer/password_generation_agent.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "components/autofill/content/common/autofill_messages.h" | 11 #include "components/autofill/content/common/autofill_messages.h" |
12 #include "components/autofill/content/renderer/form_autofill_util.h" | 12 #include "components/autofill/content/renderer/form_autofill_util.h" |
13 #include "components/autofill/content/renderer/form_classifier.h" | 13 #include "components/autofill/content/renderer/form_classifier.h" |
14 #include "components/autofill/content/renderer/password_autofill_agent.h" | 14 #include "components/autofill/content/renderer/password_autofill_agent.h" |
15 #include "components/autofill/content/renderer/password_form_conversion_utils.h" | 15 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
16 #include "components/autofill/core/common/autofill_switches.h" | 16 #include "components/autofill/core/common/autofill_switches.h" |
17 #include "components/autofill/core/common/form_data.h" | 17 #include "components/autofill/core/common/form_data.h" |
18 #include "components/autofill/core/common/password_form.h" | 18 #include "components/autofill/core/common/password_form.h" |
19 #include "components/autofill/core/common/password_form_generation_data.h" | 19 #include "components/autofill/core/common/password_form_generation_data.h" |
20 #include "components/autofill/core/common/password_generation_util.h" | 20 #include "components/autofill/core/common/password_generation_util.h" |
| 21 #include "components/autofill/core/common/signatures_util.h" |
21 #include "content/public/renderer/render_frame.h" | 22 #include "content/public/renderer/render_frame.h" |
22 #include "content/public/renderer/render_view.h" | 23 #include "content/public/renderer/render_view.h" |
23 #include "google_apis/gaia/gaia_urls.h" | 24 #include "google_apis/gaia/gaia_urls.h" |
24 #include "services/shell/public/cpp/interface_registry.h" | 25 #include "services/shell/public/cpp/interface_registry.h" |
25 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" | 26 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" |
26 #include "third_party/WebKit/public/platform/WebVector.h" | 27 #include "third_party/WebKit/public/platform/WebVector.h" |
27 #include "third_party/WebKit/public/web/WebDocument.h" | 28 #include "third_party/WebKit/public/web/WebDocument.h" |
28 #include "third_party/WebKit/public/web/WebFormElement.h" | 29 #include "third_party/WebKit/public/web/WebFormElement.h" |
29 #include "third_party/WebKit/public/web/WebInputElement.h" | 30 #include "third_party/WebKit/public/web/WebInputElement.h" |
30 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 31 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
(...skipping 17 matching lines...) Expand all Loading... |
48 passwords->push_back(*input_element); | 49 passwords->push_back(*input_element); |
49 } | 50 } |
50 } | 51 } |
51 return !passwords->empty(); | 52 return !passwords->empty(); |
52 } | 53 } |
53 | 54 |
54 bool ContainsURL(const std::vector<GURL>& urls, const GURL& url) { | 55 bool ContainsURL(const std::vector<GURL>& urls, const GURL& url) { |
55 return std::find(urls.begin(), urls.end(), url) != urls.end(); | 56 return std::find(urls.begin(), urls.end(), url) != urls.end(); |
56 } | 57 } |
57 | 58 |
58 // Finds a form in |forms| that has the same action and name as |form|. | 59 // Calculates the signature of |form| and searches it in |forms|. |
59 const PasswordFormGenerationData* FindFormGenerationData( | 60 const PasswordFormGenerationData* FindFormGenerationData( |
60 const std::vector<PasswordFormGenerationData>& forms, | 61 const std::vector<PasswordFormGenerationData>& forms, |
61 const PasswordForm& form) { | 62 const PasswordForm& form) { |
| 63 FormSignature form_signature = CalculateFormSignature(form.form_data); |
62 for (const auto& form_it : forms) { | 64 for (const auto& form_it : forms) { |
63 if (form_it.name == form.form_data.name && form_it.action == form.action) | 65 if (form_it.form_signature == form_signature) |
64 return &form_it; | 66 return &form_it; |
65 } | 67 } |
66 return nullptr; | 68 return nullptr; |
67 } | 69 } |
68 | 70 |
69 // This function returns a vector of password fields into which Chrome should | 71 // This function returns a vector of password fields into which Chrome should |
70 // fill the generated password. It assumes that |field_data| describes the field | 72 // fill the generated password. It assumes that |field_signature| describes the |
71 // where Chrome shows the password generation prompt. It returns no more | 73 // field where Chrome shows the password generation prompt. It returns no more |
72 // than 2 elements. | 74 // than 2 elements. |
73 std::vector<blink::WebInputElement> FindPasswordElementsForGeneration( | 75 std::vector<blink::WebInputElement> FindPasswordElementsForGeneration( |
74 const std::vector<blink::WebInputElement>& all_password_elements, | 76 const std::vector<blink::WebInputElement>& all_password_elements, |
75 const base::string16& field_name) { | 77 const FieldSignature field_signature) { |
76 auto iter = | 78 auto iter = std::find_if( |
77 std::find_if(all_password_elements.begin(), all_password_elements.end(), | 79 all_password_elements.begin(), all_password_elements.end(), |
78 [&field_name](const blink::WebInputElement& input) { | 80 [&field_signature](const blink::WebInputElement& input) { |
79 // Make explicit conversion before comparing with string16. | 81 FieldSignature signature = CalculateFieldSignatureByNameAndType( |
80 base::string16 input_name = input.nameForAutofill(); | 82 input.nameForAutofill(), input.formControlType().utf8()); |
81 return input_name == field_name; | 83 return signature == field_signature; |
82 }); | 84 }); |
83 std::vector<blink::WebInputElement> passwords; | 85 std::vector<blink::WebInputElement> passwords; |
84 | 86 |
85 // We copy not more than 2 fields because occasionally there are forms where | 87 // We copy not more than 2 fields because occasionally there are forms where |
86 // the security question answers are put in password fields and we don't want | 88 // the security question answers are put in password fields and we don't want |
87 // to fill those. | 89 // to fill those. |
88 for (; iter != all_password_elements.end() && passwords.size() < 2; ++iter) { | 90 for (; iter != all_password_elements.end() && passwords.size() < 2; ++iter) |
89 passwords.push_back(*iter); | 91 passwords.push_back(*iter); |
90 } | |
91 return passwords; | 92 return passwords; |
92 } | 93 } |
93 | 94 |
94 void CopyElementValueToOtherInputElements( | 95 void CopyElementValueToOtherInputElements( |
95 const blink::WebInputElement* element, | 96 const blink::WebInputElement* element, |
96 std::vector<blink::WebInputElement>* elements) { | 97 std::vector<blink::WebInputElement>* elements) { |
97 for (blink::WebInputElement& it : *elements) { | 98 for (blink::WebInputElement& it : *elements) { |
98 if (*element != it) { | 99 if (*element != it) { |
99 it.setValue(element->value(), true /* sendEvents */); | 100 it.setValue(element->value(), true /* sendEvents */); |
100 } | 101 } |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 << "used for account creation"; | 397 << "used for account creation"; |
397 continue; | 398 continue; |
398 } | 399 } |
399 } | 400 } |
400 } | 401 } |
401 | 402 |
402 VLOG(2) << "Password generation eligible form found"; | 403 VLOG(2) << "Password generation eligible form found"; |
403 std::vector<blink::WebInputElement> password_elements = | 404 std::vector<blink::WebInputElement> password_elements = |
404 generation_data ? FindPasswordElementsForGeneration( | 405 generation_data ? FindPasswordElementsForGeneration( |
405 possible_form_data.password_elements, | 406 possible_form_data.password_elements, |
406 generation_data->generation_field.name) | 407 generation_data->field_signature) |
407 : possible_form_data.password_elements; | 408 : possible_form_data.password_elements; |
408 if (password_elements.empty()) { | 409 if (password_elements.empty()) { |
409 // It might be if JavaScript changes field names. | 410 // It might be if JavaScript changes field names. |
410 VLOG(2) << "Fields for generation are not found"; | 411 VLOG(2) << "Fields for generation are not found"; |
411 return; | 412 return; |
412 } | 413 } |
413 generation_form_data_.reset(new AccountCreationFormData( | 414 generation_form_data_.reset(new AccountCreationFormData( |
414 possible_form_data.form, std::move(password_elements))); | 415 possible_form_data.form, std::move(password_elements))); |
415 generation_element_ = generation_form_data_->password_elements[0]; | 416 generation_element_ = generation_form_data_->password_elements[0]; |
416 generation_element_.setAttribute("aria-autocomplete", "list"); | 417 generation_element_.setAttribute("aria-autocomplete", "list"); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 form_util::GetUnownedFormFieldElements(doc.all(), nullptr); | 559 form_util::GetUnownedFormFieldElements(doc.all(), nullptr); |
559 } | 560 } |
560 | 561 |
561 if (!password_form) | 562 if (!password_form) |
562 return; | 563 return; |
563 | 564 |
564 generation_element_ = last_focused_password_element_; | 565 generation_element_ = last_focused_password_element_; |
565 std::vector<blink::WebInputElement> password_elements; | 566 std::vector<blink::WebInputElement> password_elements; |
566 GetAccountCreationPasswordFields(control_elements, &password_elements); | 567 GetAccountCreationPasswordFields(control_elements, &password_elements); |
567 password_elements = FindPasswordElementsForGeneration( | 568 password_elements = FindPasswordElementsForGeneration( |
568 password_elements, last_focused_password_element_.nameForAutofill()); | 569 password_elements, |
| 570 CalculateFieldSignatureByNameAndType( |
| 571 last_focused_password_element_.nameForAutofill(), |
| 572 last_focused_password_element_.formControlType().utf8())); |
569 generation_form_data_.reset(new AccountCreationFormData( | 573 generation_form_data_.reset(new AccountCreationFormData( |
570 make_linked_ptr(password_form.release()), password_elements)); | 574 make_linked_ptr(password_form.release()), password_elements)); |
571 is_manually_triggered_ = true; | 575 is_manually_triggered_ = true; |
572 ShowGenerationPopup(); | 576 ShowGenerationPopup(); |
573 } | 577 } |
574 | 578 |
575 const mojom::PasswordManagerDriverPtr& | 579 const mojom::PasswordManagerDriverPtr& |
576 PasswordGenerationAgent::GetPasswordManagerDriver() { | 580 PasswordGenerationAgent::GetPasswordManagerDriver() { |
577 DCHECK(password_agent_); | 581 DCHECK(password_agent_); |
578 return password_agent_->GetPasswordManagerDriver(); | 582 return password_agent_->GetPasswordManagerDriver(); |
579 } | 583 } |
580 | 584 |
581 } // namespace autofill | 585 } // namespace autofill |
OLD | NEW |