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

Side by Side Diff: components/password_manager/core/browser/login_database.cc

Issue 316243002: Add date_synced to PasswordForm. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: +comment Created 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/login_database.h" 5 #include "components/password_manager/core/browser/login_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/pickle.h" 14 #include "base/pickle.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "components/autofill/core/common/password_form.h" 17 #include "components/autofill/core/common/password_form.h"
18 #include "sql/connection.h" 18 #include "sql/connection.h"
19 #include "sql/statement.h" 19 #include "sql/statement.h"
20 #include "sql/transaction.h" 20 #include "sql/transaction.h"
21 21
22 using autofill::PasswordForm; 22 using autofill::PasswordForm;
23 23
24 namespace password_manager { 24 namespace password_manager {
25 25
26 static const int kCurrentVersionNumber = 5; 26 static const int kCurrentVersionNumber = 6;
27 static const int kCompatibleVersionNumber = 1; 27 static const int kCompatibleVersionNumber = 1;
28 28
29 Pickle SerializeVector(const std::vector<base::string16>& vec) { 29 Pickle SerializeVector(const std::vector<base::string16>& vec) {
30 Pickle p; 30 Pickle p;
31 for (size_t i = 0; i < vec.size(); ++i) { 31 for (size_t i = 0; i < vec.size(); ++i) {
32 p.WriteString16(vec[i]); 32 p.WriteString16(vec[i]);
33 } 33 }
34 return p; 34 return p;
35 } 35 }
36 36
(...skipping 22 matching lines...) Expand all
59 COLUMN_SIGNON_REALM, 59 COLUMN_SIGNON_REALM,
60 COLUMN_SSL_VALID, 60 COLUMN_SSL_VALID,
61 COLUMN_PREFERRED, 61 COLUMN_PREFERRED,
62 COLUMN_DATE_CREATED, 62 COLUMN_DATE_CREATED,
63 COLUMN_BLACKLISTED_BY_USER, 63 COLUMN_BLACKLISTED_BY_USER,
64 COLUMN_SCHEME, 64 COLUMN_SCHEME,
65 COLUMN_PASSWORD_TYPE, 65 COLUMN_PASSWORD_TYPE,
66 COLUMN_POSSIBLE_USERNAMES, 66 COLUMN_POSSIBLE_USERNAMES,
67 COLUMN_TIMES_USED, 67 COLUMN_TIMES_USED,
68 COLUMN_FORM_DATA, 68 COLUMN_FORM_DATA,
69 COLUMN_USE_ADDITIONAL_AUTH 69 COLUMN_USE_ADDITIONAL_AUTH,
70 COLUMN_DATE_SYNCED
70 }; 71 };
71 72
72 void BindAddStatement(const PasswordForm& form, 73 void BindAddStatement(const PasswordForm& form,
73 const std::string& encrypted_password, 74 const std::string& encrypted_password,
74 sql::Statement* s) { 75 sql::Statement* s) {
75 s->BindString(COLUMN_ORIGIN_URL, form.origin.spec()); 76 s->BindString(COLUMN_ORIGIN_URL, form.origin.spec());
76 s->BindString(COLUMN_ACTION_URL, form.action.spec()); 77 s->BindString(COLUMN_ACTION_URL, form.action.spec());
77 s->BindString16(COLUMN_USERNAME_ELEMENT, form.username_element); 78 s->BindString16(COLUMN_USERNAME_ELEMENT, form.username_element);
78 s->BindString16(COLUMN_USERNAME_VALUE, form.username_value); 79 s->BindString16(COLUMN_USERNAME_VALUE, form.username_value);
79 s->BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element); 80 s->BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element);
(...skipping 11 matching lines...) Expand all
91 s->BindBlob(COLUMN_POSSIBLE_USERNAMES, 92 s->BindBlob(COLUMN_POSSIBLE_USERNAMES,
92 usernames_pickle.data(), 93 usernames_pickle.data(),
93 usernames_pickle.size()); 94 usernames_pickle.size());
94 s->BindInt(COLUMN_TIMES_USED, form.times_used); 95 s->BindInt(COLUMN_TIMES_USED, form.times_used);
95 Pickle form_data_pickle; 96 Pickle form_data_pickle;
96 autofill::SerializeFormData(form.form_data, &form_data_pickle); 97 autofill::SerializeFormData(form.form_data, &form_data_pickle);
97 s->BindBlob(COLUMN_FORM_DATA, 98 s->BindBlob(COLUMN_FORM_DATA,
98 form_data_pickle.data(), 99 form_data_pickle.data(),
99 form_data_pickle.size()); 100 form_data_pickle.size());
100 s->BindInt(COLUMN_USE_ADDITIONAL_AUTH, form.use_additional_authentication); 101 s->BindInt(COLUMN_USE_ADDITIONAL_AUTH, form.use_additional_authentication);
102 s->BindInt64(COLUMN_DATE_SYNCED, form.date_synced.ToInternalValue());
101 } 103 }
102 104
103 void AddCallback(int err, sql::Statement* /*stmt*/) { 105 void AddCallback(int err, sql::Statement* /*stmt*/) {
104 if (err == 19 /*SQLITE_CONSTRAINT*/) 106 if (err == 19 /*SQLITE_CONSTRAINT*/)
105 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form"; 107 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form";
106 } 108 }
107 109
108 } // namespace 110 } // namespace
109 111
110 LoginDatabase::LoginDatabase() { 112 LoginDatabase::LoginDatabase() {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 } 193 }
192 meta_table_.SetVersionNumber(4); 194 meta_table_.SetVersionNumber(4);
193 // Fall through. 195 // Fall through.
194 case 4: 196 case 4:
195 if (!db_.Execute( 197 if (!db_.Execute(
196 "ALTER TABLE logins ADD COLUMN use_additional_auth INTEGER")) { 198 "ALTER TABLE logins ADD COLUMN use_additional_auth INTEGER")) {
197 return false; 199 return false;
198 } 200 }
199 meta_table_.SetVersionNumber(5); 201 meta_table_.SetVersionNumber(5);
200 // Fall through. 202 // Fall through.
203 case 5:
204 if (!db_.Execute(
205 "ALTER TABLE logins ADD COLUMN date_synced INTEGER")) {
206 return false;
207 }
208 meta_table_.SetVersionNumber(6);
209 // Fall through.
201 case kCurrentVersionNumber: 210 case kCurrentVersionNumber:
202 // Already up to date 211 // Already up to date
203 return true; 212 return true;
204 default: 213 default:
205 NOTREACHED(); 214 NOTREACHED();
206 return false; 215 return false;
207 } 216 }
208 } 217 }
209 218
210 bool LoginDatabase::InitLoginsTable() { 219 bool LoginDatabase::InitLoginsTable() {
(...skipping 10 matching lines...) Expand all
221 "ssl_valid INTEGER NOT NULL," 230 "ssl_valid INTEGER NOT NULL,"
222 "preferred INTEGER NOT NULL," 231 "preferred INTEGER NOT NULL,"
223 "date_created INTEGER NOT NULL," 232 "date_created INTEGER NOT NULL,"
224 "blacklisted_by_user INTEGER NOT NULL," 233 "blacklisted_by_user INTEGER NOT NULL,"
225 "scheme INTEGER NOT NULL," 234 "scheme INTEGER NOT NULL,"
226 "password_type INTEGER," 235 "password_type INTEGER,"
227 "possible_usernames BLOB," 236 "possible_usernames BLOB,"
228 "times_used INTEGER," 237 "times_used INTEGER,"
229 "form_data BLOB," 238 "form_data BLOB,"
230 "use_additional_auth INTEGER," 239 "use_additional_auth INTEGER,"
240 "date_synced INTEGER,"
231 "UNIQUE " 241 "UNIQUE "
232 "(origin_url, username_element, " 242 "(origin_url, username_element, "
233 "username_value, password_element, " 243 "username_value, password_element, "
234 "submit_element, signon_realm))")) { 244 "submit_element, signon_realm))")) {
235 NOTREACHED(); 245 NOTREACHED();
236 return false; 246 return false;
237 } 247 }
238 if (!db_.Execute("CREATE INDEX logins_signon ON " 248 if (!db_.Execute("CREATE INDEX logins_signon ON "
239 "logins (signon_realm)")) { 249 "logins (signon_realm)")) {
240 NOTREACHED(); 250 NOTREACHED();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 ENCRYPTION_RESULT_SUCCESS) 311 ENCRYPTION_RESULT_SUCCESS)
302 return list; 312 return list;
303 313
304 // You *must* change LoginTableColumns if this query changes. 314 // You *must* change LoginTableColumns if this query changes.
305 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, 315 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
306 "INSERT INTO logins " 316 "INSERT INTO logins "
307 "(origin_url, action_url, username_element, username_value, " 317 "(origin_url, action_url, username_element, username_value, "
308 " password_element, password_value, submit_element, " 318 " password_element, password_value, submit_element, "
309 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 319 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
310 " scheme, password_type, possible_usernames, times_used, form_data, " 320 " scheme, password_type, possible_usernames, times_used, form_data, "
311 " use_additional_auth) VALUES " 321 " use_additional_auth, date_synced) VALUES "
312 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); 322 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
313 BindAddStatement(form, encrypted_password, &s); 323 BindAddStatement(form, encrypted_password, &s);
314 db_.set_error_callback(base::Bind(&AddCallback)); 324 db_.set_error_callback(base::Bind(&AddCallback));
315 const bool success = s.Run(); 325 const bool success = s.Run();
316 db_.reset_error_callback(); 326 db_.reset_error_callback();
317 if (success) { 327 if (success) {
318 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); 328 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
319 return list; 329 return list;
320 } 330 }
321 // Repeat the same statement but with REPLACE semantic. 331 // Repeat the same statement but with REPLACE semantic.
322 s.Assign(db_.GetCachedStatement(SQL_FROM_HERE, 332 s.Assign(db_.GetCachedStatement(SQL_FROM_HERE,
323 "INSERT OR REPLACE INTO logins " 333 "INSERT OR REPLACE INTO logins "
324 "(origin_url, action_url, username_element, username_value, " 334 "(origin_url, action_url, username_element, username_value, "
325 " password_element, password_value, submit_element, " 335 " password_element, password_value, submit_element, "
326 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 336 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
327 " scheme, password_type, possible_usernames, times_used, form_data, " 337 " scheme, password_type, possible_usernames, times_used, form_data, "
328 " use_additional_auth) VALUES " 338 " use_additional_auth, date_synced) VALUES "
329 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); 339 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
330 BindAddStatement(form, encrypted_password, &s); 340 BindAddStatement(form, encrypted_password, &s);
331 if (s.Run()) { 341 if (s.Run()) {
332 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); 342 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
333 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); 343 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
334 } 344 }
335 return list; 345 return list;
336 } 346 }
337 347
338 PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) { 348 PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) {
339 std::string encrypted_password; 349 std::string encrypted_password;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 form->times_used = s.ColumnInt(COLUMN_TIMES_USED); 467 form->times_used = s.ColumnInt(COLUMN_TIMES_USED);
458 if (s.ColumnByteLength(COLUMN_FORM_DATA)) { 468 if (s.ColumnByteLength(COLUMN_FORM_DATA)) {
459 Pickle form_data_pickle( 469 Pickle form_data_pickle(
460 static_cast<const char*>(s.ColumnBlob(COLUMN_FORM_DATA)), 470 static_cast<const char*>(s.ColumnBlob(COLUMN_FORM_DATA)),
461 s.ColumnByteLength(COLUMN_FORM_DATA)); 471 s.ColumnByteLength(COLUMN_FORM_DATA));
462 PickleIterator form_data_iter(form_data_pickle); 472 PickleIterator form_data_iter(form_data_pickle);
463 autofill::DeserializeFormData(&form_data_iter, &form->form_data); 473 autofill::DeserializeFormData(&form_data_iter, &form->form_data);
464 } 474 }
465 form->use_additional_authentication = 475 form->use_additional_authentication =
466 (s.ColumnInt(COLUMN_USE_ADDITIONAL_AUTH) > 0); 476 (s.ColumnInt(COLUMN_USE_ADDITIONAL_AUTH) > 0);
477 form->date_synced = base::Time::FromInternalValue(
478 s.ColumnInt64(COLUMN_DATE_SYNCED));
467 return ENCRYPTION_RESULT_SUCCESS; 479 return ENCRYPTION_RESULT_SUCCESS;
468 } 480 }
469 481
470 bool LoginDatabase::GetLogins(const PasswordForm& form, 482 bool LoginDatabase::GetLogins(const PasswordForm& form,
471 std::vector<PasswordForm*>* forms) const { 483 std::vector<PasswordForm*>* forms) const {
472 DCHECK(forms); 484 DCHECK(forms);
473 // You *must* change LoginTableColumns if this query changes. 485 // You *must* change LoginTableColumns if this query changes.
474 const std::string sql_query = "SELECT origin_url, action_url, " 486 const std::string sql_query = "SELECT origin_url, action_url, "
475 "username_element, username_value, " 487 "username_element, username_value, "
476 "password_element, password_value, submit_element, " 488 "password_element, password_value, submit_element, "
477 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 489 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
478 "scheme, password_type, possible_usernames, times_used, form_data, " 490 "scheme, password_type, possible_usernames, times_used, form_data, "
479 "use_additional_auth FROM logins WHERE signon_realm == ? "; 491 "use_additional_auth, date_synced FROM logins WHERE signon_realm == ? ";
480 sql::Statement s; 492 sql::Statement s;
481 const GURL signon_realm(form.signon_realm); 493 const GURL signon_realm(form.signon_realm);
482 std::string registered_domain = 494 std::string registered_domain =
483 PSLMatchingHelper::GetRegistryControlledDomain(signon_realm); 495 PSLMatchingHelper::GetRegistryControlledDomain(signon_realm);
484 PSLMatchingHelper::PSLDomainMatchMetric psl_domain_match_metric = 496 PSLMatchingHelper::PSLDomainMatchMetric psl_domain_match_metric =
485 PSLMatchingHelper::PSL_DOMAIN_MATCH_NONE; 497 PSLMatchingHelper::PSL_DOMAIN_MATCH_NONE;
486 // PSL matching only applies to HTML forms. 498 // PSL matching only applies to HTML forms.
487 if (form.scheme == PasswordForm::SCHEME_HTML && 499 if (form.scheme == PasswordForm::SCHEME_HTML &&
488 psl_helper_.ShouldPSLDomainMatchingApply(registered_domain)) { 500 psl_helper_.ShouldPSLDomainMatchingApply(registered_domain)) {
489 // We are extending the original SQL query with one that includes more 501 // We are extending the original SQL query with one that includes more
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 const base::Time begin, 576 const base::Time begin,
565 const base::Time end, 577 const base::Time end,
566 std::vector<autofill::PasswordForm*>* forms) const { 578 std::vector<autofill::PasswordForm*>* forms) const {
567 DCHECK(forms); 579 DCHECK(forms);
568 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, 580 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
569 "SELECT origin_url, action_url, " 581 "SELECT origin_url, action_url, "
570 "username_element, username_value, " 582 "username_element, username_value, "
571 "password_element, password_value, submit_element, " 583 "password_element, password_value, submit_element, "
572 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 584 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
573 "scheme, password_type, possible_usernames, times_used, form_data, " 585 "scheme, password_type, possible_usernames, times_used, form_data, "
574 "use_additional_auth FROM logins " 586 "use_additional_auth, date_synced FROM logins "
575 "WHERE date_created >= ? AND date_created < ?" 587 "WHERE date_created >= ? AND date_created < ?"
576 "ORDER BY origin_url")); 588 "ORDER BY origin_url"));
577 s.BindInt64(0, begin.ToTimeT()); 589 s.BindInt64(0, begin.ToTimeT());
578 s.BindInt64(1, end.is_null() ? std::numeric_limits<int64>::max() 590 s.BindInt64(1, end.is_null() ? std::numeric_limits<int64>::max()
579 : end.ToTimeT()); 591 : end.ToTimeT());
580 592
581 while (s.Step()) { 593 while (s.Step()) {
582 scoped_ptr<PasswordForm> new_form(new PasswordForm()); 594 scoped_ptr<PasswordForm> new_form(new PasswordForm());
583 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); 595 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s);
584 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) 596 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE)
(...skipping 19 matching lines...) Expand all
604 bool LoginDatabase::GetAllLoginsWithBlacklistSetting( 616 bool LoginDatabase::GetAllLoginsWithBlacklistSetting(
605 bool blacklisted, std::vector<PasswordForm*>* forms) const { 617 bool blacklisted, std::vector<PasswordForm*>* forms) const {
606 DCHECK(forms); 618 DCHECK(forms);
607 // You *must* change LoginTableColumns if this query changes. 619 // You *must* change LoginTableColumns if this query changes.
608 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, 620 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
609 "SELECT origin_url, action_url, " 621 "SELECT origin_url, action_url, "
610 "username_element, username_value, " 622 "username_element, username_value, "
611 "password_element, password_value, submit_element, " 623 "password_element, password_value, submit_element, "
612 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 624 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
613 "scheme, password_type, possible_usernames, times_used, form_data, " 625 "scheme, password_type, possible_usernames, times_used, form_data, "
614 "use_additional_auth FROM logins WHERE blacklisted_by_user == ? " 626 "use_additional_auth, date_synced FROM logins "
615 "ORDER BY origin_url")); 627 "WHERE blacklisted_by_user == ? ORDER BY origin_url"));
616 s.BindInt(0, blacklisted ? 1 : 0); 628 s.BindInt(0, blacklisted ? 1 : 0);
617 629
618 while (s.Step()) { 630 while (s.Step()) {
619 scoped_ptr<PasswordForm> new_form(new PasswordForm()); 631 scoped_ptr<PasswordForm> new_form(new PasswordForm());
620 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); 632 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s);
621 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) 633 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE)
622 return false; 634 return false;
623 if (result == ENCRYPTION_RESULT_ITEM_FAILURE) 635 if (result == ENCRYPTION_RESULT_ITEM_FAILURE)
624 continue; 636 continue;
625 DCHECK(result == ENCRYPTION_RESULT_SUCCESS); 637 DCHECK(result == ENCRYPTION_RESULT_SUCCESS);
626 forms->push_back(new_form.release()); 638 forms->push_back(new_form.release());
627 } 639 }
628 return s.Succeeded(); 640 return s.Succeeded();
629 } 641 }
630 642
631 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { 643 bool LoginDatabase::DeleteAndRecreateDatabaseFile() {
632 DCHECK(db_.is_open()); 644 DCHECK(db_.is_open());
633 meta_table_.Reset(); 645 meta_table_.Reset();
634 db_.Close(); 646 db_.Close();
635 sql::Connection::Delete(db_path_); 647 sql::Connection::Delete(db_path_);
636 return Init(db_path_); 648 return Init(db_path_);
637 } 649 }
638 650
639 } // namespace password_manager 651 } // namespace password_manager
OLDNEW
« no previous file with comments | « components/autofill/core/common/password_form.cc ('k') | components/password_manager/core/browser/login_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698