// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/policy/core/common/policy_map.h" #include #include "base/bind.h" #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "components/policy/core/common/external_data_manager.h" #include "components/policy/core/common/policy_types.h" #include "testing/gtest/include/gtest/gtest.h" namespace policy { namespace { // Dummy policy names. const char kTestPolicyName1[] = "policy.test.1"; const char kTestPolicyName2[] = "policy.test.2"; const char kTestPolicyName3[] = "policy.test.3"; const char kTestPolicyName4[] = "policy.test.4"; const char kTestPolicyName5[] = "policy.test.5"; const char kTestPolicyName6[] = "policy.test.6"; const char kTestPolicyName7[] = "policy.test.7"; const char kTestPolicyName8[] = "policy.test.8"; // Dummy error message. const char kTestError[] = "Test error message"; // Utility functions for the tests. void SetPolicy(PolicyMap* map, const char* name, std::unique_ptr value) { map->Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::move(value), nullptr); } void SetPolicy(PolicyMap* map, const char* name, std::unique_ptr external_data_fetcher) { map->Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, nullptr, std::move(external_data_fetcher)); } } // namespace class PolicyMapTest : public testing::Test { protected: std::unique_ptr CreateExternalDataFetcher( const std::string& policy) const; }; std::unique_ptr PolicyMapTest::CreateExternalDataFetcher( const std::string& policy) const { return std::make_unique( base::WeakPtr(), policy); } TEST_F(PolicyMapTest, SetAndGet) { PolicyMap map; SetPolicy(&map, kTestPolicyName1, std::make_unique("aaa")); base::Value expected("aaa"); EXPECT_TRUE(expected.Equals(map.GetValue(kTestPolicyName1))); SetPolicy(&map, kTestPolicyName1, std::make_unique("bbb")); base::Value expected_b("bbb"); EXPECT_TRUE(expected_b.Equals(map.GetValue(kTestPolicyName1))); SetPolicy(&map, kTestPolicyName1, CreateExternalDataFetcher("dummy")); map.SetError(kTestPolicyName1, kTestError); EXPECT_FALSE(map.GetValue(kTestPolicyName1)); const PolicyMap::Entry* entry = map.Get(kTestPolicyName1); ASSERT_TRUE(entry != nullptr); EXPECT_EQ(POLICY_LEVEL_MANDATORY, entry->level); EXPECT_EQ(POLICY_SCOPE_USER, entry->scope); EXPECT_EQ(POLICY_SOURCE_CLOUD, entry->source); EXPECT_EQ(kTestError, entry->error); EXPECT_TRUE( ExternalDataFetcher::Equals(entry->external_data_fetcher.get(), CreateExternalDataFetcher("dummy").get())); map.Set(kTestPolicyName1, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_ENTERPRISE_DEFAULT, nullptr, nullptr); EXPECT_FALSE(map.GetValue(kTestPolicyName1)); entry = map.Get(kTestPolicyName1); ASSERT_TRUE(entry != nullptr); EXPECT_EQ(POLICY_LEVEL_RECOMMENDED, entry->level); EXPECT_EQ(POLICY_SCOPE_MACHINE, entry->scope); EXPECT_EQ(POLICY_SOURCE_ENTERPRISE_DEFAULT, entry->source); EXPECT_EQ("", entry->error); EXPECT_FALSE(entry->external_data_fetcher); } TEST_F(PolicyMapTest, Equals) { PolicyMap a; SetPolicy(&a, kTestPolicyName1, std::make_unique("aaa")); PolicyMap a2; SetPolicy(&a2, kTestPolicyName1, std::make_unique("aaa")); PolicyMap b; SetPolicy(&b, kTestPolicyName1, std::make_unique("bbb")); PolicyMap c; SetPolicy(&c, kTestPolicyName1, std::make_unique("aaa")); SetPolicy(&c, kTestPolicyName2, std::make_unique(true)); PolicyMap d; SetPolicy(&d, kTestPolicyName1, CreateExternalDataFetcher("ddd")); PolicyMap d2; SetPolicy(&d2, kTestPolicyName1, CreateExternalDataFetcher("ddd")); PolicyMap e; SetPolicy(&e, kTestPolicyName1, CreateExternalDataFetcher("eee")); EXPECT_FALSE(a.Equals(b)); EXPECT_FALSE(a.Equals(c)); EXPECT_FALSE(a.Equals(d)); EXPECT_FALSE(a.Equals(e)); EXPECT_FALSE(b.Equals(a)); EXPECT_FALSE(b.Equals(c)); EXPECT_FALSE(b.Equals(d)); EXPECT_FALSE(b.Equals(e)); EXPECT_FALSE(c.Equals(a)); EXPECT_FALSE(c.Equals(b)); EXPECT_FALSE(c.Equals(d)); EXPECT_FALSE(c.Equals(e)); EXPECT_FALSE(d.Equals(a)); EXPECT_FALSE(d.Equals(b)); EXPECT_FALSE(d.Equals(c)); EXPECT_FALSE(d.Equals(e)); EXPECT_FALSE(e.Equals(a)); EXPECT_FALSE(e.Equals(b)); EXPECT_FALSE(e.Equals(c)); EXPECT_FALSE(e.Equals(d)); EXPECT_TRUE(a.Equals(a2)); EXPECT_TRUE(a2.Equals(a)); EXPECT_TRUE(d.Equals(d2)); EXPECT_TRUE(d2.Equals(d)); PolicyMap empty1; PolicyMap empty2; EXPECT_TRUE(empty1.Equals(empty2)); EXPECT_TRUE(empty2.Equals(empty1)); EXPECT_FALSE(empty1.Equals(a)); EXPECT_FALSE(a.Equals(empty1)); } TEST_F(PolicyMapTest, Swap) { PolicyMap a; SetPolicy(&a, kTestPolicyName1, std::make_unique("aaa")); SetPolicy(&a, kTestPolicyName2, CreateExternalDataFetcher("dummy")); PolicyMap b; SetPolicy(&b, kTestPolicyName1, std::make_unique("bbb")); SetPolicy(&b, kTestPolicyName3, std::make_unique(true)); a.Swap(&b); base::Value expected("bbb"); EXPECT_TRUE(expected.Equals(a.GetValue(kTestPolicyName1))); base::Value expected_bool(true); EXPECT_TRUE(expected_bool.Equals(a.GetValue(kTestPolicyName3))); EXPECT_FALSE(a.GetValue(kTestPolicyName2)); EXPECT_FALSE(a.Get(kTestPolicyName2)); base::Value expected_a("aaa"); EXPECT_TRUE(expected_a.Equals(b.GetValue(kTestPolicyName1))); EXPECT_FALSE(b.GetValue(kTestPolicyName3)); EXPECT_FALSE(a.GetValue(kTestPolicyName2)); const PolicyMap::Entry* entry = b.Get(kTestPolicyName2); ASSERT_TRUE(entry); EXPECT_TRUE( ExternalDataFetcher::Equals(CreateExternalDataFetcher("dummy").get(), entry->external_data_fetcher.get())); b.Clear(); a.Swap(&b); PolicyMap empty; EXPECT_TRUE(a.Equals(empty)); EXPECT_FALSE(b.Equals(empty)); } TEST_F(PolicyMapTest, MergeFrom) { PolicyMap a; a.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique("google.com"), nullptr); a.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique(true), nullptr); a.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_ENTERPRISE_DEFAULT, nullptr, CreateExternalDataFetcher("a")); a.Set(kTestPolicyName4, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique(false), nullptr); a.Set(kTestPolicyName5, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique("google.com/q={x}"), nullptr); a.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_ENTERPRISE_DEFAULT, std::make_unique(false), nullptr); PolicyMap b; b.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique("chromium.org"), nullptr); b.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique(false), nullptr); b.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_ENTERPRISE_DEFAULT, nullptr, CreateExternalDataFetcher("b")); b.Set(kTestPolicyName4, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PUBLIC_SESSION_OVERRIDE, std::make_unique(true), nullptr); b.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, std::make_unique(std::string()), nullptr); b.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique(true), nullptr); b.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_ACTIVE_DIRECTORY, std::make_unique(true), nullptr); a.MergeFrom(b); PolicyMap c; // POLICY_SCOPE_MACHINE over POLICY_SCOPE_USER. c.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique("chromium.org"), nullptr); // |a| has precedence over |b|. c.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique(true), nullptr); c.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_ENTERPRISE_DEFAULT, nullptr, CreateExternalDataFetcher("a")); // POLICY_SCOPE_MACHINE over POLICY_SCOPE_USER for POLICY_LEVEL_RECOMMENDED. c.Set(kTestPolicyName4, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PUBLIC_SESSION_OVERRIDE, std::make_unique(true), nullptr); // POLICY_LEVEL_MANDATORY over POLICY_LEVEL_RECOMMENDED. c.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, std::make_unique(std::string()), nullptr); // Merge new ones. c.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique(true), nullptr); // POLICY_SOURCE_ACTIVE_DIRECTORY over POLICY_SOURCE_ENTERPRISE_DEFAULT. c.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_ACTIVE_DIRECTORY, std::make_unique(true), nullptr); EXPECT_TRUE(a.Equals(c)); } TEST_F(PolicyMapTest, GetDifferingKeys) { PolicyMap a; a.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique("google.com"), nullptr); a.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, nullptr, CreateExternalDataFetcher("dummy")); a.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique(true), nullptr); a.Set(kTestPolicyName4, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, nullptr, CreateExternalDataFetcher("a")); a.Set(kTestPolicyName5, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique(false), nullptr); a.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique("google.com/q={x}"), nullptr); a.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique(true), nullptr); PolicyMap b; b.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique("google.com"), nullptr); b.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, nullptr, CreateExternalDataFetcher("dummy")); b.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique(false), nullptr); b.Set(kTestPolicyName4, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, nullptr, CreateExternalDataFetcher("b")); b.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique(false), nullptr); b.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique("google.com/q={x}"), nullptr); b.Set(kTestPolicyName8, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique(true), nullptr); std::set diff; std::set diff2; a.GetDifferingKeys(b, &diff); b.GetDifferingKeys(a, &diff2); // Order shouldn't matter. EXPECT_EQ(diff, diff2); // No change. EXPECT_TRUE(diff.find(kTestPolicyName1) == diff.end()); EXPECT_TRUE(diff.find(kTestPolicyName2) == diff.end()); // Different values. EXPECT_TRUE(diff.find(kTestPolicyName3) != diff.end()); // Different external data references. EXPECT_TRUE(diff.find(kTestPolicyName4) != diff.end()); // Different levels. EXPECT_TRUE(diff.find(kTestPolicyName5) != diff.end()); // Different scopes. EXPECT_TRUE(diff.find(kTestPolicyName6) != diff.end()); // Not in |a|. EXPECT_TRUE(diff.find(kTestPolicyName8) != diff.end()); // Not in |b|. EXPECT_TRUE(diff.find(kTestPolicyName7) != diff.end()); // No surprises. EXPECT_EQ(6u, diff.size()); } TEST_F(PolicyMapTest, LoadFromSetsLevelScopeAndSource) { base::DictionaryValue policies; policies.SetString("TestPolicy1", "google.com"); policies.SetBoolean("TestPolicy2", true); policies.SetInteger("TestPolicy3", -12321); PolicyMap loaded; loaded.LoadFrom(&policies, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM); PolicyMap expected; expected.Set("TestPolicy1", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM, std::make_unique("google.com"), nullptr); expected.Set("TestPolicy2", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM, std::make_unique(true), nullptr); expected.Set("TestPolicy3", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM, std::make_unique(-12321), nullptr); EXPECT_TRUE(loaded.Equals(expected)); } bool IsMandatory(const PolicyMap::PolicyMapType::const_iterator iter) { return iter->second.level == POLICY_LEVEL_MANDATORY; } TEST_F(PolicyMapTest, EraseNonmatching) { PolicyMap a; a.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique("google.com"), nullptr); a.Set(kTestPolicyName2, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::make_unique(true), nullptr); a.EraseNonmatching(base::Bind(&IsMandatory)); PolicyMap b; b.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::make_unique("google.com"), nullptr); EXPECT_TRUE(a.Equals(b)); } } // namespace policy