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