default_search_policy_handler.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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.
  4. #include "components/search_engines/default_search_policy_handler.h"
  5. #include <stddef.h>
  6. #include <utility>
  7. #include "base/strings/string_number_conversions.h"
  8. #include "base/values.h"
  9. #include "build/build_config.h"
  10. #include "components/policy/core/browser/policy_error_map.h"
  11. #include "components/policy/core/common/policy_map.h"
  12. #include "components/policy/policy_constants.h"
  13. #include "components/prefs/pref_value_map.h"
  14. #include "components/search_engines/default_search_manager.h"
  15. #include "components/search_engines/search_engines_pref_names.h"
  16. #include "components/search_engines/search_terms_data.h"
  17. #include "components/search_engines/template_url.h"
  18. #include "components/strings/grit/components_strings.h"
  19. namespace policy {
  20. namespace {
  21. // Extracts a list from a policy value and adds it to a pref dictionary.
  22. void SetListInPref(const PolicyMap& policies,
  23. const char* policy_name,
  24. const char* key,
  25. base::Value::Dict& dict) {
  26. const base::Value* policy_value =
  27. policies.GetValue(policy_name, base::Value::Type::LIST);
  28. dict.Set(key, policy_value ? policy_value->Clone()
  29. : base::Value(base::Value::Type::LIST));
  30. }
  31. // Extracts a string from a policy value and adds it to a pref dictionary.
  32. void SetStringInPref(const PolicyMap& policies,
  33. const char* policy_name,
  34. const char* key,
  35. base::Value::Dict& dict) {
  36. const base::Value* policy_value =
  37. policies.GetValue(policy_name, base::Value::Type::STRING);
  38. dict.Set(key, policy_value ? policy_value->GetString() : std::string());
  39. }
  40. void SetBooleanInPref(const PolicyMap& policies,
  41. const char* policy_name,
  42. const char* key,
  43. base::Value::Dict& dict) {
  44. const base::Value* policy_value =
  45. policies.GetValue(policy_name, base::Value::Type::BOOLEAN);
  46. dict.SetByDottedPath(key, policy_value && policy_value->GetBool());
  47. }
  48. } // namespace
  49. // List of policy types to preference names, for policies affecting the default
  50. // search provider. Please update ApplyPolicySettings() when add or remove
  51. // items.
  52. const PolicyToPreferenceMapEntry kDefaultSearchPolicyDataMap[] = {
  53. {key::kDefaultSearchProviderEnabled, prefs::kDefaultSearchProviderEnabled,
  54. base::Value::Type::BOOLEAN},
  55. {key::kDefaultSearchProviderName, DefaultSearchManager::kShortName,
  56. base::Value::Type::STRING},
  57. {key::kDefaultSearchProviderKeyword, DefaultSearchManager::kKeyword,
  58. base::Value::Type::STRING},
  59. {key::kDefaultSearchProviderSearchURL, DefaultSearchManager::kURL,
  60. base::Value::Type::STRING},
  61. {key::kDefaultSearchProviderSuggestURL,
  62. DefaultSearchManager::kSuggestionsURL, base::Value::Type::STRING},
  63. {key::kDefaultSearchProviderIconURL, DefaultSearchManager::kFaviconURL,
  64. base::Value::Type::STRING},
  65. {key::kDefaultSearchProviderEncodings,
  66. DefaultSearchManager::kInputEncodings, base::Value::Type::LIST},
  67. {key::kDefaultSearchProviderAlternateURLs,
  68. DefaultSearchManager::kAlternateURLs, base::Value::Type::LIST},
  69. {key::kDefaultSearchProviderImageURL, DefaultSearchManager::kImageURL,
  70. base::Value::Type::STRING},
  71. {key::kDefaultSearchProviderNewTabURL, DefaultSearchManager::kNewTabURL,
  72. base::Value::Type::STRING},
  73. {key::kDefaultSearchProviderSearchURLPostParams,
  74. DefaultSearchManager::kSearchURLPostParams, base::Value::Type::STRING},
  75. {key::kDefaultSearchProviderSuggestURLPostParams,
  76. DefaultSearchManager::kSuggestionsURLPostParams,
  77. base::Value::Type::STRING},
  78. {key::kDefaultSearchProviderImageURLPostParams,
  79. DefaultSearchManager::kImageURLPostParams, base::Value::Type::STRING},
  80. #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
  81. {key::kDefaultSearchProviderContextMenuAccessAllowed,
  82. prefs::kDefaultSearchProviderContextMenuAccessAllowed,
  83. base::Value::Type::BOOLEAN},
  84. #endif
  85. };
  86. // DefaultSearchPolicyHandler implementation -----------------------------------
  87. DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() {}
  88. DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() {}
  89. bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
  90. PolicyErrorMap* errors) {
  91. if (!CheckIndividualPolicies(policies, errors))
  92. return false;
  93. if (!DefaultSearchProviderPolicyIsSet(policies) ||
  94. DefaultSearchProviderIsDisabled(policies)) {
  95. // Add an error for all specified default search policies except
  96. // DefaultSearchProviderEnabled and
  97. // DefaultSearchProviderContextMenuAccessAllowed.
  98. for (const auto& policy_map_entry : kDefaultSearchPolicyDataMap) {
  99. const char* policy_name = policy_map_entry.policy_name;
  100. if (policy_name != key::kDefaultSearchProviderEnabled &&
  101. #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
  102. policy_name != key::kDefaultSearchProviderContextMenuAccessAllowed &&
  103. #endif
  104. HasDefaultSearchPolicy(policies, policy_name)) {
  105. errors->AddError(policy_name, IDS_POLICY_DEFAULT_SEARCH_DISABLED);
  106. }
  107. }
  108. return true;
  109. }
  110. const base::Value* url;
  111. std::string dummy;
  112. if (DefaultSearchURLIsValid(policies, &url, &dummy) ||
  113. !AnyDefaultSearchPoliciesSpecified(policies))
  114. return true;
  115. errors->AddError(key::kDefaultSearchProviderSearchURL, url ?
  116. IDS_POLICY_INVALID_SEARCH_URL_ERROR : IDS_POLICY_NOT_SPECIFIED_ERROR);
  117. return false;
  118. }
  119. void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
  120. PrefValueMap* prefs) {
  121. // If the main switch is not set don't set anything.
  122. if (!DefaultSearchProviderPolicyIsSet(policies))
  123. return;
  124. if (DefaultSearchProviderIsDisabled(policies)) {
  125. base::Value::Dict dict;
  126. dict.Set(DefaultSearchManager::kDisabledByPolicy, true);
  127. DefaultSearchManager::AddPrefValueToMap(std::move(dict), prefs);
  128. return;
  129. }
  130. // The search URL is required. The other entries are optional. Just make
  131. // sure that they are all specified via policy, so that the regular prefs
  132. // aren't used.
  133. const base::Value* dummy;
  134. std::string url;
  135. if (!DefaultSearchURLIsValid(policies, &dummy, &url))
  136. return;
  137. base::Value::Dict dict;
  138. // Set pref values for policies affecting the default
  139. // search provider, which are listed in kDefaultSearchPolicyDataMap.
  140. // Set or remove pref accordingly when kDefaultSearchPolicyDataMap has a
  141. // change, then revise the number in the check below to be correct.
  142. SetBooleanInPref(policies, key::kDefaultSearchProviderEnabled,
  143. prefs::kDefaultSearchProviderEnabled, dict);
  144. SetStringInPref(policies, key::kDefaultSearchProviderName,
  145. DefaultSearchManager::kShortName, dict);
  146. SetStringInPref(policies, key::kDefaultSearchProviderKeyword,
  147. DefaultSearchManager::kKeyword, dict);
  148. SetStringInPref(policies, key::kDefaultSearchProviderSearchURL,
  149. DefaultSearchManager::kURL, dict);
  150. SetStringInPref(policies, key::kDefaultSearchProviderSuggestURL,
  151. DefaultSearchManager::kSuggestionsURL, dict);
  152. SetStringInPref(policies, key::kDefaultSearchProviderIconURL,
  153. DefaultSearchManager::kFaviconURL, dict);
  154. SetListInPref(policies, key::kDefaultSearchProviderEncodings,
  155. DefaultSearchManager::kInputEncodings, dict);
  156. SetListInPref(policies, key::kDefaultSearchProviderAlternateURLs,
  157. DefaultSearchManager::kAlternateURLs, dict);
  158. SetStringInPref(policies, key::kDefaultSearchProviderImageURL,
  159. DefaultSearchManager::kImageURL, dict);
  160. SetStringInPref(policies, key::kDefaultSearchProviderNewTabURL,
  161. DefaultSearchManager::kNewTabURL, dict);
  162. SetStringInPref(policies, key::kDefaultSearchProviderSearchURLPostParams,
  163. DefaultSearchManager::kSearchURLPostParams, dict);
  164. SetStringInPref(policies, key::kDefaultSearchProviderSuggestURLPostParams,
  165. DefaultSearchManager::kSuggestionsURLPostParams, dict);
  166. SetStringInPref(policies, key::kDefaultSearchProviderImageURLPostParams,
  167. DefaultSearchManager::kImageURLPostParams, dict);
  168. #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
  169. SetBooleanInPref(policies,
  170. key::kDefaultSearchProviderContextMenuAccessAllowed,
  171. prefs::kDefaultSearchProviderContextMenuAccessAllowed, dict);
  172. size_t policyCount = 14;
  173. #else
  174. size_t policyCount = 13;
  175. #endif
  176. CHECK_EQ(policyCount, std::size(kDefaultSearchPolicyDataMap));
  177. // Set the fields which are not specified by the policy to default values.
  178. dict.Set(DefaultSearchManager::kID,
  179. base::NumberToString(kInvalidTemplateURLID));
  180. dict.Set(DefaultSearchManager::kPrepopulateID, 0);
  181. dict.Set(DefaultSearchManager::kStarterPackId, 0);
  182. dict.Set(DefaultSearchManager::kSyncGUID, std::string());
  183. dict.Set(DefaultSearchManager::kOriginatingURL, std::string());
  184. dict.Set(DefaultSearchManager::kSafeForAutoReplace, true);
  185. dict.Set(DefaultSearchManager::kDateCreated,
  186. static_cast<double>(base::Time::Now().ToInternalValue()));
  187. dict.Set(DefaultSearchManager::kLastModified,
  188. static_cast<double>(base::Time::Now().ToInternalValue()));
  189. dict.Set(DefaultSearchManager::kUsageCount, 0);
  190. dict.Set(DefaultSearchManager::kCreatedByPolicy, true);
  191. // For the name and keyword, default to the host if not specified. If
  192. // there is no host (as is the case with file URLs of the form:
  193. // "file:///c:/..."), use "_" to guarantee that the keyword is non-empty.
  194. std::string* keyword = dict.FindString(DefaultSearchManager::kKeyword);
  195. std::string* name = dict.FindString(DefaultSearchManager::kShortName);
  196. std::string* url_str = dict.FindString(DefaultSearchManager::kURL);
  197. if (url_str)
  198. url = *url_str;
  199. std::string host(GURL(url).host());
  200. if (host.empty())
  201. host = "_";
  202. if (!name || name->empty())
  203. dict.Set(DefaultSearchManager::kShortName, host);
  204. if (!keyword || keyword->empty())
  205. dict.Set(DefaultSearchManager::kKeyword, host);
  206. DefaultSearchManager::AddPrefValueToMap(std::move(dict), prefs);
  207. }
  208. bool DefaultSearchPolicyHandler::CheckIndividualPolicies(
  209. const PolicyMap& policies,
  210. PolicyErrorMap* errors) {
  211. bool all_ok = true;
  212. for (const auto& policy_map_entry : kDefaultSearchPolicyDataMap) {
  213. // It's safe to use `GetValueUnsafe()` as multiple policy types are handled.
  214. // It's important to check policy type for all policies and not just exit on
  215. // the first error, so we report all policy errors.
  216. const base::Value* value =
  217. policies.GetValueUnsafe(policy_map_entry.policy_name);
  218. if (value && value->type() != policy_map_entry.value_type) {
  219. errors->AddError(policy_map_entry.policy_name, IDS_POLICY_TYPE_ERROR,
  220. base::Value::GetTypeName(policy_map_entry.value_type));
  221. all_ok = false;
  222. }
  223. }
  224. return all_ok;
  225. }
  226. bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
  227. const PolicyMap& policies,
  228. const char* policy_name) {
  229. return policies.Get(policy_name) != nullptr;
  230. }
  231. bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified(
  232. const PolicyMap& policies) {
  233. for (const auto& policy_map_entry : kDefaultSearchPolicyDataMap) {
  234. if (policies.Get(policy_map_entry.policy_name))
  235. return true;
  236. }
  237. return false;
  238. }
  239. bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
  240. const PolicyMap& policies) {
  241. const base::Value* provider_enabled = policies.GetValue(
  242. key::kDefaultSearchProviderEnabled, base::Value::Type::BOOLEAN);
  243. return provider_enabled && !provider_enabled->GetBool();
  244. }
  245. bool DefaultSearchPolicyHandler::DefaultSearchProviderPolicyIsSet(
  246. const PolicyMap& policies) {
  247. return HasDefaultSearchPolicy(policies, key::kDefaultSearchProviderEnabled);
  248. }
  249. bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid(
  250. const PolicyMap& policies,
  251. const base::Value** url_value,
  252. std::string* url_string) {
  253. *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL,
  254. base::Value::Type::STRING);
  255. if (!*url_value)
  256. return false;
  257. *url_string = (*url_value)->GetString();
  258. if (url_string->empty())
  259. return false;
  260. TemplateURLData data;
  261. data.SetURL(*url_string);
  262. SearchTermsData search_terms_data;
  263. return TemplateURL(data).SupportsReplacement(search_terms_data);
  264. }
  265. void DefaultSearchPolicyHandler::EnsureStringPrefExists(
  266. PrefValueMap* prefs,
  267. const std::string& path) {
  268. std::string value;
  269. if (!prefs->GetString(path, &value))
  270. prefs->SetString(path, value);
  271. }
  272. void DefaultSearchPolicyHandler::EnsureListPrefExists(
  273. PrefValueMap* prefs,
  274. const std::string& path) {
  275. base::Value* value;
  276. if (!prefs->GetValue(path, &value) || !value->is_list())
  277. prefs->SetValue(path, base::Value(base::Value::Type::LIST));
  278. }
  279. } // namespace policy