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

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

Issue 2906383003: Teach PasswordAutofillAgent sometimes match prefixes of usernames (Closed)
Patch Set: . Created 3 years, 7 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_autofill_agent.cc
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 642f6ff863bf131e0268361f5924545bc5ba5fbc..f1505962828835b6c27eff934458875a02b44563 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -267,13 +267,14 @@ bool IsElementEditable(const blink::WebInputElement& element) {
return element.IsEnabled() && !element.IsReadOnly();
}
-bool DoUsernamesMatch(const base::string16& username1,
- const base::string16& username2,
+bool DoUsernamesMatch(const base::string16& potential_suggestion,
+ const base::string16& current_username,
bool exact_match) {
- if (exact_match)
- return username1 == username2;
- return FieldIsSuggestionSubstringStartingOnTokenBoundary(username1, username2,
- true);
+ bool match = (potential_suggestion == current_username);
+ return exact_match
+ ? match
+ : (match || IsPrefixStartingOnTokenBoundary(
+ current_username, potential_suggestion, true));
dvadym 2017/06/01 12:15:56 As far as I understand the main use case is emails
melandory 2017/06/12 14:56:12 My motivation was that since currently gmail suffe
vabr (Chromium) 2017/06/12 18:56:58 Currently case sensitive equality is required. Let
}
// Returns |true| if the given element is editable. Otherwise, returns |false|.
@@ -358,6 +359,51 @@ void UpdateFieldValueAndPropertiesMaskMap(
}
}
+void FindMatchesByUsername(const PasswordFormFillData& fill_data,
+ const base::string16& current_username,
+ bool exact_username_match,
+ RendererSavePasswordProgressLogger* logger,
+ base::string16* username,
+ base::string16* password) {
+ // Look for any suitable matches to current field text.
+ if (DoUsernamesMatch(fill_data.username_field.value, current_username,
+ exact_username_match)) {
+ *username = fill_data.username_field.value;
+ *password = fill_data.password_field.value;
+ if (logger)
+ logger->LogMessage(Logger::STRING_USERNAMES_MATCH);
+ } else {
+ // Scan additional logins for a match.
+ for (const auto& it : fill_data.additional_logins) {
+ if (DoUsernamesMatch(it.first, current_username, exact_username_match)) {
+ *username = it.first;
+ *password = it.second.password;
+ break;
+ }
+ }
+ if (logger) {
+ logger->LogBoolean(Logger::STRING_MATCH_IN_ADDITIONAL,
+ !(username->empty() && password->empty()));
+ }
+
+ // Check possible usernames.
+ if (username->empty() && password->empty()) {
+ for (const auto& it : fill_data.other_possible_usernames) {
+ for (size_t i = 0; i < it.second.size(); ++i) {
+ if (DoUsernamesMatch(it.second[i], current_username,
+ exact_username_match)) {
+ *username = it.second[i];
+ *password = it.first.password;
+ break;
+ }
+ }
+ if (!username->empty() && !password->empty())
+ break;
+ }
+ }
+ }
+}
+
// This function attempts to fill |username_element| and |password_element|
// with values from |fill_data|. The |password_element| will only have the
// suggestedValue set, and will be registered for copying that to the real
@@ -389,43 +435,9 @@ bool FillUserNameAndPassword(
base::string16 username;
base::string16 password;
- // Look for any suitable matches to current field text.
- if (DoUsernamesMatch(fill_data.username_field.value, current_username,
- exact_username_match)) {
- username = fill_data.username_field.value;
- password = fill_data.password_field.value;
- if (logger)
- logger->LogMessage(Logger::STRING_USERNAMES_MATCH);
- } else {
- // Scan additional logins for a match.
- for (const auto& it : fill_data.additional_logins) {
- if (DoUsernamesMatch(it.first, current_username, exact_username_match)) {
- username = it.first;
- password = it.second.password;
- break;
- }
- }
- if (logger) {
- logger->LogBoolean(Logger::STRING_MATCH_IN_ADDITIONAL,
- !(username.empty() && password.empty()));
- }
+ FindMatchesByUsername(fill_data, current_username, exact_username_match,
+ logger, &username, &password);
- // Check possible usernames.
- if (username.empty() && password.empty()) {
- for (const auto& it : fill_data.other_possible_usernames) {
- for (size_t i = 0; i < it.second.size(); ++i) {
- if (DoUsernamesMatch(
- it.second[i], current_username, exact_username_match)) {
- username = it.second[i];
- password = it.first.password;
- break;
- }
- }
- if (!username.empty() && !password.empty())
- break;
- }
- }
- }
if (password.empty())
return false;
@@ -447,9 +459,10 @@ bool FillUserNameAndPassword(
form_util::PreviewSuggestion(username, current_username,
username_element);
}
- } else if (current_username != username) {
+ } else if (exact_username_match && current_username != username) {
// If the username can't be filled and it doesn't match a saved password
- // as is, don't autofill a password.
+ // as is, autofill the password only in case the username element id read
+ // only.
return false;
}
@@ -535,12 +548,15 @@ bool FillFormOnPasswordReceived(
blink::WebString::FromUTF16(fill_data.username_field.value));
}
- // Fill if we have an exact match for the username. Note that this sets
- // username to autofilled.
+ bool exact_username_match =
+ username_element.IsNull() || IsElementEditable(username_element);
+ // User the exact match for the editable username fields and allow prefix
+ // match for read-only username fields.
+ // Note that this sets username to autofilled.
return FillUserNameAndPassword(
- &username_element, &password_element, fill_data,
- true /* exact_username_match */, false /* set_selection */,
- field_value_and_properties_map, registration_callback, logger);
+ &username_element, &password_element, fill_data, exact_username_match,
+ false /* set_selection */, field_value_and_properties_map,
+ registration_callback, logger);
}
// Annotate |forms| with form and field signatures as HTML attributes.

Powered by Google App Engine
This is Rietveld 408576698