blob: 0915f3bbe8f8f524e2201efe496a701d745d2db8 [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/webdata/token_service_table.h"
#include <map>
#include <string>
#include "base/logging.h"
#include "components/webdata/common/web_database.h"
#include "components/webdata/encryptor/encryptor.h"
#include "sql/statement.h"
namespace {
WebDatabaseTable::TypeKey GetKey() {
// We just need a unique constant. Use the address of a static that
// COMDAT folding won't touch in an optimizing linker.
static int table_key = 0;
return reinterpret_cast<void*>(&table_key);
}
} // namespace
TokenServiceTable* TokenServiceTable::FromWebDatabase(WebDatabase* db) {
return static_cast<TokenServiceTable*>(db->GetTable(GetKey()));
}
WebDatabaseTable::TypeKey TokenServiceTable::GetTypeKey() const {
return GetKey();
}
bool TokenServiceTable::Init(sql::Connection* db, sql::MetaTable* meta_table) {
WebDatabaseTable::Init(db, meta_table);
if (!db_->DoesTableExist("token_service")) {
if (!db_->Execute("CREATE TABLE token_service ("
"service VARCHAR PRIMARY KEY NOT NULL,"
"encrypted_token BLOB)")) {
NOTREACHED();
return false;
}
}
return true;
}
bool TokenServiceTable::IsSyncable() {
return true;
}
bool TokenServiceTable::MigrateToVersion(int version,
bool* update_compatible_version) {
return true;
}
bool TokenServiceTable::RemoveAllTokens() {
sql::Statement s(db_->GetUniqueStatement(
"DELETE FROM token_service"));
return s.Run();
}
bool TokenServiceTable::RemoveTokenForService(const std::string& service) {
sql::Statement s(db_->GetUniqueStatement(
"DELETE FROM token_service WHERE service = ?"));
s.BindString(0, service);
return s.Run();
}
bool TokenServiceTable::SetTokenForService(const std::string& service,
const std::string& token) {
std::string encrypted_token;
bool encrypted = Encryptor::EncryptString(token, &encrypted_token);
if (!encrypted) {
return false;
}
// Don't bother with a cached statement since this will be a relatively
// infrequent operation.
sql::Statement s(db_->GetUniqueStatement(
"INSERT OR REPLACE INTO token_service "
"(service, encrypted_token) VALUES (?, ?)"));
s.BindString(0, service);
s.BindBlob(1, encrypted_token.data(),
static_cast<int>(encrypted_token.length()));
return s.Run();
}
bool TokenServiceTable::GetAllTokens(
std::map<std::string, std::string>* tokens) {
sql::Statement s(db_->GetUniqueStatement(
"SELECT service, encrypted_token FROM token_service"));
if (!s.is_valid())
return false;
while (s.Step()) {
std::string encrypted_token;
std::string decrypted_token;
std::string service;
service = s.ColumnString(0);
bool entry_ok = !service.empty() &&
s.ColumnBlobAsString(1, &encrypted_token);
if (entry_ok) {
Encryptor::DecryptString(encrypted_token, &decrypted_token);
(*tokens)[service] = decrypted_token;
} else {
NOTREACHED();
return false;
}
}
return true;
}