1// Copyright 2013 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/chromeos/policy/cloud_external_data_store.h"
6
7#include <set>
8
9#include "base/logging.h"
10#include "base/sequenced_task_runner.h"
11#include "base/strings/string_number_conversions.h"
12#include "components/policy/core/common/cloud/resource_cache.h"
13#include "crypto/sha2.h"
14
15namespace policy {
16
17namespace {
18
19// Encodes (policy, hash) into a single string.
20std::string GetSubkey(const std::string& policy, const std::string& hash) {
21  DCHECK(!policy.empty());
22  DCHECK(!hash.empty());
23  return base::IntToString(policy.size()) + ":" +
24         base::IntToString(hash.size()) + ":" +
25         policy + hash;
26}
27
28}  // namespace
29
30CloudExternalDataStore::CloudExternalDataStore(
31    const std::string& cache_key,
32    scoped_refptr<base::SequencedTaskRunner> task_runner,
33    ResourceCache* cache)
34    : cache_key_(cache_key),
35      task_runner_(task_runner),
36      cache_(cache) {
37}
38
39CloudExternalDataStore::~CloudExternalDataStore() {
40  DCHECK(task_runner_->RunsTasksOnCurrentThread());
41}
42
43void CloudExternalDataStore::Prune(
44    const CloudExternalDataManager::Metadata& metadata) {
45  DCHECK(task_runner_->RunsTasksOnCurrentThread());
46  std::set<std::string> subkeys_to_keep;
47  for (CloudExternalDataManager::Metadata::const_iterator it = metadata.begin();
48       it != metadata.end(); ++it) {
49    subkeys_to_keep.insert(GetSubkey(it->first, it->second.hash));
50  }
51  cache_->PurgeOtherSubkeys(cache_key_, subkeys_to_keep);
52}
53
54bool CloudExternalDataStore::Store(const std::string& policy,
55                                   const std::string& hash,
56                                   const std::string& data) {
57  DCHECK(task_runner_->RunsTasksOnCurrentThread());
58  return cache_->Store(cache_key_, GetSubkey(policy, hash), data);
59}
60
61bool CloudExternalDataStore::Load(const std::string& policy,
62                                  const std::string& hash,
63                                  size_t max_size,
64                                  std::string* data) {
65  DCHECK(task_runner_->RunsTasksOnCurrentThread());
66  const std::string subkey = GetSubkey(policy, hash);
67  if (cache_->Load(cache_key_, subkey, data)) {
68    if (data->size() <= max_size && crypto::SHA256HashString(*data) == hash)
69      return true;
70    // If the data is larger than allowed or does not match the expected hash,
71    // delete the entry.
72    cache_->Delete(cache_key_, subkey);
73    data->clear();
74  }
75  return false;
76}
77
78}  // namespace policy
79