blob: fcf89f92de80c7582215cf69adf5d787707bf6a0 [file] [log] [blame]
joaodasilva@chromium.org3cfd7c62013-12-09 06:10:04 +09001// 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"
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090014#include "base/strings/sys_string_conversions.h"
joaodasilva@chromium.org3cfd7c62013-12-09 06:10:04 +090015#include "base/values.h"
avidc427ef2015-12-26 04:39:53 +090016#include "build/build_config.h"
joaodasilva@chromium.org3cfd7c62013-12-09 06:10:04 +090017#include "components/policy/core/common/policy_bundle.h"
18
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090019#if defined(OS_IOS) || defined(OS_MACOSX)
20#include <CoreFoundation/CoreFoundation.h>
21
22#include "base/mac/scoped_cftyperef.h"
23#endif
24
joaodasilva@chromium.org3cfd7c62013-12-09 06:10:04 +090025namespace policy {
26
27PolicyDetailsMap::PolicyDetailsMap() {}
28
29PolicyDetailsMap::~PolicyDetailsMap() {}
30
31GetChromePolicyDetailsCallback PolicyDetailsMap::GetCallback() const {
32 return base::Bind(&PolicyDetailsMap::Lookup, base::Unretained(this));
33}
34
35void PolicyDetailsMap::SetDetails(const std::string& policy,
36 const PolicyDetails* details) {
37 map_[policy] = details;
38}
39
40const PolicyDetails* PolicyDetailsMap::Lookup(const std::string& policy) const {
41 PolicyDetailsMapping::const_iterator it = map_.find(policy);
42 return it == map_.end() ? NULL : it->second;
43}
44
45bool PolicyServiceIsEmpty(const PolicyService* service) {
46 const PolicyMap& map = service->GetPolicies(
47 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
48 if (!map.empty()) {
49 base::DictionaryValue dict;
50 for (PolicyMap::const_iterator it = map.begin(); it != map.end(); ++it)
51 dict.SetWithoutPathExpansion(it->first, it->second.value->DeepCopy());
52 LOG(WARNING) << "There are pre-existing policies in this machine: " << dict;
53 }
54 return map.empty();
55}
56
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090057#if defined(OS_IOS) || defined(OS_MACOSX)
dcheng1fa44fb2016-05-26 03:30:47 +090058CFPropertyListRef ValueToProperty(const base::Value& value) {
59 switch (value.GetType()) {
jdoerrie89ee31a2016-12-08 00:43:28 +090060 case base::Value::Type::NONE:
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090061 return kCFNull;
62
jdoerrie89ee31a2016-12-08 00:43:28 +090063 case base::Value::Type::BOOLEAN: {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090064 bool bool_value;
dcheng1fa44fb2016-05-26 03:30:47 +090065 if (value.GetAsBoolean(&bool_value))
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090066 return bool_value ? kCFBooleanTrue : kCFBooleanFalse;
67 break;
68 }
69
jdoerrie89ee31a2016-12-08 00:43:28 +090070 case base::Value::Type::INTEGER: {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090071 int int_value;
dcheng1fa44fb2016-05-26 03:30:47 +090072 if (value.GetAsInteger(&int_value)) {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090073 return CFNumberCreate(
74 kCFAllocatorDefault, kCFNumberIntType, &int_value);
75 }
76 break;
77 }
78
jdoerrie89ee31a2016-12-08 00:43:28 +090079 case base::Value::Type::DOUBLE: {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090080 double double_value;
dcheng1fa44fb2016-05-26 03:30:47 +090081 if (value.GetAsDouble(&double_value)) {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090082 return CFNumberCreate(
83 kCFAllocatorDefault, kCFNumberDoubleType, &double_value);
84 }
85 break;
86 }
87
jdoerrie89ee31a2016-12-08 00:43:28 +090088 case base::Value::Type::STRING: {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090089 std::string string_value;
dcheng1fa44fb2016-05-26 03:30:47 +090090 if (value.GetAsString(&string_value))
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090091 return base::SysUTF8ToCFStringRef(string_value);
92 break;
93 }
94
jdoerrie89ee31a2016-12-08 00:43:28 +090095 case base::Value::Type::DICTIONARY: {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090096 const base::DictionaryValue* dict_value;
dcheng1fa44fb2016-05-26 03:30:47 +090097 if (value.GetAsDictionary(&dict_value)) {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +090098 // |dict| is owned by the caller.
99 CFMutableDictionaryRef dict =
100 CFDictionaryCreateMutable(kCFAllocatorDefault,
101 dict_value->size(),
102 &kCFTypeDictionaryKeyCallBacks,
103 &kCFTypeDictionaryValueCallBacks);
104 for (base::DictionaryValue::Iterator iterator(*dict_value);
105 !iterator.IsAtEnd(); iterator.Advance()) {
106 // CFDictionaryAddValue() retains both |key| and |value|, so make sure
107 // the references are balanced.
108 base::ScopedCFTypeRef<CFStringRef> key(
109 base::SysUTF8ToCFStringRef(iterator.key()));
110 base::ScopedCFTypeRef<CFPropertyListRef> cf_value(
dcheng1fa44fb2016-05-26 03:30:47 +0900111 ValueToProperty(iterator.value()));
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +0900112 if (cf_value)
113 CFDictionaryAddValue(dict, key, cf_value);
114 }
115 return dict;
116 }
117 break;
118 }
119
jdoerrie89ee31a2016-12-08 00:43:28 +0900120 case base::Value::Type::LIST: {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +0900121 const base::ListValue* list;
dcheng1fa44fb2016-05-26 03:30:47 +0900122 if (value.GetAsList(&list)) {
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +0900123 CFMutableArrayRef array =
124 CFArrayCreateMutable(NULL, list->GetSize(), &kCFTypeArrayCallBacks);
dcheng1fa44fb2016-05-26 03:30:47 +0900125 for (const auto& entry : *list) {
126 // CFArrayAppendValue() retains |cf_value|, so make sure the reference
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +0900127 // created by ValueToProperty() is released.
128 base::ScopedCFTypeRef<CFPropertyListRef> cf_value(
jdoerrie45184002017-04-12 03:09:14 +0900129 ValueToProperty(entry));
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +0900130 if (cf_value)
131 CFArrayAppendValue(array, cf_value);
132 }
133 return array;
134 }
135 break;
136 }
137
jdoerrie89ee31a2016-12-08 00:43:28 +0900138 case base::Value::Type::BINARY:
joaodasilva@chromium.org83911e52014-03-05 16:05:57 +0900139 // 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
joaodasilva@chromium.org3cfd7c62013-12-09 06:10:04 +0900149} // 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 }
emaxxe3b915d2016-11-01 07:34:17 +0900206 case policy::POLICY_DOMAIN_SIGNIN_EXTENSIONS: {
207 os << "POLICY_DOMAIN_SIGNIN_EXTENSIONS";
208 break;
209 }
joaodasilva@chromium.org3cfd7c62013-12-09 06:10:04 +0900210 default: {
211 os << "POLICY_DOMAIN_UNKNOWN(" << int(domain) << ")";
212 }
213 }
214 return os;
215}
216
217std::ostream& operator<<(std::ostream& os, const policy::PolicyMap& policies) {
218 os << "{" << std::endl;
219 for (policy::PolicyMap::const_iterator iter = policies.begin();
220 iter != policies.end(); ++iter) {
221 os << " \"" << iter->first << "\": " << iter->second << "," << std::endl;
222 }
223 os << "}";
224 return os;
225}
226
227std::ostream& operator<<(std::ostream& os, const policy::PolicyMap::Entry& e) {
228 std::string value;
estadeb5f30dd2015-05-16 10:02:34 +0900229 base::JSONWriter::WriteWithOptions(
230 *e.value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &value);
joaodasilva@chromium.org3cfd7c62013-12-09 06:10:04 +0900231 os << "{" << std::endl
232 << " \"level\": " << e.level << "," << std::endl
233 << " \"scope\": " << e.scope << "," << std::endl
234 << " \"value\": " << value
235 << "}";
236 return os;
237}
238
239std::ostream& operator<<(std::ostream& os, const policy::PolicyNamespace& ns) {
240 os << ns.domain << "/" << ns.component_id;
241 return os;
242}