Home | History | Annotate | Download | only in policy
      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