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

Unified Diff: components/autofill/content/renderer/password_generation_agent.cc

Issue 2917933002: [PasswordGeneration] Improve change/confirm password field detection. (Closed)
Patch Set: Address more comments. Created 3 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: components/autofill/content/renderer/password_generation_agent.cc
diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc
index bf50f220493544252111f122723c9c80668fe832..f9fe4c97345751f016629265c79bd45d9554e130 100644
--- a/components/autofill/content/renderer/password_generation_agent.cc
+++ b/components/autofill/content/renderer/password_generation_agent.cc
@@ -4,7 +4,9 @@
#include "components/autofill/content/renderer/password_generation_agent.h"
+#include <algorithm>
#include <memory>
+#include <utility>
#include "base/command_line.h"
#include "base/logging.h"
@@ -39,17 +41,17 @@ namespace {
using Logger = autofill::SavePasswordProgressLogger;
-// Returns true if we think that this form is for account creation. |passwords|
-// is filled with the password field(s) in the form.
+// Returns true if we think that this form is for account creation. Password
+// field(s) of the form are pushed back to |passwords|.
bool GetAccountCreationPasswordFields(
const std::vector<blink::WebFormControlElement>& control_elements,
std::vector<blink::WebInputElement>* passwords) {
- for (size_t i = 0; i < control_elements.size(); i++) {
+ for (const auto& control_element : control_elements) {
const blink::WebInputElement* input_element =
- ToWebInputElement(&control_elements[i]);
- if (input_element && input_element->IsTextField()) {
- if (input_element->IsPasswordField())
- passwords->push_back(*input_element);
+ ToWebInputElement(&control_element);
+ if (input_element && input_element->IsTextField() &&
+ input_element->IsPasswordField()) {
+ passwords->push_back(*input_element);
}
}
return !passwords->empty();
@@ -71,10 +73,33 @@ const PasswordFormGenerationData* FindFormGenerationData(
return nullptr;
}
-// This function returns a vector of password fields into which Chrome should
-// fill the generated password. It assumes that |field_signature| describes the
-// field where Chrome shows the password generation prompt. It returns no more
-// than 2 elements.
+// Returns a vector of up to 2 password fields with autocomplete attribute set
+// to "new-password". These will be filled with the generated password.
+std::vector<blink::WebInputElement> FindNewPasswordElementsMarkedBySite(
+ const std::vector<blink::WebInputElement>& all_password_elements) {
+ std::vector<blink::WebInputElement> passwords;
+
+ auto is_new_password_field = [](const blink::WebInputElement& element) {
+ return HasAutocompleteAttributeValue(element, "new-password");
+ };
+
+ auto field_iter =
+ std::find_if(all_password_elements.begin(), all_password_elements.end(),
+ is_new_password_field);
+ if (field_iter != all_password_elements.end()) {
+ passwords.push_back(*field_iter++);
+ field_iter = std::find_if(field_iter, all_password_elements.end(),
+ is_new_password_field);
+ if (field_iter != all_password_elements.end())
+ passwords.push_back(*field_iter);
+ }
+
+ return passwords;
+}
+
+// Returns a vector of up to 2 password fields into which Chrome should fill the
+// generated password. It assumes that |field_signature| describes the field
+// where Chrome shows the password generation prompt.
std::vector<blink::WebInputElement> FindPasswordElementsForGeneration(
const std::vector<blink::WebInputElement>& all_password_elements,
const PasswordFormGenerationData& generation_data) {
@@ -85,11 +110,12 @@ std::vector<blink::WebInputElement> FindPasswordElementsForGeneration(
const blink::WebInputElement& input = *iter;
FieldSignature signature = CalculateFieldSignatureByNameAndType(
input.NameForAutofill().Utf16(), input.FormControlType().Utf8());
- if (signature == generation_data.field_signature)
+ if (signature == generation_data.field_signature) {
generation_field_iter = iter;
- else if (generation_data.confirmation_field_signature &&
- signature == *generation_data.confirmation_field_signature)
+ } else if (generation_data.confirmation_field_signature &&
+ signature == *generation_data.confirmation_field_signature) {
confirmation_field_iter = iter;
+ }
}
std::vector<blink::WebInputElement> passwords;
@@ -114,17 +140,12 @@ void CopyElementValueToOtherInputElements(
}
}
-bool AutocompleteAttributesSetForGeneration(const PasswordForm& form) {
- return form.username_marked_by_site && form.new_password_marked_by_site;
-}
-
} // namespace
PasswordGenerationAgent::AccountCreationFormData::AccountCreationFormData(
linked_ptr<PasswordForm> password_form,
std::vector<blink::WebInputElement> passwords)
- : form(password_form),
- password_elements(passwords) {}
+ : form(password_form), password_elements(std::move(passwords)) {}
PasswordGenerationAgent::AccountCreationFormData::AccountCreationFormData(
const AccountCreationFormData& other) = default;
@@ -277,9 +298,8 @@ void PasswordGenerationAgent::FindPossibleGenerationForm() {
&passwords)) {
if (form_classifier_enabled_)
RunFormClassifierAndSaveVote(forms[i], *password_form);
- AccountCreationFormData ac_form_data(
- make_linked_ptr(password_form.release()), passwords);
- possible_account_creation_forms_.push_back(ac_form_data);
+ possible_account_creation_forms_.emplace_back(
+ make_linked_ptr(password_form.release()), std::move(passwords));
}
}
@@ -389,8 +409,11 @@ void PasswordGenerationAgent::DetermineGenerationElement() {
for (auto& possible_form_data : possible_account_creation_forms_) {
PasswordForm* possible_password_form = possible_form_data.form.get();
const PasswordFormGenerationData* generation_data = nullptr;
+
+ std::vector<blink::WebInputElement> password_elements;
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kLocalHeuristicsOnlyForPasswordGeneration)) {
+ password_elements = possible_form_data.password_elements;
VLOG(2) << "Bypassing additional checks.";
} else if (!ContainsURL(not_blacklisted_password_form_origins_,
possible_password_form->origin)) {
@@ -399,28 +422,31 @@ void PasswordGenerationAgent::DetermineGenerationElement() {
} else {
generation_data = FindFormGenerationData(generation_enabled_forms_,
*possible_password_form);
- if (!generation_data) {
- if (AutocompleteAttributesSetForGeneration(*possible_password_form)) {
- LogMessage(Logger::STRING_GENERATION_RENDERER_AUTOCOMPLETE_ATTRIBUTE);
- password_generation::LogPasswordGenerationEvent(
- password_generation::AUTOCOMPLETE_ATTRIBUTES_ENABLED_GENERATION);
- } else {
+ if (generation_data) {
+ password_elements = FindPasswordElementsForGeneration(
+ possible_form_data.password_elements, *generation_data);
+ } else {
+ if (!possible_password_form->new_password_marked_by_site) {
LogMessage(Logger::STRING_GENERATION_RENDERER_NO_SERVER_SIGNAL);
continue;
}
+
+ LogMessage(Logger::STRING_GENERATION_RENDERER_AUTOCOMPLETE_ATTRIBUTE);
+ password_generation::LogPasswordGenerationEvent(
+ password_generation::AUTOCOMPLETE_ATTRIBUTES_ENABLED_GENERATION);
+
+ password_elements = FindNewPasswordElementsMarkedBySite(
+ possible_form_data.password_elements);
}
}
+
LogMessage(Logger::STRING_GENERATION_RENDERER_ELIGIBLE_FORM_FOUND);
- std::vector<blink::WebInputElement> password_elements =
- generation_data
- ? FindPasswordElementsForGeneration(
- possible_form_data.password_elements, *generation_data)
- : possible_form_data.password_elements;
if (password_elements.empty()) {
// It might be if JavaScript changes field names.
LogMessage(Logger::STRING_GENERATION_RENDERER_NO_FIELD_FOUND);
return;
}
+
generation_form_data_.reset(new AccountCreationFormData(
possible_form_data.form, std::move(password_elements)));
generation_element_ = generation_form_data_->password_elements[0];

Powered by Google App Engine
This is Rietveld 408576698