19ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
29ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
39ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// found in the LICENSE file.
49ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/chromeos/policy/cloud_external_data_store.h"
69ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include <set>
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/logging.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/sequenced_task_runner.h"
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/strings/string_number_conversions.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/resource_cache.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/sha2.h"
149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochnamespace policy {
169ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochnamespace {
189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
199ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Encodes (policy, hash) into a single string.
209ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochstd::string GetSubkey(const std::string& policy, const std::string& hash) {
219ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  DCHECK(!policy.empty());
229ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  DCHECK(!hash.empty());
239ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  return base::IntToString(policy.size()) + ":" +
249ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch         base::IntToString(hash.size()) + ":" +
259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch         policy + hash;
269ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
279ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
289ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}  // namespace
299ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)CloudExternalDataStore::CloudExternalDataStore(
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const std::string& cache_key,
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> task_runner,
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceCache* cache)
349ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    : cache_key_(cache_key),
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      task_runner_(task_runner),
369ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      cache_(cache) {
379ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
389ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
399ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben MurdochCloudExternalDataStore::~CloudExternalDataStore() {
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
429ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochvoid CloudExternalDataStore::Prune(
449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    const CloudExternalDataManager::Metadata& metadata) {
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
469ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  std::set<std::string> subkeys_to_keep;
479ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  for (CloudExternalDataManager::Metadata::const_iterator it = metadata.begin();
489ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch       it != metadata.end(); ++it) {
499ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    subkeys_to_keep.insert(GetSubkey(it->first, it->second.hash));
509ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  }
519ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  cache_->PurgeOtherSubkeys(cache_key_, subkeys_to_keep);
529ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
539ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
549ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochbool CloudExternalDataStore::Store(const std::string& policy,
559ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                   const std::string& hash,
569ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                   const std::string& data) {
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
589ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  return cache_->Store(cache_key_, GetSubkey(policy, hash), data);
599ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
609ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
619ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochbool CloudExternalDataStore::Load(const std::string& policy,
629ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                  const std::string& hash,
639ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                  size_t max_size,
649ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                  std::string* data) {
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
669ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  const std::string subkey = GetSubkey(policy, hash);
679ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  if (cache_->Load(cache_key_, subkey, data)) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (data->size() <= max_size && crypto::SHA256HashString(*data) == hash)
699ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      return true;
709ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    // If the data is larger than allowed or does not match the expected hash,
719ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    // delete the entry.
729ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    cache_->Delete(cache_key_, subkey);
739ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    data->clear();
749ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  }
759ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  return false;
769ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
779ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
789ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}  // namespace policy
79