OLD | NEW |
---|---|
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 "components/password_manager/core/browser/password_form_manager.h" | 5 #include "components/password_manager/core/browser/password_form_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/command_line.h" | |
10 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
11 #include "base/metrics/user_metrics.h" | 12 #include "base/metrics/user_metrics.h" |
12 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
14 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
15 #include "components/autofill/core/browser/autofill_manager.h" | 16 #include "components/autofill/core/browser/autofill_manager.h" |
16 #include "components/autofill/core/browser/form_structure.h" | 17 #include "components/autofill/core/browser/form_structure.h" |
17 #include "components/autofill/core/browser/validation.h" | 18 #include "components/autofill/core/browser/validation.h" |
19 #include "components/autofill/core/common/autofill_switches.h" | |
18 #include "components/autofill/core/common/password_form.h" | 20 #include "components/autofill/core/common/password_form.h" |
19 #include "components/password_manager/core/browser/browser_save_password_progres s_logger.h" | 21 #include "components/password_manager/core/browser/browser_save_password_progres s_logger.h" |
20 #include "components/password_manager/core/browser/password_manager.h" | 22 #include "components/password_manager/core/browser/password_manager.h" |
21 #include "components/password_manager/core/browser/password_manager_client.h" | 23 #include "components/password_manager/core/browser/password_manager_client.h" |
22 #include "components/password_manager/core/browser/password_manager_driver.h" | 24 #include "components/password_manager/core/browser/password_manager_driver.h" |
23 #include "components/password_manager/core/browser/password_store.h" | 25 #include "components/password_manager/core/browser/password_store.h" |
24 | 26 |
25 using autofill::FormStructure; | 27 using autofill::FormStructure; |
26 using autofill::PasswordForm; | 28 using autofill::PasswordForm; |
27 using autofill::PasswordFormMap; | 29 using autofill::PasswordFormMap; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 event, SUBMISSION_EVENT_ENUM_COUNT); | 63 event, SUBMISSION_EVENT_ENUM_COUNT); |
62 } | 64 } |
63 | 65 |
64 PasswordForm CopyAndModifySSLValidity(const PasswordForm& orig, | 66 PasswordForm CopyAndModifySSLValidity(const PasswordForm& orig, |
65 bool ssl_valid) { | 67 bool ssl_valid) { |
66 PasswordForm result(orig); | 68 PasswordForm result(orig); |
67 result.ssl_valid = ssl_valid; | 69 result.ssl_valid = ssl_valid; |
68 return result; | 70 return result; |
69 } | 71 } |
70 | 72 |
73 bool IsChangePasswordForm(const PasswordForm& candidate) { | |
74 return !candidate.new_password_element.empty() && | |
75 !candidate.password_element.empty(); | |
76 } | |
77 | |
71 } // namespace | 78 } // namespace |
72 | 79 |
73 PasswordFormManager::PasswordFormManager( | 80 PasswordFormManager::PasswordFormManager( |
74 PasswordManager* password_manager, | 81 PasswordManager* password_manager, |
75 PasswordManagerClient* client, | 82 PasswordManagerClient* client, |
76 const base::WeakPtr<PasswordManagerDriver>& driver, | 83 const base::WeakPtr<PasswordManagerDriver>& driver, |
77 const PasswordForm& observed_form, | 84 const PasswordForm& observed_form, |
78 bool ssl_valid) | 85 bool ssl_valid) |
79 : best_matches_deleter_(&best_matches_), | 86 : best_matches_deleter_(&best_matches_), |
80 observed_form_(CopyAndModifySSLValidity(observed_form, ssl_valid)), | 87 observed_form_(CopyAndModifySSLValidity(observed_form, ssl_valid)), |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 DCHECK_NE(RESULT_NO_MATCH, DoesManage(credentials)); | 246 DCHECK_NE(RESULT_NO_MATCH, DoesManage(credentials)); |
240 | 247 |
241 // If this was a sign-up or change password form, we want to persist the new | 248 // If this was a sign-up or change password form, we want to persist the new |
242 // password; if this was a login form, then the current password (which might | 249 // password; if this was a login form, then the current password (which might |
243 // still be "new" in the sense that we see these credentials for the first | 250 // still be "new" in the sense that we see these credentials for the first |
244 // time, or that the user manually entered his actual password to overwrite an | 251 // time, or that the user manually entered his actual password to overwrite an |
245 // obsolete password we had in the store). | 252 // obsolete password we had in the store). |
246 base::string16 password_to_save(credentials.new_password_element.empty() ? | 253 base::string16 password_to_save(credentials.new_password_element.empty() ? |
247 credentials.password_value : credentials.new_password_value); | 254 credentials.password_value : credentials.new_password_value); |
248 | 255 |
256 bool is_username_certainly_correct = credentials.username_marked_by_site; | |
vabr (Chromium)
2015/02/02 14:18:49
nit: Because credentials.username_marked_by_site i
Pritam Nikam
2015/02/05 06:12:07
Done.
| |
257 | |
249 // Make sure the important fields stay the same as the initially observed or | 258 // Make sure the important fields stay the same as the initially observed or |
250 // autofilled ones, as they may have changed if the user experienced a login | 259 // autofilled ones, as they may have changed if the user experienced a login |
251 // failure. | 260 // failure. |
252 // Look for these credentials in the list containing auto-fill entries. | 261 // Look for these credentials in the list containing auto-fill entries. |
253 PasswordFormMap::const_iterator it = | 262 PasswordFormMap::const_iterator it = |
254 best_matches_.find(credentials.username_value); | 263 best_matches_.find(credentials.username_value); |
255 if (it != best_matches_.end()) { | 264 if (!is_username_certainly_correct && it != best_matches_.end()) { |
vabr (Chromium)
2015/02/02 14:18:49
Don't narrow the condition this way -- observe tha
Pritam Nikam
2015/02/05 06:12:06
Done.
| |
256 // The user signed in with a login we autofilled. | 265 // The user signed in with a login we autofilled. |
257 pending_credentials_ = *it->second; | 266 pending_credentials_ = *it->second; |
258 bool password_changed = | 267 bool password_changed = |
259 pending_credentials_.password_value != password_to_save; | 268 pending_credentials_.password_value != password_to_save; |
260 if (IsPendingCredentialsPublicSuffixMatch()) { | 269 if (IsPendingCredentialsPublicSuffixMatch()) { |
261 // If the autofilled credentials were only a PSL match, store a copy with | 270 // If the autofilled credentials were only a PSL match, store a copy with |
262 // the current origin and signon realm. This ensures that on the next | 271 // the current origin and signon realm. This ensures that on the next |
263 // visit, a precise match is found. | 272 // visit, a precise match is found. |
264 is_new_login_ = true; | 273 is_new_login_ = true; |
265 user_action_ = password_changed ? kUserActionChoosePslMatch | 274 user_action_ = password_changed ? kUserActionChoosePslMatch |
(...skipping 30 matching lines...) Expand all Loading... | |
296 // infrequently, and the inconvenience put on the user by asking them is | 305 // infrequently, and the inconvenience put on the user by asking them is |
297 // not significant, so we are fine with asking here again. | 306 // not significant, so we are fine with asking here again. |
298 if (password_changed) { | 307 if (password_changed) { |
299 pending_credentials_.original_signon_realm.clear(); | 308 pending_credentials_.original_signon_realm.clear(); |
300 DCHECK(!IsPendingCredentialsPublicSuffixMatch()); | 309 DCHECK(!IsPendingCredentialsPublicSuffixMatch()); |
301 } | 310 } |
302 } else { // Not a PSL match. | 311 } else { // Not a PSL match. |
303 is_new_login_ = false; | 312 is_new_login_ = false; |
304 if (password_changed) | 313 if (password_changed) |
305 user_action_ = kUserActionOverridePassword; | 314 user_action_ = kUserActionOverridePassword; |
315 | |
316 // Check whether its a change-password form with matching credentials in | |
317 // stored form. | |
318 PasswordForm matching_form; | |
319 if (IsChangePasswordForm(credentials) && | |
320 HasMatchingCredentialsInStore(credentials, &matching_form)) { | |
vabr (Chromium)
2015/02/02 14:18:49
This is actually unnecessary -- you already know t
Pritam Nikam
2015/02/05 06:12:07
Done.
| |
321 pending_credentials_ = matching_form; | |
vabr (Chromium)
2015/02/02 14:18:50
Save the copy -- just pass pending_credentials_ to
vabr (Chromium)
2015/02/02 14:18:50
Given the other comments, the modification needed
Pritam Nikam
2015/02/05 06:12:06
Done.
Pritam Nikam
2015/02/05 06:12:06
Done.
| |
322 selected_username_ = matching_form.username_value; | |
vabr (Chromium)
2015/02/02 14:18:50
Why do you set this? According to password_form_ma
Pritam Nikam
2015/02/05 06:12:06
Done.
| |
323 user_action_ = kUserActionOverridePassword; | |
vabr (Chromium)
2015/02/02 14:18:49
How do you know the password is overridden? Should
Pritam Nikam
2015/02/05 06:12:07
Done.
| |
324 } | |
306 } | 325 } |
307 } else if (action == ALLOW_OTHER_POSSIBLE_USERNAMES && | 326 } else if (action == ALLOW_OTHER_POSSIBLE_USERNAMES && |
308 UpdatePendingCredentialsIfOtherPossibleUsername( | 327 UpdatePendingCredentialsIfOtherPossibleUsername( |
309 credentials.username_value)) { | 328 credentials.username_value)) { |
310 // |pending_credentials_| is now set. Note we don't update | 329 // |pending_credentials_| is now set. Note we don't update |
311 // |pending_credentials_.username_value| to |credentials.username_value| | 330 // |pending_credentials_.username_value| to |credentials.username_value| |
312 // yet because we need to keep the original username to modify the stored | 331 // yet because we need to keep the original username to modify the stored |
313 // credential. | 332 // credential. |
314 selected_username_ = credentials.username_value; | 333 selected_username_ = credentials.username_value; |
315 is_new_login_ = false; | 334 is_new_login_ = false; |
316 } else { | 335 } else { |
317 // User typed in a new, unknown username. | 336 // User typed in a new, unknown username. |
318 user_action_ = kUserActionOverrideUsernameAndPassword; | 337 user_action_ = kUserActionOverrideUsernameAndPassword; |
319 pending_credentials_ = observed_form_; | 338 pending_credentials_ = observed_form_; |
320 pending_credentials_.username_value = credentials.username_value; | 339 pending_credentials_.username_value = credentials.username_value; |
321 pending_credentials_.other_possible_usernames = | 340 pending_credentials_.other_possible_usernames = |
322 credentials.other_possible_usernames; | 341 credentials.other_possible_usernames; |
323 | 342 |
324 // The password value will be filled in later, remove any garbage for now. | 343 // The password value will be filled in later, remove any garbage for now. |
325 pending_credentials_.password_value.clear(); | 344 pending_credentials_.password_value.clear(); |
326 pending_credentials_.new_password_value.clear(); | 345 pending_credentials_.new_password_value.clear(); |
327 | 346 |
328 // If this was a sign-up or change password form, the names of the elements | 347 // If this was a sign-up or change password form, the names of the |
329 // are likely different than those on a login form, so do not bother saving | 348 // elements are likely different than those on a login form, so do not |
vabr (Chromium)
2015/02/02 14:18:49
Please do not just reformat the comments, if you d
Pritam Nikam
2015/02/05 06:12:06
Done.
| |
330 // them. We will fill them with meaningful values in UpdateLogin() when the | 349 // bother saving them. We will fill them with meaningful values in |
331 // user goes onto a real login form for the first time. | 350 // UpdateLogin() when the user goes onto a real login form for the first |
351 // time. | |
332 if (!credentials.new_password_element.empty()) { | 352 if (!credentials.new_password_element.empty()) { |
333 pending_credentials_.password_element.clear(); | 353 pending_credentials_.password_element.clear(); |
334 pending_credentials_.new_password_element.clear(); | 354 pending_credentials_.new_password_element.clear(); |
335 } | 355 } |
336 } | 356 } |
337 | 357 |
338 pending_credentials_.action = credentials.action; | 358 pending_credentials_.action = credentials.action; |
339 // If the user selected credentials we autofilled from a PasswordForm | 359 // If the user selected credentials we autofilled from a PasswordForm |
340 // that contained no action URL (IE6/7 imported passwords, for example), | 360 // that contained no action URL (IE6/7 imported passwords, for example), |
341 // bless it with the action URL from the observed form. See bug 1107719. | 361 // bless it with the action URL from the observed form. See bug 1107719. |
(...skipping 29 matching lines...) Expand all Loading... | |
371 state_ = MATCHING_PHASE; | 391 state_ = MATCHING_PHASE; |
372 | 392 |
373 scoped_ptr<BrowserSavePasswordProgressLogger> logger; | 393 scoped_ptr<BrowserSavePasswordProgressLogger> logger; |
374 if (client_->IsLoggingActive()) { | 394 if (client_->IsLoggingActive()) { |
375 logger.reset(new BrowserSavePasswordProgressLogger(client_)); | 395 logger.reset(new BrowserSavePasswordProgressLogger(client_)); |
376 logger->LogMessage(Logger::STRING_FETCH_LOGINS_METHOD); | 396 logger->LogMessage(Logger::STRING_FETCH_LOGINS_METHOD); |
377 } | 397 } |
378 | 398 |
379 // Do not autofill on sign-up or change password forms (until we have some | 399 // Do not autofill on sign-up or change password forms (until we have some |
380 // working change password functionality). | 400 // working change password functionality). |
381 if (!observed_form_.new_password_element.empty()) { | 401 if (!observed_form_.new_password_element.empty() && |
402 !base::CommandLine::ForCurrentProcess()->HasSwitch( | |
vabr (Chromium)
2015/02/02 14:18:49
This change looks like a bad merge, and nothing to
Pritam Nikam
2015/02/05 06:12:06
Done.
| |
403 autofill::switches::kEnablePasswordSaveOnInPageNavigation)) { | |
382 if (logger) | 404 if (logger) |
383 logger->LogMessage(Logger::STRING_FORM_NOT_AUTOFILLED); | 405 logger->LogMessage(Logger::STRING_FORM_NOT_AUTOFILLED); |
384 client_->AutofillResultsComputed(); | 406 client_->AutofillResultsComputed(); |
385 // There is no point in looking for the credentials in the store when they | 407 // There is no point in looking for the credentials in the store when they |
386 // won't be autofilled, so pretend there were none. | 408 // won't be autofilled, so pretend there were none. |
387 std::vector<autofill::PasswordForm*> dummy_results; | 409 std::vector<autofill::PasswordForm*> dummy_results; |
388 OnGetPasswordStoreResults(dummy_results); | 410 OnGetPasswordStoreResults(dummy_results); |
389 return; | 411 return; |
390 } | 412 } |
391 | 413 |
392 PasswordStore* password_store = client_->GetPasswordStore(); | 414 PasswordStore* password_store = client_->GetPasswordStore(); |
393 if (!password_store) { | 415 if (!password_store) { |
394 if (logger) | 416 if (logger) |
395 logger->LogMessage(Logger::STRING_NO_STORE); | 417 logger->LogMessage(Logger::STRING_NO_STORE); |
396 NOTREACHED(); | 418 NOTREACHED(); |
397 return; | 419 return; |
398 } | 420 } |
399 password_store->GetLogins(observed_form_, prompt_policy, this); | 421 password_store->GetLogins(observed_form_, prompt_policy, this); |
400 } | 422 } |
401 | 423 |
402 bool PasswordFormManager::HasCompletedMatching() const { | 424 bool PasswordFormManager::HasCompletedMatching() const { |
403 return state_ == POST_MATCHING_PHASE; | 425 return state_ == POST_MATCHING_PHASE; |
404 } | 426 } |
405 | 427 |
406 bool PasswordFormManager::IsIgnorableChangePasswordForm() const { | 428 bool PasswordFormManager::IsIgnorableChangePasswordForm() const { |
407 bool is_change_password_form = !observed_form_.new_password_element.empty() && | |
408 !observed_form_.password_element.empty(); | |
409 bool is_username_certainly_correct = observed_form_.username_marked_by_site; | 429 bool is_username_certainly_correct = observed_form_.username_marked_by_site; |
410 return is_change_password_form && !is_username_certainly_correct; | 430 return IsChangePasswordForm(observed_form_) && !is_username_certainly_correct; |
411 } | 431 } |
412 | 432 |
413 void PasswordFormManager::OnRequestDone( | 433 void PasswordFormManager::OnRequestDone( |
414 const std::vector<PasswordForm*>& logins_result) { | 434 const std::vector<PasswordForm*>& logins_result) { |
415 // Note that the result gets deleted after this call completes, but we own | 435 // Note that the result gets deleted after this call completes, but we own |
416 // the PasswordForm objects pointed to by the result vector, thus we keep | 436 // the PasswordForm objects pointed to by the result vector, thus we keep |
417 // copies to a minimum here. | 437 // copies to a minimum here. |
418 | 438 |
419 scoped_ptr<BrowserSavePasswordProgressLogger> logger; | 439 scoped_ptr<BrowserSavePasswordProgressLogger> logger; |
420 if (client_->IsLoggingActive()) { | 440 if (client_->IsLoggingActive()) { |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 if (has_generated_password_) | 881 if (has_generated_password_) |
862 LogPasswordGenerationSubmissionEvent(PASSWORD_SUBMITTED); | 882 LogPasswordGenerationSubmissionEvent(PASSWORD_SUBMITTED); |
863 } | 883 } |
864 | 884 |
865 void PasswordFormManager::SubmitFailed() { | 885 void PasswordFormManager::SubmitFailed() { |
866 submit_result_ = kSubmitResultFailed; | 886 submit_result_ = kSubmitResultFailed; |
867 if (has_generated_password_) | 887 if (has_generated_password_) |
868 LogPasswordGenerationSubmissionEvent(PASSWORD_SUBMISSION_FAILED); | 888 LogPasswordGenerationSubmissionEvent(PASSWORD_SUBMISSION_FAILED); |
869 } | 889 } |
870 | 890 |
891 bool PasswordFormManager::HasMatchingCredentialsInStore( | |
892 const autofill::PasswordForm& candidate, | |
893 autofill::PasswordForm* matching_form) const { | |
894 bool match_found = false; | |
895 for (const auto& match : best_matches_) { | |
896 if (match.second->username_value == candidate.username_value && | |
897 match.second->password_value == candidate.password_value) { | |
898 if (matching_form) | |
vabr (Chromium)
2015/02/02 14:18:49
There should also be a check that the candidate ha
Pritam Nikam
2015/02/05 06:12:06
Done. Removed this function, instead performed in-
| |
899 *matching_form = *(match.second); | |
900 match_found = true; | |
901 break; | |
902 } | |
903 } | |
904 | |
905 return match_found; | |
906 } | |
907 | |
871 } // namespace password_manager | 908 } // namespace password_manager |
OLD | NEW |