1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/policy_ui.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/compiler_specific.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/strings/string16.h"
15 #include "base/time/time.h"
16 #include "base/values.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/policy/browser_policy_connector.h"
20 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
21 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
22 #include "chrome/browser/policy/cloud/cloud_policy_core.h"
23 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h"
24 #include "chrome/browser/policy/cloud/cloud_policy_store.h"
25 #include "chrome/browser/policy/cloud/cloud_policy_validator.h"
26 #include "chrome/browser/policy/cloud/message_util.h"
27 #include "chrome/browser/policy/configuration_policy_handler_list.h"
28 #include "chrome/browser/policy/policy_error_map.h"
29 #include "chrome/browser/policy/policy_map.h"
30 #include "chrome/browser/policy/policy_service.h"
31 #include "chrome/browser/policy/policy_types.h"
32 #include "chrome/browser/policy/profile_policy_connector.h"
33 #include "chrome/browser/policy/profile_policy_connector_factory.h"
34 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
35 #include "chrome/browser/profiles/profile.h"
36 #include "chrome/common/url_constants.h"
37 #include "content/public/browser/notification_observer.h"
38 #include "content/public/browser/notification_registrar.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/web_ui.h"
41 #include "content/public/browser/web_ui_data_source.h"
42 #include "content/public/browser/web_ui_message_handler.h"
43 #include "google_apis/gaia/gaia_auth_util.h"
44 #include "grit/browser_resources.h"
45 #include "grit/generated_resources.h"
46 #include "policy/policy_constants.h"
47 #include "ui/base/l10n/l10n_util.h"
48 #include "ui/base/l10n/time_format.h"
50 #if defined(OS_CHROMEOS)
51 #include "chrome/browser/chromeos/login/user_manager.h"
52 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
53 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
54 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
55 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
57 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
58 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
61 #if !defined(OS_ANDROID) && !defined(OS_IOS)
62 #include "chrome/browser/extensions/extension_service.h"
63 #include "chrome/browser/extensions/extension_system.h"
64 #include "chrome/browser/policy/policy_domain_descriptor.h"
65 #include "chrome/common/extensions/extension.h"
66 #include "chrome/common/extensions/extension_set.h"
67 #include "components/policy/core/common/schema.h"
68 #include "extensions/common/manifest.h"
69 #include "extensions/common/manifest_constants.h"
72 namespace em
= enterprise_management
;
76 content::WebUIDataSource
* CreatePolicyUIHTMLSource() {
77 content::WebUIDataSource
* source
=
78 content::WebUIDataSource::Create(chrome::kChromeUIPolicyHost
);
81 source
->AddLocalizedString("title", IDS_POLICY_TITLE
);
82 source
->AddLocalizedString("filterPlaceholder",
83 IDS_POLICY_FILTER_PLACEHOLDER
);
84 source
->AddLocalizedString("reloadPolicies", IDS_POLICY_RELOAD_POLICIES
);
85 source
->AddLocalizedString("status", IDS_POLICY_STATUS
);
86 source
->AddLocalizedString("statusDevice", IDS_POLICY_STATUS_DEVICE
);
87 source
->AddLocalizedString("statusUser", IDS_POLICY_STATUS_USER
);
88 source
->AddLocalizedString("labelDomain", IDS_POLICY_LABEL_DOMAIN
);
89 source
->AddLocalizedString("labelUsername", IDS_POLICY_LABEL_USERNAME
);
90 source
->AddLocalizedString("labelClientId", IDS_POLICY_LABEL_CLIENT_ID
);
91 source
->AddLocalizedString("labelTimeSinceLastRefresh",
92 IDS_POLICY_LABEL_TIME_SINCE_LAST_REFRESH
);
93 source
->AddLocalizedString("labelRefreshInterval",
94 IDS_POLICY_LABEL_REFRESH_INTERVAL
);
95 source
->AddLocalizedString("labelStatus", IDS_POLICY_LABEL_STATUS
);
96 source
->AddLocalizedString("showUnset", IDS_POLICY_SHOW_UNSET
);
97 source
->AddLocalizedString("noPoliciesSet", IDS_POLICY_NO_POLICIES_SET
);
98 source
->AddLocalizedString("headerScope", IDS_POLICY_HEADER_SCOPE
);
99 source
->AddLocalizedString("headerLevel", IDS_POLICY_HEADER_LEVEL
);
100 source
->AddLocalizedString("headerName", IDS_POLICY_HEADER_NAME
);
101 source
->AddLocalizedString("headerValue", IDS_POLICY_HEADER_VALUE
);
102 source
->AddLocalizedString("headerStatus", IDS_POLICY_HEADER_STATUS
);
103 source
->AddLocalizedString("showExpandedValue",
104 IDS_POLICY_SHOW_EXPANDED_VALUE
);
105 source
->AddLocalizedString("hideExpandedValue",
106 IDS_POLICY_HIDE_EXPANDED_VALUE
);
107 source
->AddLocalizedString("scopeUser", IDS_POLICY_SCOPE_USER
);
108 source
->AddLocalizedString("scopeDevice", IDS_POLICY_SCOPE_DEVICE
);
109 source
->AddLocalizedString("levelRecommended", IDS_POLICY_LEVEL_RECOMMENDED
);
110 source
->AddLocalizedString("levelMandatory", IDS_POLICY_LEVEL_MANDATORY
);
111 source
->AddLocalizedString("ok", IDS_POLICY_OK
);
112 source
->AddLocalizedString("unset", IDS_POLICY_UNSET
);
113 source
->AddLocalizedString("unknown", IDS_POLICY_UNKNOWN
);
115 source
->SetUseJsonJSFormatV2();
116 source
->SetJsonPath("strings.js");
118 // Add required resources.
119 source
->AddResourcePath("policy.css", IDR_POLICY_CSS
);
120 source
->AddResourcePath("policy.js", IDR_POLICY_JS
);
121 source
->AddResourcePath("uber_utils.js", IDR_UBER_UTILS_JS
);
122 source
->SetDefaultResource(IDR_POLICY_HTML
);
127 void GetStatusFromCore(const policy::CloudPolicyCore
* core
,
128 base::DictionaryValue
* dict
) {
129 const policy::CloudPolicyStore
* store
= core
->store();
130 const policy::CloudPolicyClient
* client
= core
->client();
131 const policy::CloudPolicyRefreshScheduler
* refresh_scheduler
=
132 core
->refresh_scheduler();
134 bool no_error
= store
->status() == policy::CloudPolicyStore::STATUS_OK
&&
135 client
&& client
->status() == policy::DM_STATUS_SUCCESS
;
136 string16 status
= store
->status() == policy::CloudPolicyStore::STATUS_OK
&&
137 client
&& client
->status() != policy::DM_STATUS_SUCCESS
?
138 policy::FormatDeviceManagementStatus(client
->status()) :
139 policy::FormatStoreStatus(store
->status(),
140 store
->validation_status());
141 const em::PolicyData
* policy
= store
->policy();
142 std::string client_id
= policy
? policy
->device_id() : std::string();
143 std::string username
= policy
? policy
->username() : std::string();
144 base::TimeDelta refresh_interval
=
145 base::TimeDelta::FromMilliseconds(refresh_scheduler
?
146 refresh_scheduler
->refresh_delay() :
147 policy::CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs
);
148 base::Time last_refresh_time
= refresh_scheduler
?
149 refresh_scheduler
->last_refresh() : base::Time();
151 dict
->SetBoolean("error", !no_error
);
152 dict
->SetString("status", status
);
153 dict
->SetString("clientId", client_id
);
154 dict
->SetString("username", username
);
155 dict
->SetString("refreshInterval",
156 ui::TimeFormat::TimeRemainingShort(refresh_interval
));
157 dict
->SetString("timeSinceLastRefresh", last_refresh_time
.is_null() ?
158 l10n_util::GetStringUTF16(IDS_POLICY_NEVER_FETCHED
) :
159 ui::TimeFormat::TimeElapsed(base::Time::NowFromSystemTime() -
163 void ExtractDomainFromUsername(base::DictionaryValue
* dict
) {
164 std::string username
;
165 dict
->GetString("username", &username
);
166 if (!username
.empty())
167 dict
->SetString("domain", gaia::ExtractDomainName(username
));
172 // An interface for querying the status of cloud policy.
173 class CloudPolicyStatusProvider
{
175 CloudPolicyStatusProvider();
176 virtual ~CloudPolicyStatusProvider();
178 // Sets a callback to invoke upon status changes.
179 void SetStatusChangeCallback(const base::Closure
& callback
);
181 virtual void GetStatus(base::DictionaryValue
* dict
);
184 void NotifyStatusChange();
187 base::Closure callback_
;
189 DISALLOW_COPY_AND_ASSIGN(CloudPolicyStatusProvider
);
192 // Status provider implementation that pulls cloud policy status from a
193 // CloudPolicyCore instance provided at construction time. Also listens for
194 // changes on that CloudPolicyCore and reports them through the status change
196 class CloudPolicyCoreStatusProvider
197 : public CloudPolicyStatusProvider
,
198 public policy::CloudPolicyStore::Observer
{
200 explicit CloudPolicyCoreStatusProvider(policy::CloudPolicyCore
* core
);
201 virtual ~CloudPolicyCoreStatusProvider();
203 // policy::CloudPolicyStore::Observer implementation.
204 virtual void OnStoreLoaded(policy::CloudPolicyStore
* store
) OVERRIDE
;
205 virtual void OnStoreError(policy::CloudPolicyStore
* store
) OVERRIDE
;
208 // Policy status is read from the CloudPolicyClient, CloudPolicyStore and
209 // CloudPolicyRefreshScheduler hosted by this |core_|.
210 policy::CloudPolicyCore
* core_
;
212 DISALLOW_COPY_AND_ASSIGN(CloudPolicyCoreStatusProvider
);
215 // A cloud policy status provider for user policy.
216 class UserPolicyStatusProvider
: public CloudPolicyCoreStatusProvider
{
218 explicit UserPolicyStatusProvider(policy::CloudPolicyCore
* core
);
219 virtual ~UserPolicyStatusProvider();
221 // CloudPolicyCoreStatusProvider implementation.
222 virtual void GetStatus(base::DictionaryValue
* dict
) OVERRIDE
;
225 DISALLOW_COPY_AND_ASSIGN(UserPolicyStatusProvider
);
228 #if defined(OS_CHROMEOS)
229 // A cloud policy status provider for device policy.
230 class DevicePolicyStatusProvider
: public CloudPolicyCoreStatusProvider
{
232 explicit DevicePolicyStatusProvider(
233 policy::BrowserPolicyConnector
* connector
);
234 virtual ~DevicePolicyStatusProvider();
236 // CloudPolicyCoreStatusProvider implementation.
237 virtual void GetStatus(base::DictionaryValue
* dict
) OVERRIDE
;
242 DISALLOW_COPY_AND_ASSIGN(DevicePolicyStatusProvider
);
245 // A cloud policy status provider that reads policy status from the policy core
246 // associated with the device-local account specified by |user_id| at
247 // construction time. The indirection via user ID and
248 // DeviceLocalAccountPolicyService is necessary because the device-local account
249 // may go away any time behind the scenes, at which point the status message
250 // text will indicate CloudPolicyStore::STATUS_BAD_STATE.
251 class DeviceLocalAccountPolicyStatusProvider
252 : public CloudPolicyStatusProvider
,
253 public policy::DeviceLocalAccountPolicyService::Observer
{
255 DeviceLocalAccountPolicyStatusProvider(
256 const std::string
& user_id
,
257 policy::DeviceLocalAccountPolicyService
* service
);
258 virtual ~DeviceLocalAccountPolicyStatusProvider();
260 // CloudPolicyStatusProvider implementation.
261 virtual void GetStatus(base::DictionaryValue
* dict
) OVERRIDE
;
263 // policy::DeviceLocalAccountPolicyService::Observer implementation.
264 virtual void OnPolicyUpdated(const std::string
& user_id
) OVERRIDE
;
265 virtual void OnDeviceLocalAccountsChanged() OVERRIDE
;
268 const std::string user_id_
;
269 policy::DeviceLocalAccountPolicyService
* service_
;
271 DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountPolicyStatusProvider
);
275 // The JavaScript message handler for the chrome://policy page.
276 class PolicyUIHandler
: public content::NotificationObserver
,
277 public content::WebUIMessageHandler
,
278 public policy::PolicyService::Observer
{
281 virtual ~PolicyUIHandler();
283 // content::NotificationObserver implementation.
284 virtual void Observe(int type
,
285 const content::NotificationSource
& source
,
286 const content::NotificationDetails
& details
) OVERRIDE
;
288 // content::WebUIMessageHandler implementation.
289 virtual void RegisterMessages() OVERRIDE
;
291 // policy::PolicyService::Observer implementation.
292 virtual void OnPolicyUpdated(const policy::PolicyNamespace
& ns
,
293 const policy::PolicyMap
& previous
,
294 const policy::PolicyMap
& current
) OVERRIDE
;
297 // Send a dictionary containing the names of all known policies to the UI.
298 void SendPolicyNames() const;
300 // Send information about the current policy values to the UI. For each policy
301 // whose value has been set, a dictionary containing the value and additional
303 void SendPolicyValues() const;
305 // Send the status of cloud policy to the UI. For each scope that has cloud
306 // policy enabled (device and/or user), a dictionary containing status
307 // information is sent.
308 void SendStatus() const;
310 // Inserts a description of each policy in |policy_map| into |values|, using
311 // the optional errors in |errors| to determine the status of each policy.
312 void GetPolicyValues(const policy::PolicyMap
& policy_map
,
313 policy::PolicyErrorMap
* errors
,
314 base::DictionaryValue
* values
) const;
316 void GetChromePolicyValues(base::DictionaryValue
* values
) const;
318 void HandleInitialized(const base::ListValue
* args
);
319 void HandleReloadPolicies(const base::ListValue
* args
);
321 void OnRefreshPoliciesDone() const;
323 policy::PolicyService
* GetPolicyService() const;
326 std::string device_domain_
;
328 // Providers that supply status dictionaries for user and device policy,
329 // respectively. These are created on initialization time as appropriate for
330 // the platform (Chrome OS / desktop) and type of policy that is in effect.
331 scoped_ptr
<CloudPolicyStatusProvider
> user_status_provider_
;
332 scoped_ptr
<CloudPolicyStatusProvider
> device_status_provider_
;
334 content::NotificationRegistrar registrar_
;
336 base::WeakPtrFactory
<PolicyUIHandler
> weak_factory_
;
338 DISALLOW_COPY_AND_ASSIGN(PolicyUIHandler
);
341 CloudPolicyStatusProvider::CloudPolicyStatusProvider() {
344 CloudPolicyStatusProvider::~CloudPolicyStatusProvider() {
347 void CloudPolicyStatusProvider::SetStatusChangeCallback(
348 const base::Closure
& callback
) {
349 callback_
= callback
;
352 void CloudPolicyStatusProvider::GetStatus(base::DictionaryValue
* dict
) {
355 void CloudPolicyStatusProvider::NotifyStatusChange() {
356 if (!callback_
.is_null())
360 CloudPolicyCoreStatusProvider::CloudPolicyCoreStatusProvider(
361 policy::CloudPolicyCore
* core
) : core_(core
) {
362 core_
->store()->AddObserver(this);
363 // TODO(bartfab): Add an observer that watches for client errors. Observing
364 // core_->client() directly is not safe as the client may be destroyed and
365 // (re-)created anytime if the user signs in or out on desktop platforms.
368 CloudPolicyCoreStatusProvider::~CloudPolicyCoreStatusProvider() {
369 core_
->store()->RemoveObserver(this);
372 void CloudPolicyCoreStatusProvider::OnStoreLoaded(
373 policy::CloudPolicyStore
* store
) {
374 NotifyStatusChange();
377 void CloudPolicyCoreStatusProvider::OnStoreError(
378 policy::CloudPolicyStore
* store
) {
379 NotifyStatusChange();
382 UserPolicyStatusProvider::UserPolicyStatusProvider(
383 policy::CloudPolicyCore
* core
) : CloudPolicyCoreStatusProvider(core
) {
386 UserPolicyStatusProvider::~UserPolicyStatusProvider() {
389 void UserPolicyStatusProvider::GetStatus(base::DictionaryValue
* dict
) {
390 if (!core_
->store()->is_managed())
392 GetStatusFromCore(core_
, dict
);
393 ExtractDomainFromUsername(dict
);
396 #if defined(OS_CHROMEOS)
397 DevicePolicyStatusProvider::DevicePolicyStatusProvider(
398 policy::BrowserPolicyConnector
* connector
)
399 : CloudPolicyCoreStatusProvider(
400 connector
->GetDeviceCloudPolicyManager()->core()) {
401 domain_
= connector
->GetEnterpriseDomain();
404 DevicePolicyStatusProvider::~DevicePolicyStatusProvider() {
407 void DevicePolicyStatusProvider::GetStatus(base::DictionaryValue
* dict
) {
408 GetStatusFromCore(core_
, dict
);
409 dict
->SetString("domain", domain_
);
412 DeviceLocalAccountPolicyStatusProvider::DeviceLocalAccountPolicyStatusProvider(
413 const std::string
& user_id
,
414 policy::DeviceLocalAccountPolicyService
* service
)
417 service_
->AddObserver(this);
420 DeviceLocalAccountPolicyStatusProvider::
421 ~DeviceLocalAccountPolicyStatusProvider() {
422 service_
->RemoveObserver(this);
425 void DeviceLocalAccountPolicyStatusProvider::GetStatus(
426 base::DictionaryValue
* dict
) {
427 const policy::DeviceLocalAccountPolicyBroker
* broker
=
428 service_
->GetBrokerForUser(user_id_
);
430 GetStatusFromCore(broker
->core(), dict
);
432 dict
->SetBoolean("error", true);
433 dict
->SetString("status",
434 policy::FormatStoreStatus(
435 policy::CloudPolicyStore::STATUS_BAD_STATE
,
436 policy::CloudPolicyValidatorBase::VALIDATION_OK
));
437 dict
->SetString("username", std::string());
439 ExtractDomainFromUsername(dict
);
440 dict
->SetBoolean("publicAccount", true);
443 void DeviceLocalAccountPolicyStatusProvider::OnPolicyUpdated(
444 const std::string
& user_id
) {
445 if (user_id
== user_id_
)
446 NotifyStatusChange();
449 void DeviceLocalAccountPolicyStatusProvider::OnDeviceLocalAccountsChanged() {
450 NotifyStatusChange();
454 PolicyUIHandler::PolicyUIHandler()
455 : initialized_(false),
456 weak_factory_(this) {
459 PolicyUIHandler::~PolicyUIHandler() {
460 GetPolicyService()->RemoveObserver(policy::POLICY_DOMAIN_CHROME
, this);
461 GetPolicyService()->RemoveObserver(policy::POLICY_DOMAIN_EXTENSIONS
, this);
464 void PolicyUIHandler::RegisterMessages() {
465 #if defined(OS_CHROMEOS)
466 policy::BrowserPolicyConnector
* connector
=
467 g_browser_process
->browser_policy_connector();
468 if (connector
->IsEnterpriseManaged())
469 device_status_provider_
.reset(new DevicePolicyStatusProvider(connector
));
471 const chromeos::UserManager
* user_manager
= chromeos::UserManager::Get();
472 if (user_manager
->IsLoggedInAsPublicAccount()) {
473 policy::DeviceLocalAccountPolicyService
* local_account_service
=
474 connector
->GetDeviceLocalAccountPolicyService();
475 if (local_account_service
) {
476 user_status_provider_
.reset(
477 new DeviceLocalAccountPolicyStatusProvider(
478 user_manager
->GetLoggedInUser()->email(), local_account_service
));
481 policy::UserCloudPolicyManagerChromeOS
* user_cloud_policy_manager
=
482 policy::UserCloudPolicyManagerFactoryChromeOS::GetForProfile(
483 Profile::FromWebUI(web_ui()));
484 if (user_cloud_policy_manager
) {
485 user_status_provider_
.reset(
486 new UserPolicyStatusProvider(user_cloud_policy_manager
->core()));
490 policy::UserCloudPolicyManager
* user_cloud_policy_manager
=
491 policy::UserCloudPolicyManagerFactory::GetForProfile(
492 Profile::FromWebUI(web_ui()));
493 if (user_cloud_policy_manager
) {
494 user_status_provider_
.reset(
495 new UserPolicyStatusProvider(user_cloud_policy_manager
->core()));
499 if (!user_status_provider_
.get())
500 user_status_provider_
.reset(new CloudPolicyStatusProvider());
501 if (!device_status_provider_
.get())
502 device_status_provider_
.reset(new CloudPolicyStatusProvider());
504 base::Closure
update_callback(base::Bind(&PolicyUIHandler::SendStatus
,
505 base::Unretained(this)));
506 user_status_provider_
->SetStatusChangeCallback(update_callback
);
507 device_status_provider_
->SetStatusChangeCallback(update_callback
);
508 GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_CHROME
, this);
509 GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS
, this);
512 chrome::NOTIFICATION_EXTENSION_LOADED
,
513 content::NotificationService::AllSources());
515 chrome::NOTIFICATION_EXTENSION_UNLOADED
,
516 content::NotificationService::AllSources());
518 web_ui()->RegisterMessageCallback(
520 base::Bind(&PolicyUIHandler::HandleInitialized
, base::Unretained(this)));
521 web_ui()->RegisterMessageCallback(
523 base::Bind(&PolicyUIHandler::HandleReloadPolicies
,
524 base::Unretained(this)));
527 void PolicyUIHandler::Observe(int type
,
528 const content::NotificationSource
& source
,
529 const content::NotificationDetails
& details
) {
530 DCHECK(type
== chrome::NOTIFICATION_EXTENSION_LOADED
||
531 type
== chrome::NOTIFICATION_EXTENSION_UNLOADED
);
536 void PolicyUIHandler::OnPolicyUpdated(const policy::PolicyNamespace
& ns
,
537 const policy::PolicyMap
& previous
,
538 const policy::PolicyMap
& current
) {
542 void PolicyUIHandler::SendPolicyNames() const {
543 base::DictionaryValue names
;
545 // Add Chrome policy names.
546 base::DictionaryValue
* chrome_policy_names
= new base::DictionaryValue
;
547 const policy::PolicyDefinitionList
* list
=
548 policy::GetChromePolicyDefinitionList();
549 for (const policy::PolicyDefinitionList::Entry
* entry
= list
->begin
;
550 entry
!= list
->end
; ++entry
) {
551 chrome_policy_names
->SetBoolean(entry
->name
, true);
553 names
.Set("chromePolicyNames", chrome_policy_names
);
555 #if !defined(OS_ANDROID) && !defined(OS_IOS)
556 // Add extension policy names.
557 base::DictionaryValue
* extension_policy_names
= new base::DictionaryValue
;
558 extensions::ExtensionSystem
* extension_system
=
559 extensions::ExtensionSystem::Get(Profile::FromWebUI(web_ui()));
560 const ExtensionSet
* extensions
=
561 extension_system
->extension_service()->extensions();
562 scoped_refptr
<const policy::PolicyDomainDescriptor
> policy_domain_descriptor
;
563 policy_domain_descriptor
= GetPolicyService()->
564 GetPolicyDomainDescriptor(policy::POLICY_DOMAIN_EXTENSIONS
);
565 const policy::PolicyDomainDescriptor::SchemaMap
& schema_map
=
566 policy_domain_descriptor
->components();
568 for (ExtensionSet::const_iterator it
= extensions
->begin();
569 it
!= extensions
->end(); ++it
) {
570 const extensions::Extension
* extension
= it
->get();
571 // Skip this extension if it's not an enterprise extension.
572 if (!extension
->manifest()->HasPath(
573 extensions::manifest_keys::kStorageManagedSchema
))
575 base::DictionaryValue
* extension_value
= new base::DictionaryValue
;
576 extension_value
->SetString("name", extension
->name());
577 policy::PolicyDomainDescriptor::SchemaMap::const_iterator schema
=
578 schema_map
.find(extension
->id());
579 base::DictionaryValue
* policy_names
= new base::DictionaryValue
;
580 if (schema
!= schema_map
.end()) {
581 // Get policy names from the extension's policy schema.
582 // Store in a map, not an array, for faster lookup on JS side.
583 policy::Schema policy_schema
= schema
->second
;
584 for (policy::Schema::Iterator it_policies
=
585 policy_schema
.GetPropertiesIterator();
586 !it_policies
.IsAtEnd(); it_policies
.Advance()) {
587 policy_names
->SetBoolean(it_policies
.key(), true);
590 extension_value
->Set("policyNames", policy_names
);
591 extension_policy_names
->Set(extension
->id(), extension_value
);
593 names
.Set("extensionPolicyNames", extension_policy_names
);
596 web_ui()->CallJavascriptFunction("policy.Page.setPolicyNames", names
);
599 void PolicyUIHandler::SendPolicyValues() const {
600 base::DictionaryValue all_policies
;
602 // Add Chrome policy values.
603 base::DictionaryValue
* chrome_policies
= new base::DictionaryValue
;
604 GetChromePolicyValues(chrome_policies
);
605 all_policies
.Set("chromePolicies", chrome_policies
);
607 #if !defined(OS_ANDROID) && !defined(OS_IOS)
608 // Add extension policy values.
609 extensions::ExtensionSystem
* extension_system
=
610 extensions::ExtensionSystem::Get(Profile::FromWebUI(web_ui()));
611 const ExtensionSet
* extensions
=
612 extension_system
->extension_service()->extensions();
613 base::DictionaryValue
* extension_values
= new base::DictionaryValue
;
615 for (ExtensionSet::const_iterator it
= extensions
->begin();
616 it
!= extensions
->end(); ++it
) {
617 const extensions::Extension
* extension
= it
->get();
618 // Skip this extension if it's not an enterprise extension.
619 if (!extension
->manifest()->HasPath(
620 extensions::manifest_keys::kStorageManagedSchema
))
622 base::DictionaryValue
* extension_policies
= new base::DictionaryValue
;
623 policy::PolicyNamespace policy_namespace
= policy::PolicyNamespace(
624 policy::POLICY_DOMAIN_EXTENSIONS
, extension
->id());
625 policy::PolicyErrorMap empty_error_map
;
626 GetPolicyValues(GetPolicyService()->GetPolicies(policy_namespace
),
627 &empty_error_map
, extension_policies
);
628 extension_values
->Set(extension
->id(), extension_policies
);
630 all_policies
.Set("extensionPolicies", extension_values
);
632 web_ui()->CallJavascriptFunction("policy.Page.setPolicyValues", all_policies
);
635 void PolicyUIHandler::GetPolicyValues(const policy::PolicyMap
& map
,
636 policy::PolicyErrorMap
* errors
,
637 base::DictionaryValue
* values
) const {
638 for (policy::PolicyMap::const_iterator entry
= map
.begin();
639 entry
!= map
.end(); ++entry
) {
640 base::DictionaryValue
* value
= new base::DictionaryValue
;
641 value
->Set("value", entry
->second
.value
->DeepCopy());
642 if (entry
->second
.scope
== policy::POLICY_SCOPE_USER
)
643 value
->SetString("scope", "user");
645 value
->SetString("scope", "machine");
646 if (entry
->second
.level
== policy::POLICY_LEVEL_RECOMMENDED
)
647 value
->SetString("level", "recommended");
649 value
->SetString("level", "mandatory");
650 string16 error
= errors
->GetErrors(entry
->first
);
652 value
->SetString("error", error
);
653 values
->Set(entry
->first
, value
);
657 void PolicyUIHandler::GetChromePolicyValues(
658 base::DictionaryValue
* values
) const {
659 policy::PolicyService
* policy_service
= GetPolicyService();
660 policy::PolicyMap map
;
662 // Make a copy that can be modified, since some policy values are modified
663 // before being displayed.
664 map
.CopyFrom(policy_service
->GetPolicies(
665 policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME
, std::string())));
667 // Get a list of all the errors in the policy values.
668 const policy::ConfigurationPolicyHandlerList
* handler_list
=
669 g_browser_process
->browser_policy_connector()->GetHandlerList();
670 policy::PolicyErrorMap errors
;
671 handler_list
->ApplyPolicySettings(map
, NULL
, &errors
);
673 // Convert dictionary values to strings for display.
674 handler_list
->PrepareForDisplaying(&map
);
676 GetPolicyValues(map
, &errors
, values
);
679 void PolicyUIHandler::SendStatus() const {
680 scoped_ptr
<base::DictionaryValue
> device_status(new base::DictionaryValue
);
681 device_status_provider_
->GetStatus(device_status
.get());
682 if (!device_domain_
.empty())
683 device_status
->SetString("domain", device_domain_
);
684 scoped_ptr
<base::DictionaryValue
> user_status(new base::DictionaryValue
);
685 user_status_provider_
->GetStatus(user_status
.get());
686 std::string username
;
687 user_status
->GetString("username", &username
);
688 if (!username
.empty())
689 user_status
->SetString("domain", gaia::ExtractDomainName(username
));
691 base::DictionaryValue status
;
692 if (!device_status
->empty())
693 status
.Set("device", device_status
.release());
694 if (!user_status
->empty())
695 status
.Set("user", user_status
.release());
697 web_ui()->CallJavascriptFunction("policy.Page.setStatus", status
);
700 void PolicyUIHandler::HandleInitialized(const base::ListValue
* args
) {
706 void PolicyUIHandler::HandleReloadPolicies(const base::ListValue
* args
) {
707 GetPolicyService()->RefreshPolicies(
708 base::Bind(&PolicyUIHandler::OnRefreshPoliciesDone
,
709 weak_factory_
.GetWeakPtr()));
712 void PolicyUIHandler::OnRefreshPoliciesDone() const {
713 web_ui()->CallJavascriptFunction("policy.Page.reloadPoliciesDone");
716 policy::PolicyService
* PolicyUIHandler::GetPolicyService() const {
717 return policy::ProfilePolicyConnectorFactory::GetForProfile(
718 Profile::FromWebUI(web_ui()))->policy_service();
721 PolicyUI::PolicyUI(content::WebUI
* web_ui
) : WebUIController(web_ui
) {
722 web_ui
->AddMessageHandler(new PolicyUIHandler
);
723 content::WebUIDataSource::Add(Profile::FromWebUI(web_ui
),
724 CreatePolicyUIHTMLSource());
727 PolicyUI::~PolicyUI() {