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