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