• 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 #include "components/policy/core/common/schema_map.h"
6 
7 #include "base/logging.h"
8 #include "base/values.h"
9 #include "components/policy/core/common/policy_bundle.h"
10 #include "components/policy/core/common/policy_map.h"
11 
12 namespace policy {
13 
SchemaMap()14 SchemaMap::SchemaMap() {}
15 
SchemaMap(DomainMap & map)16 SchemaMap::SchemaMap(DomainMap& map) {
17   map_.swap(map);
18 }
19 
~SchemaMap()20 SchemaMap::~SchemaMap() {}
21 
GetDomains() const22 const DomainMap& SchemaMap::GetDomains() const {
23   return map_;
24 }
25 
GetComponents(PolicyDomain domain) const26 const ComponentMap* SchemaMap::GetComponents(PolicyDomain domain) const {
27   DomainMap::const_iterator it = map_.find(domain);
28   return it == map_.end() ? NULL : &it->second;
29 }
30 
GetSchema(const PolicyNamespace & ns) const31 const Schema* SchemaMap::GetSchema(const PolicyNamespace& ns) const {
32   const ComponentMap* map = GetComponents(ns.domain);
33   if (!map)
34     return NULL;
35   ComponentMap::const_iterator it = map->find(ns.component_id);
36   return it == map->end() ? NULL : &it->second;
37 }
38 
FilterBundle(PolicyBundle * bundle) const39 void SchemaMap::FilterBundle(PolicyBundle* bundle) const {
40   for (PolicyBundle::iterator it = bundle->begin(); it != bundle->end(); ++it) {
41     // Chrome policies are not filtered, so that typos appear in about:policy.
42     // Everything else gets filtered, so that components only see valid policy.
43     if (it->first.domain == POLICY_DOMAIN_CHROME)
44       continue;
45 
46     const Schema* schema = GetSchema(it->first);
47 
48     if (!schema) {
49       it->second->Clear();
50       continue;
51     }
52 
53     // TODO(joaodasilva): if a component is registered but doesn't have a schema
54     // then its policies aren't filtered. This behavior is enabled to allow a
55     // graceful update of the Legacy Browser Support extension; it'll be removed
56     // in a future release. http://crbug.com/240704
57     static const char kLegacyBrowserSupportExtensionId[] =
58         "heildphpnddilhkemkielfhnkaagiabh";
59     if (it->first.domain == POLICY_DOMAIN_EXTENSIONS &&
60         it->first.component_id == kLegacyBrowserSupportExtensionId) {
61       continue;
62     }
63 
64     if (!schema->valid()) {
65       // Don't serve unknown policies.
66       it->second->Clear();
67       continue;
68     }
69 
70     PolicyMap* map = it->second;
71     for (PolicyMap::const_iterator it_map = map->begin();
72          it_map != map->end();) {
73       const std::string& policy_name = it_map->first;
74       const base::Value* policy_value = it_map->second.value;
75       Schema policy_schema = schema->GetProperty(policy_name);
76       ++it_map;
77       std::string error_path;
78       std::string error;
79       if (!policy_value ||
80           !policy_schema.Validate(*policy_value,
81                                   SCHEMA_STRICT,
82                                   &error_path,
83                                   &error)) {
84         LOG(ERROR) << "Dropping policy " << policy_name << " for "
85                    << it->first.component_id
86                    << " because it's not valid: " << error
87                    << " at " << error_path;
88         map->Erase(policy_name);
89       }
90     }
91   }
92 }
93 
HasComponents() const94 bool SchemaMap::HasComponents() const {
95   for (DomainMap::const_iterator domain = map_.begin();
96        domain != map_.end(); ++domain) {
97     if (domain->first == POLICY_DOMAIN_CHROME)
98       continue;
99     if (!domain->second.empty())
100       return true;
101   }
102   return false;
103 }
104 
GetChanges(const scoped_refptr<SchemaMap> & older,PolicyNamespaceList * removed,PolicyNamespaceList * added) const105 void SchemaMap::GetChanges(const scoped_refptr<SchemaMap>& older,
106                            PolicyNamespaceList* removed,
107                            PolicyNamespaceList* added) const {
108   GetNamespacesNotInOther(older, added);
109   older->GetNamespacesNotInOther(this, removed);
110 }
111 
GetNamespacesNotInOther(const SchemaMap * other,PolicyNamespaceList * list) const112 void SchemaMap::GetNamespacesNotInOther(const SchemaMap* other,
113                                         PolicyNamespaceList* list) const {
114   list->clear();
115   for (DomainMap::const_iterator domain = map_.begin();
116        domain != map_.end(); ++domain) {
117     const ComponentMap& components = domain->second;
118     for (ComponentMap::const_iterator comp = components.begin();
119          comp != components.end(); ++comp) {
120       PolicyNamespace ns(domain->first, comp->first);
121       if (!other->GetSchema(ns))
122         list->push_back(ns);
123     }
124   }
125 }
126 
127 }  // namespace policy
128