OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/search_engines/default_search_policy_handler.h" | |
6 | |
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 "chrome/browser/search_engines/default_search_manager.h" | |
12 #include "components/policy/core/browser/policy_error_map.h" | |
13 #include "components/policy/core/common/policy_map.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" | |
19 | |
20 namespace policy { | |
21 | |
22 namespace { | |
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, | |
26 const char* key, | |
27 base::DictionaryValue* dict) { | |
28 DCHECK(dict); | |
29 const base::Value* policy_value = policies.GetValue(policy_name); | |
30 const base::ListValue* policy_list = NULL; | |
31 if (policy_value) { | |
32 bool is_list = policy_value->GetAsList(&policy_list); | |
33 DCHECK(is_list); | |
34 } | |
35 dict->Set(key, policy_list ? policy_list->DeepCopy() : new base::ListValue()); | |
36 } | |
37 | |
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, | |
41 const char* key, | |
42 base::DictionaryValue* dict) { | |
43 DCHECK(dict); | |
44 const base::Value* policy_value = policies.GetValue(policy_name); | |
45 std::string str; | |
46 if (policy_value) { | |
47 bool is_string = policy_value->GetAsString(&str); | |
48 DCHECK(is_string); | |
49 } | |
50 dict->SetString(key, str); | |
51 } | |
52 | |
53 } // namespace | |
54 | |
55 // List of policy types to preference names, for policies affecting the default | |
56 // search provider. | |
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 }, | |
106 }; | |
107 | |
108 // List of policy types to preference names, for policies affecting the default | |
109 // search provider. | |
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}, | |
142 }; | |
143 | |
144 // DefaultSearchEncodingsPolicyHandler implementation -------------------------- | |
145 | |
146 DefaultSearchEncodingsPolicyHandler::DefaultSearchEncodingsPolicyHandler() | |
147 : TypeCheckingPolicyHandler(key::kDefaultSearchProviderEncodings, | |
148 base::Value::TYPE_LIST) {} | |
149 | |
150 DefaultSearchEncodingsPolicyHandler::~DefaultSearchEncodingsPolicyHandler() { | |
151 } | |
152 | |
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)) | |
161 return; | |
162 | |
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) { | |
167 std::string s; | |
168 if ((*iter)->GetAsString(&s)) { | |
169 string_parts.push_back(s); | |
170 } | |
171 } | |
172 std::string encodings = JoinString(string_parts, ';'); | |
173 prefs->SetValue(prefs::kDefaultSearchProviderEncodings, | |
174 base::Value::CreateStringValue(encodings)); | |
175 } | |
176 | |
177 | |
178 // DefaultSearchPolicyHandler implementation ----------------------------------- | |
179 | |
180 DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() { | |
181 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) { | |
182 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name; | |
183 if (policy_name == key::kDefaultSearchProviderEncodings) { | |
184 handlers_.push_back(new DefaultSearchEncodingsPolicyHandler()); | |
185 } else { | |
186 handlers_.push_back(new SimplePolicyHandler( | |
187 policy_name, | |
188 kDefaultSearchPolicyMap[i].preference_path, | |
189 kDefaultSearchPolicyMap[i].value_type)); | |
190 } | |
191 } | |
192 } | |
193 | |
194 DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() { | |
195 STLDeleteElements(&handlers_); | |
196 } | |
197 | |
198 bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies, | |
199 PolicyErrorMap* errors) { | |
200 if (!CheckIndividualPolicies(policies, errors)) | |
201 return false; | |
202 | |
203 if (DefaultSearchProviderIsDisabled(policies)) { | |
204 // Add an error for all specified default search policies except | |
205 // DefaultSearchProviderEnabled. | |
206 | |
207 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler = | |
208 handlers_.begin(); | |
209 handler != handlers_.end(); ++handler) { | |
210 const char* policy_name = (*handler)->policy_name(); | |
211 if (policy_name != key::kDefaultSearchProviderEnabled && | |
212 HasDefaultSearchPolicy(policies, policy_name)) { | |
213 errors->AddError(policy_name, IDS_POLICY_DEFAULT_SEARCH_DISABLED); | |
214 } | |
215 } | |
216 return true; | |
217 } | |
218 | |
219 const base::Value* url; | |
220 std::string dummy; | |
221 if (DefaultSearchURLIsValid(policies, &url, &dummy) || | |
222 !AnyDefaultSearchPoliciesSpecified(policies)) | |
223 return true; | |
224 errors->AddError(key::kDefaultSearchProviderSearchURL, url ? | |
225 IDS_POLICY_INVALID_SEARCH_URL_ERROR : IDS_POLICY_NOT_SPECIFIED_ERROR); | |
226 return false; | |
227 } | |
228 | |
229 void DefaultSearchPolicyHandler::HandleDictionaryPref(const PolicyMap& policies, | |
230 PrefValueMap* prefs) { | |
231 if (DefaultSearchProviderIsDisabled(policies)) { | |
232 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); | |
233 dict->SetBoolean(DefaultSearchManager::kDisabledByPolicy, true); | |
234 DefaultSearchManager::AddPrefValueToMap(dict.release(), prefs); | |
235 return; | |
236 } | |
237 | |
238 // The search URL is required. The other entries are optional. Just make | |
239 // sure that they are all specified via policy, so that the regular prefs | |
240 // aren't used. | |
241 const base::Value* dummy; | |
242 std::string url; | |
243 if (!DefaultSearchURLIsValid(policies, &dummy, &url)) | |
244 return; | |
245 | |
246 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); | |
247 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyDataMap); ++i) { | |
248 const char* policy_name = kDefaultSearchPolicyDataMap[i].policy_name; | |
249 switch (kDefaultSearchPolicyDataMap[i].value_type) { | |
250 case base::Value::TYPE_STRING: | |
251 SetStringInPref(policies, | |
252 policy_name, | |
253 kDefaultSearchPolicyDataMap[i].preference_path, | |
254 dict.get()); | |
255 break; | |
256 case base::Value::TYPE_LIST: | |
257 SetListInPref(policies, | |
258 policy_name, | |
259 kDefaultSearchPolicyDataMap[i].preference_path, | |
260 dict.get()); | |
261 break; | |
262 default: | |
263 NOTREACHED(); | |
264 break; | |
265 } | |
266 } | |
267 | |
268 // Set the fields which are not specified by the policy to default values. | |
269 dict->SetString(DefaultSearchManager::kID, | |
270 base::Int64ToString(kInvalidTemplateURLID)); | |
271 dict->SetInteger(DefaultSearchManager::kPrepopulateID, 0); | |
272 dict->SetString(DefaultSearchManager::kSyncGUID, std::string()); | |
273 dict->SetString(DefaultSearchManager::kOriginatingURL, std::string()); | |
274 dict->SetBoolean(DefaultSearchManager::kSafeForAutoReplace, true); | |
275 dict->SetDouble(DefaultSearchManager::kDateCreated, | |
276 base::Time::Now().ToInternalValue()); | |
277 dict->SetDouble(DefaultSearchManager::kLastModified, | |
278 base::Time::Now().ToInternalValue()); | |
279 dict->SetInteger(DefaultSearchManager::kUsageCount, 0); | |
280 dict->SetBoolean(DefaultSearchManager::kCreatedByPolicy, true); | |
281 | |
282 // For the name and keyword, default to the host if not specified. If | |
283 // there is no host (as is the case with file URLs of the form: | |
284 // "file:///c:/..."), use "_" to guarantee that the keyword is non-empty. | |
285 std::string name, keyword; | |
286 dict->GetString(DefaultSearchManager::kKeyword, &keyword); | |
287 dict->GetString(DefaultSearchManager::kShortName, &name); | |
288 dict->GetString(DefaultSearchManager::kURL, &url); | |
289 | |
290 std::string host(GURL(url).host()); | |
291 if (host.empty()) | |
292 host = "_"; | |
293 if (name.empty()) | |
294 dict->SetString(DefaultSearchManager::kShortName, host); | |
295 if (keyword.empty()) | |
296 dict->SetString(DefaultSearchManager::kKeyword, host); | |
297 | |
298 DefaultSearchManager::AddPrefValueToMap(dict.release(), prefs); | |
299 } | |
300 | |
301 void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, | |
302 PrefValueMap* prefs) { | |
303 HandleDictionaryPref(policies, prefs); | |
304 | |
305 if (DefaultSearchProviderIsDisabled(policies)) { | |
306 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, false); | |
307 | |
308 // If default search is disabled, the other fields are ignored. | |
309 prefs->SetString(prefs::kDefaultSearchProviderName, std::string()); | |
310 prefs->SetString(prefs::kDefaultSearchProviderSearchURL, std::string()); | |
311 prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string()); | |
312 prefs->SetString(prefs::kDefaultSearchProviderIconURL, std::string()); | |
313 prefs->SetString(prefs::kDefaultSearchProviderEncodings, std::string()); | |
314 prefs->SetString(prefs::kDefaultSearchProviderKeyword, std::string()); | |
315 prefs->SetString(prefs::kDefaultSearchProviderInstantURL, std::string()); | |
316 prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, std::string()); | |
317 prefs->SetValue(prefs::kDefaultSearchProviderAlternateURLs, | |
318 new base::ListValue()); | |
319 prefs->SetString( | |
320 prefs::kDefaultSearchProviderSearchTermsReplacementKey, std::string()); | |
321 prefs->SetString(prefs::kDefaultSearchProviderImageURL, std::string()); | |
322 prefs->SetString( | |
323 prefs::kDefaultSearchProviderSearchURLPostParams, std::string()); | |
324 prefs->SetString( | |
325 prefs::kDefaultSearchProviderSuggestURLPostParams, std::string()); | |
326 prefs->SetString( | |
327 prefs::kDefaultSearchProviderInstantURLPostParams, std::string()); | |
328 prefs->SetString( | |
329 prefs::kDefaultSearchProviderImageURLPostParams, std::string()); | |
330 } else { | |
331 // The search URL is required. The other entries are optional. Just make | |
332 // sure that they are all specified via policy, so that the regular prefs | |
333 // aren't used. | |
334 const base::Value* dummy; | |
335 std::string url; | |
336 if (DefaultSearchURLIsValid(policies, &dummy, &url)) { | |
337 | |
338 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler = | |
339 handlers_.begin(); | |
340 handler != handlers_.end(); ++handler) { | |
341 (*handler)->ApplyPolicySettings(policies, prefs); | |
342 } | |
343 | |
344 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderSuggestURL); | |
345 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderIconURL); | |
346 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderEncodings); | |
347 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderKeyword); | |
348 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderInstantURL); | |
349 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderNewTabURL); | |
350 EnsureListPrefExists(prefs, prefs::kDefaultSearchProviderAlternateURLs); | |
351 EnsureStringPrefExists( | |
352 prefs, | |
353 prefs::kDefaultSearchProviderSearchTermsReplacementKey); | |
354 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderImageURL); | |
355 EnsureStringPrefExists( | |
356 prefs, | |
357 prefs::kDefaultSearchProviderSearchURLPostParams); | |
358 EnsureStringPrefExists( | |
359 prefs, | |
360 prefs::kDefaultSearchProviderSuggestURLPostParams); | |
361 EnsureStringPrefExists( | |
362 prefs, | |
363 prefs::kDefaultSearchProviderInstantURLPostParams); | |
364 EnsureStringPrefExists( | |
365 prefs, | |
366 prefs::kDefaultSearchProviderImageURLPostParams); | |
367 | |
368 // For the name and keyword, default to the host if not specified. If | |
369 // there is no host (file: URLs? Not sure), use "_" to guarantee that the | |
370 // keyword is non-empty. | |
371 std::string name, keyword; | |
372 std::string host(GURL(url).host()); | |
373 if (host.empty()) | |
374 host = "_"; | |
375 if (!prefs->GetString(prefs::kDefaultSearchProviderName, &name) || | |
376 name.empty()) { | |
377 prefs->SetString(prefs::kDefaultSearchProviderName, host); | |
378 } | |
379 if (!prefs->GetString(prefs::kDefaultSearchProviderKeyword, &keyword) || | |
380 keyword.empty()) { | |
381 prefs->SetString(prefs::kDefaultSearchProviderKeyword, host); | |
382 } | |
383 | |
384 // And clear the IDs since these are not specified via policy. | |
385 prefs->SetString(prefs::kDefaultSearchProviderID, std::string()); | |
386 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, | |
387 std::string()); | |
388 } | |
389 } | |
390 } | |
391 | |
392 bool DefaultSearchPolicyHandler::CheckIndividualPolicies( | |
393 const PolicyMap& policies, | |
394 PolicyErrorMap* errors) { | |
395 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler = | |
396 handlers_.begin(); | |
397 handler != handlers_.end(); ++handler) { | |
398 if (!(*handler)->CheckPolicySettings(policies, errors)) | |
399 return false; | |
400 } | |
401 return true; | |
402 } | |
403 | |
404 bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy( | |
405 const PolicyMap& policies, | |
406 const char* policy_name) { | |
407 return policies.Get(policy_name) != NULL; | |
408 } | |
409 | |
410 bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified( | |
411 const PolicyMap& policies) { | |
412 for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler = | |
413 handlers_.begin(); | |
414 handler != handlers_.end(); ++handler) { | |
415 if (policies.Get((*handler)->policy_name())) | |
416 return true; | |
417 } | |
418 return false; | |
419 } | |
420 | |
421 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled( | |
422 const PolicyMap& policies) { | |
423 const base::Value* provider_enabled = | |
424 policies.GetValue(key::kDefaultSearchProviderEnabled); | |
425 bool enabled = true; | |
426 return provider_enabled && provider_enabled->GetAsBoolean(&enabled) && | |
427 !enabled; | |
428 } | |
429 | |
430 bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid( | |
431 const PolicyMap& policies, | |
432 const base::Value** url_value, | |
433 std::string* url_string) { | |
434 *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL); | |
435 if (!*url_value || !(*url_value)->GetAsString(url_string) || | |
436 url_string->empty()) | |
437 return false; | |
438 TemplateURLData data; | |
439 data.SetURL(*url_string); | |
440 SearchTermsData search_terms_data; | |
441 return TemplateURL(data).SupportsReplacement(search_terms_data); | |
442 } | |
443 | |
444 void DefaultSearchPolicyHandler::EnsureStringPrefExists( | |
445 PrefValueMap* prefs, | |
446 const std::string& path) { | |
447 std::string value; | |
448 if (!prefs->GetString(path, &value)) | |
449 prefs->SetString(path, value); | |
450 } | |
451 | |
452 void DefaultSearchPolicyHandler::EnsureListPrefExists( | |
453 PrefValueMap* prefs, | |
454 const std::string& path) { | |
455 base::Value* value; | |
456 base::ListValue* list_value; | |
457 if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value)) | |
458 prefs->SetValue(path, new base::ListValue()); | |
459 } | |
460 | |
461 } // namespace policy | |
OLD | NEW |