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

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

Issue 283563002: Password Login Database: report correct changes from AddLogin(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/password_manager/core/browser/login_database.h" 5 #include "components/password_manager/core/browser/login_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h"
10 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
13 #include "base/pickle.h" 14 #include "base/pickle.h"
14 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
15 #include "base/time/time.h" 16 #include "base/time/time.h"
16 #include "components/autofill/core/common/password_form.h" 17 #include "components/autofill/core/common/password_form.h"
17 #include "sql/connection.h" 18 #include "sql/connection.h"
18 #include "sql/statement.h" 19 #include "sql/statement.h"
19 #include "sql/transaction.h" 20 #include "sql/transaction.h"
(...skipping 22 matching lines...) Expand all
42 COLUMN_DATE_CREATED, 43 COLUMN_DATE_CREATED,
43 COLUMN_BLACKLISTED_BY_USER, 44 COLUMN_BLACKLISTED_BY_USER,
44 COLUMN_SCHEME, 45 COLUMN_SCHEME,
45 COLUMN_PASSWORD_TYPE, 46 COLUMN_PASSWORD_TYPE,
46 COLUMN_POSSIBLE_USERNAMES, 47 COLUMN_POSSIBLE_USERNAMES,
47 COLUMN_TIMES_USED, 48 COLUMN_TIMES_USED,
48 COLUMN_FORM_DATA, 49 COLUMN_FORM_DATA,
49 COLUMN_USE_ADDITIONAL_AUTH 50 COLUMN_USE_ADDITIONAL_AUTH
50 }; 51 };
51 52
53 void BindAddStatement(const PasswordForm& form,
54 const std::string& encrypted_password,
55 sql::Statement* s) {
56 s->BindString(COLUMN_ORIGIN_URL, form.origin.spec());
57 s->BindString(COLUMN_ACTION_URL, form.action.spec());
58 s->BindString16(COLUMN_USERNAME_ELEMENT, form.username_element);
59 s->BindString16(COLUMN_USERNAME_VALUE, form.username_value);
60 s->BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element);
61 s->BindBlob(COLUMN_PASSWORD_VALUE, encrypted_password.data(),
62 static_cast<int>(encrypted_password.length()));
63 s->BindString16(COLUMN_SUBMIT_ELEMENT, form.submit_element);
64 s->BindString(COLUMN_SIGNON_REALM, form.signon_realm);
65 s->BindInt(COLUMN_SSL_VALID, form.ssl_valid);
66 s->BindInt(COLUMN_PREFERRED, form.preferred);
67 s->BindInt64(COLUMN_DATE_CREATED, form.date_created.ToTimeT());
68 s->BindInt(COLUMN_BLACKLISTED_BY_USER, form.blacklisted_by_user);
69 s->BindInt(COLUMN_SCHEME, form.scheme);
70 s->BindInt(COLUMN_PASSWORD_TYPE, form.type);
71 Pickle usernames_pickle =
72 LoginDatabase::SerializeVector(form.other_possible_usernames);
73 s->BindBlob(COLUMN_POSSIBLE_USERNAMES,
74 usernames_pickle.data(),
75 usernames_pickle.size());
76 s->BindInt(COLUMN_TIMES_USED, form.times_used);
77 Pickle form_data_pickle;
78 autofill::SerializeFormData(form.form_data, &form_data_pickle);
79 s->BindBlob(COLUMN_FORM_DATA,
80 form_data_pickle.data(),
81 form_data_pickle.size());
82 s->BindInt(COLUMN_USE_ADDITIONAL_AUTH, form.use_additional_authentication);
83 }
84
85 void AddCallback(int err, sql::Statement* /*stmt*/) {
86 if (err == 19 /*SQLITE_CONSTRAINT*/)
87 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form";
88 }
89
52 } // namespace 90 } // namespace
53 91
54 LoginDatabase::LoginDatabase() { 92 LoginDatabase::LoginDatabase() {
55 } 93 }
56 94
57 LoginDatabase::~LoginDatabase() { 95 LoginDatabase::~LoginDatabase() {
58 } 96 }
59 97
60 bool LoginDatabase::Init(const base::FilePath& db_path) { 98 bool LoginDatabase::Init(const base::FilePath& db_path) {
61 // Set pragmas for a small, private database (based on WebDatabase). 99 // Set pragmas for a small, private database (based on WebDatabase).
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 "PasswordManager.TimesGeneratedPasswordUsed", 269 "PasswordManager.TimesGeneratedPasswordUsed",
232 usage_statement.ColumnInt(1), 0, 100, 10); 270 usage_statement.ColumnInt(1), 0, 100, 10);
233 } else { 271 } else {
234 UMA_HISTOGRAM_CUSTOM_COUNTS( 272 UMA_HISTOGRAM_CUSTOM_COUNTS(
235 "PasswordManager.TimesPasswordUsed", 273 "PasswordManager.TimesPasswordUsed",
236 usage_statement.ColumnInt(1), 0, 100, 10); 274 usage_statement.ColumnInt(1), 0, 100, 10);
237 } 275 }
238 } 276 }
239 } 277 }
240 278
241 bool LoginDatabase::AddLogin(const PasswordForm& form) { 279 PasswordStoreChangeList LoginDatabase::AddLogin(const PasswordForm& form) {
280 PasswordStoreChangeList list;
242 std::string encrypted_password; 281 std::string encrypted_password;
243 if (EncryptedString(form.password_value, &encrypted_password) != 282 if (EncryptedString(form.password_value, &encrypted_password) !=
244 ENCRYPTION_RESULT_SUCCESS) 283 ENCRYPTION_RESULT_SUCCESS)
245 return false; 284 return list;
246 285
247 // You *must* change LoginTableColumns if this query changes. 286 // You *must* change LoginTableColumns if this query changes.
248 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, 287 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
288 "INSERT INTO logins "
289 "(origin_url, action_url, username_element, username_value, "
290 " password_element, password_value, submit_element, "
291 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
292 " scheme, password_type, possible_usernames, times_used, form_data, "
293 " use_additional_auth) VALUES "
294 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
295 BindAddStatement(form, encrypted_password, &s);
296 db_.set_error_callback(base::Bind(&AddCallback));
297 const bool success = s.Run();
298 db_.reset_error_callback();
299 if (success) {
300 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
301 return list;
302 }
303 // Repeat the same statement but with REPLACE semantic.
304 s.Assign(db_.GetCachedStatement(SQL_FROM_HERE,
249 "INSERT OR REPLACE INTO logins " 305 "INSERT OR REPLACE INTO logins "
250 "(origin_url, action_url, username_element, username_value, " 306 "(origin_url, action_url, username_element, username_value, "
251 " password_element, password_value, submit_element, " 307 " password_element, password_value, submit_element, "
252 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 308 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
253 " scheme, password_type, possible_usernames, times_used, form_data, " 309 " scheme, password_type, possible_usernames, times_used, form_data, "
254 " use_additional_auth) VALUES " 310 " use_additional_auth) VALUES "
255 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); 311 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
256 s.BindString(COLUMN_ORIGIN_URL, form.origin.spec()); 312 BindAddStatement(form, encrypted_password, &s);
257 s.BindString(COLUMN_ACTION_URL, form.action.spec()); 313 if (s.Run()) {
258 s.BindString16(COLUMN_USERNAME_ELEMENT, form.username_element); 314 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
259 s.BindString16(COLUMN_USERNAME_VALUE, form.username_value); 315 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
260 s.BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element); 316 }
261 s.BindBlob(COLUMN_PASSWORD_VALUE, encrypted_password.data(), 317 return list;
262 static_cast<int>(encrypted_password.length()));
263 s.BindString16(COLUMN_SUBMIT_ELEMENT, form.submit_element);
264 s.BindString(COLUMN_SIGNON_REALM, form.signon_realm);
265 s.BindInt(COLUMN_SSL_VALID, form.ssl_valid);
266 s.BindInt(COLUMN_PREFERRED, form.preferred);
267 s.BindInt64(COLUMN_DATE_CREATED, form.date_created.ToTimeT());
268 s.BindInt(COLUMN_BLACKLISTED_BY_USER, form.blacklisted_by_user);
269 s.BindInt(COLUMN_SCHEME, form.scheme);
270 s.BindInt(COLUMN_PASSWORD_TYPE, form.type);
271 Pickle usernames_pickle = SerializeVector(form.other_possible_usernames);
272 s.BindBlob(COLUMN_POSSIBLE_USERNAMES,
273 usernames_pickle.data(),
274 usernames_pickle.size());
275 s.BindInt(COLUMN_TIMES_USED, form.times_used);
276 Pickle form_data_pickle;
277 autofill::SerializeFormData(form.form_data, &form_data_pickle);
278 s.BindBlob(COLUMN_FORM_DATA,
279 form_data_pickle.data(),
280 form_data_pickle.size());
281 s.BindInt(COLUMN_USE_ADDITIONAL_AUTH, form.use_additional_authentication);
282
283 return s.Run();
284 } 318 }
285 319
286 bool LoginDatabase::UpdateLogin(const PasswordForm& form, int* items_changed) { 320 bool LoginDatabase::UpdateLogin(const PasswordForm& form, int* items_changed) {
287 std::string encrypted_password; 321 std::string encrypted_password;
288 if (EncryptedString(form.password_value, &encrypted_password) != 322 if (EncryptedString(form.password_value, &encrypted_password) !=
289 ENCRYPTION_RESULT_SUCCESS) 323 ENCRYPTION_RESULT_SUCCESS)
290 return false; 324 return false;
291 325
292 // Replacement is necessary to deal with updating imported credentials. See 326 // Replacement is necessary to deal with updating imported credentials. See
293 // crbug.com/349138 for details. 327 // crbug.com/349138 for details.
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 } 612 }
579 613
580 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { 614 bool LoginDatabase::DeleteAndRecreateDatabaseFile() {
581 DCHECK(db_.is_open()); 615 DCHECK(db_.is_open());
582 meta_table_.Reset(); 616 meta_table_.Reset();
583 db_.Close(); 617 db_.Close();
584 sql::Connection::Delete(db_path_); 618 sql::Connection::Delete(db_path_);
585 return Init(db_path_); 619 return Init(db_path_);
586 } 620 }
587 621
588 Pickle LoginDatabase::SerializeVector( 622 // static
589 const std::vector<base::string16>& vec) const { 623 Pickle LoginDatabase::SerializeVector(const std::vector<base::string16>& vec) {
590 Pickle p; 624 Pickle p;
591 for (size_t i = 0; i < vec.size(); ++i) { 625 for (size_t i = 0; i < vec.size(); ++i) {
592 p.WriteString16(vec[i]); 626 p.WriteString16(vec[i]);
593 } 627 }
594 return p; 628 return p;
595 } 629 }
596 630
597 std::vector<base::string16> LoginDatabase::DeserializeVector( 631 // static
598 const Pickle& p) const { 632 std::vector<base::string16> LoginDatabase::DeserializeVector(const Pickle& p) {
599 std::vector<base::string16> ret; 633 std::vector<base::string16> ret;
600 base::string16 str; 634 base::string16 str;
601 635
602 PickleIterator iterator(p); 636 PickleIterator iterator(p);
603 while (iterator.ReadString16(&str)) { 637 while (iterator.ReadString16(&str)) {
604 ret.push_back(str); 638 ret.push_back(str);
605 } 639 }
606 return ret; 640 return ret;
607 } 641 }
608 642
609 } // namespace password_manager 643 } // namespace password_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698