| 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_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, const char* table_name) { |
| 155 std::string query = base::StringPrintf( |
| 156 "CREATE TABLE %s (" |
| 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_zero_click INTEGER," |
| 179 "UNIQUE (origin_url, username_element, username_value, " |
| 180 "password_element, signon_realm))", table_name); |
| 181 return db->Execute(query.c_str()); |
| 182 } |
| 183 |
| 184 bool CreateIndexOnSignonRealm(sql::Connection* db, const char* table_name) { |
| 185 std::string query = base::StringPrintf( |
| 186 "CREATE INDEX logins_signon ON %s (signon_realm)", table_name); |
| 187 return db->Execute(query.c_str()); |
| 188 } |
| 189 |
| 153 } // namespace | 190 } // namespace |
| 154 | 191 |
| 155 LoginDatabase::LoginDatabase(const base::FilePath& db_path) | 192 LoginDatabase::LoginDatabase(const base::FilePath& db_path) |
| 156 : db_path_(db_path) { | 193 : db_path_(db_path) { |
| 157 } | 194 } |
| 158 | 195 |
| 159 LoginDatabase::~LoginDatabase() { | 196 LoginDatabase::~LoginDatabase() { |
| 160 } | 197 } |
| 161 | 198 |
| 162 bool LoginDatabase::Init() { | 199 bool LoginDatabase::Init() { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 }; | 330 }; |
| 294 | 331 |
| 295 if (!db_.Execute(("CREATE TEMPORARY TABLE logins_data(" + fields_to_copy + | 332 if (!db_.Execute(("CREATE TEMPORARY TABLE logins_data(" + fields_to_copy + |
| 296 ")").c_str()) || | 333 ")").c_str()) || |
| 297 !db_.Execute(copy_data_query("logins", "logins_data").c_str()) || | 334 !db_.Execute(copy_data_query("logins", "logins_data").c_str()) || |
| 298 !db_.Execute("DROP TABLE logins") || | 335 !db_.Execute("DROP TABLE logins") || |
| 299 !db_.Execute( | 336 !db_.Execute( |
| 300 ("CREATE TABLE logins(" + fields_to_copy + ")").c_str()) || | 337 ("CREATE TABLE logins(" + fields_to_copy + ")").c_str()) || |
| 301 !db_.Execute(copy_data_query("logins_data", "logins").c_str()) || | 338 !db_.Execute(copy_data_query("logins_data", "logins").c_str()) || |
| 302 !db_.Execute("DROP TABLE logins_data") || | 339 !db_.Execute("DROP TABLE logins_data") || |
| 303 !db_.Execute("CREATE INDEX logins_signon ON logins (signon_realm)")) | 340 !CreateIndexOnSignonRealm(&db_, "logins")) |
| 304 return false; | 341 return false; |
| 305 | 342 |
| 306 meta_table_.SetVersionNumber(10); | 343 meta_table_.SetVersionNumber(10); |
| 307 } | 344 } |
| 345 case 10: { |
| 346 // rename is_zero_click -> skip_zero_click and restore the unique key |
| 347 // (origin_url, username_element, username_value, password_element, |
| 348 // signon_realm). |
| 349 const char copy_query[] = "INSERT OR REPLACE INTO logins_new SELECT " |
| 350 "origin_url, action_url, username_element, username_value, " |
| 351 "password_element, password_value, submit_element, signon_realm, " |
| 352 "ssl_valid, preferred, date_created, blacklisted_by_user, scheme, " |
| 353 "password_type, possible_usernames, times_used, form_data, " |
| 354 "date_synced, display_name, avatar_url, federation_url, is_zero_click" |
| 355 " FROM logins"; |
| 356 if (!CreateNewTable(&db_, "logins_new") || |
| 357 !db_.Execute(copy_query) || |
| 358 !db_.Execute("DROP TABLE logins") || |
| 359 !db_.Execute("ALTER TABLE logins_new RENAME TO logins") || |
| 360 !CreateIndexOnSignonRealm(&db_, "logins")) |
| 361 return false; |
| 362 meta_table_.SetVersionNumber(11); |
| 363 } |
| 308 case kCurrentVersionNumber: | 364 case kCurrentVersionNumber: |
| 309 // Already up to date | 365 // Already up to date |
| 310 return true; | 366 return true; |
| 311 default: | 367 default: |
| 312 NOTREACHED(); | 368 NOTREACHED(); |
| 313 return false; | 369 return false; |
| 314 } | 370 } |
| 315 } | 371 } |
| 316 | 372 |
| 317 bool LoginDatabase::InitLoginsTable() { | 373 bool LoginDatabase::InitLoginsTable() { |
| 318 if (!db_.DoesTableExist("logins")) { | 374 if (!db_.DoesTableExist("logins")) { |
| 319 if (!db_.Execute( | 375 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(); | 376 NOTREACHED(); |
| 348 return false; | 377 return false; |
| 349 } | 378 } |
| 350 if (!db_.Execute("CREATE INDEX logins_signon ON " | 379 if (!CreateIndexOnSignonRealm(&db_, "logins")) { |
| 351 "logins (signon_realm)")) { | |
| 352 NOTREACHED(); | 380 NOTREACHED(); |
| 353 return false; | 381 return false; |
| 354 } | 382 } |
| 355 } | 383 } |
| 356 return true; | 384 return true; |
| 357 } | 385 } |
| 358 | 386 |
| 359 void LoginDatabase::ReportMetrics(const std::string& sync_username, | 387 void LoginDatabase::ReportMetrics(const std::string& sync_username, |
| 360 bool custom_passphrase_sync_enabled) { | 388 bool custom_passphrase_sync_enabled) { |
| 361 sql::Statement s(db_.GetCachedStatement( | 389 sql::Statement s(db_.GetCachedStatement( |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 | 495 |
| 468 // You *must* change LoginTableColumns if this query changes. | 496 // You *must* change LoginTableColumns if this query changes. |
| 469 sql::Statement s(db_.GetCachedStatement( | 497 sql::Statement s(db_.GetCachedStatement( |
| 470 SQL_FROM_HERE, | 498 SQL_FROM_HERE, |
| 471 "INSERT INTO logins " | 499 "INSERT INTO logins " |
| 472 "(origin_url, action_url, username_element, username_value, " | 500 "(origin_url, action_url, username_element, username_value, " |
| 473 " password_element, password_value, submit_element, " | 501 " password_element, password_value, submit_element, " |
| 474 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 502 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 475 " scheme, password_type, possible_usernames, times_used, form_data, " | 503 " scheme, password_type, possible_usernames, times_used, form_data, " |
| 476 " date_synced, display_name, avatar_url," | 504 " date_synced, display_name, avatar_url," |
| 477 " federation_url, is_zero_click) VALUES " | 505 " federation_url, skip_zero_click) VALUES " |
| 478 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); | 506 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); |
| 479 BindAddStatement(form, encrypted_password, &s); | 507 BindAddStatement(form, encrypted_password, &s); |
| 480 db_.set_error_callback(base::Bind(&AddCallback)); | 508 db_.set_error_callback(base::Bind(&AddCallback)); |
| 481 const bool success = s.Run(); | 509 const bool success = s.Run(); |
| 482 db_.reset_error_callback(); | 510 db_.reset_error_callback(); |
| 483 if (success) { | 511 if (success) { |
| 484 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); | 512 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); |
| 485 return list; | 513 return list; |
| 486 } | 514 } |
| 487 // Repeat the same statement but with REPLACE semantic. | 515 // Repeat the same statement but with REPLACE semantic. |
| 488 s.Assign(db_.GetCachedStatement( | 516 s.Assign(db_.GetCachedStatement( |
| 489 SQL_FROM_HERE, | 517 SQL_FROM_HERE, |
| 490 "INSERT OR REPLACE INTO logins " | 518 "INSERT OR REPLACE INTO logins " |
| 491 "(origin_url, action_url, username_element, username_value, " | 519 "(origin_url, action_url, username_element, username_value, " |
| 492 " password_element, password_value, submit_element, " | 520 " password_element, password_value, submit_element, " |
| 493 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 521 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 494 " scheme, password_type, possible_usernames, times_used, form_data, " | 522 " scheme, password_type, possible_usernames, times_used, form_data, " |
| 495 " date_synced, display_name, avatar_url," | 523 " date_synced, display_name, avatar_url," |
| 496 " federation_url, is_zero_click) VALUES " | 524 " federation_url, skip_zero_click) VALUES " |
| 497 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); | 525 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); |
| 498 BindAddStatement(form, encrypted_password, &s); | 526 BindAddStatement(form, encrypted_password, &s); |
| 499 if (s.Run()) { | 527 if (s.Run()) { |
| 500 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); | 528 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); |
| 501 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); | 529 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); |
| 502 } | 530 } |
| 503 return list; | 531 return list; |
| 504 } | 532 } |
| 505 | 533 |
| 506 PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) { | 534 PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 521 "times_used = ?, " | 549 "times_used = ?, " |
| 522 "submit_element = ?, " | 550 "submit_element = ?, " |
| 523 "date_synced = ?, " | 551 "date_synced = ?, " |
| 524 "date_created = ?, " | 552 "date_created = ?, " |
| 525 "blacklisted_by_user = ?, " | 553 "blacklisted_by_user = ?, " |
| 526 "scheme = ?, " | 554 "scheme = ?, " |
| 527 "password_type = ?, " | 555 "password_type = ?, " |
| 528 "display_name = ?, " | 556 "display_name = ?, " |
| 529 "avatar_url = ?, " | 557 "avatar_url = ?, " |
| 530 "federation_url = ?, " | 558 "federation_url = ?, " |
| 531 "is_zero_click = ? " | 559 "skip_zero_click = ? " |
| 532 "WHERE origin_url = ? AND " | 560 "WHERE origin_url = ? AND " |
| 533 "username_element = ? AND " | 561 "username_element = ? AND " |
| 534 "username_value = ? AND " | 562 "username_value = ? AND " |
| 535 "password_element = ? AND " | 563 "password_element = ? AND " |
| 536 "signon_realm = ?")); | 564 "signon_realm = ?")); |
| 537 s.BindString(0, form.action.spec()); | 565 s.BindString(0, form.action.spec()); |
| 538 s.BindBlob(1, encrypted_password.data(), | 566 s.BindBlob(1, encrypted_password.data(), |
| 539 static_cast<int>(encrypted_password.length())); | 567 static_cast<int>(encrypted_password.length())); |
| 540 s.BindInt(2, form.ssl_valid); | 568 s.BindInt(2, form.ssl_valid); |
| 541 s.BindInt(3, form.preferred); | 569 s.BindInt(3, form.preferred); |
| 542 Pickle pickle = SerializeVector(form.other_possible_usernames); | 570 Pickle pickle = SerializeVector(form.other_possible_usernames); |
| 543 s.BindBlob(4, pickle.data(), pickle.size()); | 571 s.BindBlob(4, pickle.data(), pickle.size()); |
| 544 s.BindInt(5, form.times_used); | 572 s.BindInt(5, form.times_used); |
| 545 s.BindString16(6, form.submit_element); | 573 s.BindString16(6, form.submit_element); |
| 546 s.BindInt64(7, form.date_synced.ToInternalValue()); | 574 s.BindInt64(7, form.date_synced.ToInternalValue()); |
| 547 s.BindInt64(8, form.date_created.ToInternalValue()); | 575 s.BindInt64(8, form.date_created.ToInternalValue()); |
| 548 s.BindInt(9, form.blacklisted_by_user); | 576 s.BindInt(9, form.blacklisted_by_user); |
| 549 s.BindInt(10, form.scheme); | 577 s.BindInt(10, form.scheme); |
| 550 s.BindInt(11, form.type); | 578 s.BindInt(11, form.type); |
| 551 s.BindString16(12, form.display_name); | 579 s.BindString16(12, form.display_name); |
| 552 s.BindString(13, form.avatar_url.spec()); | 580 s.BindString(13, form.avatar_url.spec()); |
| 553 s.BindString(14, form.federation_url.spec()); | 581 s.BindString(14, form.federation_url.spec()); |
| 554 s.BindInt(15, form.is_zero_click); | 582 s.BindInt(15, form.skip_zero_click); |
| 555 | 583 |
| 556 // WHERE starts here. | 584 // WHERE starts here. |
| 557 s.BindString(16, form.origin.spec()); | 585 s.BindString(16, form.origin.spec()); |
| 558 s.BindString16(17, form.username_element); | 586 s.BindString16(17, form.username_element); |
| 559 s.BindString16(18, form.username_value); | 587 s.BindString16(18, form.username_value); |
| 560 s.BindString16(19, form.password_element); | 588 s.BindString16(19, form.password_element); |
| 561 s.BindString(20, form.signon_realm); | 589 s.BindString(20, form.signon_realm); |
| 562 | 590 |
| 563 if (!s.Run()) | 591 if (!s.Run()) |
| 564 return PasswordStoreChangeList(); | 592 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)), | 693 static_cast<const char*>(s.ColumnBlob(COLUMN_FORM_DATA)), |
| 666 s.ColumnByteLength(COLUMN_FORM_DATA)); | 694 s.ColumnByteLength(COLUMN_FORM_DATA)); |
| 667 PickleIterator form_data_iter(form_data_pickle); | 695 PickleIterator form_data_iter(form_data_pickle); |
| 668 autofill::DeserializeFormData(&form_data_iter, &form->form_data); | 696 autofill::DeserializeFormData(&form_data_iter, &form->form_data); |
| 669 } | 697 } |
| 670 form->date_synced = | 698 form->date_synced = |
| 671 base::Time::FromInternalValue(s.ColumnInt64(COLUMN_DATE_SYNCED)); | 699 base::Time::FromInternalValue(s.ColumnInt64(COLUMN_DATE_SYNCED)); |
| 672 form->display_name = s.ColumnString16(COLUMN_DISPLAY_NAME); | 700 form->display_name = s.ColumnString16(COLUMN_DISPLAY_NAME); |
| 673 form->avatar_url = GURL(s.ColumnString(COLUMN_AVATAR_URL)); | 701 form->avatar_url = GURL(s.ColumnString(COLUMN_AVATAR_URL)); |
| 674 form->federation_url = GURL(s.ColumnString(COLUMN_FEDERATION_URL)); | 702 form->federation_url = GURL(s.ColumnString(COLUMN_FEDERATION_URL)); |
| 675 form->is_zero_click = (s.ColumnInt(COLUMN_IS_ZERO_CLICK) > 0); | 703 form->skip_zero_click = (s.ColumnInt(COLUMN_SKIP_ZERO_CLICK) > 0); |
| 676 return ENCRYPTION_RESULT_SUCCESS; | 704 return ENCRYPTION_RESULT_SUCCESS; |
| 677 } | 705 } |
| 678 | 706 |
| 679 bool LoginDatabase::GetLogins( | 707 bool LoginDatabase::GetLogins( |
| 680 const PasswordForm& form, | 708 const PasswordForm& form, |
| 681 ScopedVector<autofill::PasswordForm>* forms) const { | 709 ScopedVector<autofill::PasswordForm>* forms) const { |
| 682 DCHECK(forms); | 710 DCHECK(forms); |
| 683 // You *must* change LoginTableColumns if this query changes. | 711 // You *must* change LoginTableColumns if this query changes. |
| 684 const std::string sql_query = | 712 const std::string sql_query = |
| 685 "SELECT origin_url, action_url, " | 713 "SELECT origin_url, action_url, " |
| 686 "username_element, username_value, " | 714 "username_element, username_value, " |
| 687 "password_element, password_value, submit_element, " | 715 "password_element, password_value, submit_element, " |
| 688 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 716 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 689 "scheme, password_type, possible_usernames, times_used, form_data, " | 717 "scheme, password_type, possible_usernames, times_used, form_data, " |
| 690 "date_synced, display_name, avatar_url, " | 718 "date_synced, display_name, avatar_url, " |
| 691 "federation_url, is_zero_click FROM logins WHERE signon_realm == ? "; | 719 "federation_url, skip_zero_click " |
| 720 "FROM logins WHERE signon_realm == ? "; |
| 692 sql::Statement s; | 721 sql::Statement s; |
| 693 const GURL signon_realm(form.signon_realm); | 722 const GURL signon_realm(form.signon_realm); |
| 694 std::string registered_domain = GetRegistryControlledDomain(signon_realm); | 723 std::string registered_domain = GetRegistryControlledDomain(signon_realm); |
| 695 PSLDomainMatchMetric psl_domain_match_metric = PSL_DOMAIN_MATCH_NONE; | 724 PSLDomainMatchMetric psl_domain_match_metric = PSL_DOMAIN_MATCH_NONE; |
| 696 const bool should_PSL_matching_apply = | 725 const bool should_PSL_matching_apply = |
| 697 form.scheme == PasswordForm::SCHEME_HTML && | 726 form.scheme == PasswordForm::SCHEME_HTML && |
| 698 ShouldPSLDomainMatchingApply(registered_domain); | 727 ShouldPSLDomainMatchingApply(registered_domain); |
| 699 // PSL matching only applies to HTML forms. | 728 // PSL matching only applies to HTML forms. |
| 700 if (should_PSL_matching_apply) { | 729 if (should_PSL_matching_apply) { |
| 701 // We are extending the original SQL query with one that includes more | 730 // 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 { | 807 ScopedVector<autofill::PasswordForm>* forms) const { |
| 779 DCHECK(forms); | 808 DCHECK(forms); |
| 780 sql::Statement s(db_.GetCachedStatement( | 809 sql::Statement s(db_.GetCachedStatement( |
| 781 SQL_FROM_HERE, | 810 SQL_FROM_HERE, |
| 782 "SELECT origin_url, action_url, " | 811 "SELECT origin_url, action_url, " |
| 783 "username_element, username_value, " | 812 "username_element, username_value, " |
| 784 "password_element, password_value, submit_element, " | 813 "password_element, password_value, submit_element, " |
| 785 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 814 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 786 "scheme, password_type, possible_usernames, times_used, form_data, " | 815 "scheme, password_type, possible_usernames, times_used, form_data, " |
| 787 "date_synced, display_name, avatar_url, " | 816 "date_synced, display_name, avatar_url, " |
| 788 "federation_url, is_zero_click FROM logins " | 817 "federation_url, skip_zero_click FROM logins " |
| 789 "WHERE date_created >= ? AND date_created < ?" | 818 "WHERE date_created >= ? AND date_created < ?" |
| 790 "ORDER BY origin_url")); | 819 "ORDER BY origin_url")); |
| 791 s.BindInt64(0, begin.ToInternalValue()); | 820 s.BindInt64(0, begin.ToInternalValue()); |
| 792 s.BindInt64(1, end.is_null() ? std::numeric_limits<int64>::max() | 821 s.BindInt64(1, end.is_null() ? std::numeric_limits<int64>::max() |
| 793 : end.ToInternalValue()); | 822 : end.ToInternalValue()); |
| 794 | 823 |
| 795 while (s.Step()) { | 824 while (s.Step()) { |
| 796 scoped_ptr<PasswordForm> new_form(new PasswordForm()); | 825 scoped_ptr<PasswordForm> new_form(new PasswordForm()); |
| 797 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); | 826 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); |
| 798 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) | 827 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 810 const base::Time end, | 839 const base::Time end, |
| 811 ScopedVector<autofill::PasswordForm>* forms) const { | 840 ScopedVector<autofill::PasswordForm>* forms) const { |
| 812 DCHECK(forms); | 841 DCHECK(forms); |
| 813 sql::Statement s(db_.GetCachedStatement( | 842 sql::Statement s(db_.GetCachedStatement( |
| 814 SQL_FROM_HERE, | 843 SQL_FROM_HERE, |
| 815 "SELECT origin_url, action_url, username_element, username_value, " | 844 "SELECT origin_url, action_url, username_element, username_value, " |
| 816 "password_element, password_value, submit_element, signon_realm, " | 845 "password_element, password_value, submit_element, signon_realm, " |
| 817 "ssl_valid, preferred, date_created, blacklisted_by_user, " | 846 "ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 818 "scheme, password_type, possible_usernames, times_used, form_data, " | 847 "scheme, password_type, possible_usernames, times_used, form_data, " |
| 819 "date_synced, display_name, avatar_url, " | 848 "date_synced, display_name, avatar_url, " |
| 820 "federation_url, is_zero_click FROM logins " | 849 "federation_url, skip_zero_click FROM logins " |
| 821 "WHERE date_synced >= ? AND date_synced < ?" | 850 "WHERE date_synced >= ? AND date_synced < ?" |
| 822 "ORDER BY origin_url")); | 851 "ORDER BY origin_url")); |
| 823 s.BindInt64(0, begin.ToInternalValue()); | 852 s.BindInt64(0, begin.ToInternalValue()); |
| 824 s.BindInt64(1, | 853 s.BindInt64(1, |
| 825 end.is_null() ? base::Time::Max().ToInternalValue() | 854 end.is_null() ? base::Time::Max().ToInternalValue() |
| 826 : end.ToInternalValue()); | 855 : end.ToInternalValue()); |
| 827 | 856 |
| 828 while (s.Step()) { | 857 while (s.Step()) { |
| 829 scoped_ptr<PasswordForm> new_form(new PasswordForm()); | 858 scoped_ptr<PasswordForm> new_form(new PasswordForm()); |
| 830 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); | 859 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 854 DCHECK(forms); | 883 DCHECK(forms); |
| 855 // You *must* change LoginTableColumns if this query changes. | 884 // You *must* change LoginTableColumns if this query changes. |
| 856 sql::Statement s(db_.GetCachedStatement( | 885 sql::Statement s(db_.GetCachedStatement( |
| 857 SQL_FROM_HERE, | 886 SQL_FROM_HERE, |
| 858 "SELECT origin_url, action_url, " | 887 "SELECT origin_url, action_url, " |
| 859 "username_element, username_value, " | 888 "username_element, username_value, " |
| 860 "password_element, password_value, submit_element, " | 889 "password_element, password_value, submit_element, " |
| 861 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " | 890 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " |
| 862 "scheme, password_type, possible_usernames, times_used, form_data, " | 891 "scheme, password_type, possible_usernames, times_used, form_data, " |
| 863 "date_synced, display_name, avatar_url, " | 892 "date_synced, display_name, avatar_url, " |
| 864 "federation_url, is_zero_click FROM logins " | 893 "federation_url, skip_zero_click FROM logins " |
| 865 "WHERE blacklisted_by_user == ? ORDER BY origin_url")); | 894 "WHERE blacklisted_by_user == ? ORDER BY origin_url")); |
| 866 s.BindInt(0, blacklisted ? 1 : 0); | 895 s.BindInt(0, blacklisted ? 1 : 0); |
| 867 | 896 |
| 868 while (s.Step()) { | 897 while (s.Step()) { |
| 869 scoped_ptr<PasswordForm> new_form(new PasswordForm()); | 898 scoped_ptr<PasswordForm> new_form(new PasswordForm()); |
| 870 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); | 899 EncryptionResult result = InitPasswordFormFromStatement(new_form.get(), s); |
| 871 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) | 900 if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) |
| 872 return false; | 901 return false; |
| 873 if (result == ENCRYPTION_RESULT_ITEM_FAILURE) | 902 if (result == ENCRYPTION_RESULT_ITEM_FAILURE) |
| 874 continue; | 903 continue; |
| 875 DCHECK(result == ENCRYPTION_RESULT_SUCCESS); | 904 DCHECK(result == ENCRYPTION_RESULT_SUCCESS); |
| 876 forms->push_back(new_form.release()); | 905 forms->push_back(new_form.release()); |
| 877 } | 906 } |
| 878 return s.Succeeded(); | 907 return s.Succeeded(); |
| 879 } | 908 } |
| 880 | 909 |
| 881 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { | 910 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { |
| 882 DCHECK(db_.is_open()); | 911 DCHECK(db_.is_open()); |
| 883 meta_table_.Reset(); | 912 meta_table_.Reset(); |
| 884 db_.Close(); | 913 db_.Close(); |
| 885 sql::Connection::Delete(db_path_); | 914 sql::Connection::Delete(db_path_); |
| 886 return Init(); | 915 return Init(); |
| 887 } | 916 } |
| 888 | 917 |
| 889 } // namespace password_manager | 918 } // namespace password_manager |
| OLD | NEW |