permission_set_unittest.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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_channel.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<base::ListValue> value(new base::ListValue()); 249 value->Append( 250 base::Value::CreateStringValue("tcp-connect:*.example.com:80")); 251 value->Append(base::Value::CreateStringValue("udp-bind::8080")); 252 value->Append(base::Value::CreateStringValue("udp-send-to::8888")); 253 if (!permission->FromValue(value.get())) { 254 NOTREACHED(); 255 } 256 } 257 258 // Union with an empty set. 259 apis1.insert(APIPermission::kTab); 260 apis1.insert(APIPermission::kBackground); 261 apis1.insert(permission->Clone()); 262 expected_apis.insert(APIPermission::kTab); 263 expected_apis.insert(APIPermission::kBackground); 264 expected_apis.insert(permission); 265 266 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 267 AddPattern(&expected_explicit_hosts, "http://*.google.com/*"); 268 AddPattern(&effective_hosts, "http://*.google.com/*"); 269 270 set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1); 271 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 272 union_set = PermissionSet::CreateUnion(set1.get(), set2.get()); 273 EXPECT_TRUE(set1->Contains(*set2.get())); 274 EXPECT_TRUE(set1->Contains(*union_set.get())); 275 EXPECT_FALSE(set2->Contains(*set1.get())); 276 EXPECT_FALSE(set2->Contains(*union_set.get())); 277 EXPECT_TRUE(union_set->Contains(*set1.get())); 278 EXPECT_TRUE(union_set->Contains(*set2.get())); 279 280 EXPECT_FALSE(union_set->HasEffectiveFullAccess()); 281 EXPECT_EQ(expected_apis, union_set->apis()); 282 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts()); 283 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts()); 284 EXPECT_EQ(expected_explicit_hosts, union_set->effective_hosts()); 285 286 // Now use a real second set. 287 apis2.insert(APIPermission::kTab); 288 apis2.insert(APIPermission::kProxy); 289 apis2.insert(APIPermission::kClipboardWrite); 290 apis2.insert(APIPermission::kPlugin); 291 292 permission = permission_info->CreateAPIPermission(); 293 { 294 scoped_ptr<base::ListValue> value(new base::ListValue()); 295 value->Append( 296 base::Value::CreateStringValue("tcp-connect:*.example.com:80")); 297 value->Append(base::Value::CreateStringValue("udp-send-to::8899")); 298 if (!permission->FromValue(value.get())) { 299 NOTREACHED(); 300 } 301 } 302 apis2.insert(permission); 303 304 expected_apis.insert(APIPermission::kTab); 305 expected_apis.insert(APIPermission::kProxy); 306 expected_apis.insert(APIPermission::kClipboardWrite); 307 expected_apis.insert(APIPermission::kPlugin); 308 309 permission = permission_info->CreateAPIPermission(); 310 { 311 scoped_ptr<base::ListValue> value(new base::ListValue()); 312 value->Append( 313 base::Value::CreateStringValue("tcp-connect:*.example.com:80")); 314 value->Append(base::Value::CreateStringValue("udp-bind::8080")); 315 value->Append(base::Value::CreateStringValue("udp-send-to::8888")); 316 value->Append(base::Value::CreateStringValue("udp-send-to::8899")); 317 if (!permission->FromValue(value.get())) { 318 NOTREACHED(); 319 } 320 } 321 // Insert a new permission socket permisssion which will replace the old one. 322 expected_apis.insert(permission); 323 324 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 325 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 326 AddPattern(&expected_explicit_hosts, "http://*.example.com/*"); 327 AddPattern(&expected_scriptable_hosts, "http://*.google.com/*"); 328 329 URLPatternSet::CreateUnion( 330 explicit_hosts2, scriptable_hosts2, &effective_hosts); 331 332 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 333 union_set = PermissionSet::CreateUnion(set1.get(), set2.get()); 334 335 EXPECT_FALSE(set1->Contains(*set2.get())); 336 EXPECT_FALSE(set1->Contains(*union_set.get())); 337 EXPECT_FALSE(set2->Contains(*set1.get())); 338 EXPECT_FALSE(set2->Contains(*union_set.get())); 339 EXPECT_TRUE(union_set->Contains(*set1.get())); 340 EXPECT_TRUE(union_set->Contains(*set2.get())); 341 342 EXPECT_TRUE(union_set->HasEffectiveFullAccess()); 343 EXPECT_TRUE(union_set->HasEffectiveAccessToAllHosts()); 344 EXPECT_EQ(expected_apis, union_set->apis()); 345 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts()); 346 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts()); 347 EXPECT_EQ(effective_hosts, union_set->effective_hosts()); 348} 349 350TEST(PermissionsTest, CreateIntersection) { 351 APIPermission* permission = NULL; 352 353 APIPermissionSet apis1; 354 APIPermissionSet apis2; 355 APIPermissionSet expected_apis; 356 357 URLPatternSet explicit_hosts1; 358 URLPatternSet explicit_hosts2; 359 URLPatternSet expected_explicit_hosts; 360 361 URLPatternSet scriptable_hosts1; 362 URLPatternSet scriptable_hosts2; 363 URLPatternSet expected_scriptable_hosts; 364 365 URLPatternSet effective_hosts; 366 367 scoped_refptr<PermissionSet> set1; 368 scoped_refptr<PermissionSet> set2; 369 scoped_refptr<PermissionSet> new_set; 370 371 const APIPermissionInfo* permission_info = 372 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 373 374 // Intersection with an empty set. 375 apis1.insert(APIPermission::kTab); 376 apis1.insert(APIPermission::kBackground); 377 permission = permission_info->CreateAPIPermission(); 378 { 379 scoped_ptr<base::ListValue> value(new base::ListValue()); 380 value->Append( 381 base::Value::CreateStringValue("tcp-connect:*.example.com:80")); 382 value->Append(base::Value::CreateStringValue("udp-bind::8080")); 383 value->Append(base::Value::CreateStringValue("udp-send-to::8888")); 384 if (!permission->FromValue(value.get())) { 385 NOTREACHED(); 386 } 387 } 388 apis1.insert(permission); 389 390 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 391 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*"); 392 393 set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1); 394 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 395 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get()); 396 EXPECT_TRUE(set1->Contains(*new_set.get())); 397 EXPECT_TRUE(set2->Contains(*new_set.get())); 398 EXPECT_TRUE(set1->Contains(*set2.get())); 399 EXPECT_FALSE(set2->Contains(*set1.get())); 400 EXPECT_FALSE(new_set->Contains(*set1.get())); 401 EXPECT_TRUE(new_set->Contains(*set2.get())); 402 403 EXPECT_TRUE(new_set->IsEmpty()); 404 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 405 EXPECT_EQ(expected_apis, new_set->apis()); 406 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 407 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 408 EXPECT_EQ(expected_explicit_hosts, new_set->effective_hosts()); 409 410 // Now use a real second set. 411 apis2.insert(APIPermission::kTab); 412 apis2.insert(APIPermission::kProxy); 413 apis2.insert(APIPermission::kClipboardWrite); 414 apis2.insert(APIPermission::kPlugin); 415 permission = permission_info->CreateAPIPermission(); 416 { 417 scoped_ptr<base::ListValue> value(new base::ListValue()); 418 value->Append(base::Value::CreateStringValue("udp-bind::8080")); 419 value->Append(base::Value::CreateStringValue("udp-send-to::8888")); 420 value->Append(base::Value::CreateStringValue("udp-send-to::8899")); 421 if (!permission->FromValue(value.get())) { 422 NOTREACHED(); 423 } 424 } 425 apis2.insert(permission); 426 427 expected_apis.insert(APIPermission::kTab); 428 permission = permission_info->CreateAPIPermission(); 429 { 430 scoped_ptr<base::ListValue> value(new base::ListValue()); 431 value->Append(base::Value::CreateStringValue("udp-bind::8080")); 432 value->Append(base::Value::CreateStringValue("udp-send-to::8888")); 433 if (!permission->FromValue(value.get())) { 434 NOTREACHED(); 435 } 436 } 437 expected_apis.insert(permission); 438 439 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 440 AddPattern(&explicit_hosts2, "http://*.google.com/*"); 441 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 442 AddPattern(&expected_explicit_hosts, "http://*.google.com/*"); 443 444 effective_hosts.ClearPatterns(); 445 AddPattern(&effective_hosts, "http://*.google.com/*"); 446 447 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 448 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get()); 449 450 EXPECT_TRUE(set1->Contains(*new_set.get())); 451 EXPECT_TRUE(set2->Contains(*new_set.get())); 452 EXPECT_FALSE(set1->Contains(*set2.get())); 453 EXPECT_FALSE(set2->Contains(*set1.get())); 454 EXPECT_FALSE(new_set->Contains(*set1.get())); 455 EXPECT_FALSE(new_set->Contains(*set2.get())); 456 457 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 458 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts()); 459 EXPECT_EQ(expected_apis, new_set->apis()); 460 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 461 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 462 EXPECT_EQ(effective_hosts, new_set->effective_hosts()); 463} 464 465TEST(PermissionsTest, CreateDifference) { 466 APIPermission* permission = NULL; 467 468 APIPermissionSet apis1; 469 APIPermissionSet apis2; 470 APIPermissionSet expected_apis; 471 472 URLPatternSet explicit_hosts1; 473 URLPatternSet explicit_hosts2; 474 URLPatternSet expected_explicit_hosts; 475 476 URLPatternSet scriptable_hosts1; 477 URLPatternSet scriptable_hosts2; 478 URLPatternSet expected_scriptable_hosts; 479 480 URLPatternSet effective_hosts; 481 482 scoped_refptr<PermissionSet> set1; 483 scoped_refptr<PermissionSet> set2; 484 scoped_refptr<PermissionSet> new_set; 485 486 const APIPermissionInfo* permission_info = 487 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 488 489 // Difference with an empty set. 490 apis1.insert(APIPermission::kTab); 491 apis1.insert(APIPermission::kBackground); 492 permission = permission_info->CreateAPIPermission(); 493 { 494 scoped_ptr<base::ListValue> value(new base::ListValue()); 495 value->Append( 496 base::Value::CreateStringValue("tcp-connect:*.example.com:80")); 497 value->Append(base::Value::CreateStringValue("udp-bind::8080")); 498 value->Append(base::Value::CreateStringValue("udp-send-to::8888")); 499 if (!permission->FromValue(value.get())) { 500 NOTREACHED(); 501 } 502 } 503 apis1.insert(permission); 504 505 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 506 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*"); 507 508 set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1); 509 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 510 new_set = PermissionSet::CreateDifference(set1.get(), set2.get()); 511 EXPECT_EQ(*set1.get(), *new_set.get()); 512 513 // Now use a real second set. 514 apis2.insert(APIPermission::kTab); 515 apis2.insert(APIPermission::kProxy); 516 apis2.insert(APIPermission::kClipboardWrite); 517 apis2.insert(APIPermission::kPlugin); 518 permission = permission_info->CreateAPIPermission(); 519 { 520 scoped_ptr<base::ListValue> value(new base::ListValue()); 521 value->Append( 522 base::Value::CreateStringValue("tcp-connect:*.example.com:80")); 523 value->Append(base::Value::CreateStringValue("udp-send-to::8899")); 524 if (!permission->FromValue(value.get())) { 525 NOTREACHED(); 526 } 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(base::Value::CreateStringValue("udp-bind::8080")); 535 value->Append(base::Value::CreateStringValue("udp-send-to::8888")); 536 if (!permission->FromValue(value.get())) { 537 NOTREACHED(); 538 } 539 } 540 expected_apis.insert(permission); 541 542 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 543 AddPattern(&explicit_hosts2, "http://*.google.com/*"); 544 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 545 AddPattern(&expected_scriptable_hosts, "http://www.reddit.com/*"); 546 547 effective_hosts.ClearPatterns(); 548 AddPattern(&effective_hosts, "http://www.reddit.com/*"); 549 550 set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2); 551 new_set = PermissionSet::CreateDifference(set1.get(), set2.get()); 552 553 EXPECT_TRUE(set1->Contains(*new_set.get())); 554 EXPECT_FALSE(set2->Contains(*new_set.get())); 555 556 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 557 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts()); 558 EXPECT_EQ(expected_apis, new_set->apis()); 559 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 560 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 561 EXPECT_EQ(effective_hosts, new_set->effective_hosts()); 562 563 // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set 564 set1 = PermissionSet::CreateIntersection(new_set.get(), set2.get()); 565 EXPECT_TRUE(set1->IsEmpty()); 566} 567 568TEST(PermissionsTest, HasLessPrivilegesThan) { 569 const struct { 570 const char* base_name; 571 bool expect_increase; 572 } kTests[] = { 573 { "allhosts1", false }, // all -> all 574 { "allhosts2", false }, // all -> one 575 { "allhosts3", true }, // one -> all 576 { "hosts1", false }, // http://a,http://b -> http://a,http://b 577 { "hosts2", true }, // http://a,http://b -> https://a,http://*.b 578 { "hosts3", false }, // http://a,http://b -> http://a 579 { "hosts4", true }, // http://a -> http://a,http://b 580 { "hosts5", false }, // http://a,b,c -> http://a,b,c + https://a,b,c 581 { "hosts6", false }, // http://a.com -> http://a.com + http://a.co.uk 582 { "permissions1", false }, // tabs -> tabs 583 { "permissions2", true }, // tabs -> tabs,bookmarks 584 { "permissions3", true }, // http://a -> http://a,tabs 585 { "permissions5", true }, // bookmarks -> bookmarks,history 586 { "equivalent_warnings", false }, // tabs --> tabs, webNavigation 587#if !defined(OS_CHROMEOS) // plugins aren't allowed in ChromeOS 588 { "permissions4", false }, // plugin -> plugin,tabs 589 { "plugin1", false }, // plugin -> plugin 590 { "plugin2", false }, // plugin -> none 591 { "plugin3", true }, // none -> plugin 592#endif 593 { "storage", false }, // none -> storage 594 { "notifications", false }, // none -> notifications 595 { "platformapp1", false }, // host permissions for platform apps 596 { "platformapp2", true }, // API permissions for platform apps 597 { "media_galleries1", true }, // read|all -> copyTo|all 598 { "media_galleries2", true }, // read|all -> read|copyTo|all 599 { "media_galleries3", true }, // all -> copyTo|all 600 { "media_galleries4", false }, // read|all -> all 601 { "media_galleries5", false }, // read|copyTo|all -> read|all 602 { "media_galleries6", false }, // read|all -> read|all 603 }; 604 605 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { 606 scoped_refptr<Extension> old_extension( 607 LoadManifest("allow_silent_upgrade", 608 std::string(kTests[i].base_name) + "_old.json")); 609 scoped_refptr<Extension> new_extension( 610 LoadManifest("allow_silent_upgrade", 611 std::string(kTests[i].base_name) + "_new.json")); 612 613 EXPECT_TRUE(new_extension.get()) << kTests[i].base_name << "_new.json"; 614 if (!new_extension.get()) 615 continue; 616 617 scoped_refptr<const PermissionSet> old_p( 618 old_extension->GetActivePermissions()); 619 scoped_refptr<const PermissionSet> new_p( 620 new_extension->GetActivePermissions()); 621 Manifest::Type extension_type = old_extension->GetType(); 622 623 EXPECT_EQ(kTests[i].expect_increase, 624 old_p->HasLessPrivilegesThan(new_p.get(), extension_type)) 625 << kTests[i].base_name; 626 } 627} 628 629TEST(PermissionsTest, PermissionMessages) { 630 // Ensure that all permissions that needs to show install UI actually have 631 // strings associated with them. 632 APIPermissionSet skip; 633 634 // These are considered "nuisance" or "trivial" permissions that don't need 635 // a prompt. 636 skip.insert(APIPermission::kActiveTab); 637 skip.insert(APIPermission::kAdView); 638 skip.insert(APIPermission::kAlarms); 639 skip.insert(APIPermission::kAppCurrentWindowInternal); 640 skip.insert(APIPermission::kAppRuntime); 641 skip.insert(APIPermission::kAppWindow); 642 skip.insert(APIPermission::kAudio); 643 skip.insert(APIPermission::kBrowsingData); 644 skip.insert(APIPermission::kContextMenus); 645 skip.insert(APIPermission::kDiagnostics); 646 skip.insert(APIPermission::kDns); 647 skip.insert(APIPermission::kDownloadsShelf); 648 skip.insert(APIPermission::kFontSettings); 649 skip.insert(APIPermission::kFullscreen); 650 skip.insert(APIPermission::kIdle); 651 skip.insert(APIPermission::kIdltest); 652 skip.insert(APIPermission::kLogPrivate); 653 skip.insert(APIPermission::kNotification); 654 skip.insert(APIPermission::kPointerLock); 655 skip.insert(APIPermission::kPower); 656 skip.insert(APIPermission::kPushMessaging); 657 skip.insert(APIPermission::kScreensaver); 658 skip.insert(APIPermission::kSessions); 659 skip.insert(APIPermission::kStorage); 660 skip.insert(APIPermission::kSystemCpu); 661 skip.insert(APIPermission::kSystemDisplay); 662 skip.insert(APIPermission::kSystemMemory); 663 skip.insert(APIPermission::kSystemStorage); 664 skip.insert(APIPermission::kTts); 665 skip.insert(APIPermission::kUnlimitedStorage); 666 skip.insert(APIPermission::kWebView); 667 668 // TODO(erikkay) add a string for this permission. 669 skip.insert(APIPermission::kBackground); 670 671 skip.insert(APIPermission::kClipboardWrite); 672 673 // The cookie permission does nothing unless you have associated host 674 // permissions. 675 skip.insert(APIPermission::kCookie); 676 677 // These are warned as part of host permission checks. 678 skip.insert(APIPermission::kDeclarativeContent); 679 skip.insert(APIPermission::kPageCapture); 680 skip.insert(APIPermission::kProxy); 681 skip.insert(APIPermission::kTabCapture); 682 skip.insert(APIPermission::kWebRequest); 683 skip.insert(APIPermission::kWebRequestBlocking); 684 685 // This permission requires explicit user action (context menu handler) 686 // so we won't prompt for it for now. 687 skip.insert(APIPermission::kFileBrowserHandler); 688 689 // These permissions require explicit user action (configuration dialog) 690 // so we don't prompt for them at install time. 691 skip.insert(APIPermission::kMediaGalleries); 692 693 // If you've turned on the experimental command-line flag, we don't need 694 // to warn you further. 695 skip.insert(APIPermission::kExperimental); 696 697 // The Identity API has its own server-driven permission prompts. 698 skip.insert(APIPermission::kIdentity); 699 700 // These are private. 701 skip.insert(APIPermission::kAutoTestPrivate); 702 skip.insert(APIPermission::kBookmarkManagerPrivate); 703 skip.insert(APIPermission::kBrailleDisplayPrivate); 704 skip.insert(APIPermission::kChromeosInfoPrivate); 705 skip.insert(APIPermission::kCloudPrintPrivate); 706 skip.insert(APIPermission::kCommandLinePrivate); 707 skip.insert(APIPermission::kDeveloperPrivate); 708 skip.insert(APIPermission::kDial); 709 skip.insert(APIPermission::kDownloadsInternal); 710 skip.insert(APIPermission::kEchoPrivate); 711 skip.insert(APIPermission::kEnterprisePlatformKeysPrivate); 712 skip.insert(APIPermission::kFeedbackPrivate); 713 skip.insert(APIPermission::kFileBrowserHandlerInternal); 714 skip.insert(APIPermission::kFileBrowserPrivate); 715 skip.insert(APIPermission::kIdentityPrivate); 716 skip.insert(APIPermission::kInfobars); 717 skip.insert(APIPermission::kInputMethodPrivate); 718 skip.insert(APIPermission::kMediaGalleriesPrivate); 719 skip.insert(APIPermission::kMediaPlayerPrivate); 720 skip.insert(APIPermission::kMetricsPrivate); 721 skip.insert(APIPermission::kMDns); 722 skip.insert(APIPermission::kPreferencesPrivate); 723 skip.insert(APIPermission::kImageWriterPrivate); 724 skip.insert(APIPermission::kRtcPrivate); 725 skip.insert(APIPermission::kStreamsPrivate); 726 skip.insert(APIPermission::kSystemPrivate); 727 skip.insert(APIPermission::kTabCaptureForTab); 728 skip.insert(APIPermission::kTerminalPrivate); 729 skip.insert(APIPermission::kVirtualKeyboardPrivate); 730 skip.insert(APIPermission::kWallpaperPrivate); 731 skip.insert(APIPermission::kWebRequestInternal); 732 skip.insert(APIPermission::kWebrtcLoggingPrivate); 733 skip.insert(APIPermission::kWebstorePrivate); 734 735 // Warned as part of host permissions. 736 skip.insert(APIPermission::kDevtools); 737 738 // Platform apps. 739 skip.insert(APIPermission::kBluetooth); 740 skip.insert(APIPermission::kFileSystem); 741 skip.insert(APIPermission::kFileSystemRetainEntries); 742 skip.insert(APIPermission::kSocket); 743 skip.insert(APIPermission::kSocketsUdp); 744 skip.insert(APIPermission::kUsbDevice); 745 746 PermissionsInfo* info = PermissionsInfo::GetInstance(); 747 APIPermissionSet permissions = info->GetAll(); 748 for (APIPermissionSet::const_iterator i = permissions.begin(); 749 i != permissions.end(); ++i) { 750 const APIPermissionInfo* permission_info = i->info(); 751 EXPECT_TRUE(permission_info != NULL); 752 753 // Always skip permissions that cannot be in the manifest. 754 scoped_ptr<const APIPermission> permission( 755 permission_info->CreateAPIPermission()); 756 if (permission->ManifestEntryForbidden()) 757 continue; 758 759 if (skip.count(i->id())) { 760 EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id()) 761 << "unexpected message_id for " << permission_info->name(); 762 } else { 763 EXPECT_NE(PermissionMessage::kNone, permission_info->message_id()) 764 << "missing message_id for " << permission_info->name(); 765 } 766 } 767} 768 769TEST(PermissionsTest, FileSystemPermissionMessages) { 770 APIPermissionSet api_permissions; 771 api_permissions.insert(APIPermission::kFileSystemWrite); 772 api_permissions.insert(APIPermission::kFileSystemDirectory); 773 scoped_refptr<PermissionSet> permissions( 774 new PermissionSet(api_permissions, URLPatternSet(), URLPatternSet())); 775 PermissionMessages messages = 776 permissions->GetPermissionMessages(Manifest::TYPE_PLATFORM_APP); 777 ASSERT_EQ(2u, messages.size()); 778 std::sort(messages.begin(), messages.end()); 779 std::set<PermissionMessage::ID> ids; 780 for (PermissionMessages::const_iterator it = messages.begin(); 781 it != messages.end(); ++it) { 782 ids.insert(it->id()); 783 } 784 EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemDirectory)); 785 EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemWrite)); 786} 787 788TEST(PermissionsTest, HiddenFileSystemPermissionMessages) { 789 APIPermissionSet api_permissions; 790 api_permissions.insert(APIPermission::kFileSystemWrite); 791 api_permissions.insert(APIPermission::kFileSystemDirectory); 792 api_permissions.insert(APIPermission::kFileSystemWriteDirectory); 793 scoped_refptr<PermissionSet> permissions( 794 new PermissionSet(api_permissions, URLPatternSet(), URLPatternSet())); 795 PermissionMessages messages = 796 permissions->GetPermissionMessages(Manifest::TYPE_PLATFORM_APP); 797 ASSERT_EQ(1u, messages.size()); 798 EXPECT_EQ(PermissionMessage::kFileSystemWriteDirectory, messages[0].id()); 799} 800 801TEST(PermissionsTest, MergedFileSystemPermissionComparison) { 802 APIPermissionSet write_api_permissions; 803 write_api_permissions.insert(APIPermission::kFileSystemWrite); 804 scoped_refptr<PermissionSet> write_permissions(new PermissionSet( 805 write_api_permissions, URLPatternSet(), URLPatternSet())); 806 807 APIPermissionSet directory_api_permissions; 808 directory_api_permissions.insert(APIPermission::kFileSystemDirectory); 809 scoped_refptr<PermissionSet> directory_permissions(new PermissionSet( 810 directory_api_permissions, URLPatternSet(), URLPatternSet())); 811 812 APIPermissionSet write_directory_api_permissions; 813 write_directory_api_permissions.insert( 814 APIPermission::kFileSystemWriteDirectory); 815 scoped_refptr<PermissionSet> write_directory_permissions(new PermissionSet( 816 write_directory_api_permissions, URLPatternSet(), URLPatternSet())); 817 818 EXPECT_FALSE(write_directory_permissions->HasLessPrivilegesThan( 819 write_permissions, Manifest::TYPE_PLATFORM_APP)); 820 EXPECT_FALSE(write_directory_permissions->HasLessPrivilegesThan( 821 directory_permissions, Manifest::TYPE_PLATFORM_APP)); 822 EXPECT_TRUE(write_permissions->HasLessPrivilegesThan( 823 directory_permissions, Manifest::TYPE_PLATFORM_APP)); 824 EXPECT_TRUE(write_permissions->HasLessPrivilegesThan( 825 write_directory_permissions, Manifest::TYPE_PLATFORM_APP)); 826 EXPECT_TRUE(directory_permissions->HasLessPrivilegesThan( 827 write_permissions, Manifest::TYPE_PLATFORM_APP)); 828 EXPECT_TRUE(directory_permissions->HasLessPrivilegesThan( 829 write_directory_permissions, Manifest::TYPE_PLATFORM_APP)); 830} 831 832TEST(PermissionsTest, GetWarningMessages_ManyHosts) { 833 scoped_refptr<Extension> extension; 834 835 extension = LoadManifest("permissions", "many-hosts.json"); 836 std::vector<string16> warnings = 837 PermissionsData::GetPermissionMessageStrings(extension.get()); 838 ASSERT_EQ(1u, warnings.size()); 839 EXPECT_EQ("Access your data on encrypted.google.com and www.google.com", 840 UTF16ToUTF8(warnings[0])); 841} 842 843TEST(PermissionsTest, GetWarningMessages_Plugins) { 844 scoped_refptr<Extension> extension; 845 scoped_refptr<PermissionSet> permissions; 846 847 extension = LoadManifest("permissions", "plugins.json"); 848 std::vector<string16> warnings = 849 PermissionsData::GetPermissionMessageStrings(extension.get()); 850// We don't parse the plugins key on Chrome OS, so it should not ask for any 851 // permissions. 852#if defined(OS_CHROMEOS) 853 ASSERT_EQ(0u, warnings.size()); 854#else 855 ASSERT_EQ(1u, warnings.size()); 856 EXPECT_EQ("Access all data on your computer and the websites you visit", 857 UTF16ToUTF8(warnings[0])); 858#endif 859} 860 861TEST(PermissionsTest, GetWarningMessages_AudioVideo) { 862 // Both audio and video present. 863 scoped_refptr<Extension> extension = 864 LoadManifest("permissions", "audio-video.json"); 865 PermissionSet* set = 866 const_cast<PermissionSet*>( 867 extension->GetActivePermissions().get()); 868 std::vector<string16> warnings = 869 set->GetWarningMessages(extension->GetType()); 870 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 871 EXPECT_FALSE(Contains(warnings, "Use your camera")); 872 EXPECT_TRUE(Contains(warnings, "Use your microphone and camera")); 873 size_t combined_index = IndexOf(warnings, "Use your microphone and camera"); 874 size_t combined_size = warnings.size(); 875 876 // Just audio present. 877 set->apis_.erase(APIPermission::kVideoCapture); 878 warnings = set->GetWarningMessages(extension->GetType()); 879 EXPECT_EQ(combined_size, warnings.size()); 880 EXPECT_EQ(combined_index, IndexOf(warnings, "Use your microphone")); 881 EXPECT_FALSE(Contains(warnings, "Use your camera")); 882 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 883 884 // Just video present. 885 set->apis_.erase(APIPermission::kAudioCapture); 886 set->apis_.insert(APIPermission::kVideoCapture); 887 warnings = set->GetWarningMessages(extension->GetType()); 888 EXPECT_EQ(combined_size, warnings.size()); 889 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 890 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 891 EXPECT_TRUE(Contains(warnings, "Use your camera")); 892} 893 894TEST(PermissionsTest, GetWarningMessages_DeclarativeWebRequest) { 895 // Test that if the declarativeWebRequest permission is present 896 // in combination with all hosts permission, then only the warning 897 // for host permissions is shown, because that covers the use of 898 // declarativeWebRequest. 899 900 // Until Declarative Web Request is in stable, let's make sure it is enabled 901 // on the current channel. 902 ScopedCurrentChannel sc(chrome::VersionInfo::CHANNEL_CANARY); 903 904 // First verify that declarativeWebRequest produces a message when host 905 // permissions do not cover all hosts. 906 scoped_refptr<Extension> extension = 907 LoadManifest("permissions", "web_request_com_host_permissions.json"); 908 const PermissionSet* set = extension->GetActivePermissions().get(); 909 std::vector<string16> warnings = 910 set->GetWarningMessages(extension->GetType()); 911 EXPECT_TRUE(Contains(warnings, "Block parts of web pages")); 912 EXPECT_FALSE(Contains(warnings, "Access your data on all websites")); 913 914 // Now verify that declarativeWebRequest does not produce a message when host 915 // permissions do cover all hosts. 916 extension = 917 LoadManifest("permissions", "web_request_all_host_permissions.json"); 918 set = extension->GetActivePermissions().get(); 919 warnings = set->GetWarningMessages(extension->GetType()); 920 EXPECT_FALSE(Contains(warnings, "Block parts of web pages")); 921 EXPECT_TRUE(Contains(warnings, "Access your data on all websites")); 922} 923 924TEST(PermissionsTest, GetWarningMessages_Serial) { 925 scoped_refptr<Extension> extension = 926 LoadManifest("permissions", "serial.json"); 927 928 EXPECT_TRUE(extension->is_platform_app()); 929 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSerial)); 930 std::vector<string16> warnings = 931 PermissionsData::GetPermissionMessageStrings(extension.get()); 932 EXPECT_TRUE( 933 Contains(warnings, "Use serial devices attached to your computer")); 934 ASSERT_EQ(1u, warnings.size()); 935} 936 937TEST(PermissionsTest, GetWarningMessages_Socket_AnyHost) { 938 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 939 940 scoped_refptr<Extension> extension = 941 LoadManifest("permissions", "socket_any_host.json"); 942 EXPECT_TRUE(extension->is_platform_app()); 943 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 944 std::vector<string16> warnings = 945 PermissionsData::GetPermissionMessageStrings(extension.get()); 946 EXPECT_EQ(1u, warnings.size()); 947 EXPECT_TRUE(Contains(warnings, "Exchange data with any computer " 948 "on the local network or internet")); 949} 950 951TEST(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) { 952 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 953 954 scoped_refptr<Extension> extension = 955 LoadManifest("permissions", "socket_one_domain_two_hostnames.json"); 956 EXPECT_TRUE(extension->is_platform_app()); 957 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 958 std::vector<string16> warnings = 959 PermissionsData::GetPermissionMessageStrings(extension.get()); 960 961 // Verify the warnings, including support for unicode characters, the fact 962 // that domain host warnings come before specific host warnings, and the fact 963 // that domains and hostnames are in alphabetical order regardless of the 964 // order in the manifest file. 965 EXPECT_EQ(2u, warnings.size()); 966 if (warnings.size() > 0) 967 EXPECT_EQ(warnings[0], 968 UTF8ToUTF16("Exchange data with any computer in the domain " 969 "example.org")); 970 if (warnings.size() > 1) 971 EXPECT_EQ(warnings[1], 972 UTF8ToUTF16("Exchange data with the computers named: " 973 "b\xC3\xA5r.example.com foo.example.com")); 974 // "\xC3\xA5" = UTF-8 for lowercase A with ring above 975} 976 977TEST(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) { 978 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 979 980 scoped_refptr<Extension> extension = 981 LoadManifest("permissions", "socket_two_domains_one_hostname.json"); 982 EXPECT_TRUE(extension->is_platform_app()); 983 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 984 std::vector<string16> warnings = 985 PermissionsData::GetPermissionMessageStrings(extension.get()); 986 987 // Verify the warnings, including the fact that domain host warnings come 988 // before specific host warnings and the fact that domains and hostnames are 989 // in alphabetical order regardless of the order in the manifest file. 990 EXPECT_EQ(2u, warnings.size()); 991 if (warnings.size() > 0) 992 EXPECT_EQ(warnings[0], 993 UTF8ToUTF16("Exchange data with any computer in the domains: " 994 "example.com foo.example.org")); 995 if (warnings.size() > 1) 996 EXPECT_EQ(warnings[1], 997 UTF8ToUTF16("Exchange data with the computer named " 998 "bar.example.org")); 999} 1000 1001TEST(PermissionsTest, GetWarningMessages_PlatformApppHosts) { 1002 scoped_refptr<Extension> extension; 1003 1004 extension = LoadManifest("permissions", "platform_app_hosts.json"); 1005 EXPECT_TRUE(extension->is_platform_app()); 1006 std::vector<string16> warnings = 1007 PermissionsData::GetPermissionMessageStrings(extension.get()); 1008 ASSERT_EQ(0u, warnings.size()); 1009 1010 extension = LoadManifest("permissions", "platform_app_all_urls.json"); 1011 EXPECT_TRUE(extension->is_platform_app()); 1012 warnings = PermissionsData::GetPermissionMessageStrings(extension.get()); 1013 ASSERT_EQ(0u, warnings.size()); 1014} 1015 1016TEST(PermissionsTest, GetDistinctHostsForDisplay) { 1017 scoped_refptr<PermissionSet> perm_set; 1018 APIPermissionSet empty_perms; 1019 std::set<std::string> expected; 1020 expected.insert("www.foo.com"); 1021 expected.insert("www.bar.com"); 1022 expected.insert("www.baz.com"); 1023 URLPatternSet explicit_hosts; 1024 URLPatternSet scriptable_hosts; 1025 1026 { 1027 SCOPED_TRACE("no dupes"); 1028 1029 // Simple list with no dupes. 1030 explicit_hosts.AddPattern( 1031 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1032 explicit_hosts.AddPattern( 1033 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path")); 1034 explicit_hosts.AddPattern( 1035 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 1036 perm_set = new PermissionSet( 1037 empty_perms, explicit_hosts, scriptable_hosts); 1038 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1039 } 1040 1041 { 1042 SCOPED_TRACE("two dupes"); 1043 1044 // Add some dupes. 1045 explicit_hosts.AddPattern( 1046 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1047 explicit_hosts.AddPattern( 1048 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 1049 perm_set = new PermissionSet( 1050 empty_perms, explicit_hosts, scriptable_hosts); 1051 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1052 } 1053 1054 { 1055 SCOPED_TRACE("schemes differ"); 1056 1057 // Add a pattern that differs only by scheme. This should be filtered out. 1058 explicit_hosts.AddPattern( 1059 URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path")); 1060 perm_set = new PermissionSet( 1061 empty_perms, explicit_hosts, scriptable_hosts); 1062 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1063 } 1064 1065 { 1066 SCOPED_TRACE("paths differ"); 1067 1068 // Add some dupes by path. 1069 explicit_hosts.AddPattern( 1070 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath")); 1071 perm_set = new PermissionSet( 1072 empty_perms, explicit_hosts, scriptable_hosts); 1073 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1074 } 1075 1076 { 1077 SCOPED_TRACE("subdomains differ"); 1078 1079 // We don't do anything special for subdomains. 1080 explicit_hosts.AddPattern( 1081 URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path")); 1082 explicit_hosts.AddPattern( 1083 URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path")); 1084 1085 expected.insert("monkey.www.bar.com"); 1086 expected.insert("bar.com"); 1087 1088 perm_set = new PermissionSet( 1089 empty_perms, explicit_hosts, scriptable_hosts); 1090 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1091 } 1092 1093 { 1094 SCOPED_TRACE("RCDs differ"); 1095 1096 // Now test for RCD uniquing. 1097 explicit_hosts.AddPattern( 1098 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1099 explicit_hosts.AddPattern( 1100 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1101 explicit_hosts.AddPattern( 1102 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path")); 1103 explicit_hosts.AddPattern( 1104 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path")); 1105 explicit_hosts.AddPattern( 1106 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1107 explicit_hosts.AddPattern( 1108 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path")); 1109 1110 // This is an unknown RCD, which shouldn't be uniqued out. 1111 explicit_hosts.AddPattern( 1112 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1113 // But it should only occur once. 1114 explicit_hosts.AddPattern( 1115 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1116 1117 expected.insert("www.foo.xyzzy"); 1118 1119 perm_set = new PermissionSet( 1120 empty_perms, explicit_hosts, scriptable_hosts); 1121 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1122 } 1123 1124 { 1125 SCOPED_TRACE("wildcards"); 1126 1127 explicit_hosts.AddPattern( 1128 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1129 1130 expected.insert("*.google.com"); 1131 1132 perm_set = new PermissionSet( 1133 empty_perms, explicit_hosts, scriptable_hosts); 1134 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1135 } 1136 1137 { 1138 SCOPED_TRACE("scriptable hosts"); 1139 explicit_hosts.ClearPatterns(); 1140 scriptable_hosts.ClearPatterns(); 1141 expected.clear(); 1142 1143 explicit_hosts.AddPattern( 1144 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1145 scriptable_hosts.AddPattern( 1146 URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*")); 1147 1148 expected.insert("*.google.com"); 1149 expected.insert("*.example.com"); 1150 1151 perm_set = new PermissionSet( 1152 empty_perms, explicit_hosts, scriptable_hosts); 1153 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1154 } 1155 1156 { 1157 // We don't display warnings for file URLs because they are off by default. 1158 SCOPED_TRACE("file urls"); 1159 explicit_hosts.ClearPatterns(); 1160 scriptable_hosts.ClearPatterns(); 1161 expected.clear(); 1162 1163 explicit_hosts.AddPattern( 1164 URLPattern(URLPattern::SCHEME_FILE, "file:///*")); 1165 1166 perm_set = new PermissionSet( 1167 empty_perms, explicit_hosts, scriptable_hosts); 1168 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1169 } 1170} 1171 1172TEST(PermissionsTest, GetDistinctHostsForDisplay_ComIsBestRcd) { 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 explicit_hosts.AddPattern( 1184 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1185 explicit_hosts.AddPattern( 1186 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1187 explicit_hosts.AddPattern( 1188 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1189 1190 std::set<std::string> expected; 1191 expected.insert("www.foo.com"); 1192 perm_set = new PermissionSet( 1193 empty_perms, explicit_hosts, scriptable_hosts); 1194 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1195} 1196 1197TEST(PermissionsTest, GetDistinctHostsForDisplay_NetIs2ndBestRcd) { 1198 scoped_refptr<PermissionSet> perm_set; 1199 APIPermissionSet empty_perms; 1200 URLPatternSet explicit_hosts; 1201 URLPatternSet scriptable_hosts; 1202 explicit_hosts.AddPattern( 1203 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1204 explicit_hosts.AddPattern( 1205 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1206 explicit_hosts.AddPattern( 1207 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1208 explicit_hosts.AddPattern( 1209 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1210 explicit_hosts.AddPattern( 1211 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1212 // No http://www.foo.com/path 1213 1214 std::set<std::string> expected; 1215 expected.insert("www.foo.net"); 1216 perm_set = new PermissionSet( 1217 empty_perms, explicit_hosts, scriptable_hosts); 1218 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1219} 1220 1221TEST(PermissionsTest, 1222 GetDistinctHostsForDisplay_OrgIs3rdBestRcd) { 1223 scoped_refptr<PermissionSet> perm_set; 1224 APIPermissionSet empty_perms; 1225 URLPatternSet explicit_hosts; 1226 URLPatternSet scriptable_hosts; 1227 explicit_hosts.AddPattern( 1228 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1229 explicit_hosts.AddPattern( 1230 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1231 explicit_hosts.AddPattern( 1232 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1233 // No http://www.foo.net/path 1234 explicit_hosts.AddPattern( 1235 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1236 // No http://www.foo.com/path 1237 1238 std::set<std::string> expected; 1239 expected.insert("www.foo.org"); 1240 perm_set = new PermissionSet( 1241 empty_perms, explicit_hosts, scriptable_hosts); 1242 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1243} 1244 1245TEST(PermissionsTest, 1246 GetDistinctHostsForDisplay_FirstInListIs4thBestRcd) { 1247 scoped_refptr<PermissionSet> perm_set; 1248 APIPermissionSet empty_perms; 1249 URLPatternSet explicit_hosts; 1250 URLPatternSet scriptable_hosts; 1251 explicit_hosts.AddPattern( 1252 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1253 // No http://www.foo.org/path 1254 explicit_hosts.AddPattern( 1255 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1256 // No http://www.foo.net/path 1257 explicit_hosts.AddPattern( 1258 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1259 // No http://www.foo.com/path 1260 1261 std::set<std::string> expected; 1262 expected.insert("www.foo.ca"); 1263 perm_set = new PermissionSet( 1264 empty_perms, explicit_hosts, scriptable_hosts); 1265 EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); 1266} 1267 1268TEST(PermissionsTest, HasLessHostPrivilegesThan) { 1269 Manifest::Type extension_type = Manifest::TYPE_EXTENSION; 1270 URLPatternSet elist1; 1271 URLPatternSet elist2; 1272 URLPatternSet slist1; 1273 URLPatternSet slist2; 1274 scoped_refptr<PermissionSet> set1; 1275 scoped_refptr<PermissionSet> set2; 1276 APIPermissionSet empty_perms; 1277 elist1.AddPattern( 1278 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1279 elist1.AddPattern( 1280 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1281 1282 // Test that the host order does not matter. 1283 elist2.AddPattern( 1284 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1285 elist2.AddPattern( 1286 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1287 1288 set1 = new PermissionSet(empty_perms, elist1, slist1); 1289 set2 = new PermissionSet(empty_perms, elist2, slist2); 1290 1291 EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get(), extension_type)); 1292 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get(), extension_type)); 1293 1294 // Test that paths are ignored. 1295 elist2.ClearPatterns(); 1296 elist2.AddPattern( 1297 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*")); 1298 set2 = new PermissionSet(empty_perms, elist2, slist2); 1299 EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get(), extension_type)); 1300 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get(), extension_type)); 1301 1302 // Test that RCDs are ignored. 1303 elist2.ClearPatterns(); 1304 elist2.AddPattern( 1305 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*")); 1306 set2 = new PermissionSet(empty_perms, elist2, slist2); 1307 EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get(), extension_type)); 1308 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get(), extension_type)); 1309 1310 // Test that subdomain wildcards are handled properly. 1311 elist2.ClearPatterns(); 1312 elist2.AddPattern( 1313 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*")); 1314 set2 = new PermissionSet(empty_perms, elist2, slist2); 1315 EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get(), extension_type)); 1316 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337 1317 // EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get())); 1318 1319 // Test that different domains count as different hosts. 1320 elist2.ClearPatterns(); 1321 elist2.AddPattern( 1322 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1323 elist2.AddPattern( 1324 URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path")); 1325 set2 = new PermissionSet(empty_perms, elist2, slist2); 1326 EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get(), extension_type)); 1327 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get(), extension_type)); 1328 1329 // Test that different subdomains count as different hosts. 1330 elist2.ClearPatterns(); 1331 elist2.AddPattern( 1332 URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*")); 1333 set2 = new PermissionSet(empty_perms, elist2, slist2); 1334 EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get(), extension_type)); 1335 EXPECT_TRUE(set2->HasLessHostPrivilegesThan(set1.get(), extension_type)); 1336 1337 // Test that platform apps do not have host permissions increases. 1338 extension_type = Manifest::TYPE_PLATFORM_APP; 1339 EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get(), extension_type)); 1340 EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get(), extension_type)); 1341} 1342 1343TEST(PermissionsTest, GetAPIsAsStrings) { 1344 APIPermissionSet apis; 1345 URLPatternSet empty_set; 1346 1347 apis.insert(APIPermission::kProxy); 1348 apis.insert(APIPermission::kBackground); 1349 apis.insert(APIPermission::kNotification); 1350 apis.insert(APIPermission::kTab); 1351 1352 scoped_refptr<PermissionSet> perm_set = new PermissionSet( 1353 apis, empty_set, empty_set); 1354 std::set<std::string> api_names = perm_set->GetAPIsAsStrings(); 1355 1356 // The result is correct if it has the same number of elements 1357 // and we can convert it back to the id set. 1358 EXPECT_EQ(4u, api_names.size()); 1359 EXPECT_EQ(apis, 1360 PermissionsInfo::GetInstance()->GetAllByName(api_names)); 1361} 1362 1363TEST(PermissionsTest, IsEmpty) { 1364 APIPermissionSet empty_apis; 1365 URLPatternSet empty_extent; 1366 1367 scoped_refptr<PermissionSet> empty = new PermissionSet(); 1368 EXPECT_TRUE(empty->IsEmpty()); 1369 scoped_refptr<PermissionSet> perm_set; 1370 1371 perm_set = new PermissionSet(empty_apis, empty_extent, empty_extent); 1372 EXPECT_TRUE(perm_set->IsEmpty()); 1373 1374 APIPermissionSet non_empty_apis; 1375 non_empty_apis.insert(APIPermission::kBackground); 1376 perm_set = new PermissionSet( 1377 non_empty_apis, empty_extent, empty_extent); 1378 EXPECT_FALSE(perm_set->IsEmpty()); 1379 1380 // Try non standard host 1381 URLPatternSet non_empty_extent; 1382 AddPattern(&non_empty_extent, "http://www.google.com/*"); 1383 1384 perm_set = new PermissionSet( 1385 empty_apis, non_empty_extent, empty_extent); 1386 EXPECT_FALSE(perm_set->IsEmpty()); 1387 1388 perm_set = new PermissionSet( 1389 empty_apis, empty_extent, non_empty_extent); 1390 EXPECT_FALSE(perm_set->IsEmpty()); 1391} 1392 1393TEST(PermissionsTest, ImpliedPermissions) { 1394 URLPatternSet empty_extent; 1395 APIPermissionSet apis; 1396 apis.insert(APIPermission::kWebRequest); 1397 apis.insert(APIPermission::kFileBrowserHandler); 1398 EXPECT_EQ(2U, apis.size()); 1399 1400 scoped_refptr<PermissionSet> perm_set; 1401 perm_set = new PermissionSet(apis, empty_extent, empty_extent); 1402 EXPECT_EQ(4U, perm_set->apis().size()); 1403} 1404 1405TEST(PermissionsTest, SyncFileSystemPermission) { 1406 scoped_refptr<Extension> extension = LoadManifest( 1407 "permissions", "sync_file_system.json"); 1408 APIPermissionSet apis; 1409 apis.insert(APIPermission::kSyncFileSystem); 1410 EXPECT_TRUE(extension->is_platform_app()); 1411 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSyncFileSystem)); 1412 std::vector<string16> warnings = 1413 PermissionsData::GetPermissionMessageStrings(extension.get()); 1414 EXPECT_TRUE(Contains(warnings, "Store data in your Google Drive account")); 1415 ASSERT_EQ(1u, warnings.size()); 1416} 1417 1418// Make sure that we don't crash when we're trying to show the permissions 1419// even though chrome://thumb (and everything that's not chrome://favicon with 1420// a chrome:// scheme) is not a valid permission. 1421// More details here: crbug/246314. 1422TEST(PermissionsTest, ChromeURLs) { 1423 URLPatternSet allowed_hosts; 1424 allowed_hosts.AddPattern( 1425 URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/")); 1426 allowed_hosts.AddPattern( 1427 URLPattern(URLPattern::SCHEME_ALL, "chrome://favicon/")); 1428 allowed_hosts.AddPattern( 1429 URLPattern(URLPattern::SCHEME_ALL, "chrome://thumb/")); 1430 scoped_refptr<PermissionSet> permissions( 1431 new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet())); 1432 permissions->GetPermissionMessages(Manifest::TYPE_EXTENSION); 1433} 1434 1435TEST(PermissionsTest, HasLessPrivilegesThan_DeclarativeWebRequest) { 1436 scoped_refptr<Extension> extension( 1437 LoadManifest("permissions", "permissions_all_urls.json")); 1438 scoped_refptr<const PermissionSet> permissions( 1439 extension->GetActivePermissions()); 1440 1441 scoped_refptr<Extension> extension_dwr( 1442 LoadManifest("permissions", "web_request_all_host_permissions.json")); 1443 scoped_refptr<const PermissionSet> permissions_dwr( 1444 extension_dwr->GetActivePermissions()); 1445 1446 EXPECT_FALSE(permissions->HasLessPrivilegesThan(permissions_dwr.get(), 1447 extension->GetType())); 1448} 1449} // namespace extensions 1450