Chromium Code Reviews| Index: chrome/browser/ui/webui/policy_ui.cc |
| diff --git a/chrome/browser/ui/webui/policy_ui.cc b/chrome/browser/ui/webui/policy_ui.cc |
| index efa876d08a8448ef0190c0c80ec8a7929c0f4cc3..0bf38fc75dd2f12e9085b1b30da38788716dede5 100644 |
| --- a/chrome/browser/ui/webui/policy_ui.cc |
| +++ b/chrome/browser/ui/webui/policy_ui.cc |
| @@ -4,37 +4,42 @@ |
| #include "chrome/browser/ui/webui/policy_ui.h" |
| -#include <vector> |
| - |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/callback.h" |
| #include "base/compiler_specific.h" |
| -#include "base/hash_tables.h" |
| -#include "base/stl_util.h" |
| +#include "base/logging.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/string16.h" |
| #include "base/time.h" |
| -#include "base/utf_string_conversions.h" |
| +#include "base/values.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/policy/browser_policy_connector.h" |
| #include "chrome/browser/policy/cloud_policy_client.h" |
| +#include "chrome/browser/policy/cloud_policy_constants.h" |
| #include "chrome/browser/policy/cloud_policy_core.h" |
| #include "chrome/browser/policy/cloud_policy_refresh_scheduler.h" |
| #include "chrome/browser/policy/cloud_policy_store.h" |
| #include "chrome/browser/policy/cloud_policy_validator.h" |
| +#include "chrome/browser/policy/configuration_policy_handler_list.h" |
| +#include "chrome/browser/policy/device_local_account_policy_service.h" |
| #include "chrome/browser/policy/message_util.h" |
| #include "chrome/browser/policy/policy_error_map.h" |
| +#include "chrome/browser/policy/policy_map.h" |
| #include "chrome/browser/policy/policy_service.h" |
| +#include "chrome/browser/policy/policy_types.h" |
| #include "chrome/browser/policy/proto/device_management_backend.pb.h" |
| -#include "chrome/browser/prefs/pref_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| -#include "chrome/common/pref_names.h" |
| #include "chrome/common/time_format.h" |
| #include "chrome/common/url_constants.h" |
| -#include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_ui.h" |
| #include "content/public/browser/web_ui_data_source.h" |
| +#include "content/public/browser/web_ui_message_handler.h" |
| +#include "google_apis/gaia/gaia_auth_util.h" |
| #include "grit/browser_resources.h" |
| #include "grit/generated_resources.h" |
| +#include "policy/policy_constants.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #if defined(OS_CHROMEOS) |
| @@ -49,13 +54,6 @@ |
| namespace em = enterprise_management; |
| -const char PolicyUIHandler::kLevel[] = "level"; |
| -const char PolicyUIHandler::kName[] = "name"; |
| -const char PolicyUIHandler::kScope[] = "scope"; |
| -const char PolicyUIHandler::kSet[] = "set"; |
| -const char PolicyUIHandler::kStatus[] = "status"; |
| -const char PolicyUIHandler::kValue[] = "value"; |
| - |
| namespace { |
| content::WebUIDataSource* CreatePolicyUIHTMLSource() { |
| @@ -63,125 +61,110 @@ content::WebUIDataSource* CreatePolicyUIHTMLSource() { |
| content::WebUIDataSource::Create(chrome::kChromeUIPolicyHost); |
| // Localized strings. |
| + source->AddLocalizedString("title", IDS_POLICY_TITLE); |
| + source->AddLocalizedString("filterPlaceholder", |
| + IDS_POLICY_FILTER_PLACEHOLDER); |
| + source->AddLocalizedString("reloadPolicies", IDS_POLICY_RELOAD_POLICIES); |
| + source->AddLocalizedString("status", IDS_POLICY_STATUS); |
| + source->AddLocalizedString("statusDevice", IDS_POLICY_STATUS_DEVICE); |
| + source->AddLocalizedString("statusUser", IDS_POLICY_STATUS_USER); |
| + source->AddLocalizedString("labelDomain", IDS_POLICY_LABEL_DOMAIN); |
| + source->AddLocalizedString("labelUsername", IDS_POLICY_LABEL_USERNAME); |
| + source->AddLocalizedString("labelClientId", IDS_POLICY_LABEL_CLIENT_ID); |
| + source->AddLocalizedString("labelTimeSinceLastRefresh", |
| + IDS_POLICY_LABEL_TIME_SINCE_LAST_REFRESH); |
| + source->AddLocalizedString("labelRefreshInterval", |
| + IDS_POLICY_LABEL_REFRESH_INTERVAL); |
| + source->AddLocalizedString("labelStatus", IDS_POLICY_LABEL_STATUS); |
| + source->AddLocalizedString("showUnset", IDS_POLICY_SHOW_UNSET); |
| + source->AddLocalizedString("noPoliciesSet", IDS_POLICY_NO_POLICIES_SET); |
| + source->AddLocalizedString("headerScope", IDS_POLICY_HEADER_SCOPE); |
| + source->AddLocalizedString("headerLevel", IDS_POLICY_HEADER_LEVEL); |
| + source->AddLocalizedString("headerName", IDS_POLICY_HEADER_NAME); |
| + source->AddLocalizedString("headerValue", IDS_POLICY_HEADER_VALUE); |
| + source->AddLocalizedString("headerStatus", IDS_POLICY_HEADER_STATUS); |
| + source->AddLocalizedString("showExpandedValue", |
| + IDS_POLICY_SHOW_EXPANDED_VALUE); |
| + source->AddLocalizedString("hideExpandedValue", |
| + IDS_POLICY_HIDE_EXPANDED_VALUE); |
| + source->AddLocalizedString("scopeUser", IDS_POLICY_SCOPE_USER); |
| + source->AddLocalizedString("scopeDevice", IDS_POLICY_SCOPE_DEVICE); |
| + source->AddLocalizedString("levelRecommended", IDS_POLICY_LEVEL_RECOMMENDED); |
| + source->AddLocalizedString("levelMandatory", IDS_POLICY_LEVEL_MANDATORY); |
| + source->AddLocalizedString("ok", IDS_POLICY_OK); |
| + source->AddLocalizedString("unset", IDS_POLICY_UNSET); |
| + source->AddLocalizedString("unknown", IDS_POLICY_UNKNOWN); |
| + |
| source->SetUseJsonJSFormatV2(); |
| - 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("clientIdText", IDS_POLICY_CLIENT_ID); |
| - source->AddLocalizedString("usernameText", IDS_POLICY_USERNAME); |
| - source->AddLocalizedString("timeSinceLastFetchText", 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->AddLocalizedString("showMoreText", IDS_POLICY_SHOW_MORE); |
| - source->AddLocalizedString("hideText", IDS_POLICY_HIDE); |
| source->SetJsonPath("strings.js"); |
| // Add required resources. |
| source->AddResourcePath("policy.css", IDR_POLICY_CSS); |
| source->AddResourcePath("policy.js", IDR_POLICY_JS); |
| + source->AddResourcePath("uber_utils.js", IDR_UBER_UTILS_JS); |
| source->SetDefaultResource(IDR_POLICY_HTML); |
| return source; |
| } |
| -string16 GetPolicyScopeString(policy::PolicyScope scope) { |
| - switch (scope) { |
| - case policy::POLICY_SCOPE_USER: |
| - return l10n_util::GetStringUTF16(IDS_POLICY_SCOPE_USER); |
| - case policy::POLICY_SCOPE_MACHINE: |
| - return l10n_util::GetStringUTF16(IDS_POLICY_SCOPE_MACHINE); |
| - } |
| - NOTREACHED(); |
| - return string16(); |
| +void GetStatusFromCore(const policy::CloudPolicyCore* core, |
| + base::DictionaryValue* dict) { |
| + const policy::CloudPolicyStore* store = core->store(); |
| + const policy::CloudPolicyClient* client = core->client(); |
| + const policy::CloudPolicyRefreshScheduler* refresh_scheduler = |
| + core->refresh_scheduler(); |
| + |
| + bool no_error = store->status() == policy::CloudPolicyStore::STATUS_OK && |
| + client && client->status() == policy::DM_STATUS_SUCCESS; |
| + string16 status = store->status() == policy::CloudPolicyStore::STATUS_OK && |
| + client && client->status() != policy::DM_STATUS_SUCCESS ? |
| + policy::FormatDeviceManagementStatus(client->status()) : |
| + policy::FormatStoreStatus(store->status(), |
| + store->validation_status()); |
| + const em::PolicyData* policy = store->policy(); |
| + std::string client_id = policy ? policy->device_id() : std::string(); |
| + std::string username = policy ? policy->username() : std::string(); |
| + base::TimeDelta refresh_interval = |
| + base::TimeDelta::FromMilliseconds(refresh_scheduler ? |
| + refresh_scheduler->refresh_delay() : |
| + policy::CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs); |
| + base::Time last_refresh_time = refresh_scheduler ? |
| + refresh_scheduler->last_refresh() : base::Time(); |
| + |
| + dict->SetBoolean("error", !no_error); |
| + dict->SetString("status", status); |
| + dict->SetString("clientId", client_id); |
| + dict->SetString("username", username); |
| + dict->SetString("refreshInterval", |
| + TimeFormat::TimeRemainingShort(refresh_interval)); |
| + dict->SetString("timeSinceLastRefresh", last_refresh_time.is_null() ? |
| + l10n_util::GetStringUTF16(IDS_POLICY_NEVER_FETCHED) : |
| + TimeFormat::TimeElapsed(base::Time::NowFromSystemTime() - |
| + last_refresh_time)); |
| } |
| -string16 GetPolicyLevelString(policy::PolicyLevel level) { |
| - switch (level) { |
| - case policy::POLICY_LEVEL_RECOMMENDED: |
| - return l10n_util::GetStringUTF16(IDS_POLICY_LEVEL_RECOMMENDED); |
| - case policy::POLICY_LEVEL_MANDATORY: |
| - return l10n_util::GetStringUTF16(IDS_POLICY_LEVEL_MANDATORY); |
| - } |
| - NOTREACHED(); |
| - return string16(); |
| -} |
| - |
| -base::DictionaryValue* GetPolicyDetails( |
| - const policy::PolicyDefinitionList::Entry* policy_definition, |
| - const policy::PolicyMap::Entry* policy_value, |
| - const string16& error_message) { |
| - base::DictionaryValue* details = new base::DictionaryValue(); |
| - details->SetString(PolicyUIHandler::kName, |
| - ASCIIToUTF16(policy_definition->name)); |
| - details->SetBoolean(PolicyUIHandler::kSet, true); |
| - details->SetString(PolicyUIHandler::kLevel, |
| - GetPolicyLevelString(policy_value->level)); |
| - details->SetString(PolicyUIHandler::kScope, |
| - GetPolicyScopeString(policy_value->scope)); |
| - details->Set(PolicyUIHandler::kValue, policy_value->value->DeepCopy()); |
| - if (error_message.empty()) { |
| - details->SetString(PolicyUIHandler::kStatus, |
| - l10n_util::GetStringUTF16(IDS_OK)); |
| - } else { |
| - details->SetString(PolicyUIHandler::kStatus, error_message); |
| - } |
| - return details; |
| -} |
| - |
| -base::DictionaryValue* GetPolicyErrorDetails(const std::string& policy_name, |
| - bool is_set) { |
| - base::DictionaryValue* details = new base::DictionaryValue(); |
| - details->SetString(PolicyUIHandler::kName, ASCIIToUTF16(policy_name)); |
| - details->SetBoolean(PolicyUIHandler::kSet, is_set); |
| - details->SetString(PolicyUIHandler::kLevel, ""); |
| - details->SetString(PolicyUIHandler::kScope, ""); |
| - details->SetString(PolicyUIHandler::kValue, ""); |
| - if (is_set) |
| - details->SetString(PolicyUIHandler::kStatus, |
| - l10n_util::GetStringUTF16(IDS_POLICY_UNKNOWN)); |
| - else |
| - details->SetString(PolicyUIHandler::kStatus, |
| - l10n_util::GetStringUTF16(IDS_POLICY_NOT_SET)); |
| - return details; |
| +void ExtractDomainFromUsername(base::DictionaryValue* dict) { |
| + std::string username; |
| + dict->GetString("username", &username); |
| + if (!username.empty()) |
| + dict->SetString("domain", gaia::ExtractDomainName(username)); |
| } |
| } // namespace |
| -// An interface for querying status data. |
| +// An interface for querying the status of cloud policy. |
| class CloudPolicyStatusProvider { |
| public: |
| - CloudPolicyStatusProvider() {} |
| - virtual ~CloudPolicyStatusProvider() {} |
| + CloudPolicyStatusProvider(); |
| + virtual ~CloudPolicyStatusProvider(); |
| // Sets a callback to invoke upon status changes. |
| - void SetStatusChangeCallback(const base::Closure& callback) { |
| - callback_ = callback; |
| - } |
| + void SetStatusChangeCallback(const base::Closure& callback); |
| - // Fills |status_dict| and returns true if the status is relevant. |
| - virtual bool GetStatus(base::DictionaryValue* status_dict) { |
| - return false; |
| - } |
| + virtual void GetStatus(base::DictionaryValue* dict); |
| protected: |
| - void NotifyStatusChange() { |
| - if (!callback_.is_null()) |
| - callback_.Run(); |
| - } |
| + void NotifyStatusChange(); |
| private: |
| base::Closure callback_; |
| @@ -197,32 +180,14 @@ class CloudPolicyCoreStatusProvider |
| : public CloudPolicyStatusProvider, |
| public policy::CloudPolicyStore::Observer { |
| public: |
| - explicit CloudPolicyCoreStatusProvider(policy::CloudPolicyCore* core) |
| - : core_(core) { |
| - core_->store()->AddObserver(this); |
| - } |
| - virtual ~CloudPolicyCoreStatusProvider() { |
| - core_->store()->RemoveObserver(this); |
| - } |
| - |
| - // CloudPolicyStatusProvider: |
| - virtual bool GetStatus(base::DictionaryValue* status_dict) OVERRIDE { |
| - return GetStatusFromCore(core_, status_dict); |
| - } |
| + explicit CloudPolicyCoreStatusProvider(policy::CloudPolicyCore* core); |
| + virtual ~CloudPolicyCoreStatusProvider(); |
| // policy::CloudPolicyStore::Observer: |
| - virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE { |
| - NotifyStatusChange(); |
| - } |
| - virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE { |
| - NotifyStatusChange(); |
| - } |
| - |
| - // Extracts status information from |core| and writes it to |status_dict|. |
| - static bool GetStatusFromCore(policy::CloudPolicyCore* core, |
| - base::DictionaryValue* status_dict); |
| + virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE; |
| + virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE; |
| - private: |
| + protected: |
| // Policy status is read from the CloudPolicyClient, CloudPolicyStore and |
| // CloudPolicyRefreshScheduler hosted by this |core_|. |
| policy::CloudPolicyCore* core_; |
| @@ -230,53 +195,36 @@ class CloudPolicyCoreStatusProvider |
| DISALLOW_COPY_AND_ASSIGN(CloudPolicyCoreStatusProvider); |
| }; |
| -// static |
| -bool CloudPolicyCoreStatusProvider::GetStatusFromCore( |
| - policy::CloudPolicyCore* core, |
| - base::DictionaryValue* status_dict) { |
| - policy::CloudPolicyStore* store = core->store(); |
| - policy::CloudPolicyClient* client = core->client(); |
| - policy::CloudPolicyRefreshScheduler* refresh_scheduler = |
| - core->refresh_scheduler(); |
| - |
| - string16 status; |
| - if (store->status() == policy::CloudPolicyStore::STATUS_OK && |
| - client && client->status() != policy::DM_STATUS_SUCCESS) { |
| - status = policy::FormatDeviceManagementStatus(client->status()); |
| - } else { |
| - status = policy::FormatStoreStatus(store->status(), |
| - store->validation_status()); |
| - } |
| - status_dict->SetString("statusMessage", status); |
| - |
| - base::Time last_refresh_time; |
| - if (refresh_scheduler) |
| - last_refresh_time = refresh_scheduler->last_refresh(); |
| - status_dict->SetString( |
| - "timeSinceLastFetch", |
| - last_refresh_time.is_null() ? |
| - l10n_util::GetStringUTF16(IDS_POLICY_NEVER_FETCHED) : |
| - TimeFormat::TimeElapsed(base::Time::NowFromSystemTime() - |
| - last_refresh_time)); |
| - |
| - const em::PolicyData* policy = store->policy(); |
| - status_dict->SetString( |
| - "clientId", policy ? ASCIIToUTF16(policy->device_id()) : string16()); |
| - status_dict->SetString( |
| - "user", policy ? UTF8ToUTF16(policy->username()) : string16()); |
| +// A cloud policy status provider for user policy. |
| +class UserPolicyStatusProvider : public CloudPolicyCoreStatusProvider { |
| + public: |
| + explicit UserPolicyStatusProvider(policy::CloudPolicyCore* core); |
| + virtual ~UserPolicyStatusProvider(); |
| - int64 interval = policy::CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs; |
| - if (refresh_scheduler) |
| - interval = refresh_scheduler->refresh_delay(); |
| - status_dict->SetString( |
| - "fetchInterval", |
| - TimeFormat::TimeRemainingShort( |
| - base::TimeDelta::FromMilliseconds(interval))); |
| + // CloudPolicyCoreStatusProvider: |
| + virtual void GetStatus(base::DictionaryValue* dict) OVERRIDE; |
| - return store->is_managed(); |
| -} |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(UserPolicyStatusProvider); |
| +}; |
| #if defined(OS_CHROMEOS) |
| +// A cloud policy status provider for device policy. |
| +class DevicePolicyStatusProvider : public CloudPolicyCoreStatusProvider { |
| + public: |
| + explicit DevicePolicyStatusProvider( |
| + policy::BrowserPolicyConnector* connector); |
| + virtual ~DevicePolicyStatusProvider(); |
| + |
| + // CloudPolicyCoreStatusProvider: |
|
James Hawkins
2013/01/31 17:08:05
nit: // CloudPolicyCoreStatusProvider implementati
bartfab (slow)
2013/01/31 17:36:13
People seem to disagree on style here. Some strong
|
| + virtual void GetStatus(base::DictionaryValue* dict) OVERRIDE; |
| + |
| + private: |
| + std::string domain_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DevicePolicyStatusProvider); |
| +}; |
| + |
| // A cloud policy status provider that reads policy status from the policy core |
| // associated with the device-local account specified by |account_id| at |
| // construction time. The indirection via account ID and |
| @@ -289,41 +237,15 @@ class DeviceLocalAccountPolicyStatusProvider |
| public: |
| DeviceLocalAccountPolicyStatusProvider( |
| const std::string& account_id, |
| - policy::DeviceLocalAccountPolicyService* service) |
| - : account_id_(account_id), |
| - service_(service) { |
| - service_->AddObserver(this); |
| - } |
| - virtual ~DeviceLocalAccountPolicyStatusProvider() { |
| - service_->RemoveObserver(this); |
| - } |
| + policy::DeviceLocalAccountPolicyService* service); |
| + virtual ~DeviceLocalAccountPolicyStatusProvider(); |
| // CloudPolicyStatusProvider: |
| - virtual bool GetStatus(base::DictionaryValue* status_dict) OVERRIDE { |
| - policy::DeviceLocalAccountPolicyBroker* broker = |
| - service_->GetBrokerForAccount(account_id_); |
| - if (broker) { |
| - return CloudPolicyCoreStatusProvider::GetStatusFromCore(broker->core(), |
| - status_dict); |
| - } |
| - |
| - status_dict->SetString("user", account_id_); |
| - status_dict->SetString( |
| - "statusMessage", |
| - policy::FormatStoreStatus( |
| - policy::CloudPolicyStore::STATUS_BAD_STATE, |
| - policy::CloudPolicyValidatorBase::VALIDATION_OK)); |
| - return true; |
| - } |
| + virtual void GetStatus(base::DictionaryValue* dict) OVERRIDE; |
| // policy::DeviceLocalAccountPolicyService::Observer: |
| - virtual void OnPolicyUpdated(const std::string& account_id) OVERRIDE { |
| - if (account_id == account_id_) |
| - NotifyStatusChange(); |
| - } |
| - virtual void OnDeviceLocalAccountsChanged() OVERRIDE { |
| - NotifyStatusChange(); |
| - } |
| + virtual void OnPolicyUpdated(const std::string& account_id) OVERRIDE; |
| + virtual void OnDeviceLocalAccountsChanged() OVERRIDE; |
| private: |
| const std::string account_id_; |
| @@ -333,14 +255,170 @@ class DeviceLocalAccountPolicyStatusProvider |
| }; |
| #endif |
| -//////////////////////////////////////////////////////////////////////////////// |
| -// |
| -// PolicyUIHandler |
| -// |
| -//////////////////////////////////////////////////////////////////////////////// |
| +// The JavaScript message handler for the chrome://policy page. |
| +class PolicyUIHandler : public content::WebUIMessageHandler, |
| + public policy::PolicyService::Observer { |
| + public: |
| + PolicyUIHandler(); |
| + virtual ~PolicyUIHandler(); |
| + |
| + // content::WebUIMessageHandler: |
| + virtual void RegisterMessages() OVERRIDE; |
| + |
| + // policy::PolicyService::Observer: |
| + virtual void OnPolicyUpdated(policy::PolicyDomain domain, |
| + const std::string& component_id, |
| + const policy::PolicyMap& previous, |
| + const policy::PolicyMap& current) OVERRIDE; |
| + |
| + private: |
| + // Send a dictionary containing the names of all known policies to the UI. |
| + void SendPolicyNames() const; |
| + // Send information about the current policy values to the UI. For each policy |
| + // whose value has been set, a dictionary containing the value and additional |
| + // metadata is sent. |
| + void SendPolicyValues() const; |
| + // Send the status of cloud policy to the UI. For each scope that has cloud |
| + // policy enabled (device and/or user), a dictionary containing status |
| + // information is sent. |
| + void SendStatus() const; |
| + |
| + void HandleInitialized(const base::ListValue* args); |
| + void HandleReloadPolicies(const base::ListValue* args); |
| + |
| + void OnRefreshPoliciesDone() const; |
| + |
| + policy::PolicyService* GetPolicyService() const; |
| + |
| + bool initialized_; |
| + std::string device_domain_; |
| + base::WeakPtrFactory<PolicyUIHandler> weak_factory_; |
| + |
| + // Providers that supply status dictionaries for user and device policy, |
| + // respectively. These are created on initialization time as appropriate for |
| + // the platform (Chrome OS / desktop) and type of policy that is in effect. |
| + scoped_ptr<CloudPolicyStatusProvider> user_status_provider_; |
| + scoped_ptr<CloudPolicyStatusProvider> device_status_provider_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PolicyUIHandler); |
| +}; |
| + |
| +CloudPolicyStatusProvider::CloudPolicyStatusProvider() { |
| +} |
| + |
| +CloudPolicyStatusProvider::~CloudPolicyStatusProvider() { |
| +} |
| + |
| +void CloudPolicyStatusProvider::SetStatusChangeCallback( |
| + const base::Closure& callback) { |
| + callback_ = callback; |
| +} |
| + |
| +void CloudPolicyStatusProvider::GetStatus(base::DictionaryValue* dict) { |
| +} |
| + |
| +void CloudPolicyStatusProvider::NotifyStatusChange() { |
| + if (!callback_.is_null()) |
| + callback_.Run(); |
| +} |
| + |
| +CloudPolicyCoreStatusProvider::CloudPolicyCoreStatusProvider( |
| + policy::CloudPolicyCore* core) : core_(core) { |
| + core_->store()->AddObserver(this); |
| + // TODO(bartfab): Add an observer that watches for client errors. Observing |
| + // core_->client() directly is not safe as the client may be destroyed and |
| + // (re-)created anytime if the user signs in or out on desktop platforms. |
| +} |
| + |
| +CloudPolicyCoreStatusProvider::~CloudPolicyCoreStatusProvider() { |
| + core_->store()->RemoveObserver(this); |
| +} |
| + |
| +void CloudPolicyCoreStatusProvider::OnStoreLoaded( |
| + policy::CloudPolicyStore* store) { |
| + NotifyStatusChange(); |
| +} |
| + |
| +void CloudPolicyCoreStatusProvider::OnStoreError( |
| + policy::CloudPolicyStore* store) { |
| + NotifyStatusChange(); |
| +} |
| + |
| +UserPolicyStatusProvider::UserPolicyStatusProvider( |
| + policy::CloudPolicyCore* core) : CloudPolicyCoreStatusProvider(core) { |
| +} |
| + |
| +UserPolicyStatusProvider::~UserPolicyStatusProvider() { |
| +} |
| + |
| +void UserPolicyStatusProvider::GetStatus(base::DictionaryValue* dict) { |
| + if (!core_->store()->is_managed()) |
| + return; |
| + GetStatusFromCore(core_, dict); |
| + ExtractDomainFromUsername(dict); |
| +} |
| + |
| +#if defined(OS_CHROMEOS) |
| +DevicePolicyStatusProvider::DevicePolicyStatusProvider( |
| + policy::BrowserPolicyConnector* connector) |
| + : CloudPolicyCoreStatusProvider( |
| + connector->GetDeviceCloudPolicyManager()->core()) { |
| + domain_ = connector->GetEnterpriseDomain(); |
| +} |
| + |
| +DevicePolicyStatusProvider::~DevicePolicyStatusProvider() { |
| +} |
| + |
| +void DevicePolicyStatusProvider::GetStatus(base::DictionaryValue* dict) { |
| + GetStatusFromCore(core_, dict); |
| + dict->SetString("domain", domain_); |
| +} |
| + |
| +DeviceLocalAccountPolicyStatusProvider::DeviceLocalAccountPolicyStatusProvider( |
| + const std::string& account_id, |
| + policy::DeviceLocalAccountPolicyService* service) |
| + : account_id_(account_id), |
| + service_(service) { |
| + service_->AddObserver(this); |
| +} |
| + |
| +DeviceLocalAccountPolicyStatusProvider:: |
| + ~DeviceLocalAccountPolicyStatusProvider() { |
| + service_->RemoveObserver(this); |
| +} |
| + |
| +void DeviceLocalAccountPolicyStatusProvider::GetStatus( |
| + base::DictionaryValue* dict) { |
| + const policy::DeviceLocalAccountPolicyBroker* broker = |
| + service_->GetBrokerForAccount(account_id_); |
| + if (broker) { |
| + GetStatusFromCore(broker->core(), dict); |
| + } else { |
| + dict->SetBoolean("error", true); |
| + dict->SetString("status", |
| + policy::FormatStoreStatus( |
| + policy::CloudPolicyStore::STATUS_BAD_STATE, |
| + policy::CloudPolicyValidatorBase::VALIDATION_OK)); |
| + dict->SetString("username", account_id_); |
| + } |
| + ExtractDomainFromUsername(dict); |
| + dict->SetBoolean("publicAccount", true); |
| +} |
| + |
| +void DeviceLocalAccountPolicyStatusProvider::OnPolicyUpdated( |
| + const std::string& account_id) { |
| + if (account_id == account_id_) |
| + NotifyStatusChange(); |
| +} |
| + |
| +void DeviceLocalAccountPolicyStatusProvider::OnDeviceLocalAccountsChanged() { |
| + NotifyStatusChange(); |
| +} |
| +#endif |
| PolicyUIHandler::PolicyUIHandler() |
| - : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {} |
| + : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| +} |
| PolicyUIHandler::~PolicyUIHandler() { |
| GetPolicyService()->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this); |
| @@ -350,14 +428,10 @@ void PolicyUIHandler::RegisterMessages() { |
| #if defined(OS_CHROMEOS) |
| policy::BrowserPolicyConnector* connector = |
| g_browser_process->browser_policy_connector(); |
| - if (connector->IsEnterpriseManaged()) { |
| - enterprise_domain_ = UTF8ToUTF16(connector->GetEnterpriseDomain()); |
| - device_status_provider_.reset( |
| - new CloudPolicyCoreStatusProvider( |
| - connector->GetDeviceCloudPolicyManager()->core())); |
| - } |
| + if (connector->IsEnterpriseManaged()) |
| + device_status_provider_.reset(new DevicePolicyStatusProvider(connector)); |
| - chromeos::UserManager* user_manager = chromeos::UserManager::Get(); |
| + const chromeos::UserManager* user_manager = chromeos::UserManager::Get(); |
| if (user_manager->IsLoggedInAsPublicAccount()) { |
| policy::DeviceLocalAccountPolicyService* local_account_service = |
| connector->GetDeviceLocalAccountPolicyService(); |
| @@ -371,7 +445,7 @@ void PolicyUIHandler::RegisterMessages() { |
| connector->GetUserCloudPolicyManager(); |
| if (user_cloud_policy_manager) { |
| user_status_provider_.reset( |
| - new CloudPolicyCoreStatusProvider(user_cloud_policy_manager->core())); |
| + new UserPolicyStatusProvider(user_cloud_policy_manager->core())); |
| } |
| } |
| #else |
| @@ -380,7 +454,7 @@ void PolicyUIHandler::RegisterMessages() { |
| Profile::FromWebUI(web_ui())); |
| if (user_cloud_policy_manager) { |
| user_status_provider_.reset( |
| - new CloudPolicyCoreStatusProvider(user_cloud_policy_manager->core())); |
| + new UserPolicyStatusProvider(user_cloud_policy_manager->core())); |
| } |
| #endif |
| @@ -389,19 +463,18 @@ void PolicyUIHandler::RegisterMessages() { |
| if (!device_status_provider_.get()) |
| device_status_provider_.reset(new CloudPolicyStatusProvider()); |
| - base::Closure update_callback(base::Bind(&PolicyUIHandler::SendDataToUI, |
| + base::Closure update_callback(base::Bind(&PolicyUIHandler::SendStatus, |
| base::Unretained(this))); |
| user_status_provider_->SetStatusChangeCallback(update_callback); |
| device_status_provider_->SetStatusChangeCallback(update_callback); |
| GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_CHROME, this); |
| web_ui()->RegisterMessageCallback( |
| - "requestData", |
| - base::Bind(&PolicyUIHandler::HandleRequestData, |
| - base::Unretained(this))); |
| + "initialized", |
| + base::Bind(&PolicyUIHandler::HandleInitialized, base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| - "fetchPolicy", |
| - base::Bind(&PolicyUIHandler::HandleFetchPolicy, |
| + "reloadPolicies", |
| + base::Bind(&PolicyUIHandler::HandleReloadPolicies, |
| base::Unretained(this))); |
| } |
| @@ -411,134 +484,103 @@ void PolicyUIHandler::OnPolicyUpdated(policy::PolicyDomain domain, |
| const policy::PolicyMap& current) { |
| DCHECK(domain == policy::POLICY_DOMAIN_CHROME); |
| DCHECK(component_id.empty()); |
| - SendDataToUI(); |
| + SendPolicyValues(); |
| +} |
| + |
| +void PolicyUIHandler::SendPolicyNames() const { |
| + base::DictionaryValue names; |
| + const policy::PolicyDefinitionList* list = |
| + policy::GetChromePolicyDefinitionList(); |
| + for (const policy::PolicyDefinitionList::Entry* entry = list->begin; |
| + entry != list->end; ++entry) { |
| + names.SetBoolean(entry->name, true); |
| + } |
| + web_ui()->CallJavascriptFunction("policy.Page.setPolicyNames", names); |
| } |
| -// static |
| -scoped_ptr<base::ListValue> PolicyUIHandler::GetPolicyStatusList( |
| - const policy::PolicyMap& policies, |
| - bool* any_policies_set) { |
| - scoped_ptr<base::ListValue> result(new base::ListValue()); |
| +void PolicyUIHandler::SendPolicyValues() const { |
| // Make a copy that can be modified, since some policy values are modified |
| // before being displayed. |
| - policy::PolicyMap policy_map; |
| - policy_map.CopyFrom(policies); |
| + policy::PolicyMap map; |
| + map.CopyFrom(GetPolicyService()->GetPolicies(policy::POLICY_DOMAIN_CHROME, |
| + std::string())); |
| // Get a list of all the errors in the policy values. |
| const policy::ConfigurationPolicyHandlerList* handler_list = |
| g_browser_process->browser_policy_connector()->GetHandlerList(); |
| policy::PolicyErrorMap errors; |
| - handler_list->ApplyPolicySettings(policy_map, NULL, &errors); |
| - handler_list->PrepareForDisplaying(&policy_map); |
| - |
| - // Append each known policy and its status. |
| - *any_policies_set = false; |
| - std::vector<base::DictionaryValue*> unset_policies; |
| - base::hash_set<std::string> known_names; |
| - const policy::PolicyDefinitionList* policy_list = |
| - policy::GetChromePolicyDefinitionList(); |
| - for (const policy::PolicyDefinitionList::Entry* policy = policy_list->begin; |
| - policy != policy_list->end; ++policy) { |
| - known_names.insert(policy->name); |
| - const policy::PolicyMap::Entry* entry = policy_map.Get(policy->name); |
| - string16 error_message = errors.GetErrors(policy->name); |
| - if (entry) { |
| - *any_policies_set = true; |
| - result->Append(GetPolicyDetails(policy, entry, error_message)); |
| - } else { |
| - unset_policies.push_back(GetPolicyErrorDetails(policy->name, false)); |
| - } |
| - } |
| - |
| - // Append unrecognized policy names. |
| - for (policy::PolicyMap::const_iterator it = policy_map.begin(); |
| - it != policy_map.end(); ++it) { |
| - if (!ContainsKey(known_names, it->first)) |
| - result->Append(GetPolicyErrorDetails(it->first, true)); |
| + handler_list->ApplyPolicySettings(map, NULL, &errors); |
| + |
| + // Convert dictionary values to strings for display. |
| + handler_list->PrepareForDisplaying(&map); |
| + |
| + base::DictionaryValue values; |
| + for (policy::PolicyMap::const_iterator entry = map.begin(); |
| + entry != map.end(); ++entry) { |
| + base::DictionaryValue* value = new base::DictionaryValue; |
| + value->Set("value", entry->second.value->DeepCopy()); |
| + if (entry->second.scope == policy::POLICY_SCOPE_USER) |
| + value->SetString("scope", "user"); |
| + else |
| + value->SetString("scope", "machine"); |
| + if (entry->second.level == policy::POLICY_LEVEL_RECOMMENDED) |
| + value->SetString("level", "recommended"); |
| + else |
| + value->SetString("level", "mandatory"); |
| + string16 error = errors.GetErrors(entry->first); |
| + if (!error.empty()) |
| + value->SetString("error", error); |
| + values.Set(entry->first, value); |
| } |
| - // Append policies that aren't currently configured to the end. |
| - for (std::vector<base::DictionaryValue*>::const_iterator it = |
| - unset_policies.begin(); |
| - it != unset_policies.end(); ++it) { |
| - result->Append(*it); |
| - } |
| + web_ui()->CallJavascriptFunction("policy.Page.setPolicyValues", values); |
| +} |
| - return result.Pass(); |
| +void PolicyUIHandler::SendStatus() const { |
| + scoped_ptr<base::DictionaryValue> device_status(new base::DictionaryValue); |
| + device_status_provider_->GetStatus(device_status.get()); |
| + if (!device_domain_.empty()) |
| + device_status->SetString("domain", device_domain_); |
| + scoped_ptr<base::DictionaryValue> user_status(new base::DictionaryValue); |
| + user_status_provider_->GetStatus(user_status.get()); |
| + std::string username; |
| + user_status->GetString("username", &username); |
| + if (!username.empty()) |
| + user_status->SetString("domain", gaia::ExtractDomainName(username)); |
| + |
| + base::DictionaryValue status; |
| + if (!device_status->empty()) |
| + status.Set("device", device_status.release()); |
| + if (!user_status->empty()) |
| + status.Set("user", user_status.release()); |
| + |
| + web_ui()->CallJavascriptFunction("policy.Page.setStatus", status); |
| } |
| -void PolicyUIHandler::HandleRequestData(const base::ListValue* args) { |
| - SendDataToUI(); |
| +void PolicyUIHandler::HandleInitialized(const base::ListValue* args) { |
| + SendPolicyNames(); |
| + SendPolicyValues(); |
| + SendStatus(); |
| } |
| -void PolicyUIHandler::HandleFetchPolicy(const base::ListValue* args) { |
| - // Fetching policy can potentially take a while due to cloud policy fetches. |
| - // Use a WeakPtr to make sure the callback is invalidated if the tab is closed |
| - // before the fetching completes. |
| +void PolicyUIHandler::HandleReloadPolicies(const base::ListValue* args) { |
| GetPolicyService()->RefreshPolicies( |
| - base::Bind(&PolicyUIHandler::OnRefreshDone, |
| + base::Bind(&PolicyUIHandler::OnRefreshPoliciesDone, |
| weak_factory_.GetWeakPtr())); |
| } |
| -void PolicyUIHandler::OnRefreshDone() { |
| - web_ui()->CallJavascriptFunction("Policy.refreshDone"); |
| -} |
| - |
| -void PolicyUIHandler::SendDataToUI() { |
| - policy::PolicyService* service = GetPolicyService(); |
| - bool any_policies_set = false; |
| - base::ListValue* list = |
| - GetPolicyStatusList( |
| - service->GetPolicies(policy::POLICY_DOMAIN_CHROME, std::string()), |
| - &any_policies_set).release(); |
| - base::DictionaryValue results; |
| - results.Set("policies", list); |
| - results.SetBoolean("anyPoliciesSet", any_policies_set); |
| - base::DictionaryValue* dict = GetStatusData(); |
| - results.Set("status", dict); |
| - web_ui()->CallJavascriptFunction("Policy.returnData", results); |
| +void PolicyUIHandler::OnRefreshPoliciesDone() const { |
| + web_ui()->CallJavascriptFunction("policy.Page.reloadPoliciesDone"); |
| } |
| -policy::PolicyService* PolicyUIHandler::GetPolicyService() { |
| - Profile* profile = Profile::FromWebUI(web_ui()); |
| - return profile->GetPolicyService(); |
| +policy::PolicyService* PolicyUIHandler::GetPolicyService() const { |
| + return Profile::FromWebUI(web_ui())->GetPolicyService(); |
| } |
| -base::DictionaryValue* PolicyUIHandler::GetStatusData() { |
| - base::DictionaryValue* results = new base::DictionaryValue(); |
| - |
| - scoped_ptr<base::DictionaryValue> user_status_dict( |
| - new base::DictionaryValue()); |
| - bool user_status_available = |
| - user_status_provider_->GetStatus(user_status_dict.get()); |
| - user_status_dict->SetBoolean("display", user_status_available); |
| - results->Set("userStatus", user_status_dict.release()); |
| - |
| - scoped_ptr<base::DictionaryValue> device_status_dict( |
| - new base::DictionaryValue()); |
| - bool device_status_available = |
| - device_status_provider_->GetStatus(device_status_dict.get()); |
| - device_status_dict->SetString("domain", enterprise_domain_); |
| - device_status_dict->SetBoolean("display", device_status_available); |
| - results->Set("deviceStatus", device_status_dict.release()); |
| - |
| - results->SetBoolean("displayStatusSection", |
| - user_status_available || device_status_available); |
| - return results; |
| -} |
| - |
| -//////////////////////////////////////////////////////////////////////////////// |
| -// |
| -// PolicyUI |
| -// |
| -//////////////////////////////////////////////////////////////////////////////// |
| - |
| PolicyUI::PolicyUI(content::WebUI* web_ui) : WebUIController(web_ui) { |
| web_ui->AddMessageHandler(new PolicyUIHandler); |
| - |
| - // Set up the chrome://policy/ source. |
| - Profile* profile = Profile::FromWebUI(web_ui); |
| - content::WebUIDataSource::Add(profile, CreatePolicyUIHTMLSource()); |
| + content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), |
| + CreatePolicyUIHTMLSource()); |
| } |
| PolicyUI::~PolicyUI() { |