Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: chrome/browser/policy/managed_mode_policy_provider.cc

Issue 23376002: Move ManagedModePolicyProvider functionality to ManagedUserSettingsService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/policy/managed_mode_policy_provider.h"
6
7 #include "base/callback.h"
8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h"
10 #include "base/prefs/json_pref_store.h"
11 #include "base/strings/string_util.h"
12 #include "base/threading/sequenced_worker_pool.h"
13 #include "chrome/browser/managed_mode/managed_mode_url_filter.h"
14 #include "chrome/browser/policy/external_data_fetcher.h"
15 #include "chrome/browser/policy/policy_bundle.h"
16 #include "chrome/browser/prefs/incognito_mode_prefs.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/common/chrome_constants.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/user_metrics.h"
21 #include "policy/policy_constants.h"
22 #include "sync/api/sync_change.h"
23 #include "sync/protocol/sync.pb.h"
24
25 using base::DictionaryValue;
26 using base::JSONReader;
27 using base::Value;
28 using content::BrowserThread;
29 using content::UserMetricsAction;
30 using syncer::MANAGED_USER_SETTINGS;
31 using syncer::ModelType;
32 using syncer::SyncChange;
33 using syncer::SyncChangeList;
34 using syncer::SyncChangeProcessor;
35 using syncer::SyncData;
36 using syncer::SyncDataList;
37 using syncer::SyncError;
38 using syncer::SyncErrorFactory;
39 using syncer::SyncMergeResult;
40
41 namespace {
42
43 const char kAtomicSettings[] = "atomic_settings";
44 const char kManagedUserInternalPolicyPrefix[] = "X-";
45 const char kQueuedItems[] = "queued_items";
46 const char kSplitSettingKeySeparator = ':';
47 const char kSplitSettings[] = "split_settings";
48
49 bool SettingShouldApplyToPolicy(const std::string& key) {
50 return !StartsWithASCII(key, kManagedUserInternalPolicyPrefix, false);
51 }
52
53 } // namespace
54
55 namespace policy {
56
57
58 // static
59 scoped_ptr<ManagedModePolicyProvider> ManagedModePolicyProvider::Create(
60 Profile* profile,
61 base::SequencedTaskRunner* sequenced_task_runner,
62 bool force_load) {
63 base::FilePath path =
64 profile->GetPath().Append(chrome::kManagedModePolicyFilename);
65 JsonPrefStore* pref_store = new JsonPrefStore(path, sequenced_task_runner);
66 // Load the data synchronously if needed (when creating profiles on startup).
67 if (force_load)
68 pref_store->ReadPrefs();
69 else
70 pref_store->ReadPrefsAsync(NULL);
71
72 return make_scoped_ptr(new ManagedModePolicyProvider(pref_store));
73 }
74
75 ManagedModePolicyProvider::ManagedModePolicyProvider(
76 PersistentPrefStore* pref_store)
77 : store_(pref_store),
78 local_policies_(new DictionaryValue) {
79 store_->AddObserver(this);
80 if (store_->IsInitializationComplete())
81 UpdatePolicyFromCache();
82 }
83
84 ManagedModePolicyProvider::~ManagedModePolicyProvider() {}
85
86 void ManagedModePolicyProvider::Clear() {
87 store_->RemoveValue(kAtomicSettings);
88 store_->RemoveValue(kSplitSettings);
89 }
90
91 // static
92 std::string ManagedModePolicyProvider::MakeSplitSettingKey(
93 const std::string& prefix,
94 const std::string& key) {
95 return prefix + kSplitSettingKeySeparator + key;
96 }
97
98 void ManagedModePolicyProvider::UploadItem(const std::string& key,
99 scoped_ptr<Value> value) {
100 DCHECK(!SettingShouldApplyToPolicy(key));
101
102 std::string key_suffix = key;
103 DictionaryValue* dict = NULL;
104 if (sync_processor_) {
105 content::RecordAction(
106 UserMetricsAction("ManagedUsers_UploadItem_Syncing"));
107 dict = GetDictionaryAndSplitKey(&key_suffix);
108 DCHECK(GetQueuedItems()->empty());
109 SyncChangeList change_list;
110 SyncData data = CreateSyncDataForPolicy(key, value.get());
111 SyncChange::SyncChangeType change_type =
112 dict->HasKey(key_suffix) ? SyncChange::ACTION_UPDATE
113 : SyncChange::ACTION_ADD;
114 change_list.push_back(SyncChange(FROM_HERE, change_type, data));
115 SyncError error =
116 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list);
117 DCHECK(!error.IsSet()) << error.ToString();
118 } else {
119 content::RecordAction(
120 UserMetricsAction("ManagedUsers_UploadItem_Queued"));
121 dict = GetQueuedItems();
122 }
123 dict->SetWithoutPathExpansion(key_suffix, value.release());
124 }
125
126 void ManagedModePolicyProvider::SetLocalPolicyForTesting(
127 const std::string& key,
128 scoped_ptr<Value> value) {
129 if (value)
130 local_policies_->SetWithoutPathExpansion(key, value.release());
131 else
132 local_policies_->RemoveWithoutPathExpansion(key, NULL);
133
134 UpdatePolicyFromCache();
135 }
136
137 // static
138 SyncData ManagedModePolicyProvider::CreateSyncDataForPolicy(
139 const std::string& name,
140 const Value* value) {
141 std::string json_value;
142 base::JSONWriter::Write(value, &json_value);
143 ::sync_pb::EntitySpecifics specifics;
144 specifics.mutable_managed_user_setting()->set_name(name);
145 specifics.mutable_managed_user_setting()->set_value(json_value);
146 return SyncData::CreateLocalData(name, name, specifics);
147 }
148
149 void ManagedModePolicyProvider::Shutdown() {
150 store_->RemoveObserver(this);
151 ConfigurationPolicyProvider::Shutdown();
152 }
153
154 void ManagedModePolicyProvider::RefreshPolicies() {
155 UpdatePolicyFromCache();
156 }
157
158 bool ManagedModePolicyProvider::IsInitializationComplete(
159 PolicyDomain domain) const {
160 if (domain == POLICY_DOMAIN_CHROME)
161 return store_->IsInitializationComplete();
162 return true;
163 }
164
165 void ManagedModePolicyProvider::OnPrefValueChanged(const std::string& key) {}
166
167 void ManagedModePolicyProvider::OnInitializationCompleted(bool success) {
168 DCHECK(success);
169 UpdatePolicyFromCache();
170 }
171
172 SyncMergeResult ManagedModePolicyProvider::MergeDataAndStartSyncing(
173 ModelType type,
174 const SyncDataList& initial_sync_data,
175 scoped_ptr<SyncChangeProcessor> sync_processor,
176 scoped_ptr<SyncErrorFactory> error_handler) {
177 DCHECK_EQ(MANAGED_USER_SETTINGS, type);
178 sync_processor_ = sync_processor.Pass();
179 error_handler_ = error_handler.Pass();
180
181 // Clear all atomic and split settings, then recreate them from Sync data.
182 Clear();
183 for (SyncDataList::const_iterator it = initial_sync_data.begin();
184 it != initial_sync_data.end(); ++it) {
185 DCHECK_EQ(MANAGED_USER_SETTINGS, it->GetDataType());
186 const ::sync_pb::ManagedUserSettingSpecifics& managed_user_setting =
187 it->GetSpecifics().managed_user_setting();
188 scoped_ptr<Value> value(JSONReader::Read(managed_user_setting.value()));
189 std::string name_suffix = managed_user_setting.name();
190 DictionaryValue* dict = GetDictionaryAndSplitKey(&name_suffix);
191 dict->SetWithoutPathExpansion(name_suffix, value.release());
192 }
193 store_->ReportValueChanged(kAtomicSettings);
194 store_->ReportValueChanged(kSplitSettings);
195 UpdatePolicyFromCache();
196
197 // Upload all the queued up items (either with an ADD or an UPDATE action,
198 // depending on whether they already exist) and move them to split settings.
199 SyncChangeList change_list;
200 DictionaryValue* queued_items = GetQueuedItems();
201 for (DictionaryValue::Iterator it(*queued_items); !it.IsAtEnd();
202 it.Advance()) {
203 std::string key_suffix = it.key();
204 DictionaryValue* dict = GetDictionaryAndSplitKey(&key_suffix);
205 SyncData data = CreateSyncDataForPolicy(it.key(), &it.value());
206 SyncChange::SyncChangeType change_type =
207 dict->HasKey(key_suffix) ? SyncChange::ACTION_UPDATE
208 : SyncChange::ACTION_ADD;
209 change_list.push_back(SyncChange(FROM_HERE, change_type, data));
210 dict->SetWithoutPathExpansion(key_suffix, it.value().DeepCopy());
211 }
212 queued_items->Clear();
213
214 SyncMergeResult result(MANAGED_USER_SETTINGS);
215 // Process all the accumulated changes from the queued items.
216 if (change_list.size() > 0) {
217 store_->ReportValueChanged(kQueuedItems);
218 result.set_error(
219 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list));
220 }
221
222 // TODO(bauerb): Statistics?
223 return result;
224 }
225
226 void ManagedModePolicyProvider::StopSyncing(ModelType type) {
227 DCHECK_EQ(syncer::MANAGED_USER_SETTINGS, type);
228 sync_processor_.reset();
229 error_handler_.reset();
230 }
231
232 SyncDataList ManagedModePolicyProvider::GetAllSyncData(ModelType type) const {
233 DCHECK_EQ(syncer::MANAGED_USER_SETTINGS, type);
234 SyncDataList data;
235 for (DictionaryValue::Iterator it(*GetAtomicSettings()); !it.IsAtEnd();
236 it.Advance()) {
237 data.push_back(CreateSyncDataForPolicy(it.key(), &it.value()));
238 }
239 for (DictionaryValue::Iterator it(*GetSplitSettings()); !it.IsAtEnd();
240 it.Advance()) {
241 const DictionaryValue* dict = NULL;
242 it.value().GetAsDictionary(&dict);
243 for (DictionaryValue::Iterator jt(*dict); !jt.IsAtEnd(); jt.Advance()) {
244 data.push_back(CreateSyncDataForPolicy(
245 MakeSplitSettingKey(it.key(), jt.key()), &jt.value()));
246 }
247 }
248 DCHECK_EQ(0u, GetQueuedItems()->size());
249 return data;
250 }
251
252 SyncError ManagedModePolicyProvider::ProcessSyncChanges(
253 const tracked_objects::Location& from_here,
254 const SyncChangeList& change_list) {
255 for (SyncChangeList::const_iterator it = change_list.begin();
256 it != change_list.end(); ++it) {
257 SyncData data = it->sync_data();
258 DCHECK_EQ(MANAGED_USER_SETTINGS, data.GetDataType());
259 const ::sync_pb::ManagedUserSettingSpecifics& managed_user_setting =
260 data.GetSpecifics().managed_user_setting();
261 std::string key = managed_user_setting.name();
262 DictionaryValue* dict = GetDictionaryAndSplitKey(&key);
263 switch (it->change_type()) {
264 case SyncChange::ACTION_ADD:
265 case SyncChange::ACTION_UPDATE: {
266 scoped_ptr<Value> value(JSONReader::Read(managed_user_setting.value()));
267 if (dict->HasKey(key)) {
268 DLOG_IF(WARNING, it->change_type() == SyncChange::ACTION_ADD)
269 << "Value for key " << key << " already exists";
270 } else {
271 DLOG_IF(WARNING, it->change_type() == SyncChange::ACTION_UPDATE)
272 << "Value for key " << key << " doesn't exist yet";
273 }
274 dict->SetWithoutPathExpansion(key, value.release());
275 break;
276 }
277 case SyncChange::ACTION_DELETE: {
278 DLOG_IF(WARNING, !dict->HasKey(key)) << "Trying to delete nonexistent "
279 << "key " << key;
280 dict->RemoveWithoutPathExpansion(key, NULL);
281 break;
282 }
283 case SyncChange::ACTION_INVALID: {
284 NOTREACHED();
285 break;
286 }
287 }
288 }
289 store_->ReportValueChanged(kAtomicSettings);
290 store_->ReportValueChanged(kSplitSettings);
291 UpdatePolicyFromCache();
292
293 SyncError error;
294 return error;
295 }
296
297 void ManagedModePolicyProvider::InitLocalPolicies() {
298 local_policies_->Clear();
299 local_policies_->SetBoolean(policy::key::kAllowDeletingBrowserHistory, false);
300 local_policies_->SetInteger(policy::key::kContentPackDefaultFilteringBehavior,
301 ManagedModeURLFilter::ALLOW);
302 local_policies_->SetBoolean(policy::key::kForceSafeSearch, true);
303 local_policies_->SetBoolean(policy::key::kHideWebStoreIcon, true);
304 local_policies_->SetInteger(policy::key::kIncognitoModeAvailability,
305 IncognitoModePrefs::DISABLED);
306 local_policies_->SetBoolean(policy::key::kSigninAllowed, false);
307 UpdatePolicyFromCache();
308 }
309
310 DictionaryValue* ManagedModePolicyProvider::GetOrCreateDictionary(
311 const std::string& key) const {
312 Value* value = NULL;
313 DictionaryValue* dict = NULL;
314 if (store_->GetMutableValue(key, &value)) {
315 bool success = value->GetAsDictionary(&dict);
316 DCHECK(success);
317 } else {
318 dict = new base::DictionaryValue;
319 store_->SetValue(key, dict);
320 }
321
322 return dict;
323 }
324
325 DictionaryValue* ManagedModePolicyProvider::GetAtomicSettings() const {
326 return GetOrCreateDictionary(kAtomicSettings);
327 }
328
329 DictionaryValue* ManagedModePolicyProvider::GetSplitSettings() const {
330 return GetOrCreateDictionary(kSplitSettings);
331 }
332
333 DictionaryValue* ManagedModePolicyProvider::GetQueuedItems() const {
334 return GetOrCreateDictionary(kQueuedItems);
335 }
336
337 DictionaryValue* ManagedModePolicyProvider::GetDictionaryAndSplitKey(
338 std::string* key) const {
339 size_t pos = key->find_first_of(kSplitSettingKeySeparator);
340 if (pos == std::string::npos)
341 return GetAtomicSettings();
342
343 DictionaryValue* split_settings = GetSplitSettings();
344 std::string prefix = key->substr(0, pos);
345 DictionaryValue* dict = NULL;
346 if (!split_settings->GetDictionary(prefix, &dict)) {
347 dict = new DictionaryValue;
348 DCHECK(!split_settings->HasKey(prefix));
349 split_settings->Set(prefix, dict);
350 }
351 key->erase(0, pos + 1);
352 return dict;
353 }
354
355 void ManagedModePolicyProvider::UpdatePolicyFromCache() {
356 scoped_ptr<PolicyBundle> policy_bundle(new PolicyBundle);
357 PolicyMap* policy_map = &policy_bundle->Get(
358 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
359 policy_map->LoadFrom(
360 local_policies_.get(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
361
362 DictionaryValue* atomic_settings = GetAtomicSettings();
363 for (DictionaryValue::Iterator it(*atomic_settings); !it.IsAtEnd();
364 it.Advance()) {
365 if (!SettingShouldApplyToPolicy(it.key()))
366 continue;
367
368 policy_map->Set(it.key(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
369 it.value().DeepCopy(), NULL);
370 }
371
372 DictionaryValue* split_settings = GetSplitSettings();
373 for (DictionaryValue::Iterator it(*split_settings); !it.IsAtEnd();
374 it.Advance()) {
375 if (!SettingShouldApplyToPolicy(it.key()))
376 continue;
377
378 policy_map->Set(it.key(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
379 it.value().DeepCopy(), NULL);
380 }
381 UpdatePolicy(policy_bundle.Pass());
382 }
383
384 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698