1 // Copyright 2019 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/net/dns_util.h"
6 
7 #include <algorithm>
8 #include <string>
9 
10 #include "base/feature_list.h"
11 #include "base/strings/string_split.h"
12 #include "chrome/common/chrome_features.h"
13 #include "components/embedder_support/pref_names.h"
14 #include "components/prefs/pref_registry_simple.h"
15 #include "components/prefs/pref_service.h"
16 #include "net/dns/public/util.h"
17 #include "net/third_party/uri_template/uri_template.h"
18 #include "url/gurl.h"
19 
20 namespace chrome_browser_net {
21 
22 namespace {
23 
24 const char kAlternateErrorPagesBackup[] = "alternate_error_pages.backup";
25 
26 }  // namespace
27 
RegisterDNSProbesSettingBackupPref(PrefRegistrySimple * registry)28 void RegisterDNSProbesSettingBackupPref(PrefRegistrySimple* registry) {
29   registry->RegisterBooleanPref(kAlternateErrorPagesBackup, true);
30 }
31 
MigrateDNSProbesSettingToOrFromBackup(PrefService * prefs)32 void MigrateDNSProbesSettingToOrFromBackup(PrefService* prefs) {
33   // If the privacy settings redesign is enabled and the user value of the
34   // preference hasn't been backed up yet, back it up, and clear it. That way,
35   // the preference will revert to using the hardcoded default value (unless
36   // it's managed by a policy or an extension). This is necessary, as the
37   // privacy settings redesign removed the user-facing toggle, and so the
38   // user value of the preference is no longer modifiable.
39   if (base::FeatureList::IsEnabled(features::kPrivacySettingsRedesign) &&
40       !prefs->HasPrefPath(kAlternateErrorPagesBackup)) {
41     // If the user never changed the value of the preference and still uses the
42     // hardcoded default value, we'll consider it to be the user value for
43     // the purposes of this migration.
44     const base::Value* user_value =
45         prefs->FindPreference(embedder_support::kAlternateErrorPagesEnabled)
46                 ->HasUserSetting()
47             ? prefs->GetUserPrefValue(
48                   embedder_support::kAlternateErrorPagesEnabled)
49             : prefs->GetDefaultPrefValue(
50                   embedder_support::kAlternateErrorPagesEnabled);
51 
52     DCHECK(user_value->is_bool());
53     prefs->SetBoolean(kAlternateErrorPagesBackup, user_value->GetBool());
54     prefs->ClearPref(embedder_support::kAlternateErrorPagesEnabled);
55   }
56 
57   // If the privacy settings redesign is rolled back and there is a backed up
58   // value of the preference, restore it to the original preference, and clear
59   // the backup.
60   if (!base::FeatureList::IsEnabled(features::kPrivacySettingsRedesign) &&
61       prefs->HasPrefPath(kAlternateErrorPagesBackup)) {
62     prefs->SetBoolean(embedder_support::kAlternateErrorPagesEnabled,
63                       prefs->GetBoolean(kAlternateErrorPagesBackup));
64     prefs->ClearPref(kAlternateErrorPagesBackup);
65   }
66 }
67 
SplitDohTemplateGroup(base::StringPiece group)68 std::vector<base::StringPiece> SplitDohTemplateGroup(base::StringPiece group) {
69   // Templates in a group are whitespace-separated.
70   return SplitStringPiece(group, " ", base::TRIM_WHITESPACE,
71                           base::SPLIT_WANT_NONEMPTY);
72 }
73 
IsValidDohTemplateGroup(base::StringPiece group)74 bool IsValidDohTemplateGroup(base::StringPiece group) {
75   // All templates must be valid for the group to be considered valid.
76   std::vector<base::StringPiece> templates = SplitDohTemplateGroup(group);
77   return std::all_of(templates.begin(), templates.end(), [](auto t) {
78     std::string method;
79     return net::dns_util::IsValidDohTemplate(t, &method);
80   });
81 }
82 
83 }  // namespace chrome_browser_net
84