joaodasilva@chromium.org | 3cfd7c6 | 2013-12-09 06:10:04 +0900 | [diff] [blame] | 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" |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 14 | #include "base/strings/sys_string_conversions.h" |
joaodasilva@chromium.org | 3cfd7c6 | 2013-12-09 06:10:04 +0900 | [diff] [blame] | 15 | #include "base/values.h" |
avi | dc427ef | 2015-12-26 04:39:53 +0900 | [diff] [blame] | 16 | #include "build/build_config.h" |
joaodasilva@chromium.org | 3cfd7c6 | 2013-12-09 06:10:04 +0900 | [diff] [blame] | 17 | #include "components/policy/core/common/policy_bundle.h" |
| 18 | |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 19 | #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.org | 3cfd7c6 | 2013-12-09 06:10:04 +0900 | [diff] [blame] | 25 | namespace policy { |
| 26 | |
| 27 | PolicyDetailsMap::PolicyDetailsMap() {} |
| 28 | |
| 29 | PolicyDetailsMap::~PolicyDetailsMap() {} |
| 30 | |
| 31 | GetChromePolicyDetailsCallback PolicyDetailsMap::GetCallback() const { |
| 32 | return base::Bind(&PolicyDetailsMap::Lookup, base::Unretained(this)); |
| 33 | } |
| 34 | |
| 35 | void PolicyDetailsMap::SetDetails(const std::string& policy, |
| 36 | const PolicyDetails* details) { |
| 37 | map_[policy] = details; |
| 38 | } |
| 39 | |
| 40 | const 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 | |
| 45 | bool 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.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 57 | #if defined(OS_IOS) || defined(OS_MACOSX) |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 58 | CFPropertyListRef ValueToProperty(const base::Value& value) { |
| 59 | switch (value.GetType()) { |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 60 | case base::Value::Type::NONE: |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 61 | return kCFNull; |
| 62 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 63 | case base::Value::Type::BOOLEAN: { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 64 | bool bool_value; |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 65 | if (value.GetAsBoolean(&bool_value)) |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 66 | return bool_value ? kCFBooleanTrue : kCFBooleanFalse; |
| 67 | break; |
| 68 | } |
| 69 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 70 | case base::Value::Type::INTEGER: { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 71 | int int_value; |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 72 | if (value.GetAsInteger(&int_value)) { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 73 | return CFNumberCreate( |
| 74 | kCFAllocatorDefault, kCFNumberIntType, &int_value); |
| 75 | } |
| 76 | break; |
| 77 | } |
| 78 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 79 | case base::Value::Type::DOUBLE: { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 80 | double double_value; |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 81 | if (value.GetAsDouble(&double_value)) { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 82 | return CFNumberCreate( |
| 83 | kCFAllocatorDefault, kCFNumberDoubleType, &double_value); |
| 84 | } |
| 85 | break; |
| 86 | } |
| 87 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 88 | case base::Value::Type::STRING: { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 89 | std::string string_value; |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 90 | if (value.GetAsString(&string_value)) |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 91 | return base::SysUTF8ToCFStringRef(string_value); |
| 92 | break; |
| 93 | } |
| 94 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 95 | case base::Value::Type::DICTIONARY: { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 96 | const base::DictionaryValue* dict_value; |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 97 | if (value.GetAsDictionary(&dict_value)) { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 98 | // |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( |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 111 | ValueToProperty(iterator.value())); |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 112 | if (cf_value) |
| 113 | CFDictionaryAddValue(dict, key, cf_value); |
| 114 | } |
| 115 | return dict; |
| 116 | } |
| 117 | break; |
| 118 | } |
| 119 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 120 | case base::Value::Type::LIST: { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 121 | const base::ListValue* list; |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 122 | if (value.GetAsList(&list)) { |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 123 | CFMutableArrayRef array = |
| 124 | CFArrayCreateMutable(NULL, list->GetSize(), &kCFTypeArrayCallBacks); |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 125 | for (const auto& entry : *list) { |
| 126 | // CFArrayAppendValue() retains |cf_value|, so make sure the reference |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 127 | // created by ValueToProperty() is released. |
| 128 | base::ScopedCFTypeRef<CFPropertyListRef> cf_value( |
jdoerrie | 4518400 | 2017-04-12 03:09:14 +0900 | [diff] [blame^] | 129 | ValueToProperty(entry)); |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 130 | if (cf_value) |
| 131 | CFArrayAppendValue(array, cf_value); |
| 132 | } |
| 133 | return array; |
| 134 | } |
| 135 | break; |
| 136 | } |
| 137 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 138 | case base::Value::Type::BINARY: |
joaodasilva@chromium.org | 83911e5 | 2014-03-05 16:05:57 +0900 | [diff] [blame] | 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 | |
joaodasilva@chromium.org | 3cfd7c6 | 2013-12-09 06:10:04 +0900 | [diff] [blame] | 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 | } |
emaxx | e3b915d | 2016-11-01 07:34:17 +0900 | [diff] [blame] | 206 | case policy::POLICY_DOMAIN_SIGNIN_EXTENSIONS: { |
| 207 | os << "POLICY_DOMAIN_SIGNIN_EXTENSIONS"; |
| 208 | break; |
| 209 | } |
joaodasilva@chromium.org | 3cfd7c6 | 2013-12-09 06:10:04 +0900 | [diff] [blame] | 210 | default: { |
| 211 | os << "POLICY_DOMAIN_UNKNOWN(" << int(domain) << ")"; |
| 212 | } |
| 213 | } |
| 214 | return os; |
| 215 | } |
| 216 | |
| 217 | std::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 | |
| 227 | std::ostream& operator<<(std::ostream& os, const policy::PolicyMap::Entry& e) { |
| 228 | std::string value; |
estade | b5f30dd | 2015-05-16 10:02:34 +0900 | [diff] [blame] | 229 | base::JSONWriter::WriteWithOptions( |
| 230 | *e.value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &value); |
joaodasilva@chromium.org | 3cfd7c6 | 2013-12-09 06:10:04 +0900 | [diff] [blame] | 231 | os << "{" << std::endl |
| 232 | << " \"level\": " << e.level << "," << std::endl |
| 233 | << " \"scope\": " << e.scope << "," << std::endl |
| 234 | << " \"value\": " << value |
| 235 | << "}"; |
| 236 | return os; |
| 237 | } |
| 238 | |
| 239 | std::ostream& operator<<(std::ostream& os, const policy::PolicyNamespace& ns) { |
| 240 | os << ns.domain << "/" << ns.component_id; |
| 241 | return os; |
| 242 | } |