1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/search_engines/default_search_policy_handler.h"
7 #include "base/prefs/pref_value_map.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "components/policy/core/browser/policy_error_map.h"
12 #include "components/policy/core/common/policy_map.h"
13 #include "components/search_engines/default_search_manager.h"
14 #include "components/search_engines/search_engines_pref_names.h"
15 #include "components/search_engines/search_terms_data.h"
16 #include "components/search_engines/template_url.h"
17 #include "grit/components_strings.h"
18 #include "policy/policy_constants.h"
23 // Extracts a list from a policy value and adds it to a pref dictionary.
24 void SetListInPref(const PolicyMap
& policies
,
25 const char* policy_name
,
27 base::DictionaryValue
* dict
) {
29 const base::Value
* policy_value
= policies
.GetValue(policy_name
);
30 const base::ListValue
* policy_list
= NULL
;
32 bool is_list
= policy_value
->GetAsList(&policy_list
);
35 dict
->Set(key
, policy_list
? policy_list
->DeepCopy() : new base::ListValue());
38 // Extracts a string from a policy value and adds it to a pref dictionary.
39 void SetStringInPref(const PolicyMap
& policies
,
40 const char* policy_name
,
42 base::DictionaryValue
* dict
) {
44 const base::Value
* policy_value
= policies
.GetValue(policy_name
);
47 bool is_string
= policy_value
->GetAsString(&str
);
50 dict
->SetString(key
, str
);
55 // List of policy types to preference names, for policies affecting the default
57 const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap
[] = {
58 { key::kDefaultSearchProviderEnabled
,
59 prefs::kDefaultSearchProviderEnabled
,
60 base::Value::TYPE_BOOLEAN
},
61 { key::kDefaultSearchProviderName
,
62 prefs::kDefaultSearchProviderName
,
63 base::Value::TYPE_STRING
},
64 { key::kDefaultSearchProviderKeyword
,
65 prefs::kDefaultSearchProviderKeyword
,
66 base::Value::TYPE_STRING
},
67 { key::kDefaultSearchProviderSearchURL
,
68 prefs::kDefaultSearchProviderSearchURL
,
69 base::Value::TYPE_STRING
},
70 { key::kDefaultSearchProviderSuggestURL
,
71 prefs::kDefaultSearchProviderSuggestURL
,
72 base::Value::TYPE_STRING
},
73 { key::kDefaultSearchProviderInstantURL
,
74 prefs::kDefaultSearchProviderInstantURL
,
75 base::Value::TYPE_STRING
},
76 { key::kDefaultSearchProviderIconURL
,
77 prefs::kDefaultSearchProviderIconURL
,
78 base::Value::TYPE_STRING
},
79 { key::kDefaultSearchProviderEncodings
,
80 prefs::kDefaultSearchProviderEncodings
,
81 base::Value::TYPE_LIST
},
82 { key::kDefaultSearchProviderAlternateURLs
,
83 prefs::kDefaultSearchProviderAlternateURLs
,
84 base::Value::TYPE_LIST
},
85 { key::kDefaultSearchProviderSearchTermsReplacementKey
,
86 prefs::kDefaultSearchProviderSearchTermsReplacementKey
,
87 base::Value::TYPE_STRING
},
88 { key::kDefaultSearchProviderImageURL
,
89 prefs::kDefaultSearchProviderImageURL
,
90 base::Value::TYPE_STRING
},
91 { key::kDefaultSearchProviderNewTabURL
,
92 prefs::kDefaultSearchProviderNewTabURL
,
93 base::Value::TYPE_STRING
},
94 { key::kDefaultSearchProviderSearchURLPostParams
,
95 prefs::kDefaultSearchProviderSearchURLPostParams
,
96 base::Value::TYPE_STRING
},
97 { key::kDefaultSearchProviderSuggestURLPostParams
,
98 prefs::kDefaultSearchProviderSuggestURLPostParams
,
99 base::Value::TYPE_STRING
},
100 { key::kDefaultSearchProviderInstantURLPostParams
,
101 prefs::kDefaultSearchProviderInstantURLPostParams
,
102 base::Value::TYPE_STRING
},
103 { key::kDefaultSearchProviderImageURLPostParams
,
104 prefs::kDefaultSearchProviderImageURLPostParams
,
105 base::Value::TYPE_STRING
},
108 // List of policy types to preference names, for policies affecting the default
110 const PolicyToPreferenceMapEntry kDefaultSearchPolicyDataMap
[] = {
111 {key::kDefaultSearchProviderName
, DefaultSearchManager::kShortName
,
112 base::Value::TYPE_STRING
},
113 {key::kDefaultSearchProviderKeyword
, DefaultSearchManager::kKeyword
,
114 base::Value::TYPE_STRING
},
115 {key::kDefaultSearchProviderSearchURL
, DefaultSearchManager::kURL
,
116 base::Value::TYPE_STRING
},
117 {key::kDefaultSearchProviderSuggestURL
,
118 DefaultSearchManager::kSuggestionsURL
, base::Value::TYPE_STRING
},
119 {key::kDefaultSearchProviderInstantURL
, DefaultSearchManager::kInstantURL
,
120 base::Value::TYPE_STRING
},
121 {key::kDefaultSearchProviderIconURL
, DefaultSearchManager::kFaviconURL
,
122 base::Value::TYPE_STRING
},
123 {key::kDefaultSearchProviderEncodings
,
124 DefaultSearchManager::kInputEncodings
, base::Value::TYPE_LIST
},
125 {key::kDefaultSearchProviderAlternateURLs
,
126 DefaultSearchManager::kAlternateURLs
, base::Value::TYPE_LIST
},
127 {key::kDefaultSearchProviderSearchTermsReplacementKey
,
128 DefaultSearchManager::kSearchTermsReplacementKey
,
129 base::Value::TYPE_STRING
},
130 {key::kDefaultSearchProviderImageURL
, DefaultSearchManager::kImageURL
,
131 base::Value::TYPE_STRING
},
132 {key::kDefaultSearchProviderNewTabURL
, DefaultSearchManager::kNewTabURL
,
133 base::Value::TYPE_STRING
},
134 {key::kDefaultSearchProviderSearchURLPostParams
,
135 DefaultSearchManager::kSearchURLPostParams
, base::Value::TYPE_STRING
},
136 {key::kDefaultSearchProviderSuggestURLPostParams
,
137 DefaultSearchManager::kSuggestionsURLPostParams
, base::Value::TYPE_STRING
},
138 {key::kDefaultSearchProviderInstantURLPostParams
,
139 DefaultSearchManager::kInstantURLPostParams
, base::Value::TYPE_STRING
},
140 {key::kDefaultSearchProviderImageURLPostParams
,
141 DefaultSearchManager::kImageURLPostParams
, base::Value::TYPE_STRING
},
144 // DefaultSearchEncodingsPolicyHandler implementation --------------------------
146 DefaultSearchEncodingsPolicyHandler::DefaultSearchEncodingsPolicyHandler()
147 : TypeCheckingPolicyHandler(key::kDefaultSearchProviderEncodings
,
148 base::Value::TYPE_LIST
) {}
150 DefaultSearchEncodingsPolicyHandler::~DefaultSearchEncodingsPolicyHandler() {
153 void DefaultSearchEncodingsPolicyHandler::ApplyPolicySettings(
154 const PolicyMap
& policies
, PrefValueMap
* prefs
) {
155 // The DefaultSearchProviderEncodings policy has type list, but the related
156 // preference has type string. Convert one into the other here, using
157 // ';' as a separator.
158 const base::Value
* value
= policies
.GetValue(policy_name());
159 const base::ListValue
* list
;
160 if (!value
|| !value
->GetAsList(&list
))
163 base::ListValue::const_iterator
iter(list
->begin());
164 base::ListValue::const_iterator
end(list
->end());
165 std::vector
<std::string
> string_parts
;
166 for (; iter
!= end
; ++iter
) {
168 if ((*iter
)->GetAsString(&s
)) {
169 string_parts
.push_back(s
);
172 std::string encodings
= JoinString(string_parts
, ';');
173 prefs
->SetString(prefs::kDefaultSearchProviderEncodings
, encodings
);
177 // DefaultSearchPolicyHandler implementation -----------------------------------
179 DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() {
180 for (size_t i
= 0; i
< arraysize(kDefaultSearchPolicyMap
); ++i
) {
181 const char* policy_name
= kDefaultSearchPolicyMap
[i
].policy_name
;
182 if (policy_name
== key::kDefaultSearchProviderEncodings
) {
183 handlers_
.push_back(new DefaultSearchEncodingsPolicyHandler());
185 handlers_
.push_back(new SimplePolicyHandler(
187 kDefaultSearchPolicyMap
[i
].preference_path
,
188 kDefaultSearchPolicyMap
[i
].value_type
));
193 DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() {
194 STLDeleteElements(&handlers_
);
197 bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap
& policies
,
198 PolicyErrorMap
* errors
) {
199 if (!CheckIndividualPolicies(policies
, errors
))
202 if (DefaultSearchProviderIsDisabled(policies
)) {
203 // Add an error for all specified default search policies except
204 // DefaultSearchProviderEnabled.
206 for (std::vector
<TypeCheckingPolicyHandler
*>::const_iterator handler
=
208 handler
!= handlers_
.end(); ++handler
) {
209 const char* policy_name
= (*handler
)->policy_name();
210 if (policy_name
!= key::kDefaultSearchProviderEnabled
&&
211 HasDefaultSearchPolicy(policies
, policy_name
)) {
212 errors
->AddError(policy_name
, IDS_POLICY_DEFAULT_SEARCH_DISABLED
);
218 const base::Value
* url
;
220 if (DefaultSearchURLIsValid(policies
, &url
, &dummy
) ||
221 !AnyDefaultSearchPoliciesSpecified(policies
))
223 errors
->AddError(key::kDefaultSearchProviderSearchURL
, url
?
224 IDS_POLICY_INVALID_SEARCH_URL_ERROR
: IDS_POLICY_NOT_SPECIFIED_ERROR
);
228 void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap
& policies
,
229 PrefValueMap
* prefs
) {
230 if (DefaultSearchProviderIsDisabled(policies
)) {
231 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue
);
232 dict
->SetBoolean(DefaultSearchManager::kDisabledByPolicy
, true);
233 DefaultSearchManager::AddPrefValueToMap(dict
.Pass(), prefs
);
237 // The search URL is required. The other entries are optional. Just make
238 // sure that they are all specified via policy, so that the regular prefs
240 const base::Value
* dummy
;
242 if (!DefaultSearchURLIsValid(policies
, &dummy
, &url
))
245 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue
);
246 for (size_t i
= 0; i
< arraysize(kDefaultSearchPolicyDataMap
); ++i
) {
247 const char* policy_name
= kDefaultSearchPolicyDataMap
[i
].policy_name
;
248 switch (kDefaultSearchPolicyDataMap
[i
].value_type
) {
249 case base::Value::TYPE_STRING
:
250 SetStringInPref(policies
,
252 kDefaultSearchPolicyDataMap
[i
].preference_path
,
255 case base::Value::TYPE_LIST
:
256 SetListInPref(policies
,
258 kDefaultSearchPolicyDataMap
[i
].preference_path
,
267 // Set the fields which are not specified by the policy to default values.
268 dict
->SetString(DefaultSearchManager::kID
,
269 base::Int64ToString(kInvalidTemplateURLID
));
270 dict
->SetInteger(DefaultSearchManager::kPrepopulateID
, 0);
271 dict
->SetString(DefaultSearchManager::kSyncGUID
, std::string());
272 dict
->SetString(DefaultSearchManager::kOriginatingURL
, std::string());
273 dict
->SetBoolean(DefaultSearchManager::kSafeForAutoReplace
, true);
274 dict
->SetDouble(DefaultSearchManager::kDateCreated
,
275 base::Time::Now().ToInternalValue());
276 dict
->SetDouble(DefaultSearchManager::kLastModified
,
277 base::Time::Now().ToInternalValue());
278 dict
->SetInteger(DefaultSearchManager::kUsageCount
, 0);
279 dict
->SetBoolean(DefaultSearchManager::kCreatedByPolicy
, true);
281 // For the name and keyword, default to the host if not specified. If
282 // there is no host (as is the case with file URLs of the form:
283 // "file:///c:/..."), use "_" to guarantee that the keyword is non-empty.
284 std::string name
, keyword
;
285 dict
->GetString(DefaultSearchManager::kKeyword
, &keyword
);
286 dict
->GetString(DefaultSearchManager::kShortName
, &name
);
287 dict
->GetString(DefaultSearchManager::kURL
, &url
);
289 std::string
host(GURL(url
).host());
293 dict
->SetString(DefaultSearchManager::kShortName
, host
);
295 dict
->SetString(DefaultSearchManager::kKeyword
, host
);
297 DefaultSearchManager::AddPrefValueToMap(dict
.Pass(), prefs
);
300 bool DefaultSearchPolicyHandler::CheckIndividualPolicies(
301 const PolicyMap
& policies
,
302 PolicyErrorMap
* errors
) {
303 for (std::vector
<TypeCheckingPolicyHandler
*>::const_iterator handler
=
305 handler
!= handlers_
.end(); ++handler
) {
306 if (!(*handler
)->CheckPolicySettings(policies
, errors
))
312 bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
313 const PolicyMap
& policies
,
314 const char* policy_name
) {
315 return policies
.Get(policy_name
) != NULL
;
318 bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified(
319 const PolicyMap
& policies
) {
320 for (std::vector
<TypeCheckingPolicyHandler
*>::const_iterator handler
=
322 handler
!= handlers_
.end(); ++handler
) {
323 if (policies
.Get((*handler
)->policy_name()))
329 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
330 const PolicyMap
& policies
) {
331 const base::Value
* provider_enabled
=
332 policies
.GetValue(key::kDefaultSearchProviderEnabled
);
334 return provider_enabled
&& provider_enabled
->GetAsBoolean(&enabled
) &&
338 bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid(
339 const PolicyMap
& policies
,
340 const base::Value
** url_value
,
341 std::string
* url_string
) {
342 *url_value
= policies
.GetValue(key::kDefaultSearchProviderSearchURL
);
343 if (!*url_value
|| !(*url_value
)->GetAsString(url_string
) ||
346 TemplateURLData data
;
347 data
.SetURL(*url_string
);
348 SearchTermsData search_terms_data
;
349 return TemplateURL(data
).SupportsReplacement(search_terms_data
);
352 void DefaultSearchPolicyHandler::EnsureStringPrefExists(
354 const std::string
& path
) {
356 if (!prefs
->GetString(path
, &value
))
357 prefs
->SetString(path
, value
);
360 void DefaultSearchPolicyHandler::EnsureListPrefExists(
362 const std::string
& path
) {
364 base::ListValue
* list_value
;
365 if (!prefs
->GetValue(path
, &value
) || !value
->GetAsList(&list_value
))
366 prefs
->SetValue(path
, make_scoped_ptr(new base::ListValue()));
369 } // namespace policy