Home | History | Annotate | Download | only in common
      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/policy_test_utils.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/bind_helpers.h"
     11 #include "base/callback.h"
     12 #include "base/json/json_writer.h"
     13 #include "base/logging.h"
     14 #include "base/strings/sys_string_conversions.h"
     15 #include "base/values.h"
     16 #include "components/policy/core/common/policy_bundle.h"
     17 
     18 #if defined(OS_IOS) || defined(OS_MACOSX)
     19 #include <CoreFoundation/CoreFoundation.h>
     20 
     21 #include "base/mac/scoped_cftyperef.h"
     22 #endif
     23 
     24 namespace policy {
     25 
     26 PolicyDetailsMap::PolicyDetailsMap() {}
     27 
     28 PolicyDetailsMap::~PolicyDetailsMap() {}
     29 
     30 GetChromePolicyDetailsCallback PolicyDetailsMap::GetCallback() const {
     31   return base::Bind(&PolicyDetailsMap::Lookup, base::Unretained(this));
     32 }
     33 
     34 void PolicyDetailsMap::SetDetails(const std::string& policy,
     35                                   const PolicyDetails* details) {
     36   map_[policy] = details;
     37 }
     38 
     39 const PolicyDetails* PolicyDetailsMap::Lookup(const std::string& policy) const {
     40   PolicyDetailsMapping::const_iterator it = map_.find(policy);
     41   return it == map_.end() ? NULL : it->second;
     42 }
     43 
     44 bool PolicyServiceIsEmpty(const PolicyService* service) {
     45   const PolicyMap& map = service->GetPolicies(
     46       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
     47   if (!map.empty()) {
     48     base::DictionaryValue dict;
     49     for (PolicyMap::const_iterator it = map.begin(); it != map.end(); ++it)
     50       dict.SetWithoutPathExpansion(it->first, it->second.value->DeepCopy());
     51     LOG(WARNING) << "There are pre-existing policies in this machine: " << dict;
     52   }
     53   return map.empty();
     54 }
     55 
     56 #if defined(OS_IOS) || defined(OS_MACOSX)
     57 CFPropertyListRef ValueToProperty(const base::Value* value) {
     58   switch (value->GetType()) {
     59     case base::Value::TYPE_NULL:
     60       return kCFNull;
     61 
     62     case base::Value::TYPE_BOOLEAN: {
     63       bool bool_value;
     64       if (value->GetAsBoolean(&bool_value))
     65         return bool_value ? kCFBooleanTrue : kCFBooleanFalse;
     66       break;
     67     }
     68 
     69     case base::Value::TYPE_INTEGER: {
     70       int int_value;
     71       if (value->GetAsInteger(&int_value)) {
     72         return CFNumberCreate(
     73             kCFAllocatorDefault, kCFNumberIntType, &int_value);
     74       }
     75       break;
     76     }
     77 
     78     case base::Value::TYPE_DOUBLE: {
     79       double double_value;
     80       if (value->GetAsDouble(&double_value)) {
     81         return CFNumberCreate(
     82             kCFAllocatorDefault, kCFNumberDoubleType, &double_value);
     83       }
     84       break;
     85     }
     86 
     87     case base::Value::TYPE_STRING: {
     88       std::string string_value;
     89       if (value->GetAsString(&string_value))
     90         return base::SysUTF8ToCFStringRef(string_value);
     91       break;
     92     }
     93 
     94     case base::Value::TYPE_DICTIONARY: {
     95       const base::DictionaryValue* dict_value;
     96       if (value->GetAsDictionary(&dict_value)) {
     97         // |dict| is owned by the caller.
     98         CFMutableDictionaryRef dict =
     99             CFDictionaryCreateMutable(kCFAllocatorDefault,
    100                                       dict_value->size(),
    101                                       &kCFTypeDictionaryKeyCallBacks,
    102                                       &kCFTypeDictionaryValueCallBacks);
    103         for (base::DictionaryValue::Iterator iterator(*dict_value);
    104              !iterator.IsAtEnd(); iterator.Advance()) {
    105           // CFDictionaryAddValue() retains both |key| and |value|, so make sure
    106           // the references are balanced.
    107           base::ScopedCFTypeRef<CFStringRef> key(
    108               base::SysUTF8ToCFStringRef(iterator.key()));
    109           base::ScopedCFTypeRef<CFPropertyListRef> cf_value(
    110               ValueToProperty(&iterator.value()));
    111           if (cf_value)
    112             CFDictionaryAddValue(dict, key, cf_value);
    113         }
    114         return dict;
    115       }
    116       break;
    117     }
    118 
    119     case base::Value::TYPE_LIST: {
    120       const base::ListValue* list;
    121       if (value->GetAsList(&list)) {
    122         CFMutableArrayRef array =
    123             CFArrayCreateMutable(NULL, list->GetSize(), &kCFTypeArrayCallBacks);
    124         for (base::ListValue::const_iterator it(list->begin());
    125              it != list->end(); ++it) {
    126           // CFArrayAppendValue() retains |value|, so make sure the reference
    127           // created by ValueToProperty() is released.
    128           base::ScopedCFTypeRef<CFPropertyListRef> cf_value(
    129               ValueToProperty(*it));
    130           if (cf_value)
    131             CFArrayAppendValue(array, cf_value);
    132         }
    133         return array;
    134       }
    135       break;
    136     }
    137 
    138     case base::Value::TYPE_BINARY:
    139       // This type isn't converted (though it can be represented as CFData)
    140       // because there's no equivalent JSON type, and policy values can only
    141       // take valid JSON values.
    142       break;
    143   }
    144 
    145   return NULL;
    146 }
    147 #endif  // defined(OS_IOS) || defined(OS_MACOSX)
    148 
    149 }  // namespace policy
    150 
    151 std::ostream& operator<<(std::ostream& os,
    152                          const policy::PolicyBundle& bundle) {
    153   os << "{" << std::endl;
    154   for (policy::PolicyBundle::const_iterator iter = bundle.begin();
    155        iter != bundle.end(); ++iter) {
    156     os << "  \"" << iter->first << "\": " << *iter->second << "," << std::endl;
    157   }
    158   os << "}";
    159   return os;
    160 }
    161 
    162 std::ostream& operator<<(std::ostream& os, policy::PolicyScope scope) {
    163   switch (scope) {
    164     case policy::POLICY_SCOPE_USER: {
    165       os << "POLICY_SCOPE_USER";
    166       break;
    167     }
    168     case policy::POLICY_SCOPE_MACHINE: {
    169       os << "POLICY_SCOPE_MACHINE";
    170       break;
    171     }
    172     default: {
    173       os << "POLICY_SCOPE_UNKNOWN(" << int(scope) << ")";
    174     }
    175   }
    176   return os;
    177 }
    178 
    179 std::ostream& operator<<(std::ostream& os, policy::PolicyLevel level) {
    180   switch (level) {
    181     case policy::POLICY_LEVEL_RECOMMENDED: {
    182       os << "POLICY_LEVEL_RECOMMENDED";
    183       break;
    184     }
    185     case policy::POLICY_LEVEL_MANDATORY: {
    186       os << "POLICY_LEVEL_MANDATORY";
    187       break;
    188     }
    189     default: {
    190       os << "POLICY_LEVEL_UNKNOWN(" << int(level) << ")";
    191     }
    192   }
    193   return os;
    194 }
    195 
    196 std::ostream& operator<<(std::ostream& os, policy::PolicyDomain domain) {
    197   switch (domain) {
    198     case policy::POLICY_DOMAIN_CHROME: {
    199       os << "POLICY_DOMAIN_CHROME";
    200       break;
    201     }
    202     case policy::POLICY_DOMAIN_EXTENSIONS: {
    203       os << "POLICY_DOMAIN_EXTENSIONS";
    204       break;
    205     }
    206     default: {
    207       os << "POLICY_DOMAIN_UNKNOWN(" << int(domain) << ")";
    208     }
    209   }
    210   return os;
    211 }
    212 
    213 std::ostream& operator<<(std::ostream& os, const policy::PolicyMap& policies) {
    214   os << "{" << std::endl;
    215   for (policy::PolicyMap::const_iterator iter = policies.begin();
    216        iter != policies.end(); ++iter) {
    217     os << "  \"" << iter->first << "\": " << iter->second << "," << std::endl;
    218   }
    219   os << "}";
    220   return os;
    221 }
    222 
    223 std::ostream& operator<<(std::ostream& os, const policy::PolicyMap::Entry& e) {
    224   std::string value;
    225   base::JSONWriter::WriteWithOptions(e.value,
    226                                      base::JSONWriter::OPTIONS_PRETTY_PRINT,
    227                                      &value);
    228   os << "{" << std::endl
    229      << "  \"level\": " << e.level << "," << std::endl
    230      << "  \"scope\": " << e.scope << "," << std::endl
    231      << "  \"value\": " << value
    232      << "}";
    233   return os;
    234 }
    235 
    236 std::ostream& operator<<(std::ostream& os, const policy::PolicyNamespace& ns) {
    237   os << ns.domain << "/" << ns.component_id;
    238   return os;
    239 }
    240