Home | History | Annotate | Download | only in webdata
      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
      3 // found in the LICENSE file.
      4 
      5 #include "components/signin/core/browser/webdata/token_service_table.h"
      6 
      7 #include <map>
      8 #include <string>
      9 
     10 #include "base/logging.h"
     11 #include "components/os_crypt/os_crypt.h"
     12 #include "components/webdata/common/web_database.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::CreateTablesIfNecessary() {
     36   if (!db_->DoesTableExist("token_service")) {
     37     if (!db_->Execute("CREATE TABLE token_service ("
     38                       "service VARCHAR PRIMARY KEY NOT NULL,"
     39                       "encrypted_token BLOB)")) {
     40       NOTREACHED();
     41       return false;
     42     }
     43   }
     44   return true;
     45 }
     46 
     47 bool TokenServiceTable::IsSyncable() {
     48   return true;
     49 }
     50 
     51 bool TokenServiceTable::MigrateToVersion(int version,
     52                                          bool* update_compatible_version) {
     53   return true;
     54 }
     55 
     56 bool TokenServiceTable::RemoveAllTokens() {
     57   sql::Statement s(db_->GetUniqueStatement(
     58       "DELETE FROM token_service"));
     59 
     60   return s.Run();
     61 }
     62 
     63 bool TokenServiceTable::RemoveTokenForService(const std::string& service) {
     64   sql::Statement s(db_->GetUniqueStatement(
     65       "DELETE FROM token_service WHERE service = ?"));
     66   s.BindString(0, service);
     67 
     68   return s.Run();
     69 }
     70 
     71 bool TokenServiceTable::SetTokenForService(const std::string& service,
     72                                            const std::string& token) {
     73   std::string encrypted_token;
     74   bool encrypted = OSCrypt::EncryptString(token, &encrypted_token);
     75   if (!encrypted) {
     76     return false;
     77   }
     78 
     79   // Don't bother with a cached statement since this will be a relatively
     80   // infrequent operation.
     81   sql::Statement s(db_->GetUniqueStatement(
     82       "INSERT OR REPLACE INTO token_service "
     83       "(service, encrypted_token) VALUES (?, ?)"));
     84   s.BindString(0, service);
     85   s.BindBlob(1, encrypted_token.data(),
     86              static_cast<int>(encrypted_token.length()));
     87 
     88   return s.Run();
     89 }
     90 
     91 bool TokenServiceTable::GetAllTokens(
     92     std::map<std::string, std::string>* tokens) {
     93   sql::Statement s(db_->GetUniqueStatement(
     94       "SELECT service, encrypted_token FROM token_service"));
     95 
     96   if (!s.is_valid())
     97     return false;
     98 
     99   while (s.Step()) {
    100     std::string encrypted_token;
    101     std::string decrypted_token;
    102     std::string service;
    103     service = s.ColumnString(0);
    104     bool entry_ok = !service.empty() &&
    105                     s.ColumnBlobAsString(1, &encrypted_token);
    106     if (entry_ok) {
    107       OSCrypt::DecryptString(encrypted_token, &decrypted_token);
    108       (*tokens)[service] = decrypted_token;
    109     } else {
    110       NOTREACHED();
    111       return false;
    112     }
    113   }
    114   return true;
    115 }
    116