permission_set_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2012 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/command_line.h" 6#include "base/json/json_file_value_serializer.h" 7#include "base/logging.h" 8#include "base/path_service.h" 9#include "base/utf_string_conversions.h" 10#include "chrome/common/chrome_paths.h" 11#include "chrome/common/chrome_switches.h" 12#include "chrome/common/extensions/extension.h" 13#include "chrome/common/extensions/extension_test_util.h" 14#include "chrome/common/extensions/features/feature.h" 15#include "chrome/common/extensions/permissions/permission_set.h" 16#include "chrome/common/extensions/permissions/permissions_data.h" 17#include "chrome/common/extensions/permissions/permissions_info.h" 18#include "chrome/common/extensions/permissions/socket_permission.h" 19#include "extensions/common/error_utils.h" 20#include "testing/gtest/include/gtest/gtest.h" 21 22using extension_test_util::LoadManifest; 23 24namespace extensions { 25 26namespace { 27 28static void AddPattern(URLPatternSet* extent, const std::string& pattern) { 29 int schemes = URLPattern::SCHEME_ALL; 30 extent->AddPattern(URLPattern(schemes, pattern)); 31} 32 33size_t IndexOf(const std::vector<string16>& warnings, 34 const std::string& warning) { 35 for (size_t i = 0; i < warnings.size(); ++i) { 36 if (warnings[i] == ASCIIToUTF16(warning)) 37 return i; 38 } 39 40 return warnings.size(); 41} 42 43bool Contains(const std::vector<string16>& warnings, 44 const std::string& warning) { 45 return IndexOf(warnings, warning) != warnings.size(); 46} 47 48} // namespace 49 50// Tests GetByID. 51TEST(PermissionsTest, GetByID) { 52 PermissionsInfo* info = PermissionsInfo::GetInstance(); 53 APIPermissionSet apis = info->GetAll(); 54 for (APIPermissionSet::const_iterator i = apis.begin(); 55 i != apis.end(); ++i) { 56 EXPECT_EQ(i->id(), i->info()->id()); 57 } 58} 59 60// Tests that GetByName works with normal permission names and aliases. 61TEST(PermissionsTest, GetByName) { 62 PermissionsInfo* info = PermissionsInfo::GetInstance(); 63 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id()); 64 EXPECT_EQ(APIPermission::kManagement, 65 info->GetByName("management")->id()); 66 EXPECT_FALSE(info->GetByName("alsdkfjasldkfj")); 67} 68 69TEST(PermissionsTest, GetAll) { 70 size_t count = 0; 71 PermissionsInfo* info = PermissionsInfo::GetInstance(); 72 APIPermissionSet apis = info->GetAll(); 73 for (APIPermissionSet::const_iterator api = apis.begin(); 74 api != apis.end(); ++api) { 75 // Make sure only the valid permission IDs get returned. 76 EXPECT_NE(APIPermission::kInvalid, api->id()); 77 EXPECT_NE(APIPermission::kUnknown, api->id()); 78 count++; 79 } 80 EXPECT_EQ(count, info->get_permission_count()); 81} 82 83TEST(PermissionsTest, GetAllByName) { 84 std::set<std::string> names; 85 names.insert("background"); 86 names.insert("management"); 87 88 // This is an alias of kTab 89 names.insert("windows"); 90 91 // This unknown name should get dropped. 92 names.insert("sdlkfjasdlkfj"); 93 94 APIPermissionSet expected; 95 expected.insert(APIPermission::kBackground); 96 expected.insert(APIPermission::kManagement); 97 expected.insert(APIPermission::kTab); 98 99 EXPECT_EQ(expected, 100 PermissionsInfo::GetInstance()->GetAllByName(names)); 101} 102 103// Tests that the aliases are properly mapped. 104TEST(PermissionsTest, Aliases) { 105 PermissionsInfo* info = PermissionsInfo::GetInstance(); 106 // tabs: tabs, windows 107 std::string tabs_name = "tabs"; 108 EXPECT_EQ(tabs_name, info->GetByID(APIPermission::kTab)->name()); 109 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id()); 110 EXPECT_EQ(APIPermission::kTab, info->GetByName("windows")->id()); 111 112 // unlimitedStorage: unlimitedStorage, unlimited_storage 113 std::string storage_name = "unlimitedStorage"; 114 EXPECT_EQ(storage_name, info->GetByID( 115 APIPermission::kUnlimitedStorage)->name()); 116 EXPECT_EQ(APIPermission::kUnlimitedStorage, 117 info->GetByName("unlimitedStorage")->id()); 118 EXPECT_EQ(APIPermission::kUnlimitedStorage, 119 info->GetByName("unlimited_storage")->id()); 120} 121 122TEST(PermissionsTest, EffectiveHostPermissions) { 123 scoped_refptr<Extension> extension; 124 scoped_refptr<const PermissionSet> permissions; 125 126 extension = LoadManifest("effective_host_permissions", "empty.json"); 127 permissions = extension->GetActivePermissions(); 128 EXPECT_EQ( 129 0u, 130 PermissionsData::GetEffectiveHostPermissions( 131 extension).patterns().size()); 132 EXPECT_FALSE(permissions->HasEffectiveAccessToURL( 133 GURL("http://www.google.com"))); 134 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 135 136 extension = LoadManifest("effective_host_permissions", "one_host.json"); 137 permissions = extension->GetActivePermissions(); 138 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 139 GURL("http://www.google.com"))); 140 EXPECT_FALSE(permissions->HasEffectiveAccessToURL( 141 GURL("https://www.google.com"))); 142 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 143 144 extension = LoadManifest("effective_host_permissions", 145 "one_host_wildcard.json"); 146 permissions = extension->GetActivePermissions(); 147 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 148 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 149 GURL("http://foo.google.com"))); 150 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 151 152 extension = LoadManifest("effective_host_permissions", "two_hosts.json"); 153 permissions = extension->GetActivePermissions(); 154 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 155 GURL("http://www.google.com"))); 156 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 157 GURL("http://www.reddit.com"))); 158 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 159 160 extension = LoadManifest("effective_host_permissions", 161 "https_not_considered.json"); 162 permissions = extension->GetActivePermissions(); 163 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 164 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://google.com"))); 165 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 166 167 extension = LoadManifest("effective_host_permissions", 168 "two_content_scripts.json"); 169 permissions = extension->GetActivePermissions(); 170 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 171 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 172 GURL("http://www.reddit.com"))); 173 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 174 GURL("http://news.ycombinator.com"))); 175 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 176 177 extension = LoadManifest("effective_host_permissions", "all_hosts.json"); 178 permissions = extension->GetActivePermissions(); 179 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 180 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("https://test/"))); 181 EXPECT_TRUE( 182 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 183 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 184 185 extension = LoadManifest("effective_host_permissions", "all_hosts2.json"); 186 permissions = extension->GetActivePermissions(); 187 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 188 EXPECT_TRUE( 189 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 190 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 191 192 extension = LoadManifest("effective_host_permissions", "all_hosts3.json"); 193 permissions = extension->GetActivePermissions(); 194 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 195 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://test/"))); 196 EXPECT_TRUE( 197 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 198 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 199} 200 201TEST(PermissionsTest, ExplicitAccessToOrigin) { 202 APIPermissionSet apis; 203 URLPatternSet explicit_hosts; 204 URLPatternSet scriptable_hosts; 205 206 AddPattern(&explicit_hosts, "http://*.google.com/*"); 207 // The explicit host paths should get set to /*. 208 AddPattern(&explicit_hosts, "http://www.example.com/a/particular/path/*"); 209 210 scoped_refptr<PermissionSet> perm_set = new PermissionSet( 211 apis, explicit_hosts, scriptable_hosts); 212 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 213 GURL("http://www.google.com/"))); 214 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 215 GURL("http://test.google.com/"))); 216 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 217 GURL("http://www.example.com"))); 218 ASSERT_TRUE(perm_set->HasEffectiveAccessToURL( 219 GURL("http://www.example.com"))); 220 ASSERT_FALSE(perm_set->HasExplicitAccessToOrigin( 221 GURL("http://test.example.com"))); 222} 223 224TEST(PermissionsTest, CreateUnion) { 225 APIPermission* permission = NULL; 226 227 APIPermissionSet apis1; 228 APIPermissionSet apis2; 229 APIPermissionSet expected_apis; 230 231 URLPatternSet explicit_hosts1; 232 URLPatternSet explicit_hosts2; 233 URLPatternSet expected_explicit_hosts; 234 235 URLPatternSet scriptable_hosts1; 236 URLPatternSet scriptable_hosts2; 237 URLPatternSet expected_scriptable_hosts; 238 239 URLPatternSet effective_hosts; 240 241 scoped_refptr<PermissionSet> set1; 242 scoped_refptr<PermissionSet> set2; 243 scoped_refptr<PermissionSet> union_set; 244 245 const APIPermissionInfo* permission_info = 246 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 247 permission = permission_info->CreateAPIPermission(); 248 { 249 scoped_ptr<ListValue> value(new ListValue()); 250 value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80")); 251 value->Append(Value::CreateStringValue("udp-bind::8080")); 252 value->Append(Value::CreateStringValue("udp-send-to::8888")); 253 if (!permission->FromValue(value.get())) { 254 NOTREACHED(); 255 } 256 } 257 258 // Union with an empty set. 259 apis1.insert(APIPermission::kTab); 260 apis1.insert(APIPermission::kBackground); 261 apis1.insert(permission->Clone()); 262 expected_apis.insert(APIPermission::kTab); 263 expected_apis.insert(APIPermission::kBackground); 264 expected_apis.insert(permission); 265 266 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 267 AddPattern(&expected_explicit_hosts, "http://*.google.com/*"); 268 AddPattern(&effective_hosts, "http://*.google.com/*"); 269 270 set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1); 271 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 272 union_set = PermissionSet::CreateUnion(set1.get(), set2.get()); 273 EXPECT_TRUE(set1->Contains(*set2)); 274 EXPECT_TRUE(set1->Contains(*union_set)); 275 EXPECT_FALSE(set2->Contains(*set1)); 276 EXPECT_FALSE(set2->Contains(*union_set)); 277 EXPECT_TRUE(union_set->Contains(*set1)); 278 EXPECT_TRUE(union_set->Contains(*set2)); 279 280 EXPECT_FALSE(union_set->HasEffectiveFullAccess()); 281 EXPECT_EQ(expected_apis, union_set->apis()); 282 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts()); 283 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts()); 284 EXPECT_EQ(expected_explicit_hosts, union_set->effective_hosts()); 285 286 // Now use a real second set. 287 apis2.insert(APIPermission::kTab); 288 apis2.insert(APIPermission::kProxy); 289 apis2.insert(APIPermission::kClipboardWrite); 290 apis2.insert(APIPermission::kPlugin); 291 292 permission = permission_info->CreateAPIPermission(); 293 { 294 scoped_ptr<ListValue> value(new ListValue()); 295 value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80")); 296 value->Append(Value::CreateStringValue("udp-send-to::8899")); 297 if (!permission->FromValue(value.get())) { 298 NOTREACHED(); 299 } 300 } 301 apis2.insert(permission); 302 303 expected_apis.insert(APIPermission::kTab); 304 expected_apis.insert(APIPermission::kProxy); 305 expected_apis.insert(APIPermission::kClipboardWrite); 306 expected_apis.insert(APIPermission::kPlugin); 307 308 permission = permission_info->CreateAPIPermission(); 309 { 310 scoped_ptr<ListValue> value(new ListValue()); 311 value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80")); 312 value->Append(Value::CreateStringValue("udp-bind::8080")); 313 value->Append(Value::CreateStringValue("udp-send-to::8888")); 314 value->Append(Value::CreateStringValue("udp-send-to::8899")); 315 if (!permission->FromValue(value.get())) { 316 NOTREACHED(); 317 } 318 } 319 // Insert a new permission socket permisssion which will replace the old one. 320 expected_apis.insert(permission); 321 322 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 323 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 324 AddPattern(&expected_explicit_hosts, "http://*.example.com/*"); 325 AddPattern(&expected_scriptable_hosts, "http://*.google.com/*"); 326 327 URLPatternSet::CreateUnion( 328 explicit_hosts2, scriptable_hosts2, &effective_hosts); 329 330 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 331 union_set = PermissionSet::CreateUnion(set1.get(), set2.get()); 332 333 EXPECT_FALSE(set1->Contains(*set2)); 334 EXPECT_FALSE(set1->Contains(*union_set)); 335 EXPECT_FALSE(set2->Contains(*set1)); 336 EXPECT_FALSE(set2->Contains(*union_set)); 337 EXPECT_TRUE(union_set->Contains(*set1)); 338 EXPECT_TRUE(union_set->Contains(*set2)); 339 340 EXPECT_TRUE(union_set->HasEffectiveFullAccess()); 341 EXPECT_TRUE(union_set->HasEffectiveAccessToAllHosts()); 342 EXPECT_EQ(expected_apis, union_set->apis()); 343 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts()); 344 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts()); 345 EXPECT_EQ(effective_hosts, union_set->effective_hosts()); 346} 347 348TEST(PermissionsTest, CreateIntersection) { 349 APIPermission* permission = NULL; 350 351 APIPermissionSet apis1; 352 APIPermissionSet apis2; 353 APIPermissionSet expected_apis; 354 355 URLPatternSet explicit_hosts1; 356 URLPatternSet explicit_hosts2; 357 URLPatternSet expected_explicit_hosts; 358 359 URLPatternSet scriptable_hosts1; 360 URLPatternSet scriptable_hosts2; 361 URLPatternSet expected_scriptable_hosts; 362 363 URLPatternSet effective_hosts; 364 365 scoped_refptr<PermissionSet> set1; 366 scoped_refptr<PermissionSet> set2; 367 scoped_refptr<PermissionSet> new_set; 368 369 const APIPermissionInfo* permission_info = 370 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 371 372 // Intersection with an empty set. 373 apis1.insert(APIPermission::kTab); 374 apis1.insert(APIPermission::kBackground); 375 permission = permission_info->CreateAPIPermission(); 376 { 377 scoped_ptr<ListValue> value(new ListValue()); 378 value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80")); 379 value->Append(Value::CreateStringValue("udp-bind::8080")); 380 value->Append(Value::CreateStringValue("udp-send-to::8888")); 381 if (!permission->FromValue(value.get())) { 382 NOTREACHED(); 383 } 384 } 385 apis1.insert(permission); 386 387 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 388 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*"); 389 390 set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1); 391 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 392 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get()); 393 EXPECT_TRUE(set1->Contains(*new_set)); 394 EXPECT_TRUE(set2->Contains(*new_set)); 395 EXPECT_TRUE(set1->Contains(*set2)); 396 EXPECT_FALSE(set2->Contains(*set1)); 397 EXPECT_FALSE(new_set->Contains(*set1)); 398 EXPECT_TRUE(new_set->Contains(*set2)); 399 400 EXPECT_TRUE(new_set->IsEmpty()); 401 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 402 EXPECT_EQ(expected_apis, new_set->apis()); 403 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 404 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 405 EXPECT_EQ(expected_explicit_hosts, new_set->effective_hosts()); 406 407 // Now use a real second set. 408 apis2.insert(APIPermission::kTab); 409 apis2.insert(APIPermission::kProxy); 410 apis2.insert(APIPermission::kClipboardWrite); 411 apis2.insert(APIPermission::kPlugin); 412 permission = permission_info->CreateAPIPermission(); 413 { 414 scoped_ptr<ListValue> value(new ListValue()); 415 value->Append(Value::CreateStringValue("udp-bind::8080")); 416 value->Append(Value::CreateStringValue("udp-send-to::8888")); 417 value->Append(Value::CreateStringValue("udp-send-to::8899")); 418 if (!permission->FromValue(value.get())) { 419 NOTREACHED(); 420 } 421 } 422 apis2.insert(permission); 423 424 expected_apis.insert(APIPermission::kTab); 425 permission = permission_info->CreateAPIPermission(); 426 { 427 scoped_ptr<ListValue> value(new ListValue()); 428 value->Append(Value::CreateStringValue("udp-bind::8080")); 429 value->Append(Value::CreateStringValue("udp-send-to::8888")); 430 if (!permission->FromValue(value.get())) { 431 NOTREACHED(); 432 } 433 } 434 expected_apis.insert(permission); 435 436 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 437 AddPattern(&explicit_hosts2, "http://*.google.com/*"); 438 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 439 AddPattern(&expected_explicit_hosts, "http://*.google.com/*"); 440 441 effective_hosts.ClearPatterns(); 442 AddPattern(&effective_hosts, "http://*.google.com/*"); 443 444 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 445 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get()); 446 447 EXPECT_TRUE(set1->Contains(*new_set)); 448 EXPECT_TRUE(set2->Contains(*new_set)); 449 EXPECT_FALSE(set1->Contains(*set2)); 450 EXPECT_FALSE(set2->Contains(*set1)); 451 EXPECT_FALSE(new_set->Contains(*set1)); 452 EXPECT_FALSE(new_set->Contains(*set2)); 453 454 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 455 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts()); 456 EXPECT_EQ(expected_apis, new_set->apis()); 457 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 458 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 459 EXPECT_EQ(effective_hosts, new_set->effective_hosts()); 460} 461 462TEST(PermissionsTest, CreateDifference) { 463 APIPermission* permission = NULL; 464 465 APIPermissionSet apis1; 466 APIPermissionSet apis2; 467 APIPermissionSet expected_apis; 468 469 URLPatternSet explicit_hosts1; 470 URLPatternSet explicit_hosts2; 471 URLPatternSet expected_explicit_hosts; 472 473 URLPatternSet scriptable_hosts1; 474 URLPatternSet scriptable_hosts2; 475 URLPatternSet expected_scriptable_hosts; 476 477 URLPatternSet effective_hosts; 478 479 scoped_refptr<PermissionSet> set1; 480 scoped_refptr<PermissionSet> set2; 481 scoped_refptr<PermissionSet> new_set; 482 483 const APIPermissionInfo* permission_info = 484 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 485 486 // Difference with an empty set. 487 apis1.insert(APIPermission::kTab); 488 apis1.insert(APIPermission::kBackground); 489 permission = permission_info->CreateAPIPermission(); 490 { 491 scoped_ptr<ListValue> value(new ListValue()); 492 value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80")); 493 value->Append(Value::CreateStringValue("udp-bind::8080")); 494 value->Append(Value::CreateStringValue("udp-send-to::8888")); 495 if (!permission->FromValue(value.get())) { 496 NOTREACHED(); 497 } 498 } 499 apis1.insert(permission); 500 501 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 502 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*"); 503 504 set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1); 505 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 506 new_set = PermissionSet::CreateDifference(set1.get(), set2.get()); 507 EXPECT_EQ(*set1, *new_set); 508 509 // Now use a real second set. 510 apis2.insert(APIPermission::kTab); 511 apis2.insert(APIPermission::kProxy); 512 apis2.insert(APIPermission::kClipboardWrite); 513 apis2.insert(APIPermission::kPlugin); 514 permission = permission_info->CreateAPIPermission(); 515 { 516 scoped_ptr<ListValue> value(new ListValue()); 517 value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80")); 518 value->Append(Value::CreateStringValue("udp-send-to::8899")); 519 if (!permission->FromValue(value.get())) { 520 NOTREACHED(); 521 } 522 } 523 apis2.insert(permission); 524 525 expected_apis.insert(APIPermission::kBackground); 526 permission = permission_info->CreateAPIPermission(); 527 { 528 scoped_ptr<ListValue> value(new ListValue()); 529 value->Append(Value::CreateStringValue("udp-bind::8080")); 530 value->Append(Value::CreateStringValue("udp-send-to::8888")); 531 if (!permission->FromValue(value.get())) { 532 NOTREACHED(); 533 } 534 } 535 expected_apis.insert(permission); 536 537 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 538 AddPattern(&explicit_hosts2, "http://*.google.com/*"); 539 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 540 AddPattern(&expected_scriptable_hosts, "http://www.reddit.com/*"); 541 542 effective_hosts.ClearPatterns(); 543 AddPattern(&effective_hosts, "http://www.reddit.com/*"); 544 545 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 546 new_set = PermissionSet::CreateDifference(set1.get(), set2.get()); 547 548 EXPECT_TRUE(set1->Contains(*new_set)); 549 EXPECT_FALSE(set2->Contains(*new_set)); 550 551 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 552 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts()); 553 EXPECT_EQ(expected_apis, new_set->apis()); 554 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 555 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 556 EXPECT_EQ(effective_hosts, new_set->effective_hosts()); 557 558 // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set 559 set1 = PermissionSet::CreateIntersection(new_set.get(), set2.get()); 560 EXPECT_TRUE(set1->IsEmpty()); 561} 562 563TEST(PermissionsTest, HasLessPrivilegesThan) { 564 const struct { 565 const char* base_name; 566 bool expect_increase; 567 } kTests[] = { 568 { "allhosts1", false }, // all -> all 569 { "allhosts2", false }, // all -> one 570 { "allhosts3", true }, // one -> all 571 { "hosts1", false }, // http://a,http://b -> http://a,http://b 572 { "hosts2", true }, // http://a,http://b -> https://a,http://*.b 573 { "hosts3", false }, // http://a,http://b -> http://a 574 { "hosts4", true }, // http://a -> http://a,http://b 575 { "hosts5", false }, // http://a,b,c -> http://a,b,c + https://a,b,c 576 { "hosts6", false }, // http://a.com -> http://a.com + http://a.co.uk 577 { "permissions1", false }, // tabs -> tabs 578 { "permissions2", true }, // tabs -> tabs,bookmarks 579 { "permissions3", true }, // http://a -> http://a,tabs 580 { "permissions5", true }, // bookmarks -> bookmarks,history 581 { "equivalent_warnings", false }, // tabs --> tabs, webNavigation 582#if !defined(OS_CHROMEOS) // plugins aren't allowed in ChromeOS 583 { "permissions4", false }, // plugin -> plugin,tabs 584 { "plugin1", false }, // plugin -> plugin 585 { "plugin2", false }, // plugin -> none 586 { "plugin3", true }, // none -> plugin 587#endif 588 { "storage", false }, // none -> storage 589 { "notifications", false }, // none -> notifications 590 }; 591 592 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { 593 scoped_refptr<Extension> old_extension( 594 LoadManifest("allow_silent_upgrade", 595 std::string(kTests[i].base_name) + "_old.json")); 596 scoped_refptr<Extension> new_extension( 597 LoadManifest("allow_silent_upgrade", 598 std::string(kTests[i].base_name) + "_new.json")); 599 600 EXPECT_TRUE(new_extension.get()) << kTests[i].base_name << "_new.json"; 601 if (!new_extension.get()) 602 continue; 603 604 scoped_refptr<const PermissionSet> old_p( 605 old_extension->GetActivePermissions()); 606 scoped_refptr<const PermissionSet> new_p( 607 new_extension->GetActivePermissions()); 608 609 EXPECT_EQ(kTests[i].expect_increase, 610 old_p->HasLessPrivilegesThan(new_p)) << kTests[i].base_name; 611 } 612} 613 614TEST(PermissionsTest, PermissionMessages) { 615 // Ensure that all permissions that needs to show install UI actually have 616 // strings associated with them. 617 APIPermissionSet skip; 618 619 // These are considered "nuisance" or "trivial" permissions that don't need 620 // a prompt. 621 skip.insert(APIPermission::kActiveTab); 622 skip.insert(APIPermission::kAdView); 623 skip.insert(APIPermission::kAlarms); 624 skip.insert(APIPermission::kAppCurrentWindowInternal); 625 skip.insert(APIPermission::kAppRuntime); 626 skip.insert(APIPermission::kAppWindow); 627 skip.insert(APIPermission::kAudio); 628 skip.insert(APIPermission::kBrowsingData); 629 skip.insert(APIPermission::kContextMenus); 630 skip.insert(APIPermission::kFontSettings); 631 skip.insert(APIPermission::kFullscreen); 632 skip.insert(APIPermission::kIdle); 633 skip.insert(APIPermission::kNotification); 634 skip.insert(APIPermission::kPointerLock); 635 skip.insert(APIPermission::kPower); 636 skip.insert(APIPermission::kPushMessaging); 637 skip.insert(APIPermission::kSessionRestore); 638 skip.insert(APIPermission::kScreensaver); 639 skip.insert(APIPermission::kStorage); 640 skip.insert(APIPermission::kSystemInfoDisplay); 641 skip.insert(APIPermission::kTts); 642 skip.insert(APIPermission::kUnlimitedStorage); 643 skip.insert(APIPermission::kWebView); 644 645 // TODO(erikkay) add a string for this permission. 646 skip.insert(APIPermission::kBackground); 647 648 skip.insert(APIPermission::kClipboardWrite); 649 650 // The cookie permission does nothing unless you have associated host 651 // permissions. 652 skip.insert(APIPermission::kCookie); 653 654 // These are warned as part of host permission checks. 655 skip.insert(APIPermission::kDeclarativeContent); 656 skip.insert(APIPermission::kDeclarativeWebRequest); 657 skip.insert(APIPermission::kNativeMessaging); 658 skip.insert(APIPermission::kPageCapture); 659 skip.insert(APIPermission::kProxy); 660 skip.insert(APIPermission::kTabCapture); 661 skip.insert(APIPermission::kWebRequest); 662 skip.insert(APIPermission::kWebRequestBlocking); 663 664 // This permission requires explicit user action (context menu handler) 665 // so we won't prompt for it for now. 666 skip.insert(APIPermission::kFileBrowserHandler); 667 668 // These permissions require explicit user action (configuration dialog) 669 // so we don't prompt for them at install time. 670 skip.insert(APIPermission::kMediaGalleries); 671 672 // If you've turned on the experimental command-line flag, we don't need 673 // to warn you further. 674 skip.insert(APIPermission::kExperimental); 675 676 // The Identity API has its own server-driven permission prompts. 677 skip.insert(APIPermission::kIdentity); 678 679 // These are private. 680 skip.insert(APIPermission::kAutoTestPrivate); 681 skip.insert(APIPermission::kBookmarkManagerPrivate); 682 skip.insert(APIPermission::kChromeosInfoPrivate); 683 skip.insert(APIPermission::kCloudPrintPrivate); 684 skip.insert(APIPermission::kCommandLinePrivate); 685 skip.insert(APIPermission::kDeveloperPrivate); 686 skip.insert(APIPermission::kDial); 687 skip.insert(APIPermission::kDownloadsInternal); 688 skip.insert(APIPermission::kEchoPrivate); 689 skip.insert(APIPermission::kEnterprisePlatformKeysPrivate); 690 skip.insert(APIPermission::kFileBrowserHandlerInternal); 691 skip.insert(APIPermission::kFileBrowserPrivate); 692 skip.insert(APIPermission::kIdentityPrivate); 693 skip.insert(APIPermission::kInputMethodPrivate); 694 skip.insert(APIPermission::kManagedModePrivate); 695 skip.insert(APIPermission::kMediaGalleriesPrivate); 696 skip.insert(APIPermission::kMediaPlayerPrivate); 697 skip.insert(APIPermission::kMetricsPrivate); 698 skip.insert(APIPermission::kNetworkingPrivate); 699 skip.insert(APIPermission::kRtcPrivate); 700 skip.insert(APIPermission::kStreamsPrivate); 701 skip.insert(APIPermission::kSystemPrivate); 702 skip.insert(APIPermission::kTerminalPrivate); 703 skip.insert(APIPermission::kWallpaperPrivate); 704 skip.insert(APIPermission::kWebRequestInternal); 705 skip.insert(APIPermission::kWebSocketProxyPrivate); 706 skip.insert(APIPermission::kWebstorePrivate); 707 708 // Warned as part of host permissions. 709 skip.insert(APIPermission::kDevtools); 710 711 // Platform apps. 712 skip.insert(APIPermission::kFileSystem); 713 skip.insert(APIPermission::kFileSystemRetainFiles); 714 skip.insert(APIPermission::kSocket); 715 skip.insert(APIPermission::kUsbDevice); 716 717 PermissionsInfo* info = PermissionsInfo::GetInstance(); 718 APIPermissionSet permissions = info->GetAll(); 719 for (APIPermissionSet::const_iterator i = permissions.begin(); 720 i != permissions.end(); ++i) { 721 const APIPermissionInfo* permission_info = i->info(); 722 EXPECT_TRUE(permission_info != NULL); 723 724 // Always skip permissions that cannot be in the manifest. 725 scoped_ptr<const APIPermission> permission( 726 permission_info->CreateAPIPermission()); 727 if (permission->ManifestEntryForbidden()) 728 continue; 729 730 if (skip.count(i->id())) { 731 EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id()) 732 << "unexpected message_id for " << permission_info->name(); 733 } else { 734 EXPECT_NE(PermissionMessage::kNone, permission_info->message_id()) 735 << "missing message_id for " << permission_info->name(); 736 } 737 } 738} 739 740// Tests the default permissions (empty API permission set). 741TEST(PermissionsTest, DefaultFunctionAccess) { 742 const struct { 743 const char* permission_name; 744 bool expect_success; 745 } kTests[] = { 746 // Negative test. 747 { "non_existing_permission", false }, 748 // Test default module/package permission. 749 { "browserAction", true }, 750 { "devtools", true }, 751 { "extension", true }, 752 { "i18n", true }, 753 { "pageAction", true }, 754 { "pageActions", true }, 755 { "test", true }, 756 // Some negative tests. 757 { "bookmarks", false }, 758 { "cookies", false }, 759 { "history", false }, 760 // Make sure we find the module name after stripping '.' and '/'. 761 { "browserAction/abcd/onClick", true }, 762 { "browserAction.abcd.onClick", true }, 763 // Test Tabs functions. 764 { "tabs.create", true}, 765 { "tabs.duplicate", true}, 766 { "tabs.update", true}, 767 { "tabs.getSelected", true}, 768 { "tabs.onUpdated", true }, 769 }; 770 771 scoped_refptr<PermissionSet> empty = new PermissionSet(); 772 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { 773 EXPECT_EQ(kTests[i].expect_success, 774 empty->HasAccessToFunction(kTests[i].permission_name, true)) 775 << "Permission being tested: " << kTests[i].permission_name; 776 } 777} 778 779// Tests the default permissions (empty API permission set). 780TEST(PermissionsTest, DefaultAnyAPIAccess) { 781 const struct { 782 const char* api_name; 783 bool expect_success; 784 } kTests[] = { 785 // Negative test. 786 { "non_existing_permission", false }, 787 // Test default module/package permission. 788 { "browserAction", true }, 789 { "devtools", true }, 790 { "extension", true }, 791 { "i18n", true }, 792 { "pageAction", true }, 793 { "pageActions", true }, 794 { "test", true }, 795 // Some negative tests. 796 { "bookmarks", false }, 797 { "cookies", false }, 798 { "history", false }, 799 // Negative APIs that have positive individual functions. 800 { "management", true}, 801 { "tabs", true}, 802 }; 803 804 scoped_refptr<PermissionSet> empty = new PermissionSet(); 805 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { 806 EXPECT_EQ(kTests[i].expect_success, 807 empty->HasAnyAccessToAPI(kTests[i].api_name)); 808 } 809} 810 811TEST(PermissionsTest, GetWarningMessages_ManyHosts) { 812 scoped_refptr<Extension> extension; 813 814 extension = LoadManifest("permissions", "many-hosts.json"); 815 std::vector<string16> warnings = 816 PermissionsData::GetPermissionMessageStrings(extension); 817 ASSERT_EQ(1u, warnings.size()); 818 EXPECT_EQ("Access your data on encrypted.google.com and www.google.com", 819 UTF16ToUTF8(warnings[0])); 820} 821 822TEST(PermissionsTest, GetWarningMessages_Plugins) { 823 scoped_refptr<Extension> extension; 824 scoped_refptr<PermissionSet> permissions; 825 826 extension = LoadManifest("permissions", "plugins.json"); 827 std::vector<string16> warnings = 828 PermissionsData::GetPermissionMessageStrings(extension); 829 // We don't parse the plugins key on Chrome OS, so it should not ask for any 830 // permissions. 831#if defined(OS_CHROMEOS) 832 ASSERT_EQ(0u, warnings.size()); 833#else 834 ASSERT_EQ(1u, warnings.size()); 835 EXPECT_EQ("Access all data on your computer and the websites you visit", 836 UTF16ToUTF8(warnings[0])); 837#endif 838} 839 840TEST(PermissionsTest, GetWarningMessages_AudioVideo) { 841 // Both audio and video present. 842 scoped_refptr<Extension> extension = 843 LoadManifest("permissions", "audio-video.json"); 844 PermissionSet* set = 845 const_cast<PermissionSet*>( 846 extension->GetActivePermissions().get()); 847 std::vector<string16> warnings = 848 set->GetWarningMessages(extension->GetType()); 849 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 850 EXPECT_FALSE(Contains(warnings, "Use your camera")); 851 EXPECT_TRUE(Contains(warnings, "Use your microphone and camera")); 852 size_t combined_index = IndexOf(warnings, "Use your microphone and camera"); 853 size_t combined_size = warnings.size(); 854 855 // Just audio present. 856 set->apis_.erase(APIPermission::kVideoCapture); 857 warnings = set->GetWarningMessages(extension->GetType()); 858 EXPECT_EQ(combined_size, warnings.size()); 859 EXPECT_EQ(combined_index, IndexOf(warnings, "Use your microphone")); 860 EXPECT_FALSE(Contains(warnings, "Use your camera")); 861 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 862 863 // Just video present. 864 set->apis_.erase(APIPermission::kAudioCapture); 865 set->apis_.insert(APIPermission::kVideoCapture); 866 warnings = set->GetWarningMessages(extension->GetType()); 867 EXPECT_EQ(combined_size, warnings.size()); 868 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 869 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 870 EXPECT_TRUE(Contains(warnings, "Use your camera")); 871} 872 873TEST(PermissionsTest, GetWarningMessages_Serial) { 874 scoped_refptr<Extension> extension = 875 LoadManifest("permissions", "serial.json"); 876 877 EXPECT_TRUE(extension->is_platform_app()); 878 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSerial)); 879 std::vector<string16> warnings = 880 PermissionsData::GetPermissionMessageStrings(extension); 881 EXPECT_TRUE(Contains(warnings, 882 "Use serial devices attached to your computer")); 883 ASSERT_EQ(1u, warnings.size()); 884} 885 886TEST(PermissionsTest, GetWarningMessages_Socket_AnyHost) { 887 Feature::ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 888 889 scoped_refptr<Extension> extension = 890 LoadManifest("permissions", "socket_any_host.json"); 891 EXPECT_TRUE(extension->is_platform_app()); 892 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 893 std::vector<string16> warnings = 894 PermissionsData::GetPermissionMessageStrings(extension); 895 EXPECT_EQ(1u, warnings.size()); 896 EXPECT_TRUE(Contains(warnings, "Exchange data with any computer " 897 "on the local network or internet")); 898} 899 900TEST(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) { 901 Feature::ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 902 903 scoped_refptr<Extension> extension = 904 LoadManifest("permissions", "socket_one_domain_two_hostnames.json"); 905 EXPECT_TRUE(extension->is_platform_app()); 906 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 907 std::vector<string16> warnings = 908 PermissionsData::GetPermissionMessageStrings(extension); 909 910 // Verify the warnings, including support for unicode characters, the fact 911 // that domain host warnings come before specific host warnings, and the fact 912 // that domains and hostnames are in alphabetical order regardless of the 913 // order in the manifest file. 914 EXPECT_EQ(2u, warnings.size()); 915 if (warnings.size() > 0) 916 EXPECT_EQ(warnings[0], 917 UTF8ToUTF16("Exchange data with any computer in the domain " 918 "example.org")); 919 if (warnings.size() > 1) 920 EXPECT_EQ(warnings[1], 921 UTF8ToUTF16("Exchange data with the computers named: " 922 "b\xC3\xA5r.example.com foo.example.com")); 923 // "\xC3\xA5" = UTF-8 for lowercase A with ring above 924} 925 926TEST(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) { 927 Feature::ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 928 929 scoped_refptr<Extension> extension = 930 LoadManifest("permissions", "socket_two_domains_one_hostname.json"); 931 EXPECT_TRUE(extension->is_platform_app()); 932 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 933 std::vector<string16> warnings = 934 PermissionsData::GetPermissionMessageStrings(extension); 935 936 // Verify the warnings, including the fact that domain host warnings come 937 // before specific host warnings and the fact that domains and hostnames are 938 // in alphabetical order regardless of the order in the manifest file. 939 EXPECT_EQ(2u, warnings.size()); 940 if (warnings.size() > 0) 941 EXPECT_EQ(warnings[0], 942 UTF8ToUTF16("Exchange data with any computer in the domains: " 943 "example.com foo.example.org")); 944 if (warnings.size() > 1) 945 EXPECT_EQ(warnings[1], 946 UTF8ToUTF16("Exchange data with the computer named " 947 "bar.example.org")); 948} 949 950TEST(PermissionsTest, GetWarningMessages_PlatformApppHosts) { 951 scoped_refptr<Extension> extension; 952 953 extension = LoadManifest("permissions", "platform_app_hosts.json"); 954 EXPECT_TRUE(extension->is_platform_app()); 955 std::vector<string16> warnings = 956 PermissionsData::GetPermissionMessageStrings(extension); 957 ASSERT_EQ(0u, warnings.size()); 958 959 extension = LoadManifest("permissions", "platform_app_all_urls.json"); 960 EXPECT_TRUE(extension->is_platform_app()); 961 warnings = PermissionsData::GetPermissionMessageStrings(extension); 962 ASSERT_EQ(0u, warnings.size()); 963} 964 965TEST(PermissionsTest, GetDistinctHostsForDisplay) { 966 scoped_refptr<PermissionSet> perm_set; 967 APIPermissionSet empty_perms; 968 std::set<std::string> expected; 969 expected.insert("www.foo.com"); 970 expected.insert("www.bar.com"); 971 expected.insert("www.baz.com"); 972 URLPatternSet explicit_hosts; 973 URLPatternSet scriptable_hosts; 974 975 { 976 SCOPED_TRACE("no dupes"); 977 978 // Simple list with no dupes. 979 explicit_hosts.AddPattern( 980 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 981 explicit_hosts.AddPattern( 982 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path")); 983 explicit_hosts.AddPattern( 984 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 985 perm_set = new PermissionSet( 986 empty_perms, explicit_hosts, scriptable_hosts); 987 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 988 } 989 990 { 991 SCOPED_TRACE("two dupes"); 992 993 // Add some dupes. 994 explicit_hosts.AddPattern( 995 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 996 explicit_hosts.AddPattern( 997 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 998 perm_set = new PermissionSet( 999 empty_perms, explicit_hosts, scriptable_hosts); 1000 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1001 } 1002 1003 { 1004 SCOPED_TRACE("schemes differ"); 1005 1006 // Add a pattern that differs only by scheme. This should be filtered out. 1007 explicit_hosts.AddPattern( 1008 URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path")); 1009 perm_set = new PermissionSet( 1010 empty_perms, explicit_hosts, scriptable_hosts); 1011 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1012 } 1013 1014 { 1015 SCOPED_TRACE("paths differ"); 1016 1017 // Add some dupes by path. 1018 explicit_hosts.AddPattern( 1019 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath")); 1020 perm_set = new PermissionSet( 1021 empty_perms, explicit_hosts, scriptable_hosts); 1022 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1023 } 1024 1025 { 1026 SCOPED_TRACE("subdomains differ"); 1027 1028 // We don't do anything special for subdomains. 1029 explicit_hosts.AddPattern( 1030 URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path")); 1031 explicit_hosts.AddPattern( 1032 URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path")); 1033 1034 expected.insert("monkey.www.bar.com"); 1035 expected.insert("bar.com"); 1036 1037 perm_set = new PermissionSet( 1038 empty_perms, explicit_hosts, scriptable_hosts); 1039 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1040 } 1041 1042 { 1043 SCOPED_TRACE("RCDs differ"); 1044 1045 // Now test for RCD uniquing. 1046 explicit_hosts.AddPattern( 1047 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1048 explicit_hosts.AddPattern( 1049 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1050 explicit_hosts.AddPattern( 1051 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path")); 1052 explicit_hosts.AddPattern( 1053 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path")); 1054 explicit_hosts.AddPattern( 1055 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1056 explicit_hosts.AddPattern( 1057 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path")); 1058 1059 // This is an unknown RCD, which shouldn't be uniqued out. 1060 explicit_hosts.AddPattern( 1061 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1062 // But it should only occur once. 1063 explicit_hosts.AddPattern( 1064 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1065 1066 expected.insert("www.foo.xyzzy"); 1067 1068 perm_set = new PermissionSet( 1069 empty_perms, explicit_hosts, scriptable_hosts); 1070 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1071 } 1072 1073 { 1074 SCOPED_TRACE("wildcards"); 1075 1076 explicit_hosts.AddPattern( 1077 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1078 1079 expected.insert("*.google.com"); 1080 1081 perm_set = new PermissionSet( 1082 empty_perms, explicit_hosts, scriptable_hosts); 1083 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1084 } 1085 1086 { 1087 SCOPED_TRACE("scriptable hosts"); 1088 explicit_hosts.ClearPatterns(); 1089 scriptable_hosts.ClearPatterns(); 1090 expected.clear(); 1091 1092 explicit_hosts.AddPattern( 1093 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1094 scriptable_hosts.AddPattern( 1095 URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*")); 1096 1097 expected.insert("*.google.com"); 1098 expected.insert("*.example.com"); 1099 1100 perm_set = new PermissionSet( 1101 empty_perms, explicit_hosts, scriptable_hosts); 1102 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1103 } 1104 1105 { 1106 // We don't display warnings for file URLs because they are off by default. 1107 SCOPED_TRACE("file urls"); 1108 explicit_hosts.ClearPatterns(); 1109 scriptable_hosts.ClearPatterns(); 1110 expected.clear(); 1111 1112 explicit_hosts.AddPattern( 1113 URLPattern(URLPattern::SCHEME_FILE, "file:///*")); 1114 1115 perm_set = new PermissionSet( 1116 empty_perms, explicit_hosts, scriptable_hosts); 1117 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1118 } 1119} 1120 1121TEST(PermissionsTest, GetDistinctHostsForDisplay_ComIsBestRcd) { 1122 scoped_refptr<PermissionSet> perm_set; 1123 APIPermissionSet empty_perms; 1124 URLPatternSet explicit_hosts; 1125 URLPatternSet scriptable_hosts; 1126 explicit_hosts.AddPattern( 1127 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1128 explicit_hosts.AddPattern( 1129 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1130 explicit_hosts.AddPattern( 1131 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1132 explicit_hosts.AddPattern( 1133 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1134 explicit_hosts.AddPattern( 1135 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1136 explicit_hosts.AddPattern( 1137 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1138 1139 std::set<std::string> expected; 1140 expected.insert("www.foo.com"); 1141 perm_set = new PermissionSet( 1142 empty_perms, explicit_hosts, scriptable_hosts); 1143 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1144} 1145 1146TEST(PermissionsTest, GetDistinctHostsForDisplay_NetIs2ndBestRcd) { 1147 scoped_refptr<PermissionSet> perm_set; 1148 APIPermissionSet empty_perms; 1149 URLPatternSet explicit_hosts; 1150 URLPatternSet scriptable_hosts; 1151 explicit_hosts.AddPattern( 1152 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1153 explicit_hosts.AddPattern( 1154 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1155 explicit_hosts.AddPattern( 1156 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1157 explicit_hosts.AddPattern( 1158 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1159 explicit_hosts.AddPattern( 1160 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1161 // No http://www.foo.com/path 1162 1163 std::set<std::string> expected; 1164 expected.insert("www.foo.net"); 1165 perm_set = new PermissionSet( 1166 empty_perms, explicit_hosts, scriptable_hosts); 1167 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1168} 1169 1170TEST(PermissionsTest, 1171 GetDistinctHostsForDisplay_OrgIs3rdBestRcd) { 1172 scoped_refptr<PermissionSet> perm_set; 1173 APIPermissionSet empty_perms; 1174 URLPatternSet explicit_hosts; 1175 URLPatternSet scriptable_hosts; 1176 explicit_hosts.AddPattern( 1177 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1178 explicit_hosts.AddPattern( 1179 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1180 explicit_hosts.AddPattern( 1181 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1182 // No http://www.foo.net/path 1183 explicit_hosts.AddPattern( 1184 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1185 // No http://www.foo.com/path 1186 1187 std::set<std::string> expected; 1188 expected.insert("www.foo.org"); 1189 perm_set = new PermissionSet( 1190 empty_perms, explicit_hosts, scriptable_hosts); 1191 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1192} 1193 1194TEST(PermissionsTest, 1195 GetDistinctHostsForDisplay_FirstInListIs4thBestRcd) { 1196 scoped_refptr<PermissionSet> perm_set; 1197 APIPermissionSet empty_perms; 1198 URLPatternSet explicit_hosts; 1199 URLPatternSet scriptable_hosts; 1200 explicit_hosts.AddPattern( 1201 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1202 // No http://www.foo.org/path 1203 explicit_hosts.AddPattern( 1204 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1205 // No http://www.foo.net/path 1206 explicit_hosts.AddPattern( 1207 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1208 // No http://www.foo.com/path 1209 1210 std::set<std::string> expected; 1211 expected.insert("www.foo.ca"); 1212 perm_set = new PermissionSet( 1213 empty_perms, explicit_hosts, scriptable_hosts); 1214 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1215} 1216 1217TEST(PermissionsTest, HasLessHostPrivilegesThan) { 1218 URLPatternSet elist1; 1219 URLPatternSet elist2; 1220 URLPatternSet slist1; 1221 URLPatternSet slist2; 1222 scoped_refptr<PermissionSet> set1; 1223 scoped_refptr<PermissionSet> set2; 1224 APIPermissionSet empty_perms; 1225 elist1.AddPattern( 1226 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1227 elist1.AddPattern( 1228 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1229 1230 // Test that the host order does not matter. 1231 elist2.AddPattern( 1232 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1233 elist2.AddPattern( 1234 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1235 1236 set1 = new PermissionSet(empty_perms, elist1, slist1); 1237 set2 = new PermissionSet(empty_perms, elist2, slist2); 1238 1239 EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get())); 1240 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get())); 1241 1242 // Test that paths are ignored. 1243 elist2.ClearPatterns(); 1244 elist2.AddPattern( 1245 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*")); 1246 set2 = new PermissionSet(empty_perms, elist2, slist2); 1247 EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get())); 1248 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get())); 1249 1250 // Test that RCDs are ignored. 1251 elist2.ClearPatterns(); 1252 elist2.AddPattern( 1253 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*")); 1254 set2 = new PermissionSet(empty_perms, elist2, slist2); 1255 EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get())); 1256 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get())); 1257 1258 // Test that subdomain wildcards are handled properly. 1259 elist2.ClearPatterns(); 1260 elist2.AddPattern( 1261 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*")); 1262 set2 = new PermissionSet(empty_perms, elist2, slist2); 1263 EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get())); 1264 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337 1265 // EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get())); 1266 1267 // Test that different domains count as different hosts. 1268 elist2.ClearPatterns(); 1269 elist2.AddPattern( 1270 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1271 elist2.AddPattern( 1272 URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path")); 1273 set2 = new PermissionSet(empty_perms, elist2, slist2); 1274 EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get())); 1275 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get())); 1276 1277 // Test that different subdomains count as different hosts. 1278 elist2.ClearPatterns(); 1279 elist2.AddPattern( 1280 URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*")); 1281 set2 = new PermissionSet(empty_perms, elist2, slist2); 1282 EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get())); 1283 EXPECT_TRUE(set2->HasLessHostPrivilegesThan(set1.get())); 1284} 1285 1286TEST(PermissionsTest, GetAPIsAsStrings) { 1287 APIPermissionSet apis; 1288 URLPatternSet empty_set; 1289 1290 apis.insert(APIPermission::kProxy); 1291 apis.insert(APIPermission::kBackground); 1292 apis.insert(APIPermission::kNotification); 1293 apis.insert(APIPermission::kTab); 1294 1295 scoped_refptr<PermissionSet> perm_set = new PermissionSet( 1296 apis, empty_set, empty_set); 1297 std::set<std::string> api_names = perm_set->GetAPIsAsStrings(); 1298 1299 // The result is correct if it has the same number of elements 1300 // and we can convert it back to the id set. 1301 EXPECT_EQ(4u, api_names.size()); 1302 EXPECT_EQ(apis, 1303 PermissionsInfo::GetInstance()->GetAllByName(api_names)); 1304} 1305 1306TEST(PermissionsTest, IsEmpty) { 1307 APIPermissionSet empty_apis; 1308 URLPatternSet empty_extent; 1309 1310 scoped_refptr<PermissionSet> empty = new PermissionSet(); 1311 EXPECT_TRUE(empty->IsEmpty()); 1312 scoped_refptr<PermissionSet> perm_set; 1313 1314 perm_set = new PermissionSet(empty_apis, empty_extent, empty_extent); 1315 EXPECT_TRUE(perm_set->IsEmpty()); 1316 1317 APIPermissionSet non_empty_apis; 1318 non_empty_apis.insert(APIPermission::kBackground); 1319 perm_set = new PermissionSet( 1320 non_empty_apis, empty_extent, empty_extent); 1321 EXPECT_FALSE(perm_set->IsEmpty()); 1322 1323 // Try non standard host 1324 URLPatternSet non_empty_extent; 1325 AddPattern(&non_empty_extent, "http://www.google.com/*"); 1326 1327 perm_set = new PermissionSet( 1328 empty_apis, non_empty_extent, empty_extent); 1329 EXPECT_FALSE(perm_set->IsEmpty()); 1330 1331 perm_set = new PermissionSet( 1332 empty_apis, empty_extent, non_empty_extent); 1333 EXPECT_FALSE(perm_set->IsEmpty()); 1334} 1335 1336TEST(PermissionsTest, ImpliedPermissions) { 1337 URLPatternSet empty_extent; 1338 APIPermissionSet apis; 1339 apis.insert(APIPermission::kWebRequest); 1340 apis.insert(APIPermission::kFileBrowserHandler); 1341 EXPECT_EQ(2U, apis.size()); 1342 1343 scoped_refptr<PermissionSet> perm_set; 1344 perm_set = new PermissionSet(apis, empty_extent, empty_extent); 1345 EXPECT_EQ(4U, perm_set->apis().size()); 1346} 1347 1348TEST(PermissionsTest, SyncFileSystemPermission) { 1349 scoped_refptr<Extension> extension = LoadManifest( 1350 "permissions", "sync_file_system.json"); 1351 APIPermissionSet apis; 1352 apis.insert(APIPermission::kSyncFileSystem); 1353 EXPECT_TRUE(extension->is_platform_app()); 1354 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSyncFileSystem)); 1355 std::vector<string16> warnings = 1356 PermissionsData::GetPermissionMessageStrings(extension); 1357 EXPECT_TRUE(Contains(warnings, "Store data in your Google Drive account")); 1358 ASSERT_EQ(1u, warnings.size()); 1359} 1360 1361} // namespace extensions 1362