Add policies to control power management on the Chrome OS login screen
[chromium-blink-merge.git] / chrome / browser / policy / configuration_policy_handler.cc
bloba1ba5bb4e40e3612cd182420c0e22a64f2017cf4
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_util.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 },
105 // List of entries determining which proxy policies can be specified, depending
106 // on the ProxyMode.
107 const ProxyModeValidationEntry kProxyModeValidationMap[] = {
108 { ProxyPrefs::kDirectProxyModeName,
109 false, false, false, IDS_POLICY_PROXY_MODE_DISABLED_ERROR },
110 { ProxyPrefs::kAutoDetectProxyModeName,
111 false, false, false, IDS_POLICY_PROXY_MODE_AUTO_DETECT_ERROR },
112 { ProxyPrefs::kPacScriptProxyModeName,
113 true, false, false, IDS_POLICY_PROXY_MODE_PAC_URL_ERROR },
114 { ProxyPrefs::kFixedServersProxyModeName,
115 false, true, true, IDS_POLICY_PROXY_MODE_FIXED_SERVERS_ERROR },
116 { ProxyPrefs::kSystemProxyModeName,
117 false, false, false, IDS_POLICY_PROXY_MODE_SYSTEM_ERROR },
121 // Helper function -------------------------------------------------------------
123 // Utility function that returns a JSON representation of the given |dict| as
124 // a StringValue. The caller owns the returned object.
125 base::StringValue* DictionaryToJSONString(const base::DictionaryValue* dict) {
126 std::string json_string;
127 base::JSONWriter::WriteWithOptions(
128 dict,
129 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE |
130 base::JSONWriter::OPTIONS_PRETTY_PRINT,
131 &json_string);
132 return Value::CreateStringValue(json_string);
136 } // namespace
139 // ConfigurationPolicyHandler implementation -----------------------------------
141 // static
142 std::string ConfigurationPolicyHandler::ValueTypeToString(Value::Type type) {
143 static const char* strings[] = {
144 "null",
145 "boolean",
146 "integer",
147 "double",
148 "string",
149 "binary",
150 "dictionary",
151 "list"
153 CHECK(static_cast<size_t>(type) < arraysize(strings));
154 return std::string(strings[type]);
157 ConfigurationPolicyHandler::ConfigurationPolicyHandler() {
160 ConfigurationPolicyHandler::~ConfigurationPolicyHandler() {
163 void ConfigurationPolicyHandler::PrepareForDisplaying(
164 PolicyMap* policies) const {
165 // jstemplate can't render DictionaryValues/objects. Convert those values to
166 // a string representation.
167 base::DictionaryValue* dict;
168 base::ListValue* list;
169 for (PolicyMap::const_iterator it = policies->begin();
170 it != policies->end(); ++it) {
171 const PolicyMap::Entry& entry = it->second;
172 if (entry.value->GetAsDictionary(&dict)) {
173 base::StringValue* value = DictionaryToJSONString(dict);
174 policies->Set(it->first, entry.level, entry.scope,
175 value, entry.external_data_fetcher ?
176 new ExternalDataFetcher(*entry.external_data_fetcher) :
177 NULL);
178 } else if (entry.value->GetAsList(&list)) {
179 for (size_t i = 0; i < list->GetSize(); ++i) {
180 if (list->GetDictionary(i, &dict)) {
181 list->Set(i, DictionaryToJSONString(dict));
189 // TypeCheckingPolicyHandler implementation ------------------------------------
191 TypeCheckingPolicyHandler::TypeCheckingPolicyHandler(
192 const char* policy_name,
193 Value::Type value_type)
194 : policy_name_(policy_name),
195 value_type_(value_type) {
198 TypeCheckingPolicyHandler::~TypeCheckingPolicyHandler() {
201 const char* TypeCheckingPolicyHandler::policy_name() const {
202 return policy_name_;
205 bool TypeCheckingPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
206 PolicyErrorMap* errors) {
207 const Value* value = NULL;
208 return CheckAndGetValue(policies, errors, &value);
211 bool TypeCheckingPolicyHandler::CheckAndGetValue(const PolicyMap& policies,
212 PolicyErrorMap* errors,
213 const Value** value) {
214 *value = policies.GetValue(policy_name_);
215 if (*value && !(*value)->IsType(value_type_)) {
216 errors->AddError(policy_name_,
217 IDS_POLICY_TYPE_ERROR,
218 ValueTypeToString(value_type_));
219 return false;
221 return true;
224 // IntRangePolicyHandlerBase implementation ------------------------------------
226 IntRangePolicyHandlerBase::IntRangePolicyHandlerBase(
227 const char* policy_name,
228 int min,
229 int max,
230 bool clamp)
231 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_INTEGER),
232 min_(min),
233 max_(max),
234 clamp_(clamp) {
237 bool IntRangePolicyHandlerBase::CheckPolicySettings(const PolicyMap& policies,
238 PolicyErrorMap* errors) {
239 const base::Value* value;
240 return CheckAndGetValue(policies, errors, &value) &&
241 EnsureInRange(value, NULL, errors);
244 IntRangePolicyHandlerBase::~IntRangePolicyHandlerBase() {
247 bool IntRangePolicyHandlerBase::EnsureInRange(const base::Value* input,
248 int* output,
249 PolicyErrorMap* errors) {
250 if (!input)
251 return true;
253 int value;
254 if (!input->GetAsInteger(&value)) {
255 NOTREACHED();
256 return false;
259 if (value < min_ || value > max_) {
260 if (errors) {
261 errors->AddError(policy_name(),
262 IDS_POLICY_OUT_OF_RANGE_ERROR,
263 base::IntToString(value));
266 if (!clamp_)
267 return false;
269 value = std::min(std::max(value, min_), max_);
272 if (output)
273 *output = value;
274 return true;
277 // StringToIntEnumListPolicyHandler implementation -----------------------------
279 StringToIntEnumListPolicyHandler::StringToIntEnumListPolicyHandler(
280 const char* policy_name,
281 const char* pref_path,
282 const MappingEntry* mapping_begin,
283 const MappingEntry* mapping_end)
284 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
285 pref_path_(pref_path),
286 mapping_begin_(mapping_begin),
287 mapping_end_(mapping_end) {}
289 bool StringToIntEnumListPolicyHandler::CheckPolicySettings(
290 const PolicyMap& policies,
291 PolicyErrorMap* errors) {
292 const base::Value* value;
293 return CheckAndGetValue(policies, errors, &value) &&
294 Convert(value, NULL, errors);
297 void StringToIntEnumListPolicyHandler::ApplyPolicySettings(
298 const PolicyMap& policies,
299 PrefValueMap* prefs) {
300 if (!pref_path_)
301 return;
302 const base::Value* value = policies.GetValue(policy_name());
303 scoped_ptr<base::ListValue> list(new base::ListValue());
304 if (value && Convert(value, list.get(), NULL))
305 prefs->SetValue(pref_path_, list.release());
308 bool StringToIntEnumListPolicyHandler::Convert(const base::Value* input,
309 base::ListValue* output,
310 PolicyErrorMap* errors) {
311 if (!input)
312 return true;
314 const base::ListValue* list_value = NULL;
315 if (!input->GetAsList(&list_value)) {
316 NOTREACHED();
317 return false;
320 for (base::ListValue::const_iterator entry(list_value->begin());
321 entry != list_value->end(); ++entry) {
322 std::string entry_value;
323 if (!(*entry)->GetAsString(&entry_value)) {
324 if (errors) {
325 errors->AddError(policy_name(),
326 entry - list_value->begin(),
327 IDS_POLICY_TYPE_ERROR,
328 ValueTypeToString(base::Value::TYPE_STRING));
330 continue;
332 bool found = false;
333 for (const MappingEntry* mapping_entry(mapping_begin_);
334 mapping_entry != mapping_end_; ++mapping_entry) {
335 if (mapping_entry->enum_value == entry_value) {
336 found = true;
337 if (output)
338 output->AppendInteger(mapping_entry->int_value);
339 break;
342 if (!found) {
343 if (errors) {
344 errors->AddError(policy_name(),
345 entry - list_value->begin(),
346 IDS_POLICY_OUT_OF_RANGE_ERROR);
351 return true;
354 // IntRangePolicyHandler implementation ----------------------------------------
356 IntRangePolicyHandler::IntRangePolicyHandler(const char* policy_name,
357 const char* pref_path,
358 int min,
359 int max,
360 bool clamp)
361 : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
362 pref_path_(pref_path) {
365 IntRangePolicyHandler::~IntRangePolicyHandler() {
368 void IntRangePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
369 PrefValueMap* prefs) {
370 if (!pref_path_)
371 return;
372 const base::Value* value = policies.GetValue(policy_name());
373 int value_in_range;
374 if (value && EnsureInRange(value, &value_in_range, NULL)) {
375 prefs->SetValue(pref_path_,
376 base::Value::CreateIntegerValue(value_in_range));
380 // IntPercentageToDoublePolicyHandler implementation ---------------------------
382 IntPercentageToDoublePolicyHandler::IntPercentageToDoublePolicyHandler(
383 const char* policy_name,
384 const char* pref_path,
385 int min,
386 int max,
387 bool clamp)
388 : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
389 pref_path_(pref_path) {
392 IntPercentageToDoublePolicyHandler::~IntPercentageToDoublePolicyHandler() {
395 void IntPercentageToDoublePolicyHandler::ApplyPolicySettings(
396 const PolicyMap& policies,
397 PrefValueMap* prefs) {
398 if (!pref_path_)
399 return;
400 const base::Value* value = policies.GetValue(policy_name());
401 int percentage;
402 if (value && EnsureInRange(value, &percentage, NULL)) {
403 prefs->SetValue(pref_path_, base::Value::CreateDoubleValue(
404 static_cast<double>(percentage) / 100.));
408 // ExtensionListPolicyHandler implementation -----------------------------------
410 ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name,
411 const char* pref_path,
412 bool allow_wildcards)
413 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
414 pref_path_(pref_path),
415 allow_wildcards_(allow_wildcards) {}
417 ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {}
419 bool ExtensionListPolicyHandler::CheckPolicySettings(
420 const PolicyMap& policies,
421 PolicyErrorMap* errors) {
422 return CheckAndGetList(policies, errors, NULL);
425 void ExtensionListPolicyHandler::ApplyPolicySettings(
426 const PolicyMap& policies,
427 PrefValueMap* prefs) {
428 scoped_ptr<base::ListValue> list;
429 PolicyErrorMap errors;
430 if (CheckAndGetList(policies, &errors, &list) && list)
431 prefs->SetValue(pref_path(), list.release());
434 const char* ExtensionListPolicyHandler::pref_path() const {
435 return pref_path_;
438 bool ExtensionListPolicyHandler::CheckAndGetList(
439 const PolicyMap& policies,
440 PolicyErrorMap* errors,
441 scoped_ptr<base::ListValue>* extension_ids) {
442 if (extension_ids)
443 extension_ids->reset();
445 const base::Value* value = NULL;
446 if (!CheckAndGetValue(policies, errors, &value))
447 return false;
449 if (!value)
450 return true;
452 const base::ListValue* list_value = NULL;
453 if (!value->GetAsList(&list_value)) {
454 NOTREACHED();
455 return false;
458 // Filter the list, rejecting any invalid extension IDs.
459 scoped_ptr<base::ListValue> filtered_list(new base::ListValue());
460 for (base::ListValue::const_iterator entry(list_value->begin());
461 entry != list_value->end(); ++entry) {
462 std::string id;
463 if (!(*entry)->GetAsString(&id)) {
464 errors->AddError(policy_name(),
465 entry - list_value->begin(),
466 IDS_POLICY_TYPE_ERROR,
467 ValueTypeToString(base::Value::TYPE_STRING));
468 continue;
470 if (!(allow_wildcards_ && id == "*") &&
471 !extensions::Extension::IdIsValid(id)) {
472 errors->AddError(policy_name(),
473 entry - list_value->begin(),
474 IDS_POLICY_VALUE_FORMAT_ERROR);
475 continue;
477 filtered_list->Append(base::Value::CreateStringValue(id));
480 if (extension_ids)
481 *extension_ids = filtered_list.Pass();
483 return true;
486 // ExtensionInstallForcelistPolicyHandler implementation -----------------------
488 ExtensionInstallForcelistPolicyHandler::
489 ExtensionInstallForcelistPolicyHandler()
490 : TypeCheckingPolicyHandler(key::kExtensionInstallForcelist,
491 base::Value::TYPE_LIST) {}
493 ExtensionInstallForcelistPolicyHandler::
494 ~ExtensionInstallForcelistPolicyHandler() {}
496 bool ExtensionInstallForcelistPolicyHandler::CheckPolicySettings(
497 const PolicyMap& policies,
498 PolicyErrorMap* errors) {
499 const base::Value* value;
500 return CheckAndGetValue(policies, errors, &value) &&
501 ParseList(value, NULL, errors);
504 void ExtensionInstallForcelistPolicyHandler::ApplyPolicySettings(
505 const PolicyMap& policies,
506 PrefValueMap* prefs) {
507 const base::Value* value = NULL;
508 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
509 if (CheckAndGetValue(policies, NULL, &value) &&
510 value &&
511 ParseList(value, dict.get(), NULL)) {
512 prefs->SetValue(prefs::kExtensionInstallForceList, dict.release());
516 bool ExtensionInstallForcelistPolicyHandler::ParseList(
517 const base::Value* policy_value,
518 base::DictionaryValue* extension_dict,
519 PolicyErrorMap* errors) {
520 if (!policy_value)
521 return true;
523 const base::ListValue* policy_list_value = NULL;
524 if (!policy_value->GetAsList(&policy_list_value)) {
525 // This should have been caught in CheckPolicySettings.
526 NOTREACHED();
527 return false;
530 for (base::ListValue::const_iterator entry(policy_list_value->begin());
531 entry != policy_list_value->end(); ++entry) {
532 std::string entry_string;
533 if (!(*entry)->GetAsString(&entry_string)) {
534 if (errors) {
535 errors->AddError(policy_name(),
536 entry - policy_list_value->begin(),
537 IDS_POLICY_TYPE_ERROR,
538 ValueTypeToString(base::Value::TYPE_STRING));
540 continue;
543 // Each string item of the list has the following form:
544 // <extension_id>;<update_url>
545 // Note: The update URL might also contain semicolons.
546 size_t pos = entry_string.find(';');
547 if (pos == std::string::npos) {
548 if (errors) {
549 errors->AddError(policy_name(),
550 entry - policy_list_value->begin(),
551 IDS_POLICY_VALUE_FORMAT_ERROR);
553 continue;
556 std::string extension_id = entry_string.substr(0, pos);
557 std::string update_url = entry_string.substr(pos+1);
558 if (!extensions::Extension::IdIsValid(extension_id) ||
559 !GURL(update_url).is_valid()) {
560 if (errors) {
561 errors->AddError(policy_name(),
562 entry - policy_list_value->begin(),
563 IDS_POLICY_VALUE_FORMAT_ERROR);
565 continue;
568 if (extension_dict) {
569 extensions::ExternalPolicyLoader::AddExtension(
570 extension_dict, extension_id, update_url);
574 return true;
577 // ExtensionURLPatternListPolicyHandler implementation -------------------------
579 ExtensionURLPatternListPolicyHandler::ExtensionURLPatternListPolicyHandler(
580 const char* policy_name,
581 const char* pref_path)
582 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
583 pref_path_(pref_path) {}
585 ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {}
587 bool ExtensionURLPatternListPolicyHandler::CheckPolicySettings(
588 const PolicyMap& policies,
589 PolicyErrorMap* errors) {
590 const base::Value* value = NULL;
591 if (!CheckAndGetValue(policies, errors, &value))
592 return false;
594 if (!value)
595 return true;
597 const base::ListValue* list_value = NULL;
598 if (!value->GetAsList(&list_value)) {
599 NOTREACHED();
600 return false;
603 // Check that the list contains valid URLPattern strings only.
604 for (base::ListValue::const_iterator entry(list_value->begin());
605 entry != list_value->end(); ++entry) {
606 std::string url_pattern_string;
607 if (!(*entry)->GetAsString(&url_pattern_string)) {
608 errors->AddError(policy_name(),
609 entry - list_value->begin(),
610 IDS_POLICY_TYPE_ERROR,
611 ValueTypeToString(base::Value::TYPE_STRING));
612 return false;
615 URLPattern pattern(URLPattern::SCHEME_ALL);
616 if (pattern.Parse(url_pattern_string) != URLPattern::PARSE_SUCCESS) {
617 errors->AddError(policy_name(),
618 entry - list_value->begin(),
619 IDS_POLICY_VALUE_FORMAT_ERROR);
620 return false;
624 return true;
627 void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings(
628 const PolicyMap& policies,
629 PrefValueMap* prefs) {
630 if (!pref_path_)
631 return;
632 const Value* value = policies.GetValue(policy_name());
633 if (value)
634 prefs->SetValue(pref_path_, value->DeepCopy());
637 // SimplePolicyHandler implementation ------------------------------------------
639 SimplePolicyHandler::SimplePolicyHandler(
640 const char* policy_name,
641 const char* pref_path,
642 Value::Type value_type)
643 : TypeCheckingPolicyHandler(policy_name, value_type),
644 pref_path_(pref_path) {
647 SimplePolicyHandler::~SimplePolicyHandler() {
650 void SimplePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
651 PrefValueMap* prefs) {
652 if (!pref_path_)
653 return;
654 const Value* value = policies.GetValue(policy_name());
655 if (value)
656 prefs->SetValue(pref_path_, value->DeepCopy());
660 // SyncPolicyHandler implementation --------------------------------------------
662 SyncPolicyHandler::SyncPolicyHandler()
663 : TypeCheckingPolicyHandler(key::kSyncDisabled,
664 Value::TYPE_BOOLEAN) {
667 SyncPolicyHandler::~SyncPolicyHandler() {
670 void SyncPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
671 PrefValueMap* prefs) {
672 const Value* value = policies.GetValue(policy_name());
673 bool disable_sync;
674 if (value && value->GetAsBoolean(&disable_sync) && disable_sync)
675 prefs->SetValue(prefs::kSyncManaged, value->DeepCopy());
679 // AutofillPolicyHandler implementation ----------------------------------------
681 AutofillPolicyHandler::AutofillPolicyHandler()
682 : TypeCheckingPolicyHandler(key::kAutoFillEnabled,
683 Value::TYPE_BOOLEAN) {
686 AutofillPolicyHandler::~AutofillPolicyHandler() {
689 void AutofillPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
690 PrefValueMap* prefs) {
691 const Value* value = policies.GetValue(policy_name());
692 bool auto_fill_enabled;
693 if (value && value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled) {
694 prefs->SetValue(autofill::prefs::kAutofillEnabled,
695 Value::CreateBooleanValue(false));
699 // Android doesn't support these policies, and doesn't have a policy_path_parser
700 // implementation.
701 #if !defined(OS_ANDROID)
703 // DownloadDirPolicyHandler implementation -------------------------------------
705 DownloadDirPolicyHandler::DownloadDirPolicyHandler()
706 : TypeCheckingPolicyHandler(key::kDownloadDirectory,
707 Value::TYPE_STRING) {
710 DownloadDirPolicyHandler::~DownloadDirPolicyHandler() {
713 void DownloadDirPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
714 PrefValueMap* prefs) {
715 const Value* value = policies.GetValue(policy_name());
716 base::FilePath::StringType string_value;
717 if (!value || !value->GetAsString(&string_value))
718 return;
720 base::FilePath::StringType expanded_value =
721 policy::path_parser::ExpandPathVariables(string_value);
722 // Make sure the path isn't empty, since that will point to an undefined
723 // location; the default location is used instead in that case.
724 // This is checked after path expansion because a non-empty policy value can
725 // lead to an empty path value after expansion (e.g. "\"\"").
726 if (expanded_value.empty())
727 expanded_value = download_util::GetDefaultDownloadDirectory().value();
728 prefs->SetValue(prefs::kDownloadDefaultDirectory,
729 Value::CreateStringValue(expanded_value));
730 prefs->SetValue(prefs::kPromptForDownload,
731 Value::CreateBooleanValue(false));
735 // DiskCacheDirPolicyHandler implementation ------------------------------------
737 DiskCacheDirPolicyHandler::DiskCacheDirPolicyHandler()
738 : TypeCheckingPolicyHandler(key::kDiskCacheDir,
739 Value::TYPE_STRING) {
742 DiskCacheDirPolicyHandler::~DiskCacheDirPolicyHandler() {
745 void DiskCacheDirPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
746 PrefValueMap* prefs) {
747 const Value* value = policies.GetValue(policy_name());
748 base::FilePath::StringType string_value;
749 if (value && value->GetAsString(&string_value)) {
750 base::FilePath::StringType expanded_value =
751 policy::path_parser::ExpandPathVariables(string_value);
752 prefs->SetValue(prefs::kDiskCacheDir,
753 Value::CreateStringValue(expanded_value));
757 #endif // !defined(OS_ANDROID)
759 // FileSelectionDialogsHandler implementation ----------------------------------
761 FileSelectionDialogsHandler::FileSelectionDialogsHandler()
762 : TypeCheckingPolicyHandler(key::kAllowFileSelectionDialogs,
763 Value::TYPE_BOOLEAN) {
766 FileSelectionDialogsHandler::~FileSelectionDialogsHandler() {
769 void FileSelectionDialogsHandler::ApplyPolicySettings(const PolicyMap& policies,
770 PrefValueMap* prefs) {
771 bool allow_dialogs;
772 const Value* value = policies.GetValue(policy_name());
773 if (value && value->GetAsBoolean(&allow_dialogs)) {
774 prefs->SetValue(prefs::kAllowFileSelectionDialogs,
775 Value::CreateBooleanValue(allow_dialogs));
776 // Disallow selecting the download location if file dialogs are disabled.
777 if (!allow_dialogs) {
778 prefs->SetValue(prefs::kPromptForDownload,
779 Value::CreateBooleanValue(false));
785 // IncognitoModePolicyHandler implementation -----------------------------------
787 IncognitoModePolicyHandler::IncognitoModePolicyHandler() {
790 IncognitoModePolicyHandler::~IncognitoModePolicyHandler() {
793 bool IncognitoModePolicyHandler::CheckPolicySettings(const PolicyMap& policies,
794 PolicyErrorMap* errors) {
795 int int_value = IncognitoModePrefs::ENABLED;
796 const Value* availability =
797 policies.GetValue(key::kIncognitoModeAvailability);
799 if (availability) {
800 if (availability->GetAsInteger(&int_value)) {
801 IncognitoModePrefs::Availability availability_enum_value;
802 if (!IncognitoModePrefs::IntToAvailability(int_value,
803 &availability_enum_value)) {
804 errors->AddError(key::kIncognitoModeAvailability,
805 IDS_POLICY_OUT_OF_RANGE_ERROR,
806 base::IntToString(int_value));
807 return false;
809 } else {
810 errors->AddError(key::kIncognitoModeAvailability,
811 IDS_POLICY_TYPE_ERROR,
812 ValueTypeToString(Value::TYPE_INTEGER));
813 return false;
815 } else {
816 const Value* deprecated_enabled = policies.GetValue(key::kIncognitoEnabled);
817 if (deprecated_enabled &&
818 !deprecated_enabled->IsType(Value::TYPE_BOOLEAN)) {
819 errors->AddError(key::kIncognitoEnabled,
820 IDS_POLICY_TYPE_ERROR,
821 ValueTypeToString(Value::TYPE_BOOLEAN));
822 return false;
825 return true;
828 void IncognitoModePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
829 PrefValueMap* prefs) {
830 const Value* availability =
831 policies.GetValue(key::kIncognitoModeAvailability);
832 const Value* deprecated_enabled = policies.GetValue(key::kIncognitoEnabled);
833 if (availability) {
834 int int_value = IncognitoModePrefs::ENABLED;
835 IncognitoModePrefs::Availability availability_enum_value;
836 if (availability->GetAsInteger(&int_value) &&
837 IncognitoModePrefs::IntToAvailability(int_value,
838 &availability_enum_value)) {
839 prefs->SetValue(prefs::kIncognitoModeAvailability,
840 Value::CreateIntegerValue(availability_enum_value));
841 } else {
842 NOTREACHED();
844 } else if (deprecated_enabled) {
845 // If kIncognitoModeAvailability is not specified, check the obsolete
846 // kIncognitoEnabled.
847 bool enabled = true;
848 if (deprecated_enabled->GetAsBoolean(&enabled)) {
849 prefs->SetInteger(prefs::kIncognitoModeAvailability,
850 enabled ? IncognitoModePrefs::ENABLED :
851 IncognitoModePrefs::DISABLED);
852 } else {
853 NOTREACHED();
859 // DefaultSearchEncodingsPolicyHandler implementation --------------------------
861 DefaultSearchEncodingsPolicyHandler::DefaultSearchEncodingsPolicyHandler()
862 : TypeCheckingPolicyHandler(key::kDefaultSearchProviderEncodings,
863 Value::TYPE_LIST) {
866 DefaultSearchEncodingsPolicyHandler::~DefaultSearchEncodingsPolicyHandler() {
869 void DefaultSearchEncodingsPolicyHandler::ApplyPolicySettings(
870 const PolicyMap& policies, PrefValueMap* prefs) {
871 // The DefaultSearchProviderEncodings policy has type list, but the related
872 // preference has type string. Convert one into the other here, using
873 // ';' as a separator.
874 const Value* value = policies.GetValue(policy_name());
875 const ListValue* list;
876 if (!value || !value->GetAsList(&list))
877 return;
879 ListValue::const_iterator iter(list->begin());
880 ListValue::const_iterator end(list->end());
881 std::vector<std::string> string_parts;
882 for (; iter != end; ++iter) {
883 std::string s;
884 if ((*iter)->GetAsString(&s)) {
885 string_parts.push_back(s);
888 std::string encodings = JoinString(string_parts, ';');
889 prefs->SetValue(prefs::kDefaultSearchProviderEncodings,
890 Value::CreateStringValue(encodings));
894 // DefaultSearchPolicyHandler implementation -----------------------------------
896 DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() {
897 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
898 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name;
899 if (policy_name == key::kDefaultSearchProviderEncodings) {
900 handlers_.push_back(new DefaultSearchEncodingsPolicyHandler());
901 } else {
902 handlers_.push_back(
903 new SimplePolicyHandler(policy_name,
904 kDefaultSearchPolicyMap[i].preference_path,
905 kDefaultSearchPolicyMap[i].value_type));
910 DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() {
911 STLDeleteElements(&handlers_);
914 bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
915 PolicyErrorMap* errors) {
916 if (!CheckIndividualPolicies(policies, errors))
917 return false;
919 if (DefaultSearchProviderIsDisabled(policies)) {
920 // Add an error for all specified default search policies except
921 // DefaultSearchProviderEnabled.
922 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
923 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name;
924 if (policy_name != key::kDefaultSearchProviderEnabled &&
925 HasDefaultSearchPolicy(policies, policy_name)) {
926 errors->AddError(policy_name, IDS_POLICY_DEFAULT_SEARCH_DISABLED);
929 return true;
932 const Value* url;
933 std::string dummy;
934 if (DefaultSearchURLIsValid(policies, &url, &dummy) ||
935 !AnyDefaultSearchPoliciesSpecified(policies))
936 return true;
937 errors->AddError(key::kDefaultSearchProviderSearchURL, url ?
938 IDS_POLICY_INVALID_SEARCH_URL_ERROR : IDS_POLICY_NOT_SPECIFIED_ERROR);
939 return false;
942 void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
943 PrefValueMap* prefs) {
944 if (DefaultSearchProviderIsDisabled(policies)) {
945 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, false);
947 // If default search is disabled, the other fields are ignored.
948 prefs->SetString(prefs::kDefaultSearchProviderName, std::string());
949 prefs->SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
950 prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
951 prefs->SetString(prefs::kDefaultSearchProviderIconURL, std::string());
952 prefs->SetString(prefs::kDefaultSearchProviderEncodings, std::string());
953 prefs->SetString(prefs::kDefaultSearchProviderKeyword, std::string());
954 prefs->SetString(prefs::kDefaultSearchProviderInstantURL, std::string());
955 prefs->SetValue(prefs::kDefaultSearchProviderAlternateURLs,
956 new ListValue());
957 prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey,
958 std::string());
959 } else {
960 // The search URL is required. The other entries are optional. Just make
961 // sure that they are all specified via policy, so that the regular prefs
962 // aren't used.
963 const Value* dummy;
964 std::string url;
965 if (DefaultSearchURLIsValid(policies, &dummy, &url)) {
966 for (std::vector<ConfigurationPolicyHandler*>::const_iterator handler =
967 handlers_.begin(); handler != handlers_.end(); ++handler)
968 (*handler)->ApplyPolicySettings(policies, prefs);
970 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderSuggestURL);
971 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderIconURL);
972 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderEncodings);
973 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderKeyword);
974 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderInstantURL);
975 EnsureListPrefExists(prefs, prefs::kDefaultSearchProviderAlternateURLs);
976 EnsureStringPrefExists(prefs,
977 prefs::kDefaultSearchProviderSearchTermsReplacementKey);
979 // For the name and keyword, default to the host if not specified. If
980 // there is no host (file: URLs? Not sure), use "_" to guarantee that the
981 // keyword is non-empty.
982 std::string name, keyword;
983 std::string host(GURL(url).host());
984 if (host.empty())
985 host = "_";
986 if (!prefs->GetString(prefs::kDefaultSearchProviderName, &name) ||
987 name.empty())
988 prefs->SetString(prefs::kDefaultSearchProviderName, host);
989 if (!prefs->GetString(prefs::kDefaultSearchProviderKeyword, &keyword) ||
990 keyword.empty())
991 prefs->SetString(prefs::kDefaultSearchProviderKeyword, host);
993 // And clear the IDs since these are not specified via policy.
994 prefs->SetString(prefs::kDefaultSearchProviderID, std::string());
995 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID,
996 std::string());
999 content::NotificationService::current()->Notify(
1000 chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
1001 content::NotificationService::AllSources(),
1002 content::NotificationService::NoDetails());
1006 bool DefaultSearchPolicyHandler::CheckIndividualPolicies(
1007 const PolicyMap& policies,
1008 PolicyErrorMap* errors) {
1009 std::vector<ConfigurationPolicyHandler*>::const_iterator handler;
1010 for (handler = handlers_.begin() ; handler != handlers_.end(); ++handler) {
1011 if (!(*handler)->CheckPolicySettings(policies, errors))
1012 return false;
1014 return true;
1017 bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
1018 const PolicyMap& policies,
1019 const char* policy_name) {
1020 return policies.Get(policy_name) != NULL;
1023 bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified(
1024 const PolicyMap& policies) {
1025 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
1026 if (policies.Get(kDefaultSearchPolicyMap[i].policy_name))
1027 return true;
1029 return false;
1032 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
1033 const PolicyMap& policies) {
1034 const Value* provider_enabled =
1035 policies.GetValue(key::kDefaultSearchProviderEnabled);
1036 bool enabled = true;
1037 return provider_enabled && provider_enabled->GetAsBoolean(&enabled) &&
1038 !enabled;
1041 bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid(
1042 const PolicyMap& policies,
1043 const Value** url_value,
1044 std::string* url_string) {
1045 *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL);
1046 if (!*url_value || !(*url_value)->GetAsString(url_string) ||
1047 url_string->empty())
1048 return false;
1049 TemplateURLData data;
1050 data.SetURL(*url_string);
1051 SearchTermsData search_terms_data;
1052 return TemplateURL(NULL, data).SupportsReplacementUsingTermsData(
1053 search_terms_data);
1056 void DefaultSearchPolicyHandler::EnsureStringPrefExists(
1057 PrefValueMap* prefs,
1058 const std::string& path) {
1059 std::string value;
1060 if (!prefs->GetString(path, &value))
1061 prefs->SetString(path, value);
1064 void DefaultSearchPolicyHandler::EnsureListPrefExists(
1065 PrefValueMap* prefs,
1066 const std::string& path) {
1067 base::Value* value;
1068 base::ListValue* list_value;
1069 if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value))
1070 prefs->SetValue(path, new ListValue());
1074 // ProxyPolicyHandler implementation -------------------------------------------
1076 // The proxy policies have the peculiarity that they are loaded from individual
1077 // policies, but the providers then expose them through a unified
1078 // DictionaryValue. Once Dictionary policies are fully supported, the individual
1079 // proxy policies will be deprecated. http://crbug.com/108996
1081 ProxyPolicyHandler::ProxyPolicyHandler() {
1084 ProxyPolicyHandler::~ProxyPolicyHandler() {
1087 bool ProxyPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
1088 PolicyErrorMap* errors) {
1089 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
1090 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
1091 const Value* server_mode =
1092 GetProxyPolicyValue(policies, key::kProxyServerMode);
1093 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
1094 const Value* bypass_list =
1095 GetProxyPolicyValue(policies, key::kProxyBypassList);
1097 if ((server || pac_url || bypass_list) && !(mode || server_mode)) {
1098 errors->AddError(key::kProxySettings,
1099 key::kProxyMode,
1100 IDS_POLICY_NOT_SPECIFIED_ERROR);
1101 return false;
1104 std::string mode_value;
1105 if (!CheckProxyModeAndServerMode(policies, errors, &mode_value))
1106 return false;
1108 // If neither ProxyMode nor ProxyServerMode are specified, mode_value will be
1109 // empty and the proxy shouldn't be configured at all.
1110 if (mode_value.empty())
1111 return true;
1113 bool is_valid_mode = false;
1114 for (size_t i = 0; i != arraysize(kProxyModeValidationMap); ++i) {
1115 const ProxyModeValidationEntry& entry = kProxyModeValidationMap[i];
1116 if (entry.mode_value != mode_value)
1117 continue;
1119 is_valid_mode = true;
1121 if (!entry.pac_url_allowed && pac_url) {
1122 errors->AddError(key::kProxySettings,
1123 key::kProxyPacUrl,
1124 entry.error_message_id);
1126 if (!entry.bypass_list_allowed && bypass_list) {
1127 errors->AddError(key::kProxySettings,
1128 key::kProxyBypassList,
1129 entry.error_message_id);
1131 if (!entry.server_allowed && server) {
1132 errors->AddError(key::kProxySettings,
1133 key::kProxyServer,
1134 entry.error_message_id);
1137 if ((!entry.pac_url_allowed && pac_url) ||
1138 (!entry.bypass_list_allowed && bypass_list) ||
1139 (!entry.server_allowed && server)) {
1140 return false;
1144 if (!is_valid_mode) {
1145 errors->AddError(key::kProxySettings,
1146 mode ? key::kProxyMode : key::kProxyServerMode,
1147 IDS_POLICY_OUT_OF_RANGE_ERROR,
1148 mode_value);
1149 return false;
1151 return true;
1154 void ProxyPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
1155 PrefValueMap* prefs) {
1156 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
1157 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
1158 const Value* server_mode =
1159 GetProxyPolicyValue(policies, key::kProxyServerMode);
1160 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
1161 const Value* bypass_list =
1162 GetProxyPolicyValue(policies, key::kProxyBypassList);
1164 ProxyPrefs::ProxyMode proxy_mode;
1165 if (mode) {
1166 std::string string_mode;
1167 CHECK(mode->GetAsString(&string_mode));
1168 CHECK(ProxyPrefs::StringToProxyMode(string_mode, &proxy_mode));
1169 } else if (server_mode) {
1170 int int_mode = 0;
1171 CHECK(server_mode->GetAsInteger(&int_mode));
1173 switch (int_mode) {
1174 case PROXY_SERVER_MODE:
1175 proxy_mode = ProxyPrefs::MODE_DIRECT;
1176 break;
1177 case PROXY_AUTO_DETECT_PROXY_SERVER_MODE:
1178 proxy_mode = ProxyPrefs::MODE_AUTO_DETECT;
1179 break;
1180 case PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE:
1181 proxy_mode = ProxyPrefs::MODE_FIXED_SERVERS;
1182 if (pac_url)
1183 proxy_mode = ProxyPrefs::MODE_PAC_SCRIPT;
1184 break;
1185 case PROXY_USE_SYSTEM_PROXY_SERVER_MODE:
1186 proxy_mode = ProxyPrefs::MODE_SYSTEM;
1187 break;
1188 default:
1189 proxy_mode = ProxyPrefs::MODE_DIRECT;
1190 NOTREACHED();
1192 } else {
1193 return;
1196 switch (proxy_mode) {
1197 case ProxyPrefs::MODE_DIRECT:
1198 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateDirect());
1199 break;
1200 case ProxyPrefs::MODE_AUTO_DETECT:
1201 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateAutoDetect());
1202 break;
1203 case ProxyPrefs::MODE_PAC_SCRIPT: {
1204 std::string pac_url_string;
1205 if (pac_url && pac_url->GetAsString(&pac_url_string)) {
1206 prefs->SetValue(prefs::kProxy,
1207 ProxyConfigDictionary::CreatePacScript(pac_url_string, false));
1208 } else {
1209 NOTREACHED();
1211 break;
1213 case ProxyPrefs::MODE_FIXED_SERVERS: {
1214 std::string proxy_server;
1215 std::string bypass_list_string;
1216 if (server->GetAsString(&proxy_server)) {
1217 if (bypass_list)
1218 bypass_list->GetAsString(&bypass_list_string);
1219 prefs->SetValue(prefs::kProxy,
1220 ProxyConfigDictionary::CreateFixedServers(
1221 proxy_server, bypass_list_string));
1223 break;
1225 case ProxyPrefs::MODE_SYSTEM:
1226 prefs->SetValue(prefs::kProxy,
1227 ProxyConfigDictionary::CreateSystem());
1228 break;
1229 case ProxyPrefs::kModeCount:
1230 NOTREACHED();
1234 const Value* ProxyPolicyHandler::GetProxyPolicyValue(
1235 const PolicyMap& policies, const char* policy_name) {
1236 // See note on the ProxyPolicyHandler implementation above.
1237 const Value* value = policies.GetValue(key::kProxySettings);
1238 const DictionaryValue* settings;
1239 if (!value || !value->GetAsDictionary(&settings))
1240 return NULL;
1242 const Value* policy_value = NULL;
1243 std::string tmp;
1244 if (!settings->Get(policy_name, &policy_value) ||
1245 policy_value->IsType(Value::TYPE_NULL) ||
1246 (policy_value->IsType(Value::TYPE_STRING) &&
1247 policy_value->GetAsString(&tmp) &&
1248 tmp.empty())) {
1249 return NULL;
1251 return policy_value;
1254 bool ProxyPolicyHandler::CheckProxyModeAndServerMode(const PolicyMap& policies,
1255 PolicyErrorMap* errors,
1256 std::string* mode_value) {
1257 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
1258 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
1259 const Value* server_mode =
1260 GetProxyPolicyValue(policies, key::kProxyServerMode);
1261 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
1263 // If there's a server mode, convert it into a mode.
1264 // When both are specified, the mode takes precedence.
1265 if (mode) {
1266 if (server_mode) {
1267 errors->AddError(key::kProxySettings,
1268 key::kProxyServerMode,
1269 IDS_POLICY_OVERRIDDEN,
1270 key::kProxyMode);
1272 if (!mode->GetAsString(mode_value)) {
1273 errors->AddError(key::kProxySettings,
1274 key::kProxyMode,
1275 IDS_POLICY_TYPE_ERROR,
1276 ValueTypeToString(Value::TYPE_BOOLEAN));
1277 return false;
1280 ProxyPrefs::ProxyMode mode;
1281 if (!ProxyPrefs::StringToProxyMode(*mode_value, &mode)) {
1282 errors->AddError(key::kProxySettings,
1283 key::kProxyMode,
1284 IDS_POLICY_INVALID_PROXY_MODE_ERROR);
1285 return false;
1288 if (mode == ProxyPrefs::MODE_PAC_SCRIPT && !pac_url) {
1289 errors->AddError(key::kProxySettings,
1290 key::kProxyPacUrl,
1291 IDS_POLICY_NOT_SPECIFIED_ERROR);
1292 return false;
1293 } else if (mode == ProxyPrefs::MODE_FIXED_SERVERS && !server) {
1294 errors->AddError(key::kProxySettings,
1295 key::kProxyServer,
1296 IDS_POLICY_NOT_SPECIFIED_ERROR);
1297 return false;
1299 } else if (server_mode) {
1300 int server_mode_value;
1301 if (!server_mode->GetAsInteger(&server_mode_value)) {
1302 errors->AddError(key::kProxySettings,
1303 key::kProxyServerMode,
1304 IDS_POLICY_TYPE_ERROR,
1305 ValueTypeToString(Value::TYPE_INTEGER));
1306 return false;
1309 switch (server_mode_value) {
1310 case PROXY_SERVER_MODE:
1311 *mode_value = ProxyPrefs::kDirectProxyModeName;
1312 break;
1313 case PROXY_AUTO_DETECT_PROXY_SERVER_MODE:
1314 *mode_value = ProxyPrefs::kAutoDetectProxyModeName;
1315 break;
1316 case PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE:
1317 if (server && pac_url) {
1318 int message_id = IDS_POLICY_PROXY_BOTH_SPECIFIED_ERROR;
1319 errors->AddError(key::kProxySettings,
1320 key::kProxyServer,
1321 message_id);
1322 errors->AddError(key::kProxySettings,
1323 key::kProxyPacUrl,
1324 message_id);
1325 return false;
1327 if (!server && !pac_url) {
1328 int message_id = IDS_POLICY_PROXY_NEITHER_SPECIFIED_ERROR;
1329 errors->AddError(key::kProxySettings,
1330 key::kProxyServer,
1331 message_id);
1332 errors->AddError(key::kProxySettings,
1333 key::kProxyPacUrl,
1334 message_id);
1335 return false;
1337 if (pac_url)
1338 *mode_value = ProxyPrefs::kPacScriptProxyModeName;
1339 else
1340 *mode_value = ProxyPrefs::kFixedServersProxyModeName;
1341 break;
1342 case PROXY_USE_SYSTEM_PROXY_SERVER_MODE:
1343 *mode_value = ProxyPrefs::kSystemProxyModeName;
1344 break;
1345 default:
1346 errors->AddError(key::kProxySettings,
1347 key::kProxyServerMode,
1348 IDS_POLICY_OUT_OF_RANGE_ERROR,
1349 base::IntToString(server_mode_value));
1350 return false;
1353 return true;
1357 // JavascriptPolicyHandler implementation --------------------------------------
1359 JavascriptPolicyHandler::JavascriptPolicyHandler() {
1362 JavascriptPolicyHandler::~JavascriptPolicyHandler() {
1365 bool JavascriptPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
1366 PolicyErrorMap* errors) {
1367 const Value* javascript_enabled = policies.GetValue(key::kJavascriptEnabled);
1368 const Value* default_setting =
1369 policies.GetValue(key::kDefaultJavaScriptSetting);
1371 if (javascript_enabled && !javascript_enabled->IsType(Value::TYPE_BOOLEAN)) {
1372 errors->AddError(key::kJavascriptEnabled,
1373 IDS_POLICY_TYPE_ERROR,
1374 ValueTypeToString(Value::TYPE_BOOLEAN));
1377 if (default_setting && !default_setting->IsType(Value::TYPE_INTEGER)) {
1378 errors->AddError(key::kDefaultJavaScriptSetting,
1379 IDS_POLICY_TYPE_ERROR,
1380 ValueTypeToString(Value::TYPE_INTEGER));
1383 if (javascript_enabled && default_setting) {
1384 errors->AddError(key::kJavascriptEnabled,
1385 IDS_POLICY_OVERRIDDEN,
1386 key::kDefaultJavaScriptSetting);
1389 return true;
1392 void JavascriptPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
1393 PrefValueMap* prefs) {
1394 int setting = CONTENT_SETTING_DEFAULT;
1395 const Value* default_setting =
1396 policies.GetValue(key::kDefaultJavaScriptSetting);
1398 if (default_setting) {
1399 default_setting->GetAsInteger(&setting);
1400 } else {
1401 const Value* javascript_enabled =
1402 policies.GetValue(key::kJavascriptEnabled);
1403 bool enabled = true;
1404 if (javascript_enabled &&
1405 javascript_enabled->GetAsBoolean(&enabled) &&
1406 !enabled) {
1407 setting = CONTENT_SETTING_BLOCK;
1411 if (setting != CONTENT_SETTING_DEFAULT) {
1412 prefs->SetValue(prefs::kManagedDefaultJavaScriptSetting,
1413 Value::CreateIntegerValue(setting));
1417 // URLBlacklistPolicyHandler implementation ------------------------------------
1419 URLBlacklistPolicyHandler::URLBlacklistPolicyHandler() {
1422 URLBlacklistPolicyHandler::~URLBlacklistPolicyHandler() {
1425 bool URLBlacklistPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
1426 PolicyErrorMap* errors) {
1427 const Value* disabled_schemes = policies.GetValue(key::kDisabledSchemes);
1428 const Value* url_blacklist = policies.GetValue(key::kURLBlacklist);
1430 if (disabled_schemes && !disabled_schemes->IsType(Value::TYPE_LIST)) {
1431 errors->AddError(key::kDisabledSchemes,
1432 IDS_POLICY_TYPE_ERROR,
1433 ValueTypeToString(Value::TYPE_LIST));
1436 if (url_blacklist && !url_blacklist->IsType(Value::TYPE_LIST)) {
1437 errors->AddError(key::kURLBlacklist,
1438 IDS_POLICY_TYPE_ERROR,
1439 ValueTypeToString(Value::TYPE_LIST));
1442 return true;
1445 void URLBlacklistPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
1446 PrefValueMap* prefs) {
1447 const base::Value* url_blacklist_policy =
1448 policies.GetValue(key::kURLBlacklist);
1449 const base::ListValue* url_blacklist = NULL;
1450 if (url_blacklist_policy)
1451 url_blacklist_policy->GetAsList(&url_blacklist);
1452 const base::Value* disabled_schemes_policy =
1453 policies.GetValue(key::kDisabledSchemes);
1454 const base::ListValue* disabled_schemes = NULL;
1455 if (disabled_schemes_policy)
1456 disabled_schemes_policy->GetAsList(&disabled_schemes);
1458 scoped_ptr<base::ListValue> merged_url_blacklist(new base::ListValue());
1460 // We start with the DisabledSchemes because we have size limit when
1461 // handling URLBacklists.
1462 if (disabled_schemes_policy) {
1463 for (base::ListValue::const_iterator entry(disabled_schemes->begin());
1464 entry != disabled_schemes->end(); ++entry) {
1465 std::string entry_value;
1466 if ((*entry)->GetAsString(&entry_value)) {
1467 entry_value.append("://*");
1468 merged_url_blacklist->AppendString(entry_value);
1473 if (url_blacklist_policy) {
1474 for (base::ListValue::const_iterator entry(url_blacklist->begin());
1475 entry != url_blacklist->end(); ++entry) {
1476 if ((*entry)->IsType(Value::TYPE_STRING))
1477 merged_url_blacklist->Append((*entry)->DeepCopy());
1481 if (disabled_schemes_policy || url_blacklist_policy)
1482 prefs->SetValue(prefs::kUrlBlacklist, merged_url_blacklist.release());
1485 // RestoreOnStartupPolicyHandler implementation --------------------------------
1487 RestoreOnStartupPolicyHandler::RestoreOnStartupPolicyHandler()
1488 : TypeCheckingPolicyHandler(key::kRestoreOnStartup,
1489 Value::TYPE_INTEGER) {
1492 RestoreOnStartupPolicyHandler::~RestoreOnStartupPolicyHandler() {
1495 void RestoreOnStartupPolicyHandler::ApplyPolicySettings(
1496 const PolicyMap& policies,
1497 PrefValueMap* prefs) {
1498 const Value* restore_on_startup_value = policies.GetValue(policy_name());
1499 if (restore_on_startup_value) {
1500 int restore_on_startup;
1501 if (!restore_on_startup_value->GetAsInteger(&restore_on_startup))
1502 return;
1504 if (restore_on_startup == SessionStartupPref::kPrefValueHomePage)
1505 ApplyPolicySettingsFromHomePage(policies, prefs);
1506 else
1507 prefs->SetInteger(prefs::kRestoreOnStartup, restore_on_startup);
1511 void RestoreOnStartupPolicyHandler::ApplyPolicySettingsFromHomePage(
1512 const PolicyMap& policies,
1513 PrefValueMap* prefs) {
1514 const base::Value* homepage_is_new_tab_page_value =
1515 policies.GetValue(key::kHomepageIsNewTabPage);
1516 if (!homepage_is_new_tab_page_value) {
1517 // The policy is enforcing 'open the homepage on startup' but not
1518 // enforcing what the homepage should be. Don't set any prefs.
1519 return;
1522 bool homepage_is_new_tab_page;
1523 if (!homepage_is_new_tab_page_value->GetAsBoolean(&homepage_is_new_tab_page))
1524 return;
1526 if (homepage_is_new_tab_page) {
1527 prefs->SetInteger(prefs::kRestoreOnStartup,
1528 SessionStartupPref::kPrefValueNewTab);
1529 } else {
1530 const base::Value* homepage_value =
1531 policies.GetValue(key::kHomepageLocation);
1532 if (!homepage_value || !homepage_value->IsType(base::Value::TYPE_STRING)) {
1533 // The policy is enforcing 'open the homepage on startup' but not
1534 // enforcing what the homepage should be. Don't set any prefs.
1535 return;
1537 ListValue* url_list = new ListValue();
1538 url_list->Append(homepage_value->DeepCopy());
1539 prefs->SetInteger(prefs::kRestoreOnStartup,
1540 SessionStartupPref::kPrefValueURLs);
1541 prefs->SetValue(prefs::kURLsToRestoreOnStartup, url_list);
1545 bool RestoreOnStartupPolicyHandler::CheckPolicySettings(
1546 const PolicyMap& policies,
1547 PolicyErrorMap* errors) {
1548 if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies, errors))
1549 return false;
1551 const base::Value* restore_policy = policies.GetValue(key::kRestoreOnStartup);
1553 if (restore_policy) {
1554 int restore_value;
1555 if (restore_policy->GetAsInteger(&restore_value)) {
1556 switch (restore_value) {
1557 case SessionStartupPref::kPrefValueHomePage:
1558 errors->AddError(policy_name(), IDS_POLICY_VALUE_DEPRECATED);
1559 break;
1560 case SessionStartupPref::kPrefValueLast: {
1561 // If the "restore last session" policy is set, session cookies are
1562 // treated as permanent cookies and site data needed to restore the
1563 // session is not cleared so we have to warn the user in that case.
1564 const base::Value* cookies_policy =
1565 policies.GetValue(key::kCookiesSessionOnlyForUrls);
1566 const base::ListValue *cookies_value;
1567 if (cookies_policy && cookies_policy->GetAsList(&cookies_value) &&
1568 !cookies_value->empty()) {
1569 errors->AddError(key::kCookiesSessionOnlyForUrls,
1570 IDS_POLICY_OVERRIDDEN,
1571 key::kRestoreOnStartup);
1574 const base::Value* exit_policy =
1575 policies.GetValue(key::kClearSiteDataOnExit);
1576 bool exit_value;
1577 if (exit_policy &&
1578 exit_policy->GetAsBoolean(&exit_value) && exit_value) {
1579 errors->AddError(key::kClearSiteDataOnExit,
1580 IDS_POLICY_OVERRIDDEN,
1581 key::kRestoreOnStartup);
1583 break;
1585 case SessionStartupPref::kPrefValueURLs:
1586 case SessionStartupPref::kPrefValueNewTab:
1587 // No error
1588 break;
1589 default:
1590 errors->AddError(policy_name(),
1591 IDS_POLICY_OUT_OF_RANGE_ERROR,
1592 base::IntToString(restore_value));
1596 return true;
1599 } // namespace policy