1// Copyright (c) 2012 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_BROWSER_CONFIGURATION_POLICY_HANDLER_H_
6#define COMPONENTS_POLICY_CORE_BROWSER_CONFIGURATION_POLICY_HANDLER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/callback.h"
13#include "base/compiler_specific.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/scoped_vector.h"
16#include "base/values.h"
17#include "components/policy/core/common/schema.h"
18#include "components/policy/policy_export.h"
19
20class PrefValueMap;
21
22namespace policy {
23
24class PolicyErrorMap;
25struct PolicyHandlerParameters;
26class PolicyMap;
27
28// Maps a policy type to a preference path, and to the expected value type.
29struct POLICY_EXPORT PolicyToPreferenceMapEntry {
30  const char* const policy_name;
31  const char* const preference_path;
32  const base::Value::Type value_type;
33};
34
35// An abstract super class that subclasses should implement to map policies to
36// their corresponding preferences, and to check whether the policies are valid.
37class POLICY_EXPORT ConfigurationPolicyHandler {
38 public:
39  static std::string ValueTypeToString(base::Value::Type type);
40
41  ConfigurationPolicyHandler();
42  virtual ~ConfigurationPolicyHandler();
43
44  // Returns whether the policy settings handled by this
45  // ConfigurationPolicyHandler can be applied.  Fills |errors| with error
46  // messages or warnings.  |errors| may contain error messages even when
47  // |CheckPolicySettings()| returns true.
48  virtual bool CheckPolicySettings(const PolicyMap& policies,
49                                   PolicyErrorMap* errors) = 0;
50
51  // Processes the policies handled by this ConfigurationPolicyHandler and sets
52  // the appropriate preferences in |prefs|.
53  virtual void ApplyPolicySettingsWithParameters(
54      const PolicyMap& policies,
55      const PolicyHandlerParameters& parameters,
56      PrefValueMap* prefs);
57
58  // This is a convenience version of ApplyPolicySettingsWithParameters()
59  // that leaves out the |parameters|. Anyone extending
60  // ConfigurationPolicyHandler should implement either ApplyPolicySettings or
61  // ApplyPolicySettingsWithParameters.
62  virtual void ApplyPolicySettings(const PolicyMap& policies,
63                                   PrefValueMap* prefs);
64
65  // Modifies the values of some of the policies in |policies| so that they
66  // are more suitable to display to the user. This can be used to remove
67  // sensitive values such as passwords, or to pretty-print values.
68  virtual void PrepareForDisplaying(PolicyMap* policies) const;
69
70 private:
71  DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyHandler);
72};
73
74// Abstract class derived from ConfigurationPolicyHandler that should be
75// subclassed to handle a single policy (not a combination of policies).
76class POLICY_EXPORT TypeCheckingPolicyHandler
77    : public ConfigurationPolicyHandler {
78 public:
79  TypeCheckingPolicyHandler(const char* policy_name,
80                            base::Value::Type value_type);
81  virtual ~TypeCheckingPolicyHandler();
82
83  // ConfigurationPolicyHandler methods:
84  virtual bool CheckPolicySettings(const PolicyMap& policies,
85                                   PolicyErrorMap* errors) OVERRIDE;
86
87  const char* policy_name() const;
88
89 protected:
90  // Runs policy checks and returns the policy value if successful.
91  bool CheckAndGetValue(const PolicyMap& policies,
92                        PolicyErrorMap* errors,
93                        const base::Value** value);
94
95 private:
96  // The name of the policy.
97  const char* policy_name_;
98
99  // The type the value of the policy should have.
100  base::Value::Type value_type_;
101
102  DISALLOW_COPY_AND_ASSIGN(TypeCheckingPolicyHandler);
103};
104
105// Abstract class derived from TypeCheckingPolicyHandler that ensures an int
106// policy's value lies in an allowed range. Either clamps or rejects values
107// outside the range.
108class POLICY_EXPORT IntRangePolicyHandlerBase
109    : public TypeCheckingPolicyHandler {
110 public:
111  IntRangePolicyHandlerBase(const char* policy_name,
112                            int min,
113                            int max,
114                            bool clamp);
115
116  // ConfigurationPolicyHandler:
117  virtual bool CheckPolicySettings(const PolicyMap& policies,
118                                   PolicyErrorMap* errors) OVERRIDE;
119
120 protected:
121  virtual ~IntRangePolicyHandlerBase();
122
123  // Ensures that the value is in the allowed range. Returns false if the value
124  // cannot be parsed or lies outside the allowed range and clamping is
125  // disabled.
126  bool EnsureInRange(const base::Value* input,
127                     int* output,
128                     PolicyErrorMap* errors);
129
130 private:
131  // The minimum value allowed.
132  int min_;
133
134  // The maximum value allowed.
135  int max_;
136
137  // Whether to clamp values lying outside the allowed range instead of
138  // rejecting them.
139  bool clamp_;
140
141  DISALLOW_COPY_AND_ASSIGN(IntRangePolicyHandlerBase);
142};
143
144// ConfigurationPolicyHandler for policies that map directly to a preference.
145class POLICY_EXPORT SimplePolicyHandler : public TypeCheckingPolicyHandler {
146 public:
147  SimplePolicyHandler(const char* policy_name,
148                      const char* pref_path,
149                      base::Value::Type value_type);
150  virtual ~SimplePolicyHandler();
151
152  // ConfigurationPolicyHandler methods:
153  virtual void ApplyPolicySettings(const PolicyMap& policies,
154                                   PrefValueMap* prefs) OVERRIDE;
155
156 private:
157  // The DictionaryValue path of the preference the policy maps to.
158  const char* pref_path_;
159
160  DISALLOW_COPY_AND_ASSIGN(SimplePolicyHandler);
161};
162
163// Base class that encapsulates logic for mapping from a string enum list
164// to a separate matching type value.
165class POLICY_EXPORT StringMappingListPolicyHandler
166    : public TypeCheckingPolicyHandler {
167 public:
168  // Data structure representing the map between policy strings and
169  // matching pref values.
170  class POLICY_EXPORT MappingEntry {
171   public:
172    MappingEntry(const char* policy_value, scoped_ptr<base::Value> map);
173    ~MappingEntry();
174
175    const char* enum_value;
176    scoped_ptr<base::Value> mapped_value;
177  };
178
179  // Callback that generates the map for this instance.
180  typedef base::Callback<void(ScopedVector<MappingEntry>*)> GenerateMapCallback;
181
182  StringMappingListPolicyHandler(const char* policy_name,
183                                 const char* pref_path,
184                                 const GenerateMapCallback& map_generator);
185  virtual ~StringMappingListPolicyHandler();
186
187  // ConfigurationPolicyHandler methods:
188  virtual bool CheckPolicySettings(const PolicyMap& policies,
189                                   PolicyErrorMap* errors) OVERRIDE;
190  virtual void ApplyPolicySettings(const PolicyMap& policies,
191                                   PrefValueMap* prefs) OVERRIDE;
192
193 private:
194  // Attempts to convert the list in |input| to |output| according to the table,
195  // returns false on errors.
196  bool Convert(const base::Value* input,
197               base::ListValue* output,
198               PolicyErrorMap* errors);
199
200  // Helper method that converts from a policy value string to the associated
201  // pref value.
202  scoped_ptr<base::Value> Map(const std::string& entry_value);
203
204  // Name of the pref to write.
205  const char* pref_path_;
206
207  // The callback invoked to generate the map for this instance.
208  GenerateMapCallback map_getter_;
209
210  // Map of string policy values to local pref values. This is generated lazily
211  // so the generation does not have to happen if no policy is present.
212  ScopedVector<MappingEntry> map_;
213
214  DISALLOW_COPY_AND_ASSIGN(StringMappingListPolicyHandler);
215};
216
217// A policy handler implementation that ensures an int policy's value lies in an
218// allowed range.
219class POLICY_EXPORT IntRangePolicyHandler : public IntRangePolicyHandlerBase {
220 public:
221  IntRangePolicyHandler(const char* policy_name,
222                        const char* pref_path,
223                        int min,
224                        int max,
225                        bool clamp);
226  virtual ~IntRangePolicyHandler();
227
228  // ConfigurationPolicyHandler:
229  virtual void ApplyPolicySettings(const PolicyMap& policies,
230                                   PrefValueMap* prefs) OVERRIDE;
231
232 private:
233  // Name of the pref to write.
234  const char* pref_path_;
235
236  DISALLOW_COPY_AND_ASSIGN(IntRangePolicyHandler);
237};
238
239// A policy handler implementation that maps an int percentage value to a
240// double.
241class POLICY_EXPORT IntPercentageToDoublePolicyHandler
242    : public IntRangePolicyHandlerBase {
243 public:
244  IntPercentageToDoublePolicyHandler(const char* policy_name,
245                                     const char* pref_path,
246                                     int min,
247                                     int max,
248                                     bool clamp);
249  virtual ~IntPercentageToDoublePolicyHandler();
250
251  // ConfigurationPolicyHandler:
252  virtual void ApplyPolicySettings(const PolicyMap& policies,
253                                   PrefValueMap* prefs) OVERRIDE;
254
255 private:
256  // Name of the pref to write.
257  const char* pref_path_;
258
259  DISALLOW_COPY_AND_ASSIGN(IntPercentageToDoublePolicyHandler);
260};
261
262// Like TypeCheckingPolicyHandler, but validates against a schema instead of a
263// single type. |schema| is the schema used for this policy, and |strategy| is
264// the strategy used for schema validation errors.
265class POLICY_EXPORT SchemaValidatingPolicyHandler
266    : public ConfigurationPolicyHandler {
267 public:
268  SchemaValidatingPolicyHandler(const char* policy_name,
269                                Schema schema,
270                                SchemaOnErrorStrategy strategy);
271  virtual ~SchemaValidatingPolicyHandler();
272
273  // ConfigurationPolicyHandler:
274  virtual bool CheckPolicySettings(const PolicyMap& policies,
275                                   PolicyErrorMap* errors) OVERRIDE;
276
277  const char* policy_name() const;
278
279 protected:
280  // Runs policy checks and returns the policy value if successful.
281  bool CheckAndGetValue(const PolicyMap& policies,
282                        PolicyErrorMap* errors,
283                        scoped_ptr<base::Value>* output);
284
285 private:
286  const char* policy_name_;
287  Schema schema_;
288  SchemaOnErrorStrategy strategy_;
289
290  DISALLOW_COPY_AND_ASSIGN(SchemaValidatingPolicyHandler);
291};
292
293// Maps policy to pref like SimplePolicyHandler while ensuring that the value
294// set matches the schema. |schema| is the schema used for policies, and
295// |strategy| is the strategy used for schema validation errors. The
296// |recommended_permission| and |mandatory_permission| flags indicate the levels
297// at which the policy can be set. A value set at an unsupported level will be
298// ignored.
299class POLICY_EXPORT SimpleSchemaValidatingPolicyHandler
300    : public SchemaValidatingPolicyHandler {
301 public:
302  enum MandatoryPermission { MANDATORY_ALLOWED, MANDATORY_PROHIBITED };
303  enum RecommendedPermission { RECOMMENDED_ALLOWED, RECOMMENDED_PROHIBITED };
304
305  SimpleSchemaValidatingPolicyHandler(
306      const char* policy_name,
307      const char* pref_path,
308      Schema schema,
309      SchemaOnErrorStrategy strategy,
310      RecommendedPermission recommended_permission,
311      MandatoryPermission mandatory_permission);
312  virtual ~SimpleSchemaValidatingPolicyHandler();
313
314  // ConfigurationPolicyHandler:
315  virtual bool CheckPolicySettings(const PolicyMap& policies,
316                                   PolicyErrorMap* errors) OVERRIDE;
317  virtual void ApplyPolicySettings(const PolicyMap& policies,
318                                   PrefValueMap* prefs) OVERRIDE;
319
320 private:
321  const char* pref_path_;
322  const bool allow_recommended_;
323  const bool allow_mandatory_;
324
325  DISALLOW_COPY_AND_ASSIGN(SimpleSchemaValidatingPolicyHandler);
326};
327
328// A policy handler to deprecate multiple legacy policies with a new one.
329// This handler will completely ignore any of legacy policy values if the new
330// one is set.
331class POLICY_EXPORT LegacyPoliciesDeprecatingPolicyHandler
332    : public ConfigurationPolicyHandler {
333 public:
334  LegacyPoliciesDeprecatingPolicyHandler(
335      ScopedVector<ConfigurationPolicyHandler> legacy_policy_handlers,
336      scoped_ptr<SchemaValidatingPolicyHandler> new_policy_handler);
337  virtual ~LegacyPoliciesDeprecatingPolicyHandler();
338
339  // ConfigurationPolicyHandler:
340  virtual bool CheckPolicySettings(const PolicyMap& policies,
341                                   PolicyErrorMap* errors) OVERRIDE;
342  virtual void ApplyPolicySettings(const PolicyMap& policies,
343                                   PrefValueMap* prefs) OVERRIDE;
344
345 private:
346  ScopedVector<ConfigurationPolicyHandler> legacy_policy_handlers_;
347  scoped_ptr<SchemaValidatingPolicyHandler> new_policy_handler_;
348
349  DISALLOW_COPY_AND_ASSIGN(LegacyPoliciesDeprecatingPolicyHandler);
350};
351
352}  // namespace policy
353
354#endif  // COMPONENTS_POLICY_CORE_BROWSER_CONFIGURATION_POLICY_HANDLER_H_
355