blob: ce7965b5ab4c65505484fe5e44ca3978eb916d28 [file] [log] [blame]
// Copyright (c) 2011 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_H_
#define CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_
#include <string>
#include "base/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/observer_list.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
#include "chrome/browser/policy/policy_map.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "policy/configuration_policy_type.h"
class DictionaryValue;
class ListValue;
class Value;
using google::protobuf::RepeatedPtrField;
namespace policy {
namespace em = enterprise_management;
// Keeps the authoritative copy of cloud policy information as read from the
// persistence file or determined by the policy backend. The cache doesn't talk
// to the service directly, but receives updated policy information through
// SetPolicy() calls, which is then persisted and decoded into the internal
// Value representation chrome uses.
class CloudPolicyCache : public base::NonThreadSafe {
public:
// Used to distinguish mandatory from recommended policies.
enum PolicyLevel {
// Policy is forced upon the user and should always take effect.
POLICY_LEVEL_MANDATORY,
// The value is just a recommendation that the user may override.
POLICY_LEVEL_RECOMMENDED,
};
explicit CloudPolicyCache(const FilePath& backing_file_path);
~CloudPolicyCache();
// Loads policy information from the backing file. Non-existing or erroneous
// cache files are ignored.
void LoadFromFile();
// Resets the policy information.
void SetPolicy(const em::PolicyFetchResponse& policy);
void SetDevicePolicy(const em::DevicePolicyResponse& policy);
ConfigurationPolicyProvider* GetManagedPolicyProvider();
ConfigurationPolicyProvider* GetRecommendedPolicyProvider();
void SetUnmanaged();
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_;
}
// Returns true if this cache holds (old-style) device policy that should be
// given preference over (new-style) mandatory/recommended policy.
bool has_device_policy() const {
return has_device_policy_;
}
private:
class CloudPolicyProvider;
friend class CloudPolicyCacheTest;
friend class DeviceManagementPolicyCacheTest;
friend class DeviceManagementPolicyCacheDecodeTest;
// Decodes a CloudPolicyResponse into two (ConfigurationPolicyType -> Value*)
// maps and a timestamp. Also performs verification, returns NULL if any
// check fails.
static bool DecodePolicyResponse(
const em::PolicyFetchResponse& policy_response,
PolicyMap* mandatory,
PolicyMap* recommended,
base::Time* timestamp);
// Returns true if |certificate_chain| is trusted and a |signature| created
// from it matches |data|.
static bool VerifySignature(
const std::string& signature,
const std::string& data,
const RepeatedPtrField<std::string>& certificate_chain);
// Decodes an int64 value. Checks whether the passed value fits the numeric
// limits of the value representation. Returns a value (ownership is
// transferred to the caller) on success, NULL on failure.
static Value* DecodeIntegerValue(google::protobuf::int64 value);
// Decode a GenericValue message to the Value representation used internally.
// Returns NULL if |value| is invalid (i.e. contains no actual value).
static Value* DecodeValue(const em::GenericValue& value);
// Decodes a policy message and returns it in Value representation. Ownership
// of the returned dictionary is transferred to the caller.
static DictionaryValue* DecodeDevicePolicy(
const em::DevicePolicyResponse& response);
// The file in which we store a cached version of the policy information.
const FilePath backing_file_path_;
// Policy key-value information.
PolicyMap mandatory_policy_;
PolicyMap recommended_policy_;
scoped_ptr<DictionaryValue> device_policy_;
// 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_;
// Tracks whether the cache currently stores |device_policy_| that should be
// given preference over |mandatory_policy_| and |recommended_policy_|.
bool has_device_policy_;
// The time at which the policy was last refreshed.
base::Time last_policy_refresh_time_;
// Policy providers.
scoped_ptr<ConfigurationPolicyProvider> managed_policy_provider_;
scoped_ptr<ConfigurationPolicyProvider> recommended_policy_provider_;
// Provider observers that are registered with this cache's providers.
ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_;
DISALLOW_COPY_AND_ASSIGN(CloudPolicyCache);
};
} // namespace policy
#endif // CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_