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