diff options
Diffstat (limited to 'chrome_frame')
-rw-r--r-- | chrome_frame/chrome_frame.gyp | 3 | ||||
-rw-r--r-- | chrome_frame/policy_settings.cc | 70 | ||||
-rw-r--r-- | chrome_frame/policy_settings.h | 45 | ||||
-rw-r--r-- | chrome_frame/test/policy_settings_unittest.cc | 156 | ||||
-rw-r--r-- | chrome_frame/utils.cc | 28 |
5 files changed, 296 insertions, 6 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp index bdc9c2f..3560f7f 100644 --- a/chrome_frame/chrome_frame.gyp +++ b/chrome_frame/chrome_frame.gyp @@ -139,6 +139,7 @@ 'test/exception_barrier_unittest.cc', 'test/html_util_unittests.cc', 'test/http_negotiate_unittest.cc', + 'test/policy_settings_unittest.cc', 'test/simulate_input.h', 'test/simulate_input.cc', 'test/urlmon_moniker_tests.h', @@ -692,6 +693,8 @@ 'module_utils.cc', 'module_utils.h', 'ole_document_impl.h', + 'policy_settings.cc', + 'policy_settings.h', 'protocol_sink_wrap.cc', 'protocol_sink_wrap.h', 'register_bho.rgs', diff --git a/chrome_frame/policy_settings.cc b/chrome_frame/policy_settings.cc new file mode 100644 index 0000000..f1c9984 --- /dev/null +++ b/chrome_frame/policy_settings.cc @@ -0,0 +1,70 @@ +// Copyright (c) 2010 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_frame/policy_settings.h" + +#include "base/logging.h" +#include "base/registry.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "chrome/common/policy_constants.h" + +PolicySettings::RendererForUrl PolicySettings::GetRendererForUrl( + const wchar_t* url) { + RendererForUrl renderer = default_renderer_; + std::vector<std::wstring>::const_iterator it; + for (it = renderer_exclusion_list_.begin(); + it != renderer_exclusion_list_.end(); ++it) { + if (MatchPattern(url, (*it))) { + renderer = (renderer == RENDER_IN_HOST) ? + RENDER_IN_CHROME_FRAME : RENDER_IN_HOST; + break; + } + } + return renderer; +} + +void PolicySettings::RefreshFromRegistry() { + default_renderer_ = RENDERER_NOT_SPECIFIED; + renderer_exclusion_list_.clear(); + + RegKey config_key; + DWORD value = RENDERER_NOT_SPECIFIED; + HKEY root_key[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; + std::wstring settings_value( + ASCIIToWide(policy::key::kChromeFrameRendererSettings)); + for (int i = 0; i < arraysize(root_key); ++i) { + if (config_key.Open(root_key[i], policy::kRegistrySubKey, KEY_READ) && + config_key.ReadValueDW(settings_value.c_str(), &value)) { + break; + } else { + config_key.Close(); + } + } + + DCHECK(value == RENDERER_NOT_SPECIFIED || + value == RENDER_IN_HOST || + value == RENDER_IN_CHROME_FRAME) << + "invalid default renderer setting: " << value; + + if (value != RENDER_IN_HOST && value != RENDER_IN_CHROME_FRAME) { + DLOG(INFO) << "default renderer not specified via policy"; + } else { + default_renderer_ = static_cast<RendererForUrl>(value); + const char* exclusion_list_name = (default_renderer_ == RENDER_IN_HOST) ? + policy::key::kRenderInChromeFrameList : + policy::key::kRenderInHostList; + + RegistryValueIterator url_list(config_key.Handle(), + ASCIIToWide(exclusion_list_name).c_str()); + while (url_list.Valid()) { + renderer_exclusion_list_.push_back(url_list.Value()); + ++url_list; + } + DLOG(INFO) << "Default renderer as specified via policy: " << + default_renderer_ << " exclusion list size: " << + renderer_exclusion_list_.size(); + } +} + diff --git a/chrome_frame/policy_settings.h b/chrome_frame/policy_settings.h new file mode 100644 index 0000000..a4c1267 --- /dev/null +++ b/chrome_frame/policy_settings.h @@ -0,0 +1,45 @@ +// Copyright (c) 2010 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_FRAME_POLICY_SETTINGS_H_ +#define CHROME_FRAME_POLICY_SETTINGS_H_ + +#include <string> +#include <vector> + +// A simple class that reads and caches policy settings for Chrome Frame. +// TODO(tommi): Support refreshing when new settings are pushed. +// TODO(tommi): Use Chrome's classes for this (and the notification service). +class PolicySettings { + public: + typedef enum RendererForUrl { + RENDERER_NOT_SPECIFIED = -1, + RENDER_IN_HOST, + RENDER_IN_CHROME_FRAME, + }; + + PolicySettings() : default_renderer_(RENDERER_NOT_SPECIFIED) { + RefreshFromRegistry(); + } + + ~PolicySettings() { + } + + RendererForUrl default_renderer() const { + return default_renderer_; + } + + RendererForUrl GetRendererForUrl(const wchar_t* url); + + protected: + // Protected for now since the class is not thread safe. + void RefreshFromRegistry(); + + protected: + RendererForUrl default_renderer_; + std::vector<std::wstring> renderer_exclusion_list_; +}; + + +#endif // CHROME_FRAME_POLICY_SETTINGS_H_ diff --git a/chrome_frame/test/policy_settings_unittest.cc b/chrome_frame/test/policy_settings_unittest.cc new file mode 100644 index 0000000..9dee3d6 --- /dev/null +++ b/chrome_frame/test/policy_settings_unittest.cc @@ -0,0 +1,156 @@ +// Copyright (c) 2010 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 "base/basictypes.h" +#include "base/logging.h" +#include "base/registry.h" +#include "base/scoped_ptr.h" +#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" +#include "chrome/common/policy_constants.h" +#include "chrome_frame/policy_settings.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +// A best effort way to zap CF policy entries that may be in the registry. +void DeleteChromeFramePolicyEntries(HKEY root) { + RegKey key; + if (key.Open(root, policy::kRegistrySubKey, KEY_ALL_ACCESS)) { + key.DeleteValue( + ASCIIToWide(policy::key::kChromeFrameRendererSettings).c_str()); + key.DeleteKey(ASCIIToWide(policy::key::kRenderInChromeFrameList).c_str()); + key.DeleteKey(ASCIIToWide(policy::key::kRenderInHostList).c_str()); + } +} + +class TempRegKeyOverride { + public: + static const wchar_t kTempTestKeyPath[]; + + TempRegKeyOverride(HKEY override, const wchar_t* temp_name) + : override_(override), temp_name_(temp_name) { + DCHECK(temp_name && lstrlenW(temp_name)); + std::wstring key_path(kTempTestKeyPath); + key_path += L"\\" + temp_name_; + EXPECT_TRUE(temp_key_.Create(HKEY_CURRENT_USER, key_path.c_str(), + KEY_ALL_ACCESS)); + EXPECT_EQ(ERROR_SUCCESS, + ::RegOverridePredefKey(override_, temp_key_.Handle())); + } + + ~TempRegKeyOverride() { + ::RegOverridePredefKey(override_, NULL); + // The temp key will be deleted via a call to DeleteAllTempKeys(). + } + + static void DeleteAllTempKeys() { + RegKey key; + if (key.Open(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS)) { + key.DeleteKey(kTempTestKeyPath); + } + } + + protected: + HKEY override_; + RegKey temp_key_; + std::wstring temp_name_; +}; + +const wchar_t TempRegKeyOverride::kTempTestKeyPath[] = + L"Software\\Chromium\\TempTestKeys"; + +bool SetRendererSettings(HKEY policy_root, + PolicySettings::RendererForUrl renderer, + const wchar_t* exclusions[], + int exclusion_count) { + RegKey policy_key; + EXPECT_TRUE(policy_key.Create(policy_root, policy::kRegistrySubKey, + KEY_ALL_ACCESS)); + if (!policy_key.Valid()) + return false; + + policy_key.WriteValue( + ASCIIToWide(policy::key::kChromeFrameRendererSettings).c_str(), + static_cast<DWORD>(renderer)); + + std::wstring in_cf(ASCIIToWide(policy::key::kRenderInChromeFrameList)); + std::wstring in_host(ASCIIToWide(policy::key::kRenderInHostList)); + // Remove any previous settings + policy_key.DeleteKey(in_cf.c_str()); + policy_key.DeleteKey(in_host.c_str()); + + std::wstring exclusion_list( + renderer == PolicySettings::RENDER_IN_CHROME_FRAME ? in_host : in_cf); + RegKey exclusion_key; + EXPECT_TRUE(exclusion_key.Create(policy_key.Handle(), exclusion_list.c_str(), + KEY_ALL_ACCESS)); + for (int i = 0; i < exclusion_count; ++i) { + EXPECT_TRUE(exclusion_key.WriteValue(StringPrintf(L"%i", i).c_str(), + exclusions[i])); + } + + return true; +} + +} // end namespace + +TEST(PolicySettings, RendererForUrl) { + TempRegKeyOverride::DeleteAllTempKeys(); + + scoped_ptr<TempRegKeyOverride> hklm_pol( + new TempRegKeyOverride(HKEY_LOCAL_MACHINE, L"hklm_pol")); + scoped_ptr<TempRegKeyOverride> hkcu_pol( + new TempRegKeyOverride(HKEY_CURRENT_USER, L"hkcu_pol")); + + const wchar_t* kTestUrls[] = { + L"http://www.example.com", + L"http://www.pattern.com", + L"http://www.test.com" + }; + const wchar_t* kTestFilters[] = { + L"*.example.com", + L"*.pattern.com", + L"*.test.com" + }; + const wchar_t kNoMatchUrl[] = L"http://www.chromium.org"; + + scoped_ptr<PolicySettings> settings(new PolicySettings()); + EXPECT_EQ(settings->default_renderer(), + PolicySettings::RENDERER_NOT_SPECIFIED); + EXPECT_EQ(settings->GetRendererForUrl(kNoMatchUrl), + PolicySettings::RENDERER_NOT_SPECIFIED); + + HKEY root[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; + for (int i = 0; i < arraysize(root); ++i) { + EXPECT_TRUE(SetRendererSettings(root[i], + PolicySettings::RENDER_IN_CHROME_FRAME, kTestFilters, + arraysize(kTestFilters))); + + settings.reset(new PolicySettings()); + EXPECT_EQ(settings->GetRendererForUrl(kNoMatchUrl), + PolicySettings::RENDER_IN_CHROME_FRAME); + for (int j = 0; j < arraysize(kTestUrls); ++j) { + EXPECT_EQ(settings->GetRendererForUrl(kTestUrls[j]), + PolicySettings::RENDER_IN_HOST); + } + + EXPECT_TRUE(SetRendererSettings(root[i], + PolicySettings::RENDER_IN_HOST, NULL, 0)); + + settings.reset(new PolicySettings()); + EXPECT_EQ(settings->GetRendererForUrl(kNoMatchUrl), + PolicySettings::RENDER_IN_HOST); + for (int j = 0; j < arraysize(kTestUrls); ++j) { + EXPECT_EQ(settings->GetRendererForUrl(kTestUrls[j]), + PolicySettings::RENDER_IN_HOST); + } + + DeleteChromeFramePolicyEntries(root[i]); + } + + hkcu_pol.reset(NULL); + hklm_pol.reset(NULL); + TempRegKeyOverride::DeleteAllTempKeys(); +} diff --git a/chrome_frame/utils.cc b/chrome_frame/utils.cc index 8526b9a..35fbc83 100644 --- a/chrome_frame/utils.cc +++ b/chrome_frame/utils.cc @@ -28,6 +28,7 @@ #include "chrome/installer/util/chrome_frame_distribution.h" #include "chrome_frame/extra_system_apis.h" #include "chrome_frame/html_utils.h" +#include "chrome_frame/policy_settings.h" #include "chrome_frame/simple_resource_loader.h" #include "chrome_frame/utils.h" #include "googleurl/src/gurl.h" @@ -686,19 +687,34 @@ bool DeleteConfigValue(const wchar_t* value_name) { } bool IsGcfDefaultRenderer() { - // TODO(tommi): Implement caching for this config value as it gets - // checked frequently. DWORD is_default = 0; // NOLINT - RegKey config_key; - if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey, KEY_READ)) { - config_key.ReadValueDW(kEnableGCFRendererByDefault, &is_default); + + // First check policy settings + Singleton<PolicySettings> policy; + PolicySettings::RendererForUrl renderer = policy->default_renderer(); + if (renderer != PolicySettings::RENDERER_NOT_SPECIFIED) { + is_default = (renderer == PolicySettings::RENDER_IN_CHROME_FRAME); + } else { + // TODO(tommi): Implement caching for this config value as it gets + // checked frequently. + RegKey config_key; + if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey, KEY_READ)) { + config_key.ReadValueDW(kEnableGCFRendererByDefault, &is_default); + } } return is_default != 0; } bool IsOptInUrl(const wchar_t* url) { - // TODO(tommi): Unit test. + // First check if the default renderer settings are specified by policy. + // If so, then that overrides the user settings. + Singleton<PolicySettings> policy; + PolicySettings::RendererForUrl renderer = policy->GetRendererForUrl(url); + if (renderer != PolicySettings::RENDERER_NOT_SPECIFIED) { + return (renderer == PolicySettings::RENDER_IN_CHROME_FRAME); + } + RegKey config_key; if (!config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey, KEY_READ)) return false; |