blob: 7aee218cac18afb56200e2d0021dedb6c2c46cca [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/policy/core/common/policy_test_utils.h"
#include <string>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/policy/core/common/policy_bundle.h"
#if defined(OS_IOS) || defined(OS_MACOSX)
#include <CoreFoundation/CoreFoundation.h>
#include "base/mac/scoped_cftyperef.h"
#endif
namespace policy {
PolicyDetailsMap::PolicyDetailsMap() {}
PolicyDetailsMap::~PolicyDetailsMap() {}
GetChromePolicyDetailsCallback PolicyDetailsMap::GetCallback() const {
return base::Bind(&PolicyDetailsMap::Lookup, base::Unretained(this));
}
void PolicyDetailsMap::SetDetails(const std::string& policy,
const PolicyDetails* details) {
map_[policy] = details;
}
const PolicyDetails* PolicyDetailsMap::Lookup(const std::string& policy) const {
PolicyDetailsMapping::const_iterator it = map_.find(policy);
return it == map_.end() ? NULL : it->second;
}
bool PolicyServiceIsEmpty(const PolicyService* service) {
const PolicyMap& map = service->GetPolicies(
PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
if (!map.empty()) {
base::DictionaryValue dict;
for (PolicyMap::const_iterator it = map.begin(); it != map.end(); ++it)
dict.SetWithoutPathExpansion(it->first, it->second.value->DeepCopy());
LOG(WARNING) << "There are pre-existing policies in this machine: " << dict;
}
return map.empty();
}
#if defined(OS_IOS) || defined(OS_MACOSX)
CFPropertyListRef ValueToProperty(const base::Value& value) {
switch (value.GetType()) {
case base::Value::TYPE_NULL:
return kCFNull;
case base::Value::TYPE_BOOLEAN: {
bool bool_value;
if (value.GetAsBoolean(&bool_value))
return bool_value ? kCFBooleanTrue : kCFBooleanFalse;
break;
}
case base::Value::TYPE_INTEGER: {
int int_value;
if (value.GetAsInteger(&int_value)) {
return CFNumberCreate(
kCFAllocatorDefault, kCFNumberIntType, &int_value);
}
break;
}
case base::Value::TYPE_DOUBLE: {
double double_value;
if (value.GetAsDouble(&double_value)) {
return CFNumberCreate(
kCFAllocatorDefault, kCFNumberDoubleType, &double_value);
}
break;
}
case base::Value::TYPE_STRING: {
std::string string_value;
if (value.GetAsString(&string_value))
return base::SysUTF8ToCFStringRef(string_value);
break;
}
case base::Value::TYPE_DICTIONARY: {
const base::DictionaryValue* dict_value;
if (value.GetAsDictionary(&dict_value)) {
// |dict| is owned by the caller.
CFMutableDictionaryRef dict =
CFDictionaryCreateMutable(kCFAllocatorDefault,
dict_value->size(),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
for (base::DictionaryValue::Iterator iterator(*dict_value);
!iterator.IsAtEnd(); iterator.Advance()) {
// CFDictionaryAddValue() retains both |key| and |value|, so make sure
// the references are balanced.
base::ScopedCFTypeRef<CFStringRef> key(
base::SysUTF8ToCFStringRef(iterator.key()));
base::ScopedCFTypeRef<CFPropertyListRef> cf_value(
ValueToProperty(iterator.value()));
if (cf_value)
CFDictionaryAddValue(dict, key, cf_value);
}
return dict;
}
break;
}
case base::Value::TYPE_LIST: {
const base::ListValue* list;
if (value.GetAsList(&list)) {
CFMutableArrayRef array =
CFArrayCreateMutable(NULL, list->GetSize(), &kCFTypeArrayCallBacks);
for (const auto& entry : *list) {
// CFArrayAppendValue() retains |cf_value|, so make sure the reference
// created by ValueToProperty() is released.
base::ScopedCFTypeRef<CFPropertyListRef> cf_value(
ValueToProperty(*entry));
if (cf_value)
CFArrayAppendValue(array, cf_value);
}
return array;
}
break;
}
case base::Value::TYPE_BINARY:
// This type isn't converted (though it can be represented as CFData)
// because there's no equivalent JSON type, and policy values can only
// take valid JSON values.
break;
}
return NULL;
}
#endif // defined(OS_IOS) || defined(OS_MACOSX)
} // namespace policy
std::ostream& operator<<(std::ostream& os,
const policy::PolicyBundle& bundle) {
os << "{" << std::endl;
for (policy::PolicyBundle::const_iterator iter = bundle.begin();
iter != bundle.end(); ++iter) {
os << " \"" << iter->first << "\": " << *iter->second << "," << std::endl;
}
os << "}";
return os;
}
std::ostream& operator<<(std::ostream& os, policy::PolicyScope scope) {
switch (scope) {
case policy::POLICY_SCOPE_USER: {
os << "POLICY_SCOPE_USER";
break;
}
case policy::POLICY_SCOPE_MACHINE: {
os << "POLICY_SCOPE_MACHINE";
break;
}
default: {
os << "POLICY_SCOPE_UNKNOWN(" << int(scope) << ")";
}
}
return os;
}
std::ostream& operator<<(std::ostream& os, policy::PolicyLevel level) {
switch (level) {
case policy::POLICY_LEVEL_RECOMMENDED: {
os << "POLICY_LEVEL_RECOMMENDED";
break;
}
case policy::POLICY_LEVEL_MANDATORY: {
os << "POLICY_LEVEL_MANDATORY";
break;
}
default: {
os << "POLICY_LEVEL_UNKNOWN(" << int(level) << ")";
}
}
return os;
}
std::ostream& operator<<(std::ostream& os, policy::PolicyDomain domain) {
switch (domain) {
case policy::POLICY_DOMAIN_CHROME: {
os << "POLICY_DOMAIN_CHROME";
break;
}
case policy::POLICY_DOMAIN_EXTENSIONS: {
os << "POLICY_DOMAIN_EXTENSIONS";
break;
}
default: {
os << "POLICY_DOMAIN_UNKNOWN(" << int(domain) << ")";
}
}
return os;
}
std::ostream& operator<<(std::ostream& os, const policy::PolicyMap& policies) {
os << "{" << std::endl;
for (policy::PolicyMap::const_iterator iter = policies.begin();
iter != policies.end(); ++iter) {
os << " \"" << iter->first << "\": " << iter->second << "," << std::endl;
}
os << "}";
return os;
}
std::ostream& operator<<(std::ostream& os, const policy::PolicyMap::Entry& e) {
std::string value;
base::JSONWriter::WriteWithOptions(
*e.value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &value);
os << "{" << std::endl
<< " \"level\": " << e.level << "," << std::endl
<< " \"scope\": " << e.scope << "," << std::endl
<< " \"value\": " << value
<< "}";
return os;
}
std::ostream& operator<<(std::ostream& os, const policy::PolicyNamespace& ns) {
os << ns.domain << "/" << ns.component_id;
return os;
}