Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 18 #include "components/autofill/core/common/password_form.h" | 18 #include "components/autofill/core/common/password_form.h" |
| 19 #include "components/password_manager/core/browser/password_manager_client.h" | 19 #include "components/password_manager/core/browser/password_manager_client.h" |
| 20 #include "google_apis/gaia/gaia_auth_util.h" | 20 #include "google_apis/gaia/gaia_auth_util.h" |
| 21 #include "google_apis/gaia/gaia_urls.h" | 21 #include "google_apis/gaia/gaia_urls.h" |
| 22 #include "sql/connection.h" | 22 #include "sql/connection.h" |
| 23 #include "sql/statement.h" | 23 #include "sql/statement.h" |
| 24 #include "sql/transaction.h" | 24 #include "sql/transaction.h" |
| 25 | 25 |
| 26 using autofill::PasswordForm; | 26 using autofill::PasswordForm; |
| 27 | 27 |
| 28 namespace password_manager { | 28 namespace password_manager { |
| 29 | 29 |
| 30 const int kCurrentVersionNumber = 10; | 30 const int kCurrentVersionNumber = 11; |
| 31 static const int kCompatibleVersionNumber = 1; | 31 static const int kCompatibleVersionNumber = 1; |
| 32 | 32 |
| 33 Pickle SerializeVector(const std::vector<base::string16>& vec) { | 33 Pickle SerializeVector(const std::vector<base::string16>& vec) { |
| 34 Pickle p; | 34 Pickle p; |
| 35 for (size_t i = 0; i < vec.size(); ++i) { | 35 for (size_t i = 0; i < vec.size(); ++i) { |
| 36 p.WriteString16(vec[i]); | 36 p.WriteString16(vec[i]); |
| 37 } | 37 } |
| 38 return p; | 38 return p; |
| 39 } | 39 } |
| 40 | 40 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 67 COLUMN_BLACKLISTED_BY_USER, | 67 COLUMN_BLACKLISTED_BY_USER, |
| 68 COLUMN_SCHEME, | 68 COLUMN_SCHEME, |
| 69 COLUMN_PASSWORD_TYPE, | 69 COLUMN_PASSWORD_TYPE, |
| 70 COLUMN_POSSIBLE_USERNAMES, | 70 COLUMN_POSSIBLE_USERNAMES, |
| 71 COLUMN_TIMES_USED, | 71 COLUMN_TIMES_USED, |
| 72 COLUMN_FORM_DATA, | 72 COLUMN_FORM_DATA, |
| 73 COLUMN_DATE_SYNCED, | 73 COLUMN_DATE_SYNCED, |
| 74 COLUMN_DISPLAY_NAME, | 74 COLUMN_DISPLAY_NAME, |
| 75 COLUMN_AVATAR_URL, | 75 COLUMN_AVATAR_URL, |
| 76 COLUMN_FEDERATION_URL, | 76 COLUMN_FEDERATION_URL, |
| 77 COLUMN_IS_ZERO_CLICK, | 77 COLUMN_SKIP_ZERO_CLICK, |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 void BindAddStatement(const PasswordForm& form, | 80 void BindAddStatement(const PasswordForm& form, |
| 81 const std::string& encrypted_password, | 81 const std::string& encrypted_password, |
| 82 sql::Statement* s) { | 82 sql::Statement* s) { |
| 83 s->BindString(COLUMN_ORIGIN_URL, form.origin.spec()); | 83 s->BindString(COLUMN_ORIGIN_URL, form.origin.spec()); |
| 84 s->BindString(COLUMN_ACTION_URL, form.action.spec()); | 84 s->BindString(COLUMN_ACTION_URL, form.action.spec()); |
| 85 s->BindString16(COLUMN_USERNAME_ELEMENT, form.username_element); | 85 s->BindString16(COLUMN_USERNAME_ELEMENT, form.username_element); |
| 86 s->BindString16(COLUMN_USERNAME_VALUE, form.username_value); | 86 s->BindString16(COLUMN_USERNAME_VALUE, form.username_value); |
| 87 s->BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element); | 87 s->BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 102 s->BindInt(COLUMN_TIMES_USED, form.times_used); | 102 s->BindInt(COLUMN_TIMES_USED, form.times_used); |
| 103 Pickle form_data_pickle; | 103 Pickle form_data_pickle; |
| 104 autofill::SerializeFormData(form.form_data, &form_data_pickle); | 104 autofill::SerializeFormData(form.form_data, &form_data_pickle); |
| 105 s->BindBlob(COLUMN_FORM_DATA, | 105 s->BindBlob(COLUMN_FORM_DATA, |
| 106 form_data_pickle.data(), | 106 form_data_pickle.data(), |
| 107 form_data_pickle.size()); | 107 form_data_pickle.size()); |
| 108 s->BindInt64(COLUMN_DATE_SYNCED, form.date_synced.ToInternalValue()); | 108 s->BindInt64(COLUMN_DATE_SYNCED, form.date_synced.ToInternalValue()); |
| 109 s->BindString16(COLUMN_DISPLAY_NAME, form.display_name); | 109 s->BindString16(COLUMN_DISPLAY_NAME, form.display_name); |
| 110 s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec()); | 110 s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec()); |
| 111 s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec()); | 111 s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec()); |
| 112 s->BindInt(COLUMN_IS_ZERO_CLICK, form.is_zero_click); | 112 s->BindInt(COLUMN_SKIP_ZERO_CLICK, form.skip_next_zero_click); |
| 113 } | 113 } |
| 114 | 114 |
| 115 void AddCallback(int err, sql::Statement* /*stmt*/) { | 115 void AddCallback(int err, sql::Statement* /*stmt*/) { |
| 116 if (err == 19 /*SQLITE_CONSTRAINT*/) | 116 if (err == 19 /*SQLITE_CONSTRAINT*/) |
| 117 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form"; | 117 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form"; |
| 118 } | 118 } |
| 119 | 119 |
| 120 bool DoesMatchConstraints(const PasswordForm& form) { | 120 bool DoesMatchConstraints(const PasswordForm& form) { |
| 121 if (form.origin.is_empty()) { | 121 if (form.origin.is_empty()) { |
| 122 DLOG(ERROR) << "Constraint violation: form.origin is empty"; | 122 DLOG(ERROR) << "Constraint violation: form.origin is empty"; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 143 } | 143 } |
| 144 | 144 |
| 145 void LogAccountStat(const std::string& name, int sample) { | 145 void LogAccountStat(const std::string& name, int sample) { |
| 146 LogDynamicUMAStat(name, sample, 0, 32, 6); | 146 LogDynamicUMAStat(name, sample, 0, 32, 6); |
| 147 } | 147 } |
| 148 | 148 |
| 149 void LogTimesUsedStat(const std::string& name, int sample) { | 149 void LogTimesUsedStat(const std::string& name, int sample) { |
| 150 LogDynamicUMAStat(name, sample, 0, 100, 10); | 150 LogDynamicUMAStat(name, sample, 0, 100, 10); |
| 151 } | 151 } |
| 152 | 152 |
| 153 // Creates a table named |table_name| using our current schema. | |
| 154 bool CreateNewTable(sql::Connection* db, base::StringPiece table_name) { | |
| 155 std::ostringstream query; | |
| 156 query << "CREATE TABLE " << table_name << | |
| 157 " (origin_url VARCHAR NOT NULL, " | |
| 158 "action_url VARCHAR, " | |
| 159 "username_element VARCHAR, " | |
| 160 "username_value VARCHAR, " | |
| 161 "password_element VARCHAR, " | |
| 162 "password_value BLOB, " | |
| 163 "submit_element VARCHAR, " | |
| 164 "signon_realm VARCHAR NOT NULL," | |
| 165 "ssl_valid INTEGER NOT NULL," | |
| 166 "preferred INTEGER NOT NULL," | |
| 167 "date_created INTEGER NOT NULL," | |
| 168 "blacklisted_by_user INTEGER NOT NULL," | |
| 169 "scheme INTEGER NOT NULL," | |
| 170 "password_type INTEGER," | |
| 171 "possible_usernames BLOB," | |
| 172 "times_used INTEGER," | |
| 173 "form_data BLOB," | |
| 174 "date_synced INTEGER," | |
| 175 "display_name VARCHAR," | |
| 176 "avatar_url VARCHAR," | |
| 177 "federation_url VARCHAR," | |
| 178 "skip_next_zero_click INTEGER," | |
| 179 "UNIQUE " | |
| 180 "(origin_url, username_element, " | |
| 181 "username_value, password_element, signon_realm))"; | |
| 182 return db->Execute(query.str().c_str()); | |
| 183 } | |
| 184 | |
| 185 bool CreateIndexOnSignonRealm(sql::Connection* db, | |
| 186 base::StringPiece table_name) { | |
| 187 std::ostringstream query; | |
| 188 query << "CREATE INDEX logins_signon ON " << table_name << " (signon_realm)"; | |
|
Mike West
2015/02/03 14:15:41
I'm deferring to gcasto@ on these bits. It has bee
vasilii
2015/02/03 19:49:17
I'm jealous :-)
| |
| 189 return db->Execute(query.str().c_str()); | |
| 190 } | |
| 191 | |
| 153 } // namespace | 192 } // namespace |
| 154 | 193 |
| 155 LoginDatabase::LoginDatabase(const base::FilePath& db_path) | 194 LoginDatabase::LoginDatabase(const base::FilePath& db_path) |
| 156 : db_path_(db_path) { | 195 : db_path_(db_path) { |
| 157 } | 196 } |
| 158 | 197 |
| 159 LoginDatabase::~LoginDatabase() { | 198 LoginDatabase::~LoginDatabase() { |
| 160 } | 199 } |
| 161 | 200 |
| 162 bool LoginDatabase::Init() { | 201 bool LoginDatabase::Init() { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 !db_.Execute("DROP TABLE logins") || | 337 !db_.Execute("DROP TABLE logins") || |
| 299 !db_.Execute( | 338 !db_.Execute( |
| 300 ("CREATE TABLE logins(" + fields_to_copy + ")").c_str()) || | 339 ("CREATE TABLE logins(" + fields_to_copy + ")").c_str()) || |
| 301 !db_.Execute(copy_data_query("logins_data", "logins").c_str()) || | 340 !db_.Execute(copy_data_query("logins_data", "logins").c_str()) || |
| 302 !db_.Execute("DROP TABLE logins_data") || | 341 !db_.Execute("DROP TABLE logins_data") || |
| 303 !db_.Execute("CREATE INDEX logins_signon ON logins (signon_realm)")) | 342 !db_.Execute("CREATE INDEX logins_signon ON logins (signon_realm)")) |
| 304 return false; | 343 return false; |
| 305 | 344 |
| 306 meta_table_.SetVersionNumber(10); | 345 meta_table_.SetVersionNumber(10); |
| 307 } | 346 } |
| 347 case 10: { | |
| 348 // rename is_zero_click -> skip_next_zero_click and restore the unique key | |
| 349 // (origin_url, username_element, username_value, password_element, | |
| 350 // signon_realm). | |
| 351 const char copy_query[] = "INSERT OR REPLACE INTO logins_new SELECT " | |
| 352 "origin_url, action_url, username_element, username_value, " | |
| 353 "password_element, password_value, submit_element, signon_realm, " | |
| 354 "ssl_valid, preferred, date_created, blacklisted_by_user, scheme, " | |
| 355 "password_type, possible_usernames, times_used, form_data, " | |
| 356 "date_synced, display_name, avatar_url, federation_url, is_zero_click" | |
|
Mike West
2015/02/03 14:15:41
In theory, we should be negating `is_zero_click`,
vasilii
2015/02/03 19:49:17
You are right. We know that is_zero_click==false f
| |
| 357 " FROM logins"; | |
| 358 if (!CreateNewTable(&db_, "logins_new") || | |
| 359 !db_.Execute(copy_query) || | |
| 360 !db_.Execute("DROP TABLE logins") || | |
| 361 !db_.Execute("ALTER TABLE logins_new RENAME TO logins") || | |
| 362 !CreateIndexOnSignonRealm(&db_, "logins")) | |
| 363 return false; | |
| 364 meta_table_.SetVersionNumber(11); | |
| 365 } | |
| 308 case kCurrentVersionNumber: | 366 case kCurrentVersionNumber: |
| 309 // Already up to date | 367 // Already up to date |
| 310 return true; | 368 return true; |
| 311 default: | 369 default: |
| 312 NOTREACHED(); | 370 NOTREACHED(); |
| 313 return false; | 371 return false; |
| 314 } | 372 } |
| 315 } | 373 } |
| 316 | 374 |
| 317 bool LoginDatabase::InitLoginsTable() { | 375 bool LoginDatabase::InitLoginsTable() { |
| 318 if (!db_.DoesTableExist("logins")) { | 376 if (!db_.DoesTableExist("logins")) { |
| 319 if (!db_.Execute( | 377 if (!CreateNewTable(&db_, "logins")) { |
| 320 "CREATE TABLE logins (" | |
| 321 "origin_url VARCHAR NOT NULL, " | |
| 322 "action_url VARCHAR, " | |
| 323 "username_element VARCHAR, " | |
| 324 "username_value VARCHAR, " | |
| 325 "password_element VARCHAR, " | |
| 326 "password_value BLOB, " | |
| 327 "submit_element VARCHAR, " | |
| 328 "signon_realm VARCHAR NOT NULL," | |
| 329 "ssl_valid INTEGER NOT NULL," | |
| 330 "preferred INTEGER NOT NULL," | |
| 331 "date_created INTEGER NOT NULL," | |
| 332 "blacklisted_by_user INTEGER NOT NULL," | |
| 333 "scheme INTEGER NOT NULL," | |
| 334 "password_type INTEGER," | |
| 335 "possible_usernames BLOB," | |
| 336 "times_used INTEGER," | |
| 337 "form_data BLOB," | |
| 338 "date_synced INTEGER," | |
| 339 "display_name VARCHAR," | |
| 340 "avatar_url VARCHAR," | |
| 341 "federation_url VARCHAR," | |
| 342 "is_zero_click INTEGER," | |
| 343 "UNIQUE " | |
| 344 "(origin_url, username_element, " | |
| 345 "username_value, password_element, " | |
| 346 "submit_element, signon_realm))")) { | |
| 347 NOTREACHED(); | 378 NOTREACHED(); |
| 348 return false; | 379 return false; |
| 349 } | 380 } |
| 350 if (!db_.Execute("CREATE INDEX logins_signon ON " | 381 if (!CreateIndexOnSignonRealm(&db_, "logins")) { |
| 351 "logins (signon_realm)")) { | |
| 352 NOTREACHED(); | 382 NOTREACHED(); |
| 353 return false; | 383 return false; |
| 354 } | 384 } |
| 355 } | 385 } |
| 356 return true; | 386 return true; |
| 357 } | 387 } |
| 358 | 388 |
| 359 void LoginDatabase::ReportMetrics(const std::string& sync_username, | 389 void LoginDatabase::ReportMetrics(const std::string& sync_username, |
| 360 bool custom_passphrase_sync_enabled) { | 390 bool custom_passphrase_sync_enabled) { |
| 361 sql::Statement s(db_.GetCachedStatement( | 391 sql::Statement s(db_.GetCachedStatement( |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 | 497 |
| 468 // You *must* change LoginTableColumns if this query changes. | 498 // You *must* change LoginTableColumns if this query changes. |
| 469 sql::Statement s(db_.GetCachedStatement( | 499 sql::Statement s(db_.GetCachedStatement( |
| 470 SQL_FROM_HERE, | 500 SQL_FROM_HERE, |
| 471 "INSERT INTO logins " | 501 "INSERT INTO logins " |
| 472 "(origin_url, action_url, username_element, username_value, " | 502 "(origin_url, action_url, username_element, username_value, " |
| 473 " password_element, password_value, submit_element, " | 503 " password_element, password_value, submit_element, " |
| 474 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 504 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 475 " scheme, password_type, possible_usernames, times_used, form_data, " | 505 " scheme, password_type, possible_usernames, times_used, form_data, " |
| 476 " date_synced, display_name, avatar_url," | 506 " date_synced, display_name, avatar_url," |
| 477 " federation_url, is_zero_click) VALUES " | 507 " federation_url, skip_next_zero_click) VALUES " |
| 478 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); | 508 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); |
| 479 BindAddStatement(form, encrypted_password, &s); | 509 BindAddStatement(form, encrypted_password, &s); |
| 480 db_.set_error_callback(base::Bind(&AddCallback)); | 510 db_.set_error_callback(base::Bind(&AddCallback)); |
| 481 const bool success = s.Run(); | 511 const bool success = s.Run(); |
| 482 db_.reset_error_callback(); | 512 db_.reset_error_callback(); |
| 483 if (success) { | 513 if (success) { |
| 484 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); | 514 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); |
| 485 return list; | 515 return list; |
| 486 } | 516 } |
| 487 // Repeat the same statement but with REPLACE semantic. | 517 // Repeat the same statement but with REPLACE semantic. |
| 488 s.Assign(db_.GetCachedStatement( | 518 s.Assign(db_.GetCachedStatement( |
| 489 SQL_FROM_HERE, | 519 SQL_FROM_HERE, |
| 490 "INSERT OR REPLACE INTO logins " | 520 "INSERT OR REPLACE INTO logins " |
| 491 "(origin_url, action_url, username_element, username_value, " | 521 "(origin_url, action_url, username_element, username_value, " |
| 492 " password_element, password_value, submit_element, " | 522 " password_element, password_value, submit_element, " |
| 493 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 523 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 494 " scheme, password_type, possible_usernames, times_used, form_data, " | 524 " scheme, password_type, possible_usernames, times_used, form_data, " |
| 495 " date_synced, display_name, avatar_url," | 525 " date_synced, display_name, avatar_url," |
| 496 " federation_url, is_zero_click) VALUES " | 526 " federation_url, skip_next_zero_click) VALUES " |
| 497 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); | 527 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); |
| 498 BindAddStatement(form, encrypted_password, &s); | 528 BindAddStatement(form, encrypted_password, &s); |
| 499 if (s.Run()) { | 529 if (s.Run()) { |
| 500 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); | 530 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); |
| 501 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); | 531 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); |
| 502 } | 532 } |
| 503 return list; | 533 return list; |
| 504 } | 534 } |
| 505 | 535 |
| 506 PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) { | 536 PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 521 "times_used = ?, " | 551 "times_used = ?, " |
| 522 "submit_element = ?, " | 552 "submit_element = ?, " |
| 523 "date_synced = ?, " | 553 "date_synced = ?, " |
| 524 "date_created = ?, " | 554 "date_created = ?, " |
| 525 "blacklisted_by_user = ?, " | 555 "blacklisted_by_user = ?, " |
| 526 "scheme = ?, " | 556 "scheme = ?, " |
| 527 "password_type = ?, " | 557 "password_type = ?, " |
| 528 "display_name = ?, " | 558 "display_name = ?, " |
| 529 "avatar_url = ?, " | 559 "avatar_url = ?, " |
| 530 "federation_url = ?, " | 560 "federation_url = ?, " |
| 531 "is_zero_click = ? " | 561 "skip_next_zero_click = ? " |
| 532 "WHERE origin_url = ? AND " | 562 "WHERE origin_url = ? AND " |
| 533 "username_element = ? AND " | 563 "username_element = ? AND " |
| 534 "username_value = ? AND " | 564 "username_value = ? AND " |
| 535 "password_element = ? AND " | 565 "password_element = ? AND " |
| 536 "signon_realm = ?")); | 566 "signon_realm = ?")); |
| 537 s.BindString(0, form.action.spec()); | 567 s.BindString(0, form.action.spec()); |
| 538 s.BindBlob(1, encrypted_password.data(), | 568 s.BindBlob(1, encrypted_password.data(), |
| 539 static_cast<int>(encrypted_password.length())); | 569 static_cast<int>(encrypted_password.length())); |
| 540 s.BindInt(2, form.ssl_valid); | 570 s.BindInt(2, form.ssl_valid); |
| 541 s.BindInt(3, form.preferred); | 571 s.BindInt(3, form.preferred); |
| 542 Pickle pickle = SerializeVector(form.other_possible_usernames); | 572 Pickle pickle = SerializeVector(form.other_possible_usernames); |
| 543 s.BindBlob(4, pickle.data(), pickle.size()); | 573 s.BindBlob(4, pickle.data(), pickle.size()); |
| 544 s.BindInt(5, form.times_used); | 574 s.BindInt(5, form.times_used); |
| 545 s.BindString16(6, form.submit_element); | 575 s.BindString16(6, form.submit_element); |
| 546 s.BindInt64(7, form.date_synced.ToInternalValue()); | 576 s.BindInt64(7, form.date_synced.ToInternalValue()); |
| 547 s.BindInt64(8, form.date_created.ToInternalValue()); | 577 s.BindInt64(8, form.date_created.ToInternalValue()); |
| 548 s.BindInt(9, form.blacklisted_by_user); | 578 s.BindInt(9, form.blacklisted_by_user); |
| 549 s.BindInt(10, form.scheme); | 579 s.BindInt(10, form.scheme); |
| 550 s.BindInt(11, form.type); | 580 s.BindInt(11, form.type); |
| 551 s.BindString16(12, form.display_name); | 581 s.BindString16(12, form.display_name); |
| 552 s.BindString(13, form.avatar_url.spec()); | 582 s.BindString(13, form.avatar_url.spec()); |
| 553 s.BindString(14, form.federation_url.spec()); | 583 s.BindString(14, form.federation_url.spec()); |
| 554 s.BindInt(15, form.is_zero_click); | 584 s.BindInt(15, form.skip_next_zero_click); |
| 555 | 585 |
| 556 // WHERE starts here. | 586 // WHERE starts here. |
| 557 s.BindString(16, form.origin.spec()); | 587 s.BindString(16, form.origin.spec()); |
| 558 s.BindString16(17, form.username_element); | 588 s.BindString16(17, form.username_element); |
| 559 s.BindString16(18, form.username_value); | 589 s.BindString16(18, form.username_value); |
| 560 s.BindString16(19, form.password_element); | 590 s.BindString16(19, form.password_element); |
| 561 s.BindString(20, form.signon_realm); | 591 s.BindString(20, form.signon_realm); |
| 562 | 592 |
| 563 if (!s.Run()) | 593 if (!s.Run()) |
| 564 return PasswordStoreChangeList(); | 594 return PasswordStoreChangeList(); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 665 static_cast<const char*>(s.ColumnBlob(COLUMN_FORM_DATA)), | 695 static_cast<const char*>(s.ColumnBlob(COLUMN_FORM_DATA)), |
| 666 s.ColumnByteLength(COLUMN_FORM_DATA)); | 696 s.ColumnByteLength(COLUMN_FORM_DATA)); |
| 667 PickleIterator form_data_iter(form_data_pickle); | 697 PickleIterator form_data_iter(form_data_pickle); |
| 668 autofill::DeserializeFormData(&form_data_iter, &form->form_data); | 698 autofill::DeserializeFormData(&form_data_iter, &form->form_data); |
| 669 } | 699 } |
| 670 form->date_synced = | 700 form->date_synced = |
| 671 base::Time::FromInternalValue(s.ColumnInt64(COLUMN_DATE_SYNCED)); | 701 base::Time::FromInternalValue(s.ColumnInt64(COLUMN_DATE_SYNCED)); |
| 672 form->display_name = s.ColumnString16(COLUMN_DISPLAY_NAME); | 702 form->display_name = s.ColumnString16(COLUMN_DISPLAY_NAME); |
| 673 form->avatar_url = GURL(s.ColumnString(COLUMN_AVATAR_URL)); | 703 form->avatar_url = GURL(s.ColumnString(COLUMN_AVATAR_URL)); |
| 674 form->federation_url = GURL(s.ColumnString(COLUMN_FEDERATION_URL)); | 704 form->federation_url = GURL(s.ColumnString(COLUMN_FEDERATION_URL)); |
| 675 form->is_zero_click = (s.ColumnInt(COLUMN_IS_ZERO_CLICK) > 0); | 705 form->skip_next_zero_click = (s.ColumnInt(COLUMN_SKIP_ZERO_CLICK) > 0); |
| 676 return ENCRYPTION_RESULT_SUCCESS; | 706 return ENCRYPTION_RESULT_SUCCESS; |
| 677 } | 707 } |
| 678 | 708 |
| 679 bool LoginDatabase::GetLogins( | 709 bool LoginDatabase::GetLogins( |
| 680 const PasswordForm& form, | 710 const PasswordForm& form, |
| 681 ScopedVector<autofill::PasswordForm>* forms) const { | 711 ScopedVector<autofill::PasswordForm>* forms) const { |
| 682 DCHECK(forms); | 712 DCHECK(forms); |
| 683 // You *must* change LoginTableColumns if this query changes. | 713 // You *must* change LoginTableColumns if this query changes. |
| 684 const std::string sql_query = | 714 const std::string sql_query = |
| 685 "SELECT origin_url, action_url, " | 715 "SELECT origin_url, action_url, " |
| 686 "username_element, username_value, " | 716 "username_element, username_value, " |
| 687 "password_element, password_value, submit_element, " | 717 "password_element, password_value, submit_element, " |
| 688 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 718 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 689 "scheme, password_type, possible_usernames, times_used, form_data, " | 719 "scheme, password_type, possible_usernames, times_used, form_data, " |
| 690 "date_synced, display_name, avatar_url, " | 720 "date_synced, display_name, avatar_url, " |
| 691 "federation_url, is_zero_click FROM logins WHERE signon_realm == ? "; | 721 "federation_url, skip_next_zero_click " |
| 722 "FROM logins WHERE signon_realm == ? "; | |
| 692 sql::Statement s; | 723 sql::Statement s; |
| 693 const GURL signon_realm(form.signon_realm); | 724 const GURL signon_realm(form.signon_realm); |
| 694 std::string registered_domain = GetRegistryControlledDomain(signon_realm); | 725 std::string registered_domain = GetRegistryControlledDomain(signon_realm); |
| 695 PSLDomainMatchMetric psl_domain_match_metric = PSL_DOMAIN_MATCH_NONE; | 726 PSLDomainMatchMetric psl_domain_match_metric = PSL_DOMAIN_MATCH_NONE; |
| 696 const bool should_PSL_matching_apply = | 727 const bool should_PSL_matching_apply = |
| 697 form.scheme == PasswordForm::SCHEME_HTML && | 728 form.scheme == PasswordForm::SCHEME_HTML && |
| 698 ShouldPSLDomainMatchingApply(registered_domain); | 729 ShouldPSLDomainMatchingApply(registered_domain); |
| 699 // PSL matching only applies to HTML forms. | 730 // PSL matching only applies to HTML forms. |
| 700 if (should_PSL_matching_apply) { | 731 if (should_PSL_matching_apply) { |
| 701 // We are extending the original SQL query with one that includes more | 732 // We are extending the original SQL query with one that includes more |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 778 ScopedVector<autofill::PasswordForm>* forms) const { | 809 ScopedVector<autofill::PasswordForm>* forms) const { |
| 779 DCHECK(forms); | 810 DCHECK(forms); |
| 780 sql::Statement s(db_.GetCachedStatement( | 811 sql::Statement s(db_.GetCachedStatement( |
| 781 SQL_FROM_HERE, | 812 SQL_FROM_HERE, |
| 782 "SELECT origin_url, action_url, " | 813 "SELECT origin_url, action_url, " |
| 783 "username_element, username_value, " | 814 "username_element, username_value, " |
| 784 "password_element, password_value, submit_element, " | 815 "password_element, password_value, submit_element, " |
| 785 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 816 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 786 "scheme, password_type, possible_usernames, times_used, form_data, " | 817 "scheme, password_type, possible_usernames, times_used, form_data, " |
| 787 "date_synced, display_name, avatar_url, " | 818 "date_synced, display_name, avatar_url, " |
| 788 "federation_url, is_zero_click FROM logins " | 819 "federation_url, skip_next_zero_click FROM logins " |
| 789 "WHERE date_created >= ? AND date_created < ?" | 820 "WHERE date_created >= ? AND date_created < ?" |
| 790 "ORDER BY origin_url")); | 821 "ORDER BY origin_url")); |
| 791 s.BindInt64(0, begin.ToInternalValue()); | 822 s.BindInt64(0, begin.ToInternalValue()); |
| 792 s.BindInt64(1, end.is_null() ? std::numeric_limits<int64>::max() | 823 s.BindInt64(1, end.is_null() ? std::numeric_limits<int64>::max() |
| 793 : end.ToInternalValue()); | 824 : end.ToInternalValue()); |
| 794 | 825 |
| 795 while (s.Step()) { | 826 while (s.Step()) { |
| 796 scoped_ptr<PasswordForm> new_form(new PasswordForm()); | 827 scoped_ptr<PasswordForm> new_form(new PasswordForm()); |
| 797 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); | 828 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); |
| 798 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) | 829 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 810 const base::Time end, | 841 const base::Time end, |
| 811 ScopedVector<autofill::PasswordForm>* forms) const { | 842 ScopedVector<autofill::PasswordForm>* forms) const { |
| 812 DCHECK(forms); | 843 DCHECK(forms); |
| 813 sql::Statement s(db_.GetCachedStatement( | 844 sql::Statement s(db_.GetCachedStatement( |
| 814 SQL_FROM_HERE, | 845 SQL_FROM_HERE, |
| 815 "SELECT origin_url, action_url, username_element, username_value, " | 846 "SELECT origin_url, action_url, username_element, username_value, " |
| 816 "password_element, password_value, submit_element, signon_realm, " | 847 "password_element, password_value, submit_element, signon_realm, " |
| 817 "ssl_valid, preferred, date_created, blacklisted_by_user, " | 848 "ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 818 "scheme, password_type, possible_usernames, times_used, form_data, " | 849 "scheme, password_type, possible_usernames, times_used, form_data, " |
| 819 "date_synced, display_name, avatar_url, " | 850 "date_synced, display_name, avatar_url, " |
| 820 "federation_url, is_zero_click FROM logins " | 851 "federation_url, skip_next_zero_click FROM logins " |
| 821 "WHERE date_synced >= ? AND date_synced < ?" | 852 "WHERE date_synced >= ? AND date_synced < ?" |
| 822 "ORDER BY origin_url")); | 853 "ORDER BY origin_url")); |
| 823 s.BindInt64(0, begin.ToInternalValue()); | 854 s.BindInt64(0, begin.ToInternalValue()); |
| 824 s.BindInt64(1, | 855 s.BindInt64(1, |
| 825 end.is_null() ? base::Time::Max().ToInternalValue() | 856 end.is_null() ? base::Time::Max().ToInternalValue() |
| 826 : end.ToInternalValue()); | 857 : end.ToInternalValue()); |
| 827 | 858 |
| 828 while (s.Step()) { | 859 while (s.Step()) { |
| 829 scoped_ptr<PasswordForm> new_form(new PasswordForm()); | 860 scoped_ptr<PasswordForm> new_form(new PasswordForm()); |
| 830 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); | 861 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 854 DCHECK(forms); | 885 DCHECK(forms); |
| 855 // You *must* change LoginTableColumns if this query changes. | 886 // You *must* change LoginTableColumns if this query changes. |
| 856 sql::Statement s(db_.GetCachedStatement( | 887 sql::Statement s(db_.GetCachedStatement( |
| 857 SQL_FROM_HERE, | 888 SQL_FROM_HERE, |
| 858 "SELECT origin_url, action_url, " | 889 "SELECT origin_url, action_url, " |
| 859 "username_element, username_value, " | 890 "username_element, username_value, " |
| 860 "password_element, password_value, submit_element, " | 891 "password_element, password_value, submit_element, " |
| 861 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 892 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 862 "scheme, password_type, possible_usernames, times_used, form_data, " | 893 "scheme, password_type, possible_usernames, times_used, form_data, " |
| 863 "date_synced, display_name, avatar_url, " | 894 "date_synced, display_name, avatar_url, " |
| 864 "federation_url, is_zero_click FROM logins " | 895 "federation_url, skip_next_zero_click FROM logins " |
| 865 "WHERE blacklisted_by_user == ? ORDER BY origin_url")); | 896 "WHERE blacklisted_by_user == ? ORDER BY origin_url")); |
| 866 s.BindInt(0, blacklisted ? 1 : 0); | 897 s.BindInt(0, blacklisted ? 1 : 0); |
| 867 | 898 |
| 868 while (s.Step()) { | 899 while (s.Step()) { |
| 869 scoped_ptr<PasswordForm> new_form(new PasswordForm()); | 900 scoped_ptr<PasswordForm> new_form(new PasswordForm()); |
| 870 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); | 901 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); |
| 871 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) | 902 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) |
| 872 return false; | 903 return false; |
| 873 if (result == ENCRYPTION_RESULT_ITEM_FAILURE) | 904 if (result == ENCRYPTION_RESULT_ITEM_FAILURE) |
| 874 continue; | 905 continue; |
| 875 DCHECK(result == ENCRYPTION_RESULT_SUCCESS); | 906 DCHECK(result == ENCRYPTION_RESULT_SUCCESS); |
| 876 forms->push_back(new_form.release()); | 907 forms->push_back(new_form.release()); |
| 877 } | 908 } |
| 878 return s.Succeeded(); | 909 return s.Succeeded(); |
| 879 } | 910 } |
| 880 | 911 |
| 881 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { | 912 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { |
| 882 DCHECK(db_.is_open()); | 913 DCHECK(db_.is_open()); |
| 883 meta_table_.Reset(); | 914 meta_table_.Reset(); |
| 884 db_.Close(); | 915 db_.Close(); |
| 885 sql::Connection::Delete(db_path_); | 916 sql::Connection::Delete(db_path_); |
| 886 return Init(); | 917 return Init(); |
| 887 } | 918 } |
| 888 | 919 |
| 889 } // namespace password_manager | 920 } // namespace password_manager |
| OLD | NEW |