// Copyright (c) 2012 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. #ifndef CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_ #define CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_ #pragma once #include "base/observer_list.h" #include "base/threading/non_thread_safe.h" #include "base/time.h" #include "chrome/browser/policy/cloud_policy_subsystem.h" #include "chrome/browser/policy/policy_map.h" #include "chrome/browser/policy/proto/device_management_backend.pb.h" namespace policy { class PolicyNotifier; // Caches policy information, as set by calls to |SetPolicy()|, persists // it to disk or session_manager (depending on subclass implementation), // and makes it available via policy providers. class CloudPolicyCacheBase : public base::NonThreadSafe { public: class Observer { public: virtual ~Observer() {} virtual void OnCacheGoingAway(CloudPolicyCacheBase*) = 0; virtual void OnCacheUpdate(CloudPolicyCacheBase*) = 0; }; CloudPolicyCacheBase(); virtual ~CloudPolicyCacheBase(); void set_policy_notifier(PolicyNotifier* notifier) { notifier_ = notifier; } // Loads persisted policy information. virtual void Load() = 0; // Resets the policy information. Returns true if |policy| was accepted and // stored. virtual bool SetPolicy( const enterprise_management::PolicyFetchResponse& policy) = 0; virtual void SetUnmanaged() = 0; // Invoked whenever an attempt to fetch policy has been completed. The fetch // may or may not have suceeded. This can be triggered by failed attempts to // fetch oauth tokens, register with dmserver or fetch policy. virtual void SetFetchingDone(); bool is_unmanaged() const { return is_unmanaged_; } // Returns the time at which the policy was last fetched. base::Time last_policy_refresh_time() const { return last_policy_refresh_time_; } bool machine_id_missing() const { return machine_id_missing_; } // Get the version of the encryption key currently used for decoding policy. // Returns true if the version is available, in which case |version| is filled // in. bool GetPublicKeyVersion(int* version); void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); // Accessor for the underlying PolicyMap. const PolicyMap* policy() { return &policies_; } // Resets the cache, clearing the policy currently stored in memory and the // last refresh time. void Reset(); // true if the cache contains data that is ready to be served as policies. // This usually means that the local policy storage has been loaded. // Note that Profile creation will block until the cache is ready. // On enrolled devices and for users of the enrolled domain, the cache only // becomes ready after a user policy fetch is completed. bool IsReady(); protected: // Wraps public key version and validity. struct PublicKeyVersion { int version; bool valid; }; // Decodes the given |policy| using |DecodePolicyResponse()|, applies the // contents to |policies_|, and notifies observers. // |timestamp| returns the timestamp embedded in |policy|, callers can pass // NULL if they don't care. |check_for_timestamp_validity| tells this method // to discard policy data with a timestamp from the future. // Returns true upon success. bool SetPolicyInternal( const enterprise_management::PolicyFetchResponse& policy, base::Time* timestamp, bool check_for_timestamp_validity); void SetUnmanagedInternal(const base::Time& timestamp); // Indicates that initialization is now complete. Observers will be notified. void SetReady(); // Decodes |policy_data|, populating |mandatory| and |recommended| with // the results. virtual bool DecodePolicyData( const enterprise_management::PolicyData& policy_data, PolicyMap* policies) = 0; // Decodes a PolicyFetchResponse into two PolicyMaps and a timestamp. // Also performs verification, returns NULL if any check fails. bool DecodePolicyResponse( const enterprise_management::PolicyFetchResponse& policy_response, PolicyMap* policies, base::Time* timestamp, PublicKeyVersion* public_key_version); // Notifies observers if the cache IsReady(). void NotifyObservers(); void InformNotifier(CloudPolicySubsystem::PolicySubsystemState state, CloudPolicySubsystem::ErrorDetails error_details); void set_last_policy_refresh_time(base::Time timestamp) { last_policy_refresh_time_ = timestamp; } private: friend class DevicePolicyCacheTest; friend class UserPolicyCacheTest; friend class MockCloudPolicyCache; // Policy key-value information. PolicyMap policies_; PolicyNotifier* notifier_; // The time at which the policy was last refreshed. Is updated both upon // successful and unsuccessful refresh attempts. base::Time last_policy_refresh_time_; // Whether initialization has been completed. This is the case when we have // valid policy, learned that the device is unmanaged or ran into // unrecoverable errors. bool initialization_complete_; // Whether the the server has indicated this device is unmanaged. bool is_unmanaged_; // Flag indicating whether the server claims that a valid machine identifier // is missing on the server side. Read directly from the policy blob. bool machine_id_missing_; // Currently used public key version, if available. PublicKeyVersion public_key_version_; // Cache observers that are registered with this cache. ObserverList observer_list_; DISALLOW_COPY_AND_ASSIGN(CloudPolicyCacheBase); }; } // namespace policy #endif // CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_