Add a minor text member to ui::MenuModel.
[chromium-blink-merge.git] / chrome / browser / policy / configuration_policy_handler.cc
blob30bcc9cd2e34a58fa428e46c23df5f01c11243c3
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.
5 #include "chrome/browser/policy/configuration_policy_handler.h"
7 #include <algorithm>
9 #include "base/callback.h"
10 #include "base/files/file_path.h"
11 #include "base/json/json_writer.h"
12 #include "base/logging.h"
13 #include "base/prefs/pref_value_map.h"
14 #include "base/stl_util.h"
15 #include "base/strings/string16.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/download/download_prefs.h"
20 #include "chrome/browser/extensions/external_policy_loader.h"
21 #include "chrome/browser/policy/configuration_policy_pref_store.h"
22 #include "chrome/browser/policy/external_data_fetcher.h"
23 #include "chrome/browser/policy/policy_error_map.h"
24 #include "chrome/browser/policy/policy_map.h"
25 #include "chrome/browser/prefs/proxy_config_dictionary.h"
26 #include "chrome/browser/prefs/proxy_prefs.h"
27 #include "chrome/browser/prefs/session_startup_pref.h"
28 #include "chrome/browser/search_engines/search_terms_data.h"
29 #include "chrome/browser/search_engines/template_url.h"
30 #include "chrome/common/extensions/extension.h"
31 #include "chrome/common/pref_names.h"
32 #include "content/public/browser/notification_service.h"
33 #include "grit/generated_resources.h"
34 #include "policy/policy_constants.h"
35 #include "url/gurl.h"
37 #if !defined(OS_ANDROID)
38 #include "chrome/browser/policy/policy_path_parser.h"
39 #endif
41 namespace policy {
43 namespace {
45 // Helper classes --------------------------------------------------------------
47 // This is used to check whether for a given ProxyMode value, the ProxyPacUrl,
48 // the ProxyBypassList and the ProxyServer policies are allowed to be specified.
49 // |error_message_id| is the message id of the localized error message to show
50 // when the policies are not specified as allowed. Each value of ProxyMode
51 // has a ProxyModeValidationEntry in the |kProxyModeValidationMap| below.
52 struct ProxyModeValidationEntry {
53 const char* mode_value;
54 bool pac_url_allowed;
55 bool bypass_list_allowed;
56 bool server_allowed;
57 int error_message_id;
60 // Maps a policy type to a preference path, and to the expected value type.
61 struct DefaultSearchSimplePolicyHandlerEntry {
62 const char* policy_name;
63 const char* preference_path;
64 base::Value::Type value_type;
68 // Static data -----------------------------------------------------------------
70 // List of policy types to preference names, for policies affecting the default
71 // search provider.
72 const DefaultSearchSimplePolicyHandlerEntry kDefaultSearchPolicyMap[] = {
73 { key::kDefaultSearchProviderEnabled,
74 prefs::kDefaultSearchProviderEnabled,
75 Value::TYPE_BOOLEAN },
76 { key::kDefaultSearchProviderName,
77 prefs::kDefaultSearchProviderName,
78 Value::TYPE_STRING },
79 { key::kDefaultSearchProviderKeyword,
80 prefs::kDefaultSearchProviderKeyword,
81 Value::TYPE_STRING },
82 { key::kDefaultSearchProviderSearchURL,
83 prefs::kDefaultSearchProviderSearchURL,
84 Value::TYPE_STRING },
85 { key::kDefaultSearchProviderSuggestURL,
86 prefs::kDefaultSearchProviderSuggestURL,
87 Value::TYPE_STRING },
88 { key::kDefaultSearchProviderInstantURL,
89 prefs::kDefaultSearchProviderInstantURL,
90 Value::TYPE_STRING },
91 { key::kDefaultSearchProviderIconURL,
92 prefs::kDefaultSearchProviderIconURL,
93 Value::TYPE_STRING },
94 { key::kDefaultSearchProviderEncodings,
95 prefs::kDefaultSearchProviderEncodings,
96 Value::TYPE_LIST },
97 { key::kDefaultSearchProviderAlternateURLs,
98 prefs::kDefaultSearchProviderAlternateURLs,
99 Value::TYPE_LIST },
100 { key::kDefaultSearchProviderSearchTermsReplacementKey,
101 prefs::kDefaultSearchProviderSearchTermsReplacementKey,
102 Value::TYPE_STRING },
103 { key::kDefaultSearchProviderImageURL,
104 prefs::kDefaultSearchProviderImageURL,
105 Value::TYPE_STRING },
106 { key::kDefaultSearchProviderNewTabURL,
107 prefs::kDefaultSearchProviderNewTabURL,
108 Value::TYPE_STRING },
109 { key::kDefaultSearchProviderSearchURLPostParams,
110 prefs::kDefaultSearchProviderSearchURLPostParams,
111 Value::TYPE_STRING },
112 { key::kDefaultSearchProviderSuggestURLPostParams,
113 prefs::kDefaultSearchProviderSuggestURLPostParams,
114 Value::TYPE_STRING },
115 { key::kDefaultSearchProviderInstantURLPostParams,
116 prefs::kDefaultSearchProviderInstantURLPostParams,
117 Value::TYPE_STRING },
118 { key::kDefaultSearchProviderImageURLPostParams,
119 prefs::kDefaultSearchProviderImageURLPostParams,
120 Value::TYPE_STRING },
123 // List of entries determining which proxy policies can be specified, depending
124 // on the ProxyMode.
125 const ProxyModeValidationEntry kProxyModeValidationMap[] = {
126 { ProxyPrefs::kDirectProxyModeName,
127 false, false, false, IDS_POLICY_PROXY_MODE_DISABLED_ERROR },
128 { ProxyPrefs::kAutoDetectProxyModeName,
129 false, false, false, IDS_POLICY_PROXY_MODE_AUTO_DETECT_ERROR },
130 { ProxyPrefs::kPacScriptProxyModeName,
131 true, false, false, IDS_POLICY_PROXY_MODE_PAC_URL_ERROR },
132 { ProxyPrefs::kFixedServersProxyModeName,
133 false, true, true, IDS_POLICY_PROXY_MODE_FIXED_SERVERS_ERROR },
134 { ProxyPrefs::kSystemProxyModeName,
135 false, false, false, IDS_POLICY_PROXY_MODE_SYSTEM_ERROR },
139 // Helper function -------------------------------------------------------------
141 // Utility function that returns a JSON representation of the given |dict| as
142 // a StringValue. The caller owns the returned object.
143 base::StringValue* DictionaryToJSONString(const base::DictionaryValue* dict) {
144 std::string json_string;
145 base::JSONWriter::WriteWithOptions(
146 dict,
147 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE |
148 base::JSONWriter::OPTIONS_PRETTY_PRINT,
149 &json_string);
150 return Value::CreateStringValue(json_string);
154 } // namespace
157 // ConfigurationPolicyHandler implementation -----------------------------------
159 // static
160 std::string ConfigurationPolicyHandler::ValueTypeToString(Value::Type type) {
161 static const char* strings[] = {
162 "null",
163 "boolean",
164 "integer",
165 "double",
166 "string",
167 "binary",
168 "dictionary",
169 "list"
171 CHECK(static_cast<size_t>(type) < arraysize(strings));
172 return std::string(strings[type]);
175 ConfigurationPolicyHandler::ConfigurationPolicyHandler() {
178 ConfigurationPolicyHandler::~ConfigurationPolicyHandler() {
181 void ConfigurationPolicyHandler::PrepareForDisplaying(
182 PolicyMap* policies) const {
183 // jstemplate can't render DictionaryValues/objects. Convert those values to
184 // a string representation.
185 base::DictionaryValue* dict;
186 base::ListValue* list;
187 for (PolicyMap::const_iterator it = policies->begin();
188 it != policies->end(); ++it) {
189 const PolicyMap::Entry& entry = it->second;
190 if (entry.value->GetAsDictionary(&dict)) {
191 base::StringValue* value = DictionaryToJSONString(dict);
192 policies->Set(it->first, entry.level, entry.scope,
193 value, entry.external_data_fetcher ?
194 new ExternalDataFetcher(*entry.external_data_fetcher) :
195 NULL);
196 } else if (entry.value->GetAsList(&list)) {
197 for (size_t i = 0; i < list->GetSize(); ++i) {
198 if (list->GetDictionary(i, &dict)) {
199 list->Set(i, DictionaryToJSONString(dict));
207 // TypeCheckingPolicyHandler implementation ------------------------------------
209 TypeCheckingPolicyHandler::TypeCheckingPolicyHandler(
210 const char* policy_name,
211 Value::Type value_type)
212 : policy_name_(policy_name),
213 value_type_(value_type) {
216 TypeCheckingPolicyHandler::~TypeCheckingPolicyHandler() {
219 const char* TypeCheckingPolicyHandler::policy_name() const {
220 return policy_name_;
223 bool TypeCheckingPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
224 PolicyErrorMap* errors) {
225 const Value* value = NULL;
226 return CheckAndGetValue(policies, errors, &value);
229 bool TypeCheckingPolicyHandler::CheckAndGetValue(const PolicyMap& policies,
230 PolicyErrorMap* errors,
231 const Value** value) {
232 *value = policies.GetValue(policy_name_);
233 if (*value && !(*value)->IsType(value_type_)) {
234 errors->AddError(policy_name_,
235 IDS_POLICY_TYPE_ERROR,
236 ValueTypeToString(value_type_));
237 return false;
239 return true;
242 // IntRangePolicyHandlerBase implementation ------------------------------------
244 IntRangePolicyHandlerBase::IntRangePolicyHandlerBase(
245 const char* policy_name,
246 int min,
247 int max,
248 bool clamp)
249 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_INTEGER),
250 min_(min),
251 max_(max),
252 clamp_(clamp) {
255 bool IntRangePolicyHandlerBase::CheckPolicySettings(const PolicyMap& policies,
256 PolicyErrorMap* errors) {
257 const base::Value* value;
258 return CheckAndGetValue(policies, errors, &value) &&
259 EnsureInRange(value, NULL, errors);
262 IntRangePolicyHandlerBase::~IntRangePolicyHandlerBase() {
265 bool IntRangePolicyHandlerBase::EnsureInRange(const base::Value* input,
266 int* output,
267 PolicyErrorMap* errors) {
268 if (!input)
269 return true;
271 int value;
272 if (!input->GetAsInteger(&value)) {
273 NOTREACHED();
274 return false;
277 if (value < min_ || value > max_) {
278 if (errors) {
279 errors->AddError(policy_name(),
280 IDS_POLICY_OUT_OF_RANGE_ERROR,
281 base::IntToString(value));
284 if (!clamp_)
285 return false;
287 value = std::min(std::max(value, min_), max_);
290 if (output)
291 *output = value;
292 return true;
295 // StringToIntEnumListPolicyHandler implementation -----------------------------
297 StringToIntEnumListPolicyHandler::StringToIntEnumListPolicyHandler(
298 const char* policy_name,
299 const char* pref_path,
300 const MappingEntry* mapping_begin,
301 const MappingEntry* mapping_end)
302 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
303 pref_path_(pref_path),
304 mapping_begin_(mapping_begin),
305 mapping_end_(mapping_end) {}
307 bool StringToIntEnumListPolicyHandler::CheckPolicySettings(
308 const PolicyMap& policies,
309 PolicyErrorMap* errors) {
310 const base::Value* value;
311 return CheckAndGetValue(policies, errors, &value) &&
312 Convert(value, NULL, errors);
315 void StringToIntEnumListPolicyHandler::ApplyPolicySettings(
316 const PolicyMap& policies,
317 PrefValueMap* prefs) {
318 if (!pref_path_)
319 return;
320 const base::Value* value = policies.GetValue(policy_name());
321 scoped_ptr<base::ListValue> list(new base::ListValue());
322 if (value && Convert(value, list.get(), NULL))
323 prefs->SetValue(pref_path_, list.release());
326 bool StringToIntEnumListPolicyHandler::Convert(const base::Value* input,
327 base::ListValue* output,
328 PolicyErrorMap* errors) {
329 if (!input)
330 return true;
332 const base::ListValue* list_value = NULL;
333 if (!input->GetAsList(&list_value)) {
334 NOTREACHED();
335 return false;
338 for (base::ListValue::const_iterator entry(list_value->begin());
339 entry != list_value->end(); ++entry) {
340 std::string entry_value;
341 if (!(*entry)->GetAsString(&entry_value)) {
342 if (errors) {
343 errors->AddError(policy_name(),
344 entry - list_value->begin(),
345 IDS_POLICY_TYPE_ERROR,
346 ValueTypeToString(base::Value::TYPE_STRING));
348 continue;
350 bool found = false;
351 for (const MappingEntry* mapping_entry(mapping_begin_);
352 mapping_entry != mapping_end_; ++mapping_entry) {
353 if (mapping_entry->enum_value == entry_value) {
354 found = true;
355 if (output)
356 output->AppendInteger(mapping_entry->int_value);
357 break;
360 if (!found) {
361 if (errors) {
362 errors->AddError(policy_name(),
363 entry - list_value->begin(),
364 IDS_POLICY_OUT_OF_RANGE_ERROR);
369 return true;
372 // IntRangePolicyHandler implementation ----------------------------------------
374 IntRangePolicyHandler::IntRangePolicyHandler(const char* policy_name,
375 const char* pref_path,
376 int min,
377 int max,
378 bool clamp)
379 : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
380 pref_path_(pref_path) {
383 IntRangePolicyHandler::~IntRangePolicyHandler() {
386 void IntRangePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
387 PrefValueMap* prefs) {
388 if (!pref_path_)
389 return;
390 const base::Value* value = policies.GetValue(policy_name());
391 int value_in_range;
392 if (value && EnsureInRange(value, &value_in_range, NULL)) {
393 prefs->SetValue(pref_path_,
394 base::Value::CreateIntegerValue(value_in_range));
398 // IntPercentageToDoublePolicyHandler implementation ---------------------------
400 IntPercentageToDoublePolicyHandler::IntPercentageToDoublePolicyHandler(
401 const char* policy_name,
402 const char* pref_path,
403 int min,
404 int max,
405 bool clamp)
406 : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
407 pref_path_(pref_path) {
410 IntPercentageToDoublePolicyHandler::~IntPercentageToDoublePolicyHandler() {
413 void IntPercentageToDoublePolicyHandler::ApplyPolicySettings(
414 const PolicyMap& policies,
415 PrefValueMap* prefs) {
416 if (!pref_path_)
417 return;
418 const base::Value* value = policies.GetValue(policy_name());
419 int percentage;
420 if (value && EnsureInRange(value, &percentage, NULL)) {
421 prefs->SetValue(pref_path_, base::Value::CreateDoubleValue(
422 static_cast<double>(percentage) / 100.));
426 // ExtensionListPolicyHandler implementation -----------------------------------
428 ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name,
429 const char* pref_path,
430 bool allow_wildcards)
431 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
432 pref_path_(pref_path),
433 allow_wildcards_(allow_wildcards) {}
435 ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {}
437 bool ExtensionListPolicyHandler::CheckPolicySettings(
438 const PolicyMap& policies,
439 PolicyErrorMap* errors) {
440 return CheckAndGetList(policies, errors, NULL);
443 void ExtensionListPolicyHandler::ApplyPolicySettings(
444 const PolicyMap& policies,
445 PrefValueMap* prefs) {
446 scoped_ptr<base::ListValue> list;
447 PolicyErrorMap errors;
448 if (CheckAndGetList(policies, &errors, &list) && list)
449 prefs->SetValue(pref_path(), list.release());
452 const char* ExtensionListPolicyHandler::pref_path() const {
453 return pref_path_;
456 bool ExtensionListPolicyHandler::CheckAndGetList(
457 const PolicyMap& policies,
458 PolicyErrorMap* errors,
459 scoped_ptr<base::ListValue>* extension_ids) {
460 if (extension_ids)
461 extension_ids->reset();
463 const base::Value* value = NULL;
464 if (!CheckAndGetValue(policies, errors, &value))
465 return false;
467 if (!value)
468 return true;
470 const base::ListValue* list_value = NULL;
471 if (!value->GetAsList(&list_value)) {
472 NOTREACHED();
473 return false;
476 // Filter the list, rejecting any invalid extension IDs.
477 scoped_ptr<base::ListValue> filtered_list(new base::ListValue());
478 for (base::ListValue::const_iterator entry(list_value->begin());
479 entry != list_value->end(); ++entry) {
480 std::string id;
481 if (!(*entry)->GetAsString(&id)) {
482 errors->AddError(policy_name(),
483 entry - list_value->begin(),
484 IDS_POLICY_TYPE_ERROR,
485 ValueTypeToString(base::Value::TYPE_STRING));
486 continue;
488 if (!(allow_wildcards_ && id == "*") &&
489 !extensions::Extension::IdIsValid(id)) {
490 errors->AddError(policy_name(),
491 entry - list_value->begin(),
492 IDS_POLICY_VALUE_FORMAT_ERROR);
493 continue;
495 filtered_list->Append(base::Value::CreateStringValue(id));
498 if (extension_ids)
499 *extension_ids = filtered_list.Pass();
501 return true;
504 // ExtensionInstallForcelistPolicyHandler implementation -----------------------
506 ExtensionInstallForcelistPolicyHandler::
507 ExtensionInstallForcelistPolicyHandler()
508 : TypeCheckingPolicyHandler(key::kExtensionInstallForcelist,
509 base::Value::TYPE_LIST) {}
511 ExtensionInstallForcelistPolicyHandler::
512 ~ExtensionInstallForcelistPolicyHandler() {}
514 bool ExtensionInstallForcelistPolicyHandler::CheckPolicySettings(
515 const PolicyMap& policies,
516 PolicyErrorMap* errors) {
517 const base::Value* value;
518 return CheckAndGetValue(policies, errors, &value) &&
519 ParseList(value, NULL, errors);
522 void ExtensionInstallForcelistPolicyHandler::ApplyPolicySettings(
523 const PolicyMap& policies,
524 PrefValueMap* prefs) {
525 const base::Value* value = NULL;
526 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
527 if (CheckAndGetValue(policies, NULL, &value) &&
528 value &&
529 ParseList(value, dict.get(), NULL)) {
530 prefs->SetValue(prefs::kExtensionInstallForceList, dict.release());
534 bool ExtensionInstallForcelistPolicyHandler::ParseList(
535 const base::Value* policy_value,
536 base::DictionaryValue* extension_dict,
537 PolicyErrorMap* errors) {
538 if (!policy_value)
539 return true;
541 const base::ListValue* policy_list_value = NULL;
542 if (!policy_value->GetAsList(&policy_list_value)) {
543 // This should have been caught in CheckPolicySettings.
544 NOTREACHED();
545 return false;
548 for (base::ListValue::const_iterator entry(policy_list_value->begin());
549 entry != policy_list_value->end(); ++entry) {
550 std::string entry_string;
551 if (!(*entry)->GetAsString(&entry_string)) {
552 if (errors) {
553 errors->AddError(policy_name(),
554 entry - policy_list_value->begin(),
555 IDS_POLICY_TYPE_ERROR,
556 ValueTypeToString(base::Value::TYPE_STRING));
558 continue;
561 // Each string item of the list has the following form:
562 // <extension_id>;<update_url>
563 // Note: The update URL might also contain semicolons.
564 size_t pos = entry_string.find(';');
565 if (pos == std::string::npos) {
566 if (errors) {
567 errors->AddError(policy_name(),
568 entry - policy_list_value->begin(),
569 IDS_POLICY_VALUE_FORMAT_ERROR);
571 continue;
574 std::string extension_id = entry_string.substr(0, pos);
575 std::string update_url = entry_string.substr(pos+1);
576 if (!extensions::Extension::IdIsValid(extension_id) ||
577 !GURL(update_url).is_valid()) {
578 if (errors) {
579 errors->AddError(policy_name(),
580 entry - policy_list_value->begin(),
581 IDS_POLICY_VALUE_FORMAT_ERROR);
583 continue;
586 if (extension_dict) {
587 extensions::ExternalPolicyLoader::AddExtension(
588 extension_dict, extension_id, update_url);
592 return true;
595 // ExtensionURLPatternListPolicyHandler implementation -------------------------
597 ExtensionURLPatternListPolicyHandler::ExtensionURLPatternListPolicyHandler(
598 const char* policy_name,
599 const char* pref_path)
600 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
601 pref_path_(pref_path) {}
603 ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {}
605 bool ExtensionURLPatternListPolicyHandler::CheckPolicySettings(
606 const PolicyMap& policies,
607 PolicyErrorMap* errors) {
608 const base::Value* value = NULL;
609 if (!CheckAndGetValue(policies, errors, &value))
610 return false;
612 if (!value)
613 return true;
615 const base::ListValue* list_value = NULL;
616 if (!value->GetAsList(&list_value)) {
617 NOTREACHED();
618 return false;
621 // Check that the list contains valid URLPattern strings only.
622 for (base::ListValue::const_iterator entry(list_value->begin());
623 entry != list_value->end(); ++entry) {
624 std::string url_pattern_string;
625 if (!(*entry)->GetAsString(&url_pattern_string)) {
626 errors->AddError(policy_name(),
627 entry - list_value->begin(),
628 IDS_POLICY_TYPE_ERROR,
629 ValueTypeToString(base::Value::TYPE_STRING));
630 return false;
633 URLPattern pattern(URLPattern::SCHEME_ALL);
634 if (pattern.Parse(url_pattern_string) != URLPattern::PARSE_SUCCESS) {
635 errors->AddError(policy_name(),
636 entry - list_value->begin(),
637 IDS_POLICY_VALUE_FORMAT_ERROR);
638 return false;
642 return true;
645 void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings(
646 const PolicyMap& policies,
647 PrefValueMap* prefs) {
648 if (!pref_path_)
649 return;
650 const Value* value = policies.GetValue(policy_name());
651 if (value)
652 prefs->SetValue(pref_path_, value->DeepCopy());
655 // SimplePolicyHandler implementation ------------------------------------------
657 SimplePolicyHandler::SimplePolicyHandler(
658 const char* policy_name,
659 const char* pref_path,
660 Value::Type value_type)
661 : TypeCheckingPolicyHandler(policy_name, value_type),
662 pref_path_(pref_path) {
665 SimplePolicyHandler::~SimplePolicyHandler() {
668 void SimplePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
669 PrefValueMap* prefs) {
670 if (!pref_path_)
671 return;
672 const Value* value = policies.GetValue(policy_name());
673 if (value)
674 prefs->SetValue(pref_path_, value->DeepCopy());
678 // SyncPolicyHandler implementation --------------------------------------------
680 SyncPolicyHandler::SyncPolicyHandler()
681 : TypeCheckingPolicyHandler(key::kSyncDisabled,
682 Value::TYPE_BOOLEAN) {
685 SyncPolicyHandler::~SyncPolicyHandler() {
688 void SyncPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
689 PrefValueMap* prefs) {
690 const Value* value = policies.GetValue(policy_name());
691 bool disable_sync;
692 if (value && value->GetAsBoolean(&disable_sync) && disable_sync)
693 prefs->SetValue(prefs::kSyncManaged, value->DeepCopy());
697 // AutofillPolicyHandler implementation ----------------------------------------
699 AutofillPolicyHandler::AutofillPolicyHandler()
700 : TypeCheckingPolicyHandler(key::kAutoFillEnabled,
701 Value::TYPE_BOOLEAN) {
704 AutofillPolicyHandler::~AutofillPolicyHandler() {
707 void AutofillPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
708 PrefValueMap* prefs) {
709 const Value* value = policies.GetValue(policy_name());
710 bool auto_fill_enabled;
711 if (value && value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled) {
712 prefs->SetValue(autofill::prefs::kAutofillEnabled,
713 Value::CreateBooleanValue(false));
717 // Android doesn't support these policies, and doesn't have a policy_path_parser
718 // implementation.
719 #if !defined(OS_ANDROID)
721 // DownloadDirPolicyHandler implementation -------------------------------------
723 DownloadDirPolicyHandler::DownloadDirPolicyHandler()
724 : TypeCheckingPolicyHandler(key::kDownloadDirectory,
725 Value::TYPE_STRING) {
728 DownloadDirPolicyHandler::~DownloadDirPolicyHandler() {
731 void DownloadDirPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
732 PrefValueMap* prefs) {
733 const Value* value = policies.GetValue(policy_name());
734 base::FilePath::StringType string_value;
735 if (!value || !value->GetAsString(&string_value))
736 return;
738 base::FilePath::StringType expanded_value =
739 policy::path_parser::ExpandPathVariables(string_value);
740 // Make sure the path isn't empty, since that will point to an undefined
741 // location; the default location is used instead in that case.
742 // This is checked after path expansion because a non-empty policy value can
743 // lead to an empty path value after expansion (e.g. "\"\"").
744 if (expanded_value.empty())
745 expanded_value = DownloadPrefs::GetDefaultDownloadDirectory().value();
746 prefs->SetValue(prefs::kDownloadDefaultDirectory,
747 Value::CreateStringValue(expanded_value));
748 prefs->SetValue(prefs::kPromptForDownload,
749 Value::CreateBooleanValue(false));
753 // DiskCacheDirPolicyHandler implementation ------------------------------------
755 DiskCacheDirPolicyHandler::DiskCacheDirPolicyHandler()
756 : TypeCheckingPolicyHandler(key::kDiskCacheDir,
757 Value::TYPE_STRING) {
760 DiskCacheDirPolicyHandler::~DiskCacheDirPolicyHandler() {
763 void DiskCacheDirPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
764 PrefValueMap* prefs) {
765 const Value* value = policies.GetValue(policy_name());
766 base::FilePath::StringType string_value;
767 if (value && value->GetAsString(&string_value)) {
768 base::FilePath::StringType expanded_value =
769 policy::path_parser::ExpandPathVariables(string_value);
770 prefs->SetValue(prefs::kDiskCacheDir,
771 Value::CreateStringValue(expanded_value));
775 #endif // !defined(OS_ANDROID)
777 // FileSelectionDialogsHandler implementation ----------------------------------
779 FileSelectionDialogsHandler::FileSelectionDialogsHandler()
780 : TypeCheckingPolicyHandler(key::kAllowFileSelectionDialogs,
781 Value::TYPE_BOOLEAN) {
784 FileSelectionDialogsHandler::~FileSelectionDialogsHandler() {
787 void FileSelectionDialogsHandler::ApplyPolicySettings(const PolicyMap& policies,
788 PrefValueMap* prefs) {
789 bool allow_dialogs;
790 const Value* value = policies.GetValue(policy_name());
791 if (value && value->GetAsBoolean(&allow_dialogs)) {
792 prefs->SetValue(prefs::kAllowFileSelectionDialogs,
793 Value::CreateBooleanValue(allow_dialogs));
794 // Disallow selecting the download location if file dialogs are disabled.
795 if (!allow_dialogs) {
796 prefs->SetValue(prefs::kPromptForDownload,
797 Value::CreateBooleanValue(false));
803 // IncognitoModePolicyHandler implementation -----------------------------------
805 IncognitoModePolicyHandler::IncognitoModePolicyHandler() {
808 IncognitoModePolicyHandler::~IncognitoModePolicyHandler() {
811 bool IncognitoModePolicyHandler::CheckPolicySettings(const PolicyMap& policies,
812 PolicyErrorMap* errors) {
813 int int_value = IncognitoModePrefs::ENABLED;
814 const Value* availability =
815 policies.GetValue(key::kIncognitoModeAvailability);
817 if (availability) {
818 if (availability->GetAsInteger(&int_value)) {
819 IncognitoModePrefs::Availability availability_enum_value;
820 if (!IncognitoModePrefs::IntToAvailability(int_value,
821 &availability_enum_value)) {
822 errors->AddError(key::kIncognitoModeAvailability,
823 IDS_POLICY_OUT_OF_RANGE_ERROR,
824 base::IntToString(int_value));
825 return false;
827 } else {
828 errors->AddError(key::kIncognitoModeAvailability,
829 IDS_POLICY_TYPE_ERROR,
830 ValueTypeToString(Value::TYPE_INTEGER));
831 return false;
833 } else {
834 const Value* deprecated_enabled = policies.GetValue(key::kIncognitoEnabled);
835 if (deprecated_enabled &&
836 !deprecated_enabled->IsType(Value::TYPE_BOOLEAN)) {
837 errors->AddError(key::kIncognitoEnabled,
838 IDS_POLICY_TYPE_ERROR,
839 ValueTypeToString(Value::TYPE_BOOLEAN));
840 return false;
843 return true;
846 void IncognitoModePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
847 PrefValueMap* prefs) {
848 const Value* availability =
849 policies.GetValue(key::kIncognitoModeAvailability);
850 const Value* deprecated_enabled = policies.GetValue(key::kIncognitoEnabled);
851 if (availability) {
852 int int_value = IncognitoModePrefs::ENABLED;
853 IncognitoModePrefs::Availability availability_enum_value;
854 if (availability->GetAsInteger(&int_value) &&
855 IncognitoModePrefs::IntToAvailability(int_value,
856 &availability_enum_value)) {
857 prefs->SetValue(prefs::kIncognitoModeAvailability,
858 Value::CreateIntegerValue(availability_enum_value));
859 } else {
860 NOTREACHED();
862 } else if (deprecated_enabled) {
863 // If kIncognitoModeAvailability is not specified, check the obsolete
864 // kIncognitoEnabled.
865 bool enabled = true;
866 if (deprecated_enabled->GetAsBoolean(&enabled)) {
867 prefs->SetInteger(prefs::kIncognitoModeAvailability,
868 enabled ? IncognitoModePrefs::ENABLED :
869 IncognitoModePrefs::DISABLED);
870 } else {
871 NOTREACHED();
877 // DefaultSearchEncodingsPolicyHandler implementation --------------------------
879 DefaultSearchEncodingsPolicyHandler::DefaultSearchEncodingsPolicyHandler()
880 : TypeCheckingPolicyHandler(key::kDefaultSearchProviderEncodings,
881 Value::TYPE_LIST) {
884 DefaultSearchEncodingsPolicyHandler::~DefaultSearchEncodingsPolicyHandler() {
887 void DefaultSearchEncodingsPolicyHandler::ApplyPolicySettings(
888 const PolicyMap& policies, PrefValueMap* prefs) {
889 // The DefaultSearchProviderEncodings policy has type list, but the related
890 // preference has type string. Convert one into the other here, using
891 // ';' as a separator.
892 const Value* value = policies.GetValue(policy_name());
893 const ListValue* list;
894 if (!value || !value->GetAsList(&list))
895 return;
897 ListValue::const_iterator iter(list->begin());
898 ListValue::const_iterator end(list->end());
899 std::vector<std::string> string_parts;
900 for (; iter != end; ++iter) {
901 std::string s;
902 if ((*iter)->GetAsString(&s)) {
903 string_parts.push_back(s);
906 std::string encodings = JoinString(string_parts, ';');
907 prefs->SetValue(prefs::kDefaultSearchProviderEncodings,
908 Value::CreateStringValue(encodings));
912 // DefaultSearchPolicyHandler implementation -----------------------------------
914 DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() {
915 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
916 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name;
917 if (policy_name == key::kDefaultSearchProviderEncodings) {
918 handlers_.push_back(new DefaultSearchEncodingsPolicyHandler());
919 } else {
920 handlers_.push_back(
921 new SimplePolicyHandler(policy_name,
922 kDefaultSearchPolicyMap[i].preference_path,
923 kDefaultSearchPolicyMap[i].value_type));
928 DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() {
929 STLDeleteElements(&handlers_);
932 bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
933 PolicyErrorMap* errors) {
934 if (!CheckIndividualPolicies(policies, errors))
935 return false;
937 if (DefaultSearchProviderIsDisabled(policies)) {
938 // Add an error for all specified default search policies except
939 // DefaultSearchProviderEnabled.
940 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
941 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name;
942 if (policy_name != key::kDefaultSearchProviderEnabled &&
943 HasDefaultSearchPolicy(policies, policy_name)) {
944 errors->AddError(policy_name, IDS_POLICY_DEFAULT_SEARCH_DISABLED);
947 return true;
950 const Value* url;
951 std::string dummy;
952 if (DefaultSearchURLIsValid(policies, &url, &dummy) ||
953 !AnyDefaultSearchPoliciesSpecified(policies))
954 return true;
955 errors->AddError(key::kDefaultSearchProviderSearchURL, url ?
956 IDS_POLICY_INVALID_SEARCH_URL_ERROR : IDS_POLICY_NOT_SPECIFIED_ERROR);
957 return false;
960 void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
961 PrefValueMap* prefs) {
962 if (DefaultSearchProviderIsDisabled(policies)) {
963 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, false);
965 // If default search is disabled, the other fields are ignored.
966 prefs->SetString(prefs::kDefaultSearchProviderName, std::string());
967 prefs->SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
968 prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
969 prefs->SetString(prefs::kDefaultSearchProviderIconURL, std::string());
970 prefs->SetString(prefs::kDefaultSearchProviderEncodings, std::string());
971 prefs->SetString(prefs::kDefaultSearchProviderKeyword, std::string());
972 prefs->SetString(prefs::kDefaultSearchProviderInstantURL, std::string());
973 prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, std::string());
974 prefs->SetValue(prefs::kDefaultSearchProviderAlternateURLs,
975 new ListValue());
976 prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey,
977 std::string());
978 prefs->SetString(prefs::kDefaultSearchProviderImageURL, std::string());
979 prefs->SetString(prefs::kDefaultSearchProviderSearchURLPostParams,
980 std::string());
981 prefs->SetString(prefs::kDefaultSearchProviderSuggestURLPostParams,
982 std::string());
983 prefs->SetString(prefs::kDefaultSearchProviderInstantURLPostParams,
984 std::string());
985 prefs->SetString(prefs::kDefaultSearchProviderImageURLPostParams,
986 std::string());
987 } else {
988 // The search URL is required. The other entries are optional. Just make
989 // sure that they are all specified via policy, so that the regular prefs
990 // aren't used.
991 const Value* dummy;
992 std::string url;
993 if (DefaultSearchURLIsValid(policies, &dummy, &url)) {
994 for (std::vector<ConfigurationPolicyHandler*>::const_iterator handler =
995 handlers_.begin(); handler != handlers_.end(); ++handler)
996 (*handler)->ApplyPolicySettings(policies, prefs);
998 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderSuggestURL);
999 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderIconURL);
1000 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderEncodings);
1001 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderKeyword);
1002 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderInstantURL);
1003 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderNewTabURL);
1004 EnsureListPrefExists(prefs, prefs::kDefaultSearchProviderAlternateURLs);
1005 EnsureStringPrefExists(prefs,
1006 prefs::kDefaultSearchProviderSearchTermsReplacementKey);
1007 EnsureStringPrefExists(prefs,
1008 prefs::kDefaultSearchProviderImageURL);
1009 EnsureStringPrefExists(prefs,
1010 prefs::kDefaultSearchProviderSearchURLPostParams);
1011 EnsureStringPrefExists(prefs,
1012 prefs::kDefaultSearchProviderSuggestURLPostParams);
1013 EnsureStringPrefExists(prefs,
1014 prefs::kDefaultSearchProviderInstantURLPostParams);
1015 EnsureStringPrefExists(prefs,
1016 prefs::kDefaultSearchProviderImageURLPostParams);
1018 // For the name and keyword, default to the host if not specified. If
1019 // there is no host (file: URLs? Not sure), use "_" to guarantee that the
1020 // keyword is non-empty.
1021 std::string name, keyword;
1022 std::string host(GURL(url).host());
1023 if (host.empty())
1024 host = "_";
1025 if (!prefs->GetString(prefs::kDefaultSearchProviderName, &name) ||
1026 name.empty())
1027 prefs->SetString(prefs::kDefaultSearchProviderName, host);
1028 if (!prefs->GetString(prefs::kDefaultSearchProviderKeyword, &keyword) ||
1029 keyword.empty())
1030 prefs->SetString(prefs::kDefaultSearchProviderKeyword, host);
1032 // And clear the IDs since these are not specified via policy.
1033 prefs->SetString(prefs::kDefaultSearchProviderID, std::string());
1034 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID,
1035 std::string());
1038 content::NotificationService::current()->Notify(
1039 chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
1040 content::NotificationService::AllSources(),
1041 content::NotificationService::NoDetails());
1044 bool DefaultSearchPolicyHandler::CheckIndividualPolicies(
1045 const PolicyMap& policies,
1046 PolicyErrorMap* errors) {
1047 std::vector<ConfigurationPolicyHandler*>::const_iterator handler;
1048 for (handler = handlers_.begin() ; handler != handlers_.end(); ++handler) {
1049 if (!(*handler)->CheckPolicySettings(policies, errors))
1050 return false;
1052 return true;
1055 bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
1056 const PolicyMap& policies,
1057 const char* policy_name) {
1058 return policies.Get(policy_name) != NULL;
1061 bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified(
1062 const PolicyMap& policies) {
1063 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
1064 if (policies.Get(kDefaultSearchPolicyMap[i].policy_name))
1065 return true;
1067 return false;
1070 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
1071 const PolicyMap& policies) {
1072 const Value* provider_enabled =
1073 policies.GetValue(key::kDefaultSearchProviderEnabled);
1074 bool enabled = true;
1075 return provider_enabled && provider_enabled->GetAsBoolean(&enabled) &&
1076 !enabled;
1079 bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid(
1080 const PolicyMap& policies,
1081 const Value** url_value,
1082 std::string* url_string) {
1083 *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL);
1084 if (!*url_value || !(*url_value)->GetAsString(url_string) ||
1085 url_string->empty())
1086 return false;
1087 TemplateURLData data;
1088 data.SetURL(*url_string);
1089 SearchTermsData search_terms_data;
1090 return TemplateURL(NULL, data).SupportsReplacementUsingTermsData(
1091 search_terms_data);
1094 void DefaultSearchPolicyHandler::EnsureStringPrefExists(
1095 PrefValueMap* prefs,
1096 const std::string& path) {
1097 std::string value;
1098 if (!prefs->GetString(path, &value))
1099 prefs->SetString(path, value);
1102 void DefaultSearchPolicyHandler::EnsureListPrefExists(
1103 PrefValueMap* prefs,
1104 const std::string& path) {
1105 base::Value* value;
1106 base::ListValue* list_value;
1107 if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value))
1108 prefs->SetValue(path, new ListValue());
1112 // ProxyPolicyHandler implementation -------------------------------------------
1114 // The proxy policies have the peculiarity that they are loaded from individual
1115 // policies, but the providers then expose them through a unified
1116 // DictionaryValue. Once Dictionary policies are fully supported, the individual
1117 // proxy policies will be deprecated. http://crbug.com/108996
1119 ProxyPolicyHandler::ProxyPolicyHandler() {
1122 ProxyPolicyHandler::~ProxyPolicyHandler() {
1125 bool ProxyPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
1126 PolicyErrorMap* errors) {
1127 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
1128 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
1129 const Value* server_mode =
1130 GetProxyPolicyValue(policies, key::kProxyServerMode);
1131 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
1132 const Value* bypass_list =
1133 GetProxyPolicyValue(policies, key::kProxyBypassList);
1135 if ((server || pac_url || bypass_list) && !(mode || server_mode)) {
1136 errors->AddError(key::kProxySettings,
1137 key::kProxyMode,
1138 IDS_POLICY_NOT_SPECIFIED_ERROR);
1139 return false;
1142 std::string mode_value;
1143 if (!CheckProxyModeAndServerMode(policies, errors, &mode_value))
1144 return false;
1146 // If neither ProxyMode nor ProxyServerMode are specified, mode_value will be
1147 // empty and the proxy shouldn't be configured at all.
1148 if (mode_value.empty())
1149 return true;
1151 bool is_valid_mode = false;
1152 for (size_t i = 0; i != arraysize(kProxyModeValidationMap); ++i) {
1153 const ProxyModeValidationEntry& entry = kProxyModeValidationMap[i];
1154 if (entry.mode_value != mode_value)
1155 continue;
1157 is_valid_mode = true;
1159 if (!entry.pac_url_allowed && pac_url) {
1160 errors->AddError(key::kProxySettings,
1161 key::kProxyPacUrl,
1162 entry.error_message_id);
1164 if (!entry.bypass_list_allowed && bypass_list) {
1165 errors->AddError(key::kProxySettings,
1166 key::kProxyBypassList,
1167 entry.error_message_id);
1169 if (!entry.server_allowed && server) {
1170 errors->AddError(key::kProxySettings,
1171 key::kProxyServer,
1172 entry.error_message_id);
1175 if ((!entry.pac_url_allowed && pac_url) ||
1176 (!entry.bypass_list_allowed && bypass_list) ||
1177 (!entry.server_allowed && server)) {
1178 return false;
1182 if (!is_valid_mode) {
1183 errors->AddError(key::kProxySettings,
1184 mode ? key::kProxyMode : key::kProxyServerMode,
1185 IDS_POLICY_OUT_OF_RANGE_ERROR,
1186 mode_value);
1187 return false;
1189 return true;
1192 void ProxyPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
1193 PrefValueMap* prefs) {
1194 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
1195 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
1196 const Value* server_mode =
1197 GetProxyPolicyValue(policies, key::kProxyServerMode);
1198 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
1199 const Value* bypass_list =
1200 GetProxyPolicyValue(policies, key::kProxyBypassList);
1202 ProxyPrefs::ProxyMode proxy_mode;
1203 if (mode) {
1204 std::string string_mode;
1205 CHECK(mode->GetAsString(&string_mode));
1206 CHECK(ProxyPrefs::StringToProxyMode(string_mode, &proxy_mode));
1207 } else if (server_mode) {
1208 int int_mode = 0;
1209 CHECK(server_mode->GetAsInteger(&int_mode));
1211 switch (int_mode) {
1212 case PROXY_SERVER_MODE:
1213 proxy_mode = ProxyPrefs::MODE_DIRECT;
1214 break;
1215 case PROXY_AUTO_DETECT_PROXY_SERVER_MODE:
1216 proxy_mode = ProxyPrefs::MODE_AUTO_DETECT;
1217 break;
1218 case PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE:
1219 proxy_mode = ProxyPrefs::MODE_FIXED_SERVERS;
1220 if (pac_url)
1221 proxy_mode = ProxyPrefs::MODE_PAC_SCRIPT;
1222 break;
1223 case PROXY_USE_SYSTEM_PROXY_SERVER_MODE:
1224 proxy_mode = ProxyPrefs::MODE_SYSTEM;
1225 break;
1226 default:
1227 proxy_mode = ProxyPrefs::MODE_DIRECT;
1228 NOTREACHED();
1230 } else {
1231 return;
1234 switch (proxy_mode) {
1235 case ProxyPrefs::MODE_DIRECT:
1236 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateDirect());
1237 break;
1238 case ProxyPrefs::MODE_AUTO_DETECT:
1239 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateAutoDetect());
1240 break;
1241 case ProxyPrefs::MODE_PAC_SCRIPT: {
1242 std::string pac_url_string;
1243 if (pac_url && pac_url->GetAsString(&pac_url_string)) {
1244 prefs->SetValue(prefs::kProxy,
1245 ProxyConfigDictionary::CreatePacScript(pac_url_string, false));
1246 } else {
1247 NOTREACHED();
1249 break;
1251 case ProxyPrefs::MODE_FIXED_SERVERS: {
1252 std::string proxy_server;
1253 std::string bypass_list_string;
1254 if (server->GetAsString(&proxy_server)) {
1255 if (bypass_list)
1256 bypass_list->GetAsString(&bypass_list_string);
1257 prefs->SetValue(prefs::kProxy,
1258 ProxyConfigDictionary::CreateFixedServers(
1259 proxy_server, bypass_list_string));
1261 break;
1263 case ProxyPrefs::MODE_SYSTEM:
1264 prefs->SetValue(prefs::kProxy,
1265 ProxyConfigDictionary::CreateSystem());
1266 break;
1267 case ProxyPrefs::kModeCount:
1268 NOTREACHED();
1272 const Value* ProxyPolicyHandler::GetProxyPolicyValue(
1273 const PolicyMap& policies, const char* policy_name) {
1274 // See note on the ProxyPolicyHandler implementation above.
1275 const Value* value = policies.GetValue(key::kProxySettings);
1276 const DictionaryValue* settings;
1277 if (!value || !value->GetAsDictionary(&settings))
1278 return NULL;
1280 const Value* policy_value = NULL;
1281 std::string tmp;
1282 if (!settings->Get(policy_name, &policy_value) ||
1283 policy_value->IsType(Value::TYPE_NULL) ||
1284 (policy_value->IsType(Value::TYPE_STRING) &&
1285 policy_value->GetAsString(&tmp) &&
1286 tmp.empty())) {
1287 return NULL;
1289 return policy_value;
1292 bool ProxyPolicyHandler::CheckProxyModeAndServerMode(const PolicyMap& policies,
1293 PolicyErrorMap* errors,
1294 std::string* mode_value) {
1295 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
1296 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
1297 const Value* server_mode =
1298 GetProxyPolicyValue(policies, key::kProxyServerMode);
1299 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
1301 // If there's a server mode, convert it into a mode.
1302 // When both are specified, the mode takes precedence.
1303 if (mode) {
1304 if (server_mode) {
1305 errors->AddError(key::kProxySettings,
1306 key::kProxyServerMode,
1307 IDS_POLICY_OVERRIDDEN,
1308 key::kProxyMode);
1310 if (!mode->GetAsString(mode_value)) {
1311 errors->AddError(key::kProxySettings,
1312 key::kProxyMode,
1313 IDS_POLICY_TYPE_ERROR,
1314 ValueTypeToString(Value::TYPE_BOOLEAN));
1315 return false;
1318 ProxyPrefs::ProxyMode mode;
1319 if (!ProxyPrefs::StringToProxyMode(*mode_value, &mode)) {
1320 errors->AddError(key::kProxySettings,
1321 key::kProxyMode,
1322 IDS_POLICY_INVALID_PROXY_MODE_ERROR);
1323 return false;
1326 if (mode == ProxyPrefs::MODE_PAC_SCRIPT && !pac_url) {
1327 errors->AddError(key::kProxySettings,
1328 key::kProxyPacUrl,
1329 IDS_POLICY_NOT_SPECIFIED_ERROR);
1330 return false;
1331 } else if (mode == ProxyPrefs::MODE_FIXED_SERVERS && !server) {
1332 errors->AddError(key::kProxySettings,
1333 key::kProxyServer,
1334 IDS_POLICY_NOT_SPECIFIED_ERROR);
1335 return false;
1337 } else if (server_mode) {
1338 int server_mode_value;
1339 if (!server_mode->GetAsInteger(&server_mode_value)) {
1340 errors->AddError(key::kProxySettings,
1341 key::kProxyServerMode,
1342 IDS_POLICY_TYPE_ERROR,
1343 ValueTypeToString(Value::TYPE_INTEGER));
1344 return false;
1347 switch (server_mode_value) {
1348 case PROXY_SERVER_MODE:
1349 *mode_value = ProxyPrefs::kDirectProxyModeName;
1350 break;
1351 case PROXY_AUTO_DETECT_PROXY_SERVER_MODE:
1352 *mode_value = ProxyPrefs::kAutoDetectProxyModeName;
1353 break;
1354 case PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE:
1355 if (server && pac_url) {
1356 int message_id = IDS_POLICY_PROXY_BOTH_SPECIFIED_ERROR;
1357 errors->AddError(key::kProxySettings,
1358 key::kProxyServer,
1359 message_id);
1360 errors->AddError(key::kProxySettings,
1361 key::kProxyPacUrl,
1362 message_id);
1363 return false;
1365 if (!server && !pac_url) {
1366 int message_id = IDS_POLICY_PROXY_NEITHER_SPECIFIED_ERROR;
1367 errors->AddError(key::kProxySettings,
1368 key::kProxyServer,
1369 message_id);
1370 errors->AddError(key::kProxySettings,
1371 key::kProxyPacUrl,
1372 message_id);
1373 return false;
1375 if (pac_url)
1376 *mode_value = ProxyPrefs::kPacScriptProxyModeName;
1377 else
1378 *mode_value = ProxyPrefs::kFixedServersProxyModeName;
1379 break;
1380 case PROXY_USE_SYSTEM_PROXY_SERVER_MODE:
1381 *mode_value = ProxyPrefs::kSystemProxyModeName;
1382 break;
1383 default:
1384 errors->AddError(key::kProxySettings,
1385 key::kProxyServerMode,
1386 IDS_POLICY_OUT_OF_RANGE_ERROR,
1387 base::IntToString(server_mode_value));
1388 return false;
1391 return true;
1395 // JavascriptPolicyHandler implementation --------------------------------------
1397 JavascriptPolicyHandler::JavascriptPolicyHandler() {
1400 JavascriptPolicyHandler::~JavascriptPolicyHandler() {
1403 bool JavascriptPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
1404 PolicyErrorMap* errors) {
1405 const Value* javascript_enabled = policies.GetValue(key::kJavascriptEnabled);
1406 const Value* default_setting =
1407 policies.GetValue(key::kDefaultJavaScriptSetting);
1409 if (javascript_enabled && !javascript_enabled->IsType(Value::TYPE_BOOLEAN)) {
1410 errors->AddError(key::kJavascriptEnabled,
1411 IDS_POLICY_TYPE_ERROR,
1412 ValueTypeToString(Value::TYPE_BOOLEAN));
1415 if (default_setting && !default_setting->IsType(Value::TYPE_INTEGER)) {
1416 errors->AddError(key::kDefaultJavaScriptSetting,
1417 IDS_POLICY_TYPE_ERROR,
1418 ValueTypeToString(Value::TYPE_INTEGER));
1421 if (javascript_enabled && default_setting) {
1422 errors->AddError(key::kJavascriptEnabled,
1423 IDS_POLICY_OVERRIDDEN,
1424 key::kDefaultJavaScriptSetting);
1427 return true;
1430 void JavascriptPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
1431 PrefValueMap* prefs) {
1432 int setting = CONTENT_SETTING_DEFAULT;
1433 const Value* default_setting =
1434 policies.GetValue(key::kDefaultJavaScriptSetting);
1436 if (default_setting) {
1437 default_setting->GetAsInteger(&setting);
1438 } else {
1439 const Value* javascript_enabled =
1440 policies.GetValue(key::kJavascriptEnabled);
1441 bool enabled = true;
1442 if (javascript_enabled &&
1443 javascript_enabled->GetAsBoolean(&enabled) &&
1444 !enabled) {
1445 setting = CONTENT_SETTING_BLOCK;
1449 if (setting != CONTENT_SETTING_DEFAULT) {
1450 prefs->SetValue(prefs::kManagedDefaultJavaScriptSetting,
1451 Value::CreateIntegerValue(setting));
1455 // URLBlacklistPolicyHandler implementation ------------------------------------
1457 URLBlacklistPolicyHandler::URLBlacklistPolicyHandler() {
1460 URLBlacklistPolicyHandler::~URLBlacklistPolicyHandler() {
1463 bool URLBlacklistPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
1464 PolicyErrorMap* errors) {
1465 const Value* disabled_schemes = policies.GetValue(key::kDisabledSchemes);
1466 const Value* url_blacklist = policies.GetValue(key::kURLBlacklist);
1468 if (disabled_schemes && !disabled_schemes->IsType(Value::TYPE_LIST)) {
1469 errors->AddError(key::kDisabledSchemes,
1470 IDS_POLICY_TYPE_ERROR,
1471 ValueTypeToString(Value::TYPE_LIST));
1474 if (url_blacklist && !url_blacklist->IsType(Value::TYPE_LIST)) {
1475 errors->AddError(key::kURLBlacklist,
1476 IDS_POLICY_TYPE_ERROR,
1477 ValueTypeToString(Value::TYPE_LIST));
1480 return true;
1483 void URLBlacklistPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
1484 PrefValueMap* prefs) {
1485 const base::Value* url_blacklist_policy =
1486 policies.GetValue(key::kURLBlacklist);
1487 const base::ListValue* url_blacklist = NULL;
1488 if (url_blacklist_policy)
1489 url_blacklist_policy->GetAsList(&url_blacklist);
1490 const base::Value* disabled_schemes_policy =
1491 policies.GetValue(key::kDisabledSchemes);
1492 const base::ListValue* disabled_schemes = NULL;
1493 if (disabled_schemes_policy)
1494 disabled_schemes_policy->GetAsList(&disabled_schemes);
1496 scoped_ptr<base::ListValue> merged_url_blacklist(new base::ListValue());
1498 // We start with the DisabledSchemes because we have size limit when
1499 // handling URLBacklists.
1500 if (disabled_schemes_policy) {
1501 for (base::ListValue::const_iterator entry(disabled_schemes->begin());
1502 entry != disabled_schemes->end(); ++entry) {
1503 std::string entry_value;
1504 if ((*entry)->GetAsString(&entry_value)) {
1505 entry_value.append("://*");
1506 merged_url_blacklist->AppendString(entry_value);
1511 if (url_blacklist_policy) {
1512 for (base::ListValue::const_iterator entry(url_blacklist->begin());
1513 entry != url_blacklist->end(); ++entry) {
1514 if ((*entry)->IsType(Value::TYPE_STRING))
1515 merged_url_blacklist->Append((*entry)->DeepCopy());
1519 if (disabled_schemes_policy || url_blacklist_policy)
1520 prefs->SetValue(prefs::kUrlBlacklist, merged_url_blacklist.release());
1523 // RestoreOnStartupPolicyHandler implementation --------------------------------
1525 RestoreOnStartupPolicyHandler::RestoreOnStartupPolicyHandler()
1526 : TypeCheckingPolicyHandler(key::kRestoreOnStartup,
1527 Value::TYPE_INTEGER) {
1530 RestoreOnStartupPolicyHandler::~RestoreOnStartupPolicyHandler() {
1533 void RestoreOnStartupPolicyHandler::ApplyPolicySettings(
1534 const PolicyMap& policies,
1535 PrefValueMap* prefs) {
1536 const Value* restore_on_startup_value = policies.GetValue(policy_name());
1537 if (restore_on_startup_value) {
1538 int restore_on_startup;
1539 if (!restore_on_startup_value->GetAsInteger(&restore_on_startup))
1540 return;
1542 if (restore_on_startup == SessionStartupPref::kPrefValueHomePage)
1543 ApplyPolicySettingsFromHomePage(policies, prefs);
1544 else
1545 prefs->SetInteger(prefs::kRestoreOnStartup, restore_on_startup);
1549 void RestoreOnStartupPolicyHandler::ApplyPolicySettingsFromHomePage(
1550 const PolicyMap& policies,
1551 PrefValueMap* prefs) {
1552 const base::Value* homepage_is_new_tab_page_value =
1553 policies.GetValue(key::kHomepageIsNewTabPage);
1554 if (!homepage_is_new_tab_page_value) {
1555 // The policy is enforcing 'open the homepage on startup' but not
1556 // enforcing what the homepage should be. Don't set any prefs.
1557 return;
1560 bool homepage_is_new_tab_page;
1561 if (!homepage_is_new_tab_page_value->GetAsBoolean(&homepage_is_new_tab_page))
1562 return;
1564 if (homepage_is_new_tab_page) {
1565 prefs->SetInteger(prefs::kRestoreOnStartup,
1566 SessionStartupPref::kPrefValueNewTab);
1567 } else {
1568 const base::Value* homepage_value =
1569 policies.GetValue(key::kHomepageLocation);
1570 if (!homepage_value || !homepage_value->IsType(base::Value::TYPE_STRING)) {
1571 // The policy is enforcing 'open the homepage on startup' but not
1572 // enforcing what the homepage should be. Don't set any prefs.
1573 return;
1575 ListValue* url_list = new ListValue();
1576 url_list->Append(homepage_value->DeepCopy());
1577 prefs->SetInteger(prefs::kRestoreOnStartup,
1578 SessionStartupPref::kPrefValueURLs);
1579 prefs->SetValue(prefs::kURLsToRestoreOnStartup, url_list);
1583 bool RestoreOnStartupPolicyHandler::CheckPolicySettings(
1584 const PolicyMap& policies,
1585 PolicyErrorMap* errors) {
1586 if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies, errors))
1587 return false;
1589 const base::Value* restore_policy = policies.GetValue(key::kRestoreOnStartup);
1591 if (restore_policy) {
1592 int restore_value;
1593 if (restore_policy->GetAsInteger(&restore_value)) {
1594 switch (restore_value) {
1595 case SessionStartupPref::kPrefValueHomePage:
1596 errors->AddError(policy_name(), IDS_POLICY_VALUE_DEPRECATED);
1597 break;
1598 case SessionStartupPref::kPrefValueLast: {
1599 // If the "restore last session" policy is set, session cookies are
1600 // treated as permanent cookies and site data needed to restore the
1601 // session is not cleared so we have to warn the user in that case.
1602 const base::Value* cookies_policy =
1603 policies.GetValue(key::kCookiesSessionOnlyForUrls);
1604 const base::ListValue *cookies_value;
1605 if (cookies_policy && cookies_policy->GetAsList(&cookies_value) &&
1606 !cookies_value->empty()) {
1607 errors->AddError(key::kCookiesSessionOnlyForUrls,
1608 IDS_POLICY_OVERRIDDEN,
1609 key::kRestoreOnStartup);
1612 const base::Value* exit_policy =
1613 policies.GetValue(key::kClearSiteDataOnExit);
1614 bool exit_value;
1615 if (exit_policy &&
1616 exit_policy->GetAsBoolean(&exit_value) && exit_value) {
1617 errors->AddError(key::kClearSiteDataOnExit,
1618 IDS_POLICY_OVERRIDDEN,
1619 key::kRestoreOnStartup);
1621 break;
1623 case SessionStartupPref::kPrefValueURLs:
1624 case SessionStartupPref::kPrefValueNewTab:
1625 // No error
1626 break;
1627 default:
1628 errors->AddError(policy_name(),
1629 IDS_POLICY_OUT_OF_RANGE_ERROR,
1630 base::IntToString(restore_value));
1634 return true;
1637 } // namespace policy