Home | History | Annotate | Download | only in storage
      1 // Copyright (c) 2012 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/extensions/api/storage/policy_value_store.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/extensions/api/storage/settings_namespace.h"
     10 #include "chrome/browser/policy/policy_map.h"
     11 #include "chrome/browser/policy/policy_types.h"
     12 #include "chrome/browser/value_store/value_store_change.h"
     13 #include "content/public/browser/browser_thread.h"
     14 
     15 using content::BrowserThread;
     16 
     17 namespace extensions {
     18 
     19 namespace {
     20 
     21 const char kReadOnlyStoreErrorMessage[] = "This is a read-only store.";
     22 
     23 ValueStore::WriteResult WriteResultError() {
     24   return ValueStore::MakeWriteResult(kReadOnlyStoreErrorMessage);
     25 }
     26 
     27 }  // namespace
     28 
     29 PolicyValueStore::PolicyValueStore(
     30     const std::string& extension_id,
     31     const scoped_refptr<SettingsObserverList>& observers,
     32     scoped_ptr<ValueStore> delegate)
     33     : extension_id_(extension_id),
     34       observers_(observers),
     35       delegate_(delegate.Pass()) {}
     36 
     37 PolicyValueStore::~PolicyValueStore() {}
     38 
     39 void PolicyValueStore::SetCurrentPolicy(const policy::PolicyMap& policy,
     40                                         bool notify_if_changed) {
     41   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
     42   // Convert |policy| to a dictionary value. Only include mandatory policies
     43   // for now.
     44   base::DictionaryValue current_policy;
     45   for (policy::PolicyMap::const_iterator it = policy.begin();
     46        it != policy.end(); ++it) {
     47     if (it->second.level == policy::POLICY_LEVEL_MANDATORY) {
     48       current_policy.SetWithoutPathExpansion(
     49           it->first, it->second.value->DeepCopy());
     50     }
     51   }
     52 
     53   // Get the previous policies stored in the database.
     54   // TODO(joaodasilva): it'd be better to have a less expensive way of
     55   // determining which keys are currently stored, or of determining which keys
     56   // must be removed.
     57   base::DictionaryValue previous_policy;
     58   ValueStore::ReadResult read_result = delegate_->Get();
     59   if (read_result->HasError()) {
     60     LOG(WARNING) << "Failed to read managed settings for extension "
     61         << extension_id_ << ": " << read_result->error();
     62     // Leave |previous_policy| empty, so that events are generated for every
     63     // policy in |current_policy|.
     64   } else {
     65     read_result->settings()->Swap(&previous_policy);
     66   }
     67 
     68   // Now get two lists of changes: changes after setting the current policies,
     69   // and changes after removing old policies that aren't in |current_policy|
     70   // anymore.
     71   std::vector<std::string> removed_keys;
     72   for (base::DictionaryValue::Iterator it(previous_policy);
     73        !it.IsAtEnd(); it.Advance()) {
     74     if (!current_policy.HasKey(it.key()))
     75       removed_keys.push_back(it.key());
     76   }
     77 
     78   ValueStoreChangeList changes;
     79 
     80   WriteResult result = delegate_->Remove(removed_keys);
     81   if (!result->HasError()) {
     82     changes.insert(
     83         changes.end(), result->changes().begin(), result->changes().end());
     84   }
     85 
     86   // IGNORE_QUOTA because these settings aren't writable by the extension, and
     87   // are configured by the domain administrator.
     88   ValueStore::WriteOptions options = ValueStore::IGNORE_QUOTA;
     89   result = delegate_->Set(options, current_policy);
     90   if (!result->HasError()) {
     91     changes.insert(
     92         changes.end(), result->changes().begin(), result->changes().end());
     93   }
     94 
     95   if (!changes.empty() && notify_if_changed) {
     96     observers_->Notify(
     97         &SettingsObserver::OnSettingsChanged,
     98         extension_id_,
     99         settings_namespace::MANAGED,
    100         ValueStoreChange::ToJson(changes));
    101   }
    102 }
    103 
    104 void PolicyValueStore::DeleteStorage() {
    105   // This is called from our owner, indicating that storage for this extension
    106   // should be removed.
    107   delegate_->Clear();
    108 }
    109 
    110 size_t PolicyValueStore::GetBytesInUse(const std::string& key) {
    111   // LeveldbValueStore doesn't implement this; and the underlying database
    112   // isn't acccessible to the extension in any case; from the extension's
    113   // perspective this is a read-only store.
    114   return 0;
    115 }
    116 
    117 size_t PolicyValueStore::GetBytesInUse(const std::vector<std::string>& keys) {
    118   // See note above.
    119   return 0;
    120 }
    121 
    122 size_t PolicyValueStore::GetBytesInUse() {
    123   // See note above.
    124   return 0;
    125 }
    126 
    127 ValueStore::ReadResult PolicyValueStore::Get(const std::string& key) {
    128   return delegate_->Get(key);
    129 }
    130 
    131 ValueStore::ReadResult PolicyValueStore::Get(
    132     const std::vector<std::string>& keys) {
    133   return delegate_->Get(keys);
    134 }
    135 
    136 ValueStore::ReadResult PolicyValueStore::Get() {
    137   return delegate_->Get();
    138 }
    139 
    140 ValueStore::WriteResult PolicyValueStore::Set(
    141     WriteOptions options, const std::string& key, const base::Value& value) {
    142   return WriteResultError();
    143 }
    144 
    145 ValueStore::WriteResult PolicyValueStore::Set(
    146     WriteOptions options, const base::DictionaryValue& settings) {
    147   return WriteResultError();
    148 }
    149 
    150 ValueStore::WriteResult PolicyValueStore::Remove(const std::string& key) {
    151   return WriteResultError();
    152 }
    153 
    154 ValueStore::WriteResult PolicyValueStore::Remove(
    155     const std::vector<std::string>& keys) {
    156   return WriteResultError();
    157 }
    158 
    159 ValueStore::WriteResult PolicyValueStore::Clear() {
    160   return WriteResultError();
    161 }
    162 
    163 }  // namespace extensions
    164