1 // Copyright (c) 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 "chrome/browser/policy/policy_domain_descriptor.h" 6 7 #include "base/logging.h" 8 #include "base/stl_util.h" 9 #include "base/values.h" 10 #include "chrome/browser/policy/policy_bundle.h" 11 #include "chrome/browser/policy/policy_map.h" 12 #include "chrome/common/policy/policy_schema.h" 13 14 namespace policy { 15 16 namespace { 17 18 bool Matches(const PolicySchema* schema, const base::Value& value) { 19 if (!schema) { 20 // Schema not found, invalid entry. 21 return false; 22 } 23 24 if (!value.IsType(schema->type())) 25 return false; 26 27 const base::DictionaryValue* dict = NULL; 28 const base::ListValue* list = NULL; 29 if (value.GetAsDictionary(&dict)) { 30 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); 31 it.Advance()) { 32 if (!Matches(schema->GetSchemaForProperty(it.key()), it.value())) 33 return false; 34 } 35 } else if (value.GetAsList(&list)) { 36 for (base::ListValue::const_iterator it = list->begin(); 37 it != list->end(); ++it) { 38 if (!*it || !Matches(schema->GetSchemaForItems(), **it)) 39 return false; 40 } 41 } 42 43 return true; 44 } 45 46 } // namespace 47 48 PolicyDomainDescriptor::PolicyDomainDescriptor(PolicyDomain domain) 49 : domain_(domain) {} 50 51 void PolicyDomainDescriptor::RegisterComponent( 52 const std::string& component_id, 53 scoped_ptr<PolicySchema> schema) { 54 const PolicySchema*& entry = schema_map_[component_id]; 55 delete entry; 56 entry = schema.release(); 57 } 58 59 void PolicyDomainDescriptor::FilterBundle(PolicyBundle* bundle) const { 60 // Chrome policies are not filtered, so that typos appear in about:policy. 61 DCHECK_NE(POLICY_DOMAIN_CHROME, domain_); 62 63 for (PolicyBundle::iterator it_bundle = bundle->begin(); 64 it_bundle != bundle->end(); ++it_bundle) { 65 const PolicyNamespace& ns = it_bundle->first; 66 if (ns.domain != domain_) 67 continue; 68 69 SchemaMap::const_iterator it_schema = schema_map_.find(ns.component_id); 70 if (it_schema == schema_map_.end()) { 71 // Component ID not found. 72 it_bundle->second->Clear(); 73 continue; 74 } 75 76 // TODO(joaodasilva): if a component is registered but doesn't have a schema 77 // then its policies aren't filtered. This behavior is enabled for M29 to 78 // allow a graceful update of the Legacy Browser Support extension; it'll 79 // be removed for M30. http://crbug.com/240704 80 if (!it_schema->second) 81 continue; 82 83 const PolicySchema* component_schema = it_schema->second; 84 PolicyMap* map = it_bundle->second; 85 for (PolicyMap::const_iterator it_map = map->begin(); 86 it_map != map->end();) { 87 const std::string& policy_name = it_map->first; 88 const base::Value* policy_value = it_map->second.value; 89 const PolicySchema* policy_schema = 90 component_schema->GetSchemaForProperty(policy_name); 91 ++it_map; 92 if (!policy_value || !Matches(policy_schema, *policy_value)) 93 map->Erase(policy_name); 94 } 95 } 96 } 97 98 PolicyDomainDescriptor::~PolicyDomainDescriptor() { 99 STLDeleteValues(&schema_map_); 100 } 101 102 } // namespace policy 103