ComponentCloudPolicyService tracks the signin state.

The ComponentCloudPolicyService is used to fetch policy for Chrome components
such as extensions. This change makes it follow the sign-in state by observing
the cloud policy store and a cloud policy core, which determine that state
from the cloud policy system perspective.

The component policy cache will be cleared on signout.

The ComponentCloudPolicyService now tracks a CloudPolicyCore to determine
whether a CloudPolicyClient is available or not; it is possible to signin
and signout multiple times.

BUG=108992

Review URL: https://codereview.chromium.org/72793003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235747 0039d316-1c4b-4281-b951-d872f2087c98
parent 3270e32c
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
#include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h"
#include "chrome/browser/policy/cloud/resource_cache.h" #include "chrome/browser/policy/cloud/resource_cache.h"
#include "chrome/browser/policy/policy_bundle.h" #include "chrome/browser/policy/policy_bundle.h"
#include "chrome/common/chrome_switches.h"
#include "components/policy/core/common/policy_pref_names.h" #include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/core/common/policy_switches.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
...@@ -232,10 +232,6 @@ void UserCloudPolicyManagerChromeOS::OnClientError( ...@@ -232,10 +232,6 @@ void UserCloudPolicyManagerChromeOS::OnClientError(
CancelWaitForPolicyFetch(); CancelWaitForPolicyFetch();
} }
void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyRefreshNeeded() {
core()->RefreshSoon();
}
void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() { void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() {
CheckAndPublishPolicy(); CheckAndPublishPolicy();
StartRefreshSchedulerIfReady(); StartRefreshSchedulerIfReady();
...@@ -264,9 +260,8 @@ void UserCloudPolicyManagerChromeOS::CreateComponentCloudPolicyService( ...@@ -264,9 +260,8 @@ void UserCloudPolicyManagerChromeOS::CreateComponentCloudPolicyService(
component_policy_service_.reset(new ComponentCloudPolicyService( component_policy_service_.reset(new ComponentCloudPolicyService(
this, this,
schema_registry(), schema_registry(),
store_.get(), core(),
resource_cache.Pass(), resource_cache.Pass(),
client(),
request_context, request_context,
backend_task_runner, backend_task_runner,
content::BrowserThread::GetMessageLoopProxyForThread( content::BrowserThread::GetMessageLoopProxyForThread(
......
...@@ -96,7 +96,6 @@ class UserCloudPolicyManagerChromeOS ...@@ -96,7 +96,6 @@ class UserCloudPolicyManagerChromeOS
virtual void OnClientError(CloudPolicyClient* client) OVERRIDE; virtual void OnClientError(CloudPolicyClient* client) OVERRIDE;
// ComponentCloudPolicyService::Delegate: // ComponentCloudPolicyService::Delegate:
virtual void OnComponentCloudPolicyRefreshNeeded() OVERRIDE;
virtual void OnComponentCloudPolicyUpdated() OVERRIDE; virtual void OnComponentCloudPolicyUpdated() OVERRIDE;
private: private:
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "components/policy/core/common/policy_switches.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
#include "policy/proto/cloud_policy.pb.h" #include "policy/proto/cloud_policy.pb.h"
...@@ -95,7 +96,7 @@ class ComponentCloudPolicyTest : public ExtensionBrowserTest { ...@@ -95,7 +96,7 @@ class ComponentCloudPolicyTest : public ExtensionBrowserTest {
// replace it. This is the default username sent in policy blobs from the // replace it. This is the default username sent in policy blobs from the
// testserver. // testserver.
command_line->AppendSwitchASCII( command_line->AppendSwitchASCII(
chromeos::switches::kLoginUser, "user@example.com"); ::chromeos::switches::kLoginUser, "user@example.com");
#endif #endif
} }
...@@ -107,7 +108,7 @@ class ComponentCloudPolicyTest : public ExtensionBrowserTest { ...@@ -107,7 +108,7 @@ class ComponentCloudPolicyTest : public ExtensionBrowserTest {
std::string url = test_server_.GetServiceURL().spec(); std::string url = test_server_.GetServiceURL().spec();
CommandLine* command_line = CommandLine::ForCurrentProcess(); CommandLine* command_line = CommandLine::ForCurrentProcess();
command_line->AppendSwitchASCII(switches::kDeviceManagementUrl, url); command_line->AppendSwitchASCII(::switches::kDeviceManagementUrl, url);
command_line->AppendSwitch(switches::kEnableComponentCloudPolicy); command_line->AppendSwitch(switches::kEnableComponentCloudPolicy);
ExtensionBrowserTest::SetUpInProcessBrowserTestFixture(); ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h" #include "base/threading/non_thread_safe.h"
#include "base/timer/timer.h"
#include "chrome/browser/policy/cloud/cloud_policy_client.h" #include "chrome/browser/policy/cloud/cloud_policy_client.h"
#include "chrome/browser/policy/cloud/cloud_policy_core.h"
#include "chrome/browser/policy/cloud/cloud_policy_store.h" #include "chrome/browser/policy/cloud/cloud_policy_store.h"
#include "chrome/browser/policy/policy_bundle.h" #include "chrome/browser/policy/policy_bundle.h"
#include "chrome/browser/policy/schema_registry.h" #include "chrome/browser/policy/schema_registry.h"
...@@ -37,6 +37,7 @@ class SchemaMap; ...@@ -37,6 +37,7 @@ class SchemaMap;
// This class takes care of fetching, validating, storing and updating policy // This class takes care of fetching, validating, storing and updating policy
// for components. The components to manage come from a SchemaRegistry. // for components. The components to manage come from a SchemaRegistry.
class ComponentCloudPolicyService : public CloudPolicyClient::Observer, class ComponentCloudPolicyService : public CloudPolicyClient::Observer,
public CloudPolicyCore::Observer,
public CloudPolicyStore::Observer, public CloudPolicyStore::Observer,
public SchemaRegistry::Observer, public SchemaRegistry::Observer,
public base::NonThreadSafe { public base::NonThreadSafe {
...@@ -45,34 +46,35 @@ class ComponentCloudPolicyService : public CloudPolicyClient::Observer, ...@@ -45,34 +46,35 @@ class ComponentCloudPolicyService : public CloudPolicyClient::Observer,
public: public:
virtual ~Delegate(); virtual ~Delegate();
// Invoked whenever the service has appended new namespaces to fetch to
// the CloudPolicyClient, signaling that a policy fetch should be done soon.
virtual void OnComponentCloudPolicyRefreshNeeded() = 0;
// Invoked whenever the policy served by policy() changes. This is also // Invoked whenever the policy served by policy() changes. This is also
// invoked for the first time once the backend is initialized, and // invoked for the first time once the backend is initialized, and
// is_initialized() becomes true. // is_initialized() becomes true.
virtual void OnComponentCloudPolicyUpdated() = 0; virtual void OnComponentCloudPolicyUpdated() = 0;
}; };
// All of these components must outlive this instance. // The |delegate| is notified of updates to the downloaded policies and must
// outlive this object.
//
// |schema_registry| is used to get the list of components to fetch cloud
// policy for. It must outlive this object.
//
// |core| is used to obtain the CloudPolicyStore and CloudPolicyClient used
// by this service. The store will be the source of the registration status
// and registration credentials; the client will be used to fetch cloud
// policy. It must outlive this object.
// //
// The |delegate| is notified of updates to the downloaded policies, and is
// notified whenever a refresh is needed.
// |schema_registry| contains the list of components to fetch policy for.
// |store| is used to get the current DMToken and the username.
// |cache| is used to load and store local copies of the downloaded policies. // |cache| is used to load and store local copies of the downloaded policies.
//
// Download scheduling, validation and caching of policies are done via the // Download scheduling, validation and caching of policies are done via the
// |backend_task_runner|, which must support file I/O. Network I/O is done via // |backend_task_runner|, which must support file I/O. Network I/O is done via
// the |io_task_runner|. // the |io_task_runner|.
// |client| is updated with the list of components to fetch. //
// |request_context| is used by the background URLFetchers. // |request_context| is used by the background URLFetchers.
ComponentCloudPolicyService( ComponentCloudPolicyService(
Delegate* delegate, Delegate* delegate,
SchemaRegistry* schema_registry, SchemaRegistry* schema_registry,
CloudPolicyStore* store, CloudPolicyCore* core,
scoped_ptr<ResourceCache> cache, scoped_ptr<ResourceCache> cache,
CloudPolicyClient* client,
scoped_refptr<net::URLRequestContextGetter> request_context, scoped_refptr<net::URLRequestContextGetter> request_context,
scoped_refptr<base::SequencedTaskRunner> backend_task_runner, scoped_refptr<base::SequencedTaskRunner> backend_task_runner,
scoped_refptr<base::SequencedTaskRunner> io_task_runner); scoped_refptr<base::SequencedTaskRunner> io_task_runner);
...@@ -83,37 +85,40 @@ class ComponentCloudPolicyService : public CloudPolicyClient::Observer, ...@@ -83,37 +85,40 @@ class ComponentCloudPolicyService : public CloudPolicyClient::Observer,
// Returns true if the backend is initialized, and the initial policies and // Returns true if the backend is initialized, and the initial policies and
// components are being served. // components are being served.
bool is_initialized() const { return is_initialized_; } bool is_initialized() const { return loaded_initial_policy_; }
// Returns the current policies for components. // Returns the current policies for components.
const PolicyBundle& policy() const { return policy_; } const PolicyBundle& policy() const { return policy_; }
// CloudPolicyClient::Observer implementation: // SchemaRegistry::Observer implementation:
virtual void OnPolicyFetched(CloudPolicyClient* client) OVERRIDE; virtual void OnSchemaRegistryReady() OVERRIDE;
virtual void OnRegistrationStateChanged(CloudPolicyClient* client) OVERRIDE; virtual void OnSchemaRegistryUpdated(bool has_new_schemas) OVERRIDE;
virtual void OnClientError(CloudPolicyClient* client) OVERRIDE;
// CloudPolicyCore::Observer implementation:
virtual void OnCoreConnected(CloudPolicyCore* core) OVERRIDE;
virtual void OnCoreDisconnecting(CloudPolicyCore* core) OVERRIDE;
virtual void OnRefreshSchedulerStarted(CloudPolicyCore* core) OVERRIDE;
// CloudPolicyStore::Observer implementation: // CloudPolicyStore::Observer implementation:
virtual void OnStoreLoaded(CloudPolicyStore* store) OVERRIDE; virtual void OnStoreLoaded(CloudPolicyStore* store) OVERRIDE;
virtual void OnStoreError(CloudPolicyStore* store) OVERRIDE; virtual void OnStoreError(CloudPolicyStore* store) OVERRIDE;
// SchemaRegistry::Observer implementation: // CloudPolicyClient::Observer implementation:
virtual void OnSchemaRegistryReady() OVERRIDE; virtual void OnPolicyFetched(CloudPolicyClient* client) OVERRIDE;
virtual void OnSchemaRegistryUpdated(bool has_new_schemas) OVERRIDE; virtual void OnRegistrationStateChanged(CloudPolicyClient* client) OVERRIDE;
virtual void OnClientError(CloudPolicyClient* client) OVERRIDE;
private: private:
class Backend; class Backend;
void InitializeIfReady(); void InitializeIfReady();
void OnBackendInitialized(scoped_ptr<PolicyBundle> initial_policy); void OnBackendInitialized(scoped_ptr<PolicyBundle> initial_policy);
void SetCurrentSchema(const scoped_refptr<SchemaMap>& new_schema_map, void SetCurrentSchema();
bool send_to_backend);
void OnPolicyUpdated(scoped_ptr<PolicyBundle> policy); void OnPolicyUpdated(scoped_ptr<PolicyBundle> policy);
Delegate* delegate_; Delegate* delegate_;
SchemaRegistry* schema_registry_; SchemaRegistry* schema_registry_;
CloudPolicyStore* store_; CloudPolicyCore* core_;
CloudPolicyClient* client_;
scoped_refptr<net::URLRequestContextGetter> request_context_; scoped_refptr<net::URLRequestContextGetter> request_context_;
scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
scoped_refptr<base::SequencedTaskRunner> io_task_runner_; scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
...@@ -140,12 +145,16 @@ class ComponentCloudPolicyService : public CloudPolicyClient::Observer, ...@@ -140,12 +145,16 @@ class ComponentCloudPolicyService : public CloudPolicyClient::Observer,
// Contains all the current policies for components. // Contains all the current policies for components.
PolicyBundle policy_; PolicyBundle policy_;
// Used to delay changes triggered by updates to the SchemaRegistry. See // Whether the backend has been initialized with the initial credentials and
// the implementation of OnSchemaRegistryUpdated() for details. // schemas, and this provider is serving the initial policies loaded from the
base::OneShotTimer<ComponentCloudPolicyService> schema_update_timer_; // cache.
bool loaded_initial_policy_;
// True if the backend currently has valid cloud policy credentials. This
// can go back to false if the user signs out, and back again to true if the
// user signs in again.
bool is_registered_for_cloud_policy_;
bool is_initialized_;
bool has_credentials_;
base::WeakPtrFactory<ComponentCloudPolicyService> weak_ptr_factory_; base::WeakPtrFactory<ComponentCloudPolicyService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ComponentCloudPolicyService); DISALLOW_COPY_AND_ASSIGN(ComponentCloudPolicyService);
......
...@@ -231,6 +231,19 @@ void ComponentCloudPolicyStore::Purge( ...@@ -231,6 +231,19 @@ void ComponentCloudPolicyStore::Purge(
delegate_->OnComponentCloudPolicyStoreUpdated(); delegate_->OnComponentCloudPolicyStoreUpdated();
} }
void ComponentCloudPolicyStore::Clear() {
for (size_t i = 0; i < arraysize(kDomains); ++i) {
cache_->Clear(kDomains[i].proto_cache_key);
cache_->Clear(kDomains[i].data_cache_key);
}
cached_hashes_.clear();
const PolicyBundle empty_bundle;
if (!policy_bundle_.Equals(empty_bundle)) {
policy_bundle_.Clear();
delegate_->OnComponentCloudPolicyStoreUpdated();
}
}
bool ComponentCloudPolicyStore::ValidatePolicy( bool ComponentCloudPolicyStore::ValidatePolicy(
scoped_ptr<em::PolicyFetchResponse> proto, scoped_ptr<em::PolicyFetchResponse> proto,
PolicyNamespace* ns, PolicyNamespace* ns,
......
...@@ -94,6 +94,9 @@ class ComponentCloudPolicyStore : public base::NonThreadSafe { ...@@ -94,6 +94,9 @@ class ComponentCloudPolicyStore : public base::NonThreadSafe {
void Purge(PolicyDomain domain, void Purge(PolicyDomain domain,
const ResourceCache::SubkeyFilter& filter); const ResourceCache::SubkeyFilter& filter);
// Deletes the storage of every component.
void Clear();
// Validates |proto| and returns the corresponding policy namespace in |ns|, // Validates |proto| and returns the corresponding policy namespace in |ns|,
// and the parsed ExternalPolicyData in |payload|. // and the parsed ExternalPolicyData in |payload|.
// If |proto| validates successfully then its |payload| can be trusted, and // If |proto| validates successfully then its |payload| can be trusted, and
......
...@@ -137,6 +137,13 @@ void ResourceCache::Delete(const std::string& key, const std::string& subkey) { ...@@ -137,6 +137,13 @@ void ResourceCache::Delete(const std::string& key, const std::string& subkey) {
base::DeleteFile(subkey_path.DirName(), false); base::DeleteFile(subkey_path.DirName(), false);
} }
void ResourceCache::Clear(const std::string& key) {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
base::FilePath key_path;
if (VerifyKeyPath(key, false, &key_path))
base::DeleteFile(key_path, true);
}
void ResourceCache::FilterSubkeys(const std::string& key, void ResourceCache::FilterSubkeys(const std::string& key,
const SubkeyFilter& test) { const SubkeyFilter& test) {
DCHECK(task_runner_->RunsTasksOnCurrentThread()); DCHECK(task_runner_->RunsTasksOnCurrentThread());
......
...@@ -52,6 +52,9 @@ class ResourceCache { ...@@ -52,6 +52,9 @@ class ResourceCache {
// Deletes (key, subkey). // Deletes (key, subkey).
void Delete(const std::string& key, const std::string& subkey); void Delete(const std::string& key, const std::string& subkey);
// Deletes all the subkeys of |key|.
void Clear(const std::string& key);
// Deletes the subkeys of |key| for which the |filter| returns true. // Deletes the subkeys of |key| for which the |filter| returns true.
typedef base::Callback<bool(const std::string&)> SubkeyFilter; typedef base::Callback<bool(const std::string&)> SubkeyFilter;
void FilterSubkeys(const std::string& key, const SubkeyFilter& filter); void FilterSubkeys(const std::string& key, const SubkeyFilter& filter);
......
...@@ -589,10 +589,6 @@ const char kEnableClientHints[] = "enable-client-hints"; ...@@ -589,10 +589,6 @@ const char kEnableClientHints[] = "enable-client-hints";
// Print Proxy component within the service process. // Print Proxy component within the service process.
const char kEnableCloudPrintProxy[] = "enable-cloud-print-proxy"; const char kEnableCloudPrintProxy[] = "enable-cloud-print-proxy";
// Enables fetching and storing cloud policy for components. This currently
// supports policy for extensions on Chrome OS.
const char kEnableComponentCloudPolicy[] = "enable-component-cloud-policy";
// Enables fetching the user's contacts from Google and showing them in the // Enables fetching the user's contacts from Google and showing them in the
// Chrome OS apps list. // Chrome OS apps list.
const char kEnableContacts[] = "enable-contacts"; const char kEnableContacts[] = "enable-contacts";
......
...@@ -171,7 +171,6 @@ extern const char kEnableAutologin[]; ...@@ -171,7 +171,6 @@ extern const char kEnableAutologin[];
extern const char kEnableBenchmarking[]; extern const char kEnableBenchmarking[];
extern const char kEnableClientHints[]; extern const char kEnableClientHints[];
extern const char kEnableCloudPrintProxy[]; extern const char kEnableCloudPrintProxy[];
extern const char kEnableComponentCloudPolicy[];
extern const char kEnableContacts[]; extern const char kEnableContacts[];
extern const char kEnableDevToolsExperiments[]; extern const char kEnableDevToolsExperiments[];
extern const char kEnableDeviceDiscoveryNotifications[]; extern const char kEnableDeviceDiscoveryNotifications[];
......
...@@ -16,6 +16,10 @@ const char kCloudPolicyInvalidationDelay[] = "cloud-policy-invalidation-delay"; ...@@ -16,6 +16,10 @@ const char kCloudPolicyInvalidationDelay[] = "cloud-policy-invalidation-delay";
// Disables pushing cloud policy to Chrome using an invalidation service. // Disables pushing cloud policy to Chrome using an invalidation service.
const char kDisableCloudPolicyPush[] = "disable-cloud-policy-push"; const char kDisableCloudPolicyPush[] = "disable-cloud-policy-push";
// Enables fetching and storing cloud policy for components. This currently
// supports policy for extensions on Chrome OS.
const char kEnableComponentCloudPolicy[] = "enable-component-cloud-policy";
#if defined(OS_ANDROID) || defined(OS_IOS) #if defined(OS_ANDROID) || defined(OS_IOS)
// Registers for cloud policy using the BROWSER client type instead of the // Registers for cloud policy using the BROWSER client type instead of the
// ANDROID_BROWSER or IOS_BROWSER types. // ANDROID_BROWSER or IOS_BROWSER types.
......
...@@ -14,6 +14,7 @@ namespace switches { ...@@ -14,6 +14,7 @@ namespace switches {
POLICY_EXPORT extern const char kCloudPolicyInvalidationDelay[]; POLICY_EXPORT extern const char kCloudPolicyInvalidationDelay[];
POLICY_EXPORT extern const char kDisableCloudPolicyPush[]; POLICY_EXPORT extern const char kDisableCloudPolicyPush[];
POLICY_EXPORT extern const char kEnableComponentCloudPolicy[];
#if defined(OS_ANDROID) || defined(OS_IOS) #if defined(OS_ANDROID) || defined(OS_IOS)
POLICY_EXPORT extern const char kFakeCloudPolicyType[]; POLICY_EXPORT extern const char kFakeCloudPolicyType[];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment