| Index: chrome/browser/policy/cloud/component_cloud_policy_service.cc
|
| diff --git a/chrome/browser/policy/cloud/component_cloud_policy_service.cc b/chrome/browser/policy/cloud/component_cloud_policy_service.cc
|
| deleted file mode 100644
|
| index f19b3ff86301142c42034d8c39b6541ff9b87ee8..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/policy/cloud/component_cloud_policy_service.cc
|
| +++ /dev/null
|
| @@ -1,515 +0,0 @@
|
| -// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/policy/cloud/component_cloud_policy_service.h"
|
| -
|
| -#include <string>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/location.h"
|
| -#include "base/logging.h"
|
| -#include "base/message_loop/message_loop_proxy.h"
|
| -#include "base/sequenced_task_runner.h"
|
| -#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
|
| -#include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h"
|
| -#include "chrome/browser/policy/cloud/component_cloud_policy_store.h"
|
| -#include "chrome/browser/policy/cloud/component_cloud_policy_updater.h"
|
| -#include "chrome/browser/policy/cloud/external_policy_data_fetcher.h"
|
| -#include "chrome/browser/policy/cloud/resource_cache.h"
|
| -#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
|
| -#include "components/policy/core/common/schema.h"
|
| -#include "components/policy/core/common/schema_map.h"
|
| -#include "net/url_request/url_request_context_getter.h"
|
| -
|
| -namespace em = enterprise_management;
|
| -
|
| -namespace policy {
|
| -
|
| -namespace {
|
| -
|
| -bool NotInSchemaMap(const scoped_refptr<SchemaMap> schema_map,
|
| - PolicyDomain domain,
|
| - const std::string& component_id) {
|
| - return schema_map->GetSchema(PolicyNamespace(domain, component_id)) == NULL;
|
| -}
|
| -
|
| -bool ToPolicyNamespaceKey(const PolicyNamespace& ns, PolicyNamespaceKey* key) {
|
| - if (!ComponentCloudPolicyStore::GetPolicyType(ns.domain, &key->first))
|
| - return false;
|
| - key->second = ns.component_id;
|
| - return true;
|
| -}
|
| -
|
| -bool ToPolicyNamespace(const PolicyNamespaceKey& key, PolicyNamespace* ns) {
|
| - if (!ComponentCloudPolicyStore::GetPolicyDomain(key.first, &ns->domain))
|
| - return false;
|
| - ns->component_id = key.second;
|
| - return true;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -ComponentCloudPolicyService::Delegate::~Delegate() {}
|
| -
|
| -// Owns the objects that live on the background thread, and posts back to the
|
| -// thread that the ComponentCloudPolicyService runs on whenever the policy
|
| -// changes.
|
| -class ComponentCloudPolicyService::Backend
|
| - : public ComponentCloudPolicyStore::Delegate {
|
| - public:
|
| - // This class can be instantiated on any thread but from then on, may be
|
| - // accessed via the |task_runner_| only. Policy changes are posted to the
|
| - // |service| via the |service_task_runner|. The |cache| is used to load and
|
| - // store local copies of the downloaded policies.
|
| - Backend(base::WeakPtr<ComponentCloudPolicyService> service,
|
| - scoped_refptr<base::SequencedTaskRunner> task_runner,
|
| - scoped_refptr<base::SequencedTaskRunner> service_task_runner,
|
| - scoped_ptr<ResourceCache> cache,
|
| - scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher);
|
| -
|
| - virtual ~Backend();
|
| -
|
| - // |username| and |dm_token| will be used to validate the cached policies.
|
| - void SetCredentials(const std::string& username, const std::string& dm_token);
|
| -
|
| - // Loads the |store_| and starts downloading updates.
|
| - void Init(scoped_refptr<SchemaMap> schema_map);
|
| -
|
| - // Passes a policy protobuf to the backend, to start its validation and
|
| - // eventual download of the policy data on the background thread.
|
| - void UpdateExternalPolicy(scoped_ptr<em::PolicyFetchResponse> response);
|
| -
|
| - // ComponentCloudPolicyStore::Delegate implementation:
|
| - virtual void OnComponentCloudPolicyStoreUpdated() OVERRIDE;
|
| -
|
| - // Passes the current SchemaMap so that the disk cache can purge components
|
| - // that aren't being tracked anymore.
|
| - // |removed| is a list of namespaces that were present in the previous
|
| - // schema and have been removed in the updated version.
|
| - void OnSchemasUpdated(scoped_refptr<SchemaMap> schema_map,
|
| - scoped_ptr<PolicyNamespaceList> removed);
|
| -
|
| - private:
|
| - // The ComponentCloudPolicyService that owns |this|. Used to inform the
|
| - // |service_| when policy changes.
|
| - base::WeakPtr<ComponentCloudPolicyService> service_;
|
| -
|
| - // The thread that |this| runs on. Used to post tasks to be run by |this|.
|
| - scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
| -
|
| - // The thread that the |service_| runs on. Used to post policy changes to the
|
| - // right thread.
|
| - scoped_refptr<base::SequencedTaskRunner> service_task_runner_;
|
| -
|
| - scoped_ptr<ResourceCache> cache_;
|
| - scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_;
|
| - ComponentCloudPolicyStore store_;
|
| - scoped_ptr<ComponentCloudPolicyUpdater> updater_;
|
| - scoped_refptr<SchemaMap> schema_map_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(Backend);
|
| -};
|
| -
|
| -ComponentCloudPolicyService::Backend::Backend(
|
| - base::WeakPtr<ComponentCloudPolicyService> service,
|
| - scoped_refptr<base::SequencedTaskRunner> task_runner,
|
| - scoped_refptr<base::SequencedTaskRunner> service_task_runner,
|
| - scoped_ptr<ResourceCache> cache,
|
| - scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher)
|
| - : service_(service),
|
| - task_runner_(task_runner),
|
| - service_task_runner_(service_task_runner),
|
| - cache_(cache.Pass()),
|
| - external_policy_data_fetcher_(external_policy_data_fetcher.Pass()),
|
| - store_(this, cache_.get()) {}
|
| -
|
| -ComponentCloudPolicyService::Backend::~Backend() {}
|
| -
|
| -void ComponentCloudPolicyService::Backend::SetCredentials(
|
| - const std::string& username,
|
| - const std::string& dm_token) {
|
| - if (username.empty() || dm_token.empty()) {
|
| - // No sign-in credentials, so drop any cached policy.
|
| - store_.Clear();
|
| - } else {
|
| - store_.SetCredentials(username, dm_token);
|
| - }
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::Backend::Init(
|
| - scoped_refptr<SchemaMap> schema_map) {
|
| - DCHECK(!schema_map_);
|
| -
|
| - OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>());
|
| -
|
| - // Read the initial policy. Note that this does not trigger notifications
|
| - // through OnComponentCloudPolicyStoreUpdated. Note also that the cached
|
| - // data may contain names or values that don't match the schema for that
|
| - // component; the data must be cached without modifications so that its
|
| - // integrity can be verified using the hash, but it must also be filtered
|
| - // right after a Load().
|
| - store_.Load();
|
| - scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
|
| - bundle->CopyFrom(store_.policy());
|
| - schema_map_->FilterBundle(bundle.get());
|
| -
|
| - // Start downloading any pending data.
|
| - updater_.reset(new ComponentCloudPolicyUpdater(
|
| - task_runner_, external_policy_data_fetcher_.Pass(), &store_));
|
| -
|
| - service_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&ComponentCloudPolicyService::OnBackendInitialized,
|
| - service_,
|
| - base::Passed(&bundle)));
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::Backend::UpdateExternalPolicy(
|
| - scoped_ptr<em::PolicyFetchResponse> response) {
|
| - updater_->UpdateExternalPolicy(response.Pass());
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::Backend::
|
| - OnComponentCloudPolicyStoreUpdated() {
|
| - if (!schema_map_) {
|
| - // Ignore notifications triggered by the initial Purge or Clear.
|
| - return;
|
| - }
|
| -
|
| - scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
|
| - bundle->CopyFrom(store_.policy());
|
| - schema_map_->FilterBundle(bundle.get());
|
| - service_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated,
|
| - service_,
|
| - base::Passed(&bundle)));
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::Backend::OnSchemasUpdated(
|
| - scoped_refptr<SchemaMap> schema_map,
|
| - scoped_ptr<PolicyNamespaceList> removed) {
|
| - // Purge any components that have been removed.
|
| - const DomainMap& domains = schema_map->GetDomains();
|
| - for (DomainMap::const_iterator domain = domains.begin();
|
| - domain != domains.end(); ++domain) {
|
| - store_.Purge(domain->first,
|
| - base::Bind(&NotInSchemaMap, schema_map, domain->first));
|
| - }
|
| -
|
| - // Set |schema_map_| after purging so that the notifications from the store
|
| - // are ignored on the first OnSchemasUpdated() call from Init().
|
| - schema_map_ = schema_map;
|
| -
|
| - if (removed) {
|
| - for (size_t i = 0; i < removed->size(); ++i)
|
| - updater_->CancelUpdate((*removed)[i]);
|
| - }
|
| -}
|
| -
|
| -ComponentCloudPolicyService::ComponentCloudPolicyService(
|
| - Delegate* delegate,
|
| - SchemaRegistry* schema_registry,
|
| - CloudPolicyCore* core,
|
| - scoped_ptr<ResourceCache> cache,
|
| - scoped_refptr<net::URLRequestContextGetter> request_context,
|
| - scoped_refptr<base::SequencedTaskRunner> backend_task_runner,
|
| - scoped_refptr<base::SequencedTaskRunner> io_task_runner)
|
| - : delegate_(delegate),
|
| - schema_registry_(schema_registry),
|
| - core_(core),
|
| - request_context_(request_context),
|
| - backend_task_runner_(backend_task_runner),
|
| - io_task_runner_(io_task_runner),
|
| - current_schema_map_(new SchemaMap),
|
| - started_loading_initial_policy_(false),
|
| - loaded_initial_policy_(false),
|
| - is_registered_for_cloud_policy_(false),
|
| - weak_ptr_factory_(this) {
|
| - external_policy_data_fetcher_backend_.reset(
|
| - new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context));
|
| -
|
| - backend_.reset(
|
| - new Backend(weak_ptr_factory_.GetWeakPtr(),
|
| - backend_task_runner_,
|
| - base::MessageLoopProxy::current(),
|
| - cache.Pass(),
|
| - external_policy_data_fetcher_backend_->CreateFrontend(
|
| - backend_task_runner_)));
|
| -
|
| - schema_registry_->AddObserver(this);
|
| - core_->store()->AddObserver(this);
|
| -
|
| - // Wait for the store and the schema registry to become ready before
|
| - // initializing the backend, so that it can get the initial list of
|
| - // components and the cached credentials (if any) to validate the cached
|
| - // policies.
|
| - if (core_->store()->is_initialized())
|
| - OnStoreLoaded(core_->store());
|
| -}
|
| -
|
| -ComponentCloudPolicyService::~ComponentCloudPolicyService() {
|
| - DCHECK(CalledOnValidThread());
|
| -
|
| - schema_registry_->RemoveObserver(this);
|
| - core_->store()->RemoveObserver(this);
|
| - core_->RemoveObserver(this);
|
| - if (core_->client())
|
| - OnCoreDisconnecting(core_);
|
| -
|
| - io_task_runner_->DeleteSoon(FROM_HERE,
|
| - external_policy_data_fetcher_backend_.release());
|
| - backend_task_runner_->DeleteSoon(FROM_HERE, backend_.release());
|
| -}
|
| -
|
| -// static
|
| -bool ComponentCloudPolicyService::SupportsDomain(PolicyDomain domain) {
|
| - return ComponentCloudPolicyStore::SupportsDomain(domain);
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::ClearCache() {
|
| - DCHECK(CalledOnValidThread());
|
| - // Empty credentials will wipe the cache.
|
| - backend_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&Backend::SetCredentials,
|
| - base::Unretained(backend_.get()),
|
| - std::string(), std::string()));
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnSchemaRegistryReady() {
|
| - DCHECK(CalledOnValidThread());
|
| - InitializeIfReady();
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnSchemaRegistryUpdated(
|
| - bool has_new_schemas) {
|
| - DCHECK(CalledOnValidThread());
|
| -
|
| - // Ignore schema updates until the backend is initialized.
|
| - // OnBackendInitialized() will send the current schema to the backend again,
|
| - // in case it was updated before the backend initialized.
|
| - if (!loaded_initial_policy_)
|
| - return;
|
| -
|
| - SetCurrentSchema();
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK_EQ(core_, core);
|
| -
|
| - core_->client()->AddObserver(this);
|
| -
|
| - // Immediately load any PolicyFetchResponses that the client may already
|
| - // have.
|
| - OnPolicyFetched(core_->client());
|
| -
|
| - // Register the current namespaces at the client.
|
| - current_schema_map_ = new SchemaMap();
|
| - SetCurrentSchema();
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK_EQ(core_, core);
|
| -
|
| - core_->client()->RemoveObserver(this);
|
| -
|
| - // Remove all the namespaces from the client.
|
| - scoped_refptr<SchemaMap> empty = new SchemaMap();
|
| - PolicyNamespaceList removed;
|
| - PolicyNamespaceList added;
|
| - empty->GetChanges(current_schema_map_, &removed, &added);
|
| - for (size_t i = 0; i < removed.size(); ++i) {
|
| - PolicyNamespaceKey key;
|
| - if (ToPolicyNamespaceKey(removed[i], &key))
|
| - core_->client()->RemoveNamespaceToFetch(key);
|
| - }
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnRefreshSchedulerStarted(
|
| - CloudPolicyCore* core) {
|
| - // Ignored.
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnStoreLoaded(CloudPolicyStore* store) {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK_EQ(core_->store(), store);
|
| -
|
| - const bool was_registered_before = is_registered_for_cloud_policy_;
|
| -
|
| - // Send the current credentials to the backend; do this whenever the store
|
| - // updates, to handle the case of the user registering for policy after the
|
| - // session starts, or the user signing out.
|
| - const em::PolicyData* policy = core_->store()->policy();
|
| - std::string username;
|
| - std::string request_token;
|
| - if (policy && policy->has_username() && policy->has_request_token()) {
|
| - is_registered_for_cloud_policy_ = true;
|
| - username = policy->username();
|
| - request_token = policy->request_token();
|
| - } else {
|
| - is_registered_for_cloud_policy_ = false;
|
| - }
|
| -
|
| - // Empty credentials will wipe the cache.
|
| - backend_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&Backend::SetCredentials,
|
| - base::Unretained(backend_.get()),
|
| - username,
|
| - request_token));
|
| -
|
| - if (!loaded_initial_policy_) {
|
| - // This is the initial load; check if we're ready to initialize the
|
| - // backend, regardless of the signin state.
|
| - InitializeIfReady();
|
| - } else if (!was_registered_before && is_registered_for_cloud_policy_) {
|
| - // We are already initialized, but just sent credentials to the backend for
|
| - // the first time; this means that the user was not registered for cloud
|
| - // policy on startup but registered during the session.
|
| - //
|
| - // When that happens, OnPolicyFetched() is sent to observers before the
|
| - // CloudPolicyStore gets a chance to verify the user policy. In those cases,
|
| - // the backend gets the PolicyFetchResponses before it has the credentials
|
| - // and therefore the validation of those responses fails.
|
| - // Reload any PolicyFetchResponses that the client may have now so that
|
| - // validation is retried with the credentials in place.
|
| - if (core_->client())
|
| - OnPolicyFetched(core_->client());
|
| - }
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnStoreError(CloudPolicyStore* store) {
|
| - DCHECK(CalledOnValidThread());
|
| - OnStoreLoaded(store);
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK_EQ(core_->client(), client);
|
| -
|
| - if (!is_registered_for_cloud_policy_) {
|
| - // Trying to load any policies now will fail validation. An OnStoreLoaded()
|
| - // notification should follow soon, after the main user policy has been
|
| - // validated and stored.
|
| - return;
|
| - }
|
| -
|
| - // Pass each PolicyFetchResponse whose policy type is registered to the
|
| - // Backend.
|
| - const CloudPolicyClient::ResponseMap& responses =
|
| - core_->client()->responses();
|
| - for (CloudPolicyClient::ResponseMap::const_iterator it = responses.begin();
|
| - it != responses.end(); ++it) {
|
| - PolicyNamespace ns;
|
| - if (ToPolicyNamespace(it->first, &ns) &&
|
| - current_schema_map_->GetSchema(ns)) {
|
| - scoped_ptr<em::PolicyFetchResponse> response(
|
| - new em::PolicyFetchResponse(*it->second));
|
| - backend_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&Backend::UpdateExternalPolicy,
|
| - base::Unretained(backend_.get()),
|
| - base::Passed(&response)));
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnRegistrationStateChanged(
|
| - CloudPolicyClient* client) {
|
| - DCHECK(CalledOnValidThread());
|
| - // Ignored; the registration state is tracked by looking at the
|
| - // CloudPolicyStore instead.
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnClientError(CloudPolicyClient* client) {
|
| - DCHECK(CalledOnValidThread());
|
| - // Ignored.
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::InitializeIfReady() {
|
| - DCHECK(CalledOnValidThread());
|
| - if (started_loading_initial_policy_ || !schema_registry_->IsReady() ||
|
| - !core_->store()->is_initialized()) {
|
| - return;
|
| - }
|
| - // The initial list of components is ready. Initialize the backend now, which
|
| - // will call back to OnBackendInitialized.
|
| - backend_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&Backend::Init,
|
| - base::Unretained(backend_.get()),
|
| - schema_registry_->schema_map()));
|
| - started_loading_initial_policy_ = true;
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnBackendInitialized(
|
| - scoped_ptr<PolicyBundle> initial_policy) {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK(!loaded_initial_policy_);
|
| -
|
| - loaded_initial_policy_ = true;
|
| -
|
| - // We're now ready to serve the initial policy; notify the policy observers.
|
| - OnPolicyUpdated(initial_policy.Pass());
|
| -
|
| - // Start observing the core and tracking the state of the client.
|
| - core_->AddObserver(this);
|
| -
|
| - if (core_->client()) {
|
| - OnCoreConnected(core_);
|
| - } else {
|
| - // Send the current schema to the backend, in case it has changed while the
|
| - // backend was initializing. OnCoreConnected() also does this if a client is
|
| - // already connected.
|
| - SetCurrentSchema();
|
| - }
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::SetCurrentSchema() {
|
| - DCHECK(CalledOnValidThread());
|
| -
|
| - scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList);
|
| - PolicyNamespaceList added;
|
| - const scoped_refptr<SchemaMap>& new_schema_map =
|
| - schema_registry_->schema_map();
|
| - new_schema_map->GetChanges(current_schema_map_, removed.get(), &added);
|
| -
|
| - current_schema_map_ = new_schema_map;
|
| -
|
| - if (core_->client()) {
|
| - for (size_t i = 0; i < removed->size(); ++i) {
|
| - PolicyNamespaceKey key;
|
| - if (ToPolicyNamespaceKey((*removed)[i], &key))
|
| - core_->client()->RemoveNamespaceToFetch(key);
|
| - }
|
| -
|
| - bool added_namespaces_to_client = false;
|
| - for (size_t i = 0; i < added.size(); ++i) {
|
| - PolicyNamespaceKey key;
|
| - if (ToPolicyNamespaceKey(added[i], &key)) {
|
| - core_->client()->AddNamespaceToFetch(key);
|
| - added_namespaces_to_client = true;
|
| - }
|
| - }
|
| -
|
| - if (added_namespaces_to_client)
|
| - core_->RefreshSoon();
|
| - }
|
| -
|
| - backend_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&Backend::OnSchemasUpdated,
|
| - base::Unretained(backend_.get()),
|
| - current_schema_map_,
|
| - base::Passed(&removed)));
|
| -}
|
| -
|
| -void ComponentCloudPolicyService::OnPolicyUpdated(
|
| - scoped_ptr<PolicyBundle> policy) {
|
| - DCHECK(CalledOnValidThread());
|
| - policy_.Swap(policy.get());
|
| - delegate_->OnComponentCloudPolicyUpdated();
|
| -}
|
| -
|
| -} // namespace policy
|
|
|