1// Copyright (c) 2013 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 COMPONENTS_POLICY_CORE_COMMON_CLOUD_COMPONENT_CLOUD_POLICY_STORE_H_
6#define COMPONENTS_POLICY_CORE_COMMON_CLOUD_COMPONENT_CLOUD_POLICY_STORE_H_
7
8#include <map>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/threading/non_thread_safe.h"
14#include "components/policy/core/common/cloud/resource_cache.h"
15#include "components/policy/core/common/policy_bundle.h"
16#include "components/policy/core/common/policy_namespace.h"
17#include "components/policy/policy_export.h"
18
19namespace enterprise_management {
20class ExternalPolicyData;
21class PolicyData;
22class PolicyFetchResponse;
23}
24
25namespace policy {
26
27// Validates protobufs for external policy data, validates the data itself, and
28// caches both locally.
29class POLICY_EXPORT ComponentCloudPolicyStore : public base::NonThreadSafe {
30 public:
31  class POLICY_EXPORT Delegate {
32   public:
33    virtual ~Delegate();
34
35    // Invoked whenever the policies served by policy() have changed, except
36    // for the initial Load().
37    virtual void OnComponentCloudPolicyStoreUpdated() = 0;
38  };
39
40  // Both the |delegate| and the |cache| must outlive this object.
41  ComponentCloudPolicyStore(Delegate* delegate,
42                            ResourceCache* cache);
43  ~ComponentCloudPolicyStore();
44
45  // Helper that returns true for PolicyDomains that can be managed by this
46  // store.
47  static bool SupportsDomain(PolicyDomain domain);
48
49  // Returns true if |domain| can be managed by this store; in that case, the
50  // dm_protocol policy type that corresponds to |domain| is stored in
51  // |policy_type|. Otherwise returns false.
52  static bool GetPolicyType(PolicyDomain domain, std::string* policy_type);
53
54  // Returns true if |policy_type| corresponds to a policy domain that can be
55  // managed by this store; in that case, the domain constants is assigned to
56  // |domain|. Otherwise returns false.
57  static bool GetPolicyDomain(const std::string& policy_type,
58                              PolicyDomain* domain);
59
60  // The current list of policies.
61  const PolicyBundle& policy() const { return policy_bundle_; }
62
63  // The cached hash for namespace |ns|, or the empty string if |ns| is not
64  // cached.
65  const std::string& GetCachedHash(const PolicyNamespace& ns) const;
66
67  // |username| and |dm_token| are used to validate the cached data, and data
68  // stored later.
69  // All ValidatePolicy() requests without credentials fail.
70  void SetCredentials(const std::string& username,
71                      const std::string& dm_token);
72
73  // Loads and validates all the currently cached protobufs and policy data.
74  // This is performed synchronously, and policy() will return the cached
75  // policies after this call.
76  void Load();
77
78  // Stores the protobuf and |data| for namespace |ns|. The protobuf is passed
79  // serialized in |serialized_policy_proto|, and must have been validated
80  // before.
81  // The |data| is validated during this call, and its secure hash must match
82  // |secure_hash|.
83  // Returns false if |data| failed validation, otherwise returns true and the
84  // data was stored in the cache.
85  bool Store(const PolicyNamespace& ns,
86             const std::string& serialized_policy_proto,
87             const std::string& secure_hash,
88             const std::string& data);
89
90  // Deletes the storage of namespace |ns| and stops serving its policies.
91  void Delete(const PolicyNamespace& ns);
92
93  // Deletes the storage of all components of |domain| that pass then given
94  // |filter|, and stops serving their policies.
95  void Purge(PolicyDomain domain,
96             const ResourceCache::SubkeyFilter& filter);
97
98  // Deletes the storage of every component.
99  void Clear();
100
101  // Validates |proto| and returns the corresponding policy namespace in |ns|,
102  // and the parsed ExternalPolicyData in |payload|.
103  // If |proto| validates successfully then its |payload| can be trusted, and
104  // the data referenced there can be downloaded. A |proto| must be validated
105  // before attempting to download the data, and before storing both.
106  bool ValidatePolicy(
107      scoped_ptr<enterprise_management::PolicyFetchResponse> proto,
108      PolicyNamespace* ns,
109      enterprise_management::ExternalPolicyData* payload);
110
111 private:
112  // Helper for ValidatePolicy(), that's also used to validate protobufs
113  // loaded from the disk cache.
114  bool ValidateProto(
115      scoped_ptr<enterprise_management::PolicyFetchResponse> proto,
116      const std::string& policy_type,
117      const std::string& settings_entity_id,
118      enterprise_management::ExternalPolicyData* payload,
119      enterprise_management::PolicyData* policy_data);
120
121  // Validates the JSON policy serialized in |data|, and verifies its hash
122  // with |secure_hash|. Returns true on success, and in that case stores the
123  // parsed policies in |policy|.
124  bool ValidateData(const std::string& data,
125                    const std::string& secure_hash,
126                    PolicyMap* policy);
127
128  // Parses the JSON policy in |data| into |policy|, and returns true if the
129  // parse was successful.
130  bool ParsePolicy(const std::string& data, PolicyMap* policy);
131
132  Delegate* delegate_;
133  ResourceCache* cache_;
134  std::string username_;
135  std::string dm_token_;
136
137  PolicyBundle policy_bundle_;
138  std::map<PolicyNamespace, std::string> cached_hashes_;
139
140  DISALLOW_COPY_AND_ASSIGN(ComponentCloudPolicyStore);
141};
142
143}  // namespace policy
144
145#endif  // COMPONENTS_POLICY_CORE_COMMON_CLOUD_COMPONENT_CLOUD_POLICY_STORE_H_
146