Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Side by Side Diff: remoting/host/policy_watcher.cc

Issue 2710023003: Refactor PolicyWatcher to allow mocking (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Most of this code is copied from: 5 // Most of this code is copied from:
6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc} 6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc}
7 7
8 #include "remoting/host/policy_watcher.h" 8 #include "remoting/host/policy_watcher.h"
9 9
10 #include <utility> 10 #include <utility>
(...skipping 29 matching lines...) Expand all
40 #elif defined(OS_POSIX) && !defined(OS_ANDROID) 40 #elif defined(OS_POSIX) && !defined(OS_ANDROID)
41 #include "components/policy/core/common/config_dir_policy_loader.h" 41 #include "components/policy/core/common/config_dir_policy_loader.h"
42 #endif 42 #endif
43 43
44 namespace remoting { 44 namespace remoting {
45 45
46 namespace key = ::policy::key; 46 namespace key = ::policy::key;
47 47
48 namespace { 48 namespace {
49 49
50 // Watches for changes to the managed remote access host policies.
51 class PolicyWatcherImpl : public PolicyWatcher,
52 private policy::PolicyService::Observer {
53 public:
54 // |policy_service_task_runner| is the task runner where it is safe
55 // to call |policy_service_| methods and where we expect to get callbacks
56 // from |policy_service_|.
57 PolicyWatcherImpl(
58 policy::PolicyService* policy_service,
59 std::unique_ptr<policy::PolicyService> owned_policy_service,
60 std::unique_ptr<policy::ConfigurationPolicyProvider>
61 owned_policy_provider,
62 std::unique_ptr<policy::SchemaRegistry> owned_schema_registry);
63
64 ~PolicyWatcherImpl() override;
65
66 void StartWatching(const PolicyUpdatedCallback& policy_updated_callback,
67 const PolicyErrorCallback& policy_error_callback) override;
68
69 private:
70 friend class PolicyWatcherTest;
71
72 const policy::Schema* GetPolicySchema() const override;
73 const base::DictionaryValue* GetDefaultValues() const override;
74
75 // Simplifying wrapper around Schema::Normalize.
76 // - Returns false if |dict| is invalid (i.e. contains mistyped policy
77 // values).
78 // - Returns true if |dict| was valid or got normalized.
79 bool NormalizePolicies(base::DictionaryValue* dict);
80
81 // Stores |new_policies| into |old_policies_|. Returns dictionary with items
82 // from |new_policies| that are different from the old |old_policies_|.
83 std::unique_ptr<base::DictionaryValue> StoreNewAndReturnChangedPolicies(
84 std::unique_ptr<base::DictionaryValue> new_policies);
85
86 // Signals policy error to the registered |PolicyErrorCallback|.
87 void SignalPolicyError();
88
89 // PolicyService::Observer interface.
90 void OnPolicyUpdated(const policy::PolicyNamespace& ns,
91 const policy::PolicyMap& previous,
92 const policy::PolicyMap& current) override;
93 void OnPolicyServiceInitialized(policy::PolicyDomain domain) override;
94
95 PolicyUpdatedCallback policy_updated_callback_;
96 PolicyErrorCallback policy_error_callback_;
97
98 std::unique_ptr<base::DictionaryValue> old_policies_;
99 std::unique_ptr<base::DictionaryValue> default_values_;
100
101 policy::PolicyService* policy_service_;
102
103 // Order of fields below is important to ensure destruction takes object
104 // dependencies into account:
105 // - |owned_policy_service_| uses |owned_policy_provider_|
106 // - |owned_policy_provider_| uses |owned_schema_registry_|
107 std::unique_ptr<policy::SchemaRegistry> owned_schema_registry_;
108 std::unique_ptr<policy::ConfigurationPolicyProvider> owned_policy_provider_;
109 std::unique_ptr<policy::PolicyService> owned_policy_service_;
110
111 DISALLOW_COPY_AND_ASSIGN(PolicyWatcherImpl);
112 };
113
50 // Copies all policy values from one dictionary to another, using values from 114 // Copies all policy values from one dictionary to another, using values from
51 // |default_values| if they are not set in |from|. 115 // |default_values| if they are not set in |from|.
52 std::unique_ptr<base::DictionaryValue> CopyValuesAndAddDefaults( 116 std::unique_ptr<base::DictionaryValue> CopyValuesAndAddDefaults(
53 const base::DictionaryValue& from, 117 const base::DictionaryValue& from,
54 const base::DictionaryValue& default_values) { 118 const base::DictionaryValue& default_values) {
55 std::unique_ptr<base::DictionaryValue> to(default_values.CreateDeepCopy()); 119 std::unique_ptr<base::DictionaryValue> to(default_values.CreateDeepCopy());
56 for (base::DictionaryValue::Iterator i(default_values); !i.IsAtEnd(); 120 for (base::DictionaryValue::Iterator i(default_values); !i.IsAtEnd();
57 i.Advance()) { 121 i.Advance()) {
58 const base::Value* value = nullptr; 122 const base::Value* value = nullptr;
59 123
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 &udp_port_range_string)) { 193 &udp_port_range_string)) {
130 if (!PortRange::Parse(udp_port_range_string, &udp_port_range)) { 194 if (!PortRange::Parse(udp_port_range_string, &udp_port_range)) {
131 return false; 195 return false;
132 } 196 }
133 } 197 }
134 198
135 // Report that all the policies were well-formed. 199 // Report that all the policies were well-formed.
136 return true; 200 return true;
137 } 201 }
138 202
139 } // namespace 203 void CopyDictionaryValue(const base::DictionaryValue& from,
204 base::DictionaryValue& to,
205 std::string key) {
206 const base::Value* value;
207 if (from.Get(key, &value)) {
208 to.Set(key, value->CreateDeepCopy());
209 }
210 }
140 211
141 void PolicyWatcher::StartWatching( 212 void PolicyWatcherImpl::StartWatching(
142 const PolicyUpdatedCallback& policy_updated_callback, 213 const PolicyUpdatedCallback& policy_updated_callback,
143 const PolicyErrorCallback& policy_error_callback) { 214 const PolicyErrorCallback& policy_error_callback) {
144 DCHECK(CalledOnValidThread()); 215 DCHECK(CalledOnValidThread());
145 DCHECK(!policy_updated_callback.is_null()); 216 DCHECK(!policy_updated_callback.is_null());
146 DCHECK(!policy_error_callback.is_null()); 217 DCHECK(!policy_error_callback.is_null());
147 DCHECK(policy_updated_callback_.is_null()); 218 DCHECK(policy_updated_callback_.is_null());
148 219
149 policy_updated_callback_ = policy_updated_callback; 220 policy_updated_callback_ = policy_updated_callback;
150 policy_error_callback_ = policy_error_callback; 221 policy_error_callback_ = policy_error_callback;
151 222
152 // Listen for future policy changes. 223 // Listen for future policy changes.
153 policy_service_->AddObserver(policy::POLICY_DOMAIN_CHROME, this); 224 policy_service_->AddObserver(policy::POLICY_DOMAIN_CHROME, this);
154 225
155 // Process current policy state. 226 // Process current policy state.
156 if (policy_service_->IsInitializationComplete(policy::POLICY_DOMAIN_CHROME)) { 227 if (policy_service_->IsInitializationComplete(policy::POLICY_DOMAIN_CHROME)) {
157 OnPolicyServiceInitialized(policy::POLICY_DOMAIN_CHROME); 228 OnPolicyServiceInitialized(policy::POLICY_DOMAIN_CHROME);
158 } 229 }
159 } 230 }
160 231
161 void PolicyWatcher::SignalPolicyError() { 232 void PolicyWatcherImpl::SignalPolicyError() {
162 old_policies_->Clear(); 233 old_policies_->Clear();
163 policy_error_callback_.Run(); 234 policy_error_callback_.Run();
164 } 235 }
165 236
166 PolicyWatcher::PolicyWatcher( 237 PolicyWatcherImpl::PolicyWatcherImpl(
167 policy::PolicyService* policy_service, 238 policy::PolicyService* policy_service,
168 std::unique_ptr<policy::PolicyService> owned_policy_service, 239 std::unique_ptr<policy::PolicyService> owned_policy_service,
169 std::unique_ptr<policy::ConfigurationPolicyProvider> owned_policy_provider, 240 std::unique_ptr<policy::ConfigurationPolicyProvider> owned_policy_provider,
170 std::unique_ptr<policy::SchemaRegistry> owned_schema_registry) 241 std::unique_ptr<policy::SchemaRegistry> owned_schema_registry)
171 : old_policies_(new base::DictionaryValue()), 242 : old_policies_(new base::DictionaryValue()),
172 default_values_(new base::DictionaryValue()), 243 default_values_(new base::DictionaryValue()),
173 policy_service_(policy_service), 244 policy_service_(policy_service),
174 owned_schema_registry_(std::move(owned_schema_registry)), 245 owned_schema_registry_(std::move(owned_schema_registry)),
175 owned_policy_provider_(std::move(owned_policy_provider)), 246 owned_policy_provider_(std::move(owned_policy_provider)),
176 owned_policy_service_(std::move(owned_policy_service)) { 247 owned_policy_service_(std::move(owned_policy_service)) {
(...skipping 15 matching lines...) Expand all
192 key::kRemoteAccessHostTokenValidationCertificateIssuer, std::string()); 263 key::kRemoteAccessHostTokenValidationCertificateIssuer, std::string());
193 default_values_->SetBoolean(key::kRemoteAccessHostAllowClientPairing, true); 264 default_values_->SetBoolean(key::kRemoteAccessHostAllowClientPairing, true);
194 default_values_->SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true); 265 default_values_->SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true);
195 default_values_->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, 266 default_values_->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection,
196 true); 267 true);
197 default_values_->SetString(key::kRemoteAccessHostUdpPortRange, ""); 268 default_values_->SetString(key::kRemoteAccessHostUdpPortRange, "");
198 default_values_->SetBoolean( 269 default_values_->SetBoolean(
199 key::kRemoteAccessHostAllowUiAccessForRemoteAssistance, false); 270 key::kRemoteAccessHostAllowUiAccessForRemoteAssistance, false);
200 } 271 }
201 272
202 PolicyWatcher::~PolicyWatcher() { 273 PolicyWatcherImpl::~PolicyWatcherImpl() {
203 // Stop observing |policy_service_| if StartWatching() has been called. 274 // Stop observing |policy_service_| if StartWatching() has been called.
204 if (!policy_updated_callback_.is_null()) { 275 if (!policy_updated_callback_.is_null()) {
205 policy_service_->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this); 276 policy_service_->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this);
206 } 277 }
207 278
208 if (owned_policy_provider_) { 279 if (owned_policy_provider_) {
209 owned_policy_provider_->Shutdown(); 280 owned_policy_provider_->Shutdown();
210 } 281 }
211 } 282 }
212 283
213 const policy::Schema* PolicyWatcher::GetPolicySchema() const { 284 const policy::Schema* PolicyWatcherImpl::GetPolicySchema() const {
214 return owned_schema_registry_->schema_map()->GetSchema(GetPolicyNamespace()); 285 return owned_schema_registry_->schema_map()->GetSchema(GetPolicyNamespace());
215 } 286 }
216 287
217 bool PolicyWatcher::NormalizePolicies(base::DictionaryValue* policy_dict) { 288 const base::DictionaryValue* PolicyWatcherImpl::GetDefaultValues() const {
289 return default_values_.get();
290 }
291
292 bool PolicyWatcherImpl::NormalizePolicies(base::DictionaryValue* policy_dict) {
218 // Allowing unrecognized policy names allows presence of 293 // Allowing unrecognized policy names allows presence of
219 // 1) comments (i.e. JSON of the form: { "_comment": "blah", ... }), 294 // 1) comments (i.e. JSON of the form: { "_comment": "blah", ... }),
220 // 2) policies intended for future/newer versions of the host, 295 // 2) policies intended for future/newer versions of the host,
221 // 3) policies not supported on all OS-s (i.e. RemoteAccessHostMatchUsername 296 // 3) policies not supported on all OS-s (i.e. RemoteAccessHostMatchUsername
222 // is not supported on Windows and therefore policy_templates.json omits 297 // is not supported on Windows and therefore policy_templates.json omits
223 // schema for this policy on this particular platform). 298 // schema for this policy on this particular platform).
224 auto strategy = policy::SCHEMA_ALLOW_UNKNOWN_TOPLEVEL; 299 auto strategy = policy::SCHEMA_ALLOW_UNKNOWN_TOPLEVEL;
225 300
226 std::string path; 301 std::string path;
227 std::string error; 302 std::string error;
228 bool changed = false; 303 bool changed = false;
229 const policy::Schema* schema = GetPolicySchema(); 304 const policy::Schema* schema = GetPolicySchema();
230 if (schema->Normalize(policy_dict, strategy, &path, &error, &changed)) { 305 if (schema->Normalize(policy_dict, strategy, &path, &error, &changed)) {
231 if (changed) { 306 if (changed) {
232 LOG(WARNING) << "Unknown (unrecognized or unsupported) policy: " << path 307 LOG(WARNING) << "Unknown (unrecognized or unsupported) policy: " << path
233 << ": " << error; 308 << ": " << error;
234 } 309 }
235 return true; 310 return true;
236 } else { 311 } else {
237 LOG(ERROR) << "Invalid policy contents: " << path << ": " << error; 312 LOG(ERROR) << "Invalid policy contents: " << path << ": " << error;
238 return false; 313 return false;
239 } 314 }
240 } 315 }
241 316
242 namespace {
243 void CopyDictionaryValue(const base::DictionaryValue& from,
244 base::DictionaryValue& to,
245 std::string key) {
246 const base::Value* value;
247 if (from.Get(key, &value)) {
248 to.Set(key, value->CreateDeepCopy());
249 }
250 }
251 } // namespace
252
253 std::unique_ptr<base::DictionaryValue> 317 std::unique_ptr<base::DictionaryValue>
254 PolicyWatcher::StoreNewAndReturnChangedPolicies( 318 PolicyWatcherImpl::StoreNewAndReturnChangedPolicies(
255 std::unique_ptr<base::DictionaryValue> new_policies) { 319 std::unique_ptr<base::DictionaryValue> new_policies) {
256 // Find the changed policies. 320 // Find the changed policies.
257 std::unique_ptr<base::DictionaryValue> changed_policies( 321 std::unique_ptr<base::DictionaryValue> changed_policies(
258 new base::DictionaryValue()); 322 new base::DictionaryValue());
259 base::DictionaryValue::Iterator iter(*new_policies); 323 base::DictionaryValue::Iterator iter(*new_policies);
260 while (!iter.IsAtEnd()) { 324 while (!iter.IsAtEnd()) {
261 base::Value* old_policy; 325 base::Value* old_policy;
262 if (!(old_policies_->Get(iter.key(), &old_policy) && 326 if (!(old_policies_->Get(iter.key(), &old_policy) &&
263 old_policy->Equals(&iter.value()))) { 327 old_policy->Equals(&iter.value()))) {
264 changed_policies->Set(iter.key(), iter.value().CreateDeepCopy()); 328 changed_policies->Set(iter.key(), iter.value().CreateDeepCopy());
(...skipping 13 matching lines...) Expand all
278 CopyDictionaryValue(*new_policies, *changed_policies, 342 CopyDictionaryValue(*new_policies, *changed_policies,
279 key::kRemoteAccessHostTokenValidationCertificateIssuer); 343 key::kRemoteAccessHostTokenValidationCertificateIssuer);
280 } 344 }
281 345
282 // Save the new policies. 346 // Save the new policies.
283 old_policies_.swap(new_policies); 347 old_policies_.swap(new_policies);
284 348
285 return changed_policies; 349 return changed_policies;
286 } 350 }
287 351
288 void PolicyWatcher::OnPolicyUpdated(const policy::PolicyNamespace& ns, 352 void PolicyWatcherImpl::OnPolicyUpdated(const policy::PolicyNamespace& ns,
289 const policy::PolicyMap& previous, 353 const policy::PolicyMap& previous,
290 const policy::PolicyMap& current) { 354 const policy::PolicyMap& current) {
291 std::unique_ptr<base::DictionaryValue> new_policies = 355 std::unique_ptr<base::DictionaryValue> new_policies =
292 CopyChromotingPoliciesIntoDictionary(current); 356 CopyChromotingPoliciesIntoDictionary(current);
293 357
294 // Check for mistyped values and get rid of unknown policies. 358 // Check for mistyped values and get rid of unknown policies.
295 if (!NormalizePolicies(new_policies.get())) { 359 if (!NormalizePolicies(new_policies.get())) {
296 SignalPolicyError(); 360 SignalPolicyError();
297 return; 361 return;
298 } 362 }
299 363
300 // Use default values for any missing policies. 364 // Use default values for any missing policies.
(...skipping 10 matching lines...) Expand all
311 // Verify that we are calling the callback with valid policies. 375 // Verify that we are calling the callback with valid policies.
312 if (!VerifyWellformedness(*changed_policies)) { 376 if (!VerifyWellformedness(*changed_policies)) {
313 SignalPolicyError(); 377 SignalPolicyError();
314 return; 378 return;
315 } 379 }
316 380
317 // Notify our client of the changed policies. 381 // Notify our client of the changed policies.
318 policy_updated_callback_.Run(std::move(changed_policies)); 382 policy_updated_callback_.Run(std::move(changed_policies));
319 } 383 }
320 384
321 void PolicyWatcher::OnPolicyServiceInitialized(policy::PolicyDomain domain) { 385 void PolicyWatcherImpl::OnPolicyServiceInitialized(
386 policy::PolicyDomain domain) {
322 policy::PolicyNamespace ns = GetPolicyNamespace(); 387 policy::PolicyNamespace ns = GetPolicyNamespace();
323 const policy::PolicyMap& current = policy_service_->GetPolicies(ns); 388 const policy::PolicyMap& current = policy_service_->GetPolicies(ns);
324 OnPolicyUpdated(ns, current, current); 389 OnPolicyUpdated(ns, current, current);
325 } 390 }
326 391
392 } // namespace
393
394 PolicyWatcher::PolicyWatcher() {}
395 PolicyWatcher::~PolicyWatcher() {}
396
327 std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateFromPolicyLoader( 397 std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateFromPolicyLoader(
328 std::unique_ptr<policy::AsyncPolicyLoader> async_policy_loader) { 398 std::unique_ptr<policy::AsyncPolicyLoader> async_policy_loader) {
329 std::unique_ptr<policy::SchemaRegistry> schema_registry = 399 std::unique_ptr<policy::SchemaRegistry> schema_registry =
330 CreateSchemaRegistry(); 400 CreateSchemaRegistry();
331 std::unique_ptr<policy::AsyncPolicyProvider> policy_provider( 401 std::unique_ptr<policy::AsyncPolicyProvider> policy_provider(
332 new policy::AsyncPolicyProvider(schema_registry.get(), 402 new policy::AsyncPolicyProvider(schema_registry.get(),
333 std::move(async_policy_loader))); 403 std::move(async_policy_loader)));
334 policy_provider->Init(schema_registry.get()); 404 policy_provider->Init(schema_registry.get());
335 405
336 policy::PolicyServiceImpl::Providers providers; 406 policy::PolicyServiceImpl::Providers providers;
337 providers.push_back(policy_provider.get()); 407 providers.push_back(policy_provider.get());
338 std::unique_ptr<policy::PolicyService> policy_service( 408 std::unique_ptr<policy::PolicyService> policy_service(
339 new policy::PolicyServiceImpl(providers)); 409 new policy::PolicyServiceImpl(providers));
340 410
341 policy::PolicyService* borrowed_policy_service = policy_service.get(); 411 policy::PolicyService* borrowed_policy_service = policy_service.get();
342 return base::WrapUnique(new PolicyWatcher( 412 return base::WrapUnique(new PolicyWatcherImpl(
343 borrowed_policy_service, std::move(policy_service), 413 borrowed_policy_service, std::move(policy_service),
344 std::move(policy_provider), std::move(schema_registry))); 414 std::move(policy_provider), std::move(schema_registry)));
345 } 415 }
346 416
347 std::unique_ptr<PolicyWatcher> PolicyWatcher::Create( 417 std::unique_ptr<PolicyWatcher> PolicyWatcher::Create(
348 policy::PolicyService* policy_service, 418 policy::PolicyService* policy_service,
349 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) { 419 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) {
350 #if defined(OS_CHROMEOS) 420 #if defined(OS_CHROMEOS)
351 // On Chrome OS the PolicyService is owned by the browser. 421 // On Chrome OS the PolicyService is owned by the browser.
352 DCHECK(policy_service); 422 DCHECK(policy_service);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 CreateSchemaRegistry())); 454 CreateSchemaRegistry()));
385 #else 455 #else
386 #error OS that is not yet supported by PolicyWatcher code. 456 #error OS that is not yet supported by PolicyWatcher code.
387 #endif 457 #endif
388 458
389 return PolicyWatcher::CreateFromPolicyLoader(std::move(policy_loader)); 459 return PolicyWatcher::CreateFromPolicyLoader(std::move(policy_loader));
390 #endif // !(OS_CHROMEOS) 460 #endif // !(OS_CHROMEOS)
391 } 461 }
392 462
393 } // namespace remoting 463 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698