diff options
author | simo@google.com <simo@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-31 16:10:04 +0000 |
---|---|---|
committer | simo@google.com <simo@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-31 16:10:04 +0000 |
commit | a8171203aadbc0d452ec3b46eb16d6b5b5e8427b (patch) | |
tree | 2c2b6003fa94f743bc6e6e4b5121a0edc93f62f0 /chrome/browser | |
parent | 5a2b69999950076443aa3c9c1def3c676eeeb870 (diff) | |
download | chromium_src-a8171203aadbc0d452ec3b46eb16d6b5b5e8427b.zip chromium_src-a8171203aadbc0d452ec3b46eb16d6b5b5e8427b.tar.gz chromium_src-a8171203aadbc0d452ec3b46eb16d6b5b5e8427b.tar.bz2 |
First CL for the about:policy page. This only implements the policy section of the page.
Preliminary design doc:
https://docs.google.com/a/google.com/document/d/1KWsF52ImY4eJbNgizaA6Gw_aMVg24zgZfypKZBs376k/edit?hl=en_US&ndplr=1
TEST=set some policies, start chrome and go to chrome://policy
Review URL: http://codereview.chromium.org/7585036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98977 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/browser_resources.grd | 3 | ||||
-rw-r--r-- | chrome/browser/policy/configuration_policy_reader.cc | 272 | ||||
-rw-r--r-- | chrome/browser/policy/configuration_policy_reader.h | 120 | ||||
-rw-r--r-- | chrome/browser/policy/configuration_policy_reader_unittest.cc | 352 | ||||
-rw-r--r-- | chrome/browser/policy/mock_configuration_policy_reader.cc | 13 | ||||
-rw-r--r-- | chrome/browser/policy/mock_configuration_policy_reader.h | 28 | ||||
-rw-r--r-- | chrome/browser/policy/policy_status_info.cc | 86 | ||||
-rw-r--r-- | chrome/browser/policy/policy_status_info.h | 97 | ||||
-rw-r--r-- | chrome/browser/resources/policy.css | 143 | ||||
-rw-r--r-- | chrome/browser/resources/policy.html | 14 | ||||
-rw-r--r-- | chrome/browser/resources/policy.js | 160 | ||||
-rw-r--r-- | chrome/browser/ui/webui/chrome_web_ui_factory.cc | 3 | ||||
-rw-r--r-- | chrome/browser/ui/webui/policy_ui.cc | 109 | ||||
-rw-r--r-- | chrome/browser/ui/webui/policy_ui.h | 46 |
14 files changed, 1438 insertions, 8 deletions
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 7891f2a..992e4e0 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -87,6 +87,9 @@ <include name="IDR_NOTIFICATION_ICON_HTML" file="resources\notification_icon.html" type="BINDATA" /> <include name="IDR_PLUGINS_HTML" file="resources\plugins.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_PLUGINS_JS" file="resources\plugins.js" type="BINDATA" /> + <include name="IDR_POLICY_HTML" file="resources\policy.html" type="BINDATA"/> + <include name="IDR_POLICY_CSS" file="resources\policy.css" type="BINDATA"/> + <include name="IDR_POLICY_JS" file="resources\policy.js" type="BINDATA"/> <include name="IDR_READER_OUT_OF_DATE_HTML" file="resources\reader_out_of_date.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_PRINT_PREVIEW_HTML" file="resources\print_preview\print_preview.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_PRINT_PREVIEW_JS" file="resources\print_preview\print_preview.js" flattenhtml="true" type="BINDATA" /> diff --git a/chrome/browser/policy/configuration_policy_reader.cc b/chrome/browser/policy/configuration_policy_reader.cc new file mode 100644 index 0000000..472a151 --- /dev/null +++ b/chrome/browser/policy/configuration_policy_reader.cc @@ -0,0 +1,272 @@ +// Copyright (c) 2011 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/configuration_policy_reader.h" + +#include <map> +#include <vector> + +#include "base/stl_util.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/policy/browser_policy_connector.h" +#include "chrome/browser/policy/configuration_policy_pref_store.h" +#include "chrome/browser/policy/configuration_policy_store_interface.h" + +namespace policy { + +// This class functions as a container for policy status information used by the +// ConfigurationPolicyReader class. It obtains policy values from a +// ConfigurationPolicyProvider and maps them to their status information. +class ConfigurationPolicyStatusKeeper + : public ConfigurationPolicyStoreInterface { + public: + ConfigurationPolicyStatusKeeper(ConfigurationPolicyProvider* provider, + PolicyStatusInfo::PolicyLevel policy_level); + virtual ~ConfigurationPolicyStatusKeeper(); + + // ConfigurationPolicyStoreInterface methods. + virtual void Apply(ConfigurationPolicyType policy, base::Value* value); + + // Returns a pointer to a DictionaryValue containing the status information + // of the policy |policy|. The caller acquires ownership of the returned + // value. Returns NULL if no such policy is stored in this keeper. + DictionaryValue* GetPolicyStatus(ConfigurationPolicyType policy) const; + + private: + typedef std::map<ConfigurationPolicyType, PolicyStatusInfo*> PolicyStatusMap; + typedef std::map<ConfigurationPolicyType, string16> PolicyNameMap; + typedef ConfigurationPolicyProvider::PolicyDefinitionList + PolicyDefinitionList; + + // Mapping from ConfigurationPolicyType to PolicyStatusInfo. + PolicyStatusMap policy_map_; + + // The level of the policies stored in this keeper (mandatory or + // recommended). + PolicyStatusInfo::PolicyLevel policy_level_; + + DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyStatusKeeper); +}; + +// ConfigurationPolicyStatusKeeper +ConfigurationPolicyStatusKeeper::ConfigurationPolicyStatusKeeper( + ConfigurationPolicyProvider* provider, + PolicyStatusInfo::PolicyLevel policy_level) : policy_level_(policy_level) { + + if (!provider->Provide(this)) + LOG(WARNING) << "Failed to get policy from provider."; +} + +ConfigurationPolicyStatusKeeper::~ConfigurationPolicyStatusKeeper() { + STLDeleteContainerPairSecondPointers(policy_map_.begin(), policy_map_.end()); + policy_map_.clear(); +} + +void ConfigurationPolicyStatusKeeper::Apply( + ConfigurationPolicyType policy, base::Value* value) { + string16 name = PolicyStatus::GetPolicyName(policy); + + if (name == string16()) { + NOTREACHED(); + } + + // TODO(simo) actually determine whether the policy is a user or a device one + // and whether the policy could be enforced or not once this information + // is available. + PolicyStatusInfo* info = new PolicyStatusInfo(name, + PolicyStatusInfo::USER, + policy_level_, + value, + PolicyStatusInfo::ENFORCED, + string16()); + policy_map_[policy] = info; +} + +DictionaryValue* ConfigurationPolicyStatusKeeper::GetPolicyStatus( + ConfigurationPolicyType policy) const { + PolicyStatusMap::const_iterator entry = policy_map_.find(policy); + return entry != policy_map_.end() ? + (entry->second)->GetDictionaryValue() : NULL; +} + +// ConfigurationPolicyReader +ConfigurationPolicyReader::~ConfigurationPolicyReader() { +} + +void ConfigurationPolicyReader::OnUpdatePolicy() { + Refresh(); +} + +void ConfigurationPolicyReader::OnProviderGoingAway() { + provider_ = NULL; +} + +// static +ConfigurationPolicyReader* + ConfigurationPolicyReader::CreateManagedPlatformPolicyReader() { + BrowserPolicyConnector* connector = + g_browser_process->browser_policy_connector(); + return new ConfigurationPolicyReader( + connector->GetManagedPlatformProvider(), PolicyStatusInfo::MANDATORY); +} + +// static +ConfigurationPolicyReader* + ConfigurationPolicyReader::CreateManagedCloudPolicyReader() { + BrowserPolicyConnector* connector = + g_browser_process->browser_policy_connector(); + return new ConfigurationPolicyReader( + connector->GetManagedCloudProvider(), PolicyStatusInfo::MANDATORY); +} + +// static +ConfigurationPolicyReader* + ConfigurationPolicyReader::CreateRecommendedPlatformPolicyReader() { + BrowserPolicyConnector* connector = + g_browser_process->browser_policy_connector(); + return new ConfigurationPolicyReader( + connector->GetRecommendedPlatformProvider(), + PolicyStatusInfo::RECOMMENDED); +} + +// static +ConfigurationPolicyReader* + ConfigurationPolicyReader::CreateRecommendedCloudPolicyReader() { + BrowserPolicyConnector* connector = + g_browser_process->browser_policy_connector(); + return new ConfigurationPolicyReader( + connector->GetRecommendedCloudProvider(), PolicyStatusInfo::RECOMMENDED); +} + +DictionaryValue* ConfigurationPolicyReader::GetPolicyStatus( + ConfigurationPolicyType policy) const { + return policy_keeper_->GetPolicyStatus(policy); +} + +ConfigurationPolicyReader::ConfigurationPolicyReader( + ConfigurationPolicyProvider* provider, + PolicyStatusInfo::PolicyLevel policy_level) + : provider_(provider), + policy_level_(policy_level) { + if (provider_) { + // Read initial policy. + policy_keeper_.reset( + new ConfigurationPolicyStatusKeeper(provider, policy_level)); + registrar_.Init(provider_, this); + } +} + +ConfigurationPolicyReader::ConfigurationPolicyReader() + : provider_(NULL), + policy_level_(PolicyStatusInfo::LEVEL_UNDEFINED), + policy_keeper_(NULL) { +} + +void ConfigurationPolicyReader::Refresh() { + if (!provider_) + return; + + // Read policy state into a new keeper and swap out old keeper. + scoped_ptr<ConfigurationPolicyStatusKeeper> new_keeper( + new ConfigurationPolicyStatusKeeper(provider_, policy_level_)); + policy_keeper_.reset(new_keeper.release()); +} + +// PolicyStatus +PolicyStatus::PolicyStatus(ConfigurationPolicyReader* managed_platform, + ConfigurationPolicyReader* managed_cloud, + ConfigurationPolicyReader* recommended_platform, + ConfigurationPolicyReader* recommended_cloud) + : managed_platform_(managed_platform), + managed_cloud_(managed_cloud), + recommended_platform_(recommended_platform), + recommended_cloud_(recommended_cloud) { +} + +PolicyStatus::~PolicyStatus() { +} + +ListValue* PolicyStatus::GetPolicyStatusList(bool* any_policies_sent) const { + ListValue* result = new ListValue(); + std::vector<DictionaryValue*> unsent_policies; + + *any_policies_sent = false; + const PolicyDefinitionList* supported_policies = + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); + const PolicyDefinitionList::Entry* policy = supported_policies->begin; + for ( ; policy != supported_policies->end; ++policy) { + if (!AddPolicyFromReaders(policy->policy_type, result)) { + PolicyStatusInfo info(ASCIIToUTF16(policy->name), + PolicyStatusInfo::SOURCE_TYPE_UNDEFINED, + PolicyStatusInfo::LEVEL_UNDEFINED, + Value::CreateNullValue(), + PolicyStatusInfo::STATUS_UNDEFINED, + string16()); + unsent_policies.push_back(info.GetDictionaryValue()); + } else { + *any_policies_sent = true; + } + } + + // Add policies that weren't actually sent from providers to list. + std::vector<DictionaryValue*>::const_iterator info = unsent_policies.begin(); + for ( ; info != unsent_policies.end(); ++info) + result->Append(*info); + + return result; +} + +// static +string16 PolicyStatus::GetPolicyName(ConfigurationPolicyType policy_type) { + static std::map<ConfigurationPolicyType, string16> name_map; + static const ConfigurationPolicyProvider::PolicyDefinitionList* + supported_policies; + + if (!supported_policies) { + supported_policies = + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); + + // Create mapping from ConfigurationPolicyTypes to actual policy names. + const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* entry = + supported_policies->begin; + for ( ; entry != supported_policies->end; ++entry) + name_map[entry->policy_type] = ASCIIToUTF16(entry->name); + } + + std::map<ConfigurationPolicyType, string16>::const_iterator entry = + name_map.find(policy_type); + + if (entry == name_map.end()) + return string16(); + + return entry->second; +} + +bool PolicyStatus::AddPolicyFromReaders( + ConfigurationPolicyType policy, ListValue* list) const { + DictionaryValue* mp_policy = + managed_platform_->GetPolicyStatus(policy); + DictionaryValue* mc_policy = + managed_cloud_->GetPolicyStatus(policy); + DictionaryValue* rp_policy = + recommended_platform_->GetPolicyStatus(policy); + DictionaryValue* rc_policy = + recommended_cloud_->GetPolicyStatus(policy); + + bool added_policy = mp_policy || mc_policy || rp_policy || rc_policy; + + if (mp_policy) + list->Append(mp_policy); + if (mc_policy) + list->Append(mc_policy); + if (rp_policy) + list->Append(rp_policy); + if (rc_policy) + list->Append(rc_policy); + + return added_policy; +} + +} // namespace policy diff --git a/chrome/browser/policy/configuration_policy_reader.h b/chrome/browser/policy/configuration_policy_reader.h new file mode 100644 index 0000000..372ff28 --- /dev/null +++ b/chrome/browser/policy/configuration_policy_reader.h @@ -0,0 +1,120 @@ +// Copyright (c) 2011 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_READER_H_ +#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_READER_H_ +#pragma once + +#include "base/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/policy/configuration_policy_provider.h" +#include "chrome/browser/policy/policy_status_info.h" + +namespace policy { + +class ConfigurationPolicyStatusKeeper; + +// This class reads policy information from a ConfigurationPolicyProvider in +// order to determine the status of a policy (this includes its value and +// whether it could be enforced on the client or not), as required by the +// about:policy UI. +class ConfigurationPolicyReader : public ConfigurationPolicyProvider::Observer { + public: + ConfigurationPolicyReader(ConfigurationPolicyProvider* provider, + PolicyStatusInfo::PolicyLevel policy_level); + virtual ~ConfigurationPolicyReader(); + + // ConfigurationPolicyProvider::Observer methods: + virtual void OnUpdatePolicy(); + virtual void OnProviderGoingAway(); + + // Creates a ConfigurationPolicyReader that reads managed platform policy. + static ConfigurationPolicyReader* + CreateManagedPlatformPolicyReader(); + + // Creates a ConfigurationPolicyReader that reads managed cloud policy. + static ConfigurationPolicyReader* + CreateManagedCloudPolicyReader(); + + // Creates a ConfigurationPolicyReader that reads recommended platform policy. + static ConfigurationPolicyReader* + CreateRecommendedPlatformPolicyReader(); + + // Creates a ConfigurationPolicyReader that reads recommended cloud policy. + static ConfigurationPolicyReader* + CreateRecommendedCloudPolicyReader(); + + // Returns a pointer to a DictionaryValue object containing policy status + // information for the UI. Ownership of the return value is acquired by the + // caller. Returns NULL if the reader is not aware of the given policy. + virtual DictionaryValue* + GetPolicyStatus(ConfigurationPolicyType policy) const; + + private: + friend class MockConfigurationPolicyReader; + + // Only used in tests. + ConfigurationPolicyReader(); + + // Updates the policy information held in this reader. This is called when + // the ConfigurationPolicyProvider is updated. + void Refresh(); + + // The policy provider from which policy settings are read. + ConfigurationPolicyProvider* provider_; + + // Whether this ConfigurationPolicyReader contains managed policies. + PolicyStatusInfo::PolicyLevel policy_level_; + + // Current policy status. + scoped_ptr<ConfigurationPolicyStatusKeeper> policy_keeper_; + + ConfigurationPolicyObserverRegistrar registrar_; + + DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyReader); +}; + +// This class combines the policy information from different +// ConfigurationPolicyReaders into a single list of policy information that the +// about:policy UI can display. +class PolicyStatus { + public: + PolicyStatus(ConfigurationPolicyReader* managed_platform, + ConfigurationPolicyReader* managed_cloud, + ConfigurationPolicyReader* recommended_platform, + ConfigurationPolicyReader* recommended_cloud); + ~PolicyStatus(); + + // Returns a ListValue pointer containing the status information of all + // policies supported by the client. |any_policies_sent| is set to true if + // there are policies in the list that were sent by a provider, otherwise + // it is set to false. This is for the about:policy UI to display. + ListValue* GetPolicyStatusList(bool* any_policies_sent) const; + + // Returns a string16 containing the actual name of the policy corresponding + // to |policy_type|. Returns an empty string if there is no such policy_type + // among the policies supported by the client. + static string16 GetPolicyName(ConfigurationPolicyType policy_type); + + private: + typedef ConfigurationPolicyProvider::PolicyDefinitionList + PolicyDefinitionList; + + // Add the policy information for |policy| to the ListValue pointed to be + // |list| as it is returned by the different ConfigurationPolicyReader + // objects. Returns true if a policy was added and false otherwise. + bool AddPolicyFromReaders(ConfigurationPolicyType policy, + ListValue* list) const; + + scoped_ptr<ConfigurationPolicyReader> managed_platform_; + scoped_ptr<ConfigurationPolicyReader> managed_cloud_; + scoped_ptr<ConfigurationPolicyReader> recommended_platform_; + scoped_ptr<ConfigurationPolicyReader> recommended_cloud_; + + DISALLOW_COPY_AND_ASSIGN(PolicyStatus); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_READER_H_ diff --git a/chrome/browser/policy/configuration_policy_reader_unittest.cc b/chrome/browser/policy/configuration_policy_reader_unittest.cc new file mode 100644 index 0000000..f7164a4 --- /dev/null +++ b/chrome/browser/policy/configuration_policy_reader_unittest.cc @@ -0,0 +1,352 @@ +// Copyright (c) 2011 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/scoped_ptr.h" +#include "base/string16.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/policy/configuration_policy_pref_store.h" +#include "chrome/browser/policy/configuration_policy_reader.h" +#include "chrome/browser/policy/mock_configuration_policy_provider.h" +#include "chrome/browser/policy/mock_configuration_policy_reader.h" +#include "policy/policy_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::Return; +using ::testing::ReturnNull; +using ::testing::_; + +namespace policy { + +class ConfigurationPolicyReaderTest : public testing::Test { + protected: + ConfigurationPolicyReaderTest() : provider_() { + managed_reader_.reset( + new ConfigurationPolicyReader(&provider_, PolicyStatusInfo::MANDATORY)); + recommended_reader_.reset(new ConfigurationPolicyReader(&provider_, + PolicyStatusInfo::RECOMMENDED)); + status_ok_ = ASCIIToUTF16("ok"); + } + + DictionaryValue* CreateDictionary(const char* policy_name, + Value* policy_value) { + DictionaryValue* dict = new DictionaryValue(); + dict->SetString( + PolicyStatusInfo::kNameDictPath, ASCIIToUTF16(policy_name)); + dict->SetString(PolicyStatusInfo::kLevelDictPath, + PolicyStatusInfo::GetPolicyLevelString(PolicyStatusInfo::MANDATORY)); + dict->SetString(PolicyStatusInfo::kSourceTypeDictPath, + PolicyStatusInfo::GetSourceTypeString(PolicyStatusInfo::USER)); + dict->Set(PolicyStatusInfo::kValueDictPath, policy_value); + dict->SetBoolean(PolicyStatusInfo::kSetDictPath, true); + dict->SetString(PolicyStatusInfo::kStatusDictPath, status_ok_); + + return dict; + } + + MockConfigurationPolicyProvider provider_; + scoped_ptr<ConfigurationPolicyReader> managed_reader_; + scoped_ptr<ConfigurationPolicyReader> recommended_reader_; + string16 status_ok_; +}; + +TEST_F(ConfigurationPolicyReaderTest, GetDefault) { + EXPECT_EQ(NULL, managed_reader_->GetPolicyStatus(kPolicyHomepageLocation)); +} + +// Test for list-valued policy settings. +TEST_F(ConfigurationPolicyReaderTest, SetListValue) { + ListValue* in_value = new ListValue(); + in_value->Append(Value::CreateStringValue("test1")); + in_value->Append(Value::CreateStringValue("test2")); + provider_.AddPolicy(kPolicyRestoreOnStartupURLs, in_value); + managed_reader_->OnUpdatePolicy(); + + scoped_ptr<DictionaryValue> + dict(CreateDictionary(key::kRestoreOnStartupURLs, in_value->DeepCopy())); + scoped_ptr<DictionaryValue> result( + managed_reader_->GetPolicyStatus(kPolicyRestoreOnStartupURLs)); + EXPECT_TRUE(dict->Equals(result.get())); + + recommended_reader_->OnUpdatePolicy(); + dict->SetString("level", + PolicyStatusInfo::GetPolicyLevelString(PolicyStatusInfo::RECOMMENDED)); + result.reset( + recommended_reader_->GetPolicyStatus(kPolicyRestoreOnStartupURLs)); + EXPECT_TRUE(dict->Equals(result.get())); +} + +// Test for string-valued policy settings. +TEST_F(ConfigurationPolicyReaderTest, SetStringValue) { + provider_.AddPolicy(kPolicyHomepageLocation, + Value::CreateStringValue("http://chromium.org")); + managed_reader_->OnUpdatePolicy(); + scoped_ptr<DictionaryValue> dict(CreateDictionary(key::kHomepageLocation, + Value::CreateStringValue("http://chromium.org"))); + scoped_ptr<DictionaryValue> result( + managed_reader_->GetPolicyStatus(kPolicyHomepageLocation)); + EXPECT_TRUE(dict->Equals(result.get())); + + recommended_reader_->OnUpdatePolicy(); + dict->SetString("level", + PolicyStatusInfo::GetPolicyLevelString(PolicyStatusInfo::RECOMMENDED)); + result.reset( + recommended_reader_->GetPolicyStatus(kPolicyHomepageLocation)); + EXPECT_TRUE(dict->Equals(result.get())); +} + +// Test for boolean-valued policy settings. +TEST_F(ConfigurationPolicyReaderTest, SetBooleanValue) { + provider_.AddPolicy(kPolicyShowHomeButton, Value::CreateBooleanValue(true)); + managed_reader_->OnUpdatePolicy(); + scoped_ptr<DictionaryValue> dict(CreateDictionary(key::kShowHomeButton, + Value::CreateBooleanValue(true))); + scoped_ptr<DictionaryValue> result( + managed_reader_->GetPolicyStatus(kPolicyShowHomeButton)); + EXPECT_TRUE(dict->Equals(result.get())); + + recommended_reader_->OnUpdatePolicy(); + dict->SetString("level", + PolicyStatusInfo::GetPolicyLevelString(PolicyStatusInfo::RECOMMENDED)); + result.reset(recommended_reader_->GetPolicyStatus(kPolicyShowHomeButton)); + EXPECT_TRUE(dict->Equals(result.get())); + + provider_.AddPolicy(kPolicyShowHomeButton, Value::CreateBooleanValue(false)); + managed_reader_->OnUpdatePolicy(); + dict->Set( + PolicyStatusInfo::kValueDictPath, Value::CreateBooleanValue(false)); + dict->SetString("level", + PolicyStatusInfo::GetPolicyLevelString(PolicyStatusInfo::MANDATORY)); + result.reset(managed_reader_->GetPolicyStatus(kPolicyShowHomeButton)); + EXPECT_TRUE(dict->Equals(result.get())); + + recommended_reader_->OnUpdatePolicy(); + dict->SetString("level", + PolicyStatusInfo::GetPolicyLevelString(PolicyStatusInfo::RECOMMENDED)); + result.reset(recommended_reader_->GetPolicyStatus(kPolicyShowHomeButton)); + EXPECT_TRUE(dict->Equals(result.get())); +} + +// Test for integer-valued policy settings. +TEST_F(ConfigurationPolicyReaderTest, SetIntegerValue) { + provider_.AddPolicy(kPolicyRestoreOnStartup, Value::CreateIntegerValue(3)); + managed_reader_->OnUpdatePolicy(); + scoped_ptr<DictionaryValue> dict(CreateDictionary(key::kRestoreOnStartup, + Value::CreateIntegerValue(3))); + scoped_ptr<DictionaryValue> result( + managed_reader_->GetPolicyStatus(kPolicyRestoreOnStartup)); + EXPECT_TRUE(dict->Equals(result.get())); + + recommended_reader_->OnUpdatePolicy(); + dict->SetString("level", + PolicyStatusInfo::GetPolicyLevelString(PolicyStatusInfo::RECOMMENDED)); + result.reset(recommended_reader_->GetPolicyStatus(kPolicyRestoreOnStartup)); + EXPECT_TRUE(dict->Equals(result.get())); +} + +class PolicyStatusTest : public testing::Test { + protected: + typedef ConfigurationPolicyProvider::PolicyDefinitionList + PolicyDefinitionList; + + PolicyStatusTest() { + managed_platform_ = new MockConfigurationPolicyReader(); + managed_cloud_ = new MockConfigurationPolicyReader(); + recommended_platform_ = new MockConfigurationPolicyReader(); + recommended_cloud_ = new MockConfigurationPolicyReader(); + + policy_status_.reset(new PolicyStatus(managed_platform_, + managed_cloud_, + recommended_platform_, + recommended_cloud_)); + status_ok_ = ASCIIToUTF16("ok"); + + policy_list_ = + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); + policy_list_size_ = + static_cast<size_t>(policy_list_->end - policy_list_->begin); + } + + void DontSendPolicies() { + EXPECT_CALL(*managed_platform_, GetPolicyStatus(_)) + .WillRepeatedly(ReturnNull()); + EXPECT_CALL(*managed_cloud_, GetPolicyStatus(_)) + .WillRepeatedly(ReturnNull()); + EXPECT_CALL(*recommended_platform_, GetPolicyStatus(_)) + .WillRepeatedly(ReturnNull()); + EXPECT_CALL(*recommended_cloud_, GetPolicyStatus(_)) + .WillRepeatedly(ReturnNull()); + } + + void SendPolicies() { + EXPECT_CALL(*managed_platform_, GetPolicyStatus(_)) + .WillRepeatedly(ReturnNull()); + EXPECT_CALL(*managed_cloud_, GetPolicyStatus(_)) + .WillRepeatedly(ReturnNull()); + EXPECT_CALL(*recommended_platform_, GetPolicyStatus(_)) + .WillRepeatedly(ReturnNull()); + EXPECT_CALL(*recommended_cloud_, GetPolicyStatus(_)) + .WillRepeatedly(ReturnNull()); + + EXPECT_CALL(*managed_platform_, GetPolicyStatus(kPolicyInstantEnabled)) + .WillRepeatedly(Return(CreateDictionary(key::kInstantEnabled, + PolicyStatusInfo::MANDATORY))); + EXPECT_CALL(*managed_cloud_, GetPolicyStatus(kPolicyDisablePluginFinder)) + .WillRepeatedly(Return(CreateDictionary(key::kDisablePluginFinder, + PolicyStatusInfo::MANDATORY))); + EXPECT_CALL(*recommended_platform_, GetPolicyStatus(kPolicySyncDisabled)) + .WillRepeatedly( + Return(CreateDictionary(key::kSyncDisabled, + PolicyStatusInfo::RECOMMENDED))); + EXPECT_CALL(*recommended_cloud_, GetPolicyStatus(kPolicyTranslateEnabled)) + .WillRepeatedly( + Return(CreateDictionary(key::kTranslateEnabled, + PolicyStatusInfo::RECOMMENDED))); + } + + DictionaryValue* CreateDictionary(const char* name, + PolicyStatusInfo::PolicyLevel level) { + DictionaryValue* value = new DictionaryValue(); + value->SetString(PolicyStatusInfo::kNameDictPath, ASCIIToUTF16(name)); + value->SetString(PolicyStatusInfo::kLevelDictPath, + PolicyStatusInfo::GetPolicyLevelString(level)); + value->SetString(PolicyStatusInfo::kSourceTypeDictPath, + PolicyStatusInfo::GetSourceTypeString( + PolicyStatusInfo::USER)); + value->SetBoolean(PolicyStatusInfo::kValueDictPath, true); + value->SetBoolean(PolicyStatusInfo::kSetDictPath, true); + value->SetString(PolicyStatusInfo::kStatusDictPath, status_ok_); + + return value; + } + + void SetDictionaryPaths(DictionaryValue* dict, + const char* policy_name, + bool defined, + PolicyStatusInfo::PolicyLevel level) { + dict->SetString(PolicyStatusInfo::kNameDictPath, + ASCIIToUTF16(policy_name)); + if (defined) { + dict->SetString(PolicyStatusInfo::kLevelDictPath, + PolicyStatusInfo::GetPolicyLevelString(level)); + } + } + + MockConfigurationPolicyReader* managed_platform_; + MockConfigurationPolicyReader* managed_cloud_; + MockConfigurationPolicyReader* recommended_platform_; + MockConfigurationPolicyReader* recommended_cloud_; + scoped_ptr<PolicyStatus> policy_status_; + const PolicyDefinitionList* policy_list_; + size_t policy_list_size_; + string16 status_ok_; +}; + +TEST_F(PolicyStatusTest, GetPolicyStatusListNoSetPolicies) { + DontSendPolicies(); + bool any_policies_sent; + scoped_ptr<ListValue> status_list( + policy_status_->GetPolicyStatusList(&any_policies_sent)); + EXPECT_FALSE(any_policies_sent); + EXPECT_EQ(policy_list_size_, status_list->GetSize()); +} + +TEST_F(PolicyStatusTest, GetPolicyStatusListSetPolicies) { + SendPolicies(); + bool any_policies_sent; + scoped_ptr<ListValue> status_list( + policy_status_->GetPolicyStatusList(&any_policies_sent)); + EXPECT_TRUE(any_policies_sent); + EXPECT_EQ(policy_list_size_, status_list->GetSize()); + + scoped_ptr<DictionaryValue> undefined_dict(new DictionaryValue()); + undefined_dict->SetString(PolicyStatusInfo::kLevelDictPath, + PolicyStatusInfo::GetPolicyLevelString( + PolicyStatusInfo::LEVEL_UNDEFINED)); + undefined_dict->SetString(PolicyStatusInfo::kSourceTypeDictPath, + PolicyStatusInfo::GetSourceTypeString( + PolicyStatusInfo::SOURCE_TYPE_UNDEFINED)); + undefined_dict->Set(PolicyStatusInfo::kValueDictPath, + Value::CreateNullValue()); + undefined_dict->SetBoolean(PolicyStatusInfo::kSetDictPath, false); + undefined_dict->SetString(PolicyStatusInfo::kStatusDictPath, string16()); + + scoped_ptr<DictionaryValue> defined_dict(new DictionaryValue()); + defined_dict->SetString(PolicyStatusInfo::kSourceTypeDictPath, + PolicyStatusInfo::GetSourceTypeString( + PolicyStatusInfo::USER)); + defined_dict->Set(PolicyStatusInfo::kValueDictPath, + Value::CreateBooleanValue(true)); + defined_dict->SetBoolean(PolicyStatusInfo::kSetDictPath, true); + defined_dict->SetString(PolicyStatusInfo::kStatusDictPath, status_ok_); + + for (const PolicyDefinitionList::Entry* entry = policy_list_->begin; + entry != policy_list_->end; ++entry) { + Value* status_dict = NULL; + + // Every policy in |policy_list_| has to appear in the returned ListValue. + string16 name = ASCIIToUTF16(entry->name); + for (ListValue::const_iterator status_entry = status_list->begin(); + status_entry != status_list->end(); + ++status_entry) { + string16 value; + ASSERT_TRUE((*status_entry)->IsType(Value::TYPE_DICTIONARY)); + DictionaryValue* dict = static_cast<DictionaryValue*>(*status_entry); + ASSERT_TRUE(dict->GetString(PolicyStatusInfo::kNameDictPath, &value)); + + if (value == name) { + status_dict = *status_entry; + } + } + + ASSERT_FALSE(status_dict == NULL); + + switch (entry->policy_type) { + case kPolicyInstantEnabled: + SetDictionaryPaths(defined_dict.get(), + entry->name, + true, + PolicyStatusInfo::MANDATORY); + EXPECT_TRUE(defined_dict->Equals(status_dict)); + break; + case kPolicyDisablePluginFinder: + SetDictionaryPaths(defined_dict.get(), + entry->name, + true, + PolicyStatusInfo::MANDATORY); + EXPECT_TRUE(defined_dict->Equals(status_dict)); + break; + case kPolicySyncDisabled: + SetDictionaryPaths(defined_dict.get(), + entry->name, + true, + PolicyStatusInfo::RECOMMENDED); + EXPECT_TRUE(defined_dict->Equals(status_dict)); + break; + case kPolicyTranslateEnabled: + SetDictionaryPaths(defined_dict.get(), + entry->name, + true, + PolicyStatusInfo::RECOMMENDED); + EXPECT_TRUE(defined_dict->Equals(status_dict)); + break; + default: + SetDictionaryPaths(undefined_dict.get(), + entry->name, + false, + PolicyStatusInfo::LEVEL_UNDEFINED); + EXPECT_TRUE(undefined_dict->Equals(status_dict)); + break; + } + } +} + +TEST_F(PolicyStatusTest, GetPolicyName) { + for (const PolicyDefinitionList::Entry* entry = policy_list_->begin; + entry != policy_list_->end; ++entry) { + EXPECT_EQ(ASCIIToUTF16(entry->name), + PolicyStatus::GetPolicyName(entry->policy_type)); + } +} + +} // namespace policy diff --git a/chrome/browser/policy/mock_configuration_policy_reader.cc b/chrome/browser/policy/mock_configuration_policy_reader.cc new file mode 100644 index 0000000..ccfb6f1 --- /dev/null +++ b/chrome/browser/policy/mock_configuration_policy_reader.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2011 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/mock_configuration_policy_reader.h" + +namespace policy { + +MockConfigurationPolicyReader::MockConfigurationPolicyReader() {} + +MockConfigurationPolicyReader::~MockConfigurationPolicyReader() {} + +} // namespace policy diff --git a/chrome/browser/policy/mock_configuration_policy_reader.h b/chrome/browser/policy/mock_configuration_policy_reader.h new file mode 100644 index 0000000..f94e4a3 --- /dev/null +++ b/chrome/browser/policy/mock_configuration_policy_reader.h @@ -0,0 +1,28 @@ +// Copyright (c) 2011 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_MOCK_CONFIGURATION_POLICY_READER_H_ +#define CHROME_BROWSER_POLICY_MOCK_CONFIGURATION_POLICY_READER_H_ +#pragma once + +#include "chrome/browser/policy/configuration_policy_reader.h" + +#include "base/values.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace policy { + +// Mock ConfigurationPolicyReader implementation. +class MockConfigurationPolicyReader : public ConfigurationPolicyReader { + public: + MockConfigurationPolicyReader(); + virtual ~MockConfigurationPolicyReader(); + + MOCK_CONST_METHOD1(GetPolicyStatus, + DictionaryValue*(ConfigurationPolicyType policy)); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_MOCK_CONFIGURATION_POLICY_READER_H_ diff --git a/chrome/browser/policy/policy_status_info.cc b/chrome/browser/policy/policy_status_info.cc new file mode 100644 index 0000000..e2fdc00 --- /dev/null +++ b/chrome/browser/policy/policy_status_info.cc @@ -0,0 +1,86 @@ +// Copyright (c) 2011 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_status_info.h" + +#include <algorithm> + +#include "base/logging.h" +#include "base/utf_string_conversions.h" + +namespace policy { + +const std::string PolicyStatusInfo::kLevelDictPath = "level"; +const std::string PolicyStatusInfo::kNameDictPath = "name"; +const std::string PolicyStatusInfo::kSetDictPath = "set"; +const std::string PolicyStatusInfo::kSourceTypeDictPath = "sourceType"; +const std::string PolicyStatusInfo::kStatusDictPath = "status"; +const std::string PolicyStatusInfo::kValueDictPath = "value"; + +// PolicyStatusInfo +PolicyStatusInfo::PolicyStatusInfo() { +} + +PolicyStatusInfo::PolicyStatusInfo( + string16 name, + PolicySourceType source_type, + PolicyLevel level, + Value* value, + PolicyStatus status, + string16 error_message) + : name(name), + source_type(source_type), + level(level), + value(value), + status(status), + error_message(error_message) { +} + +PolicyStatusInfo::~PolicyStatusInfo() { +} + +DictionaryValue* PolicyStatusInfo::GetDictionaryValue() const { + string16 level_string = GetPolicyLevelString(level); + string16 source_type_string = GetSourceTypeString(source_type); + string16 status_message = status == ENFORCED ? ASCIIToUTF16("ok") + : error_message; + DictionaryValue* result = new DictionaryValue(); + result->SetString(kNameDictPath, name); + result->SetString(kLevelDictPath, level_string); + result->SetString(kSourceTypeDictPath, source_type_string); + result->Set(kValueDictPath, value->DeepCopy()); + result->SetBoolean(kSetDictPath, level != LEVEL_UNDEFINED); + result->SetString(kStatusDictPath, status_message); + + return result; +} + +bool PolicyStatusInfo::Equals(const PolicyStatusInfo* other_info) const { + return name == other_info->name && + source_type == other_info->source_type && + level == other_info->level && + value->Equals(other_info->value.get()) && + status == other_info->status && + error_message == other_info->error_message; +} + +// static +string16 PolicyStatusInfo::GetSourceTypeString(PolicySourceType source_type) { + static string16 strings[] = { ASCIIToUTF16("user"), + ASCIIToUTF16("device"), + ASCIIToUTF16("undefined") }; + DCHECK(static_cast<size_t>(source_type) < arraysize(strings)); + return strings[source_type]; +} + +// static +string16 PolicyStatusInfo::GetPolicyLevelString(PolicyLevel level) { + static string16 strings[] = { ASCIIToUTF16("mandatory"), + ASCIIToUTF16("recommended"), + ASCIIToUTF16("undefined") }; + DCHECK(static_cast<size_t>(level) < arraysize(strings)); + return strings[level]; +} + +} // namespace policy diff --git a/chrome/browser/policy/policy_status_info.h b/chrome/browser/policy/policy_status_info.h new file mode 100644 index 0000000..ab1726e --- /dev/null +++ b/chrome/browser/policy/policy_status_info.h @@ -0,0 +1,97 @@ + // Copyright (c) 2011 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_STATUS_INFO_H_ +#define CHROME_BROWSER_POLICY_POLICY_STATUS_INFO_H_ + +#include <map> +#include <string> + +#include "base/scoped_ptr.h" +#include "base/string16.h" +#include "base/values.h" +#include "policy/configuration_policy_type.h" + +namespace policy { + +// Describes a policy's status on the client. +struct PolicyStatusInfo { + + // Defines the possible sources a policy can have. + enum PolicySourceType { + USER, + DEVICE, + SOURCE_TYPE_UNDEFINED, + }; + + // Defines the possible levels a policy can be operating on. + enum PolicyLevel { + MANDATORY, + RECOMMENDED, + LEVEL_UNDEFINED, + }; + + // Defines the possible statuses a policy can have. + enum PolicyStatus { + ENFORCED, + FAILED, + STATUS_UNDEFINED, + }; + + PolicyStatusInfo(); + PolicyStatusInfo(string16 name, + PolicySourceType source_type, + PolicyLevel level, + Value* value, + PolicyStatus status, + string16 error_message); + ~PolicyStatusInfo(); + + // Returns a DictionaryValue pointer containing the information in the object + // for UI purposes. The caller acquires ownership of the returned value. + DictionaryValue* GetDictionaryValue() const; + + // Returns true if this PolicyStatusInfo object and |other_info| have equal + // contents and false otherwise. + bool Equals(const PolicyStatusInfo* other_info) const; + + // Returns the string corresponding to the PolicySourceType enum value + // |source_type|. + static string16 GetSourceTypeString(PolicySourceType source_type); + + // Returns the string corresponding to the PolicyLevel enum value |level|. + static string16 GetPolicyLevelString(PolicyLevel level); + + // The name of the policy. + string16 name; + + // The source type of the policy (user, device or undefined). + PolicySourceType source_type; + + // The level of the policy (mandatory, recommended or undefined). + PolicyLevel level; + + // The policy value. + scoped_ptr<Value> value; + + // The policy status (details whether the policy was successfully enforced). + PolicyStatus status; + + // An error message in cases where the policy could not be enforced. + string16 error_message; + + // Paths for the DictionaryValue returned by GetDictionaryValue(). + static const std::string kLevelDictPath; + static const std::string kNameDictPath; + static const std::string kSetDictPath; + static const std::string kSourceTypeDictPath; + static const std::string kStatusDictPath; + static const std::string kValueDictPath; + + DISALLOW_COPY_AND_ASSIGN(PolicyStatusInfo); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_POLICY_STATUS_INFO_H_ diff --git a/chrome/browser/resources/policy.css b/chrome/browser/resources/policy.css new file mode 100644 index 0000000..2fa9a1b --- /dev/null +++ b/chrome/browser/resources/policy.css @@ -0,0 +1,143 @@ +body { + color: black; + cursor: default; + font-family: Arial, sans-serif; + font-size: 14px; + margin: 0 10px; + min-width: 47em; +} + +button { + font-size: 0.9em; +} + +#header { + border-bottom: 1px solid #000; + padding-top: 20px; +} + +#about-policy-title { + -webkit-padding-end: 24px; + -webkit-user-select: none; + border-bottom: 1px solid #c6c9ce; + color: #53637d; + cursor: pointer; + font-size: 200%; + font-weight: normal; + margin: 0; + padding-bottom: 14px; + padding-top: 13px; + text-shadow: white 0 1px 2px; +} + +#main-content { + min-height: 100%; +} + +#status-title, +#policies-title { + font-size: 120%; + font-weight: bold; + width: 65%; +} + +section { + border-bottom: 1px solid #eee; + margin-top: 17px; + padding-bottom: 20px; + width: 100%; +} + +.separator { + -webkit-box-orient: horizontal; + display: -webkit-box; +} + +#fetch-policies, +#unsent-policies-control { + -webkit-box-flex: 1; +} + +#fetch-policies, +#unsent-policies-control, +#search { + bottom: 3px; + position: relative; +} + +#fetch-policies { + direction: rtl; +} + +#checkbox-and-label { + -webkit-padding-end: 20px; + float: right; +} + +html[dir='rtl'] #checkbox-and-label { + float: left; +} + +#search-field { + bottom: 2px; + position: relative; +} + +#status-pane { + -webkit-box-flex: 1; + -webkit-box-orient: horizontal; + display: -webkit-box; + margin: 0 10%; +} + +.status-box { + border: 1px solid #d9d9d9; + margin: 20px 100px; + min-height: 140px; + min-width: 300px; + overflow: hidden; + padding: 2px; + width: 30%; +} + +legend { + padding: 0.2em 0.5em; +} + +.status-box ul { + -webkit-padding-start: 10px; + list-style-type: none; +} + +.status-box li { + padding: 3px; +} + +#no-policies-text { + font-weight: bold; + margin: 20px; + text-align: center; +} + +#policy-table { + table-layout: fixed; + width: 100%; +} + +#policy-table th td { + border: 1px solid #fff; + border-collapse: collapse; +} + +#policy-table th { + background-color: #dadadd; + padding: 10px; +} + +#policy-table td { + background-color: #eaeef3; + overflow: hidden; + padding: 10px; + text-overflow: ellipsis; + width: 20%; +} diff --git a/chrome/browser/resources/policy.html b/chrome/browser/resources/policy.html index 8eb63e1..db547b4 100644 --- a/chrome/browser/resources/policy.html +++ b/chrome/browser/resources/policy.html @@ -20,9 +20,6 @@ <h1 id="about-policy-title" i18n-content="policyTitle"></h1> </div> <div id="main-content"> - <section id="description-section"> - <p i18n-content="aboutPolicyDescription"></p> - </section> <section id="status-section"> <div class="separator"> <span id="status-title" i18n-content="statusPaneTitle"></span> @@ -65,7 +62,7 @@ </div> <div id="search"> <input id="search-field" type="search" incremental - placeholder="Filter policies by name"> + i18n-values="placeholder: filterPoliciesText"> </div> </div> <div> @@ -73,7 +70,8 @@ <div id="no-policies-text" i18n-content="noPoliciesSet"></div> </div> <div id="policies" - jsvalues=".style.visibility: anyPoliciesSet ? 'visible': 'hidden'"> + jsvalues=".style.display: anyPoliciesSet ? + '': 'none'"> <table id="policy-table"> <tr> <th i18n-content="appliesToTableHeader"></th> @@ -82,11 +80,11 @@ <th i18n-content="policyValueTableHeader"></th> <th i18n-content="policyStatusTableHeader"></th> </tr> - <tr jsselect="policies" - jsvalues=".className: Policy.isPolicySet($this)? + <tr jsselect="policies" + jsvalues=".className: $this.set ? 'policy-set': 'policy-unset'; .style.display: Policy.shouldDisplayPolicy($this) ? - 'table-row': 'none'"> + '': 'none'"> <td> <span class="policy-type" jscontent="sourceType"></span> </td> diff --git a/chrome/browser/resources/policy.js b/chrome/browser/resources/policy.js new file mode 100644 index 0000000..db4f404 --- /dev/null +++ b/chrome/browser/resources/policy.js @@ -0,0 +1,160 @@ +// Copyright (c) 2011 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. + +var localStrings = new LocalStrings(); + +/** + * This variable structure is here to document the structure that the template + * expects to correctly populate the page. + */ +var policyDataformat = { + 'policies': [ + { + 'level': 'managed', + 'name': 'AllowXYZ', + 'set': true, + 'sourceType': 'Device', + 'status': 'ok', + 'value': true, + }, + ], + 'anyPoliciesSet': true +}; + +cr.define('policies', function() { + + function Policy() { + } + + cr.addSingletonGetter(Policy); + + Policy.prototype = { + + /** + * True if none of the received policies are actually set, false otherwise. + * @type {boolean} + */ + noActivePolicies_: false, + + /** + * The current search term for filtering of the policy table. + * @type {string} + * @private + */ + searchTerm_: '', + + /** + * Takes the |policyData| input argument which represents data about the + * policies supported by the device/client and populates the html jstemplate + * with that data. It expects an object structure like the above. + * @param {Object} policyData Detailed info about policies + */ + renderTemplate: function(policyData) { + this.noActivePolicies_ = !policyData.anyPoliciesSet; + + // This is the javascript code that processes the template: + var input = new JsEvalContext(policyData); + var output = $('policiesTemplate'); + jstProcess(input, output); + }, + + /** + * Filters the table of policies by name. + * @param {string} term The search string + */ + filterTable: function(term) { + this.searchTerm_ = term.toLowerCase(); + var table = $('policy-table'); + var showUnsent = $('toggle-unsent-policies').checked; + for (var r = 1; r < table.rows.length; r++) { + var row = table.rows[r]; + + // Don't change visibility of policies that aren't set if the checkbox + // isn't checked. + if (!showUnsent && row.className == 'policy-unset') + continue; + + var nameCell = row.querySelector('.policy-name'); + var cellContents = nameCell.textContent; + if (cellContents.toLowerCase().indexOf(this.searchTerm_) >= 0) + row.style.display = 'table-row'; + else + row.style.display = 'none'; + } + }, + + /** + * Updates the visibility of the policies depending on the state of the + * 'toggle-unsent-policies' checkbox. + */ + updatePolicyVisibility: function() { + if ($('toggle-unsent-policies').checked) + $('policies').style.display = ''; + else if (this.noActivePolicies_) + $('policies').style.display = 'none'; + + var tableRows = document.getElementsByClassName('policy-unset'); + for (var i = 0; i < tableRows.length; i++) { + if ($('toggle-unsent-policies').checked) + tableRows[i].style.visibility = 'visible'; + else + tableRows[i].style.visibility = 'hidden'; + } + + // Filter table again in case a search was active. + this.filterTable(this.searchTerm_); + } + }; + + /** + * Asks the C++ PolicyUIHandler to get details about policies. The + * PolicyDOMHandler should reply to returnPolicyData() (below). + */ + Policy.requestPolicyData = function() { + chrome.send('requestPolicyData'); + }; + + /** + * Called by the C++ PolicyUIHandler when it has the requested policy data. + */ + Policy.returnPolicyData = function(policyData) { + Policy.getInstance().renderTemplate(policyData); + }; + + /** + * Determines whether a policy should be visible or not. + * @param {policy} policy information in the format given by above the + * PolicyDataFormat + */ + Policy.shouldDisplayPolicy = function(policy) { + return $('toggle-unsent-policies').checked || policy.set; + }; + + /** + * Initializes the page and loads the list of policies. + */ + Policy.initialize = function() { + i18nTemplate.process(document, templateData); + Policy.requestPolicyData(); + + // Set HTML event handlers. + $('toggle-unsent-policies').onchange = function(event) { + Policy.getInstance().updatePolicyVisibility(); + }; + + $('search-field').onsearch = function(event) { + Policy.getInstance().filterTable(this.value); + }; + }; + + // Export + return { + Policy: Policy + }; +}); + +var Policy = policies.Policy; + +// Get data and have it displayed upon loading. +document.addEventListener('DOMContentLoaded', policies.Policy.initialize); diff --git a/chrome/browser/ui/webui/chrome_web_ui_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_factory.cc index 4df28b0..5a788a3 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_factory.cc @@ -30,6 +30,7 @@ #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" #include "chrome/browser/ui/webui/options/options_ui.h" #include "chrome/browser/ui/webui/plugins_ui.h" +#include "chrome/browser/ui/webui/policy_ui.h" #include "chrome/browser/ui/webui/print_preview_ui.h" #include "chrome/browser/ui/webui/quota_internals_ui.h" #include "chrome/browser/ui/webui/sessions_ui.h" @@ -195,6 +196,8 @@ static WebUIFactoryFunction GetWebUIFactoryFunction(Profile* profile, return &NewWebUI<NetInternalsUI>; if (url.host() == chrome::kChromeUIPluginsHost) return &NewWebUI<PluginsUI>; + if (url.host() == chrome::kChromeUIPolicyHost) + return &NewWebUI<PolicyUI>; if (url.host() == chrome::kChromeUISessionsHost) return &NewWebUI<SessionsUI>; if (url.host() == chrome::kChromeUISyncInternalsHost) diff --git a/chrome/browser/ui/webui/policy_ui.cc b/chrome/browser/ui/webui/policy_ui.cc new file mode 100644 index 0000000..99ebb3e --- /dev/null +++ b/chrome/browser/ui/webui/policy_ui.cc @@ -0,0 +1,109 @@ +// Copyright (c) 2011 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/ui/webui/policy_ui.h" + +#include "chrome/browser/policy/policy_status_info.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" +#include "chrome/common/url_constants.h" +#include "content/browser/tab_contents/tab_contents.h" +#include "grit/browser_resources.h" +#include "grit/generated_resources.h" + +ChromeWebUIDataSource* CreatePolicyUIHTMLSource() { + ChromeWebUIDataSource* source = + new ChromeWebUIDataSource(chrome::kChromeUIPolicyHost); + + // Localized strings. + source->AddLocalizedString("policyTitle", IDS_POLICY_TITLE); + source->AddLocalizedString("statusPaneTitle", IDS_POLICY_STATUS_TITLE); + source->AddLocalizedString("fetchPoliciesText", IDS_POLICY_FETCH); + source->AddLocalizedString("devicePoliciesBoxTitle", + IDS_POLICY_DEVICE_POLICIES); + source->AddLocalizedString("userPoliciesBoxTitle", + IDS_POLICY_USER_POLICIES); + source->AddLocalizedString("enrollmentDomainText", + IDS_POLICY_ENROLLMENT_DOMAIN); + source->AddLocalizedString("lastFetchedText", IDS_POLICY_LAST_FETCHED); + source->AddLocalizedString("fetchIntervalText", IDS_POLICY_FETCH_INTERVAL); + source->AddLocalizedString("serverStatusText", IDS_POLICY_SERVER_STATUS); + source->AddLocalizedString("showUnsentPoliciesText", + IDS_POLICY_SHOW_UNSENT); + source->AddLocalizedString("filterPoliciesText", IDS_POLICY_FILTER); + source->AddLocalizedString("noPoliciesSet",IDS_POLICY_NO_POLICIES_SET); + source->AddLocalizedString("appliesToTableHeader", IDS_POLICY_APPLIES_TO); + source->AddLocalizedString("policyLevelTableHeader", IDS_POLICY_LEVEL); + source->AddLocalizedString("policyNameTableHeader", IDS_POLICY_ENTRY_NAME); + source->AddLocalizedString("policyValueTableHeader", IDS_POLICY_ENTRY_VALUE); + source->AddLocalizedString("policyStatusTableHeader", + IDS_POLICY_ENTRY_STATUS); + source->set_json_path("strings.js"); + + // Add required resources. + source->add_resource_path("policy.css", IDR_POLICY_CSS); + source->add_resource_path("policy.js", IDR_POLICY_JS); + source->set_default_resource(IDR_POLICY_HTML); + + return source; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// PolicyUIHandler +// +//////////////////////////////////////////////////////////////////////////////// + +PolicyUIHandler::PolicyUIHandler() { + policy::ConfigurationPolicyReader* managed_platform = + ConfigurationPolicyReader::CreateManagedPlatformPolicyReader(); + policy::ConfigurationPolicyReader* managed_cloud = + ConfigurationPolicyReader::CreateManagedCloudPolicyReader(); + policy::ConfigurationPolicyReader* recommended_platform = + ConfigurationPolicyReader::CreateRecommendedPlatformPolicyReader(); + policy::ConfigurationPolicyReader* recommended_cloud = + ConfigurationPolicyReader::CreateRecommendedCloudPolicyReader(); + policy_status_.reset(new policy::PolicyStatus(managed_platform, + managed_cloud, + recommended_platform, + recommended_cloud)); +} + +PolicyUIHandler::~PolicyUIHandler() { +} + +WebUIMessageHandler* PolicyUIHandler::Attach(WebUI* web_ui) { + return WebUIMessageHandler::Attach(web_ui); +} + +void PolicyUIHandler::RegisterMessages() { + web_ui_->RegisterMessageCallback("requestPolicyData", + NewCallback(this, &PolicyUIHandler::HandleRequestPolicyData)); +} + +void PolicyUIHandler::HandleRequestPolicyData(const ListValue* args) { + bool any_policies_sent; + ListValue* list = policy_status_->GetPolicyStatusList(&any_policies_sent); + DictionaryValue results; + results.Set("policies", list); + results.SetBoolean("anyPoliciesSet", any_policies_sent); + web_ui_->CallJavascriptFunction("Policy.returnPolicyData", results); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// PolicyUI +// +//////////////////////////////////////////////////////////////////////////////// + +PolicyUI::PolicyUI(TabContents* contents) : ChromeWebUI(contents) { + AddMessageHandler((new PolicyUIHandler)->Attach(this)); + + // Set up the chrome://policy/ source. + Profile* profile = Profile::FromBrowserContext(contents->browser_context()); + profile->GetChromeURLDataManager()->AddDataSource(CreatePolicyUIHTMLSource()); +} + +PolicyUI::~PolicyUI() { +} diff --git a/chrome/browser/ui/webui/policy_ui.h b/chrome/browser/ui/webui/policy_ui.h new file mode 100644 index 0000000..f773a4b --- /dev/null +++ b/chrome/browser/ui/webui/policy_ui.h @@ -0,0 +1,46 @@ +// Copyright (c) 2011 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_UI_WEBUI_POLICY_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_POLICY_UI_H_ +#pragma once + +#include "base/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/policy/configuration_policy_reader.h" +#include "chrome/browser/ui/webui/chrome_web_ui.h" +#include "content/common/notification_observer.h" + +// The base class handler of Javascript messages of the about:policy page. +class PolicyUIHandler : public WebUIMessageHandler { + public: + PolicyUIHandler(); + virtual ~PolicyUIHandler(); + + // WebUIMessageHandler implementation. + virtual WebUIMessageHandler* Attach(WebUI* web_ui) OVERRIDE; + virtual void RegisterMessages() OVERRIDE; + + private: + typedef policy::ConfigurationPolicyReader ConfigurationPolicyReader; + + // Callback for the "requestPolicyData" message. + void HandleRequestPolicyData(const ListValue* args); + + scoped_ptr<policy::PolicyStatus> policy_status_; + + DISALLOW_COPY_AND_ASSIGN(PolicyUIHandler); +}; + +// The Web UI handler for about:policy. +class PolicyUI : public ChromeWebUI { + public: + explicit PolicyUI(TabContents* contents); + virtual ~PolicyUI(); + + private: + DISALLOW_COPY_AND_ASSIGN(PolicyUI); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_POLICY_UI_H_ |