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

Unified Diff: components/password_manager/core/browser/password_form_manager.cc

Issue 2747733004: [Password Manager] Send username correction votes (Closed)
Patch Set: Changes addressed to reviewer comments Created 3 years, 9 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/password_manager/core/browser/password_form_manager.cc
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 0c30c1677cf966e7c3f08c5083081e0d360fde4d..b371b69a71a0453e2a6ff0c54ad74d22b85691d5 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -37,6 +37,7 @@
using autofill::FormStructure;
using autofill::PasswordForm;
+using autofill::PossibleUsernamePair;
using base::Time;
// Shorten the name to spare line breaks. The code provides enough context
@@ -110,12 +111,20 @@ void SanitizePossibleUsernames(PasswordForm* form) {
auto new_end = std::unique(usernames.begin(), usernames.end());
// Filter out |form->username_value|.
- new_end = std::remove(usernames.begin(), new_end, form->username_value);
+ const base::string16& username_value = form->username_value;
+ new_end = std::remove_if(usernames.begin(), new_end,
+ [&username_value](PossibleUsernamePair pair) {
dvadym 2017/03/22 10:56:18 Nit: PossibleUsernamePair -> const PossibleUsernam
kolos1 2017/03/22 13:40:39 Done.
+ return pair.first == username_value;
+ });
// Filter out sensitive information.
- new_end = std::remove_if(usernames.begin(), new_end,
- autofill::IsValidCreditCardNumber);
- new_end = std::remove_if(usernames.begin(), new_end, autofill::IsSSN);
+ new_end =
+ std::remove_if(usernames.begin(), new_end, [](PossibleUsernamePair pair) {
dvadym 2017/03/22 10:56:18 Nit: PossibleUsernamePair -> const PossibleUsernam
kolos1 2017/03/22 13:40:39 Done.
+ return autofill::IsValidCreditCardNumber(pair.first);
+ });
+ new_end = std::remove_if(
+ usernames.begin(), new_end,
+ [](PossibleUsernamePair pair) { return autofill::IsSSN(pair.first); });
dvadym 2017/03/22 10:56:19 Nit: PossibleUsernamePair -> const PossibleUsernam
kolos1 2017/03/22 13:40:39 Done.
usernames.erase(new_end, usernames.end());
}
@@ -440,7 +449,7 @@ void PasswordFormManager::Update(
const autofill::PasswordForm& credentials_to_update) {
if (observed_form_.IsPossibleChangePasswordForm()) {
FormStructure form_structure(credentials_to_update.form_data);
- UploadPasswordVote(autofill::NEW_PASSWORD,
+ UploadPasswordVote(observed_form_, autofill::NEW_PASSWORD,
form_structure.FormSignatureAsStr());
}
base::string16 password_to_save = pending_credentials_.password_value;
@@ -674,7 +683,7 @@ void PasswordFormManager::ProcessUpdate() {
// Do not send votes on change password forms, since they were already sent in
// Update() method.
if (!observed_form_.IsPossibleChangePasswordForm())
- SendAutofillVotes(observed_form_, &pending_credentials_);
+ SendVoteOnCredentialsReuse(observed_form_, &pending_credentials_);
}
bool PasswordFormManager::UpdatePendingCredentialsIfOtherPossibleUsername(
@@ -682,7 +691,7 @@ bool PasswordFormManager::UpdatePendingCredentialsIfOtherPossibleUsername(
for (const auto& key_value : best_matches_) {
const PasswordForm& match = *key_value.second;
for (size_t i = 0; i < match.other_possible_usernames.size(); ++i) {
- if (match.other_possible_usernames[i] == username) {
+ if (match.other_possible_usernames[i].first == username) {
pending_credentials_ = match;
return true;
}
@@ -691,8 +700,40 @@ bool PasswordFormManager::UpdatePendingCredentialsIfOtherPossibleUsername(
return false;
}
-void PasswordFormManager::SendAutofillVotes(const PasswordForm& observed,
- PasswordForm* pending) {
+bool PasswordFormManager::FindUsernameInOtherPossibleUsernames(
dvadym 2017/03/22 10:56:19 I'm wondering whether we should match credentials
kolos1 2017/03/22 13:40:39 Great point! I was going to check the password val
+ const autofill::PasswordForm& match,
+ const base::string16& username) {
+ DCHECK(!username_correction_vote_);
+
+ for (const autofill::PossibleUsernamePair& pair :
dvadym 2017/03/22 10:56:18 Nit: autofill::PossibleUsernamePair->PossibleUsern
kolos1 2017/03/22 13:40:39 Done.
+ match.other_possible_usernames) {
+ if (pair.second.empty())
dvadym 2017/03/22 10:56:19 I feel that we shouldn't skip fields with empty id
kolos1 2017/03/22 13:40:39 Done.
+ continue;
+ if (pair.first == username) {
+ username_correction_vote_.reset(new autofill::PasswordForm(match));
+ username_correction_vote_->username_element = pair.second;
+ return true;
+ }
+ }
+ return false;
+}
+
+void PasswordFormManager::FindCorrectedUsernameElement(
+ const base::string16& username) {
+ for (const auto& key_value : best_matches_) {
+ PasswordForm match(*key_value.second);
+ if (FindUsernameInOtherPossibleUsernames(match, username))
+ return;
+ }
+ for (const autofill::PasswordForm* match : not_best_matches_) {
+ if (FindUsernameInOtherPossibleUsernames(*match, username))
+ return;
+ }
+}
+
+void PasswordFormManager::SendVoteOnCredentialsReuse(
+ const PasswordForm& observed,
+ PasswordForm* pending) {
// Ignore |pending_structure| if its FormData has no fields. This is to
// weed out those credentials that were saved before FormData was added
// to PasswordForm. Even without this check, these FormStructure's won't
@@ -713,7 +754,7 @@ void PasswordFormManager::SendAutofillVotes(const PasswordForm& observed,
// in cases where we currently save the wrong username isn't great.
// TODO(gcasto): Determine if generation should be offered in this case.
if (pending->times_used == 1 && selected_username_.empty()) {
- if (UploadPasswordVote(autofill::ACCOUNT_CREATION_PASSWORD,
+ if (UploadPasswordVote(*pending, autofill::ACCOUNT_CREATION_PASSWORD,
observed_structure.FormSignatureAsStr())) {
pending->generation_upload_status =
autofill::PasswordForm::POSITIVE_SIGNAL_SENT;
@@ -724,7 +765,7 @@ void PasswordFormManager::SendAutofillVotes(const PasswordForm& observed,
// A signal was sent that this was an account creation form, but the
// credential is now being used on the same form again. This cancels out
// the previous vote.
- if (UploadPasswordVote(autofill::NOT_ACCOUNT_CREATION_PASSWORD,
+ if (UploadPasswordVote(*pending, autofill::NOT_ACCOUNT_CREATION_PASSWORD,
std::string())) {
pending->generation_upload_status =
autofill::PasswordForm::NEGATIVE_SIGNAL_SENT;
@@ -732,11 +773,12 @@ void PasswordFormManager::SendAutofillVotes(const PasswordForm& observed,
} else if (generation_popup_was_shown_) {
// Even if there is no autofill vote to be sent, send the vote about the
// usage of the generation popup.
- UploadPasswordVote(autofill::UNKNOWN_TYPE, std::string());
+ UploadPasswordVote(*pending, autofill::UNKNOWN_TYPE, std::string());
}
}
bool PasswordFormManager::UploadPasswordVote(
+ const autofill::PasswordForm& form_to_upload,
const autofill::ServerFieldType& password_type,
const std::string& login_form_signature) {
// Check if there is any vote to be sent.
@@ -750,14 +792,10 @@ bool PasswordFormManager::UploadPasswordVote(
if (!autofill_manager || !autofill_manager->download_manager())
return false;
- bool is_update = password_type == autofill::NEW_PASSWORD ||
- password_type == autofill::PROBABLY_NEW_PASSWORD ||
- password_type == autofill::NOT_NEW_PASSWORD;
// If this is an update, a vote about the observed form is sent. If the user
// re-uses credentials, a vote about the saved form is sent. If the user saves
// credentials, the observed and pending forms are the same.
- FormStructure form_structure(is_update ? observed_form_.form_data
- : pending_credentials_.form_data);
+ FormStructure form_structure(form_to_upload.form_data);
if (!autofill_manager->ShouldUploadForm(form_structure) ||
!form_structure.ShouldBeCrowdsourced()) {
UMA_HISTOGRAM_BOOLEAN("PasswordGeneration.UploadStarted", false);
@@ -765,30 +803,36 @@ bool PasswordFormManager::UploadPasswordVote(
}
autofill::ServerFieldTypeSet available_field_types;
- if (has_autofill_vote) {
- // A map from field names to field types.
- FieldTypeMap field_types;
- DCHECK(submitted_form_);
- if (is_update) {
- if (submitted_form_->new_password_element.empty())
- return false;
- SetFieldLabelsOnUpdate(password_type, *submitted_form_, &field_types);
- } else {
- SetFieldLabelsOnSave(password_type, *submitted_form_, &field_types);
- if (password_type == autofill::ACCOUNT_CREATION_PASSWORD) {
- field_types[pending_credentials_.username_element] = autofill::USERNAME;
+ if (password_type != autofill::USERNAME) {
+ if (has_autofill_vote) {
+ // A map from field names to field types.
+ FieldTypeMap field_types;
+ DCHECK(submitted_form_);
+ bool is_update = password_type == autofill::NEW_PASSWORD ||
+ password_type == autofill::PROBABLY_NEW_PASSWORD ||
+ password_type == autofill::NOT_NEW_PASSWORD;
+ if (is_update) {
+ if (submitted_form_->new_password_element.empty())
+ return false;
+ SetFieldLabelsOnUpdate(password_type, *submitted_form_, &field_types);
+ } else { // Saving.
+ SetFieldLabelsOnSave(password_type, *submitted_form_, &field_types);
}
+ field_types[submitted_form_->confirmation_password_element] =
+ autofill::CONFIRMATION_PASSWORD;
+ LabelFields(field_types, &form_structure, &available_field_types);
}
- field_types[submitted_form_->confirmation_password_element] =
- autofill::CONFIRMATION_PASSWORD;
+
+ if (generation_popup_was_shown_)
+ AddGeneratedVote(&form_structure);
+ if (form_classifier_outcome_ != kNoOutcome)
+ AddFormClassifierVote(&form_structure);
+ } else { // Username correction vote.
+ FieldTypeMap field_types;
+ field_types[form_to_upload.username_element] = autofill::USERNAME;
LabelFields(field_types, &form_structure, &available_field_types);
}
- if (generation_popup_was_shown_)
- AddGeneratedVote(&form_structure);
- if (form_classifier_outcome_ != kNoOutcome)
- AddFormClassifierVote(&form_structure);
-
// Force uploading as these events are relatively rare and we want to make
// sure to receive them.
form_structure.set_upload_required(UPLOAD_REQUIRED);
@@ -969,6 +1013,7 @@ void PasswordFormManager::CreatePendingCredentials() {
}
} else {
CreatePendingCredentialsForNewCredentials();
+ FindCorrectedUsernameElement(submitted_form_->username_value);
}
if (!IsValidAndroidFacetURI(pending_credentials_.signon_realm)) {
@@ -1161,19 +1206,22 @@ void PasswordFormManager::CreatePendingCredentialsForNewCredentials() {
}
void PasswordFormManager::OnNopeUpdateClicked() {
- UploadPasswordVote(autofill::NOT_NEW_PASSWORD, std::string());
+ UploadPasswordVote(observed_form_, autofill::NOT_NEW_PASSWORD, std::string());
}
void PasswordFormManager::OnNeverClicked() {
- UploadPasswordVote(autofill::UNKNOWN_TYPE, std::string());
+ UploadPasswordVote(pending_credentials_, autofill::UNKNOWN_TYPE,
+ std::string());
PermanentlyBlacklist();
}
void PasswordFormManager::OnNoInteraction(bool is_update) {
if (is_update)
- UploadPasswordVote(autofill::PROBABLY_NEW_PASSWORD, std::string());
+ UploadPasswordVote(observed_form_, autofill::PROBABLY_NEW_PASSWORD,
+ std::string());
else {
- UploadPasswordVote(autofill::UNKNOWN_TYPE, std::string());
+ UploadPasswordVote(pending_credentials_, autofill::UNKNOWN_TYPE,
+ std::string());
}
}
@@ -1236,12 +1284,17 @@ void PasswordFormManager::SendVotesOnSave() {
// Credentials that have been previously used (e.g., PSL matches) are checked
// to see if they are valid account creation forms.
if (pending_credentials_.times_used == 0) {
- autofill::ServerFieldType password_type = autofill::PASSWORD;
- if (does_look_like_signup_form_)
- password_type = autofill::PROBABLY_ACCOUNT_CREATION_PASSWORD;
- UploadPasswordVote(password_type, std::string());
+ autofill::ServerFieldType password_type = autofill::PASSWORD;
+ if (does_look_like_signup_form_)
+ password_type = autofill::PROBABLY_ACCOUNT_CREATION_PASSWORD;
+ UploadPasswordVote(pending_credentials_, password_type, std::string());
+ if (username_correction_vote_) {
+ UploadPasswordVote(
+ *username_correction_vote_, autofill::USERNAME,
+ FormStructure(observed_form_.form_data).FormSignatureAsStr());
+ }
} else
- SendAutofillVotes(observed_form_, &pending_credentials_);
+ SendVoteOnCredentialsReuse(observed_form_, &pending_credentials_);
}
void PasswordFormManager::SetUserAction(UserAction user_action) {

Powered by Google App Engine
This is Rietveld 408576698