1 // Copyright 2015 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 #ifndef REMOTING_HOST_POLICY_WATCHER_H_
6 #define REMOTING_HOST_POLICY_WATCHER_H_
8 #include "base/callback.h"
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/threading/non_thread_safe.h"
13 #include "components/policy/core/common/policy_service.h"
16 class DictionaryValue
;
17 class SingleThreadTaskRunner
;
21 class AsyncPolicyLoader
;
22 class ConfigurationPolicyProvider
;
29 // Watches for changes to the managed remote access host policies.
30 class PolicyWatcher
: public policy::PolicyService::Observer
,
31 public base::NonThreadSafe
{
33 // Called first with all policies, and subsequently with any changed policies.
34 typedef base::Callback
<void(scoped_ptr
<base::DictionaryValue
>)>
35 PolicyUpdatedCallback
;
37 // Called after detecting malformed policies.
38 typedef base::Callback
<void()> PolicyErrorCallback
;
40 ~PolicyWatcher() override
;
42 // This guarantees that the |policy_updated_callback| is called at least once
43 // with the current policies. After that, |policy_updated_callback| will be
44 // called whenever a change to any policy is detected. It will then be called
45 // only with the changed policies.
47 // |policy_error_callback| will be called when malformed policies are detected
48 // (i.e. wrong type of policy value, or unparseable files under
49 // /etc/opt/chrome/policies/managed).
50 // When called, the |policy_error_callback| is responsible for mitigating the
51 // security risk of running with incorrectly formulated policies (by either
52 // shutting down or locking down the host).
53 // After calling |policy_error_callback| PolicyWatcher will continue watching
54 // for policy changes and will call |policy_updated_callback| when the error
55 // is recovered from and may call |policy_error_callback| when new errors are
57 virtual void StartWatching(
58 const PolicyUpdatedCallback
& policy_updated_callback
,
59 const PolicyErrorCallback
& policy_error_callback
);
61 // Specify a |policy_service| to borrow (on Chrome OS, from the browser
62 // process) or specify nullptr to internally construct and use a new
63 // PolicyService (on other OS-es). PolicyWatcher must be used on the thread on
64 // which it is created. |policy_service| is called on the same thread.
66 // When |policy_service| is null, then |file_task_runner| is used for reading
67 // the policy from files / registry / preferences (which are blocking
68 // operations). |file_task_runner| should be of TYPE_IO type.
70 // When |policy_service| is specified then |file_task_runner| argument is
71 // ignored and 1) BrowserThread::UI is used for PolicyUpdatedCallback and
72 // PolicyErrorCallback and 2) BrowserThread::FILE is used for reading the
73 // policy from files / registry / preferences (although (2) is just an
74 // implementation detail and should likely be ignored outside of
76 static scoped_ptr
<PolicyWatcher
> Create(
77 policy::PolicyService
* policy_service
,
78 const scoped_refptr
<base::SingleThreadTaskRunner
>& file_task_runner
);
81 friend class PolicyWatcherTest
;
83 // Gets Chromoting schema stored inside |owned_schema_registry_|.
84 const policy::Schema
* GetPolicySchema() const;
86 // Simplifying wrapper around Schema::Normalize.
87 // - Returns false if |dict| is invalid (i.e. contains mistyped policy
89 // - Returns true if |dict| was valid or got normalized.
90 bool NormalizePolicies(base::DictionaryValue
* dict
);
92 // Stores |new_policies| into |old_policies_|. Returns dictionary with items
93 // from |new_policies| that are different from the old |old_policies_|.
94 scoped_ptr
<base::DictionaryValue
> StoreNewAndReturnChangedPolicies(
95 scoped_ptr
<base::DictionaryValue
> new_policies
);
97 // Signals policy error to the registered |PolicyErrorCallback|.
98 void SignalPolicyError();
100 // |policy_service_task_runner| is the task runner where it is safe
101 // to call |policy_service_| methods and where we expect to get callbacks
102 // from |policy_service_|.
104 policy::PolicyService
* policy_service
,
105 scoped_ptr
<policy::PolicyService
> owned_policy_service
,
106 scoped_ptr
<policy::ConfigurationPolicyProvider
> owned_policy_provider
,
107 scoped_ptr
<policy::SchemaRegistry
> owned_schema_registry
);
109 // Creates PolicyWatcher that wraps the owned |async_policy_loader| with an
110 // appropriate PolicySchema.
112 // |policy_service_task_runner| is passed through to the constructor of
114 static scoped_ptr
<PolicyWatcher
> CreateFromPolicyLoader(
115 scoped_ptr
<policy::AsyncPolicyLoader
> async_policy_loader
);
117 // PolicyService::Observer interface.
118 void OnPolicyUpdated(const policy::PolicyNamespace
& ns
,
119 const policy::PolicyMap
& previous
,
120 const policy::PolicyMap
& current
) override
;
121 void OnPolicyServiceInitialized(policy::PolicyDomain domain
) override
;
123 PolicyUpdatedCallback policy_updated_callback_
;
124 PolicyErrorCallback policy_error_callback_
;
126 scoped_ptr
<base::DictionaryValue
> old_policies_
;
127 scoped_ptr
<base::DictionaryValue
> default_values_
;
129 policy::PolicyService
* policy_service_
;
131 // Order of fields below is important to ensure destruction takes object
132 // dependencies into account:
133 // - |owned_policy_service_| uses |owned_policy_provider_|
134 // - |owned_policy_provider_| uses |owned_schema_registry_|
135 scoped_ptr
<policy::SchemaRegistry
> owned_schema_registry_
;
136 scoped_ptr
<policy::ConfigurationPolicyProvider
> owned_policy_provider_
;
137 scoped_ptr
<policy::PolicyService
> owned_policy_service_
;
139 DISALLOW_COPY_AND_ASSIGN(PolicyWatcher
);
142 } // namespace remoting
144 #endif // REMOTING_HOST_POLICY_WATCHER_H_