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

Side by Side Diff: chrome/browser/password_manager/password_form_manager.cc

Issue 23533069: [password generation] Always allow generated passwords to be shown. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 7 years, 3 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
« no previous file with comments | « no previous file | chrome/browser/password_manager/password_form_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/password_manager/password_form_manager.h" 5 #include "chrome/browser/password_manager/password_form_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_split.h" 10 #include "base/strings/string_split.h"
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 return state_ == POST_MATCHING_PHASE; 285 return state_ == POST_MATCHING_PHASE;
286 } 286 }
287 287
288 void PasswordFormManager::OnRequestDone( 288 void PasswordFormManager::OnRequestDone(
289 const std::vector<PasswordForm*>& logins_result) { 289 const std::vector<PasswordForm*>& logins_result) {
290 // Note that the result gets deleted after this call completes, but we own 290 // Note that the result gets deleted after this call completes, but we own
291 // the PasswordForm objects pointed to by the result vector, thus we keep 291 // the PasswordForm objects pointed to by the result vector, thus we keep
292 // copies to a minimum here. 292 // copies to a minimum here.
293 293
294 int best_score = 0; 294 int best_score = 0;
295 std::vector<PasswordForm> empties; // Empty-path matches in result set. 295 // These credentials will be in the final result regardless of score.
296 std::vector<PasswordForm> credentials_to_keep;
296 for (size_t i = 0; i < logins_result.size(); i++) { 297 for (size_t i = 0; i < logins_result.size(); i++) {
297 if (IgnoreResult(*logins_result[i])) { 298 if (IgnoreResult(*logins_result[i])) {
298 delete logins_result[i]; 299 delete logins_result[i];
299 continue; 300 continue;
300 } 301 }
301 // Score and update best matches. 302 // Score and update best matches.
302 int current_score = ScoreResult(*logins_result[i]); 303 int current_score = ScoreResult(*logins_result[i]);
303 // This check is here so we can append empty path matches in the event 304 // This check is here so we can append empty path matches in the event
304 // they don't score as high as others and aren't added to best_matches_. 305 // they don't score as high as others and aren't added to best_matches_.
305 // This is most commonly imported firefox logins. We skip blacklisted 306 // This is most commonly imported firefox logins. We skip blacklisted
306 // ones because clearly we don't want to autofill them, and secondly 307 // ones because clearly we don't want to autofill them, and secondly
307 // because they only mean something when we have no other matches already 308 // because they only mean something when we have no other matches already
308 // saved in Chrome - in which case they'll make it through the regular 309 // saved in Chrome - in which case they'll make it through the regular
309 // scoring flow below by design. Note signon_realm == origin implies empty 310 // scoring flow below by design. Note signon_realm == origin implies empty
310 // path logins_result, since signon_realm is a prefix of origin for HTML 311 // path logins_result, since signon_realm is a prefix of origin for HTML
311 // password forms. 312 // password forms.
312 // TODO(timsteele): Bug 1269400. We probably should do something more 313 // TODO(timsteele): Bug 1269400. We probably should do something more
313 // elegant for any shorter-path match instead of explicitly handling empty 314 // elegant for any shorter-path match instead of explicitly handling empty
314 // path matches. 315 // path matches.
315 if ((observed_form_.scheme == PasswordForm::SCHEME_HTML) && 316 if ((observed_form_.scheme == PasswordForm::SCHEME_HTML) &&
316 (observed_form_.signon_realm == logins_result[i]->origin.spec()) && 317 (observed_form_.signon_realm == logins_result[i]->origin.spec()) &&
317 (current_score > 0) && (!logins_result[i]->blacklisted_by_user)) { 318 (current_score > 0) && (!logins_result[i]->blacklisted_by_user)) {
318 empties.push_back(*logins_result[i]); 319 credentials_to_keep.push_back(*logins_result[i]);
319 } 320 }
320 321
322 // Always keep generated passwords as part of the result set. If a user
323 // generates a password on a signup form, it should show on a login form
324 // even if they have a previous login saved.
325 // TODO(gcasto): We don't want to cut credentials that were saved on signup
326 // forms even if they weren't generated, but currently it's hard to
327 // distinguish between those forms and two different login forms on the
328 // same domain. Filed http://crbug.com/294468 to look into this.
329 if (logins_result[i]->type == PasswordForm::TYPE_GENERATED)
330 credentials_to_keep.push_back(*logins_result[i]);
331
321 if (current_score < best_score) { 332 if (current_score < best_score) {
322 delete logins_result[i]; 333 delete logins_result[i];
323 continue; 334 continue;
324 } 335 }
325 if (current_score == best_score) { 336 if (current_score == best_score) {
326 best_matches_[logins_result[i]->username_value] = logins_result[i]; 337 best_matches_[logins_result[i]->username_value] = logins_result[i];
327 } else if (current_score > best_score) { 338 } else if (current_score > best_score) {
328 best_score = current_score; 339 best_score = current_score;
329 // This new login has a better score than all those up to this point 340 // This new login has a better score than all those up to this point
330 // Note 'this' owns all the PasswordForms in best_matches_. 341 // Note 'this' owns all the PasswordForms in best_matches_.
331 STLDeleteValues(&best_matches_); 342 STLDeleteValues(&best_matches_);
332 best_matches_.clear(); 343 best_matches_.clear();
333 preferred_match_ = NULL; // Don't delete, its owned by best_matches_. 344 preferred_match_ = NULL; // Don't delete, its owned by best_matches_.
334 best_matches_[logins_result[i]->username_value] = logins_result[i]; 345 best_matches_[logins_result[i]->username_value] = logins_result[i];
335 } 346 }
336 preferred_match_ = logins_result[i]->preferred ? logins_result[i] 347 preferred_match_ = logins_result[i]->preferred ? logins_result[i]
337 : preferred_match_; 348 : preferred_match_;
338 } 349 }
339 // We're done matching now. 350 // We're done matching now.
340 state_ = POST_MATCHING_PHASE; 351 state_ = POST_MATCHING_PHASE;
341 352
342 if (best_score <= 0) { 353 if (best_score <= 0) {
343 return; 354 return;
344 } 355 }
345 356
346 for (std::vector<PasswordForm>::const_iterator it = empties.begin(); 357 for (std::vector<PasswordForm>::const_iterator it =
347 it != empties.end(); ++it) { 358 credentials_to_keep.begin();
359 it != credentials_to_keep.end(); ++it) {
348 // If we don't already have a result with the same username, add the 360 // If we don't already have a result with the same username, add the
349 // lower-scored empty-path match (if it had equal score it would already be 361 // lower-scored match (if it had equal score it would already be in
350 // in best_matches_). 362 // best_matches_).
351 if (best_matches_.find(it->username_value) == best_matches_.end()) 363 if (best_matches_.find(it->username_value) == best_matches_.end())
352 best_matches_[it->username_value] = new PasswordForm(*it); 364 best_matches_[it->username_value] = new PasswordForm(*it);
353 } 365 }
354 366
355 // It is possible we have at least one match but have no preferred_match_, 367 // It is possible we have at least one match but have no preferred_match_,
356 // because a user may have chosen to 'Forget' the preferred match. So we 368 // because a user may have chosen to 'Forget' the preferred match. So we
357 // just pick the first one and whichever the user selects for submit will 369 // just pick the first one and whichever the user selects for submit will
358 // be saved as preferred. 370 // be saved as preferred.
359 DCHECK(!best_matches_.empty()); 371 DCHECK(!best_matches_.empty());
360 if (!preferred_match_) 372 if (!preferred_match_)
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 628
617 void PasswordFormManager::SubmitFailed() { 629 void PasswordFormManager::SubmitFailed() {
618 submit_result_ = kSubmitResultFailed; 630 submit_result_ = kSubmitResultFailed;
619 } 631 }
620 632
621 void PasswordFormManager::SendNotBlacklistedToRenderer() { 633 void PasswordFormManager::SendNotBlacklistedToRenderer() {
622 content::RenderViewHost* host = web_contents_->GetRenderViewHost(); 634 content::RenderViewHost* host = web_contents_->GetRenderViewHost();
623 host->Send(new AutofillMsg_FormNotBlacklisted(host->GetRoutingID(), 635 host->Send(new AutofillMsg_FormNotBlacklisted(host->GetRoutingID(),
624 observed_form_)); 636 observed_form_));
625 } 637 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/password_manager/password_form_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698