xref: /aosp_15_r20/external/libchrome/components/policy/core/common/schema_map.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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   const auto it = map_.find(domain);
28   return it == map_.end() ? nullptr : &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 nullptr;
35   const auto it = map->find(ns.component_id);
36   return it == map->end() ? nullptr : &it->second;
37 }
38 
FilterBundle(PolicyBundle * bundle) const39 void SchemaMap::FilterBundle(PolicyBundle* bundle) const {
40   for (const auto& bundle_item : *bundle) {
41     const PolicyNamespace& ns = bundle_item.first;
42     const std::unique_ptr<PolicyMap>& policy_map = bundle_item.second;
43 
44     // Chrome policies are not filtered, so that typos appear in about:policy.
45     // Everything else gets filtered, so that components only see valid policy.
46     if (ns.domain == POLICY_DOMAIN_CHROME)
47       continue;
48 
49     const Schema* schema = GetSchema(ns);
50 
51     if (!schema) {
52       policy_map->Clear();
53       continue;
54     }
55 
56     if (!schema->valid()) {
57       // Don't serve unknown policies.
58       policy_map->Clear();
59       continue;
60     }
61 
62     for (auto it_map = policy_map->begin(); it_map != policy_map->end();) {
63       const std::string& policy_name = it_map->first;
64       const base::Value* policy_value = it_map->second.value.get();
65       Schema policy_schema = schema->GetProperty(policy_name);
66       ++it_map;
67       std::string error_path;
68       std::string error;
69       if (!policy_value ||
70           !policy_schema.Validate(*policy_value,
71                                   SCHEMA_STRICT,
72                                   &error_path,
73                                   &error)) {
74         LOG(ERROR) << "Dropping policy " << policy_name << " of component "
75                    << ns.component_id << " due to error at "
76                    << (error_path.empty() ? "root" : error_path) << ": "
77                    << error;
78         policy_map->Erase(policy_name);
79       }
80     }
81   }
82 }
83 
HasComponents() const84 bool SchemaMap::HasComponents() const {
85   for (const auto& item : map_) {
86     const PolicyDomain& domain = item.first;
87     const ComponentMap& component_map = item.second;
88     if (domain == POLICY_DOMAIN_CHROME)
89       continue;
90     if (!component_map.empty())
91       return true;
92   }
93   return false;
94 }
95 
GetChanges(const scoped_refptr<SchemaMap> & older,PolicyNamespaceList * removed,PolicyNamespaceList * added) const96 void SchemaMap::GetChanges(const scoped_refptr<SchemaMap>& older,
97                            PolicyNamespaceList* removed,
98                            PolicyNamespaceList* added) const {
99   GetNamespacesNotInOther(older.get(), added);
100   older->GetNamespacesNotInOther(this, removed);
101 }
102 
GetNamespacesNotInOther(const SchemaMap * other,PolicyNamespaceList * list) const103 void SchemaMap::GetNamespacesNotInOther(const SchemaMap* other,
104                                         PolicyNamespaceList* list) const {
105   list->clear();
106   for (const auto& item : map_) {
107     const PolicyDomain& domain = item.first;
108     const ComponentMap& component_map = item.second;
109     for (const auto& comp : component_map) {
110       const std::string& component_id = comp.first;
111       const PolicyNamespace ns(domain, component_id);
112       if (!other->GetSchema(ns))
113         list->push_back(ns);
114     }
115   }
116 }
117 
118 }  // namespace policy
119