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 "app/sql/statement.h"
11#include "base/logging.h"
12#include "chrome/browser/password_manager/encryptor.h"
13
14bool TokenServiceTable::Init() {
15  if (!db_->DoesTableExist("token_service")) {
16    if (!db_->Execute("CREATE TABLE token_service ("
17                      "service VARCHAR PRIMARY KEY NOT NULL,"
18                      "encrypted_token BLOB)")) {
19      NOTREACHED();
20      return false;
21    }
22  }
23  return true;
24}
25
26bool TokenServiceTable::IsSyncable() {
27  return true;
28}
29
30bool TokenServiceTable::RemoveAllTokens() {
31  sql::Statement s(db_->GetUniqueStatement(
32      "DELETE FROM token_service"));
33  if (!s) {
34    NOTREACHED() << "Statement prepare failed";
35    return false;
36  }
37
38  return s.Run();
39}
40
41bool TokenServiceTable::SetTokenForService(const std::string& service,
42                                           const std::string& token) {
43  // Don't bother with a cached statement since this will be a relatively
44  // infrequent operation.
45  sql::Statement s(db_->GetUniqueStatement(
46      "INSERT OR REPLACE INTO token_service "
47      "(service, encrypted_token) VALUES (?, ?)"));
48  if (!s) {
49    NOTREACHED() << "Statement prepare failed";
50    return false;
51  }
52
53  std::string encrypted_token;
54
55  bool encrypted = Encryptor::EncryptString(token, &encrypted_token);
56  if (!encrypted) {
57    return false;
58  }
59
60  s.BindString(0, service);
61  s.BindBlob(1, encrypted_token.data(),
62             static_cast<int>(encrypted_token.length()));
63  return s.Run();
64}
65
66bool TokenServiceTable::GetAllTokens(
67    std::map<std::string, std::string>* tokens) {
68  sql::Statement s(db_->GetUniqueStatement(
69      "SELECT service, encrypted_token FROM token_service"));
70  if (!s) {
71    NOTREACHED() << "Statement prepare failed";
72    return false;
73  }
74
75  while (s.Step()) {
76    std::string encrypted_token;
77    std::string decrypted_token;
78    std::string service;
79    service = s.ColumnString(0);
80    bool entry_ok = !service.empty() &&
81                    s.ColumnBlobAsString(1, &encrypted_token);
82    if (entry_ok) {
83      Encryptor::DecryptString(encrypted_token, &decrypted_token);
84      (*tokens)[service] = decrypted_token;
85    } else {
86      NOTREACHED();
87      return false;
88    }
89  }
90  return true;
91}
92
93