• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SCHEMA_H_
6 #define COMPONENTS_POLICY_CORE_COMMON_SCHEMA_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/basictypes.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/values.h"
14 #include "components/policy/policy_export.h"
15 
16 namespace policy {
17 namespace internal {
18 
19 struct POLICY_EXPORT SchemaData;
20 struct POLICY_EXPORT SchemaNode;
21 struct POLICY_EXPORT PropertyNode;
22 struct POLICY_EXPORT PropertiesNode;
23 
24 }  // namespace internal
25 
26 // Option flags passed to Schema::Validate() and Schema::Normalize(), describing
27 // the strategy to handle unknown properties or invalid values for dict type.
28 // Note that in Schema::Normalize() allowed errors will be dropped and thus
29 // ignored.
30 // Unknown error indicates that some value in a dictionary (may or may not be
31 // the one in root) have unknown property name according to schema.
32 // Invalid error indicates a validation failure against the schema. As
33 // validation is done recursively, a validation failure of dict properties or
34 // list items might be ignored (or dropped in Normalize()) or trigger whole
35 // dictionary/list validation failure.
36 enum SchemaOnErrorStrategy {
37   // No errors will be allowed.
38   SCHEMA_STRICT = 0,
39   // Unknown properties in the top-level dictionary will be ignored.
40   SCHEMA_ALLOW_UNKNOWN_TOPLEVEL,
41   // Unknown properties in any dictionary will be ignored.
42   SCHEMA_ALLOW_UNKNOWN,
43   // Mismatched values will be ignored at the toplevel.
44   SCHEMA_ALLOW_INVALID_TOPLEVEL,
45   // Mismatched values will be ignored at the top-level value.
46   // Unknown properties in any dictionary will be ignored.
47   SCHEMA_ALLOW_INVALID_TOPLEVEL_AND_ALLOW_UNKNOWN,
48   // Mismatched values will be ignored.
49   SCHEMA_ALLOW_INVALID,
50 };
51 
52 class Schema;
53 
54 typedef std::vector<Schema> SchemaList;
55 
56 // Describes the expected type of one policy. Also recursively describes the
57 // types of inner elements, for structured types.
58 // Objects of this class refer to external, immutable data and are cheap to
59 // copy.
60 class POLICY_EXPORT Schema {
61  public:
62   // Used internally to store shared data.
63   class InternalStorage;
64 
65   // Builds an empty, invalid schema.
66   Schema();
67 
68   // Makes a copy of |schema| that shares the same internal storage.
69   Schema(const Schema& schema);
70 
71   ~Schema();
72 
73   Schema& operator=(const Schema& schema);
74 
75   // Returns a Schema that references static data. This can be used by
76   // the embedder to pass structures generated at compile time, which can then
77   // be quickly loaded at runtime.
78   static Schema Wrap(const internal::SchemaData* data);
79 
80   // Parses the JSON schema in |schema| and returns a Schema that owns
81   // the internal representation. If |schema| is invalid then an invalid Schema
82   // is returned and |error| contains a reason for the failure.
83   static Schema Parse(const std::string& schema, std::string* error);
84 
85   // Returns true if this Schema is valid. Schemas returned by the methods below
86   // may be invalid, and in those cases the other methods must not be used.
valid()87   bool valid() const { return node_ != NULL; }
88 
89   base::Value::Type type() const;
90 
91   // Validate |value| against current schema, |strategy| is the strategy to
92   // handle unknown properties or invalid values. Allowed errors will be
93   // ignored. |error_path| and |error| will contain the last error location and
94   // detailed message if |value| doesn't strictly conform to the schema. If
95   // |value| doesn't conform to the schema even within the allowance of
96   // |strategy|, false will be returned and |error_path| and |error| will
97   // contain the corresponding error that caused the failure. |error_path| can
98   // be NULL and in that case no error path will be returned.
99   bool Validate(const base::Value& value,
100                 SchemaOnErrorStrategy strategy,
101                 std::string* error_path,
102                 std::string* error) const;
103 
104   // Similar to Validate() but drop values with errors instead of ignoring them.
105   // |changed| is a pointer to a boolean value, and indicate whether |value|
106   // is changed or not (probably dropped properties or items). Be sure to set
107   // the bool that |changed| pointed to to false before calling Normalize().
108   // |changed| can be NULL and in that case no boolean will be set.
109   // This function will also take the ownership of dropped base::Value and
110   // destroy them.
111   bool Normalize(base::Value* value,
112                  SchemaOnErrorStrategy strategy,
113                  std::string* error_path,
114                  std::string* error,
115                  bool* changed) const;
116 
117   // Used to iterate over the known properties of TYPE_DICTIONARY schemas.
118   class POLICY_EXPORT Iterator {
119    public:
120     Iterator(const scoped_refptr<const InternalStorage>& storage,
121              const internal::PropertiesNode* node);
122     Iterator(const Iterator& iterator);
123     ~Iterator();
124 
125     Iterator& operator=(const Iterator& iterator);
126 
127     // The other methods must not be called if the iterator is at the end.
128     bool IsAtEnd() const;
129 
130     // Advances the iterator to the next property.
131     void Advance();
132 
133     // Returns the name of the current property.
134     const char* key() const;
135 
136     // Returns the Schema for the current property. This Schema is always valid.
137     Schema schema() const;
138 
139    private:
140     scoped_refptr<const InternalStorage> storage_;
141     const internal::PropertyNode* it_;
142     const internal::PropertyNode* end_;
143   };
144 
145   // These methods should be called only if type() == TYPE_DICTIONARY,
146   // otherwise invalid memory will be read. A CHECK is currently enforcing this.
147 
148   // Returns an iterator that goes over the named properties of this schema.
149   // The returned iterator is at the beginning.
150   Iterator GetPropertiesIterator() const;
151 
152   // Returns the Schema for the property named |key|. If |key| is not a known
153   // property name then the returned Schema is not valid.
154   Schema GetKnownProperty(const std::string& key) const;
155 
156   // Returns all Schemas from pattern properties that match |key|. May be empty.
157   SchemaList GetPatternProperties(const std::string& key) const;
158 
159   // Returns the Schema for additional properties. If additional properties are
160   // not allowed for this Schema then the Schema returned is not valid.
161   Schema GetAdditionalProperties() const;
162 
163   // Returns the Schema for |key| if it is a known property, otherwise returns
164   // the Schema for additional properties.
165   // DEPRECATED: This function didn't consider patternProperties, use
166   // GetMatchingProperties() instead.
167   // TODO(binjin): Replace calls to this function with GetKnownProperty() or
168   // GetMatchingProperties() and remove this later.
169   Schema GetProperty(const std::string& key) const;
170 
171   // Returns all Schemas that are supposed to be validated against for |key|.
172   // May be empty.
173   SchemaList GetMatchingProperties(const std::string& key) const;
174 
175   // Returns the Schema for items of an array.
176   // This method should be called only if type() == TYPE_LIST,
177   // otherwise invalid memory will be read. A CHECK is currently enforcing this.
178   Schema GetItems() const;
179 
180  private:
181   // Builds a schema pointing to the inner structure of |storage|,
182   // rooted at |node|.
183   Schema(const scoped_refptr<const InternalStorage>& storage,
184          const internal::SchemaNode* node);
185 
186   bool ValidateIntegerRestriction(int index, int value) const;
187   bool ValidateStringRestriction(int index, const char* str) const;
188 
189   scoped_refptr<const InternalStorage> storage_;
190   const internal::SchemaNode* node_;
191 };
192 
193 }  // namespace policy
194 
195 #endif  // COMPONENTS_POLICY_CORE_COMMON_SCHEMA_H_
196