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; | |
Garrett Casto
2015/02/04 06:58:40
The style guide discourages streams other than for
vasilii
2015/02/04 12:44:02
Done.
| |
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; | |
Garrett Casto
2015/02/04 06:58:40
Same here.
vasilii
2015/02/04 12:44:02
Done.
| |
188 query << "CREATE INDEX logins_signon ON " << table_name << " (signon_realm)"; | |
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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 }; | 332 }; |
294 | 333 |
295 if (!db_.Execute(("CREATE TEMPORARY TABLE logins_data(" + fields_to_copy + | 334 if (!db_.Execute(("CREATE TEMPORARY TABLE logins_data(" + fields_to_copy + |
296 ")").c_str()) || | 335 ")").c_str()) || |
297 !db_.Execute(copy_data_query("logins", "logins_data").c_str()) || | 336 !db_.Execute(copy_data_query("logins", "logins_data").c_str()) || |
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)")) |
Garrett Casto
2015/02/04 06:58:40
Nit: Might as well use CreateIndexOnSignonRealm()
vasilii
2015/02/04 12:44:02
Done.
| |
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" | |
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 |