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/strings/utf_string_conversions.h" 10 #include "chrome/common/chrome_paths.h" 11 #include "chrome/common/chrome_switches.h" 12 #include "chrome/common/extensions/extension_test_util.h" 13 #include "chrome/common/extensions/features/feature_channel.h" 14 #include "chrome/common/extensions/permissions/chrome_permission_message_provider.h" 15 #include "chrome/grit/generated_resources.h" 16 #include "extensions/common/error_utils.h" 17 #include "extensions/common/extension.h" 18 #include "extensions/common/extension_builder.h" 19 #include "extensions/common/permissions/permission_message_provider.h" 20 #include "extensions/common/permissions/permission_message_util.h" 21 #include "extensions/common/permissions/permission_set.h" 22 #include "extensions/common/permissions/permissions_data.h" 23 #include "extensions/common/permissions/permissions_info.h" 24 #include "extensions/common/permissions/socket_permission.h" 25 #include "extensions/common/value_builder.h" 26 #include "extensions/strings/grit/extensions_strings.h" 27 #include "testing/gtest/include/gtest/gtest.h" 28 #include "ui/base/l10n/l10n_util.h" 29 30 using extension_test_util::LoadManifest; 31 32 namespace extensions { 33 34 namespace { 35 36 static void AddPattern(URLPatternSet* extent, const std::string& pattern) { 37 int schemes = URLPattern::SCHEME_ALL; 38 extent->AddPattern(URLPattern(schemes, pattern)); 39 } 40 41 size_t IndexOf(const std::vector<base::string16>& warnings, 42 const std::string& warning) { 43 for (size_t i = 0; i < warnings.size(); ++i) { 44 if (warnings[i] == base::ASCIIToUTF16(warning)) 45 return i; 46 } 47 48 return warnings.size(); 49 } 50 51 bool Contains(const std::vector<base::string16>& warnings, 52 const std::string& warning) { 53 return IndexOf(warnings, warning) != warnings.size(); 54 } 55 56 } // namespace 57 58 // Tests GetByID. 59 TEST(PermissionsTest, GetByID) { 60 PermissionsInfo* info = PermissionsInfo::GetInstance(); 61 APIPermissionSet apis = info->GetAll(); 62 for (APIPermissionSet::const_iterator i = apis.begin(); 63 i != apis.end(); ++i) { 64 EXPECT_EQ(i->id(), i->info()->id()); 65 } 66 } 67 68 // Tests that GetByName works with normal permission names and aliases. 69 TEST(PermissionsTest, GetByName) { 70 PermissionsInfo* info = PermissionsInfo::GetInstance(); 71 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id()); 72 EXPECT_EQ(APIPermission::kManagement, 73 info->GetByName("management")->id()); 74 EXPECT_FALSE(info->GetByName("alsdkfjasldkfj")); 75 } 76 77 TEST(PermissionsTest, GetAll) { 78 size_t count = 0; 79 PermissionsInfo* info = PermissionsInfo::GetInstance(); 80 APIPermissionSet apis = info->GetAll(); 81 for (APIPermissionSet::const_iterator api = apis.begin(); 82 api != apis.end(); ++api) { 83 // Make sure only the valid permission IDs get returned. 84 EXPECT_NE(APIPermission::kInvalid, api->id()); 85 EXPECT_NE(APIPermission::kUnknown, api->id()); 86 count++; 87 } 88 EXPECT_EQ(count, info->get_permission_count()); 89 } 90 91 TEST(PermissionsTest, GetAllByName) { 92 std::set<std::string> names; 93 names.insert("background"); 94 names.insert("management"); 95 96 // This is an alias of kTab 97 names.insert("windows"); 98 99 // This unknown name should get dropped. 100 names.insert("sdlkfjasdlkfj"); 101 102 APIPermissionSet expected; 103 expected.insert(APIPermission::kBackground); 104 expected.insert(APIPermission::kManagement); 105 expected.insert(APIPermission::kTab); 106 107 EXPECT_EQ(expected, 108 PermissionsInfo::GetInstance()->GetAllByName(names)); 109 } 110 111 // Tests that the aliases are properly mapped. 112 TEST(PermissionsTest, Aliases) { 113 PermissionsInfo* info = PermissionsInfo::GetInstance(); 114 // tabs: tabs, windows 115 std::string tabs_name = "tabs"; 116 EXPECT_EQ(tabs_name, info->GetByID(APIPermission::kTab)->name()); 117 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id()); 118 EXPECT_EQ(APIPermission::kTab, info->GetByName("windows")->id()); 119 120 // unlimitedStorage: unlimitedStorage, unlimited_storage 121 std::string storage_name = "unlimitedStorage"; 122 EXPECT_EQ(storage_name, info->GetByID( 123 APIPermission::kUnlimitedStorage)->name()); 124 EXPECT_EQ(APIPermission::kUnlimitedStorage, 125 info->GetByName("unlimitedStorage")->id()); 126 EXPECT_EQ(APIPermission::kUnlimitedStorage, 127 info->GetByName("unlimited_storage")->id()); 128 } 129 130 TEST(PermissionsTest, EffectiveHostPermissions) { 131 scoped_refptr<Extension> extension; 132 scoped_refptr<const PermissionSet> permissions; 133 134 extension = LoadManifest("effective_host_permissions", "empty.json"); 135 permissions = extension->permissions_data()->active_permissions(); 136 EXPECT_EQ(0u, 137 extension->permissions_data() 138 ->GetEffectiveHostPermissions() 139 .patterns() 140 .size()); 141 EXPECT_FALSE( 142 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 143 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 144 145 extension = LoadManifest("effective_host_permissions", "one_host.json"); 146 permissions = extension->permissions_data()->active_permissions(); 147 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 148 GURL("http://www.google.com"))); 149 EXPECT_FALSE(permissions->HasEffectiveAccessToURL( 150 GURL("https://www.google.com"))); 151 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 152 153 extension = LoadManifest("effective_host_permissions", 154 "one_host_wildcard.json"); 155 permissions = extension->permissions_data()->active_permissions(); 156 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 157 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 158 GURL("http://foo.google.com"))); 159 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 160 161 extension = LoadManifest("effective_host_permissions", "two_hosts.json"); 162 permissions = extension->permissions_data()->active_permissions(); 163 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 164 GURL("http://www.google.com"))); 165 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 166 GURL("http://www.reddit.com"))); 167 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 168 169 extension = LoadManifest("effective_host_permissions", 170 "https_not_considered.json"); 171 permissions = extension->permissions_data()->active_permissions(); 172 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 173 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://google.com"))); 174 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 175 176 extension = LoadManifest("effective_host_permissions", 177 "two_content_scripts.json"); 178 permissions = extension->permissions_data()->active_permissions(); 179 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 180 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 181 GURL("http://www.reddit.com"))); 182 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 183 GURL("http://news.ycombinator.com"))); 184 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 185 186 extension = LoadManifest("effective_host_permissions", "all_hosts.json"); 187 permissions = extension->permissions_data()->active_permissions(); 188 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 189 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("https://test/"))); 190 EXPECT_TRUE( 191 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 192 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 193 194 extension = LoadManifest("effective_host_permissions", "all_hosts2.json"); 195 permissions = extension->permissions_data()->active_permissions(); 196 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 197 EXPECT_TRUE( 198 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 199 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 200 201 extension = LoadManifest("effective_host_permissions", "all_hosts3.json"); 202 permissions = extension->permissions_data()->active_permissions(); 203 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 204 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://test/"))); 205 EXPECT_TRUE( 206 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 207 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 208 } 209 210 TEST(PermissionsTest, ExplicitAccessToOrigin) { 211 APIPermissionSet apis; 212 ManifestPermissionSet manifest_permissions; 213 URLPatternSet explicit_hosts; 214 URLPatternSet scriptable_hosts; 215 216 AddPattern(&explicit_hosts, "http://*.google.com/*"); 217 // The explicit host paths should get set to /*. 218 AddPattern(&explicit_hosts, "http://www.example.com/a/particular/path/*"); 219 220 scoped_refptr<PermissionSet> perm_set = new PermissionSet( 221 apis, manifest_permissions, explicit_hosts, scriptable_hosts); 222 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 223 GURL("http://www.google.com/"))); 224 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 225 GURL("http://test.google.com/"))); 226 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 227 GURL("http://www.example.com"))); 228 ASSERT_TRUE(perm_set->HasEffectiveAccessToURL( 229 GURL("http://www.example.com"))); 230 ASSERT_FALSE(perm_set->HasExplicitAccessToOrigin( 231 GURL("http://test.example.com"))); 232 } 233 234 TEST(PermissionsTest, CreateUnion) { 235 APIPermission* permission = NULL; 236 237 ManifestPermissionSet manifest_permissions; 238 APIPermissionSet apis1; 239 APIPermissionSet apis2; 240 APIPermissionSet expected_apis; 241 242 URLPatternSet explicit_hosts1; 243 URLPatternSet explicit_hosts2; 244 URLPatternSet expected_explicit_hosts; 245 246 URLPatternSet scriptable_hosts1; 247 URLPatternSet scriptable_hosts2; 248 URLPatternSet expected_scriptable_hosts; 249 250 URLPatternSet effective_hosts; 251 252 scoped_refptr<PermissionSet> set1; 253 scoped_refptr<PermissionSet> set2; 254 scoped_refptr<PermissionSet> union_set; 255 256 const APIPermissionInfo* permission_info = 257 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 258 permission = permission_info->CreateAPIPermission(); 259 { 260 scoped_ptr<base::ListValue> value(new base::ListValue()); 261 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 262 value->Append(new base::StringValue("udp-bind::8080")); 263 value->Append(new base::StringValue("udp-send-to::8888")); 264 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 265 } 266 267 // Union with an empty set. 268 apis1.insert(APIPermission::kTab); 269 apis1.insert(APIPermission::kBackground); 270 apis1.insert(permission->Clone()); 271 expected_apis.insert(APIPermission::kTab); 272 expected_apis.insert(APIPermission::kBackground); 273 expected_apis.insert(permission); 274 275 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 276 AddPattern(&expected_explicit_hosts, "http://*.google.com/*"); 277 AddPattern(&effective_hosts, "http://*.google.com/*"); 278 279 set1 = new PermissionSet(apis1, manifest_permissions, 280 explicit_hosts1, scriptable_hosts1); 281 set2 = new PermissionSet(apis2, manifest_permissions, 282 explicit_hosts2, scriptable_hosts2); 283 union_set = PermissionSet::CreateUnion(set1.get(), set2.get()); 284 EXPECT_TRUE(set1->Contains(*set2.get())); 285 EXPECT_TRUE(set1->Contains(*union_set.get())); 286 EXPECT_FALSE(set2->Contains(*set1.get())); 287 EXPECT_FALSE(set2->Contains(*union_set.get())); 288 EXPECT_TRUE(union_set->Contains(*set1.get())); 289 EXPECT_TRUE(union_set->Contains(*set2.get())); 290 291 EXPECT_FALSE(union_set->HasEffectiveFullAccess()); 292 EXPECT_EQ(expected_apis, union_set->apis()); 293 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts()); 294 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts()); 295 EXPECT_EQ(expected_explicit_hosts, union_set->effective_hosts()); 296 297 // Now use a real second set. 298 apis2.insert(APIPermission::kTab); 299 apis2.insert(APIPermission::kProxy); 300 apis2.insert(APIPermission::kClipboardWrite); 301 apis2.insert(APIPermission::kPlugin); 302 303 permission = permission_info->CreateAPIPermission(); 304 { 305 scoped_ptr<base::ListValue> value(new base::ListValue()); 306 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 307 value->Append(new base::StringValue("udp-send-to::8899")); 308 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 309 } 310 apis2.insert(permission); 311 312 expected_apis.insert(APIPermission::kTab); 313 expected_apis.insert(APIPermission::kProxy); 314 expected_apis.insert(APIPermission::kClipboardWrite); 315 expected_apis.insert(APIPermission::kPlugin); 316 317 permission = permission_info->CreateAPIPermission(); 318 { 319 scoped_ptr<base::ListValue> value(new base::ListValue()); 320 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 321 value->Append(new base::StringValue("udp-bind::8080")); 322 value->Append(new base::StringValue("udp-send-to::8888")); 323 value->Append(new base::StringValue("udp-send-to::8899")); 324 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 325 } 326 // Insert a new permission socket permisssion which will replace the old one. 327 expected_apis.insert(permission); 328 329 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 330 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 331 AddPattern(&expected_explicit_hosts, "http://*.example.com/*"); 332 AddPattern(&expected_scriptable_hosts, "http://*.google.com/*"); 333 334 URLPatternSet::CreateUnion( 335 explicit_hosts2, scriptable_hosts2, &effective_hosts); 336 337 set2 = new PermissionSet(apis2, manifest_permissions, 338 explicit_hosts2, scriptable_hosts2); 339 union_set = PermissionSet::CreateUnion(set1.get(), set2.get()); 340 341 EXPECT_FALSE(set1->Contains(*set2.get())); 342 EXPECT_FALSE(set1->Contains(*union_set.get())); 343 EXPECT_FALSE(set2->Contains(*set1.get())); 344 EXPECT_FALSE(set2->Contains(*union_set.get())); 345 EXPECT_TRUE(union_set->Contains(*set1.get())); 346 EXPECT_TRUE(union_set->Contains(*set2.get())); 347 348 EXPECT_TRUE(union_set->HasEffectiveFullAccess()); 349 EXPECT_TRUE(union_set->HasEffectiveAccessToAllHosts()); 350 EXPECT_EQ(expected_apis, union_set->apis()); 351 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts()); 352 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts()); 353 EXPECT_EQ(effective_hosts, union_set->effective_hosts()); 354 } 355 356 TEST(PermissionsTest, CreateIntersection) { 357 APIPermission* permission = NULL; 358 359 ManifestPermissionSet manifest_permissions; 360 APIPermissionSet apis1; 361 APIPermissionSet apis2; 362 APIPermissionSet expected_apis; 363 364 URLPatternSet explicit_hosts1; 365 URLPatternSet explicit_hosts2; 366 URLPatternSet expected_explicit_hosts; 367 368 URLPatternSet scriptable_hosts1; 369 URLPatternSet scriptable_hosts2; 370 URLPatternSet expected_scriptable_hosts; 371 372 URLPatternSet effective_hosts; 373 374 scoped_refptr<PermissionSet> set1; 375 scoped_refptr<PermissionSet> set2; 376 scoped_refptr<PermissionSet> new_set; 377 378 const APIPermissionInfo* permission_info = 379 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 380 381 // Intersection with an empty set. 382 apis1.insert(APIPermission::kTab); 383 apis1.insert(APIPermission::kBackground); 384 permission = permission_info->CreateAPIPermission(); 385 { 386 scoped_ptr<base::ListValue> value(new base::ListValue()); 387 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 388 value->Append(new base::StringValue("udp-bind::8080")); 389 value->Append(new base::StringValue("udp-send-to::8888")); 390 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 391 } 392 apis1.insert(permission); 393 394 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 395 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*"); 396 397 set1 = new PermissionSet(apis1, manifest_permissions, 398 explicit_hosts1, scriptable_hosts1); 399 set2 = new PermissionSet(apis2, manifest_permissions, 400 explicit_hosts2, scriptable_hosts2); 401 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get()); 402 EXPECT_TRUE(set1->Contains(*new_set.get())); 403 EXPECT_TRUE(set2->Contains(*new_set.get())); 404 EXPECT_TRUE(set1->Contains(*set2.get())); 405 EXPECT_FALSE(set2->Contains(*set1.get())); 406 EXPECT_FALSE(new_set->Contains(*set1.get())); 407 EXPECT_TRUE(new_set->Contains(*set2.get())); 408 409 EXPECT_TRUE(new_set->IsEmpty()); 410 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 411 EXPECT_EQ(expected_apis, new_set->apis()); 412 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 413 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 414 EXPECT_EQ(expected_explicit_hosts, new_set->effective_hosts()); 415 416 // Now use a real second set. 417 apis2.insert(APIPermission::kTab); 418 apis2.insert(APIPermission::kProxy); 419 apis2.insert(APIPermission::kClipboardWrite); 420 apis2.insert(APIPermission::kPlugin); 421 permission = permission_info->CreateAPIPermission(); 422 { 423 scoped_ptr<base::ListValue> value(new base::ListValue()); 424 value->Append(new base::StringValue("udp-bind::8080")); 425 value->Append(new base::StringValue("udp-send-to::8888")); 426 value->Append(new base::StringValue("udp-send-to::8899")); 427 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 428 } 429 apis2.insert(permission); 430 431 expected_apis.insert(APIPermission::kTab); 432 permission = permission_info->CreateAPIPermission(); 433 { 434 scoped_ptr<base::ListValue> value(new base::ListValue()); 435 value->Append(new base::StringValue("udp-bind::8080")); 436 value->Append(new base::StringValue("udp-send-to::8888")); 437 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 438 } 439 expected_apis.insert(permission); 440 441 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 442 AddPattern(&explicit_hosts2, "http://*.google.com/*"); 443 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 444 AddPattern(&expected_explicit_hosts, "http://*.google.com/*"); 445 446 effective_hosts.ClearPatterns(); 447 AddPattern(&effective_hosts, "http://*.google.com/*"); 448 449 set2 = new PermissionSet(apis2, manifest_permissions, 450 explicit_hosts2, scriptable_hosts2); 451 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get()); 452 453 EXPECT_TRUE(set1->Contains(*new_set.get())); 454 EXPECT_TRUE(set2->Contains(*new_set.get())); 455 EXPECT_FALSE(set1->Contains(*set2.get())); 456 EXPECT_FALSE(set2->Contains(*set1.get())); 457 EXPECT_FALSE(new_set->Contains(*set1.get())); 458 EXPECT_FALSE(new_set->Contains(*set2.get())); 459 460 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 461 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts()); 462 EXPECT_EQ(expected_apis, new_set->apis()); 463 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 464 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 465 EXPECT_EQ(effective_hosts, new_set->effective_hosts()); 466 } 467 468 TEST(PermissionsTest, CreateDifference) { 469 APIPermission* permission = NULL; 470 471 ManifestPermissionSet manifest_permissions; 472 APIPermissionSet apis1; 473 APIPermissionSet apis2; 474 APIPermissionSet expected_apis; 475 476 URLPatternSet explicit_hosts1; 477 URLPatternSet explicit_hosts2; 478 URLPatternSet expected_explicit_hosts; 479 480 URLPatternSet scriptable_hosts1; 481 URLPatternSet scriptable_hosts2; 482 URLPatternSet expected_scriptable_hosts; 483 484 URLPatternSet effective_hosts; 485 486 scoped_refptr<PermissionSet> set1; 487 scoped_refptr<PermissionSet> set2; 488 scoped_refptr<PermissionSet> new_set; 489 490 const APIPermissionInfo* permission_info = 491 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 492 493 // Difference with an empty set. 494 apis1.insert(APIPermission::kTab); 495 apis1.insert(APIPermission::kBackground); 496 permission = permission_info->CreateAPIPermission(); 497 { 498 scoped_ptr<base::ListValue> value(new base::ListValue()); 499 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 500 value->Append(new base::StringValue("udp-bind::8080")); 501 value->Append(new base::StringValue("udp-send-to::8888")); 502 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 503 } 504 apis1.insert(permission); 505 506 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 507 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*"); 508 509 set1 = new PermissionSet(apis1, manifest_permissions, 510 explicit_hosts1, scriptable_hosts1); 511 set2 = new PermissionSet(apis2, manifest_permissions, 512 explicit_hosts2, scriptable_hosts2); 513 new_set = PermissionSet::CreateDifference(set1.get(), set2.get()); 514 EXPECT_EQ(*set1.get(), *new_set.get()); 515 516 // Now use a real second set. 517 apis2.insert(APIPermission::kTab); 518 apis2.insert(APIPermission::kProxy); 519 apis2.insert(APIPermission::kClipboardWrite); 520 apis2.insert(APIPermission::kPlugin); 521 permission = permission_info->CreateAPIPermission(); 522 { 523 scoped_ptr<base::ListValue> value(new base::ListValue()); 524 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 525 value->Append(new base::StringValue("udp-send-to::8899")); 526 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 527 } 528 apis2.insert(permission); 529 530 expected_apis.insert(APIPermission::kBackground); 531 permission = permission_info->CreateAPIPermission(); 532 { 533 scoped_ptr<base::ListValue> value(new base::ListValue()); 534 value->Append(new base::StringValue("udp-bind::8080")); 535 value->Append(new base::StringValue("udp-send-to::8888")); 536 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 537 } 538 expected_apis.insert(permission); 539 540 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 541 AddPattern(&explicit_hosts2, "http://*.google.com/*"); 542 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 543 AddPattern(&expected_scriptable_hosts, "http://www.reddit.com/*"); 544 545 effective_hosts.ClearPatterns(); 546 AddPattern(&effective_hosts, "http://www.reddit.com/*"); 547 548 set2 = new PermissionSet(apis2, manifest_permissions, 549 explicit_hosts2, scriptable_hosts2); 550 new_set = PermissionSet::CreateDifference(set1.get(), set2.get()); 551 552 EXPECT_TRUE(set1->Contains(*new_set.get())); 553 EXPECT_FALSE(set2->Contains(*new_set.get())); 554 555 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 556 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts()); 557 EXPECT_EQ(expected_apis, new_set->apis()); 558 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 559 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 560 EXPECT_EQ(effective_hosts, new_set->effective_hosts()); 561 562 // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set 563 set1 = PermissionSet::CreateIntersection(new_set.get(), set2.get()); 564 EXPECT_TRUE(set1->IsEmpty()); 565 } 566 567 TEST(PermissionsTest, IsPrivilegeIncrease) { 568 const struct { 569 const char* base_name; 570 bool expect_increase; 571 } kTests[] = { 572 { "allhosts1", false }, // all -> all 573 { "allhosts2", false }, // all -> one 574 { "allhosts3", true }, // one -> all 575 { "hosts1", false }, // http://a,http://b -> http://a,http://b 576 { "hosts2", true }, // http://a,http://b -> https://a,http://*.b 577 { "hosts3", false }, // http://a,http://b -> http://a 578 { "hosts4", true }, // http://a -> http://a,http://b 579 { "hosts5", false }, // http://a,b,c -> http://a,b,c + https://a,b,c 580 { "hosts6", false }, // http://a.com -> http://a.com + http://a.co.uk 581 { "permissions1", false }, // tabs -> tabs 582 { "permissions2", true }, // tabs -> tabs,bookmarks 583 { "permissions3", true }, // http://a -> http://a,tabs 584 { "permissions5", true }, // bookmarks -> bookmarks,history 585 { "equivalent_warnings", false }, // tabs --> tabs, webNavigation 586 #if !defined(OS_CHROMEOS) // plugins aren't allowed in ChromeOS 587 { "permissions4", false }, // plugin -> plugin,tabs 588 { "plugin1", false }, // plugin -> plugin 589 { "plugin2", false }, // plugin -> none 590 { "plugin3", true }, // none -> plugin 591 #endif 592 { "storage", false }, // none -> storage 593 { "notifications", false }, // none -> notifications 594 { "platformapp1", false }, // host permissions for platform apps 595 { "platformapp2", true }, // API permissions for platform apps 596 { "media_galleries1", true }, // all -> read|all 597 { "media_galleries2", true }, // read|all -> read|delete|copyTo|all 598 { "media_galleries3", true }, // all -> read|delete|all 599 { "media_galleries4", false }, // read|all -> all 600 { "media_galleries5", false }, // read|copyTo|delete|all -> read|all 601 { "media_galleries6", false }, // read|all -> read|all 602 { "media_galleries7", true }, // read|delete|all -> read|copyTo|delete|all 603 { "sockets1", true }, // none -> tcp:*:* 604 { "sockets2", false }, // tcp:*:* -> tcp:*:* 605 { "sockets3", true }, // tcp:a.com:80 -> tcp:*:* 606 }; 607 608 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { 609 scoped_refptr<Extension> old_extension( 610 LoadManifest("allow_silent_upgrade", 611 std::string(kTests[i].base_name) + "_old.json")); 612 scoped_refptr<Extension> new_extension( 613 LoadManifest("allow_silent_upgrade", 614 std::string(kTests[i].base_name) + "_new.json")); 615 616 EXPECT_TRUE(new_extension.get()) << kTests[i].base_name << "_new.json"; 617 if (!new_extension.get()) 618 continue; 619 620 scoped_refptr<const PermissionSet> old_p( 621 old_extension->permissions_data()->active_permissions()); 622 scoped_refptr<const PermissionSet> new_p( 623 new_extension->permissions_data()->active_permissions()); 624 Manifest::Type extension_type = old_extension->GetType(); 625 626 bool increased = PermissionMessageProvider::Get()->IsPrivilegeIncrease( 627 old_p.get(), new_p.get(), extension_type); 628 EXPECT_EQ(kTests[i].expect_increase, increased) << kTests[i].base_name; 629 } 630 } 631 632 TEST(PermissionsTest, PermissionMessages) { 633 // Ensure that all permissions that needs to show install UI actually have 634 // strings associated with them. 635 APIPermissionSet skip; 636 637 // These are considered "nuisance" or "trivial" permissions that don't need 638 // a prompt. 639 skip.insert(APIPermission::kActiveTab); 640 skip.insert(APIPermission::kAlarms); 641 skip.insert(APIPermission::kAlphaEnabled); 642 skip.insert(APIPermission::kAlwaysOnTopWindows); 643 skip.insert(APIPermission::kAppView); 644 skip.insert(APIPermission::kAudio); 645 skip.insert(APIPermission::kBrowsingData); 646 skip.insert(APIPermission::kCastStreaming); 647 skip.insert(APIPermission::kCommandsAccessibility); 648 skip.insert(APIPermission::kContextMenus); 649 skip.insert(APIPermission::kCopresencePrivate); 650 skip.insert(APIPermission::kDiagnostics); 651 skip.insert(APIPermission::kDns); 652 skip.insert(APIPermission::kDownloadsShelf); 653 skip.insert(APIPermission::kEmbeddedExtensionOptions); 654 skip.insert(APIPermission::kFontSettings); 655 skip.insert(APIPermission::kFullscreen); 656 skip.insert(APIPermission::kGcm); 657 skip.insert(APIPermission::kIdle); 658 skip.insert(APIPermission::kIdltest); 659 skip.insert(APIPermission::kLogPrivate); 660 skip.insert(APIPermission::kNotifications); 661 skip.insert(APIPermission::kNotificationProvider); 662 skip.insert(APIPermission::kOverrideEscFullscreen); 663 skip.insert(APIPermission::kPointerLock); 664 skip.insert(APIPermission::kPower); 665 skip.insert(APIPermission::kPushMessaging); 666 skip.insert(APIPermission::kSessions); 667 skip.insert(APIPermission::kStorage); 668 skip.insert(APIPermission::kSystemCpu); 669 skip.insert(APIPermission::kSystemDisplay); 670 skip.insert(APIPermission::kSystemMemory); 671 skip.insert(APIPermission::kSystemNetwork); 672 skip.insert(APIPermission::kSystemStorage); 673 skip.insert(APIPermission::kTts); 674 skip.insert(APIPermission::kUnlimitedStorage); 675 skip.insert(APIPermission::kWebcamPrivate); 676 skip.insert(APIPermission::kWebView); 677 skip.insert(APIPermission::kWindowShape); 678 679 // These permissions are restricted to extensions force-installed by policy 680 // and don't require a prompt, i.e. they're restricted to location 'policy'. 681 skip.insert(APIPermission::kEnterprisePlatformKeys); 682 683 // TODO(erikkay) add a string for this permission. 684 skip.insert(APIPermission::kBackground); 685 686 skip.insert(APIPermission::kClipboardWrite); 687 688 // The cookie permission does nothing unless you have associated host 689 // permissions. 690 skip.insert(APIPermission::kCookie); 691 692 // These are warned as part of host permission checks. 693 skip.insert(APIPermission::kDeclarativeContent); 694 skip.insert(APIPermission::kPageCapture); 695 skip.insert(APIPermission::kProxy); 696 skip.insert(APIPermission::kTabCapture); 697 skip.insert(APIPermission::kWebRequest); 698 skip.insert(APIPermission::kWebRequestBlocking); 699 700 // This permission requires explicit user action (context menu handler) 701 // so we won't prompt for it for now. 702 skip.insert(APIPermission::kFileBrowserHandler); 703 704 // These permissions require explicit user action (configuration dialog) 705 // so we don't prompt for them at install time. 706 skip.insert(APIPermission::kMediaGalleries); 707 708 // If you've turned on the experimental command-line flag, we don't need 709 // to warn you further. 710 skip.insert(APIPermission::kExperimental); 711 712 // The Identity API has its own server-driven permission prompts. 713 skip.insert(APIPermission::kIdentity); 714 715 // These are private. 716 skip.insert(APIPermission::kAccessibilityPrivate); 717 skip.insert(APIPermission::kAutoTestPrivate); 718 skip.insert(APIPermission::kBookmarkManagerPrivate); 719 skip.insert(APIPermission::kBrailleDisplayPrivate); 720 skip.insert(APIPermission::kCast); 721 skip.insert(APIPermission::kCastStreaming); 722 skip.insert(APIPermission::kChromeosInfoPrivate); 723 skip.insert(APIPermission::kCloudPrintPrivate); 724 skip.insert(APIPermission::kCommandLinePrivate); 725 skip.insert(APIPermission::kDeveloperPrivate); 726 skip.insert(APIPermission::kDial); 727 skip.insert(APIPermission::kDownloadsInternal); 728 skip.insert(APIPermission::kEasyUnlockPrivate); 729 skip.insert(APIPermission::kEchoPrivate); 730 skip.insert(APIPermission::kEnterprisePlatformKeysPrivate); 731 skip.insert(APIPermission::kFeedbackPrivate); 732 skip.insert(APIPermission::kFileBrowserHandlerInternal); 733 skip.insert(APIPermission::kFileManagerPrivate); 734 skip.insert(APIPermission::kFirstRunPrivate); 735 skip.insert(APIPermission::kGcdPrivate); 736 skip.insert(APIPermission::kHotwordPrivate); 737 skip.insert(APIPermission::kIdentityPrivate); 738 skip.insert(APIPermission::kInfobars); 739 skip.insert(APIPermission::kInputMethodPrivate); 740 skip.insert(APIPermission::kMediaGalleriesPrivate); 741 skip.insert(APIPermission::kMediaPlayerPrivate); 742 skip.insert(APIPermission::kMetricsPrivate); 743 skip.insert(APIPermission::kMDns); 744 skip.insert(APIPermission::kPreferencesPrivate); 745 skip.insert(APIPermission::kPrincipalsPrivate); 746 skip.insert(APIPermission::kImageWriterPrivate); 747 skip.insert(APIPermission::kReadingListPrivate); 748 skip.insert(APIPermission::kRtcPrivate); 749 skip.insert(APIPermission::kStreamsPrivate); 750 skip.insert(APIPermission::kSyncedNotificationsPrivate); 751 skip.insert(APIPermission::kSystemPrivate); 752 skip.insert(APIPermission::kTabCaptureForTab); 753 skip.insert(APIPermission::kTerminalPrivate); 754 skip.insert(APIPermission::kVirtualKeyboardPrivate); 755 skip.insert(APIPermission::kWallpaperPrivate); 756 skip.insert(APIPermission::kWebrtcAudioPrivate); 757 skip.insert(APIPermission::kWebrtcLoggingPrivate); 758 skip.insert(APIPermission::kWebstorePrivate); 759 760 // Warned as part of host permissions. 761 skip.insert(APIPermission::kDevtools); 762 763 // Platform apps. 764 skip.insert(APIPermission::kBrowser); 765 skip.insert(APIPermission::kFileSystem); 766 skip.insert(APIPermission::kFileSystemProvider); 767 skip.insert(APIPermission::kFileSystemRetainEntries); 768 skip.insert(APIPermission::kFileSystemWrite); 769 skip.insert(APIPermission::kSocket); 770 skip.insert(APIPermission::kUsbDevice); 771 772 // We already have a generic message for declaring externally_connectable. 773 skip.insert(APIPermission::kExternallyConnectableAllUrls); 774 775 PermissionsInfo* info = PermissionsInfo::GetInstance(); 776 APIPermissionSet permissions = info->GetAll(); 777 for (APIPermissionSet::const_iterator i = permissions.begin(); 778 i != permissions.end(); ++i) { 779 const APIPermissionInfo* permission_info = i->info(); 780 EXPECT_TRUE(permission_info != NULL); 781 782 if (skip.count(i->id())) { 783 EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id()) 784 << "unexpected message_id for " << permission_info->name(); 785 } else { 786 EXPECT_NE(PermissionMessage::kNone, permission_info->message_id()) 787 << "missing message_id for " << permission_info->name(); 788 } 789 } 790 } 791 792 TEST(PermissionsTest, FileSystemPermissionMessages) { 793 APIPermissionSet api_permissions; 794 api_permissions.insert(APIPermission::kFileSystemWrite); 795 api_permissions.insert(APIPermission::kFileSystemDirectory); 796 scoped_refptr<PermissionSet> permissions( 797 new PermissionSet(api_permissions, ManifestPermissionSet(), 798 URLPatternSet(), URLPatternSet())); 799 PermissionMessages messages = 800 PermissionMessageProvider::Get()->GetPermissionMessages( 801 permissions.get(), Manifest::TYPE_PLATFORM_APP); 802 ASSERT_EQ(1u, messages.size()); 803 std::sort(messages.begin(), messages.end()); 804 std::set<PermissionMessage::ID> ids; 805 for (PermissionMessages::const_iterator it = messages.begin(); 806 it != messages.end(); ++it) { 807 ids.insert(it->id()); 808 } 809 EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemDirectory)); 810 } 811 812 // The file system permissions have a special-case hack to show a warning for 813 // write and directory at the same time. 814 // TODO(sammc): Remove this. See http://crbug.com/284849. 815 TEST(PermissionsTest, FileSystemImplicitPermissions) { 816 APIPermissionSet apis; 817 apis.insert(APIPermission::kFileSystemWrite); 818 apis.AddImpliedPermissions(); 819 820 EXPECT_EQ(apis.find(APIPermission::kFileSystemWrite)->id(), 821 APIPermission::kFileSystemWrite); 822 EXPECT_EQ(apis.size(), 1u); 823 824 apis.erase(APIPermission::kFileSystemWrite); 825 apis.insert(APIPermission::kFileSystemDirectory); 826 apis.AddImpliedPermissions(); 827 828 EXPECT_EQ(apis.find(APIPermission::kFileSystemDirectory)->id(), 829 APIPermission::kFileSystemDirectory); 830 EXPECT_EQ(apis.size(), 1u); 831 832 apis.insert(APIPermission::kFileSystemWrite); 833 apis.AddImpliedPermissions(); 834 835 EXPECT_EQ(apis.find(APIPermission::kFileSystemWrite)->id(), 836 APIPermission::kFileSystemWrite); 837 EXPECT_EQ(apis.find(APIPermission::kFileSystemDirectory)->id(), 838 APIPermission::kFileSystemDirectory); 839 EXPECT_EQ(apis.find(APIPermission::kFileSystemWriteDirectory)->id(), 840 APIPermission::kFileSystemWriteDirectory); 841 EXPECT_EQ(apis.size(), 3u); 842 } 843 844 TEST(PermissionsTest, HiddenFileSystemPermissionMessages) { 845 APIPermissionSet api_permissions; 846 api_permissions.insert(APIPermission::kFileSystemWrite); 847 api_permissions.insert(APIPermission::kFileSystemDirectory); 848 api_permissions.insert(APIPermission::kFileSystemWriteDirectory); 849 scoped_refptr<PermissionSet> permissions( 850 new PermissionSet(api_permissions, ManifestPermissionSet(), 851 URLPatternSet(), URLPatternSet())); 852 PermissionMessages messages = 853 PermissionMessageProvider::Get()->GetPermissionMessages( 854 permissions.get(), Manifest::TYPE_PLATFORM_APP); 855 ASSERT_EQ(1u, messages.size()); 856 EXPECT_EQ(PermissionMessage::kFileSystemWriteDirectory, messages[0].id()); 857 } 858 859 TEST(PermissionsTest, SuppressedPermissionMessages) { 860 { 861 // Tabs warning suppresses favicon warning. 862 APIPermissionSet api_permissions; 863 api_permissions.insert(APIPermission::kTab); 864 URLPatternSet hosts; 865 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, 866 "chrome://favicon/")); 867 scoped_refptr<PermissionSet> permissions( 868 new PermissionSet(api_permissions, ManifestPermissionSet(), 869 hosts, URLPatternSet())); 870 PermissionMessages messages = 871 PermissionMessageProvider::Get()->GetPermissionMessages( 872 permissions.get(), Manifest::TYPE_EXTENSION); 873 EXPECT_EQ(1u, messages.size()); 874 EXPECT_EQ(PermissionMessage::kTabs, messages[0].id()); 875 } 876 { 877 // History warning suppresses favicon warning. 878 APIPermissionSet api_permissions; 879 api_permissions.insert(APIPermission::kHistory); 880 URLPatternSet hosts; 881 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, 882 "chrome://favicon/")); 883 scoped_refptr<PermissionSet> permissions( 884 new PermissionSet(api_permissions, ManifestPermissionSet(), 885 hosts, URLPatternSet())); 886 PermissionMessages messages = 887 PermissionMessageProvider::Get()->GetPermissionMessages( 888 permissions.get(), Manifest::TYPE_EXTENSION); 889 EXPECT_EQ(1u, messages.size()); 890 EXPECT_EQ(PermissionMessage::kBrowsingHistory, messages[0].id()); 891 } 892 { 893 // All sites warning suppresses tabs warning. 894 APIPermissionSet api_permissions; 895 URLPatternSet hosts; 896 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, "*://*/*")); 897 api_permissions.insert(APIPermission::kTab); 898 scoped_refptr<PermissionSet> permissions(new PermissionSet( 899 api_permissions, ManifestPermissionSet(), hosts, URLPatternSet())); 900 PermissionMessages messages = 901 PermissionMessageProvider::Get()->GetPermissionMessages( 902 permissions.get(), Manifest::TYPE_EXTENSION); 903 EXPECT_EQ(1u, messages.size()); 904 EXPECT_EQ(PermissionMessage::kHostsAll, messages[0].id()); 905 } 906 { 907 // All sites warning suppresses topSites warning. 908 APIPermissionSet api_permissions; 909 URLPatternSet hosts; 910 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, "*://*/*")); 911 api_permissions.insert(APIPermission::kTopSites); 912 scoped_refptr<PermissionSet> permissions(new PermissionSet( 913 api_permissions, ManifestPermissionSet(), hosts, URLPatternSet())); 914 PermissionMessages messages = 915 PermissionMessageProvider::Get()->GetPermissionMessages( 916 permissions.get(), Manifest::TYPE_EXTENSION); 917 EXPECT_EQ(1u, messages.size()); 918 EXPECT_EQ(PermissionMessage::kHostsAll, messages[0].id()); 919 } 920 { 921 // All sites warning suppresses declarativeWebRequest warning. 922 APIPermissionSet api_permissions; 923 URLPatternSet hosts; 924 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, "*://*/*")); 925 api_permissions.insert(APIPermission::kDeclarativeWebRequest); 926 scoped_refptr<PermissionSet> permissions(new PermissionSet( 927 api_permissions, ManifestPermissionSet(), hosts, URLPatternSet())); 928 PermissionMessages messages = 929 PermissionMessageProvider::Get()->GetPermissionMessages( 930 permissions.get(), Manifest::TYPE_EXTENSION); 931 EXPECT_EQ(1u, messages.size()); 932 EXPECT_EQ(PermissionMessage::kHostsAll, messages[0].id()); 933 } 934 { 935 // BrowsingHistory warning suppresses all history read/write warnings. 936 APIPermissionSet api_permissions; 937 api_permissions.insert(APIPermission::kHistory); 938 api_permissions.insert(APIPermission::kTab); 939 api_permissions.insert(APIPermission::kTopSites); 940 api_permissions.insert(APIPermission::kProcesses); 941 api_permissions.insert(APIPermission::kWebNavigation); 942 scoped_refptr<PermissionSet> permissions( 943 new PermissionSet(api_permissions, ManifestPermissionSet(), 944 URLPatternSet(), URLPatternSet())); 945 PermissionMessages messages = 946 PermissionMessageProvider::Get()->GetPermissionMessages( 947 permissions.get(), Manifest::TYPE_EXTENSION); 948 EXPECT_EQ(1u, messages.size()); 949 EXPECT_EQ(PermissionMessage::kBrowsingHistory, messages[0].id()); 950 } 951 { 952 // Tabs warning suppresses all read-only history warnings. 953 APIPermissionSet api_permissions; 954 api_permissions.insert(APIPermission::kTab); 955 api_permissions.insert(APIPermission::kTopSites); 956 api_permissions.insert(APIPermission::kProcesses); 957 api_permissions.insert(APIPermission::kWebNavigation); 958 scoped_refptr<PermissionSet> permissions( 959 new PermissionSet(api_permissions, ManifestPermissionSet(), 960 URLPatternSet(), URLPatternSet())); 961 PermissionMessages messages = 962 PermissionMessageProvider::Get()->GetPermissionMessages( 963 permissions.get(), Manifest::TYPE_EXTENSION); 964 EXPECT_EQ(1u, messages.size()); 965 EXPECT_EQ(PermissionMessage::kTabs, messages[0].id()); 966 } 967 } 968 969 TEST(PermissionsTest, AccessToDevicesMessages) { 970 { 971 APIPermissionSet api_permissions; 972 api_permissions.insert(APIPermission::kUsb); 973 scoped_refptr<PermissionSet> permissions( 974 new PermissionSet(api_permissions, 975 ManifestPermissionSet(), 976 URLPatternSet(), 977 URLPatternSet())); 978 std::vector<base::string16> messages = 979 PermissionMessageProvider::Get()->GetWarningMessages( 980 permissions.get(), Manifest::TYPE_EXTENSION); 981 EXPECT_EQ(1u, messages.size()); 982 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB), 983 messages[0]); 984 } 985 { 986 // Testing that multiple permissions will show the one message. 987 APIPermissionSet api_permissions; 988 api_permissions.insert(APIPermission::kUsb); 989 api_permissions.insert(APIPermission::kUsb); 990 scoped_refptr<PermissionSet> permissions( 991 new PermissionSet(api_permissions, 992 ManifestPermissionSet(), 993 URLPatternSet(), 994 URLPatternSet())); 995 std::vector<base::string16> messages = 996 PermissionMessageProvider::Get()->GetWarningMessages( 997 permissions.get(), Manifest::TYPE_EXTENSION); 998 EXPECT_EQ(1u, messages.size()); 999 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB), 1000 messages[0]); 1001 } 1002 { 1003 APIPermissionSet api_permissions; 1004 api_permissions.insert(APIPermission::kSerial); 1005 scoped_refptr<PermissionSet> permissions( 1006 new PermissionSet(api_permissions, 1007 ManifestPermissionSet(), 1008 URLPatternSet(), 1009 URLPatternSet())); 1010 std::vector<base::string16> messages = 1011 PermissionMessageProvider::Get()->GetWarningMessages( 1012 permissions.get(), Manifest::TYPE_EXTENSION); 1013 EXPECT_EQ(1u, messages.size()); 1014 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_SERIAL), 1015 messages[0]); 1016 } 1017 { 1018 APIPermissionSet api_permissions; 1019 api_permissions.insert(APIPermission::kUsb); 1020 api_permissions.insert(APIPermission::kSerial); 1021 scoped_refptr<PermissionSet> permissions( 1022 new PermissionSet(api_permissions, 1023 ManifestPermissionSet(), 1024 URLPatternSet(), 1025 URLPatternSet())); 1026 std::vector<base::string16> messages = 1027 PermissionMessageProvider::Get()->GetWarningMessages( 1028 permissions.get(), Manifest::TYPE_EXTENSION); 1029 EXPECT_EQ(1u, messages.size()); 1030 EXPECT_EQ( 1031 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_SERIAL), 1032 messages[0]); 1033 } 1034 { 1035 // Testing that the same permission(s) will show one message. 1036 APIPermissionSet api_permissions; 1037 api_permissions.insert(APIPermission::kUsb); 1038 api_permissions.insert(APIPermission::kSerial); 1039 api_permissions.insert(APIPermission::kUsb); 1040 scoped_refptr<PermissionSet> permissions( 1041 new PermissionSet(api_permissions, 1042 ManifestPermissionSet(), 1043 URLPatternSet(), 1044 URLPatternSet())); 1045 std::vector<base::string16> messages = 1046 PermissionMessageProvider::Get()->GetWarningMessages( 1047 permissions.get(), Manifest::TYPE_EXTENSION); 1048 EXPECT_EQ(1u, messages.size()); 1049 EXPECT_EQ( 1050 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_SERIAL), 1051 messages[0]); 1052 } 1053 { 1054 scoped_refptr<Extension> extension = 1055 LoadManifest("permissions", "access_to_devices_bluetooth.json"); 1056 const PermissionMessageProvider* provider = 1057 PermissionMessageProvider::Get(); 1058 PermissionSet* set = const_cast<PermissionSet*>( 1059 extension->permissions_data()->active_permissions().get()); 1060 std::vector<base::string16> warnings = 1061 provider->GetWarningMessages(set, extension->GetType()); 1062 EXPECT_EQ(1u, warnings.size()); 1063 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH), 1064 warnings[0]); 1065 1066 // Test Bluetooth and Serial 1067 set->apis_.insert(APIPermission::kSerial); 1068 warnings = provider->GetWarningMessages(set, extension->GetType()); 1069 EXPECT_EQ(1u, warnings.size()); 1070 EXPECT_EQ(l10n_util::GetStringUTF16( 1071 IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_SERIAL), 1072 warnings[0]); 1073 set->apis_.erase(APIPermission::kSerial); 1074 1075 // Test USB and Bluetooth 1076 set->apis_.insert(APIPermission::kUsb); 1077 warnings = provider->GetWarningMessages(set, extension->GetType()); 1078 EXPECT_EQ(1u, warnings.size()); 1079 EXPECT_EQ( 1080 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_BLUETOOTH), 1081 warnings[0]); 1082 1083 // Test USB, Bluetooth and Serial 1084 set->apis_.insert(APIPermission::kSerial); 1085 warnings = provider->GetWarningMessages(set, extension->GetType()); 1086 EXPECT_EQ(1u, warnings.size()); 1087 EXPECT_EQ( 1088 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_DEVICES), 1089 warnings[0]); 1090 } 1091 } 1092 1093 TEST(PermissionsTest, MergedFileSystemPermissionComparison) { 1094 APIPermissionSet write_api_permissions; 1095 write_api_permissions.insert(APIPermission::kFileSystemWrite); 1096 scoped_refptr<PermissionSet> write_permissions( 1097 new PermissionSet(write_api_permissions, ManifestPermissionSet(), 1098 URLPatternSet(), URLPatternSet())); 1099 1100 APIPermissionSet directory_api_permissions; 1101 directory_api_permissions.insert(APIPermission::kFileSystemDirectory); 1102 scoped_refptr<PermissionSet> directory_permissions( 1103 new PermissionSet(directory_api_permissions, ManifestPermissionSet(), 1104 URLPatternSet(), URLPatternSet())); 1105 1106 APIPermissionSet write_directory_api_permissions; 1107 write_directory_api_permissions.insert( 1108 APIPermission::kFileSystemWriteDirectory); 1109 scoped_refptr<PermissionSet> write_directory_permissions( 1110 new PermissionSet(write_directory_api_permissions, 1111 ManifestPermissionSet(), 1112 URLPatternSet(), 1113 URLPatternSet())); 1114 1115 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1116 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions.get(), 1117 write_permissions.get(), 1118 Manifest::TYPE_PLATFORM_APP)); 1119 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions.get(), 1120 directory_permissions.get(), 1121 Manifest::TYPE_PLATFORM_APP)); 1122 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions.get(), 1123 directory_permissions.get(), 1124 Manifest::TYPE_PLATFORM_APP)); 1125 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions.get(), 1126 write_directory_permissions.get(), 1127 Manifest::TYPE_PLATFORM_APP)); 1128 EXPECT_FALSE(provider->IsPrivilegeIncrease(directory_permissions.get(), 1129 write_permissions.get(), 1130 Manifest::TYPE_PLATFORM_APP)); 1131 EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions.get(), 1132 write_directory_permissions.get(), 1133 Manifest::TYPE_PLATFORM_APP)); 1134 } 1135 1136 TEST(PermissionsTest, GetWarningMessages_ManyHosts) { 1137 scoped_refptr<Extension> extension; 1138 1139 extension = LoadManifest("permissions", "many-hosts.json"); 1140 std::vector<base::string16> warnings = 1141 extension->permissions_data()->GetPermissionMessageStrings(); 1142 ASSERT_EQ(1u, warnings.size()); 1143 EXPECT_EQ( 1144 "Read and change your data on encrypted.google.com and " 1145 "www.google.com", 1146 base::UTF16ToUTF8(warnings[0])); 1147 } 1148 1149 TEST(PermissionsTest, GetWarningMessages_Plugins) { 1150 scoped_refptr<Extension> extension; 1151 scoped_refptr<PermissionSet> permissions; 1152 1153 extension = LoadManifest("permissions", "plugins.json"); 1154 std::vector<base::string16> warnings = 1155 extension->permissions_data()->GetPermissionMessageStrings(); 1156 // We don't parse the plugins key on Chrome OS, so it should not ask for any 1157 // permissions. 1158 #if defined(OS_CHROMEOS) 1159 ASSERT_EQ(0u, warnings.size()); 1160 #else 1161 ASSERT_EQ(1u, warnings.size()); 1162 EXPECT_EQ( 1163 "Read and change all your data on your computer and the websites " 1164 "you visit", 1165 base::UTF16ToUTF8(warnings[0])); 1166 #endif 1167 } 1168 1169 TEST(PermissionsTest, GetWarningMessages_AudioVideo) { 1170 // Both audio and video present. 1171 scoped_refptr<Extension> extension = 1172 LoadManifest("permissions", "audio-video.json"); 1173 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1174 PermissionSet* set = const_cast<PermissionSet*>( 1175 extension->permissions_data()->active_permissions().get()); 1176 std::vector<base::string16> warnings = 1177 provider->GetWarningMessages(set, extension->GetType()); 1178 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 1179 EXPECT_FALSE(Contains(warnings, "Use your camera")); 1180 EXPECT_TRUE(Contains(warnings, "Use your microphone and camera")); 1181 size_t combined_index = IndexOf(warnings, "Use your microphone and camera"); 1182 size_t combined_size = warnings.size(); 1183 1184 // Just audio present. 1185 set->apis_.erase(APIPermission::kVideoCapture); 1186 warnings = provider->GetWarningMessages(set, extension->GetType()); 1187 EXPECT_EQ(combined_size, warnings.size()); 1188 EXPECT_EQ(combined_index, IndexOf(warnings, "Use your microphone")); 1189 EXPECT_FALSE(Contains(warnings, "Use your camera")); 1190 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 1191 1192 // Just video present. 1193 set->apis_.erase(APIPermission::kAudioCapture); 1194 set->apis_.insert(APIPermission::kVideoCapture); 1195 warnings = provider->GetWarningMessages(set, extension->GetType()); 1196 EXPECT_EQ(combined_size, warnings.size()); 1197 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 1198 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 1199 EXPECT_TRUE(Contains(warnings, "Use your camera")); 1200 } 1201 1202 TEST(PermissionsTest, GetWarningMessages_CombinedSessions) { 1203 { 1204 APIPermissionSet api_permissions; 1205 api_permissions.insert(APIPermission::kTab); 1206 api_permissions.insert(APIPermission::kTopSites); 1207 api_permissions.insert(APIPermission::kProcesses); 1208 api_permissions.insert(APIPermission::kWebNavigation); 1209 api_permissions.insert(APIPermission::kSessions); 1210 scoped_refptr<PermissionSet> permissions( 1211 new PermissionSet(api_permissions, ManifestPermissionSet(), 1212 URLPatternSet(), URLPatternSet())); 1213 std::vector<base::string16> messages = 1214 PermissionMessageProvider::Get()->GetWarningMessages( 1215 permissions.get(), Manifest::TYPE_EXTENSION); 1216 EXPECT_EQ(1u, messages.size()); 1217 EXPECT_EQ(l10n_util::GetStringUTF16( 1218 IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ_AND_SESSIONS), 1219 messages[0]); 1220 } 1221 { 1222 APIPermissionSet api_permissions; 1223 api_permissions.insert(APIPermission::kHistory); 1224 api_permissions.insert(APIPermission::kTab); 1225 api_permissions.insert(APIPermission::kTopSites); 1226 api_permissions.insert(APIPermission::kProcesses); 1227 api_permissions.insert(APIPermission::kWebNavigation); 1228 api_permissions.insert(APIPermission::kSessions); 1229 scoped_refptr<PermissionSet> permissions( 1230 new PermissionSet(api_permissions, ManifestPermissionSet(), 1231 URLPatternSet(), URLPatternSet())); 1232 std::vector<base::string16> messages = 1233 PermissionMessageProvider::Get()->GetWarningMessages( 1234 permissions.get(), Manifest::TYPE_EXTENSION); 1235 EXPECT_EQ(1u, messages.size()); 1236 EXPECT_EQ(l10n_util::GetStringUTF16( 1237 IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_AND_SESSIONS), 1238 messages[0]); 1239 } 1240 } 1241 1242 TEST(PermissionsTest, GetWarningMessages_DeclarativeWebRequest) { 1243 // Test that if the declarativeWebRequest permission is present 1244 // in combination with all hosts permission, then only the warning 1245 // for host permissions is shown, because that covers the use of 1246 // declarativeWebRequest. 1247 1248 // Until Declarative Web Request is in stable, let's make sure it is enabled 1249 // on the current channel. 1250 ScopedCurrentChannel sc(chrome::VersionInfo::CHANNEL_CANARY); 1251 1252 // First verify that declarativeWebRequest produces a message when host 1253 // permissions do not cover all hosts. 1254 scoped_refptr<Extension> extension = 1255 LoadManifest("permissions", "web_request_not_all_host_permissions.json"); 1256 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1257 const PermissionSet* set = 1258 extension->permissions_data()->active_permissions().get(); 1259 std::vector<base::string16> warnings = 1260 provider->GetWarningMessages(set, extension->GetType()); 1261 EXPECT_TRUE(Contains(warnings, "Block parts of web pages")); 1262 EXPECT_FALSE(Contains( 1263 warnings, "Read and change all your data on the websites you visit")); 1264 1265 // Now verify that declarativeWebRequest does not produce a message when host 1266 // permissions do cover all hosts. 1267 extension = 1268 LoadManifest("permissions", "web_request_all_host_permissions.json"); 1269 set = extension->permissions_data()->active_permissions().get(); 1270 warnings = provider->GetWarningMessages(set, extension->GetType()); 1271 EXPECT_FALSE(Contains(warnings, "Block parts of web pages")); 1272 EXPECT_TRUE(Contains( 1273 warnings, "Read and change all your data on the websites you visit")); 1274 } 1275 1276 TEST(PermissionsTest, GetWarningMessages_Serial) { 1277 scoped_refptr<Extension> extension = 1278 LoadManifest("permissions", "serial.json"); 1279 1280 EXPECT_TRUE(extension->is_platform_app()); 1281 EXPECT_TRUE( 1282 extension->permissions_data()->HasAPIPermission(APIPermission::kSerial)); 1283 std::vector<base::string16> warnings = 1284 extension->permissions_data()->GetPermissionMessageStrings(); 1285 EXPECT_TRUE(Contains(warnings, "Access your serial devices")); 1286 ASSERT_EQ(1u, warnings.size()); 1287 } 1288 1289 TEST(PermissionsTest, GetWarningMessages_Socket_AnyHost) { 1290 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 1291 1292 scoped_refptr<Extension> extension = 1293 LoadManifest("permissions", "socket_any_host.json"); 1294 EXPECT_TRUE(extension->is_platform_app()); 1295 EXPECT_TRUE( 1296 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket)); 1297 std::vector<base::string16> warnings = 1298 extension->permissions_data()->GetPermissionMessageStrings(); 1299 EXPECT_EQ(1u, warnings.size()); 1300 EXPECT_TRUE(Contains(warnings, "Exchange data with any computer " 1301 "on the local network or internet")); 1302 } 1303 1304 TEST(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) { 1305 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 1306 1307 scoped_refptr<Extension> extension = 1308 LoadManifest("permissions", "socket_one_domain_two_hostnames.json"); 1309 EXPECT_TRUE(extension->is_platform_app()); 1310 EXPECT_TRUE( 1311 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket)); 1312 std::vector<base::string16> warnings = 1313 extension->permissions_data()->GetPermissionMessageStrings(); 1314 1315 // Verify the warnings, including support for unicode characters, the fact 1316 // that domain host warnings come before specific host warnings, and the fact 1317 // that domains and hostnames are in alphabetical order regardless of the 1318 // order in the manifest file. 1319 EXPECT_EQ(2u, warnings.size()); 1320 if (warnings.size() > 0) 1321 EXPECT_EQ(warnings[0], 1322 base::UTF8ToUTF16("Exchange data with any computer in the domain " 1323 "example.org")); 1324 if (warnings.size() > 1) 1325 EXPECT_EQ(warnings[1], 1326 base::UTF8ToUTF16("Exchange data with the computers named: " 1327 "b\xC3\xA5r.example.com foo.example.com")); 1328 // "\xC3\xA5" = UTF-8 for lowercase A with ring above 1329 } 1330 1331 TEST(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) { 1332 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 1333 1334 scoped_refptr<Extension> extension = 1335 LoadManifest("permissions", "socket_two_domains_one_hostname.json"); 1336 EXPECT_TRUE(extension->is_platform_app()); 1337 EXPECT_TRUE( 1338 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket)); 1339 std::vector<base::string16> warnings = 1340 extension->permissions_data()->GetPermissionMessageStrings(); 1341 1342 // Verify the warnings, including the fact that domain host warnings come 1343 // before specific host warnings and the fact that domains and hostnames are 1344 // in alphabetical order regardless of the order in the manifest file. 1345 EXPECT_EQ(2u, warnings.size()); 1346 if (warnings.size() > 0) 1347 EXPECT_EQ(warnings[0], 1348 base::UTF8ToUTF16("Exchange data with any computer in the " 1349 "domains: example.com foo.example.org")); 1350 if (warnings.size() > 1) 1351 EXPECT_EQ(warnings[1], 1352 base::UTF8ToUTF16("Exchange data with the computer named " 1353 "bar.example.org")); 1354 } 1355 1356 TEST(PermissionsTest, GetWarningMessages_PlatformApppHosts) { 1357 scoped_refptr<Extension> extension; 1358 1359 extension = LoadManifest("permissions", "platform_app_hosts.json"); 1360 EXPECT_TRUE(extension->is_platform_app()); 1361 std::vector<base::string16> warnings = 1362 extension->permissions_data()->GetPermissionMessageStrings(); 1363 ASSERT_EQ(0u, warnings.size()); 1364 1365 extension = LoadManifest("permissions", "platform_app_all_urls.json"); 1366 EXPECT_TRUE(extension->is_platform_app()); 1367 warnings = extension->permissions_data()->GetPermissionMessageStrings(); 1368 ASSERT_EQ(0u, warnings.size()); 1369 } 1370 1371 bool ShowsAllHostsWarning(const std::string& pattern) { 1372 scoped_refptr<Extension> extension = 1373 ExtensionBuilder() 1374 .SetManifest(DictionaryBuilder() 1375 .Set("name", "TLDWildCardTest") 1376 .Set("version", "0.1.0") 1377 .Set("permissions", ListBuilder().Append(pattern)) 1378 .Build()) 1379 .Build(); 1380 1381 std::vector<base::string16> warnings = 1382 extension->permissions_data()->GetPermissionMessageStrings(); 1383 1384 if (warnings.empty()) 1385 return false; 1386 1387 if (warnings[0] != 1388 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)) { 1389 return false; 1390 } 1391 1392 return true; 1393 } 1394 1395 TEST(PermissionsTest, GetWarningMessages_TLDWildcardTreatedAsAllHosts) { 1396 EXPECT_TRUE(ShowsAllHostsWarning("http://*.com/*")); // most popular. 1397 EXPECT_TRUE(ShowsAllHostsWarning("http://*.org/*")); // sanity check. 1398 EXPECT_TRUE(ShowsAllHostsWarning("http://*.co.uk/*")); // eTLD. 1399 EXPECT_TRUE(ShowsAllHostsWarning("http://*.de/*")); // foreign country tld. 1400 1401 // We should still show the normal permissions (i.e., "Can access your data on 1402 // *.rdcronin.com") for things that are not TLDs. 1403 EXPECT_FALSE(ShowsAllHostsWarning("http://*.rdcronin.com/*")); 1404 1405 // Pseudo-TLDs, like appspot.com, should not show all hosts. 1406 EXPECT_FALSE(ShowsAllHostsWarning("http://*.appspot.com/*")); 1407 1408 // Non-TLDs should be likewise exempt. 1409 EXPECT_FALSE(ShowsAllHostsWarning("http://*.notarealtld/*")); 1410 1411 // Our internal checks use "foo", so let's make sure we're not messing 1412 // something up with it. 1413 EXPECT_FALSE(ShowsAllHostsWarning("http://*.foo.com")); 1414 EXPECT_FALSE(ShowsAllHostsWarning("http://foo.com")); 1415 // This will fail if foo becomes a recognized TLD. Which could be soon. 1416 // Update as needed. 1417 EXPECT_FALSE(ShowsAllHostsWarning("http://*.foo")); 1418 } 1419 1420 TEST(PermissionsTest, GetDistinctHosts) { 1421 URLPatternSet explicit_hosts; 1422 std::set<std::string> expected; 1423 expected.insert("www.foo.com"); 1424 expected.insert("www.bar.com"); 1425 expected.insert("www.baz.com"); 1426 1427 { 1428 SCOPED_TRACE("no dupes"); 1429 1430 // Simple list with no dupes. 1431 explicit_hosts.AddPattern( 1432 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1433 explicit_hosts.AddPattern( 1434 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path")); 1435 explicit_hosts.AddPattern( 1436 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 1437 EXPECT_EQ(expected, 1438 permission_message_util::GetDistinctHosts( 1439 explicit_hosts, true, true)); 1440 } 1441 1442 { 1443 SCOPED_TRACE("two dupes"); 1444 1445 // Add some dupes. 1446 explicit_hosts.AddPattern( 1447 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1448 explicit_hosts.AddPattern( 1449 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 1450 EXPECT_EQ(expected, 1451 permission_message_util::GetDistinctHosts( 1452 explicit_hosts, true, true)); 1453 } 1454 1455 { 1456 SCOPED_TRACE("schemes differ"); 1457 1458 // Add a pattern that differs only by scheme. This should be filtered out. 1459 explicit_hosts.AddPattern( 1460 URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path")); 1461 EXPECT_EQ(expected, 1462 permission_message_util::GetDistinctHosts( 1463 explicit_hosts, true, true)); 1464 } 1465 1466 { 1467 SCOPED_TRACE("paths differ"); 1468 1469 // Add some dupes by path. 1470 explicit_hosts.AddPattern( 1471 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath")); 1472 EXPECT_EQ(expected, 1473 permission_message_util::GetDistinctHosts( 1474 explicit_hosts, true, true)); 1475 } 1476 1477 { 1478 SCOPED_TRACE("subdomains differ"); 1479 1480 // We don't do anything special for subdomains. 1481 explicit_hosts.AddPattern( 1482 URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path")); 1483 explicit_hosts.AddPattern( 1484 URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path")); 1485 1486 expected.insert("monkey.www.bar.com"); 1487 expected.insert("bar.com"); 1488 1489 EXPECT_EQ(expected, 1490 permission_message_util::GetDistinctHosts( 1491 explicit_hosts, true, true)); 1492 } 1493 1494 { 1495 SCOPED_TRACE("RCDs differ"); 1496 1497 // Now test for RCD uniquing. 1498 explicit_hosts.AddPattern( 1499 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1500 explicit_hosts.AddPattern( 1501 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1502 explicit_hosts.AddPattern( 1503 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path")); 1504 explicit_hosts.AddPattern( 1505 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path")); 1506 explicit_hosts.AddPattern( 1507 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1508 explicit_hosts.AddPattern( 1509 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path")); 1510 1511 // This is an unknown RCD, which shouldn't be uniqued out. 1512 explicit_hosts.AddPattern( 1513 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1514 // But it should only occur once. 1515 explicit_hosts.AddPattern( 1516 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1517 1518 expected.insert("www.foo.xyzzy"); 1519 1520 EXPECT_EQ(expected, 1521 permission_message_util::GetDistinctHosts( 1522 explicit_hosts, true, true)); 1523 } 1524 1525 { 1526 SCOPED_TRACE("wildcards"); 1527 1528 explicit_hosts.AddPattern( 1529 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1530 1531 expected.insert("*.google.com"); 1532 1533 EXPECT_EQ(expected, 1534 permission_message_util::GetDistinctHosts( 1535 explicit_hosts, true, true)); 1536 } 1537 1538 { 1539 SCOPED_TRACE("scriptable hosts"); 1540 1541 APIPermissionSet empty_perms; 1542 explicit_hosts.ClearPatterns(); 1543 URLPatternSet scriptable_hosts; 1544 expected.clear(); 1545 1546 explicit_hosts.AddPattern( 1547 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1548 scriptable_hosts.AddPattern( 1549 URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*")); 1550 1551 expected.insert("*.google.com"); 1552 expected.insert("*.example.com"); 1553 1554 scoped_refptr<PermissionSet> perm_set(new PermissionSet( 1555 empty_perms, ManifestPermissionSet(), 1556 explicit_hosts, scriptable_hosts)); 1557 EXPECT_EQ(expected, 1558 permission_message_util::GetDistinctHosts( 1559 perm_set->effective_hosts(), true, true)); 1560 } 1561 1562 { 1563 // We don't display warnings for file URLs because they are off by default. 1564 SCOPED_TRACE("file urls"); 1565 1566 explicit_hosts.ClearPatterns(); 1567 expected.clear(); 1568 1569 explicit_hosts.AddPattern( 1570 URLPattern(URLPattern::SCHEME_FILE, "file:///*")); 1571 1572 EXPECT_EQ(expected, 1573 permission_message_util::GetDistinctHosts( 1574 explicit_hosts, true, true)); 1575 } 1576 } 1577 1578 TEST(PermissionsTest, GetDistinctHosts_ComIsBestRcd) { 1579 URLPatternSet explicit_hosts; 1580 explicit_hosts.AddPattern( 1581 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1582 explicit_hosts.AddPattern( 1583 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1584 explicit_hosts.AddPattern( 1585 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1586 explicit_hosts.AddPattern( 1587 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1588 explicit_hosts.AddPattern( 1589 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1590 explicit_hosts.AddPattern( 1591 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1592 1593 std::set<std::string> expected; 1594 expected.insert("www.foo.com"); 1595 EXPECT_EQ(expected, 1596 permission_message_util::GetDistinctHosts( 1597 explicit_hosts, true, true)); 1598 } 1599 1600 TEST(PermissionsTest, GetDistinctHosts_NetIs2ndBestRcd) { 1601 URLPatternSet explicit_hosts; 1602 explicit_hosts.AddPattern( 1603 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1604 explicit_hosts.AddPattern( 1605 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1606 explicit_hosts.AddPattern( 1607 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1608 explicit_hosts.AddPattern( 1609 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1610 explicit_hosts.AddPattern( 1611 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1612 // No http://www.foo.com/path 1613 1614 std::set<std::string> expected; 1615 expected.insert("www.foo.net"); 1616 EXPECT_EQ(expected, 1617 permission_message_util::GetDistinctHosts( 1618 explicit_hosts, true, true)); 1619 } 1620 1621 TEST(PermissionsTest, GetDistinctHosts_OrgIs3rdBestRcd) { 1622 URLPatternSet explicit_hosts; 1623 explicit_hosts.AddPattern( 1624 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1625 explicit_hosts.AddPattern( 1626 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1627 explicit_hosts.AddPattern( 1628 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1629 // No http://www.foo.net/path 1630 explicit_hosts.AddPattern( 1631 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1632 // No http://www.foo.com/path 1633 1634 std::set<std::string> expected; 1635 expected.insert("www.foo.org"); 1636 EXPECT_EQ(expected, 1637 permission_message_util::GetDistinctHosts( 1638 explicit_hosts, true, true)); 1639 } 1640 1641 TEST(PermissionsTest, GetDistinctHosts_FirstInListIs4thBestRcd) { 1642 URLPatternSet explicit_hosts; 1643 explicit_hosts.AddPattern( 1644 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1645 // No http://www.foo.org/path 1646 explicit_hosts.AddPattern( 1647 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1648 // No http://www.foo.net/path 1649 explicit_hosts.AddPattern( 1650 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1651 // No http://www.foo.com/path 1652 1653 std::set<std::string> expected; 1654 expected.insert("www.foo.ca"); 1655 EXPECT_EQ(expected, 1656 permission_message_util::GetDistinctHosts( 1657 explicit_hosts, true, true)); 1658 } 1659 1660 TEST(PermissionsTest, IsHostPrivilegeIncrease) { 1661 Manifest::Type type = Manifest::TYPE_EXTENSION; 1662 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1663 ManifestPermissionSet empty_manifest_permissions; 1664 URLPatternSet elist1; 1665 URLPatternSet elist2; 1666 URLPatternSet slist1; 1667 URLPatternSet slist2; 1668 scoped_refptr<PermissionSet> set1; 1669 scoped_refptr<PermissionSet> set2; 1670 APIPermissionSet empty_perms; 1671 elist1.AddPattern( 1672 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1673 elist1.AddPattern( 1674 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1675 1676 // Test that the host order does not matter. 1677 elist2.AddPattern( 1678 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1679 elist2.AddPattern( 1680 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1681 1682 set1 = new PermissionSet(empty_perms, empty_manifest_permissions, 1683 elist1, slist1); 1684 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1685 elist2, slist2); 1686 1687 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type)); 1688 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type)); 1689 1690 // Test that paths are ignored. 1691 elist2.ClearPatterns(); 1692 elist2.AddPattern( 1693 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*")); 1694 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1695 elist2, slist2); 1696 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type)); 1697 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type)); 1698 1699 // Test that RCDs are ignored. 1700 elist2.ClearPatterns(); 1701 elist2.AddPattern( 1702 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*")); 1703 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1704 elist2, slist2); 1705 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type)); 1706 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type)); 1707 1708 // Test that subdomain wildcards are handled properly. 1709 elist2.ClearPatterns(); 1710 elist2.AddPattern( 1711 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*")); 1712 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1713 elist2, slist2); 1714 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type)); 1715 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337 1716 // EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1717 1718 // Test that different domains count as different hosts. 1719 elist2.ClearPatterns(); 1720 elist2.AddPattern( 1721 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1722 elist2.AddPattern( 1723 URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path")); 1724 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1725 elist2, slist2); 1726 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type)); 1727 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type)); 1728 1729 // Test that different subdomains count as different hosts. 1730 elist2.ClearPatterns(); 1731 elist2.AddPattern( 1732 URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*")); 1733 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1734 elist2, slist2); 1735 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type)); 1736 EXPECT_TRUE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type)); 1737 1738 // Test that platform apps do not have host permissions increases. 1739 type = Manifest::TYPE_PLATFORM_APP; 1740 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1.get(), set2.get(), type)); 1741 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2.get(), set1.get(), type)); 1742 } 1743 1744 TEST(PermissionsTest, GetAPIsAsStrings) { 1745 APIPermissionSet apis; 1746 URLPatternSet empty_set; 1747 1748 apis.insert(APIPermission::kProxy); 1749 apis.insert(APIPermission::kBackground); 1750 apis.insert(APIPermission::kNotifications); 1751 apis.insert(APIPermission::kTab); 1752 1753 scoped_refptr<PermissionSet> perm_set = new PermissionSet( 1754 apis, ManifestPermissionSet(), empty_set, empty_set); 1755 std::set<std::string> api_names = perm_set->GetAPIsAsStrings(); 1756 1757 // The result is correct if it has the same number of elements 1758 // and we can convert it back to the id set. 1759 EXPECT_EQ(4u, api_names.size()); 1760 EXPECT_EQ(apis, 1761 PermissionsInfo::GetInstance()->GetAllByName(api_names)); 1762 } 1763 1764 TEST(PermissionsTest, IsEmpty) { 1765 APIPermissionSet empty_apis; 1766 URLPatternSet empty_extent; 1767 1768 scoped_refptr<PermissionSet> empty = new PermissionSet(); 1769 EXPECT_TRUE(empty->IsEmpty()); 1770 scoped_refptr<PermissionSet> perm_set; 1771 1772 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1773 empty_extent, empty_extent); 1774 EXPECT_TRUE(perm_set->IsEmpty()); 1775 1776 APIPermissionSet non_empty_apis; 1777 non_empty_apis.insert(APIPermission::kBackground); 1778 perm_set = new PermissionSet(non_empty_apis, ManifestPermissionSet(), 1779 empty_extent, empty_extent); 1780 EXPECT_FALSE(perm_set->IsEmpty()); 1781 1782 // Try non standard host 1783 URLPatternSet non_empty_extent; 1784 AddPattern(&non_empty_extent, "http://www.google.com/*"); 1785 1786 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1787 non_empty_extent, empty_extent); 1788 EXPECT_FALSE(perm_set->IsEmpty()); 1789 1790 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1791 empty_extent, non_empty_extent); 1792 EXPECT_FALSE(perm_set->IsEmpty()); 1793 } 1794 1795 TEST(PermissionsTest, ImpliedPermissions) { 1796 URLPatternSet empty_extent; 1797 APIPermissionSet apis; 1798 apis.insert(APIPermission::kFileBrowserHandler); 1799 EXPECT_EQ(1U, apis.size()); 1800 1801 scoped_refptr<PermissionSet> perm_set; 1802 perm_set = new PermissionSet(apis, ManifestPermissionSet(), 1803 empty_extent, empty_extent); 1804 EXPECT_EQ(2U, perm_set->apis().size()); 1805 } 1806 1807 TEST(PermissionsTest, SyncFileSystemPermission) { 1808 scoped_refptr<Extension> extension = LoadManifest( 1809 "permissions", "sync_file_system.json"); 1810 APIPermissionSet apis; 1811 apis.insert(APIPermission::kSyncFileSystem); 1812 EXPECT_TRUE(extension->is_platform_app()); 1813 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission( 1814 APIPermission::kSyncFileSystem)); 1815 std::vector<base::string16> warnings = 1816 extension->permissions_data()->GetPermissionMessageStrings(); 1817 EXPECT_TRUE(Contains(warnings, "Store data in your Google Drive account")); 1818 ASSERT_EQ(1u, warnings.size()); 1819 } 1820 1821 // Make sure that we don't crash when we're trying to show the permissions 1822 // even though chrome://thumb (and everything that's not chrome://favicon with 1823 // a chrome:// scheme) is not a valid permission. 1824 // More details here: crbug/246314. 1825 TEST(PermissionsTest, ChromeURLs) { 1826 URLPatternSet allowed_hosts; 1827 allowed_hosts.AddPattern( 1828 URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/")); 1829 allowed_hosts.AddPattern( 1830 URLPattern(URLPattern::SCHEME_ALL, "chrome://favicon/")); 1831 allowed_hosts.AddPattern( 1832 URLPattern(URLPattern::SCHEME_ALL, "chrome://thumb/")); 1833 scoped_refptr<PermissionSet> permissions( 1834 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), 1835 allowed_hosts, URLPatternSet())); 1836 PermissionMessageProvider::Get()->GetPermissionMessages( 1837 permissions.get(), Manifest::TYPE_EXTENSION); 1838 } 1839 1840 TEST(PermissionsTest, IsPrivilegeIncrease_DeclarativeWebRequest) { 1841 scoped_refptr<Extension> extension( 1842 LoadManifest("permissions", "permissions_all_urls.json")); 1843 scoped_refptr<const PermissionSet> permissions( 1844 extension->permissions_data()->active_permissions()); 1845 1846 scoped_refptr<Extension> extension_dwr( 1847 LoadManifest("permissions", "web_request_all_host_permissions.json")); 1848 scoped_refptr<const PermissionSet> permissions_dwr( 1849 extension_dwr->permissions_data()->active_permissions()); 1850 1851 EXPECT_FALSE(PermissionMessageProvider::Get()-> 1852 IsPrivilegeIncrease(permissions.get(), 1853 permissions_dwr.get(), 1854 extension->GetType())); 1855 } 1856 1857 } // namespace extensions 1858