Home | History | Annotate | Download | only in webdata
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/webdata/token_service_table.h"
      6 
      7 #include <map>
      8 #include <string>
      9 
     10 #include "base/logging.h"
     11 #include "components/webdata/common/web_database.h"
     12 #include "components/webdata/encryptor/encryptor.h"
     13 #include "sql/statement.h"
     14 
     15 namespace {
     16 
     17 WebDatabaseTable::TypeKey GetKey() {
     18   // We just need a unique constant. Use the address of a static that
     19   // COMDAT folding won't touch in an optimizing linker.
     20   static int table_key = 0;
     21   return reinterpret_cast<void*>(&table_key);
     22 }
     23 
     24 }  // namespace
     25 
     26 TokenServiceTable* TokenServiceTable::FromWebDatabase(WebDatabase* db) {
     27   return static_cast<TokenServiceTable*>(db->GetTable(GetKey()));
     28 
     29 }
     30 
     31 WebDatabaseTable::TypeKey TokenServiceTable::GetTypeKey() const {
     32   return GetKey();
     33 }
     34 
     35 bool TokenServiceTable::Init(sql::Connection* db, sql::MetaTable* meta_table) {
     36   WebDatabaseTable::Init(db, meta_table);
     37   if (!db_->DoesTableExist("token_service")) {
     38     if (!db_->Execute("CREATE TABLE token_service ("
     39                       "service VARCHAR PRIMARY KEY NOT NULL,"
     40                       "encrypted_token BLOB)")) {
     41       NOTREACHED();
     42       return false;
     43     }
     44   }
     45   return true;
     46 }
     47 
     48 bool TokenServiceTable::IsSyncable() {
     49   return true;
     50 }
     51 
     52 bool TokenServiceTable::MigrateToVersion(int version,
     53                                          bool* update_compatible_version) {
     54   return true;
     55 }
     56 
     57 bool TokenServiceTable::RemoveAllTokens() {
     58   sql::Statement s(db_->GetUniqueStatement(
     59       "DELETE FROM token_service"));
     60 
     61   return s.Run();
     62 }
     63 
     64 bool TokenServiceTable::RemoveTokenForService(const std::string& service) {
     65   sql::Statement s(db_->GetUniqueStatement(
     66       "DELETE FROM token_service WHERE service = ?"));
     67   s.BindString(0, service);
     68 
     69   return s.Run();
     70 }
     71 
     72 bool TokenServiceTable::SetTokenForService(const std::string& service,
     73                                            const std::string& token) {
     74   std::string encrypted_token;
     75   bool encrypted = Encryptor::EncryptString(token, &encrypted_token);
     76   if (!encrypted) {
     77     return false;
     78   }
     79 
     80   // Don't bother with a cached statement since this will be a relatively
     81   // infrequent operation.
     82   sql::Statement s(db_->GetUniqueStatement(
     83       "INSERT OR REPLACE INTO token_service "
     84       "(service, encrypted_token) VALUES (?, ?)"));
     85   s.BindString(0, service);
     86   s.BindBlob(1, encrypted_token.data(),
     87              static_cast<int>(encrypted_token.length()));
     88 
     89   return s.Run();
     90 }
     91 
     92 bool TokenServiceTable::GetAllTokens(
     93     std::map<std::string, std::string>* tokens) {
     94   sql::Statement s(db_->GetUniqueStatement(
     95       "SELECT service, encrypted_token FROM token_service"));
     96 
     97   if (!s.is_valid())
     98     return false;
     99 
    100   while (s.Step()) {
    101     std::string encrypted_token;
    102     std::string decrypted_token;
    103     std::string service;
    104     service = s.ColumnString(0);
    105     bool entry_ok = !service.empty() &&
    106                     s.ColumnBlobAsString(1, &encrypted_token);
    107     if (entry_ok) {
    108       Encryptor::DecryptString(encrypted_token, &decrypted_token);
    109       (*tokens)[service] = decrypted_token;
    110     } else {
    111       NOTREACHED();
    112       return false;
    113     }
    114   }
    115   return true;
    116 }
    117