1 // Copyright (c) 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 "services/preferences/tracked/dictionary_hash_store_contents.h"
6 
7 #include "base/callback.h"
8 #include "base/check.h"
9 #include "base/macros.h"
10 #include "base/notreached.h"
11 #include "base/values.h"
12 #include "components/pref_registry/pref_registry_syncable.h"
13 #include "components/prefs/persistent_pref_store.h"
14 
15 namespace {
16 const char kPreferenceMACs[] = "protection.macs";
17 const char kSuperMACPref[] = "protection.super_mac";
18 }
19 
DictionaryHashStoreContents(base::DictionaryValue * storage)20 DictionaryHashStoreContents::DictionaryHashStoreContents(
21     base::DictionaryValue* storage)
22     : storage_(storage) {}
23 
24 // static
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)25 void DictionaryHashStoreContents::RegisterProfilePrefs(
26     user_prefs::PrefRegistrySyncable* registry) {
27   registry->RegisterDictionaryPref(kPreferenceMACs);
28   registry->RegisterStringPref(kSuperMACPref, std::string());
29 }
30 
IsCopyable() const31 bool DictionaryHashStoreContents::IsCopyable() const {
32   return false;
33 }
34 
MakeCopy() const35 std::unique_ptr<HashStoreContents> DictionaryHashStoreContents::MakeCopy()
36     const {
37   NOTREACHED() << "DictionaryHashStoreContents does not support MakeCopy";
38   return nullptr;
39 }
40 
GetUMASuffix() const41 base::StringPiece DictionaryHashStoreContents::GetUMASuffix() const {
42   // To stay consistent with existing reported data, do not append a suffix
43   // when reporting UMA stats for this content.
44   return base::StringPiece();
45 }
46 
Reset()47 void DictionaryHashStoreContents::Reset() {
48   storage_->Remove(kPreferenceMACs, NULL);
49 }
50 
GetMac(const std::string & path,std::string * out_value)51 bool DictionaryHashStoreContents::GetMac(const std::string& path,
52                                          std::string* out_value) {
53   const base::DictionaryValue* macs_dict = GetContents();
54   if (macs_dict)
55     return macs_dict->GetString(path, out_value);
56 
57   return false;
58 }
59 
GetSplitMacs(const std::string & path,std::map<std::string,std::string> * split_macs)60 bool DictionaryHashStoreContents::GetSplitMacs(
61     const std::string& path,
62     std::map<std::string, std::string>* split_macs) {
63   DCHECK(split_macs);
64   DCHECK(split_macs->empty());
65 
66   const base::DictionaryValue* macs_dict = GetContents();
67   const base::DictionaryValue* split_macs_dict = NULL;
68   if (!macs_dict || !macs_dict->GetDictionary(path, &split_macs_dict))
69     return false;
70   for (base::DictionaryValue::Iterator it(*split_macs_dict); !it.IsAtEnd();
71        it.Advance()) {
72     std::string mac_string;
73     if (!it.value().GetAsString(&mac_string)) {
74       NOTREACHED();
75       continue;
76     }
77     split_macs->insert(make_pair(it.key(), mac_string));
78   }
79   return true;
80 }
81 
SetMac(const std::string & path,const std::string & value)82 void DictionaryHashStoreContents::SetMac(const std::string& path,
83                                          const std::string& value) {
84   base::DictionaryValue* macs_dict = GetMutableContents(true);
85   macs_dict->SetString(path, value);
86 }
87 
SetSplitMac(const std::string & path,const std::string & split_path,const std::string & value)88 void DictionaryHashStoreContents::SetSplitMac(const std::string& path,
89                                               const std::string& split_path,
90                                               const std::string& value) {
91   base::DictionaryValue* macs_dict = GetMutableContents(true);
92   base::DictionaryValue* split_dict = nullptr;
93   macs_dict->GetDictionary(path, &split_dict);
94   if (!split_dict) {
95     split_dict = macs_dict->SetDictionary(
96         path, std::make_unique<base::DictionaryValue>());
97   }
98   split_dict->SetKey(split_path, base::Value(value));
99 }
100 
ImportEntry(const std::string & path,const base::Value * in_value)101 void DictionaryHashStoreContents::ImportEntry(const std::string& path,
102                                               const base::Value* in_value) {
103   base::DictionaryValue* macs_dict = GetMutableContents(true);
104   macs_dict->Set(path, std::make_unique<base::Value>(in_value->Clone()));
105 }
106 
RemoveEntry(const std::string & path)107 bool DictionaryHashStoreContents::RemoveEntry(const std::string& path) {
108   base::DictionaryValue* macs_dict = GetMutableContents(false);
109   if (macs_dict)
110     return macs_dict->RemovePath(path, NULL);
111 
112   return false;
113 }
114 
GetSuperMac() const115 std::string DictionaryHashStoreContents::GetSuperMac() const {
116   std::string super_mac_string;
117   storage_->GetString(kSuperMACPref, &super_mac_string);
118   return super_mac_string;
119 }
120 
SetSuperMac(const std::string & super_mac)121 void DictionaryHashStoreContents::SetSuperMac(const std::string& super_mac) {
122   storage_->SetString(kSuperMACPref, super_mac);
123 }
124 
GetContents() const125 const base::DictionaryValue* DictionaryHashStoreContents::GetContents() const {
126   const base::DictionaryValue* macs_dict = NULL;
127   storage_->GetDictionary(kPreferenceMACs, &macs_dict);
128   return macs_dict;
129 }
130 
GetMutableContents(bool create_if_null)131 base::DictionaryValue* DictionaryHashStoreContents::GetMutableContents(
132     bool create_if_null) {
133   base::DictionaryValue* macs_dict = NULL;
134   storage_->GetDictionary(kPreferenceMACs, &macs_dict);
135   if (!macs_dict && create_if_null) {
136     macs_dict = storage_->SetDictionary(
137         kPreferenceMACs, std::make_unique<base::DictionaryValue>());
138   }
139   return macs_dict;
140 }
141