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

Side by Side Diff: components/policy/core/common/cloud/component_cloud_policy_service.cc

Issue 337053005: Precache policy-for-extensions for device-local accounts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed ios tests Created 6 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 #include "components/policy/core/common/cloud/component_cloud_policy_service.h" 5 #include "components/policy/core/common/cloud/component_cloud_policy_service.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 scoped_refptr<base::SequencedTaskRunner> task_runner_; 93 scoped_refptr<base::SequencedTaskRunner> task_runner_;
94 94
95 // The thread that the |service_| runs on. Used to post policy changes to the 95 // The thread that the |service_| runs on. Used to post policy changes to the
96 // right thread. 96 // right thread.
97 scoped_refptr<base::SequencedTaskRunner> service_task_runner_; 97 scoped_refptr<base::SequencedTaskRunner> service_task_runner_;
98 98
99 scoped_ptr<ResourceCache> cache_; 99 scoped_ptr<ResourceCache> cache_;
100 scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_; 100 scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_;
101 ComponentCloudPolicyStore store_; 101 ComponentCloudPolicyStore store_;
102 scoped_ptr<ComponentCloudPolicyUpdater> updater_; 102 scoped_ptr<ComponentCloudPolicyUpdater> updater_;
103 scoped_refptr<SchemaMap> schema_map_; 103 bool initialized_;
104 104
105 DISALLOW_COPY_AND_ASSIGN(Backend); 105 DISALLOW_COPY_AND_ASSIGN(Backend);
106 }; 106 };
107 107
108 ComponentCloudPolicyService::Backend::Backend( 108 ComponentCloudPolicyService::Backend::Backend(
109 base::WeakPtr<ComponentCloudPolicyService> service, 109 base::WeakPtr<ComponentCloudPolicyService> service,
110 scoped_refptr<base::SequencedTaskRunner> task_runner, 110 scoped_refptr<base::SequencedTaskRunner> task_runner,
111 scoped_refptr<base::SequencedTaskRunner> service_task_runner, 111 scoped_refptr<base::SequencedTaskRunner> service_task_runner,
112 scoped_ptr<ResourceCache> cache, 112 scoped_ptr<ResourceCache> cache,
113 scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher) 113 scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher)
114 : service_(service), 114 : service_(service),
115 task_runner_(task_runner), 115 task_runner_(task_runner),
116 service_task_runner_(service_task_runner), 116 service_task_runner_(service_task_runner),
117 cache_(cache.Pass()), 117 cache_(cache.Pass()),
118 external_policy_data_fetcher_(external_policy_data_fetcher.Pass()), 118 external_policy_data_fetcher_(external_policy_data_fetcher.Pass()),
119 store_(this, cache_.get()) {} 119 store_(this, cache_.get()),
120 initialized_(false) {}
120 121
121 ComponentCloudPolicyService::Backend::~Backend() {} 122 ComponentCloudPolicyService::Backend::~Backend() {}
122 123
123 void ComponentCloudPolicyService::Backend::SetCredentials( 124 void ComponentCloudPolicyService::Backend::SetCredentials(
124 const std::string& username, 125 const std::string& username,
125 const std::string& dm_token) { 126 const std::string& dm_token) {
126 if (username.empty() || dm_token.empty()) { 127 if (username.empty() || dm_token.empty()) {
127 // No sign-in credentials, so drop any cached policy. 128 // No sign-in credentials, so drop any cached policy.
128 store_.Clear(); 129 store_.Clear();
129 } else { 130 } else {
130 store_.SetCredentials(username, dm_token); 131 store_.SetCredentials(username, dm_token);
131 } 132 }
132 } 133 }
133 134
134 void ComponentCloudPolicyService::Backend::Init( 135 void ComponentCloudPolicyService::Backend::Init(
135 scoped_refptr<SchemaMap> schema_map) { 136 scoped_refptr<SchemaMap> schema_map) {
136 DCHECK(!schema_map_); 137 DCHECK(!initialized_);
137 138
138 OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>()); 139 OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>());
139 140
140 // Read the initial policy. Note that this does not trigger notifications 141 // Read the initial policy. Note that this does not trigger notifications
141 // through OnComponentCloudPolicyStoreUpdated. Note also that the cached 142 // through OnComponentCloudPolicyStoreUpdated. Note also that the cached
142 // data may contain names or values that don't match the schema for that 143 // data may contain names or values that don't match the schema for that
143 // component; the data must be cached without modifications so that its 144 // component; the data must be cached without modifications so that its
144 // integrity can be verified using the hash, but it must also be filtered 145 // integrity can be verified using the hash, but it must also be filtered
145 // right after a Load(). 146 // right after a Load().
146 store_.Load(); 147 store_.Load();
147 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); 148 scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
148 bundle->CopyFrom(store_.policy()); 149 bundle->CopyFrom(store_.policy());
149 schema_map_->FilterBundle(bundle.get());
150 150
151 // Start downloading any pending data. 151 // Start downloading any pending data.
152 updater_.reset(new ComponentCloudPolicyUpdater( 152 updater_.reset(new ComponentCloudPolicyUpdater(
153 task_runner_, external_policy_data_fetcher_.Pass(), &store_)); 153 task_runner_, external_policy_data_fetcher_.Pass(), &store_));
154 154
155 service_task_runner_->PostTask( 155 service_task_runner_->PostTask(
156 FROM_HERE, 156 FROM_HERE,
157 base::Bind(&ComponentCloudPolicyService::OnBackendInitialized, 157 base::Bind(&ComponentCloudPolicyService::OnBackendInitialized,
158 service_, 158 service_,
159 base::Passed(&bundle))); 159 base::Passed(&bundle)));
160
161 initialized_ = true;
160 } 162 }
161 163
162 void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( 164 void ComponentCloudPolicyService::Backend::UpdateExternalPolicy(
163 scoped_ptr<em::PolicyFetchResponse> response) { 165 scoped_ptr<em::PolicyFetchResponse> response) {
164 updater_->UpdateExternalPolicy(response.Pass()); 166 updater_->UpdateExternalPolicy(response.Pass());
165 } 167 }
166 168
167 void ComponentCloudPolicyService::Backend:: 169 void ComponentCloudPolicyService::Backend::
168 OnComponentCloudPolicyStoreUpdated() { 170 OnComponentCloudPolicyStoreUpdated() {
169 if (!schema_map_) { 171 if (!initialized_) {
170 // Ignore notifications triggered by the initial Purge or Clear. 172 // Ignore notifications triggered by the initial Purge or Clear.
171 return; 173 return;
172 } 174 }
173 175
174 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); 176 scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
175 bundle->CopyFrom(store_.policy()); 177 bundle->CopyFrom(store_.policy());
176 schema_map_->FilterBundle(bundle.get());
177 service_task_runner_->PostTask( 178 service_task_runner_->PostTask(
178 FROM_HERE, 179 FROM_HERE,
179 base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, 180 base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated,
180 service_, 181 service_,
181 base::Passed(&bundle))); 182 base::Passed(&bundle)));
182 } 183 }
183 184
184 void ComponentCloudPolicyService::Backend::OnSchemasUpdated( 185 void ComponentCloudPolicyService::Backend::OnSchemasUpdated(
185 scoped_refptr<SchemaMap> schema_map, 186 scoped_refptr<SchemaMap> schema_map,
186 scoped_ptr<PolicyNamespaceList> removed) { 187 scoped_ptr<PolicyNamespaceList> removed) {
187 // Purge any components that have been removed. 188 // Purge any components that have been removed.
188 const DomainMap& domains = schema_map->GetDomains(); 189 const DomainMap& domains = schema_map->GetDomains();
189 for (DomainMap::const_iterator domain = domains.begin(); 190 for (DomainMap::const_iterator domain = domains.begin();
190 domain != domains.end(); ++domain) { 191 domain != domains.end(); ++domain) {
191 store_.Purge(domain->first, 192 store_.Purge(domain->first,
192 base::Bind(&NotInSchemaMap, schema_map, domain->first)); 193 base::Bind(&NotInSchemaMap, schema_map, domain->first));
193 } 194 }
194 195
195 // Set |schema_map_| after purging so that the notifications from the store
196 // are ignored on the first OnSchemasUpdated() call from Init().
197 schema_map_ = schema_map;
198
199 if (removed) { 196 if (removed) {
200 for (size_t i = 0; i < removed->size(); ++i) 197 for (size_t i = 0; i < removed->size(); ++i)
201 updater_->CancelUpdate((*removed)[i]); 198 updater_->CancelUpdate((*removed)[i]);
202 } 199 }
203 } 200 }
204 201
205 ComponentCloudPolicyService::ComponentCloudPolicyService( 202 ComponentCloudPolicyService::ComponentCloudPolicyService(
206 Delegate* delegate, 203 Delegate* delegate,
207 SchemaRegistry* schema_registry, 204 SchemaRegistry* schema_registry,
208 CloudPolicyCore* core, 205 CloudPolicyCore* core,
209 scoped_ptr<ResourceCache> cache, 206 scoped_ptr<ResourceCache> cache,
210 scoped_refptr<net::URLRequestContextGetter> request_context, 207 scoped_refptr<net::URLRequestContextGetter> request_context,
211 scoped_refptr<base::SequencedTaskRunner> backend_task_runner, 208 scoped_refptr<base::SequencedTaskRunner> backend_task_runner,
212 scoped_refptr<base::SequencedTaskRunner> io_task_runner) 209 scoped_refptr<base::SequencedTaskRunner> io_task_runner)
213 : delegate_(delegate), 210 : delegate_(delegate),
214 schema_registry_(schema_registry), 211 schema_registry_(schema_registry),
215 core_(core), 212 core_(core),
216 request_context_(request_context), 213 request_context_(request_context),
217 backend_task_runner_(backend_task_runner), 214 backend_task_runner_(backend_task_runner),
218 io_task_runner_(io_task_runner), 215 io_task_runner_(io_task_runner),
219 current_schema_map_(new SchemaMap), 216 current_schema_map_(new SchemaMap),
217 unfiltered_policy_(new PolicyBundle),
220 started_loading_initial_policy_(false), 218 started_loading_initial_policy_(false),
221 loaded_initial_policy_(false), 219 loaded_initial_policy_(false),
222 is_registered_for_cloud_policy_(false), 220 is_registered_for_cloud_policy_(false),
223 weak_ptr_factory_(this) { 221 weak_ptr_factory_(this) {
224 external_policy_data_fetcher_backend_.reset( 222 external_policy_data_fetcher_backend_.reset(
225 new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context)); 223 new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context));
226 224
227 backend_.reset( 225 backend_.reset(
228 new Backend(weak_ptr_factory_.GetWeakPtr(), 226 new Backend(weak_ptr_factory_.GetWeakPtr(),
229 backend_task_runner_, 227 backend_task_runner_,
230 base::MessageLoopProxy::current(), 228 base::MessageLoopProxy::current(),
231 cache.Pass(), 229 cache.Pass(),
232 external_policy_data_fetcher_backend_->CreateFrontend( 230 external_policy_data_fetcher_backend_->CreateFrontend(
233 backend_task_runner_))); 231 backend_task_runner_)));
234 232
235 schema_registry_->AddObserver(this); 233 schema_registry_->AddObserver(this);
236 core_->store()->AddObserver(this); 234 core_->store()->AddObserver(this);
237 235
238 // Wait for the store and the schema registry to become ready before 236 // Wait for the store and the schema registry to become ready before
239 // initializing the backend, so that it can get the initial list of 237 // initializing the backend, so that it can get the initial list of
240 // components and the cached credentials (if any) to validate the cached 238 // components and the cached credentials (if any) to validate the cached
241 // policies. 239 // policies.
242 if (core_->store()->is_initialized()) 240 if (core_->store()->is_initialized())
243 OnStoreLoaded(core_->store()); 241 OnStoreLoaded(core_->store());
242
243 // Start observing the core and tracking the state of the client.
244 core_->AddObserver(this);
245 if (core_->client())
246 OnCoreConnected(core_);
244 } 247 }
245 248
246 ComponentCloudPolicyService::~ComponentCloudPolicyService() { 249 ComponentCloudPolicyService::~ComponentCloudPolicyService() {
247 DCHECK(CalledOnValidThread()); 250 DCHECK(CalledOnValidThread());
248 251
249 schema_registry_->RemoveObserver(this); 252 schema_registry_->RemoveObserver(this);
250 core_->store()->RemoveObserver(this); 253 core_->store()->RemoveObserver(this);
251 core_->RemoveObserver(this); 254 core_->RemoveObserver(this);
252 if (core_->client()) 255 if (core_->client())
253 OnCoreDisconnecting(core_); 256 OnCoreDisconnecting(core_);
(...skipping 26 matching lines...) Expand all
280 bool has_new_schemas) { 283 bool has_new_schemas) {
281 DCHECK(CalledOnValidThread()); 284 DCHECK(CalledOnValidThread());
282 285
283 // Ignore schema updates until the backend is initialized. 286 // Ignore schema updates until the backend is initialized.
284 // OnBackendInitialized() will send the current schema to the backend again, 287 // OnBackendInitialized() will send the current schema to the backend again,
285 // in case it was updated before the backend initialized. 288 // in case it was updated before the backend initialized.
286 if (!loaded_initial_policy_) 289 if (!loaded_initial_policy_)
287 return; 290 return;
288 291
289 ReloadSchema(); 292 ReloadSchema();
293
294 // Filter the |unfiltered_policy_| again, now that |current_schema_map_| has
295 // been updated. We must make sure we never serve invalid policy; we must
296 // also filter again if an invalid Schema has now been loaded.
297 OnPolicyUpdated(unfiltered_policy_.Pass());
290 } 298 }
291 299
292 void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) { 300 void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) {
293 DCHECK(CalledOnValidThread()); 301 DCHECK(CalledOnValidThread());
294 DCHECK_EQ(core_, core); 302 DCHECK_EQ(core_, core);
295 303
296 core_->client()->AddObserver(this); 304 core_->client()->AddObserver(this);
297 305
298 // Register the supported policy domains at the client. 306 // Register the supported policy domains at the client.
299 core_->client()->AddNamespaceToFetch( 307 core_->client()->AddNamespaceToFetch(
300 PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType, "")); 308 PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType, ""));
301 309
302 // Immediately load any PolicyFetchResponses that the client may already 310 // Immediately load any PolicyFetchResponses that the client may already
303 // have. 311 // have if the backend is ready.
304 OnPolicyFetched(core_->client()); 312 if (loaded_initial_policy_)
313 OnPolicyFetched(core_->client());
305 } 314 }
306 315
307 void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) { 316 void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) {
308 DCHECK(CalledOnValidThread()); 317 DCHECK(CalledOnValidThread());
309 DCHECK_EQ(core_, core); 318 DCHECK_EQ(core_, core);
310 319
311 core_->client()->RemoveObserver(this); 320 core_->client()->RemoveObserver(this);
312 321
313 // Remove all the namespaces from the client. 322 // Remove all the namespaces from the client.
314 core_->client()->RemoveNamespaceToFetch( 323 core_->client()->RemoveNamespaceToFetch(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 DCHECK(CalledOnValidThread()); 423 DCHECK(CalledOnValidThread());
415 // Ignored. 424 // Ignored.
416 } 425 }
417 426
418 void ComponentCloudPolicyService::InitializeIfReady() { 427 void ComponentCloudPolicyService::InitializeIfReady() {
419 DCHECK(CalledOnValidThread()); 428 DCHECK(CalledOnValidThread());
420 if (started_loading_initial_policy_ || !schema_registry_->IsReady() || 429 if (started_loading_initial_policy_ || !schema_registry_->IsReady() ||
421 !core_->store()->is_initialized()) { 430 !core_->store()->is_initialized()) {
422 return; 431 return;
423 } 432 }
433
424 // The initial list of components is ready. Initialize the backend now, which 434 // The initial list of components is ready. Initialize the backend now, which
425 // will call back to OnBackendInitialized. 435 // will call back to OnBackendInitialized.
426 backend_task_runner_->PostTask(FROM_HERE, 436 backend_task_runner_->PostTask(FROM_HERE,
427 base::Bind(&Backend::Init, 437 base::Bind(&Backend::Init,
428 base::Unretained(backend_.get()), 438 base::Unretained(backend_.get()),
429 schema_registry_->schema_map())); 439 schema_registry_->schema_map()));
430 started_loading_initial_policy_ = true; 440 started_loading_initial_policy_ = true;
431 } 441 }
432 442
433 void ComponentCloudPolicyService::OnBackendInitialized( 443 void ComponentCloudPolicyService::OnBackendInitialized(
434 scoped_ptr<PolicyBundle> initial_policy) { 444 scoped_ptr<PolicyBundle> initial_policy) {
435 DCHECK(CalledOnValidThread()); 445 DCHECK(CalledOnValidThread());
436 DCHECK(!loaded_initial_policy_); 446 DCHECK(!loaded_initial_policy_);
437 447
438 loaded_initial_policy_ = true; 448 loaded_initial_policy_ = true;
439 449
440 // We're now ready to serve the initial policy; notify the policy observers.
441 OnPolicyUpdated(initial_policy.Pass());
442
443 // Send the current schema to the backend, in case it has changed while the 450 // Send the current schema to the backend, in case it has changed while the
444 // backend was initializing. 451 // backend was initializing.
445 ReloadSchema(); 452 ReloadSchema();
446 453
447 // Start observing the core and tracking the state of the client. 454 // We're now ready to serve the initial policy; notify the policy observers.
448 core_->AddObserver(this); 455 OnPolicyUpdated(initial_policy.Pass());
449
450 if (core_->client())
451 OnCoreConnected(core_);
452 } 456 }
453 457
454 void ComponentCloudPolicyService::ReloadSchema() { 458 void ComponentCloudPolicyService::ReloadSchema() {
455 DCHECK(CalledOnValidThread()); 459 DCHECK(CalledOnValidThread());
456 460
457 scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList); 461 scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList);
458 PolicyNamespaceList added; 462 PolicyNamespaceList added;
459 const scoped_refptr<SchemaMap>& new_schema_map = 463 const scoped_refptr<SchemaMap>& new_schema_map =
460 schema_registry_->schema_map(); 464 schema_registry_->schema_map();
461 new_schema_map->GetChanges(current_schema_map_, removed.get(), &added); 465 new_schema_map->GetChanges(current_schema_map_, removed.get(), &added);
462 466
463 current_schema_map_ = new_schema_map; 467 current_schema_map_ = new_schema_map;
464 468
465 // Schedule a policy refresh if a new managed component was added.
466 if (core_->client() && !added.empty())
467 core_->RefreshSoon();
468
469 // Send the updated SchemaMap and a list of removed components to the 469 // Send the updated SchemaMap and a list of removed components to the
470 // backend. 470 // backend.
471 backend_task_runner_->PostTask(FROM_HERE, 471 backend_task_runner_->PostTask(FROM_HERE,
472 base::Bind(&Backend::OnSchemasUpdated, 472 base::Bind(&Backend::OnSchemasUpdated,
473 base::Unretained(backend_.get()), 473 base::Unretained(backend_.get()),
474 current_schema_map_, 474 current_schema_map_,
475 base::Passed(&removed))); 475 base::Passed(&removed)));
476
477 // Have another look at the client if the core is already connected.
478 // The client may have already fetched policy for some component and it was
479 // previously ignored because the component wasn't listed in the schema map.
480 // There's no point in fetching policy from the server again; the server
481 // always pushes all the components it knows about.
482 if (core_->client())
483 OnPolicyFetched(core_->client());
476 } 484 }
477 485
478 void ComponentCloudPolicyService::OnPolicyUpdated( 486 void ComponentCloudPolicyService::OnPolicyUpdated(
479 scoped_ptr<PolicyBundle> policy) { 487 scoped_ptr<PolicyBundle> policy) {
480 DCHECK(CalledOnValidThread()); 488 DCHECK(CalledOnValidThread());
481 policy_.Swap(policy.get()); 489
490 // Store the current unfiltered policies.
491 unfiltered_policy_ = policy.Pass();
492
493 // Make a copy in |policy_| and filter it; this is what's passed to the
494 // outside world.
495 policy_.CopyFrom(*unfiltered_policy_);
496 current_schema_map_->FilterBundle(&policy_);
497
482 delegate_->OnComponentCloudPolicyUpdated(); 498 delegate_->OnComponentCloudPolicyUpdated();
483 } 499 }
484 500
485 } // namespace policy 501 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698