diff options
Diffstat (limited to 'chrome')
| -rw-r--r-- | chrome/browser/policy/browser_policy_connector.cc | 8 | ||||
| -rw-r--r-- | chrome/browser/policy/configuration_policy_provider_mac.h | 71 | ||||
| -rw-r--r-- | chrome/browser/policy/configuration_policy_provider_test.cc | 15 | ||||
| -rw-r--r-- | chrome/browser/policy/configuration_policy_provider_test.h | 23 | ||||
| -rw-r--r-- | chrome/browser/policy/policy_loader_mac.cc | 181 | ||||
| -rw-r--r-- | chrome/browser/policy/policy_loader_mac.h | 65 | ||||
| -rw-r--r-- | chrome/browser/policy/policy_loader_mac_unittest.cc | 321 | ||||
| -rw-r--r-- | chrome/chrome_browser.gypi | 4 | ||||
| -rw-r--r-- | chrome/chrome_tests.gypi | 2 |
9 files changed, 610 insertions, 80 deletions
diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc index bc2258d..7ae5eaa 100644 --- a/chrome/browser/policy/browser_policy_connector.cc +++ b/chrome/browser/policy/browser_policy_connector.cc @@ -10,6 +10,7 @@ #include "base/file_path.h" #include "base/path_service.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/policy/async_policy_provider.h" #include "chrome/browser/policy/cloud_policy_client.h" #include "chrome/browser/policy/cloud_policy_provider.h" #include "chrome/browser/policy/cloud_policy_service.h" @@ -34,7 +35,8 @@ #if defined(OS_WIN) #include "chrome/browser/policy/configuration_policy_provider_win.h" #elif defined(OS_MACOSX) -#include "chrome/browser/policy/configuration_policy_provider_mac.h" +#include "chrome/browser/policy/policy_loader_mac.h" +#include "chrome/browser/preferences_mac.h" #elif defined(OS_POSIX) #include "chrome/browser/policy/config_dir_policy_provider.h" #endif @@ -560,7 +562,9 @@ ConfigurationPolicyProvider* #if defined(OS_WIN) return new ConfigurationPolicyProviderWin(policy_list); #elif defined(OS_MACOSX) - return new ConfigurationPolicyProviderMac(policy_list); + scoped_ptr<AsyncPolicyLoader> loader( + new PolicyLoaderMac(policy_list, new MacPreferences())); + return new AsyncPolicyProvider(policy_list, loader.Pass()); #elif defined(OS_POSIX) FilePath config_dir_path; if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) { diff --git a/chrome/browser/policy/configuration_policy_provider_mac.h b/chrome/browser/policy/configuration_policy_provider_mac.h deleted file mode 100644 index e2bf37a..0000000 --- a/chrome/browser/policy/configuration_policy_provider_mac.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_MAC_H_ -#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_MAC_H_ -#pragma once - -#include <CoreFoundation/CoreFoundation.h> - -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/policy/file_based_policy_provider.h" - -class MacPreferences; - -namespace base { -class Value; -} - -namespace policy { - -// A provider delegate implementation that reads Mac OS X's managed preferences. -class MacPreferencesPolicyProviderDelegate - : public FileBasedPolicyProvider::ProviderDelegate { - public: - // Takes ownership of |preferences|. - MacPreferencesPolicyProviderDelegate( - MacPreferences* preferences, - const PolicyDefinitionList* policy_list); - virtual ~MacPreferencesPolicyProviderDelegate(); - - // FileBasedPolicyLoader::Delegate implementation. - virtual scoped_ptr<PolicyBundle> Load() OVERRIDE; - virtual base::Time GetLastModification() OVERRIDE; - - // Converts a CFPropertyListRef to the equivalent base::Value. CFDictionary - // entries whose key is not a CFStringRef are ignored. - // The returned value is owned by the caller. - // Returns NULL if an invalid CFType was found, such as CFDate or CFData. - static base::Value* CreateValueFromProperty(CFPropertyListRef property); - - private: - // In order to access the application preferences API, the names and values of - // the policies that are recognized must be known to the loader. - // Unfortunately, we cannot get the policy list at load time from the - // provider, because the loader may outlive the provider, so we store our own - // pointer to the list. - const PolicyDefinitionList* policy_list_; - - scoped_ptr<MacPreferences> preferences_; - - DISALLOW_COPY_AND_ASSIGN(MacPreferencesPolicyProviderDelegate); -}; - -// An implementation of |ConfigurationPolicyProvider| using the mechanism -// provided by Mac OS X's managed preferences. -class ConfigurationPolicyProviderMac : public FileBasedPolicyProvider { - public: - explicit ConfigurationPolicyProviderMac( - const PolicyDefinitionList* policy_list); - - // For testing; takes ownership of |preferences|. - ConfigurationPolicyProviderMac(const PolicyDefinitionList* policy_list, - MacPreferences* preferences); - - DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProviderMac); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_MAC_H_ diff --git a/chrome/browser/policy/configuration_policy_provider_test.cc b/chrome/browser/policy/configuration_policy_provider_test.cc index 64a83c0..c6c9ab1 100644 --- a/chrome/browser/policy/configuration_policy_provider_test.cc +++ b/chrome/browser/policy/configuration_policy_provider_test.cc @@ -14,6 +14,7 @@ #include "policy/policy_constants.h" #include "testing/gmock/include/gmock/gmock.h" +using content::BrowserThread; using ::testing::Mock; using ::testing::_; @@ -41,6 +42,16 @@ const PolicyDefinitionList kList = { } // namespace test_policy_definitions +PolicyTestBase::PolicyTestBase() + : ui_thread_(BrowserThread::UI, &loop_), + file_thread_(BrowserThread::FILE, &loop_) {} + +PolicyTestBase::~PolicyTestBase() {} + +void PolicyTestBase::TearDown() { + loop_.RunAllPending(); +} + PolicyProviderTestHarness::PolicyProviderTestHarness(PolicyLevel level, PolicyScope scope) : level_(level), scope_(scope) {} @@ -60,7 +71,7 @@ ConfigurationPolicyProviderTest::ConfigurationPolicyProviderTest() {} ConfigurationPolicyProviderTest::~ConfigurationPolicyProviderTest() {} void ConfigurationPolicyProviderTest::SetUp() { - AsynchronousPolicyTestBase::SetUp(); + PolicyTestBase::SetUp(); test_harness_.reset((*GetParam())()); test_harness_->SetUp(); @@ -79,7 +90,7 @@ void ConfigurationPolicyProviderTest::TearDown() { // Give providers the chance to clean up after themselves on the file thread. provider_.reset(); - AsynchronousPolicyTestBase::TearDown(); + PolicyTestBase::TearDown(); } void ConfigurationPolicyProviderTest::CheckValue( diff --git a/chrome/browser/policy/configuration_policy_provider_test.h b/chrome/browser/policy/configuration_policy_provider_test.h index 126ca5e..a24519c 100644 --- a/chrome/browser/policy/configuration_policy_provider_test.h +++ b/chrome/browser/policy/configuration_policy_provider_test.h @@ -12,7 +12,7 @@ #include "base/callback_forward.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" -#include "chrome/browser/policy/asynchronous_policy_test_base.h" +#include "chrome/browser/policy/policy_constants.h" #include "content/public/test/test_browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -43,6 +43,25 @@ extern const PolicyDefinitionList kList; } // namespace test_policy_definitions +class PolicyTestBase : public testing::Test { + public: + PolicyTestBase(); + virtual ~PolicyTestBase(); + + // testing::Test: + virtual void TearDown() OVERRIDE; + + protected: + // Create an actual IO loop (needed by FilePathWatcher). + MessageLoopForIO loop_; + + private: + content::TestBrowserThread ui_thread_; + content::TestBrowserThread file_thread_; + + DISALLOW_COPY_AND_ASSIGN(PolicyTestBase); +}; + // An interface for creating a test policy provider and creating a policy // provider instance for testing. Used as the parameter to the abstract // ConfigurationPolicyProviderTest below. @@ -92,7 +111,7 @@ typedef PolicyProviderTestHarness* (*CreatePolicyProviderTestHarness)(); // policy provider implementation, passing in a suitable harness factory // function as the test parameter. class ConfigurationPolicyProviderTest - : public AsynchronousPolicyTestBase, + : public PolicyTestBase, public testing::WithParamInterface<CreatePolicyProviderTestHarness> { protected: ConfigurationPolicyProviderTest(); diff --git a/chrome/browser/policy/policy_loader_mac.cc b/chrome/browser/policy/policy_loader_mac.cc new file mode 100644 index 0000000..4e6c2f1 --- /dev/null +++ b/chrome/browser/policy/policy_loader_mac.cc @@ -0,0 +1,181 @@ +// Copyright (c) 2012 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 "chrome/browser/policy/policy_loader_mac.h" + +#include <string> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/file_util.h" +#include "base/mac/foundation_util.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/path_service.h" +#include "base/platform_file.h" +#include "base/sys_string_conversions.h" +#include "base/values.h" +#include "chrome/browser/policy/policy_bundle.h" +#include "chrome/browser/policy/policy_map.h" +#include "chrome/browser/preferences_mac.h" +#include "chrome/common/chrome_paths.h" +#include "policy/policy_constants.h" + +using base::mac::CFCast; +using base::mac::ScopedCFTypeRef; + +namespace policy { + +namespace { + +FilePath GetManagedPolicyPath() { + // This constructs the path to the plist file in which Mac OS X stores the + // managed preference for the application. This is undocumented and therefore + // fragile, but if it doesn't work out, AsyncPolicyLoader has a task that + // polls periodically in order to reload managed preferences later even if we + // missed the change. + FilePath path; + if (!PathService::Get(chrome::DIR_MANAGED_PREFS, &path)) + return FilePath(); + + CFBundleRef bundle(CFBundleGetMainBundle()); + if (!bundle) + return FilePath(); + + CFStringRef bundle_id = CFBundleGetIdentifier(bundle); + if (!bundle_id) + return FilePath(); + + return path.Append(base::SysCFStringRefToUTF8(bundle_id) + ".plist"); +} + +// Callback function for CFDictionaryApplyFunction. |key| and |value| are an +// entry of the CFDictionary that should be converted into an equivalent entry +// in the DictionaryValue in |context|. +void DictionaryEntryToValue(const void* key, const void* value, void* context) { + if (CFStringRef cf_key = CFCast<CFStringRef>(key)) { + base::Value* converted = + PolicyLoaderMac::CreateValueFromProperty( + static_cast<CFPropertyListRef>(value)); + if (converted) { + const std::string string = base::SysCFStringRefToUTF8(cf_key); + static_cast<base::DictionaryValue *>(context)->Set(string, converted); + } + } +} + +// Callback function for CFArrayApplyFunction. |value| is an entry of the +// CFArray that should be converted into an equivalent entry in the ListValue +// in |context|. +void ArrayEntryToValue(const void* value, void* context) { + base::Value* converted = + PolicyLoaderMac::CreateValueFromProperty( + static_cast<CFPropertyListRef>(value)); + if (converted) + static_cast<base::ListValue *>(context)->Append(converted); +} + +} // namespace + +PolicyLoaderMac::PolicyLoaderMac(const PolicyDefinitionList* policy_list, + MacPreferences* preferences) + : policy_list_(policy_list), + preferences_(preferences), + managed_policy_path_(GetManagedPolicyPath()) {} + +PolicyLoaderMac::~PolicyLoaderMac() {} + +void PolicyLoaderMac::InitOnFile() { + if (!managed_policy_path_.empty()) { + watcher_.Watch( + managed_policy_path_, + base::Bind(&PolicyLoaderMac::OnFileUpdated, base::Unretained(this))); + } +} + +scoped_ptr<PolicyBundle> PolicyLoaderMac::Load() { + preferences_->AppSynchronize(kCFPreferencesCurrentApplication); + scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); + PolicyMap& chrome_policy = bundle->Get(POLICY_DOMAIN_CHROME, std::string()); + + const PolicyDefinitionList::Entry* current; + for (current = policy_list_->begin; current != policy_list_->end; ++current) { + base::mac::ScopedCFTypeRef<CFStringRef> name( + base::SysUTF8ToCFStringRef(current->name)); + base::mac::ScopedCFTypeRef<CFPropertyListRef> value( + preferences_->CopyAppValue(name, kCFPreferencesCurrentApplication)); + if (!value.get()) + continue; + bool forced = + preferences_->AppValueIsForced(name, kCFPreferencesCurrentApplication); + PolicyLevel level = forced ? POLICY_LEVEL_MANDATORY : + POLICY_LEVEL_RECOMMENDED; + // TODO(joaodasilva): figure the policy scope. + base::Value* policy = CreateValueFromProperty(value); + if (policy) + chrome_policy.Set(current->name, level, POLICY_SCOPE_USER, policy); + } + + return bundle.Pass(); +} + +base::Time PolicyLoaderMac::LastModificationTime() { + base::PlatformFileInfo file_info; + if (!file_util::GetFileInfo(managed_policy_path_, &file_info) || + file_info.is_directory) { + return base::Time(); + } + + return file_info.last_modified; +} + +// static +base::Value* PolicyLoaderMac::CreateValueFromProperty( + CFPropertyListRef property) { + if (CFCast<CFNullRef>(property)) + return base::Value::CreateNullValue(); + + if (CFBooleanRef boolean = CFCast<CFBooleanRef>(property)) + return base::Value::CreateBooleanValue(CFBooleanGetValue(boolean)); + + if (CFNumberRef number = CFCast<CFNumberRef>(property)) { + // CFNumberGetValue() converts values implicitly when the conversion is not + // lossy. Check the type before trying to convert. + if (CFNumberIsFloatType(number)) { + double double_value; + if (CFNumberGetValue(number, kCFNumberDoubleType, &double_value)) + return base::Value::CreateDoubleValue(double_value); + } else { + int int_value; + if (CFNumberGetValue(number, kCFNumberIntType, &int_value)) + return base::Value::CreateIntegerValue(int_value); + } + } + + if (CFStringRef string = CFCast<CFStringRef>(property)) + return base::Value::CreateStringValue(base::SysCFStringRefToUTF8(string)); + + if (CFDictionaryRef dict = CFCast<CFDictionaryRef>(property)) { + base::DictionaryValue* dict_value = new base::DictionaryValue(); + CFDictionaryApplyFunction(dict, DictionaryEntryToValue, dict_value); + return dict_value; + } + + if (CFArrayRef array = CFCast<CFArrayRef>(property)) { + base::ListValue* list_value = new base::ListValue(); + CFArrayApplyFunction(array, + CFRangeMake(0, CFArrayGetCount(array)), + ArrayEntryToValue, + list_value); + return list_value; + } + + return NULL; +} + +void PolicyLoaderMac::OnFileUpdated(const FilePath& path, bool error) { + if (!error) + Reload(false); +} + +} // namespace policy diff --git a/chrome/browser/policy/policy_loader_mac.h b/chrome/browser/policy/policy_loader_mac.h new file mode 100644 index 0000000..e141ee8 --- /dev/null +++ b/chrome/browser/policy/policy_loader_mac.h @@ -0,0 +1,65 @@ +// Copyright (c) 2012 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. + +#ifndef CHROME_BROWSER_POLICY_POLICY_LOADER_MAC_H_ +#define CHROME_BROWSER_POLICY_POLICY_LOADER_MAC_H_ +#pragma once + +#include <CoreFoundation/CoreFoundation.h> + +#include "base/file_path.h" +#include "base/files/file_path_watcher.h" +#include "chrome/browser/policy/async_policy_loader.h" + +class MacPreferences; + +namespace base { +class Value; +} // namespace base + +namespace policy { + +struct PolicyDefinitionList; + +// A policy loader that loads policies from the Mac preferences system, and +// watches the managed preferences files for updates. +class PolicyLoaderMac : public AsyncPolicyLoader { + public: + PolicyLoaderMac(const PolicyDefinitionList* policy_list, + MacPreferences* preferences); + virtual ~PolicyLoaderMac(); + + // AsyncPolicyLoader implementation. + virtual void InitOnFile() OVERRIDE; + virtual scoped_ptr<PolicyBundle> Load() OVERRIDE; + virtual base::Time LastModificationTime() OVERRIDE; + + // Converts a CFPropertyListRef to the equivalent base::Value. CFDictionary + // entries whose key is not a CFStringRef are ignored. + // The returned value is owned by the caller. + // Returns NULL if an invalid CFType was found, such as CFDate or CFData. + static base::Value* CreateValueFromProperty(CFPropertyListRef property); + + private: + // Callback for the FilePathWatcher. + void OnFileUpdated(const FilePath& path, bool error); + + // List of recognized policies. + const PolicyDefinitionList* policy_list_; + + scoped_ptr<MacPreferences> preferences_; + + // Path to the managed preferences file for the current user, if it could + // be found. Updates of this file trigger a policy reload. + FilePath managed_policy_path_; + + // Watches for events on the |managed_policy_path_|. + base::files::FilePathWatcher watcher_; + + DISALLOW_COPY_AND_ASSIGN(PolicyLoaderMac); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_POLICY_LOADER_MAC_H_ diff --git a/chrome/browser/policy/policy_loader_mac_unittest.cc b/chrome/browser/policy/policy_loader_mac_unittest.cc new file mode 100644 index 0000000..51a31c8 --- /dev/null +++ b/chrome/browser/policy/policy_loader_mac_unittest.cc @@ -0,0 +1,321 @@ +// Copyright (c) 2012 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 <CoreFoundation/CoreFoundation.h> + +#include "base/basictypes.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/sys_string_conversions.h" +#include "base/values.h" +#include "chrome/browser/policy/async_policy_provider.h" +#include "chrome/browser/policy/configuration_policy_provider_test.h" +#include "chrome/browser/policy/policy_bundle.h" +#include "chrome/browser/policy/policy_loader_mac.h" +#include "chrome/browser/policy/policy_map.h" +#include "chrome/browser/preferences_mock_mac.h" +#include "policy/policy_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::mac::ScopedCFTypeRef; + +namespace policy { + +namespace { + +// Converts a base::Value to the equivalent CFPropertyListRef. +// The returned value is owned by the caller. +CFPropertyListRef CreatePropertyFromValue(const base::Value* value) { + switch (value->GetType()) { + case base::Value::TYPE_NULL: + return kCFNull; + + case base::Value::TYPE_BOOLEAN: { + bool bool_value; + if (value->GetAsBoolean(&bool_value)) + return bool_value ? kCFBooleanTrue : kCFBooleanFalse; + break; + } + + case base::Value::TYPE_INTEGER: { + int int_value; + if (value->GetAsInteger(&int_value)) { + return CFNumberCreate( + kCFAllocatorDefault, kCFNumberIntType, &int_value); + } + break; + } + + case base::Value::TYPE_DOUBLE: { + double double_value; + if (value->GetAsDouble(&double_value)) { + return CFNumberCreate( + kCFAllocatorDefault, kCFNumberDoubleType, &double_value); + } + break; + } + + case base::Value::TYPE_STRING: { + std::string string_value; + if (value->GetAsString(&string_value)) + return base::SysUTF8ToCFStringRef(string_value); + break; + } + + case base::Value::TYPE_DICTIONARY: { + const base::DictionaryValue* dict_value; + if (value->GetAsDictionary(&dict_value)) { + // |dict| is owned by the caller. + CFMutableDictionaryRef dict = + CFDictionaryCreateMutable(kCFAllocatorDefault, + dict_value->size(), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + for (base::DictionaryValue::Iterator iterator(*dict_value); + iterator.HasNext(); iterator.Advance()) { + // CFDictionaryAddValue() retains both |key| and |value|, so make sure + // the references are balanced. + ScopedCFTypeRef<CFStringRef> key( + base::SysUTF8ToCFStringRef(iterator.key())); + ScopedCFTypeRef<CFPropertyListRef> cf_value( + CreatePropertyFromValue(&iterator.value())); + if (cf_value) + CFDictionaryAddValue(dict, key, cf_value); + } + return dict; + } + break; + } + + case base::Value::TYPE_LIST: { + const base::ListValue* list; + if (value->GetAsList(&list)) { + CFMutableArrayRef array = + CFArrayCreateMutable(NULL, list->GetSize(), &kCFTypeArrayCallBacks); + for (base::ListValue::const_iterator it(list->begin()); + it != list->end(); ++it) { + // CFArrayAppendValue() retains |value|, so make sure the reference + // created by CreatePropertyFromValue() is released. + ScopedCFTypeRef<CFPropertyListRef> cf_value( + CreatePropertyFromValue(*it)); + if (cf_value) + CFArrayAppendValue(array, cf_value); + } + return array; + } + break; + } + + case base::Value::TYPE_BINARY: + // This type isn't converted (though it can be represented as CFData) + // because there's no equivalent JSON type, and policy values can only + // take valid JSON values. + break; + } + + return NULL; +} + +class TestHarness : public PolicyProviderTestHarness { + public: + TestHarness(); + virtual ~TestHarness(); + + virtual void SetUp() OVERRIDE; + + virtual ConfigurationPolicyProvider* CreateProvider( + const PolicyDefinitionList* policy_definition_list) OVERRIDE; + + virtual void InstallEmptyPolicy() OVERRIDE; + virtual void InstallStringPolicy(const std::string& policy_name, + const std::string& policy_value) OVERRIDE; + virtual void InstallIntegerPolicy(const std::string& policy_name, + int policy_value) OVERRIDE; + virtual void InstallBooleanPolicy(const std::string& policy_name, + bool policy_value) OVERRIDE; + virtual void InstallStringListPolicy( + const std::string& policy_name, + const base::ListValue* policy_value) OVERRIDE; + virtual void InstallDictionaryPolicy( + const std::string& policy_name, + const base::DictionaryValue* policy_value) OVERRIDE; + + static PolicyProviderTestHarness* Create(); + + private: + MockPreferences* prefs_; + + DISALLOW_COPY_AND_ASSIGN(TestHarness); +}; + +TestHarness::TestHarness() + : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER) {} + +TestHarness::~TestHarness() {} + +void TestHarness::SetUp() {} + +ConfigurationPolicyProvider* TestHarness::CreateProvider( + const PolicyDefinitionList* policy_definition_list) { + prefs_ = new MockPreferences(); + scoped_ptr<AsyncPolicyLoader> loader( + new PolicyLoaderMac(policy_definition_list, prefs_)); + return new AsyncPolicyProvider(policy_definition_list, loader.Pass()); +} + +void TestHarness::InstallEmptyPolicy() {} + +void TestHarness::InstallStringPolicy(const std::string& policy_name, + const std::string& policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + ScopedCFTypeRef<CFStringRef> value(base::SysUTF8ToCFStringRef(policy_value)); + prefs_->AddTestItem(name, value, true); +} + +void TestHarness::InstallIntegerPolicy(const std::string& policy_name, + int policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + ScopedCFTypeRef<CFNumberRef> value( + CFNumberCreate(NULL, kCFNumberIntType, &policy_value)); + prefs_->AddTestItem(name, value, true); +} + +void TestHarness::InstallBooleanPolicy(const std::string& policy_name, + bool policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + prefs_->AddTestItem(name, + policy_value ? kCFBooleanTrue : kCFBooleanFalse, + true); +} + +void TestHarness::InstallStringListPolicy(const std::string& policy_name, + const base::ListValue* policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + ScopedCFTypeRef<CFPropertyListRef> array( + CreatePropertyFromValue(policy_value)); + ASSERT_TRUE(array); + prefs_->AddTestItem(name, array, true); +} + +void TestHarness::InstallDictionaryPolicy( + const std::string& policy_name, + const base::DictionaryValue* policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + ScopedCFTypeRef<CFPropertyListRef> dict( + CreatePropertyFromValue(policy_value)); + ASSERT_TRUE(dict); + prefs_->AddTestItem(name, dict, true); +} + +// static +PolicyProviderTestHarness* TestHarness::Create() { + return new TestHarness(); +} + +} // namespace + +// Instantiate abstract test case for basic policy reading tests. +INSTANTIATE_TEST_CASE_P( + PolicyProviderMacTest, + ConfigurationPolicyProviderTest, + testing::Values(TestHarness::Create)); + +// Special test cases for some mac preferences details. +class PolicyLoaderMacTest : public PolicyTestBase { + protected: + PolicyLoaderMacTest() + : prefs_(new MockPreferences()), + loader_(new PolicyLoaderMac(&test_policy_definitions::kList, prefs_)), + provider_(&test_policy_definitions::kList, + scoped_ptr<AsyncPolicyLoader>(loader_)) {} + virtual ~PolicyLoaderMacTest() {} + + MockPreferences* prefs_; + PolicyLoaderMac* loader_; + AsyncPolicyProvider provider_; +}; + +TEST_F(PolicyLoaderMacTest, Invalid) { + ScopedCFTypeRef<CFStringRef> name( + base::SysUTF8ToCFStringRef(test_policy_definitions::kKeyString)); + const char buffer[] = "binary \xde\xad\xbe\xef data"; + ScopedCFTypeRef<CFDataRef> invalid_data( + CFDataCreate(kCFAllocatorDefault, + reinterpret_cast<const UInt8 *>(buffer), + arraysize(buffer))); + ASSERT_TRUE(invalid_data); + prefs_->AddTestItem(name, invalid_data.get(), true); + prefs_->AddTestItem(name, invalid_data.get(), false); + + // Make the provider read the updated |prefs_|. + provider_.RefreshPolicies(); + loop_.RunAllPending(); + const PolicyBundle kEmptyBundle; + EXPECT_TRUE(provider_.policies().Equals(kEmptyBundle)); +} + +TEST_F(PolicyLoaderMacTest, TestNonForcedValue) { + ScopedCFTypeRef<CFStringRef> name( + base::SysUTF8ToCFStringRef(test_policy_definitions::kKeyString)); + ScopedCFTypeRef<CFPropertyListRef> test_value( + base::SysUTF8ToCFStringRef("string value")); + ASSERT_TRUE(test_value.get()); + prefs_->AddTestItem(name, test_value.get(), false); + + // Make the provider read the updated |prefs_|. + provider_.RefreshPolicies(); + loop_.RunAllPending(); + PolicyBundle expected_bundle; + expected_bundle.Get(POLICY_DOMAIN_CHROME, "") + .Set(test_policy_definitions::kKeyString, POLICY_LEVEL_RECOMMENDED, + POLICY_SCOPE_USER, base::Value::CreateStringValue("string value")); + EXPECT_TRUE(provider_.policies().Equals(expected_bundle)); +} + +TEST_F(PolicyLoaderMacTest, TestConversions) { + base::DictionaryValue root; + + // base::Value::TYPE_NULL + root.Set("null", base::Value::CreateNullValue()); + + // base::Value::TYPE_BOOLEAN + root.SetBoolean("false", false); + root.SetBoolean("true", true); + + // base::Value::TYPE_INTEGER + root.SetInteger("int", 123); + root.SetInteger("zero", 0); + + // base::Value::TYPE_DOUBLE + root.SetDouble("double", 123.456); + root.SetDouble("zerod", 0.0); + + // base::Value::TYPE_STRING + root.SetString("string", "the fox jumps over something"); + root.SetString("empty", ""); + + // base::Value::TYPE_LIST + base::ListValue list; + root.Set("emptyl", list.DeepCopy()); + for (base::DictionaryValue::Iterator it(root); it.HasNext(); it.Advance()) + list.Append(it.value().DeepCopy()); + EXPECT_EQ(root.size(), list.GetSize()); + list.Append(root.DeepCopy()); + root.Set("list", list.DeepCopy()); + + // base::Value::TYPE_DICTIONARY + base::DictionaryValue dict; + root.Set("emptyd", dict.DeepCopy()); + // Very meta. + root.Set("dict", root.DeepCopy()); + + ScopedCFTypeRef<CFPropertyListRef> property(CreatePropertyFromValue(&root)); + ASSERT_TRUE(property); + scoped_ptr<base::Value> value( + PolicyLoaderMac::CreateValueFromProperty(property)); + ASSERT_TRUE(value.get()); + + EXPECT_TRUE(root.Equals(value.get())); +} + +} // namespace policy diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 829f52b..4b59bb5 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1607,8 +1607,6 @@ 'browser/policy/configuration_policy_provider.h', 'browser/policy/configuration_policy_provider_delegate_win.cc', 'browser/policy/configuration_policy_provider_delegate_win.h', - 'browser/policy/configuration_policy_provider_mac.cc', - 'browser/policy/configuration_policy_provider_mac.h', 'browser/policy/configuration_policy_provider_win.cc', 'browser/policy/configuration_policy_provider_win.h', 'browser/policy/cros_user_policy_cache.cc', @@ -1638,6 +1636,8 @@ 'browser/policy/policy_constants.h', 'browser/policy/policy_error_map.cc', 'browser/policy/policy_error_map.h', + 'browser/policy/policy_loader_mac.cc', + 'browser/policy/policy_loader_mac.h', 'browser/policy/policy_notifier.cc', 'browser/policy/policy_notifier.h', 'browser/policy/policy_path_parser.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 7a7f795..e5c1a62 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1363,7 +1363,6 @@ 'browser/policy/configuration_policy_handler_chromeos_unittest.cc', 'browser/policy/configuration_policy_handler_unittest.cc', 'browser/policy/configuration_policy_pref_store_unittest.cc', - 'browser/policy/configuration_policy_provider_mac_unittest.cc', 'browser/policy/configuration_policy_provider_test.cc', 'browser/policy/configuration_policy_provider_test.h', 'browser/policy/configuration_policy_provider_win_unittest.cc', @@ -1387,6 +1386,7 @@ 'browser/policy/mock_device_management_service.h', 'browser/policy/network_configuration_updater_unittest.cc', 'browser/policy/policy_bundle_unittest.cc', + 'browser/policy/policy_loader_mac_unittest.cc', 'browser/policy/policy_map_unittest.cc', 'browser/policy/policy_path_parser_unittest.cc', 'browser/policy/policy_service_impl_unittest.cc', |
