1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_
6#define CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_
7#pragma once
8
9#include "base/gtest_prod_util.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/observer_list.h"
12#include "base/threading/non_thread_safe.h"
13#include "base/time.h"
14#include "chrome/browser/policy/cloud_policy_subsystem.h"
15#include "chrome/browser/policy/configuration_policy_provider.h"
16#include "chrome/browser/policy/policy_map.h"
17#include "chrome/browser/policy/proto/device_management_backend.pb.h"
18
19namespace policy {
20
21class PolicyMap;
22class PolicyNotifier;
23
24namespace em = enterprise_management;
25
26// Caches policy information, as set by calls to |SetPolicy()|, persists
27// it to disk or session_manager (depending on subclass implementation),
28// and makes it available via policy providers.
29class CloudPolicyCacheBase : public base::NonThreadSafe {
30 public:
31  // Used to distinguish mandatory from recommended policies.
32  enum PolicyLevel {
33    // Policy is forced upon the user and should always take effect.
34    POLICY_LEVEL_MANDATORY,
35    // The value is just a recommendation that the user may override.
36    POLICY_LEVEL_RECOMMENDED,
37  };
38
39  CloudPolicyCacheBase();
40  virtual ~CloudPolicyCacheBase();
41
42  void set_policy_notifier(PolicyNotifier* notifier) {
43    notifier_ = notifier;
44  }
45
46  // Loads persisted policy information.
47  virtual void Load() = 0;
48
49  // Resets the policy information.
50  virtual void SetPolicy(const em::PolicyFetchResponse& policy) = 0;
51
52  ConfigurationPolicyProvider* GetManagedPolicyProvider();
53  ConfigurationPolicyProvider* GetRecommendedPolicyProvider();
54
55  virtual void SetUnmanaged() = 0;
56  bool is_unmanaged() const {
57    return is_unmanaged_;
58  }
59
60  // Returns the time at which the policy was last fetched.
61  base::Time last_policy_refresh_time() const {
62    return last_policy_refresh_time_;
63  }
64
65  // Get the version of the encryption key currently used for decoding policy.
66  // Returns true if the version is available, in which case |version| is filled
67  // in.
68  bool GetPublicKeyVersion(int* version);
69
70 protected:
71  // Wraps public key version and validity.
72  struct PublicKeyVersion {
73    int version;
74    bool valid;
75  };
76
77  // Decodes the given |policy| using |DecodePolicyResponse()|, applies the
78  // contents to |{mandatory,recommended}_policy_|, and notifies observers.
79  // |timestamp| returns the timestamp embedded in |policy|, callers can pass
80  // NULL if they don't care. |check_for_timestamp_validity| tells this method
81  // to discard policy data with a timestamp from the future.
82  // Returns true upon success.
83  bool SetPolicyInternal(const em::PolicyFetchResponse& policy,
84                         base::Time* timestamp,
85                         bool check_for_timestamp_validity);
86
87  void SetUnmanagedInternal(const base::Time& timestamp);
88
89  // Decodes |policy_data|, populating |mandatory| and |recommended| with
90  // the results.
91  virtual bool DecodePolicyData(const em::PolicyData& policy_data,
92                                PolicyMap* mandatory,
93                                PolicyMap* recommended) = 0;
94
95  // Decodes a PolicyFetchResponse into two PolicyMaps and a timestamp.
96  // Also performs verification, returns NULL if any check fails.
97  bool DecodePolicyResponse(const em::PolicyFetchResponse& policy_response,
98                            PolicyMap* mandatory,
99                            PolicyMap* recommended,
100                            base::Time* timestamp,
101                            PublicKeyVersion* public_key_version);
102
103  void InformNotifier(CloudPolicySubsystem::PolicySubsystemState state,
104                      CloudPolicySubsystem::ErrorDetails error_details);
105
106  // See comment for |initialization_complete_|.
107  bool initialization_complete() {
108    return initialization_complete_;
109  }
110
111  void set_last_policy_refresh_time(base::Time timestamp) {
112    last_policy_refresh_time_ = timestamp;
113  }
114
115 private:
116  class CloudPolicyProvider;
117
118  friend class DevicePolicyCacheTest;
119  friend class UserPolicyCacheTest;
120
121  // Policy key-value information.
122  PolicyMap mandatory_policy_;
123  PolicyMap recommended_policy_;
124
125  // Policy providers.
126  scoped_ptr<ConfigurationPolicyProvider> managed_policy_provider_;
127  scoped_ptr<ConfigurationPolicyProvider> recommended_policy_provider_;
128
129  PolicyNotifier* notifier_;
130
131  // The time at which the policy was last refreshed. Is updated both upon
132  // successful and unsuccessful refresh attempts.
133  base::Time last_policy_refresh_time_;
134
135  // Whether initialization has been completed. This is the case when we have
136  // valid policy, learned that the device is unmanaged or ran into
137  // unrecoverable errors.
138  bool initialization_complete_;
139
140  // Whether the the server has indicated this device is unmanaged.
141  bool is_unmanaged_;
142
143  // Currently used public key version, if available.
144  PublicKeyVersion public_key_version_;
145
146  // Provider observers that are registered with this cache's providers.
147  ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_;
148
149  DISALLOW_COPY_AND_ASSIGN(CloudPolicyCacheBase);
150};
151
152}  // namespace policy
153
154#endif  // CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_
155