permission_set_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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::kPointerLock); 657 skip.insert(APIPermission::kPower); 658 skip.insert(APIPermission::kPushMessaging); 659 skip.insert(APIPermission::kSessions); 660 skip.insert(APIPermission::kStorage); 661 skip.insert(APIPermission::kSystemCpu); 662 skip.insert(APIPermission::kSystemDisplay); 663 skip.insert(APIPermission::kSystemMemory); 664 skip.insert(APIPermission::kSystemNetwork); 665 skip.insert(APIPermission::kSystemStorage); 666 skip.insert(APIPermission::kTts); 667 skip.insert(APIPermission::kUnlimitedStorage); 668 skip.insert(APIPermission::kWebView); 669 skip.insert(APIPermission::kOverrideEscFullscreen); 670 671 // TODO(erikkay) add a string for this permission. 672 skip.insert(APIPermission::kBackground); 673 674 skip.insert(APIPermission::kClipboardWrite); 675 676 // The cookie permission does nothing unless you have associated host 677 // permissions. 678 skip.insert(APIPermission::kCookie); 679 680 // These are warned as part of host permission checks. 681 skip.insert(APIPermission::kDeclarativeContent); 682 skip.insert(APIPermission::kPageCapture); 683 skip.insert(APIPermission::kProxy); 684 skip.insert(APIPermission::kTabCapture); 685 skip.insert(APIPermission::kWebRequest); 686 skip.insert(APIPermission::kWebRequestBlocking); 687 688 // This permission requires explicit user action (context menu handler) 689 // so we won't prompt for it for now. 690 skip.insert(APIPermission::kFileBrowserHandler); 691 692 // These permissions require explicit user action (configuration dialog) 693 // so we don't prompt for them at install time. 694 skip.insert(APIPermission::kMediaGalleries); 695 696 // If you've turned on the experimental command-line flag, we don't need 697 // to warn you further. 698 skip.insert(APIPermission::kExperimental); 699 700 // The Identity API has its own server-driven permission prompts. 701 skip.insert(APIPermission::kIdentity); 702 703 // These are private. 704 skip.insert(APIPermission::kAutoTestPrivate); 705 skip.insert(APIPermission::kBookmarkManagerPrivate); 706 skip.insert(APIPermission::kBrailleDisplayPrivate); 707 skip.insert(APIPermission::kCast); 708 skip.insert(APIPermission::kCastStreaming); 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::kFirstRunPrivate); 721 skip.insert(APIPermission::kHotwordPrivate); 722 skip.insert(APIPermission::kIdentityPrivate); 723 skip.insert(APIPermission::kInfobars); 724 skip.insert(APIPermission::kInputMethodPrivate); 725 skip.insert(APIPermission::kMediaGalleriesPrivate); 726 skip.insert(APIPermission::kMediaPlayerPrivate); 727 skip.insert(APIPermission::kMetricsPrivate); 728 skip.insert(APIPermission::kMDns); 729 skip.insert(APIPermission::kPreferencesPrivate); 730 skip.insert(APIPermission::kPrincipalsPrivate); 731 skip.insert(APIPermission::kImageWriterPrivate); 732 skip.insert(APIPermission::kReadingListPrivate); 733 skip.insert(APIPermission::kRtcPrivate); 734 skip.insert(APIPermission::kStreamsPrivate); 735 skip.insert(APIPermission::kSystemPrivate); 736 skip.insert(APIPermission::kTabCaptureForTab); 737 skip.insert(APIPermission::kTerminalPrivate); 738 skip.insert(APIPermission::kVirtualKeyboardPrivate); 739 skip.insert(APIPermission::kWallpaperPrivate); 740 skip.insert(APIPermission::kWebRequestInternal); 741 skip.insert(APIPermission::kWebrtcAudioPrivate); 742 skip.insert(APIPermission::kWebrtcLoggingPrivate); 743 skip.insert(APIPermission::kWebstorePrivate); 744 745 // Warned as part of host permissions. 746 skip.insert(APIPermission::kDevtools); 747 748 // Platform apps. 749 skip.insert(APIPermission::kFileSystem); 750 skip.insert(APIPermission::kFileSystemProvider); 751 skip.insert(APIPermission::kFileSystemRetainEntries); 752 skip.insert(APIPermission::kSocket); 753 skip.insert(APIPermission::kUsbDevice); 754 755 PermissionsInfo* info = PermissionsInfo::GetInstance(); 756 APIPermissionSet permissions = info->GetAll(); 757 for (APIPermissionSet::const_iterator i = permissions.begin(); 758 i != permissions.end(); ++i) { 759 const APIPermissionInfo* permission_info = i->info(); 760 EXPECT_TRUE(permission_info != NULL); 761 762 if (skip.count(i->id())) { 763 EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id()) 764 << "unexpected message_id for " << permission_info->name(); 765 } else { 766 EXPECT_NE(PermissionMessage::kNone, permission_info->message_id()) 767 << "missing message_id for " << permission_info->name(); 768 } 769 } 770} 771 772TEST(PermissionsTest, FileSystemPermissionMessages) { 773 APIPermissionSet api_permissions; 774 api_permissions.insert(APIPermission::kFileSystemWrite); 775 api_permissions.insert(APIPermission::kFileSystemDirectory); 776 scoped_refptr<PermissionSet> permissions( 777 new PermissionSet(api_permissions, ManifestPermissionSet(), 778 URLPatternSet(), URLPatternSet())); 779 PermissionMessages messages = 780 PermissionMessageProvider::Get()->GetPermissionMessages( 781 permissions, Manifest::TYPE_PLATFORM_APP); 782 ASSERT_EQ(2u, messages.size()); 783 std::sort(messages.begin(), messages.end()); 784 std::set<PermissionMessage::ID> ids; 785 for (PermissionMessages::const_iterator it = messages.begin(); 786 it != messages.end(); ++it) { 787 ids.insert(it->id()); 788 } 789 EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemDirectory)); 790 EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemWrite)); 791} 792 793TEST(PermissionsTest, HiddenFileSystemPermissionMessages) { 794 APIPermissionSet api_permissions; 795 api_permissions.insert(APIPermission::kFileSystemWrite); 796 api_permissions.insert(APIPermission::kFileSystemDirectory); 797 api_permissions.insert(APIPermission::kFileSystemWriteDirectory); 798 scoped_refptr<PermissionSet> permissions( 799 new PermissionSet(api_permissions, ManifestPermissionSet(), 800 URLPatternSet(), URLPatternSet())); 801 PermissionMessages messages = 802 PermissionMessageProvider::Get()->GetPermissionMessages( 803 permissions, Manifest::TYPE_PLATFORM_APP); 804 ASSERT_EQ(1u, messages.size()); 805 EXPECT_EQ(PermissionMessage::kFileSystemWriteDirectory, messages[0].id()); 806} 807 808TEST(PermissionsTest, MergedFileSystemPermissionComparison) { 809 APIPermissionSet write_api_permissions; 810 write_api_permissions.insert(APIPermission::kFileSystemWrite); 811 scoped_refptr<PermissionSet> write_permissions( 812 new PermissionSet(write_api_permissions, ManifestPermissionSet(), 813 URLPatternSet(), URLPatternSet())); 814 815 APIPermissionSet directory_api_permissions; 816 directory_api_permissions.insert(APIPermission::kFileSystemDirectory); 817 scoped_refptr<PermissionSet> directory_permissions( 818 new PermissionSet(directory_api_permissions, ManifestPermissionSet(), 819 URLPatternSet(), URLPatternSet())); 820 821 APIPermissionSet write_directory_api_permissions; 822 write_directory_api_permissions.insert( 823 APIPermission::kFileSystemWriteDirectory); 824 scoped_refptr<PermissionSet> write_directory_permissions( 825 new PermissionSet(write_directory_api_permissions, 826 ManifestPermissionSet(), 827 URLPatternSet(), 828 URLPatternSet())); 829 830 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 831 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions, 832 write_permissions, 833 Manifest::TYPE_PLATFORM_APP)); 834 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions, 835 directory_permissions, 836 Manifest::TYPE_PLATFORM_APP)); 837 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions, 838 directory_permissions, 839 Manifest::TYPE_PLATFORM_APP)); 840 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions, 841 write_directory_permissions, 842 Manifest::TYPE_PLATFORM_APP)); 843 EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions, 844 write_permissions, 845 Manifest::TYPE_PLATFORM_APP)); 846 EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions, 847 write_directory_permissions, 848 Manifest::TYPE_PLATFORM_APP)); 849} 850 851TEST(PermissionsTest, GetWarningMessages_ManyHosts) { 852 scoped_refptr<Extension> extension; 853 854 extension = LoadManifest("permissions", "many-hosts.json"); 855 std::vector<base::string16> warnings = 856 PermissionsData::GetPermissionMessageStrings(extension.get()); 857 ASSERT_EQ(1u, warnings.size()); 858 EXPECT_EQ("Access your data on encrypted.google.com and www.google.com", 859 base::UTF16ToUTF8(warnings[0])); 860} 861 862TEST(PermissionsTest, GetWarningMessages_Plugins) { 863 scoped_refptr<Extension> extension; 864 scoped_refptr<PermissionSet> permissions; 865 866 extension = LoadManifest("permissions", "plugins.json"); 867 std::vector<base::string16> warnings = 868 PermissionsData::GetPermissionMessageStrings(extension.get()); 869// We don't parse the plugins key on Chrome OS, so it should not ask for any 870 // permissions. 871#if defined(OS_CHROMEOS) 872 ASSERT_EQ(0u, warnings.size()); 873#else 874 ASSERT_EQ(1u, warnings.size()); 875 EXPECT_EQ("Access all data on your computer and the websites you visit", 876 base::UTF16ToUTF8(warnings[0])); 877#endif 878} 879 880TEST(PermissionsTest, GetWarningMessages_AudioVideo) { 881 // Both audio and video present. 882 scoped_refptr<Extension> extension = 883 LoadManifest("permissions", "audio-video.json"); 884 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 885 PermissionSet* set = 886 const_cast<PermissionSet*>( 887 extension->GetActivePermissions().get()); 888 std::vector<base::string16> warnings = 889 provider->GetWarningMessages(set, extension->GetType()); 890 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 891 EXPECT_FALSE(Contains(warnings, "Use your camera")); 892 EXPECT_TRUE(Contains(warnings, "Use your microphone and camera")); 893 size_t combined_index = IndexOf(warnings, "Use your microphone and camera"); 894 size_t combined_size = warnings.size(); 895 896 // Just audio present. 897 set->apis_.erase(APIPermission::kVideoCapture); 898 warnings = provider->GetWarningMessages(set, extension->GetType()); 899 EXPECT_EQ(combined_size, warnings.size()); 900 EXPECT_EQ(combined_index, IndexOf(warnings, "Use your microphone")); 901 EXPECT_FALSE(Contains(warnings, "Use your camera")); 902 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 903 904 // Just video present. 905 set->apis_.erase(APIPermission::kAudioCapture); 906 set->apis_.insert(APIPermission::kVideoCapture); 907 warnings = provider->GetWarningMessages(set, extension->GetType()); 908 EXPECT_EQ(combined_size, warnings.size()); 909 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 910 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 911 EXPECT_TRUE(Contains(warnings, "Use your camera")); 912} 913 914TEST(PermissionsTest, GetWarningMessages_DeclarativeWebRequest) { 915 // Test that if the declarativeWebRequest permission is present 916 // in combination with all hosts permission, then only the warning 917 // for host permissions is shown, because that covers the use of 918 // declarativeWebRequest. 919 920 // Until Declarative Web Request is in stable, let's make sure it is enabled 921 // on the current channel. 922 ScopedCurrentChannel sc(chrome::VersionInfo::CHANNEL_CANARY); 923 924 // First verify that declarativeWebRequest produces a message when host 925 // permissions do not cover all hosts. 926 scoped_refptr<Extension> extension = 927 LoadManifest("permissions", "web_request_com_host_permissions.json"); 928 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 929 const PermissionSet* set = extension->GetActivePermissions().get(); 930 std::vector<base::string16> warnings = 931 provider->GetWarningMessages(set, extension->GetType()); 932 EXPECT_TRUE(Contains(warnings, "Block parts of web pages")); 933 EXPECT_FALSE(Contains(warnings, "Access your data on all websites")); 934 935 // Now verify that declarativeWebRequest does not produce a message when host 936 // permissions do cover all hosts. 937 extension = 938 LoadManifest("permissions", "web_request_all_host_permissions.json"); 939 set = extension->GetActivePermissions().get(); 940 warnings = provider->GetWarningMessages(set, extension->GetType()); 941 EXPECT_FALSE(Contains(warnings, "Block parts of web pages")); 942 EXPECT_TRUE(Contains(warnings, "Access your data on all websites")); 943} 944 945TEST(PermissionsTest, GetWarningMessages_Serial) { 946 scoped_refptr<Extension> extension = 947 LoadManifest("permissions", "serial.json"); 948 949 EXPECT_TRUE(extension->is_platform_app()); 950 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSerial)); 951 std::vector<base::string16> warnings = 952 PermissionsData::GetPermissionMessageStrings(extension.get()); 953 EXPECT_TRUE( 954 Contains(warnings, "Use serial devices attached to your computer")); 955 ASSERT_EQ(1u, warnings.size()); 956} 957 958TEST(PermissionsTest, GetWarningMessages_Socket_AnyHost) { 959 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 960 961 scoped_refptr<Extension> extension = 962 LoadManifest("permissions", "socket_any_host.json"); 963 EXPECT_TRUE(extension->is_platform_app()); 964 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 965 std::vector<base::string16> warnings = 966 PermissionsData::GetPermissionMessageStrings(extension.get()); 967 EXPECT_EQ(1u, warnings.size()); 968 EXPECT_TRUE(Contains(warnings, "Exchange data with any computer " 969 "on the local network or internet")); 970} 971 972TEST(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) { 973 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 974 975 scoped_refptr<Extension> extension = 976 LoadManifest("permissions", "socket_one_domain_two_hostnames.json"); 977 EXPECT_TRUE(extension->is_platform_app()); 978 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 979 std::vector<base::string16> warnings = 980 PermissionsData::GetPermissionMessageStrings(extension.get()); 981 982 // Verify the warnings, including support for unicode characters, the fact 983 // that domain host warnings come before specific host warnings, and the fact 984 // that domains and hostnames are in alphabetical order regardless of the 985 // order in the manifest file. 986 EXPECT_EQ(2u, warnings.size()); 987 if (warnings.size() > 0) 988 EXPECT_EQ(warnings[0], 989 base::UTF8ToUTF16("Exchange data with any computer in the domain " 990 "example.org")); 991 if (warnings.size() > 1) 992 EXPECT_EQ(warnings[1], 993 base::UTF8ToUTF16("Exchange data with the computers named: " 994 "b\xC3\xA5r.example.com foo.example.com")); 995 // "\xC3\xA5" = UTF-8 for lowercase A with ring above 996} 997 998TEST(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) { 999 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 1000 1001 scoped_refptr<Extension> extension = 1002 LoadManifest("permissions", "socket_two_domains_one_hostname.json"); 1003 EXPECT_TRUE(extension->is_platform_app()); 1004 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket)); 1005 std::vector<base::string16> warnings = 1006 PermissionsData::GetPermissionMessageStrings(extension.get()); 1007 1008 // Verify the warnings, including the fact that domain host warnings come 1009 // before specific host warnings and the fact that domains and hostnames are 1010 // in alphabetical order regardless of the order in the manifest file. 1011 EXPECT_EQ(2u, warnings.size()); 1012 if (warnings.size() > 0) 1013 EXPECT_EQ(warnings[0], 1014 base::UTF8ToUTF16("Exchange data with any computer in the " 1015 "domains: example.com foo.example.org")); 1016 if (warnings.size() > 1) 1017 EXPECT_EQ(warnings[1], 1018 base::UTF8ToUTF16("Exchange data with the computer named " 1019 "bar.example.org")); 1020} 1021 1022TEST(PermissionsTest, GetWarningMessages_PlatformApppHosts) { 1023 scoped_refptr<Extension> extension; 1024 1025 extension = LoadManifest("permissions", "platform_app_hosts.json"); 1026 EXPECT_TRUE(extension->is_platform_app()); 1027 std::vector<base::string16> warnings = 1028 PermissionsData::GetPermissionMessageStrings(extension.get()); 1029 ASSERT_EQ(0u, warnings.size()); 1030 1031 extension = LoadManifest("permissions", "platform_app_all_urls.json"); 1032 EXPECT_TRUE(extension->is_platform_app()); 1033 warnings = PermissionsData::GetPermissionMessageStrings(extension.get()); 1034 ASSERT_EQ(0u, warnings.size()); 1035} 1036 1037TEST(PermissionsTest, GetDistinctHosts) { 1038 URLPatternSet explicit_hosts; 1039 std::set<std::string> expected; 1040 expected.insert("www.foo.com"); 1041 expected.insert("www.bar.com"); 1042 expected.insert("www.baz.com"); 1043 1044 { 1045 SCOPED_TRACE("no dupes"); 1046 1047 // Simple list with no dupes. 1048 explicit_hosts.AddPattern( 1049 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1050 explicit_hosts.AddPattern( 1051 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path")); 1052 explicit_hosts.AddPattern( 1053 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 1054 EXPECT_EQ(expected, 1055 permission_message_util::GetDistinctHosts( 1056 explicit_hosts, true, true)); 1057 } 1058 1059 { 1060 SCOPED_TRACE("two dupes"); 1061 1062 // Add some dupes. 1063 explicit_hosts.AddPattern( 1064 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1065 explicit_hosts.AddPattern( 1066 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 1067 EXPECT_EQ(expected, 1068 permission_message_util::GetDistinctHosts( 1069 explicit_hosts, true, true)); 1070 } 1071 1072 { 1073 SCOPED_TRACE("schemes differ"); 1074 1075 // Add a pattern that differs only by scheme. This should be filtered out. 1076 explicit_hosts.AddPattern( 1077 URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path")); 1078 EXPECT_EQ(expected, 1079 permission_message_util::GetDistinctHosts( 1080 explicit_hosts, true, true)); 1081 } 1082 1083 { 1084 SCOPED_TRACE("paths differ"); 1085 1086 // Add some dupes by path. 1087 explicit_hosts.AddPattern( 1088 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath")); 1089 EXPECT_EQ(expected, 1090 permission_message_util::GetDistinctHosts( 1091 explicit_hosts, true, true)); 1092 } 1093 1094 { 1095 SCOPED_TRACE("subdomains differ"); 1096 1097 // We don't do anything special for subdomains. 1098 explicit_hosts.AddPattern( 1099 URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path")); 1100 explicit_hosts.AddPattern( 1101 URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path")); 1102 1103 expected.insert("monkey.www.bar.com"); 1104 expected.insert("bar.com"); 1105 1106 EXPECT_EQ(expected, 1107 permission_message_util::GetDistinctHosts( 1108 explicit_hosts, true, true)); 1109 } 1110 1111 { 1112 SCOPED_TRACE("RCDs differ"); 1113 1114 // Now test for RCD uniquing. 1115 explicit_hosts.AddPattern( 1116 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1117 explicit_hosts.AddPattern( 1118 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1119 explicit_hosts.AddPattern( 1120 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path")); 1121 explicit_hosts.AddPattern( 1122 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path")); 1123 explicit_hosts.AddPattern( 1124 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1125 explicit_hosts.AddPattern( 1126 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path")); 1127 1128 // This is an unknown RCD, which shouldn't be uniqued out. 1129 explicit_hosts.AddPattern( 1130 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1131 // But it should only occur once. 1132 explicit_hosts.AddPattern( 1133 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1134 1135 expected.insert("www.foo.xyzzy"); 1136 1137 EXPECT_EQ(expected, 1138 permission_message_util::GetDistinctHosts( 1139 explicit_hosts, true, true)); 1140 } 1141 1142 { 1143 SCOPED_TRACE("wildcards"); 1144 1145 explicit_hosts.AddPattern( 1146 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1147 1148 expected.insert("*.google.com"); 1149 1150 EXPECT_EQ(expected, 1151 permission_message_util::GetDistinctHosts( 1152 explicit_hosts, true, true)); 1153 } 1154 1155 { 1156 SCOPED_TRACE("scriptable hosts"); 1157 1158 APIPermissionSet empty_perms; 1159 explicit_hosts.ClearPatterns(); 1160 URLPatternSet scriptable_hosts; 1161 expected.clear(); 1162 1163 explicit_hosts.AddPattern( 1164 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1165 scriptable_hosts.AddPattern( 1166 URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*")); 1167 1168 expected.insert("*.google.com"); 1169 expected.insert("*.example.com"); 1170 1171 scoped_refptr<PermissionSet> perm_set(new PermissionSet( 1172 empty_perms, ManifestPermissionSet(), 1173 explicit_hosts, scriptable_hosts)); 1174 EXPECT_EQ(expected, 1175 permission_message_util::GetDistinctHosts( 1176 perm_set->effective_hosts(), true, true)); 1177 } 1178 1179 { 1180 // We don't display warnings for file URLs because they are off by default. 1181 SCOPED_TRACE("file urls"); 1182 1183 explicit_hosts.ClearPatterns(); 1184 expected.clear(); 1185 1186 explicit_hosts.AddPattern( 1187 URLPattern(URLPattern::SCHEME_FILE, "file:///*")); 1188 1189 EXPECT_EQ(expected, 1190 permission_message_util::GetDistinctHosts( 1191 explicit_hosts, true, true)); 1192 } 1193} 1194 1195TEST(PermissionsTest, GetDistinctHosts_ComIsBestRcd) { 1196 URLPatternSet explicit_hosts; 1197 explicit_hosts.AddPattern( 1198 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1199 explicit_hosts.AddPattern( 1200 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1201 explicit_hosts.AddPattern( 1202 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1203 explicit_hosts.AddPattern( 1204 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1205 explicit_hosts.AddPattern( 1206 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1207 explicit_hosts.AddPattern( 1208 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1209 1210 std::set<std::string> expected; 1211 expected.insert("www.foo.com"); 1212 EXPECT_EQ(expected, 1213 permission_message_util::GetDistinctHosts( 1214 explicit_hosts, true, true)); 1215} 1216 1217TEST(PermissionsTest, GetDistinctHosts_NetIs2ndBestRcd) { 1218 URLPatternSet explicit_hosts; 1219 explicit_hosts.AddPattern( 1220 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1221 explicit_hosts.AddPattern( 1222 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1223 explicit_hosts.AddPattern( 1224 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1225 explicit_hosts.AddPattern( 1226 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1227 explicit_hosts.AddPattern( 1228 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1229 // No http://www.foo.com/path 1230 1231 std::set<std::string> expected; 1232 expected.insert("www.foo.net"); 1233 EXPECT_EQ(expected, 1234 permission_message_util::GetDistinctHosts( 1235 explicit_hosts, true, true)); 1236} 1237 1238TEST(PermissionsTest, GetDistinctHosts_OrgIs3rdBestRcd) { 1239 URLPatternSet explicit_hosts; 1240 explicit_hosts.AddPattern( 1241 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1242 explicit_hosts.AddPattern( 1243 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1244 explicit_hosts.AddPattern( 1245 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1246 // No http://www.foo.net/path 1247 explicit_hosts.AddPattern( 1248 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1249 // No http://www.foo.com/path 1250 1251 std::set<std::string> expected; 1252 expected.insert("www.foo.org"); 1253 EXPECT_EQ(expected, 1254 permission_message_util::GetDistinctHosts( 1255 explicit_hosts, true, true)); 1256} 1257 1258TEST(PermissionsTest, GetDistinctHosts_FirstInListIs4thBestRcd) { 1259 URLPatternSet explicit_hosts; 1260 explicit_hosts.AddPattern( 1261 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1262 // No http://www.foo.org/path 1263 explicit_hosts.AddPattern( 1264 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1265 // No http://www.foo.net/path 1266 explicit_hosts.AddPattern( 1267 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1268 // No http://www.foo.com/path 1269 1270 std::set<std::string> expected; 1271 expected.insert("www.foo.ca"); 1272 EXPECT_EQ(expected, 1273 permission_message_util::GetDistinctHosts( 1274 explicit_hosts, true, true)); 1275} 1276 1277TEST(PermissionsTest, IsHostPrivilegeIncrease) { 1278 Manifest::Type type = Manifest::TYPE_EXTENSION; 1279 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1280 ManifestPermissionSet empty_manifest_permissions; 1281 URLPatternSet elist1; 1282 URLPatternSet elist2; 1283 URLPatternSet slist1; 1284 URLPatternSet slist2; 1285 scoped_refptr<PermissionSet> set1; 1286 scoped_refptr<PermissionSet> set2; 1287 APIPermissionSet empty_perms; 1288 elist1.AddPattern( 1289 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1290 elist1.AddPattern( 1291 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1292 1293 // Test that the host order does not matter. 1294 elist2.AddPattern( 1295 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1296 elist2.AddPattern( 1297 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1298 1299 set1 = new PermissionSet(empty_perms, empty_manifest_permissions, 1300 elist1, slist1); 1301 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1302 elist2, slist2); 1303 1304 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type)); 1305 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1306 1307 // Test that paths are ignored. 1308 elist2.ClearPatterns(); 1309 elist2.AddPattern( 1310 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*")); 1311 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1312 elist2, slist2); 1313 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type)); 1314 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1315 1316 // Test that RCDs are ignored. 1317 elist2.ClearPatterns(); 1318 elist2.AddPattern( 1319 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*")); 1320 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1321 elist2, slist2); 1322 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type)); 1323 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1324 1325 // Test that subdomain wildcards are handled properly. 1326 elist2.ClearPatterns(); 1327 elist2.AddPattern( 1328 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*")); 1329 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1330 elist2, slist2); 1331 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type)); 1332 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337 1333 // EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1334 1335 // Test that different domains count as different hosts. 1336 elist2.ClearPatterns(); 1337 elist2.AddPattern( 1338 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1339 elist2.AddPattern( 1340 URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path")); 1341 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1342 elist2, slist2); 1343 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type)); 1344 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1345 1346 // Test that different subdomains count as different hosts. 1347 elist2.ClearPatterns(); 1348 elist2.AddPattern( 1349 URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*")); 1350 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1351 elist2, slist2); 1352 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type)); 1353 EXPECT_TRUE(provider->IsPrivilegeIncrease(set2, set1, type)); 1354 1355 // Test that platform apps do not have host permissions increases. 1356 type = Manifest::TYPE_PLATFORM_APP; 1357 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type)); 1358 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1359} 1360 1361TEST(PermissionsTest, GetAPIsAsStrings) { 1362 APIPermissionSet apis; 1363 URLPatternSet empty_set; 1364 1365 apis.insert(APIPermission::kProxy); 1366 apis.insert(APIPermission::kBackground); 1367 apis.insert(APIPermission::kNotification); 1368 apis.insert(APIPermission::kTab); 1369 1370 scoped_refptr<PermissionSet> perm_set = new PermissionSet( 1371 apis, ManifestPermissionSet(), empty_set, empty_set); 1372 std::set<std::string> api_names = perm_set->GetAPIsAsStrings(); 1373 1374 // The result is correct if it has the same number of elements 1375 // and we can convert it back to the id set. 1376 EXPECT_EQ(4u, api_names.size()); 1377 EXPECT_EQ(apis, 1378 PermissionsInfo::GetInstance()->GetAllByName(api_names)); 1379} 1380 1381TEST(PermissionsTest, IsEmpty) { 1382 APIPermissionSet empty_apis; 1383 URLPatternSet empty_extent; 1384 1385 scoped_refptr<PermissionSet> empty = new PermissionSet(); 1386 EXPECT_TRUE(empty->IsEmpty()); 1387 scoped_refptr<PermissionSet> perm_set; 1388 1389 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1390 empty_extent, empty_extent); 1391 EXPECT_TRUE(perm_set->IsEmpty()); 1392 1393 APIPermissionSet non_empty_apis; 1394 non_empty_apis.insert(APIPermission::kBackground); 1395 perm_set = new PermissionSet(non_empty_apis, ManifestPermissionSet(), 1396 empty_extent, empty_extent); 1397 EXPECT_FALSE(perm_set->IsEmpty()); 1398 1399 // Try non standard host 1400 URLPatternSet non_empty_extent; 1401 AddPattern(&non_empty_extent, "http://www.google.com/*"); 1402 1403 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1404 non_empty_extent, empty_extent); 1405 EXPECT_FALSE(perm_set->IsEmpty()); 1406 1407 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1408 empty_extent, non_empty_extent); 1409 EXPECT_FALSE(perm_set->IsEmpty()); 1410} 1411 1412TEST(PermissionsTest, ImpliedPermissions) { 1413 URLPatternSet empty_extent; 1414 APIPermissionSet apis; 1415 apis.insert(APIPermission::kWebRequest); 1416 apis.insert(APIPermission::kFileBrowserHandler); 1417 EXPECT_EQ(2U, apis.size()); 1418 1419 scoped_refptr<PermissionSet> perm_set; 1420 perm_set = new PermissionSet(apis, ManifestPermissionSet(), 1421 empty_extent, empty_extent); 1422 EXPECT_EQ(4U, perm_set->apis().size()); 1423} 1424 1425TEST(PermissionsTest, SyncFileSystemPermission) { 1426 scoped_refptr<Extension> extension = LoadManifest( 1427 "permissions", "sync_file_system.json"); 1428 APIPermissionSet apis; 1429 apis.insert(APIPermission::kSyncFileSystem); 1430 EXPECT_TRUE(extension->is_platform_app()); 1431 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSyncFileSystem)); 1432 std::vector<base::string16> warnings = 1433 PermissionsData::GetPermissionMessageStrings(extension.get()); 1434 EXPECT_TRUE(Contains(warnings, "Store data in your Google Drive account")); 1435 ASSERT_EQ(1u, warnings.size()); 1436} 1437 1438// Make sure that we don't crash when we're trying to show the permissions 1439// even though chrome://thumb (and everything that's not chrome://favicon with 1440// a chrome:// scheme) is not a valid permission. 1441// More details here: crbug/246314. 1442TEST(PermissionsTest, ChromeURLs) { 1443 URLPatternSet allowed_hosts; 1444 allowed_hosts.AddPattern( 1445 URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/")); 1446 allowed_hosts.AddPattern( 1447 URLPattern(URLPattern::SCHEME_ALL, "chrome://favicon/")); 1448 allowed_hosts.AddPattern( 1449 URLPattern(URLPattern::SCHEME_ALL, "chrome://thumb/")); 1450 scoped_refptr<PermissionSet> permissions( 1451 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), 1452 allowed_hosts, URLPatternSet())); 1453 PermissionMessageProvider::Get()-> 1454 GetPermissionMessages(permissions, Manifest::TYPE_EXTENSION); 1455} 1456 1457TEST(PermissionsTest, IsPrivilegeIncrease_DeclarativeWebRequest) { 1458 scoped_refptr<Extension> extension( 1459 LoadManifest("permissions", "permissions_all_urls.json")); 1460 scoped_refptr<const PermissionSet> permissions( 1461 extension->GetActivePermissions()); 1462 1463 scoped_refptr<Extension> extension_dwr( 1464 LoadManifest("permissions", "web_request_all_host_permissions.json")); 1465 scoped_refptr<const PermissionSet> permissions_dwr( 1466 extension_dwr->GetActivePermissions()); 1467 1468 EXPECT_FALSE(PermissionMessageProvider::Get()-> 1469 IsPrivilegeIncrease(permissions.get(), 1470 permissions_dwr.get(), 1471 extension->GetType())); 1472} 1473 1474} // namespace extensions 1475