• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetKey()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 
FromWebDatabase(WebDatabase * db)26 TokenServiceTable* TokenServiceTable::FromWebDatabase(WebDatabase* db) {
27   return static_cast<TokenServiceTable*>(db->GetTable(GetKey()));
28 
29 }
30 
GetTypeKey() const31 WebDatabaseTable::TypeKey TokenServiceTable::GetTypeKey() const {
32   return GetKey();
33 }
34 
CreateTablesIfNecessary()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 
IsSyncable()47 bool TokenServiceTable::IsSyncable() {
48   return true;
49 }
50 
MigrateToVersion(int version,bool * update_compatible_version)51 bool TokenServiceTable::MigrateToVersion(int version,
52                                          bool* update_compatible_version) {
53   return true;
54 }
55 
RemoveAllTokens()56 bool TokenServiceTable::RemoveAllTokens() {
57   sql::Statement s(db_->GetUniqueStatement(
58       "DELETE FROM token_service"));
59 
60   return s.Run();
61 }
62 
RemoveTokenForService(const std::string & service)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 
SetTokenForService(const std::string & service,const std::string & token)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 
GetAllTokens(std::map<std::string,std::string> * tokens)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