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 24namespace policy { 25 26PolicyDetailsMap::PolicyDetailsMap() {} 27 28PolicyDetailsMap::~PolicyDetailsMap() {} 29 30GetChromePolicyDetailsCallback PolicyDetailsMap::GetCallback() const { 31 return base::Bind(&PolicyDetailsMap::Lookup, base::Unretained(this)); 32} 33 34void PolicyDetailsMap::SetDetails(const std::string& policy, 35 const PolicyDetails* details) { 36 map_[policy] = details; 37} 38 39const 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 44bool 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) 57CFPropertyListRef 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 151std::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 162std::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 179std::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 196std::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 213std::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 223std::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 236std::ostream& operator<<(std::ostream& os, const policy::PolicyNamespace& ns) { 237 os << ns.domain << "/" << ns.component_id; 238 return os; 239} 240