Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/webdata/logins_table.h" | 5 #include "chrome/browser/webdata/logins_table.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <string> | |
| 9 | 8 |
| 10 #include "base/logging.h" | 9 #include "base/logging.h" |
| 11 #include "chrome/browser/password_manager/encryptor.h" | |
| 12 #include "sql/statement.h" | 10 #include "sql/statement.h" |
| 13 #include "webkit/forms/password_form.h" | |
| 14 | |
| 15 using webkit::forms::PasswordForm; | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 void InitPasswordFormFromStatement(PasswordForm* form, sql::Statement* s) { | |
| 20 std::string tmp; | |
| 21 string16 decrypted_password; | |
| 22 tmp = s->ColumnString(0); | |
| 23 form->origin = GURL(tmp); | |
| 24 tmp = s->ColumnString(1); | |
| 25 form->action = GURL(tmp); | |
| 26 form->username_element = s->ColumnString16(2); | |
| 27 form->username_value = s->ColumnString16(3); | |
| 28 form->password_element = s->ColumnString16(4); | |
| 29 | |
| 30 int encrypted_password_len = s->ColumnByteLength(5); | |
| 31 std::string encrypted_password; | |
| 32 if (encrypted_password_len) { | |
| 33 encrypted_password.resize(encrypted_password_len); | |
| 34 memcpy(&encrypted_password[0], s->ColumnBlob(5), encrypted_password_len); | |
| 35 Encryptor::DecryptString16(encrypted_password, &decrypted_password); | |
| 36 } | |
| 37 | |
| 38 form->password_value = decrypted_password; | |
| 39 form->submit_element = s->ColumnString16(6); | |
| 40 tmp = s->ColumnString(7); | |
| 41 form->signon_realm = tmp; | |
| 42 form->ssl_valid = (s->ColumnInt(8) > 0); | |
| 43 form->preferred = (s->ColumnInt(9) > 0); | |
| 44 form->date_created = base::Time::FromTimeT(s->ColumnInt64(10)); | |
| 45 form->blacklisted_by_user = (s->ColumnInt(11) > 0); | |
| 46 int scheme_int = s->ColumnInt(12); | |
| 47 DCHECK((scheme_int >= 0) && (scheme_int <= PasswordForm::SCHEME_OTHER)); | |
| 48 form->scheme = static_cast<PasswordForm::Scheme>(scheme_int); | |
| 49 } | |
| 50 | |
| 51 } // anonymous namespace | |
| 52 | 11 |
| 53 bool LoginsTable::Init() { | 12 bool LoginsTable::Init() { |
| 54 if (!db_->DoesTableExist("logins")) { | 13 if (db_->DoesTableExist("logins")) { |
| 55 if (!db_->Execute("CREATE TABLE logins (" | 14 if (!db_->Execute("DROP TABLE logins")) { |
| 56 "origin_url VARCHAR NOT NULL, " | |
| 57 "action_url VARCHAR, " | |
| 58 "username_element VARCHAR, " | |
| 59 "username_value VARCHAR, " | |
| 60 "password_element VARCHAR, " | |
| 61 "password_value BLOB, " | |
| 62 "submit_element VARCHAR, " | |
| 63 "signon_realm VARCHAR NOT NULL," | |
| 64 "ssl_valid INTEGER NOT NULL," | |
| 65 "preferred INTEGER NOT NULL," | |
| 66 "date_created INTEGER NOT NULL," | |
| 67 "blacklisted_by_user INTEGER NOT NULL," | |
| 68 "scheme INTEGER NOT NULL," | |
| 69 "UNIQUE " | |
| 70 "(origin_url, username_element, " | |
| 71 "username_value, password_element, " | |
| 72 "submit_element, signon_realm))")) { | |
| 73 NOTREACHED(); | |
| 74 return false; | |
| 75 } | |
| 76 if (!db_->Execute("CREATE INDEX logins_signon ON logins (signon_realm)")) { | |
| 77 NOTREACHED(); | 15 NOTREACHED(); |
| 78 return false; | 16 return false; |
|
stuartmorgan
2012/04/26 08:06:13
Remove this; there's no reason to fail init if we
Mike Mammarella
2012/04/26 18:07:33
Done.
| |
| 79 } | 17 } |
| 80 } | 18 } |
| 81 | 19 |
| 82 #if defined(OS_WIN) | 20 #if defined(OS_WIN) |
| 83 if (!db_->DoesTableExist("ie7_logins")) { | 21 if (!db_->DoesTableExist("ie7_logins")) { |
| 84 if (!db_->Execute("CREATE TABLE ie7_logins (" | 22 if (!db_->Execute("CREATE TABLE ie7_logins (" |
| 85 "url_hash VARCHAR NOT NULL, " | 23 "url_hash VARCHAR NOT NULL, " |
| 86 "password_value BLOB, " | 24 "password_value BLOB, " |
| 87 "date_created INTEGER NOT NULL," | 25 "date_created INTEGER NOT NULL," |
| 88 "UNIQUE " | 26 "UNIQUE " |
| 89 "(url_hash))")) { | 27 "(url_hash))")) { |
| 90 NOTREACHED(); | 28 NOTREACHED(); |
| 91 return false; | 29 return false; |
| 92 } | 30 } |
| 93 if (!db_->Execute("CREATE INDEX ie7_logins_hash ON " | 31 if (!db_->Execute("CREATE INDEX ie7_logins_hash ON " |
| 94 "ie7_logins (url_hash)")) { | 32 "ie7_logins (url_hash)")) { |
| 95 NOTREACHED(); | 33 NOTREACHED(); |
| 96 return false; | 34 return false; |
| 97 } | 35 } |
| 98 } | 36 } |
| 99 #endif | 37 #endif |
| 100 | 38 |
| 101 return true; | 39 return true; |
| 102 } | 40 } |
| 103 | 41 |
| 104 bool LoginsTable::IsSyncable() { | 42 bool LoginsTable::IsSyncable() { |
| 105 return true; | 43 return true; |
| 106 } | 44 } |
| 107 | |
| 108 bool LoginsTable::AddLogin(const PasswordForm& form) { | |
| 109 sql::Statement s(db_->GetUniqueStatement( | |
| 110 "INSERT OR REPLACE INTO logins " | |
| 111 "(origin_url, action_url, username_element, username_value, " | |
| 112 " password_element, password_value, submit_element, " | |
| 113 " signon_realm, ssl_valid, preferred, date_created, " | |
| 114 " blacklisted_by_user, scheme) " | |
| 115 "VALUES " | |
| 116 "(?,?,?,?,?,?,?,?,?,?,?,?,?)")); | |
| 117 | |
| 118 std::string encrypted_password; | |
| 119 s.BindString(0, form.origin.spec()); | |
| 120 s.BindString(1, form.action.spec()); | |
| 121 s.BindString16(2, form.username_element); | |
| 122 s.BindString16(3, form.username_value); | |
| 123 s.BindString16(4, form.password_element); | |
| 124 Encryptor::EncryptString16(form.password_value, &encrypted_password); | |
| 125 s.BindBlob(5, encrypted_password.data(), | |
| 126 static_cast<int>(encrypted_password.length())); | |
| 127 s.BindString16(6, form.submit_element); | |
| 128 s.BindString(7, form.signon_realm); | |
| 129 s.BindInt(8, form.ssl_valid); | |
| 130 s.BindInt(9, form.preferred); | |
| 131 s.BindInt64(10, form.date_created.ToTimeT()); | |
| 132 s.BindInt(11, form.blacklisted_by_user); | |
| 133 s.BindInt(12, form.scheme); | |
| 134 | |
| 135 return s.Run(); | |
| 136 } | |
| 137 | |
| 138 bool LoginsTable::UpdateLogin(const PasswordForm& form) { | |
| 139 sql::Statement s(db_->GetUniqueStatement( | |
| 140 "UPDATE logins SET " | |
| 141 "action_url = ?, " | |
| 142 "password_value = ?, " | |
| 143 "ssl_valid = ?, " | |
| 144 "preferred = ? " | |
| 145 "WHERE origin_url = ? AND " | |
| 146 "username_element = ? AND " | |
| 147 "username_value = ? AND " | |
| 148 "password_element = ? AND " | |
| 149 "signon_realm = ?")); | |
| 150 | |
| 151 s.BindString(0, form.action.spec()); | |
| 152 std::string encrypted_password; | |
| 153 Encryptor::EncryptString16(form.password_value, &encrypted_password); | |
| 154 s.BindBlob(1, encrypted_password.data(), | |
| 155 static_cast<int>(encrypted_password.length())); | |
| 156 s.BindInt(2, form.ssl_valid); | |
| 157 s.BindInt(3, form.preferred); | |
| 158 s.BindString(4, form.origin.spec()); | |
| 159 s.BindString16(5, form.username_element); | |
| 160 s.BindString16(6, form.username_value); | |
| 161 s.BindString16(7, form.password_element); | |
| 162 s.BindString(8, form.signon_realm); | |
| 163 | |
| 164 return s.Run(); | |
| 165 } | |
| 166 | |
| 167 bool LoginsTable::RemoveLogin(const PasswordForm& form) { | |
| 168 // Remove a login by UNIQUE-constrained fields. | |
| 169 sql::Statement s(db_->GetUniqueStatement( | |
| 170 "DELETE FROM logins WHERE " | |
| 171 "origin_url = ? AND " | |
| 172 "username_element = ? AND " | |
| 173 "username_value = ? AND " | |
| 174 "password_element = ? AND " | |
| 175 "submit_element = ? AND " | |
| 176 "signon_realm = ?")); | |
| 177 s.BindString(0, form.origin.spec()); | |
| 178 s.BindString16(1, form.username_element); | |
| 179 s.BindString16(2, form.username_value); | |
| 180 s.BindString16(3, form.password_element); | |
| 181 s.BindString16(4, form.submit_element); | |
| 182 s.BindString(5, form.signon_realm); | |
| 183 | |
| 184 return s.Run(); | |
| 185 } | |
| 186 | |
| 187 bool LoginsTable::RemoveLoginsCreatedBetween(base::Time delete_begin, | |
| 188 base::Time delete_end) { | |
| 189 sql::Statement s1(db_->GetUniqueStatement( | |
| 190 "DELETE FROM logins WHERE " | |
| 191 "date_created >= ? AND date_created < ?")); | |
| 192 s1.BindInt64(0, delete_begin.ToTimeT()); | |
| 193 s1.BindInt64(1, | |
| 194 delete_end.is_null() ? | |
| 195 std::numeric_limits<int64>::max() : | |
| 196 delete_end.ToTimeT()); | |
| 197 bool success = s1.Run(); | |
| 198 | |
| 199 #if defined(OS_WIN) | |
| 200 sql::Statement s2(db_->GetUniqueStatement( | |
| 201 "DELETE FROM ie7_logins WHERE date_created >= ? AND date_created < ?")); | |
| 202 s2.BindInt64(0, delete_begin.ToTimeT()); | |
| 203 s2.BindInt64(1, | |
| 204 delete_end.is_null() ? | |
| 205 std::numeric_limits<int64>::max() : | |
| 206 delete_end.ToTimeT()); | |
| 207 success = success && s2.Run(); | |
| 208 #endif | |
| 209 | |
| 210 return success; | |
| 211 } | |
| 212 | |
| 213 bool LoginsTable::GetLogins(const PasswordForm& form, | |
| 214 std::vector<PasswordForm*>* forms) { | |
| 215 DCHECK(forms); | |
| 216 sql::Statement s(db_->GetUniqueStatement( | |
| 217 "SELECT origin_url, action_url, " | |
| 218 "username_element, username_value, " | |
| 219 "password_element, password_value, " | |
| 220 "submit_element, signon_realm, " | |
| 221 "ssl_valid, preferred, " | |
| 222 "date_created, blacklisted_by_user, scheme FROM logins " | |
| 223 "WHERE signon_realm == ?")); | |
| 224 s.BindString(0, form.signon_realm); | |
| 225 | |
| 226 while (s.Step()) { | |
| 227 PasswordForm* new_form = new PasswordForm(); | |
| 228 InitPasswordFormFromStatement(new_form, &s); | |
| 229 | |
| 230 forms->push_back(new_form); | |
| 231 } | |
| 232 return s.Succeeded(); | |
| 233 } | |
| 234 | |
| 235 bool LoginsTable::GetAllLogins(std::vector<PasswordForm*>* forms, | |
| 236 bool include_blacklisted) { | |
| 237 DCHECK(forms); | |
| 238 std::string stmt = "SELECT origin_url, action_url, " | |
| 239 "username_element, username_value, " | |
| 240 "password_element, password_value, " | |
| 241 "submit_element, signon_realm, ssl_valid, preferred, " | |
| 242 "date_created, blacklisted_by_user, scheme FROM logins "; | |
| 243 if (!include_blacklisted) | |
| 244 stmt.append("WHERE blacklisted_by_user == 0 "); | |
| 245 stmt.append("ORDER BY origin_url"); | |
| 246 | |
| 247 sql::Statement s(db_->GetUniqueStatement(stmt.c_str())); | |
| 248 | |
| 249 while (s.Step()) { | |
| 250 PasswordForm* new_form = new PasswordForm(); | |
| 251 InitPasswordFormFromStatement(new_form, &s); | |
| 252 | |
| 253 forms->push_back(new_form); | |
| 254 } | |
| 255 return s.Succeeded(); | |
| 256 } | |
| OLD | NEW |