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