1 // Copyright 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_POLICY_MAP_H_
6 #define COMPONENTS_POLICY_CORE_COMMON_POLICY_MAP_H_
7 
8 #include <stddef.h>
9 
10 #include <map>
11 #include <memory>
12 #include <set>
13 #include <string>
14 
15 #include "base/callback.h"
16 #include "base/macros.h"
17 #include "base/values.h"
18 #include "components/policy/core/common/external_data_fetcher.h"
19 #include "components/policy/core/common/policy_types.h"
20 #include "components/policy/policy_export.h"
21 
22 namespace policy {
23 
24 // A mapping of policy names to policy values for a given policy namespace.
25 class POLICY_EXPORT PolicyMap {
26  public:
27   // Each policy maps to an Entry which keeps the policy value as well as other
28   // relevant data about the policy.
29   struct POLICY_EXPORT Entry {
30     PolicyLevel level = POLICY_LEVEL_RECOMMENDED;
31     PolicyScope scope = POLICY_SCOPE_USER;
32     std::unique_ptr<base::Value> value;
33     std::string error;
34     std::unique_ptr<ExternalDataFetcher> external_data_fetcher;
35 
36     // For debugging and displaying only. Set by provider delivering the policy.
37     PolicySource source = POLICY_SOURCE_ENTERPRISE_DEFAULT;
38 
39     Entry();
40     ~Entry();
41 
42     Entry(Entry&&) noexcept;
43     Entry& operator=(Entry&&) noexcept;
44 
45     // Returns a copy of |this|.
46     Entry DeepCopy() const;
47 
48     // Returns true if |this| has higher priority than |other|. The priority of
49     // the fields are |level| > |scope| > |source|.
50     bool has_higher_priority_than(const Entry& other) const;
51 
52     // Returns true if |this| equals |other|.
53     bool Equals(const Entry& other) const;
54   };
55 
56   typedef std::map<std::string, Entry> PolicyMapType;
57   typedef PolicyMapType::const_iterator const_iterator;
58 
59   PolicyMap();
60   virtual ~PolicyMap();
61 
62   // Returns a weak reference to the entry currently stored for key |policy|,
63   // or NULL if not found. Ownership is retained by the PolicyMap.
64   const Entry* Get(const std::string& policy) const;
65   Entry* GetMutable(const std::string& policy);
66 
67   // Returns a weak reference to the value currently stored for key
68   // |policy|, or NULL if not found. Ownership is retained by the PolicyMap.
69   // This is equivalent to Get(policy)->value, when it doesn't return NULL.
70   const base::Value* GetValue(const std::string& policy) const;
71   base::Value* GetMutableValue(const std::string& policy);
72 
73   // Overwrites any existing information stored in the map for the key |policy|.
74   // Resets the error for that policy to the empty string.
75   void Set(const std::string& policy,
76            PolicyLevel level,
77            PolicyScope scope,
78            PolicySource source,
79            std::unique_ptr<base::Value> value,
80            std::unique_ptr<ExternalDataFetcher> external_data_fetcher);
81 
82   void Set(const std::string& policy, Entry entry);
83 
84   // Adds an |error| to the map for the key |policy| that should be shown to the
85   // user alongside the value in the policy UI. This is equivalent to calling
86   // |GetMutableValue(policy)->error = error|, so should only be called for
87   // policies that are already stored in this map.
88   void SetError(const std::string& policy, const std::string& error);
89 
90   // For all policies, overwrite the PolicySource with |source|.
91   void SetSourceForAll(PolicySource source);
92 
93   // Erase the given |policy|, if it exists in this map.
94   void Erase(const std::string& policy);
95 
96   // Erase all entries for which |filter| returns true.
97   void EraseMatching(const base::Callback<bool(const const_iterator)>& filter);
98 
99   // Erase all entries for which |filter| returns false.
100   void EraseNonmatching(
101       const base::Callback<bool(const const_iterator)>& filter);
102 
103   // Swaps the internal representation of |this| with |other|.
104   void Swap(PolicyMap* other);
105 
106   // |this| becomes a copy of |other|. Any existing policies are dropped.
107   void CopyFrom(const PolicyMap& other);
108 
109   // Returns a copy of |this|.
110   std::unique_ptr<PolicyMap> DeepCopy() const;
111 
112   // Merges policies from |other| into |this|. Existing policies are only
113   // overridden by those in |other| if they have a higher priority, as defined
114   // by Entry::has_higher_priority_than(). If a policy is contained in both
115   // maps with the same priority, the current value in |this| is preserved.
116   void MergeFrom(const PolicyMap& other);
117 
118   // Loads the values in |policies| into this PolicyMap. All policies loaded
119   // will have |level|, |scope| and |source| in their entries. Existing entries
120   // are replaced.
121   void LoadFrom(const base::DictionaryValue* policies,
122                 PolicyLevel level,
123                 PolicyScope scope,
124                 PolicySource source);
125 
126   // Compares this value map against |other| and stores all key names that have
127   // different values or reference different external data in |differing_keys|.
128   // This includes keys that are present only in one of the maps.
129   // |differing_keys| is not cleared before the keys are added.
130   void GetDifferingKeys(const PolicyMap& other,
131                         std::set<std::string>* differing_keys) const;
132 
133   bool Equals(const PolicyMap& other) const;
134   bool empty() const;
135   size_t size() const;
136 
137   const_iterator begin() const;
138   const_iterator end() const;
139   void Clear();
140 
141  private:
142   // Helper function for Equals().
143   static bool MapEntryEquals(const PolicyMapType::value_type& a,
144                              const PolicyMapType::value_type& b);
145 
146   // Erase all entries for which |filter| returns |deletion_value|.
147   void FilterErase(const base::Callback<bool(const const_iterator)>& filter,
148                    bool deletion_value);
149 
150   PolicyMapType map_;
151 
152   DISALLOW_COPY_AND_ASSIGN(PolicyMap);
153 };
154 
155 }  // namespace policy
156 
157 #endif  // COMPONENTS_POLICY_CORE_COMMON_POLICY_MAP_H_
158