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 "base/pickle.h" 6 #include "base/values.h" 7 #include "chrome/common/extensions/extension_messages.h" 8 #include "extensions/common/permissions/api_permission_set.h" 9 #include "extensions/common/permissions/permissions_info.h" 10 #include "ipc/ipc_message.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 namespace extensions { 14 15 TEST(APIPermissionSetTest, General) { 16 APIPermissionSet apis; 17 apis.insert(APIPermission::kTab); 18 apis.insert(APIPermission::kBackground); 19 apis.insert(APIPermission::kProxy); 20 apis.insert(APIPermission::kClipboardWrite); 21 apis.insert(APIPermission::kPlugin); 22 23 EXPECT_EQ(apis.find(APIPermission::kProxy)->id(), APIPermission::kProxy); 24 EXPECT_TRUE(apis.find(APIPermission::kSocket) == apis.end()); 25 26 EXPECT_EQ(apis.size(), 5u); 27 28 EXPECT_EQ(apis.erase(APIPermission::kTab), 1u); 29 EXPECT_EQ(apis.size(), 4u); 30 31 EXPECT_EQ(apis.erase(APIPermission::kTab), 0u); 32 EXPECT_EQ(apis.size(), 4u); 33 } 34 35 TEST(APIPermissionSetTest, CreateUnion) { 36 APIPermission* permission = NULL; 37 38 APIPermissionSet apis1; 39 APIPermissionSet apis2; 40 APIPermissionSet expected_apis; 41 APIPermissionSet result; 42 43 const APIPermissionInfo* permission_info = 44 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 45 permission = permission_info->CreateAPIPermission(); 46 { 47 scoped_ptr<base::ListValue> value(new base::ListValue()); 48 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 49 value->Append(new base::StringValue("udp-bind::8080")); 50 value->Append(new base::StringValue("udp-send-to::8888")); 51 if (!permission->FromValue(value.get())) { 52 NOTREACHED(); 53 } 54 } 55 56 // Union with an empty set. 57 apis1.insert(APIPermission::kTab); 58 apis1.insert(APIPermission::kBackground); 59 apis1.insert(permission->Clone()); 60 expected_apis.insert(APIPermission::kTab); 61 expected_apis.insert(APIPermission::kBackground); 62 expected_apis.insert(permission); 63 64 APIPermissionSet::Union(apis1, apis2, &result); 65 66 EXPECT_TRUE(apis1.Contains(apis2)); 67 EXPECT_TRUE(apis1.Contains(result)); 68 EXPECT_FALSE(apis2.Contains(apis1)); 69 EXPECT_FALSE(apis2.Contains(result)); 70 EXPECT_TRUE(result.Contains(apis1)); 71 EXPECT_TRUE(result.Contains(apis2)); 72 73 EXPECT_EQ(expected_apis, result); 74 75 // Now use a real second set. 76 apis2.insert(APIPermission::kTab); 77 apis2.insert(APIPermission::kProxy); 78 apis2.insert(APIPermission::kClipboardWrite); 79 apis2.insert(APIPermission::kPlugin); 80 81 permission = permission_info->CreateAPIPermission(); 82 { 83 scoped_ptr<base::ListValue> value(new base::ListValue()); 84 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 85 value->Append(new base::StringValue("udp-send-to::8899")); 86 if (!permission->FromValue(value.get())) { 87 NOTREACHED(); 88 } 89 } 90 apis2.insert(permission); 91 92 expected_apis.insert(APIPermission::kTab); 93 expected_apis.insert(APIPermission::kProxy); 94 expected_apis.insert(APIPermission::kClipboardWrite); 95 expected_apis.insert(APIPermission::kPlugin); 96 97 permission = permission_info->CreateAPIPermission(); 98 { 99 scoped_ptr<base::ListValue> value(new base::ListValue()); 100 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 101 value->Append(new base::StringValue("udp-bind::8080")); 102 value->Append(new base::StringValue("udp-send-to::8888")); 103 value->Append(new base::StringValue("udp-send-to::8899")); 104 if (!permission->FromValue(value.get())) { 105 NOTREACHED(); 106 } 107 } 108 // Insert a new socket permission which will replace the old one. 109 expected_apis.insert(permission); 110 111 APIPermissionSet::Union(apis1, apis2, &result); 112 113 EXPECT_FALSE(apis1.Contains(apis2)); 114 EXPECT_FALSE(apis1.Contains(result)); 115 EXPECT_FALSE(apis2.Contains(apis1)); 116 EXPECT_FALSE(apis2.Contains(result)); 117 EXPECT_TRUE(result.Contains(apis1)); 118 EXPECT_TRUE(result.Contains(apis2)); 119 120 EXPECT_EQ(expected_apis, result); 121 } 122 123 TEST(APIPermissionSetTest, CreateIntersection) { 124 APIPermission* permission = NULL; 125 126 APIPermissionSet apis1; 127 APIPermissionSet apis2; 128 APIPermissionSet expected_apis; 129 APIPermissionSet result; 130 131 const APIPermissionInfo* permission_info = 132 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 133 134 // Intersection with an empty set. 135 apis1.insert(APIPermission::kTab); 136 apis1.insert(APIPermission::kBackground); 137 permission = permission_info->CreateAPIPermission(); 138 { 139 scoped_ptr<base::ListValue> value(new base::ListValue()); 140 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 141 value->Append(new base::StringValue("udp-bind::8080")); 142 value->Append(new base::StringValue("udp-send-to::8888")); 143 if (!permission->FromValue(value.get())) { 144 NOTREACHED(); 145 } 146 } 147 apis1.insert(permission); 148 149 APIPermissionSet::Intersection(apis1, apis2, &result); 150 EXPECT_TRUE(apis1.Contains(result)); 151 EXPECT_TRUE(apis2.Contains(result)); 152 EXPECT_TRUE(apis1.Contains(apis2)); 153 EXPECT_FALSE(apis2.Contains(apis1)); 154 EXPECT_FALSE(result.Contains(apis1)); 155 EXPECT_TRUE(result.Contains(apis2)); 156 157 EXPECT_TRUE(result.empty()); 158 EXPECT_EQ(expected_apis, result); 159 160 // Now use a real second set. 161 apis2.insert(APIPermission::kTab); 162 apis2.insert(APIPermission::kProxy); 163 apis2.insert(APIPermission::kClipboardWrite); 164 apis2.insert(APIPermission::kPlugin); 165 permission = permission_info->CreateAPIPermission(); 166 { 167 scoped_ptr<base::ListValue> value(new base::ListValue()); 168 value->Append(new base::StringValue("udp-bind::8080")); 169 value->Append(new base::StringValue("udp-send-to::8888")); 170 value->Append(new base::StringValue("udp-send-to::8899")); 171 if (!permission->FromValue(value.get())) { 172 NOTREACHED(); 173 } 174 } 175 apis2.insert(permission); 176 177 expected_apis.insert(APIPermission::kTab); 178 permission = permission_info->CreateAPIPermission(); 179 { 180 scoped_ptr<base::ListValue> value(new base::ListValue()); 181 value->Append(new base::StringValue("udp-bind::8080")); 182 value->Append(new base::StringValue("udp-send-to::8888")); 183 if (!permission->FromValue(value.get())) { 184 NOTREACHED(); 185 } 186 } 187 expected_apis.insert(permission); 188 189 APIPermissionSet::Intersection(apis1, apis2, &result); 190 191 EXPECT_TRUE(apis1.Contains(result)); 192 EXPECT_TRUE(apis2.Contains(result)); 193 EXPECT_FALSE(apis1.Contains(apis2)); 194 EXPECT_FALSE(apis2.Contains(apis1)); 195 EXPECT_FALSE(result.Contains(apis1)); 196 EXPECT_FALSE(result.Contains(apis2)); 197 198 EXPECT_EQ(expected_apis, result); 199 } 200 201 TEST(APIPermissionSetTest, CreateDifference) { 202 APIPermission* permission = NULL; 203 204 APIPermissionSet apis1; 205 APIPermissionSet apis2; 206 APIPermissionSet expected_apis; 207 APIPermissionSet result; 208 209 const APIPermissionInfo* permission_info = 210 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 211 212 // Difference with an empty set. 213 apis1.insert(APIPermission::kTab); 214 apis1.insert(APIPermission::kBackground); 215 permission = permission_info->CreateAPIPermission(); 216 { 217 scoped_ptr<base::ListValue> value(new base::ListValue()); 218 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 219 value->Append(new base::StringValue("udp-bind::8080")); 220 value->Append(new base::StringValue("udp-send-to::8888")); 221 if (!permission->FromValue(value.get())) { 222 NOTREACHED(); 223 } 224 } 225 apis1.insert(permission); 226 227 APIPermissionSet::Difference(apis1, apis2, &result); 228 229 EXPECT_EQ(apis1, result); 230 231 // Now use a real second set. 232 apis2.insert(APIPermission::kTab); 233 apis2.insert(APIPermission::kProxy); 234 apis2.insert(APIPermission::kClipboardWrite); 235 apis2.insert(APIPermission::kPlugin); 236 permission = permission_info->CreateAPIPermission(); 237 { 238 scoped_ptr<base::ListValue> value(new base::ListValue()); 239 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 240 value->Append(new base::StringValue("udp-send-to::8899")); 241 if (!permission->FromValue(value.get())) { 242 NOTREACHED(); 243 } 244 } 245 apis2.insert(permission); 246 247 expected_apis.insert(APIPermission::kBackground); 248 permission = permission_info->CreateAPIPermission(); 249 { 250 scoped_ptr<base::ListValue> value(new base::ListValue()); 251 value->Append(new base::StringValue("udp-bind::8080")); 252 value->Append(new base::StringValue("udp-send-to::8888")); 253 if (!permission->FromValue(value.get())) { 254 NOTREACHED(); 255 } 256 } 257 expected_apis.insert(permission); 258 259 APIPermissionSet::Difference(apis1, apis2, &result); 260 261 EXPECT_TRUE(apis1.Contains(result)); 262 EXPECT_FALSE(apis2.Contains(result)); 263 264 EXPECT_EQ(expected_apis, result); 265 266 // |result| = |apis1| - |apis2| --> |result| intersect |apis2| == empty_set 267 APIPermissionSet result2; 268 APIPermissionSet::Intersection(result, apis2, &result2); 269 EXPECT_TRUE(result2.empty()); 270 } 271 272 TEST(APIPermissionSetTest, IPC) { 273 APIPermission* permission = NULL; 274 275 APIPermissionSet apis; 276 APIPermissionSet expected_apis; 277 278 const APIPermissionInfo* permission_info = 279 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 280 281 apis.insert(APIPermission::kTab); 282 apis.insert(APIPermission::kBackground); 283 permission = permission_info->CreateAPIPermission(); 284 { 285 scoped_ptr<base::ListValue> value(new base::ListValue()); 286 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 287 value->Append(new base::StringValue("udp-bind::8080")); 288 value->Append(new base::StringValue("udp-send-to::8888")); 289 if (!permission->FromValue(value.get())) { 290 NOTREACHED(); 291 } 292 } 293 apis.insert(permission); 294 295 EXPECT_NE(apis, expected_apis); 296 297 IPC::Message m; 298 WriteParam(&m, apis); 299 PickleIterator iter(m); 300 CHECK(ReadParam(&m, &iter, &expected_apis)); 301 EXPECT_EQ(apis, expected_apis); 302 } 303 304 TEST(APIPermissionSetTest, ImplicitPermissions) { 305 APIPermissionSet apis; 306 apis.insert(APIPermission::kFileSystemWrite); 307 apis.AddImpliedPermissions(); 308 309 EXPECT_EQ(apis.find(APIPermission::kFileSystemWrite)->id(), 310 APIPermission::kFileSystemWrite); 311 EXPECT_EQ(apis.size(), 1u); 312 313 apis.erase(APIPermission::kFileSystemWrite); 314 apis.insert(APIPermission::kFileSystemDirectory); 315 apis.AddImpliedPermissions(); 316 317 EXPECT_EQ(apis.find(APIPermission::kFileSystemDirectory)->id(), 318 APIPermission::kFileSystemDirectory); 319 EXPECT_EQ(apis.size(), 1u); 320 321 apis.insert(APIPermission::kFileSystemWrite); 322 apis.AddImpliedPermissions(); 323 324 EXPECT_EQ(apis.find(APIPermission::kFileSystemWrite)->id(), 325 APIPermission::kFileSystemWrite); 326 EXPECT_EQ(apis.find(APIPermission::kFileSystemDirectory)->id(), 327 APIPermission::kFileSystemDirectory); 328 EXPECT_EQ(apis.find(APIPermission::kFileSystemWriteDirectory)->id(), 329 APIPermission::kFileSystemWriteDirectory); 330 EXPECT_EQ(apis.size(), 3u); 331 } 332 333 } // namespace extensions 334