1 // Copyright 2020 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 "components/policy/core/browser/configuration_policy_handler_list.h"
6 
7 #include <string>
8 #include <tuple>
9 
10 #include "base/bind.h"
11 #include "base/values.h"
12 #include "components/policy/core/browser/configuration_policy_handler.h"
13 #include "components/policy/core/browser/policy_conversions_client.h"
14 #include "components/policy/core/browser/policy_error_map.h"
15 #include "components/policy/core/common/policy_details.h"
16 #include "components/policy/core/common/policy_map.h"
17 #include "components/policy/core/common/policy_types.h"
18 #include "components/policy/policy_constants.h"
19 #include "components/prefs/pref_value_map.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 
22 namespace policy {
23 
24 namespace {
25 
26 const char kPolicyName[] = "PolicyName";
27 const char kPolicyName2[] = "PolicyName2";
28 const int kPolicyValue = 12;
29 
30 class StubPolicyHandler : public ConfigurationPolicyHandler {
31  public:
StubPolicyHandler(const std::string & policy_name)32   explicit StubPolicyHandler(const std::string& policy_name)
33       : policy_name_(policy_name) {}
34   ~StubPolicyHandler() override = default;
35 
CheckPolicySettings(const PolicyMap & policies,PolicyErrorMap * errors)36   bool CheckPolicySettings(const PolicyMap& policies,
37                            PolicyErrorMap* errors) override {
38     return policies.GetValue(policy_name_);
39   }
40 
41  protected:
ApplyPolicySettings(const PolicyMap & policies,PrefValueMap * prefs)42   void ApplyPolicySettings(const PolicyMap& policies,
43                            PrefValueMap* prefs) override {
44     prefs->SetInteger(policy_name_, policies.GetValue(policy_name_)->GetInt());
45   }
46 
47  private:
48   std::string policy_name_;
49 };
50 
51 }  // namespace
52 
53 class ConfigurationPolicyHandlerListTest : public ::testing::Test {
54  public:
SetUp()55   void SetUp() override { CreateHandlerList(); }
56 
AddSimplePolicy()57   void AddSimplePolicy() {
58     AddPolicy(kPolicyName, /* is_cloud */ true, base::Value(kPolicyValue));
59   }
60 
AddPolicy(const std::string policy_name,bool is_cloud,base::Value value)61   void AddPolicy(const std::string policy_name,
62                  bool is_cloud,
63                  base::Value value) {
64     policies_.Set(policy_name, PolicyLevel::POLICY_LEVEL_MANDATORY,
65                   PolicyScope::POLICY_SCOPE_MACHINE,
66                   is_cloud ? PolicySource::POLICY_SOURCE_CLOUD
67                            : PolicySource::POLICY_SOURCE_PLATFORM,
68                   std::move(value), nullptr);
69     if (policy_name != key::kEnableExperimentalPolicies) {
70       handler_list_->AddHandler(
71           std::make_unique<StubPolicyHandler>(policy_name));
72     }
73   }
74 
ApplySettings()75   void ApplySettings() {
76     handler_list_->ApplyPolicySettings(
77         policies_, &prefs_, &errors_, &deprecated_policies_, &future_policies_);
78   }
79 
CreateHandlerList(bool allow_all_future_policies=false)80   void CreateHandlerList(bool allow_all_future_policies = false) {
81     handler_list_ = std::make_unique<ConfigurationPolicyHandlerList>(
82         ConfigurationPolicyHandlerList::
83             PopulatePolicyHandlerParametersCallback(),
84         base::BindRepeating(
85             &ConfigurationPolicyHandlerListTest::GetPolicyDetails,
86             base::Unretained(this)),
87         allow_all_future_policies);
88   }
89 
prefs()90   PrefValueMap* prefs() { return &prefs_; }
91 
GetPolicyDetails(const std::string & policy_name)92   const PolicyDetails* GetPolicyDetails(const std::string& policy_name) {
93     return &details_;
94   }
details()95   PolicyDetails* details() { return &details_; }
96 
VerifyPolicyAndPref(const std::string & policy_name,bool in_pref,bool in_deprecated=false,bool in_future=false)97   void VerifyPolicyAndPref(const std::string& policy_name,
98                            bool in_pref,
99                            bool in_deprecated = false,
100                            bool in_future = false) {
101     int pref_value;
102 
103     ASSERT_EQ(in_pref, prefs_.GetInteger(policy_name, &pref_value));
104     if (in_pref)
105       EXPECT_EQ(kPolicyValue, pref_value);
106 
107     // Pref filter never affects PolicyMap.
108     const base::Value* policy_value = policies_.GetValue(policy_name);
109     ASSERT_TRUE(policy_value);
110     EXPECT_EQ(kPolicyValue, policy_value->GetInt());
111 
112     EXPECT_EQ(in_deprecated, deprecated_policies_.find(policy_name) !=
113                                  deprecated_policies_.end());
114     EXPECT_EQ(in_future,
115               future_policies_.find(policy_name) != future_policies_.end());
116   }
117 
118  private:
119   PrefValueMap prefs_;
120   PolicyErrorMap errors_;
121   PolicyMap policies_;
122   PoliciesSet deprecated_policies_;
123   PoliciesSet future_policies_;
124   PolicyDetails details_{false, false, false, 0, 0, {}};
125 
126   std::unique_ptr<ConfigurationPolicyHandlerList> handler_list_;
127 };
128 
TEST_F(ConfigurationPolicyHandlerListTest,ApplySettingsWithNormalPolicy)129 TEST_F(ConfigurationPolicyHandlerListTest, ApplySettingsWithNormalPolicy) {
130   AddSimplePolicy();
131   ApplySettings();
132   VerifyPolicyAndPref(kPolicyName, /* in_pref */ true);
133 }
134 
135 // Future policy will be filter out unless it's whitelisted by
136 // kEnableExperimentalPolicies.
TEST_F(ConfigurationPolicyHandlerListTest,ApplySettingsWithFuturePolicy)137 TEST_F(ConfigurationPolicyHandlerListTest, ApplySettingsWithFuturePolicy) {
138   AddSimplePolicy();
139   details()->is_future = true;
140 
141   ApplySettings();
142 
143   VerifyPolicyAndPref(kPolicyName, /* in_pref */ false,
144                       /* in_deprecated */ false, /* in_future */ true);
145 
146   // Whitelist a different policy.
147   base::Value::ListStorage enabled_future_policies;
148   enabled_future_policies.push_back(base::Value(kPolicyName2));
149   AddPolicy(key::kEnableExperimentalPolicies, /* is_cloud */ true,
150             base::Value(enabled_future_policies));
151 
152   ApplySettings();
153 
154   VerifyPolicyAndPref(kPolicyName, /* in_pref */ false,
155                       /* in_deprecated */ false, /* in_future */ true);
156 
157   // Whitelist the policy.
158   enabled_future_policies.push_back(base::Value(kPolicyName));
159   AddPolicy(key::kEnableExperimentalPolicies, /* is_cloud */ true,
160             base::Value(enabled_future_policies));
161 
162   ApplySettings();
163 
164   VerifyPolicyAndPref(kPolicyName, /* in_pref */ true);
165 }
166 
TEST_F(ConfigurationPolicyHandlerListTest,ApplySettingsWithoutFutureFilterPolicy)167 TEST_F(ConfigurationPolicyHandlerListTest,
168        ApplySettingsWithoutFutureFilterPolicy) {
169   CreateHandlerList(true);
170   AddSimplePolicy();
171   details()->is_future = true;
172 
173   ApplySettings();
174 
175   VerifyPolicyAndPref(kPolicyName, /* in_pref */ true);
176 }
177 
178 // Device platform policy will be fitered out.
TEST_F(ConfigurationPolicyHandlerListTest,ApplySettingsWithPlatformDevicePolicy)179 TEST_F(ConfigurationPolicyHandlerListTest,
180        ApplySettingsWithPlatformDevicePolicy) {
181   AddSimplePolicy();
182   details()->is_device_policy = true;
183 
184   ApplySettings();
185   VerifyPolicyAndPref(kPolicyName, /* in_pref */ true);
186 
187   AddPolicy(kPolicyName2, /* is_cloud */ false, base::Value(kPolicyValue));
188 
189   ApplySettings();
190   VerifyPolicyAndPref(kPolicyName2, /* in_pref */ false);
191 }
192 
193 // Deprecated policy won't be filtered out.
TEST_F(ConfigurationPolicyHandlerListTest,ApplySettingsWithDeprecatedPolicy)194 TEST_F(ConfigurationPolicyHandlerListTest, ApplySettingsWithDeprecatedPolicy) {
195   AddSimplePolicy();
196   details()->is_deprecated = true;
197 
198   ApplySettings();
199   VerifyPolicyAndPref(kPolicyName, /* in_pref */ true, /* in_deprecated*/ true);
200 }
201 
202 }  // namespace policy
203