permission_set_unittest.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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/grit/generated_resources.h" 16#include "extensions/common/error_utils.h" 17#include "extensions/common/extension.h" 18#include "extensions/common/extension_builder.h" 19#include "extensions/common/permissions/permission_message_provider.h" 20#include "extensions/common/permissions/permission_message_util.h" 21#include "extensions/common/permissions/permission_set.h" 22#include "extensions/common/permissions/permissions_data.h" 23#include "extensions/common/permissions/permissions_info.h" 24#include "extensions/common/permissions/socket_permission.h" 25#include "extensions/common/value_builder.h" 26#include "extensions/strings/grit/extensions_strings.h" 27#include "testing/gtest/include/gtest/gtest.h" 28#include "ui/base/l10n/l10n_util.h" 29 30using extension_test_util::LoadManifest; 31 32namespace extensions { 33 34namespace { 35 36static void AddPattern(URLPatternSet* extent, const std::string& pattern) { 37 int schemes = URLPattern::SCHEME_ALL; 38 extent->AddPattern(URLPattern(schemes, pattern)); 39} 40 41size_t IndexOf(const std::vector<base::string16>& warnings, 42 const std::string& warning) { 43 for (size_t i = 0; i < warnings.size(); ++i) { 44 if (warnings[i] == base::ASCIIToUTF16(warning)) 45 return i; 46 } 47 48 return warnings.size(); 49} 50 51bool Contains(const std::vector<base::string16>& warnings, 52 const std::string& warning) { 53 return IndexOf(warnings, warning) != warnings.size(); 54} 55 56} // namespace 57 58// Tests GetByID. 59TEST(PermissionsTest, GetByID) { 60 PermissionsInfo* info = PermissionsInfo::GetInstance(); 61 APIPermissionSet apis = info->GetAll(); 62 for (APIPermissionSet::const_iterator i = apis.begin(); 63 i != apis.end(); ++i) { 64 EXPECT_EQ(i->id(), i->info()->id()); 65 } 66} 67 68// Tests that GetByName works with normal permission names and aliases. 69TEST(PermissionsTest, GetByName) { 70 PermissionsInfo* info = PermissionsInfo::GetInstance(); 71 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id()); 72 EXPECT_EQ(APIPermission::kManagement, 73 info->GetByName("management")->id()); 74 EXPECT_FALSE(info->GetByName("alsdkfjasldkfj")); 75} 76 77TEST(PermissionsTest, GetAll) { 78 size_t count = 0; 79 PermissionsInfo* info = PermissionsInfo::GetInstance(); 80 APIPermissionSet apis = info->GetAll(); 81 for (APIPermissionSet::const_iterator api = apis.begin(); 82 api != apis.end(); ++api) { 83 // Make sure only the valid permission IDs get returned. 84 EXPECT_NE(APIPermission::kInvalid, api->id()); 85 EXPECT_NE(APIPermission::kUnknown, api->id()); 86 count++; 87 } 88 EXPECT_EQ(count, info->get_permission_count()); 89} 90 91TEST(PermissionsTest, GetAllByName) { 92 std::set<std::string> names; 93 names.insert("background"); 94 names.insert("management"); 95 96 // This is an alias of kTab 97 names.insert("windows"); 98 99 // This unknown name should get dropped. 100 names.insert("sdlkfjasdlkfj"); 101 102 APIPermissionSet expected; 103 expected.insert(APIPermission::kBackground); 104 expected.insert(APIPermission::kManagement); 105 expected.insert(APIPermission::kTab); 106 107 EXPECT_EQ(expected, 108 PermissionsInfo::GetInstance()->GetAllByName(names)); 109} 110 111// Tests that the aliases are properly mapped. 112TEST(PermissionsTest, Aliases) { 113 PermissionsInfo* info = PermissionsInfo::GetInstance(); 114 // tabs: tabs, windows 115 std::string tabs_name = "tabs"; 116 EXPECT_EQ(tabs_name, info->GetByID(APIPermission::kTab)->name()); 117 EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id()); 118 EXPECT_EQ(APIPermission::kTab, info->GetByName("windows")->id()); 119 120 // unlimitedStorage: unlimitedStorage, unlimited_storage 121 std::string storage_name = "unlimitedStorage"; 122 EXPECT_EQ(storage_name, info->GetByID( 123 APIPermission::kUnlimitedStorage)->name()); 124 EXPECT_EQ(APIPermission::kUnlimitedStorage, 125 info->GetByName("unlimitedStorage")->id()); 126 EXPECT_EQ(APIPermission::kUnlimitedStorage, 127 info->GetByName("unlimited_storage")->id()); 128} 129 130TEST(PermissionsTest, EffectiveHostPermissions) { 131 scoped_refptr<Extension> extension; 132 scoped_refptr<const PermissionSet> permissions; 133 134 extension = LoadManifest("effective_host_permissions", "empty.json"); 135 permissions = extension->permissions_data()->active_permissions(); 136 EXPECT_EQ(0u, 137 extension->permissions_data() 138 ->GetEffectiveHostPermissions() 139 .patterns() 140 .size()); 141 EXPECT_FALSE( 142 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 143 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 144 145 extension = LoadManifest("effective_host_permissions", "one_host.json"); 146 permissions = extension->permissions_data()->active_permissions(); 147 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 148 GURL("http://www.google.com"))); 149 EXPECT_FALSE(permissions->HasEffectiveAccessToURL( 150 GURL("https://www.google.com"))); 151 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 152 153 extension = LoadManifest("effective_host_permissions", 154 "one_host_wildcard.json"); 155 permissions = extension->permissions_data()->active_permissions(); 156 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 157 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 158 GURL("http://foo.google.com"))); 159 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 160 161 extension = LoadManifest("effective_host_permissions", "two_hosts.json"); 162 permissions = extension->permissions_data()->active_permissions(); 163 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 164 GURL("http://www.google.com"))); 165 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 166 GURL("http://www.reddit.com"))); 167 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 168 169 extension = LoadManifest("effective_host_permissions", 170 "https_not_considered.json"); 171 permissions = extension->permissions_data()->active_permissions(); 172 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 173 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://google.com"))); 174 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 175 176 extension = LoadManifest("effective_host_permissions", 177 "two_content_scripts.json"); 178 permissions = extension->permissions_data()->active_permissions(); 179 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com"))); 180 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 181 GURL("http://www.reddit.com"))); 182 EXPECT_TRUE(permissions->HasEffectiveAccessToURL( 183 GURL("http://news.ycombinator.com"))); 184 EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts()); 185 186 extension = LoadManifest("effective_host_permissions", "all_hosts.json"); 187 permissions = extension->permissions_data()->active_permissions(); 188 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 189 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("https://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_hosts2.json"); 195 permissions = extension->permissions_data()->active_permissions(); 196 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 197 EXPECT_TRUE( 198 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 199 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 200 201 extension = LoadManifest("effective_host_permissions", "all_hosts3.json"); 202 permissions = extension->permissions_data()->active_permissions(); 203 EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("http://test/"))); 204 EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://test/"))); 205 EXPECT_TRUE( 206 permissions->HasEffectiveAccessToURL(GURL("http://www.google.com"))); 207 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 208} 209 210TEST(PermissionsTest, ExplicitAccessToOrigin) { 211 APIPermissionSet apis; 212 ManifestPermissionSet manifest_permissions; 213 URLPatternSet explicit_hosts; 214 URLPatternSet scriptable_hosts; 215 216 AddPattern(&explicit_hosts, "http://*.google.com/*"); 217 // The explicit host paths should get set to /*. 218 AddPattern(&explicit_hosts, "http://www.example.com/a/particular/path/*"); 219 220 scoped_refptr<PermissionSet> perm_set = new PermissionSet( 221 apis, manifest_permissions, explicit_hosts, scriptable_hosts); 222 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 223 GURL("http://www.google.com/"))); 224 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 225 GURL("http://test.google.com/"))); 226 ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin( 227 GURL("http://www.example.com"))); 228 ASSERT_TRUE(perm_set->HasEffectiveAccessToURL( 229 GURL("http://www.example.com"))); 230 ASSERT_FALSE(perm_set->HasExplicitAccessToOrigin( 231 GURL("http://test.example.com"))); 232} 233 234TEST(PermissionsTest, CreateUnion) { 235 APIPermission* permission = NULL; 236 237 ManifestPermissionSet manifest_permissions; 238 APIPermissionSet apis1; 239 APIPermissionSet apis2; 240 APIPermissionSet expected_apis; 241 242 URLPatternSet explicit_hosts1; 243 URLPatternSet explicit_hosts2; 244 URLPatternSet expected_explicit_hosts; 245 246 URLPatternSet scriptable_hosts1; 247 URLPatternSet scriptable_hosts2; 248 URLPatternSet expected_scriptable_hosts; 249 250 URLPatternSet effective_hosts; 251 252 scoped_refptr<PermissionSet> set1; 253 scoped_refptr<PermissionSet> set2; 254 scoped_refptr<PermissionSet> union_set; 255 256 const APIPermissionInfo* permission_info = 257 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 258 permission = permission_info->CreateAPIPermission(); 259 { 260 scoped_ptr<base::ListValue> value(new base::ListValue()); 261 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 262 value->Append(new base::StringValue("udp-bind::8080")); 263 value->Append(new base::StringValue("udp-send-to::8888")); 264 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 265 } 266 267 // Union with an empty set. 268 apis1.insert(APIPermission::kTab); 269 apis1.insert(APIPermission::kBackground); 270 apis1.insert(permission->Clone()); 271 expected_apis.insert(APIPermission::kTab); 272 expected_apis.insert(APIPermission::kBackground); 273 expected_apis.insert(permission); 274 275 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 276 AddPattern(&expected_explicit_hosts, "http://*.google.com/*"); 277 AddPattern(&effective_hosts, "http://*.google.com/*"); 278 279 set1 = new PermissionSet(apis1, manifest_permissions, 280 explicit_hosts1, scriptable_hosts1); 281 set2 = new PermissionSet(apis2, manifest_permissions, 282 explicit_hosts2, scriptable_hosts2); 283 union_set = PermissionSet::CreateUnion(set1.get(), set2.get()); 284 EXPECT_TRUE(set1->Contains(*set2.get())); 285 EXPECT_TRUE(set1->Contains(*union_set.get())); 286 EXPECT_FALSE(set2->Contains(*set1.get())); 287 EXPECT_FALSE(set2->Contains(*union_set.get())); 288 EXPECT_TRUE(union_set->Contains(*set1.get())); 289 EXPECT_TRUE(union_set->Contains(*set2.get())); 290 291 EXPECT_FALSE(union_set->HasEffectiveFullAccess()); 292 EXPECT_EQ(expected_apis, union_set->apis()); 293 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts()); 294 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts()); 295 EXPECT_EQ(expected_explicit_hosts, union_set->effective_hosts()); 296 297 // Now use a real second set. 298 apis2.insert(APIPermission::kTab); 299 apis2.insert(APIPermission::kProxy); 300 apis2.insert(APIPermission::kClipboardWrite); 301 apis2.insert(APIPermission::kPlugin); 302 303 permission = permission_info->CreateAPIPermission(); 304 { 305 scoped_ptr<base::ListValue> value(new base::ListValue()); 306 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 307 value->Append(new base::StringValue("udp-send-to::8899")); 308 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 309 } 310 apis2.insert(permission); 311 312 expected_apis.insert(APIPermission::kTab); 313 expected_apis.insert(APIPermission::kProxy); 314 expected_apis.insert(APIPermission::kClipboardWrite); 315 expected_apis.insert(APIPermission::kPlugin); 316 317 permission = permission_info->CreateAPIPermission(); 318 { 319 scoped_ptr<base::ListValue> value(new base::ListValue()); 320 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 321 value->Append(new base::StringValue("udp-bind::8080")); 322 value->Append(new base::StringValue("udp-send-to::8888")); 323 value->Append(new base::StringValue("udp-send-to::8899")); 324 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 325 } 326 // Insert a new permission socket permisssion which will replace the old one. 327 expected_apis.insert(permission); 328 329 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 330 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 331 AddPattern(&expected_explicit_hosts, "http://*.example.com/*"); 332 AddPattern(&expected_scriptable_hosts, "http://*.google.com/*"); 333 334 URLPatternSet::CreateUnion( 335 explicit_hosts2, scriptable_hosts2, &effective_hosts); 336 337 set2 = new PermissionSet(apis2, manifest_permissions, 338 explicit_hosts2, scriptable_hosts2); 339 union_set = PermissionSet::CreateUnion(set1.get(), set2.get()); 340 341 EXPECT_FALSE(set1->Contains(*set2.get())); 342 EXPECT_FALSE(set1->Contains(*union_set.get())); 343 EXPECT_FALSE(set2->Contains(*set1.get())); 344 EXPECT_FALSE(set2->Contains(*union_set.get())); 345 EXPECT_TRUE(union_set->Contains(*set1.get())); 346 EXPECT_TRUE(union_set->Contains(*set2.get())); 347 348 EXPECT_TRUE(union_set->HasEffectiveFullAccess()); 349 EXPECT_TRUE(union_set->HasEffectiveAccessToAllHosts()); 350 EXPECT_EQ(expected_apis, union_set->apis()); 351 EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts()); 352 EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts()); 353 EXPECT_EQ(effective_hosts, union_set->effective_hosts()); 354} 355 356TEST(PermissionsTest, CreateIntersection) { 357 APIPermission* permission = NULL; 358 359 ManifestPermissionSet manifest_permissions; 360 APIPermissionSet apis1; 361 APIPermissionSet apis2; 362 APIPermissionSet expected_apis; 363 364 URLPatternSet explicit_hosts1; 365 URLPatternSet explicit_hosts2; 366 URLPatternSet expected_explicit_hosts; 367 368 URLPatternSet scriptable_hosts1; 369 URLPatternSet scriptable_hosts2; 370 URLPatternSet expected_scriptable_hosts; 371 372 URLPatternSet effective_hosts; 373 374 scoped_refptr<PermissionSet> set1; 375 scoped_refptr<PermissionSet> set2; 376 scoped_refptr<PermissionSet> new_set; 377 378 const APIPermissionInfo* permission_info = 379 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 380 381 // Intersection with an empty set. 382 apis1.insert(APIPermission::kTab); 383 apis1.insert(APIPermission::kBackground); 384 permission = permission_info->CreateAPIPermission(); 385 { 386 scoped_ptr<base::ListValue> value(new base::ListValue()); 387 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 388 value->Append(new base::StringValue("udp-bind::8080")); 389 value->Append(new base::StringValue("udp-send-to::8888")); 390 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 391 } 392 apis1.insert(permission); 393 394 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 395 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*"); 396 397 set1 = new PermissionSet(apis1, manifest_permissions, 398 explicit_hosts1, scriptable_hosts1); 399 set2 = new PermissionSet(apis2, manifest_permissions, 400 explicit_hosts2, scriptable_hosts2); 401 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get()); 402 EXPECT_TRUE(set1->Contains(*new_set.get())); 403 EXPECT_TRUE(set2->Contains(*new_set.get())); 404 EXPECT_TRUE(set1->Contains(*set2.get())); 405 EXPECT_FALSE(set2->Contains(*set1.get())); 406 EXPECT_FALSE(new_set->Contains(*set1.get())); 407 EXPECT_TRUE(new_set->Contains(*set2.get())); 408 409 EXPECT_TRUE(new_set->IsEmpty()); 410 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 411 EXPECT_EQ(expected_apis, new_set->apis()); 412 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 413 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 414 EXPECT_EQ(expected_explicit_hosts, new_set->effective_hosts()); 415 416 // Now use a real second set. 417 apis2.insert(APIPermission::kTab); 418 apis2.insert(APIPermission::kProxy); 419 apis2.insert(APIPermission::kClipboardWrite); 420 apis2.insert(APIPermission::kPlugin); 421 permission = permission_info->CreateAPIPermission(); 422 { 423 scoped_ptr<base::ListValue> value(new base::ListValue()); 424 value->Append(new base::StringValue("udp-bind::8080")); 425 value->Append(new base::StringValue("udp-send-to::8888")); 426 value->Append(new base::StringValue("udp-send-to::8899")); 427 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 428 } 429 apis2.insert(permission); 430 431 expected_apis.insert(APIPermission::kTab); 432 permission = permission_info->CreateAPIPermission(); 433 { 434 scoped_ptr<base::ListValue> value(new base::ListValue()); 435 value->Append(new base::StringValue("udp-bind::8080")); 436 value->Append(new base::StringValue("udp-send-to::8888")); 437 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 438 } 439 expected_apis.insert(permission); 440 441 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 442 AddPattern(&explicit_hosts2, "http://*.google.com/*"); 443 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 444 AddPattern(&expected_explicit_hosts, "http://*.google.com/*"); 445 446 effective_hosts.ClearPatterns(); 447 AddPattern(&effective_hosts, "http://*.google.com/*"); 448 449 set2 = new PermissionSet(apis2, manifest_permissions, 450 explicit_hosts2, scriptable_hosts2); 451 new_set = PermissionSet::CreateIntersection(set1.get(), set2.get()); 452 453 EXPECT_TRUE(set1->Contains(*new_set.get())); 454 EXPECT_TRUE(set2->Contains(*new_set.get())); 455 EXPECT_FALSE(set1->Contains(*set2.get())); 456 EXPECT_FALSE(set2->Contains(*set1.get())); 457 EXPECT_FALSE(new_set->Contains(*set1.get())); 458 EXPECT_FALSE(new_set->Contains(*set2.get())); 459 460 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 461 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts()); 462 EXPECT_EQ(expected_apis, new_set->apis()); 463 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 464 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 465 EXPECT_EQ(effective_hosts, new_set->effective_hosts()); 466} 467 468TEST(PermissionsTest, CreateDifference) { 469 APIPermission* permission = NULL; 470 471 ManifestPermissionSet manifest_permissions; 472 APIPermissionSet apis1; 473 APIPermissionSet apis2; 474 APIPermissionSet expected_apis; 475 476 URLPatternSet explicit_hosts1; 477 URLPatternSet explicit_hosts2; 478 URLPatternSet expected_explicit_hosts; 479 480 URLPatternSet scriptable_hosts1; 481 URLPatternSet scriptable_hosts2; 482 URLPatternSet expected_scriptable_hosts; 483 484 URLPatternSet effective_hosts; 485 486 scoped_refptr<PermissionSet> set1; 487 scoped_refptr<PermissionSet> set2; 488 scoped_refptr<PermissionSet> new_set; 489 490 const APIPermissionInfo* permission_info = 491 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 492 493 // Difference with an empty set. 494 apis1.insert(APIPermission::kTab); 495 apis1.insert(APIPermission::kBackground); 496 permission = permission_info->CreateAPIPermission(); 497 { 498 scoped_ptr<base::ListValue> value(new base::ListValue()); 499 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 500 value->Append(new base::StringValue("udp-bind::8080")); 501 value->Append(new base::StringValue("udp-send-to::8888")); 502 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 503 } 504 apis1.insert(permission); 505 506 AddPattern(&explicit_hosts1, "http://*.google.com/*"); 507 AddPattern(&scriptable_hosts1, "http://www.reddit.com/*"); 508 509 set1 = new PermissionSet(apis1, manifest_permissions, 510 explicit_hosts1, scriptable_hosts1); 511 set2 = new PermissionSet(apis2, manifest_permissions, 512 explicit_hosts2, scriptable_hosts2); 513 new_set = PermissionSet::CreateDifference(set1.get(), set2.get()); 514 EXPECT_EQ(*set1.get(), *new_set.get()); 515 516 // Now use a real second set. 517 apis2.insert(APIPermission::kTab); 518 apis2.insert(APIPermission::kProxy); 519 apis2.insert(APIPermission::kClipboardWrite); 520 apis2.insert(APIPermission::kPlugin); 521 permission = permission_info->CreateAPIPermission(); 522 { 523 scoped_ptr<base::ListValue> value(new base::ListValue()); 524 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 525 value->Append(new base::StringValue("udp-send-to::8899")); 526 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 527 } 528 apis2.insert(permission); 529 530 expected_apis.insert(APIPermission::kBackground); 531 permission = permission_info->CreateAPIPermission(); 532 { 533 scoped_ptr<base::ListValue> value(new base::ListValue()); 534 value->Append(new base::StringValue("udp-bind::8080")); 535 value->Append(new base::StringValue("udp-send-to::8888")); 536 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 537 } 538 expected_apis.insert(permission); 539 540 AddPattern(&explicit_hosts2, "http://*.example.com/*"); 541 AddPattern(&explicit_hosts2, "http://*.google.com/*"); 542 AddPattern(&scriptable_hosts2, "http://*.google.com/*"); 543 AddPattern(&expected_scriptable_hosts, "http://www.reddit.com/*"); 544 545 effective_hosts.ClearPatterns(); 546 AddPattern(&effective_hosts, "http://www.reddit.com/*"); 547 548 set2 = new PermissionSet(apis2, manifest_permissions, 549 explicit_hosts2, scriptable_hosts2); 550 new_set = PermissionSet::CreateDifference(set1.get(), set2.get()); 551 552 EXPECT_TRUE(set1->Contains(*new_set.get())); 553 EXPECT_FALSE(set2->Contains(*new_set.get())); 554 555 EXPECT_FALSE(new_set->HasEffectiveFullAccess()); 556 EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts()); 557 EXPECT_EQ(expected_apis, new_set->apis()); 558 EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts()); 559 EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts()); 560 EXPECT_EQ(effective_hosts, new_set->effective_hosts()); 561 562 // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set 563 set1 = PermissionSet::CreateIntersection(new_set.get(), set2.get()); 564 EXPECT_TRUE(set1->IsEmpty()); 565} 566 567TEST(PermissionsTest, IsPrivilegeIncrease) { 568 const struct { 569 const char* base_name; 570 bool expect_increase; 571 } kTests[] = { 572 { "allhosts1", false }, // all -> all 573 { "allhosts2", false }, // all -> one 574 { "allhosts3", true }, // one -> all 575 { "hosts1", false }, // http://a,http://b -> http://a,http://b 576 { "hosts2", true }, // http://a,http://b -> https://a,http://*.b 577 { "hosts3", false }, // http://a,http://b -> http://a 578 { "hosts4", true }, // http://a -> http://a,http://b 579 { "hosts5", false }, // http://a,b,c -> http://a,b,c + https://a,b,c 580 { "hosts6", false }, // http://a.com -> http://a.com + http://a.co.uk 581 { "permissions1", false }, // tabs -> tabs 582 { "permissions2", true }, // tabs -> tabs,bookmarks 583 { "permissions3", true }, // http://a -> http://a,tabs 584 { "permissions5", true }, // bookmarks -> bookmarks,history 585 { "equivalent_warnings", false }, // tabs --> tabs, webNavigation 586#if !defined(OS_CHROMEOS) // plugins aren't allowed in ChromeOS 587 { "permissions4", false }, // plugin -> plugin,tabs 588 { "plugin1", false }, // plugin -> plugin 589 { "plugin2", false }, // plugin -> none 590 { "plugin3", true }, // none -> plugin 591#endif 592 { "storage", false }, // none -> storage 593 { "notifications", false }, // none -> notifications 594 { "platformapp1", false }, // host permissions for platform apps 595 { "platformapp2", true }, // API permissions for platform apps 596 { "media_galleries1", true }, // all -> read|all 597 { "media_galleries2", true }, // read|all -> read|delete|copyTo|all 598 { "media_galleries3", true }, // all -> read|delete|all 599 { "media_galleries4", false }, // read|all -> all 600 { "media_galleries5", false }, // read|copyTo|delete|all -> read|all 601 { "media_galleries6", false }, // read|all -> read|all 602 { "media_galleries7", true }, // read|delete|all -> read|copyTo|delete|all 603 { "sockets1", true }, // none -> tcp:*:* 604 { "sockets2", false }, // tcp:*:* -> tcp:*:* 605 { "sockets3", true }, // tcp:a.com:80 -> tcp:*:* 606 }; 607 608 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { 609 scoped_refptr<Extension> old_extension( 610 LoadManifest("allow_silent_upgrade", 611 std::string(kTests[i].base_name) + "_old.json")); 612 scoped_refptr<Extension> new_extension( 613 LoadManifest("allow_silent_upgrade", 614 std::string(kTests[i].base_name) + "_new.json")); 615 616 EXPECT_TRUE(new_extension.get()) << kTests[i].base_name << "_new.json"; 617 if (!new_extension.get()) 618 continue; 619 620 scoped_refptr<const PermissionSet> old_p( 621 old_extension->permissions_data()->active_permissions()); 622 scoped_refptr<const PermissionSet> new_p( 623 new_extension->permissions_data()->active_permissions()); 624 Manifest::Type extension_type = old_extension->GetType(); 625 626 bool increased = PermissionMessageProvider::Get()->IsPrivilegeIncrease( 627 old_p.get(), new_p.get(), extension_type); 628 EXPECT_EQ(kTests[i].expect_increase, increased) << kTests[i].base_name; 629 } 630} 631 632TEST(PermissionsTest, PermissionMessages) { 633 // Ensure that all permissions that needs to show install UI actually have 634 // strings associated with them. 635 APIPermissionSet skip; 636 637 // These are considered "nuisance" or "trivial" permissions that don't need 638 // a prompt. 639 skip.insert(APIPermission::kActiveTab); 640 skip.insert(APIPermission::kAlarms); 641 skip.insert(APIPermission::kAlphaEnabled); 642 skip.insert(APIPermission::kAlwaysOnTopWindows); 643 skip.insert(APIPermission::kAppView); 644 skip.insert(APIPermission::kAudio); 645 skip.insert(APIPermission::kBrowsingData); 646 skip.insert(APIPermission::kCastStreaming); 647 skip.insert(APIPermission::kContextMenus); 648 skip.insert(APIPermission::kCopresence); 649 skip.insert(APIPermission::kCopresencePrivate); 650 skip.insert(APIPermission::kDiagnostics); 651 skip.insert(APIPermission::kDns); 652 skip.insert(APIPermission::kDownloadsShelf); 653 skip.insert(APIPermission::kEmbeddedExtensionOptions); 654 skip.insert(APIPermission::kFontSettings); 655 skip.insert(APIPermission::kFullscreen); 656 skip.insert(APIPermission::kGcm); 657 skip.insert(APIPermission::kIdle); 658 skip.insert(APIPermission::kIdltest); 659 skip.insert(APIPermission::kLedger); 660 skip.insert(APIPermission::kLogPrivate); 661 skip.insert(APIPermission::kNotifications); 662 skip.insert(APIPermission::kNotificationProvider); 663 skip.insert(APIPermission::kOverrideEscFullscreen); 664 skip.insert(APIPermission::kPointerLock); 665 skip.insert(APIPermission::kPower); 666 skip.insert(APIPermission::kPushMessaging); 667 skip.insert(APIPermission::kSessions); 668 skip.insert(APIPermission::kStorage); 669 skip.insert(APIPermission::kSystemCpu); 670 skip.insert(APIPermission::kSystemDisplay); 671 skip.insert(APIPermission::kSystemMemory); 672 skip.insert(APIPermission::kSystemNetwork); 673 skip.insert(APIPermission::kSystemStorage); 674 skip.insert(APIPermission::kTts); 675 skip.insert(APIPermission::kUnlimitedStorage); 676 skip.insert(APIPermission::kWebcamPrivate); 677 skip.insert(APIPermission::kWebView); 678 skip.insert(APIPermission::kWindowShape); 679 680 // These permissions are restricted to extensions force-installed by policy 681 // and don't require a prompt, i.e. they're restricted to location 'policy'. 682 skip.insert(APIPermission::kEnterprisePlatformKeys); 683 684 // TODO(erikkay) add a string for this permission. 685 skip.insert(APIPermission::kBackground); 686 687 skip.insert(APIPermission::kClipboardWrite); 688 689 // The cookie permission does nothing unless you have associated host 690 // permissions. 691 skip.insert(APIPermission::kCookie); 692 693 // These are warned as part of host permission checks. 694 skip.insert(APIPermission::kDeclarativeContent); 695 skip.insert(APIPermission::kPageCapture); 696 skip.insert(APIPermission::kProxy); 697 skip.insert(APIPermission::kTabCapture); 698 skip.insert(APIPermission::kWebRequest); 699 skip.insert(APIPermission::kWebRequestBlocking); 700 701 // This permission requires explicit user action (context menu handler) 702 // so we won't prompt for it for now. 703 skip.insert(APIPermission::kFileBrowserHandler); 704 705 // These permissions require explicit user action (configuration dialog) 706 // so we don't prompt for them at install time. 707 skip.insert(APIPermission::kMediaGalleries); 708 709 // If you've turned on the experimental command-line flag, we don't need 710 // to warn you further. 711 skip.insert(APIPermission::kExperimental); 712 713 // The Identity API has its own server-driven permission prompts. 714 skip.insert(APIPermission::kIdentity); 715 716 // These are private. 717 skip.insert(APIPermission::kAccessibilityPrivate); 718 skip.insert(APIPermission::kAutoTestPrivate); 719 skip.insert(APIPermission::kBookmarkManagerPrivate); 720 skip.insert(APIPermission::kBrailleDisplayPrivate); 721 skip.insert(APIPermission::kCast); 722 skip.insert(APIPermission::kCastStreaming); 723 skip.insert(APIPermission::kChromeosInfoPrivate); 724 skip.insert(APIPermission::kCloudPrintPrivate); 725 skip.insert(APIPermission::kCommandLinePrivate); 726 skip.insert(APIPermission::kDeveloperPrivate); 727 skip.insert(APIPermission::kDial); 728 skip.insert(APIPermission::kDownloadsInternal); 729 skip.insert(APIPermission::kEasyUnlockPrivate); 730 skip.insert(APIPermission::kEchoPrivate); 731 skip.insert(APIPermission::kEnterprisePlatformKeysPrivate); 732 skip.insert(APIPermission::kFeedbackPrivate); 733 skip.insert(APIPermission::kFileBrowserHandlerInternal); 734 skip.insert(APIPermission::kFileBrowserPrivate); 735 skip.insert(APIPermission::kFirstRunPrivate); 736 skip.insert(APIPermission::kGcdPrivate); 737 skip.insert(APIPermission::kHotwordPrivate); 738 skip.insert(APIPermission::kIdentityPrivate); 739 skip.insert(APIPermission::kInfobars); 740 skip.insert(APIPermission::kInputMethodPrivate); 741 skip.insert(APIPermission::kMediaGalleriesPrivate); 742 skip.insert(APIPermission::kMediaPlayerPrivate); 743 skip.insert(APIPermission::kMetricsPrivate); 744 skip.insert(APIPermission::kMDns); 745 skip.insert(APIPermission::kPreferencesPrivate); 746 skip.insert(APIPermission::kPrincipalsPrivate); 747 skip.insert(APIPermission::kImageWriterPrivate); 748 skip.insert(APIPermission::kReadingListPrivate); 749 skip.insert(APIPermission::kRtcPrivate); 750 skip.insert(APIPermission::kStreamsPrivate); 751 skip.insert(APIPermission::kSyncedNotificationsPrivate); 752 skip.insert(APIPermission::kSystemPrivate); 753 skip.insert(APIPermission::kTabCaptureForTab); 754 skip.insert(APIPermission::kTerminalPrivate); 755 skip.insert(APIPermission::kVirtualKeyboardPrivate); 756 skip.insert(APIPermission::kWallpaperPrivate); 757 skip.insert(APIPermission::kWebrtcAudioPrivate); 758 skip.insert(APIPermission::kWebrtcLoggingPrivate); 759 skip.insert(APIPermission::kWebstorePrivate); 760 761 // Warned as part of host permissions. 762 skip.insert(APIPermission::kDevtools); 763 764 // Platform apps. 765 skip.insert(APIPermission::kBrowser); 766 skip.insert(APIPermission::kFileSystem); 767 skip.insert(APIPermission::kFileSystemProvider); 768 skip.insert(APIPermission::kFileSystemRetainEntries); 769 skip.insert(APIPermission::kFileSystemWrite); 770 skip.insert(APIPermission::kSocket); 771 skip.insert(APIPermission::kUsbDevice); 772 773 PermissionsInfo* info = PermissionsInfo::GetInstance(); 774 APIPermissionSet permissions = info->GetAll(); 775 for (APIPermissionSet::const_iterator i = permissions.begin(); 776 i != permissions.end(); ++i) { 777 const APIPermissionInfo* permission_info = i->info(); 778 EXPECT_TRUE(permission_info != NULL); 779 780 if (skip.count(i->id())) { 781 EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id()) 782 << "unexpected message_id for " << permission_info->name(); 783 } else { 784 EXPECT_NE(PermissionMessage::kNone, permission_info->message_id()) 785 << "missing message_id for " << permission_info->name(); 786 } 787 } 788} 789 790TEST(PermissionsTest, FileSystemPermissionMessages) { 791 APIPermissionSet api_permissions; 792 api_permissions.insert(APIPermission::kFileSystemWrite); 793 api_permissions.insert(APIPermission::kFileSystemDirectory); 794 scoped_refptr<PermissionSet> permissions( 795 new PermissionSet(api_permissions, ManifestPermissionSet(), 796 URLPatternSet(), URLPatternSet())); 797 PermissionMessages messages = 798 PermissionMessageProvider::Get()->GetPermissionMessages( 799 permissions, Manifest::TYPE_PLATFORM_APP); 800 ASSERT_EQ(1u, messages.size()); 801 std::sort(messages.begin(), messages.end()); 802 std::set<PermissionMessage::ID> ids; 803 for (PermissionMessages::const_iterator it = messages.begin(); 804 it != messages.end(); ++it) { 805 ids.insert(it->id()); 806 } 807 EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemDirectory)); 808} 809 810TEST(PermissionsTest, HiddenFileSystemPermissionMessages) { 811 APIPermissionSet api_permissions; 812 api_permissions.insert(APIPermission::kFileSystemWrite); 813 api_permissions.insert(APIPermission::kFileSystemDirectory); 814 api_permissions.insert(APIPermission::kFileSystemWriteDirectory); 815 scoped_refptr<PermissionSet> permissions( 816 new PermissionSet(api_permissions, ManifestPermissionSet(), 817 URLPatternSet(), URLPatternSet())); 818 PermissionMessages messages = 819 PermissionMessageProvider::Get()->GetPermissionMessages( 820 permissions, Manifest::TYPE_PLATFORM_APP); 821 ASSERT_EQ(1u, messages.size()); 822 EXPECT_EQ(PermissionMessage::kFileSystemWriteDirectory, messages[0].id()); 823} 824 825TEST(PermissionsTest, SuppressedPermissionMessages) { 826 { 827 APIPermissionSet api_permissions; 828 api_permissions.insert(APIPermission::kTab); 829 URLPatternSet hosts; 830 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, 831 "chrome://favicon/")); 832 scoped_refptr<PermissionSet> permissions( 833 new PermissionSet(api_permissions, ManifestPermissionSet(), 834 hosts, URLPatternSet())); 835 PermissionMessages messages = 836 PermissionMessageProvider::Get()->GetPermissionMessages( 837 permissions, Manifest::TYPE_EXTENSION); 838 EXPECT_EQ(1u, messages.size()); 839 EXPECT_EQ(PermissionMessage::kTabs, messages[0].id()); 840 } 841 { 842 APIPermissionSet api_permissions; 843 api_permissions.insert(APIPermission::kHistory); 844 URLPatternSet hosts; 845 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, 846 "chrome://favicon/")); 847 scoped_refptr<PermissionSet> permissions( 848 new PermissionSet(api_permissions, ManifestPermissionSet(), 849 hosts, URLPatternSet())); 850 PermissionMessages messages = 851 PermissionMessageProvider::Get()->GetPermissionMessages( 852 permissions, Manifest::TYPE_EXTENSION); 853 EXPECT_EQ(1u, messages.size()); 854 EXPECT_EQ(PermissionMessage::kBrowsingHistory, messages[0].id()); 855 } 856 { 857 APIPermissionSet api_permissions; 858 URLPatternSet hosts; 859 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, "*://*/*")); 860 api_permissions.insert(APIPermission::kTab); 861 scoped_refptr<PermissionSet> permissions(new PermissionSet( 862 api_permissions, ManifestPermissionSet(), hosts, URLPatternSet())); 863 PermissionMessages messages = 864 PermissionMessageProvider::Get()->GetPermissionMessages( 865 permissions, Manifest::TYPE_EXTENSION); 866 EXPECT_EQ(1u, messages.size()); 867 EXPECT_EQ(PermissionMessage::kHostsAll, messages[0].id()); 868 } 869 { 870 APIPermissionSet api_permissions; 871 URLPatternSet hosts; 872 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, "*://*/*")); 873 api_permissions.insert(APIPermission::kDeclarativeWebRequest); 874 scoped_refptr<PermissionSet> permissions(new PermissionSet( 875 api_permissions, ManifestPermissionSet(), hosts, URLPatternSet())); 876 PermissionMessages messages = 877 PermissionMessageProvider::Get()->GetPermissionMessages( 878 permissions, Manifest::TYPE_EXTENSION); 879 EXPECT_EQ(1u, messages.size()); 880 EXPECT_EQ(PermissionMessage::kHostsAll, messages[0].id()); 881 } 882 { 883 APIPermissionSet api_permissions; 884 api_permissions.insert(APIPermission::kHistory); 885 api_permissions.insert(APIPermission::kTab); 886 api_permissions.insert(APIPermission::kTopSites); 887 api_permissions.insert(APIPermission::kProcesses); 888 api_permissions.insert(APIPermission::kWebNavigation); 889 scoped_refptr<PermissionSet> permissions( 890 new PermissionSet(api_permissions, ManifestPermissionSet(), 891 URLPatternSet(), URLPatternSet())); 892 PermissionMessages messages = 893 PermissionMessageProvider::Get()->GetPermissionMessages( 894 permissions, Manifest::TYPE_EXTENSION); 895 EXPECT_EQ(1u, messages.size()); 896 EXPECT_EQ(PermissionMessage::kBrowsingHistory, messages[0].id()); 897 } 898 { 899 APIPermissionSet api_permissions; 900 api_permissions.insert(APIPermission::kTab); 901 api_permissions.insert(APIPermission::kTopSites); 902 api_permissions.insert(APIPermission::kProcesses); 903 api_permissions.insert(APIPermission::kWebNavigation); 904 scoped_refptr<PermissionSet> permissions( 905 new PermissionSet(api_permissions, ManifestPermissionSet(), 906 URLPatternSet(), URLPatternSet())); 907 PermissionMessages messages = 908 PermissionMessageProvider::Get()->GetPermissionMessages( 909 permissions, Manifest::TYPE_EXTENSION); 910 EXPECT_EQ(1u, messages.size()); 911 EXPECT_EQ(PermissionMessage::kTabs, messages[0].id()); 912 } 913} 914 915TEST(PermissionsTest, AccessToDevicesMessages) { 916 { 917 APIPermissionSet api_permissions; 918 api_permissions.insert(APIPermission::kUsb); 919 scoped_refptr<PermissionSet> permissions( 920 new PermissionSet(api_permissions, 921 ManifestPermissionSet(), 922 URLPatternSet(), 923 URLPatternSet())); 924 std::vector<base::string16> messages = 925 PermissionMessageProvider::Get()->GetWarningMessages( 926 permissions, Manifest::TYPE_EXTENSION); 927 EXPECT_EQ(1u, messages.size()); 928 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB), 929 messages[0]); 930 } 931 { 932 // Testing that multiple permissions will show the one message. 933 APIPermissionSet api_permissions; 934 api_permissions.insert(APIPermission::kUsb); 935 api_permissions.insert(APIPermission::kUsb); 936 scoped_refptr<PermissionSet> permissions( 937 new PermissionSet(api_permissions, 938 ManifestPermissionSet(), 939 URLPatternSet(), 940 URLPatternSet())); 941 std::vector<base::string16> messages = 942 PermissionMessageProvider::Get()->GetWarningMessages( 943 permissions, Manifest::TYPE_EXTENSION); 944 EXPECT_EQ(1u, messages.size()); 945 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB), 946 messages[0]); 947 } 948 { 949 APIPermissionSet api_permissions; 950 api_permissions.insert(APIPermission::kSerial); 951 scoped_refptr<PermissionSet> permissions( 952 new PermissionSet(api_permissions, 953 ManifestPermissionSet(), 954 URLPatternSet(), 955 URLPatternSet())); 956 std::vector<base::string16> messages = 957 PermissionMessageProvider::Get()->GetWarningMessages( 958 permissions, Manifest::TYPE_EXTENSION); 959 EXPECT_EQ(1u, messages.size()); 960 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_SERIAL), 961 messages[0]); 962 } 963 { 964 APIPermissionSet api_permissions; 965 api_permissions.insert(APIPermission::kUsb); 966 api_permissions.insert(APIPermission::kSerial); 967 scoped_refptr<PermissionSet> permissions( 968 new PermissionSet(api_permissions, 969 ManifestPermissionSet(), 970 URLPatternSet(), 971 URLPatternSet())); 972 std::vector<base::string16> messages = 973 PermissionMessageProvider::Get()->GetWarningMessages( 974 permissions, Manifest::TYPE_EXTENSION); 975 EXPECT_EQ(1u, messages.size()); 976 EXPECT_EQ( 977 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_SERIAL), 978 messages[0]); 979 } 980 { 981 // Testing that the same permission(s) will show one message. 982 APIPermissionSet api_permissions; 983 api_permissions.insert(APIPermission::kUsb); 984 api_permissions.insert(APIPermission::kSerial); 985 api_permissions.insert(APIPermission::kUsb); 986 scoped_refptr<PermissionSet> permissions( 987 new PermissionSet(api_permissions, 988 ManifestPermissionSet(), 989 URLPatternSet(), 990 URLPatternSet())); 991 std::vector<base::string16> messages = 992 PermissionMessageProvider::Get()->GetWarningMessages( 993 permissions, Manifest::TYPE_EXTENSION); 994 EXPECT_EQ(1u, messages.size()); 995 EXPECT_EQ( 996 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_SERIAL), 997 messages[0]); 998 } 999 { 1000 scoped_refptr<Extension> extension = 1001 LoadManifest("permissions", "access_to_devices_bluetooth.json"); 1002 const PermissionMessageProvider* provider = 1003 PermissionMessageProvider::Get(); 1004 PermissionSet* set = const_cast<PermissionSet*>( 1005 extension->permissions_data()->active_permissions().get()); 1006 std::vector<base::string16> warnings = 1007 provider->GetWarningMessages(set, extension->GetType()); 1008 EXPECT_EQ(1u, warnings.size()); 1009 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH), 1010 warnings[0]); 1011 1012 // Test Bluetooth and Serial 1013 set->apis_.insert(APIPermission::kSerial); 1014 warnings = provider->GetWarningMessages(set, extension->GetType()); 1015 EXPECT_EQ(1u, warnings.size()); 1016 EXPECT_EQ(l10n_util::GetStringUTF16( 1017 IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_SERIAL), 1018 warnings[0]); 1019 set->apis_.erase(APIPermission::kSerial); 1020 1021 // Test USB and Bluetooth 1022 set->apis_.insert(APIPermission::kUsb); 1023 warnings = provider->GetWarningMessages(set, extension->GetType()); 1024 EXPECT_EQ(1u, warnings.size()); 1025 EXPECT_EQ( 1026 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_BLUETOOTH), 1027 warnings[0]); 1028 1029 // Test USB, Bluetooth and Serial 1030 set->apis_.insert(APIPermission::kSerial); 1031 warnings = provider->GetWarningMessages(set, extension->GetType()); 1032 EXPECT_EQ(1u, warnings.size()); 1033 EXPECT_EQ( 1034 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_DEVICES), 1035 warnings[0]); 1036 } 1037} 1038 1039TEST(PermissionsTest, MergedFileSystemPermissionComparison) { 1040 APIPermissionSet write_api_permissions; 1041 write_api_permissions.insert(APIPermission::kFileSystemWrite); 1042 scoped_refptr<PermissionSet> write_permissions( 1043 new PermissionSet(write_api_permissions, ManifestPermissionSet(), 1044 URLPatternSet(), URLPatternSet())); 1045 1046 APIPermissionSet directory_api_permissions; 1047 directory_api_permissions.insert(APIPermission::kFileSystemDirectory); 1048 scoped_refptr<PermissionSet> directory_permissions( 1049 new PermissionSet(directory_api_permissions, ManifestPermissionSet(), 1050 URLPatternSet(), URLPatternSet())); 1051 1052 APIPermissionSet write_directory_api_permissions; 1053 write_directory_api_permissions.insert( 1054 APIPermission::kFileSystemWriteDirectory); 1055 scoped_refptr<PermissionSet> write_directory_permissions( 1056 new PermissionSet(write_directory_api_permissions, 1057 ManifestPermissionSet(), 1058 URLPatternSet(), 1059 URLPatternSet())); 1060 1061 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1062 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions, 1063 write_permissions, 1064 Manifest::TYPE_PLATFORM_APP)); 1065 EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions, 1066 directory_permissions, 1067 Manifest::TYPE_PLATFORM_APP)); 1068 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions, 1069 directory_permissions, 1070 Manifest::TYPE_PLATFORM_APP)); 1071 EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions, 1072 write_directory_permissions, 1073 Manifest::TYPE_PLATFORM_APP)); 1074 EXPECT_FALSE(provider->IsPrivilegeIncrease(directory_permissions, 1075 write_permissions, 1076 Manifest::TYPE_PLATFORM_APP)); 1077 EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions, 1078 write_directory_permissions, 1079 Manifest::TYPE_PLATFORM_APP)); 1080} 1081 1082TEST(PermissionsTest, GetWarningMessages_ManyHosts) { 1083 scoped_refptr<Extension> extension; 1084 1085 extension = LoadManifest("permissions", "many-hosts.json"); 1086 std::vector<base::string16> warnings = 1087 extension->permissions_data()->GetPermissionMessageStrings(); 1088 ASSERT_EQ(1u, warnings.size()); 1089 EXPECT_EQ( 1090 "Read and change your data on encrypted.google.com and " 1091 "www.google.com", 1092 base::UTF16ToUTF8(warnings[0])); 1093} 1094 1095TEST(PermissionsTest, GetWarningMessages_Plugins) { 1096 scoped_refptr<Extension> extension; 1097 scoped_refptr<PermissionSet> permissions; 1098 1099 extension = LoadManifest("permissions", "plugins.json"); 1100 std::vector<base::string16> warnings = 1101 extension->permissions_data()->GetPermissionMessageStrings(); 1102// We don't parse the plugins key on Chrome OS, so it should not ask for any 1103 // permissions. 1104#if defined(OS_CHROMEOS) 1105 ASSERT_EQ(0u, warnings.size()); 1106#else 1107 ASSERT_EQ(1u, warnings.size()); 1108 EXPECT_EQ( 1109 "Read and change all your data on your computer and the websites " 1110 "you visit", 1111 base::UTF16ToUTF8(warnings[0])); 1112#endif 1113} 1114 1115TEST(PermissionsTest, GetWarningMessages_AudioVideo) { 1116 // Both audio and video present. 1117 scoped_refptr<Extension> extension = 1118 LoadManifest("permissions", "audio-video.json"); 1119 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1120 PermissionSet* set = const_cast<PermissionSet*>( 1121 extension->permissions_data()->active_permissions().get()); 1122 std::vector<base::string16> warnings = 1123 provider->GetWarningMessages(set, extension->GetType()); 1124 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 1125 EXPECT_FALSE(Contains(warnings, "Use your camera")); 1126 EXPECT_TRUE(Contains(warnings, "Use your microphone and camera")); 1127 size_t combined_index = IndexOf(warnings, "Use your microphone and camera"); 1128 size_t combined_size = warnings.size(); 1129 1130 // Just audio present. 1131 set->apis_.erase(APIPermission::kVideoCapture); 1132 warnings = provider->GetWarningMessages(set, extension->GetType()); 1133 EXPECT_EQ(combined_size, warnings.size()); 1134 EXPECT_EQ(combined_index, IndexOf(warnings, "Use your microphone")); 1135 EXPECT_FALSE(Contains(warnings, "Use your camera")); 1136 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 1137 1138 // Just video present. 1139 set->apis_.erase(APIPermission::kAudioCapture); 1140 set->apis_.insert(APIPermission::kVideoCapture); 1141 warnings = provider->GetWarningMessages(set, extension->GetType()); 1142 EXPECT_EQ(combined_size, warnings.size()); 1143 EXPECT_FALSE(Contains(warnings, "Use your microphone")); 1144 EXPECT_FALSE(Contains(warnings, "Use your microphone and camera")); 1145 EXPECT_TRUE(Contains(warnings, "Use your camera")); 1146} 1147 1148TEST(PermissionsTest, GetWarningMessages_CombinedSessions) { 1149 { 1150 APIPermissionSet api_permissions; 1151 api_permissions.insert(APIPermission::kTab); 1152 api_permissions.insert(APIPermission::kTopSites); 1153 api_permissions.insert(APIPermission::kProcesses); 1154 api_permissions.insert(APIPermission::kWebNavigation); 1155 api_permissions.insert(APIPermission::kSessions); 1156 scoped_refptr<PermissionSet> permissions( 1157 new PermissionSet(api_permissions, ManifestPermissionSet(), 1158 URLPatternSet(), URLPatternSet())); 1159 std::vector<base::string16> messages = 1160 PermissionMessageProvider::Get()->GetWarningMessages( 1161 permissions, Manifest::TYPE_EXTENSION); 1162 EXPECT_EQ(1u, messages.size()); 1163 EXPECT_EQ(l10n_util::GetStringUTF16( 1164 IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ_AND_SESSIONS), 1165 messages[0]); 1166 } 1167 { 1168 APIPermissionSet api_permissions; 1169 api_permissions.insert(APIPermission::kHistory); 1170 api_permissions.insert(APIPermission::kTab); 1171 api_permissions.insert(APIPermission::kTopSites); 1172 api_permissions.insert(APIPermission::kProcesses); 1173 api_permissions.insert(APIPermission::kWebNavigation); 1174 api_permissions.insert(APIPermission::kSessions); 1175 scoped_refptr<PermissionSet> permissions( 1176 new PermissionSet(api_permissions, ManifestPermissionSet(), 1177 URLPatternSet(), URLPatternSet())); 1178 std::vector<base::string16> messages = 1179 PermissionMessageProvider::Get()->GetWarningMessages( 1180 permissions, Manifest::TYPE_EXTENSION); 1181 EXPECT_EQ(1u, messages.size()); 1182 EXPECT_EQ(l10n_util::GetStringUTF16( 1183 IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_AND_SESSIONS), 1184 messages[0]); 1185 } 1186} 1187 1188TEST(PermissionsTest, GetWarningMessages_DeclarativeWebRequest) { 1189 // Test that if the declarativeWebRequest permission is present 1190 // in combination with all hosts permission, then only the warning 1191 // for host permissions is shown, because that covers the use of 1192 // declarativeWebRequest. 1193 1194 // Until Declarative Web Request is in stable, let's make sure it is enabled 1195 // on the current channel. 1196 ScopedCurrentChannel sc(chrome::VersionInfo::CHANNEL_CANARY); 1197 1198 // First verify that declarativeWebRequest produces a message when host 1199 // permissions do not cover all hosts. 1200 scoped_refptr<Extension> extension = 1201 LoadManifest("permissions", "web_request_not_all_host_permissions.json"); 1202 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1203 const PermissionSet* set = 1204 extension->permissions_data()->active_permissions().get(); 1205 std::vector<base::string16> warnings = 1206 provider->GetWarningMessages(set, extension->GetType()); 1207 EXPECT_TRUE(Contains(warnings, "Block parts of web pages")); 1208 EXPECT_FALSE(Contains( 1209 warnings, "Read and change all your data on the websites you visit")); 1210 1211 // Now verify that declarativeWebRequest does not produce a message when host 1212 // permissions do cover all hosts. 1213 extension = 1214 LoadManifest("permissions", "web_request_all_host_permissions.json"); 1215 set = extension->permissions_data()->active_permissions().get(); 1216 warnings = provider->GetWarningMessages(set, extension->GetType()); 1217 EXPECT_FALSE(Contains(warnings, "Block parts of web pages")); 1218 EXPECT_TRUE(Contains( 1219 warnings, "Read and change all your data on the websites you visit")); 1220} 1221 1222TEST(PermissionsTest, GetWarningMessages_Serial) { 1223 scoped_refptr<Extension> extension = 1224 LoadManifest("permissions", "serial.json"); 1225 1226 EXPECT_TRUE(extension->is_platform_app()); 1227 EXPECT_TRUE( 1228 extension->permissions_data()->HasAPIPermission(APIPermission::kSerial)); 1229 std::vector<base::string16> warnings = 1230 extension->permissions_data()->GetPermissionMessageStrings(); 1231 EXPECT_TRUE(Contains(warnings, "Access your serial devices")); 1232 ASSERT_EQ(1u, warnings.size()); 1233} 1234 1235TEST(PermissionsTest, GetWarningMessages_Socket_AnyHost) { 1236 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 1237 1238 scoped_refptr<Extension> extension = 1239 LoadManifest("permissions", "socket_any_host.json"); 1240 EXPECT_TRUE(extension->is_platform_app()); 1241 EXPECT_TRUE( 1242 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket)); 1243 std::vector<base::string16> warnings = 1244 extension->permissions_data()->GetPermissionMessageStrings(); 1245 EXPECT_EQ(1u, warnings.size()); 1246 EXPECT_TRUE(Contains(warnings, "Exchange data with any computer " 1247 "on the local network or internet")); 1248} 1249 1250TEST(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) { 1251 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 1252 1253 scoped_refptr<Extension> extension = 1254 LoadManifest("permissions", "socket_one_domain_two_hostnames.json"); 1255 EXPECT_TRUE(extension->is_platform_app()); 1256 EXPECT_TRUE( 1257 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket)); 1258 std::vector<base::string16> warnings = 1259 extension->permissions_data()->GetPermissionMessageStrings(); 1260 1261 // Verify the warnings, including support for unicode characters, the fact 1262 // that domain host warnings come before specific host warnings, and the fact 1263 // that domains and hostnames are in alphabetical order regardless of the 1264 // order in the manifest file. 1265 EXPECT_EQ(2u, warnings.size()); 1266 if (warnings.size() > 0) 1267 EXPECT_EQ(warnings[0], 1268 base::UTF8ToUTF16("Exchange data with any computer in the domain " 1269 "example.org")); 1270 if (warnings.size() > 1) 1271 EXPECT_EQ(warnings[1], 1272 base::UTF8ToUTF16("Exchange data with the computers named: " 1273 "b\xC3\xA5r.example.com foo.example.com")); 1274 // "\xC3\xA5" = UTF-8 for lowercase A with ring above 1275} 1276 1277TEST(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) { 1278 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV); 1279 1280 scoped_refptr<Extension> extension = 1281 LoadManifest("permissions", "socket_two_domains_one_hostname.json"); 1282 EXPECT_TRUE(extension->is_platform_app()); 1283 EXPECT_TRUE( 1284 extension->permissions_data()->HasAPIPermission(APIPermission::kSocket)); 1285 std::vector<base::string16> warnings = 1286 extension->permissions_data()->GetPermissionMessageStrings(); 1287 1288 // Verify the warnings, including the fact that domain host warnings come 1289 // before specific host warnings and the fact that domains and hostnames are 1290 // in alphabetical order regardless of the order in the manifest file. 1291 EXPECT_EQ(2u, warnings.size()); 1292 if (warnings.size() > 0) 1293 EXPECT_EQ(warnings[0], 1294 base::UTF8ToUTF16("Exchange data with any computer in the " 1295 "domains: example.com foo.example.org")); 1296 if (warnings.size() > 1) 1297 EXPECT_EQ(warnings[1], 1298 base::UTF8ToUTF16("Exchange data with the computer named " 1299 "bar.example.org")); 1300} 1301 1302TEST(PermissionsTest, GetWarningMessages_PlatformApppHosts) { 1303 scoped_refptr<Extension> extension; 1304 1305 extension = LoadManifest("permissions", "platform_app_hosts.json"); 1306 EXPECT_TRUE(extension->is_platform_app()); 1307 std::vector<base::string16> warnings = 1308 extension->permissions_data()->GetPermissionMessageStrings(); 1309 ASSERT_EQ(0u, warnings.size()); 1310 1311 extension = LoadManifest("permissions", "platform_app_all_urls.json"); 1312 EXPECT_TRUE(extension->is_platform_app()); 1313 warnings = extension->permissions_data()->GetPermissionMessageStrings(); 1314 ASSERT_EQ(0u, warnings.size()); 1315} 1316 1317bool ShowsAllHostsWarning(const std::string& pattern) { 1318 scoped_refptr<Extension> extension = 1319 ExtensionBuilder() 1320 .SetManifest(DictionaryBuilder() 1321 .Set("name", "TLDWildCardTest") 1322 .Set("version", "0.1.0") 1323 .Set("permissions", ListBuilder().Append(pattern)) 1324 .Build()) 1325 .Build(); 1326 1327 std::vector<base::string16> warnings = 1328 extension->permissions_data()->GetPermissionMessageStrings(); 1329 1330 if (warnings.empty()) 1331 return false; 1332 1333 if (warnings[0] != 1334 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)) { 1335 return false; 1336 } 1337 1338 return true; 1339} 1340 1341TEST(PermissionsTest, GetWarningMessages_TLDWildcardTreatedAsAllHosts) { 1342 EXPECT_TRUE(ShowsAllHostsWarning("http://*.com/*")); // most popular. 1343 EXPECT_TRUE(ShowsAllHostsWarning("http://*.org/*")); // sanity check. 1344 EXPECT_TRUE(ShowsAllHostsWarning("http://*.co.uk/*")); // eTLD. 1345 EXPECT_TRUE(ShowsAllHostsWarning("http://*.de/*")); // foreign country tld. 1346 1347 // We should still show the normal permissions (i.e., "Can access your data on 1348 // *.rdcronin.com") for things that are not TLDs. 1349 EXPECT_FALSE(ShowsAllHostsWarning("http://*.rdcronin.com/*")); 1350 1351 // Pseudo-TLDs, like appspot.com, should not show all hosts. 1352 EXPECT_FALSE(ShowsAllHostsWarning("http://*.appspot.com/*")); 1353 1354 // Non-TLDs should be likewise exempt. 1355 EXPECT_FALSE(ShowsAllHostsWarning("http://*.notarealtld/*")); 1356 1357 // Our internal checks use "foo", so let's make sure we're not messing 1358 // something up with it. 1359 EXPECT_FALSE(ShowsAllHostsWarning("http://*.foo.com")); 1360 EXPECT_FALSE(ShowsAllHostsWarning("http://foo.com")); 1361 // This will fail if foo becomes a recognized TLD. Which could be soon. 1362 // Update as needed. 1363 EXPECT_FALSE(ShowsAllHostsWarning("http://*.foo")); 1364} 1365 1366TEST(PermissionsTest, GetDistinctHosts) { 1367 URLPatternSet explicit_hosts; 1368 std::set<std::string> expected; 1369 expected.insert("www.foo.com"); 1370 expected.insert("www.bar.com"); 1371 expected.insert("www.baz.com"); 1372 1373 { 1374 SCOPED_TRACE("no dupes"); 1375 1376 // Simple list with no dupes. 1377 explicit_hosts.AddPattern( 1378 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1379 explicit_hosts.AddPattern( 1380 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path")); 1381 explicit_hosts.AddPattern( 1382 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 1383 EXPECT_EQ(expected, 1384 permission_message_util::GetDistinctHosts( 1385 explicit_hosts, true, true)); 1386 } 1387 1388 { 1389 SCOPED_TRACE("two dupes"); 1390 1391 // Add some dupes. 1392 explicit_hosts.AddPattern( 1393 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1394 explicit_hosts.AddPattern( 1395 URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path")); 1396 EXPECT_EQ(expected, 1397 permission_message_util::GetDistinctHosts( 1398 explicit_hosts, true, true)); 1399 } 1400 1401 { 1402 SCOPED_TRACE("schemes differ"); 1403 1404 // Add a pattern that differs only by scheme. This should be filtered out. 1405 explicit_hosts.AddPattern( 1406 URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path")); 1407 EXPECT_EQ(expected, 1408 permission_message_util::GetDistinctHosts( 1409 explicit_hosts, true, true)); 1410 } 1411 1412 { 1413 SCOPED_TRACE("paths differ"); 1414 1415 // Add some dupes by path. 1416 explicit_hosts.AddPattern( 1417 URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath")); 1418 EXPECT_EQ(expected, 1419 permission_message_util::GetDistinctHosts( 1420 explicit_hosts, true, true)); 1421 } 1422 1423 { 1424 SCOPED_TRACE("subdomains differ"); 1425 1426 // We don't do anything special for subdomains. 1427 explicit_hosts.AddPattern( 1428 URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path")); 1429 explicit_hosts.AddPattern( 1430 URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path")); 1431 1432 expected.insert("monkey.www.bar.com"); 1433 expected.insert("bar.com"); 1434 1435 EXPECT_EQ(expected, 1436 permission_message_util::GetDistinctHosts( 1437 explicit_hosts, true, true)); 1438 } 1439 1440 { 1441 SCOPED_TRACE("RCDs differ"); 1442 1443 // Now test for RCD uniquing. 1444 explicit_hosts.AddPattern( 1445 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1446 explicit_hosts.AddPattern( 1447 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1448 explicit_hosts.AddPattern( 1449 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path")); 1450 explicit_hosts.AddPattern( 1451 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path")); 1452 explicit_hosts.AddPattern( 1453 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1454 explicit_hosts.AddPattern( 1455 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path")); 1456 1457 // This is an unknown RCD, which shouldn't be uniqued out. 1458 explicit_hosts.AddPattern( 1459 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1460 // But it should only occur once. 1461 explicit_hosts.AddPattern( 1462 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path")); 1463 1464 expected.insert("www.foo.xyzzy"); 1465 1466 EXPECT_EQ(expected, 1467 permission_message_util::GetDistinctHosts( 1468 explicit_hosts, true, true)); 1469 } 1470 1471 { 1472 SCOPED_TRACE("wildcards"); 1473 1474 explicit_hosts.AddPattern( 1475 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1476 1477 expected.insert("*.google.com"); 1478 1479 EXPECT_EQ(expected, 1480 permission_message_util::GetDistinctHosts( 1481 explicit_hosts, true, true)); 1482 } 1483 1484 { 1485 SCOPED_TRACE("scriptable hosts"); 1486 1487 APIPermissionSet empty_perms; 1488 explicit_hosts.ClearPatterns(); 1489 URLPatternSet scriptable_hosts; 1490 expected.clear(); 1491 1492 explicit_hosts.AddPattern( 1493 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*")); 1494 scriptable_hosts.AddPattern( 1495 URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*")); 1496 1497 expected.insert("*.google.com"); 1498 expected.insert("*.example.com"); 1499 1500 scoped_refptr<PermissionSet> perm_set(new PermissionSet( 1501 empty_perms, ManifestPermissionSet(), 1502 explicit_hosts, scriptable_hosts)); 1503 EXPECT_EQ(expected, 1504 permission_message_util::GetDistinctHosts( 1505 perm_set->effective_hosts(), true, true)); 1506 } 1507 1508 { 1509 // We don't display warnings for file URLs because they are off by default. 1510 SCOPED_TRACE("file urls"); 1511 1512 explicit_hosts.ClearPatterns(); 1513 expected.clear(); 1514 1515 explicit_hosts.AddPattern( 1516 URLPattern(URLPattern::SCHEME_FILE, "file:///*")); 1517 1518 EXPECT_EQ(expected, 1519 permission_message_util::GetDistinctHosts( 1520 explicit_hosts, true, true)); 1521 } 1522} 1523 1524TEST(PermissionsTest, GetDistinctHosts_ComIsBestRcd) { 1525 URLPatternSet explicit_hosts; 1526 explicit_hosts.AddPattern( 1527 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1528 explicit_hosts.AddPattern( 1529 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1530 explicit_hosts.AddPattern( 1531 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1532 explicit_hosts.AddPattern( 1533 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1534 explicit_hosts.AddPattern( 1535 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1536 explicit_hosts.AddPattern( 1537 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path")); 1538 1539 std::set<std::string> expected; 1540 expected.insert("www.foo.com"); 1541 EXPECT_EQ(expected, 1542 permission_message_util::GetDistinctHosts( 1543 explicit_hosts, true, true)); 1544} 1545 1546TEST(PermissionsTest, GetDistinctHosts_NetIs2ndBestRcd) { 1547 URLPatternSet explicit_hosts; 1548 explicit_hosts.AddPattern( 1549 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1550 explicit_hosts.AddPattern( 1551 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1552 explicit_hosts.AddPattern( 1553 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1554 explicit_hosts.AddPattern( 1555 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path")); 1556 explicit_hosts.AddPattern( 1557 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1558 // No http://www.foo.com/path 1559 1560 std::set<std::string> expected; 1561 expected.insert("www.foo.net"); 1562 EXPECT_EQ(expected, 1563 permission_message_util::GetDistinctHosts( 1564 explicit_hosts, true, true)); 1565} 1566 1567TEST(PermissionsTest, GetDistinctHosts_OrgIs3rdBestRcd) { 1568 URLPatternSet explicit_hosts; 1569 explicit_hosts.AddPattern( 1570 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1571 explicit_hosts.AddPattern( 1572 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path")); 1573 explicit_hosts.AddPattern( 1574 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1575 // No http://www.foo.net/path 1576 explicit_hosts.AddPattern( 1577 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1578 // No http://www.foo.com/path 1579 1580 std::set<std::string> expected; 1581 expected.insert("www.foo.org"); 1582 EXPECT_EQ(expected, 1583 permission_message_util::GetDistinctHosts( 1584 explicit_hosts, true, true)); 1585} 1586 1587TEST(PermissionsTest, GetDistinctHosts_FirstInListIs4thBestRcd) { 1588 URLPatternSet explicit_hosts; 1589 explicit_hosts.AddPattern( 1590 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path")); 1591 // No http://www.foo.org/path 1592 explicit_hosts.AddPattern( 1593 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path")); 1594 // No http://www.foo.net/path 1595 explicit_hosts.AddPattern( 1596 URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path")); 1597 // No http://www.foo.com/path 1598 1599 std::set<std::string> expected; 1600 expected.insert("www.foo.ca"); 1601 EXPECT_EQ(expected, 1602 permission_message_util::GetDistinctHosts( 1603 explicit_hosts, true, true)); 1604} 1605 1606TEST(PermissionsTest, IsHostPrivilegeIncrease) { 1607 Manifest::Type type = Manifest::TYPE_EXTENSION; 1608 const PermissionMessageProvider* provider = PermissionMessageProvider::Get(); 1609 ManifestPermissionSet empty_manifest_permissions; 1610 URLPatternSet elist1; 1611 URLPatternSet elist2; 1612 URLPatternSet slist1; 1613 URLPatternSet slist2; 1614 scoped_refptr<PermissionSet> set1; 1615 scoped_refptr<PermissionSet> set2; 1616 APIPermissionSet empty_perms; 1617 elist1.AddPattern( 1618 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1619 elist1.AddPattern( 1620 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1621 1622 // Test that the host order does not matter. 1623 elist2.AddPattern( 1624 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1625 elist2.AddPattern( 1626 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path")); 1627 1628 set1 = new PermissionSet(empty_perms, empty_manifest_permissions, 1629 elist1, slist1); 1630 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1631 elist2, slist2); 1632 1633 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type)); 1634 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1635 1636 // Test that paths are ignored. 1637 elist2.ClearPatterns(); 1638 elist2.AddPattern( 1639 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*")); 1640 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1641 elist2, slist2); 1642 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type)); 1643 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1644 1645 // Test that RCDs are ignored. 1646 elist2.ClearPatterns(); 1647 elist2.AddPattern( 1648 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*")); 1649 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1650 elist2, slist2); 1651 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type)); 1652 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1653 1654 // Test that subdomain wildcards are handled properly. 1655 elist2.ClearPatterns(); 1656 elist2.AddPattern( 1657 URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*")); 1658 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1659 elist2, slist2); 1660 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type)); 1661 // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337 1662 // EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1663 1664 // Test that different domains count as different hosts. 1665 elist2.ClearPatterns(); 1666 elist2.AddPattern( 1667 URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path")); 1668 elist2.AddPattern( 1669 URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path")); 1670 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1671 elist2, slist2); 1672 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type)); 1673 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1674 1675 // Test that different subdomains count as different hosts. 1676 elist2.ClearPatterns(); 1677 elist2.AddPattern( 1678 URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*")); 1679 set2 = new PermissionSet(empty_perms, empty_manifest_permissions, 1680 elist2, slist2); 1681 EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type)); 1682 EXPECT_TRUE(provider->IsPrivilegeIncrease(set2, set1, type)); 1683 1684 // Test that platform apps do not have host permissions increases. 1685 type = Manifest::TYPE_PLATFORM_APP; 1686 EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type)); 1687 EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type)); 1688} 1689 1690TEST(PermissionsTest, GetAPIsAsStrings) { 1691 APIPermissionSet apis; 1692 URLPatternSet empty_set; 1693 1694 apis.insert(APIPermission::kProxy); 1695 apis.insert(APIPermission::kBackground); 1696 apis.insert(APIPermission::kNotifications); 1697 apis.insert(APIPermission::kTab); 1698 1699 scoped_refptr<PermissionSet> perm_set = new PermissionSet( 1700 apis, ManifestPermissionSet(), empty_set, empty_set); 1701 std::set<std::string> api_names = perm_set->GetAPIsAsStrings(); 1702 1703 // The result is correct if it has the same number of elements 1704 // and we can convert it back to the id set. 1705 EXPECT_EQ(4u, api_names.size()); 1706 EXPECT_EQ(apis, 1707 PermissionsInfo::GetInstance()->GetAllByName(api_names)); 1708} 1709 1710TEST(PermissionsTest, IsEmpty) { 1711 APIPermissionSet empty_apis; 1712 URLPatternSet empty_extent; 1713 1714 scoped_refptr<PermissionSet> empty = new PermissionSet(); 1715 EXPECT_TRUE(empty->IsEmpty()); 1716 scoped_refptr<PermissionSet> perm_set; 1717 1718 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1719 empty_extent, empty_extent); 1720 EXPECT_TRUE(perm_set->IsEmpty()); 1721 1722 APIPermissionSet non_empty_apis; 1723 non_empty_apis.insert(APIPermission::kBackground); 1724 perm_set = new PermissionSet(non_empty_apis, ManifestPermissionSet(), 1725 empty_extent, empty_extent); 1726 EXPECT_FALSE(perm_set->IsEmpty()); 1727 1728 // Try non standard host 1729 URLPatternSet non_empty_extent; 1730 AddPattern(&non_empty_extent, "http://www.google.com/*"); 1731 1732 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1733 non_empty_extent, empty_extent); 1734 EXPECT_FALSE(perm_set->IsEmpty()); 1735 1736 perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(), 1737 empty_extent, non_empty_extent); 1738 EXPECT_FALSE(perm_set->IsEmpty()); 1739} 1740 1741TEST(PermissionsTest, ImpliedPermissions) { 1742 URLPatternSet empty_extent; 1743 APIPermissionSet apis; 1744 apis.insert(APIPermission::kFileBrowserHandler); 1745 EXPECT_EQ(1U, apis.size()); 1746 1747 scoped_refptr<PermissionSet> perm_set; 1748 perm_set = new PermissionSet(apis, ManifestPermissionSet(), 1749 empty_extent, empty_extent); 1750 EXPECT_EQ(2U, perm_set->apis().size()); 1751} 1752 1753TEST(PermissionsTest, SyncFileSystemPermission) { 1754 scoped_refptr<Extension> extension = LoadManifest( 1755 "permissions", "sync_file_system.json"); 1756 APIPermissionSet apis; 1757 apis.insert(APIPermission::kSyncFileSystem); 1758 EXPECT_TRUE(extension->is_platform_app()); 1759 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission( 1760 APIPermission::kSyncFileSystem)); 1761 std::vector<base::string16> warnings = 1762 extension->permissions_data()->GetPermissionMessageStrings(); 1763 EXPECT_TRUE(Contains(warnings, "Store data in your Google Drive account")); 1764 ASSERT_EQ(1u, warnings.size()); 1765} 1766 1767// Make sure that we don't crash when we're trying to show the permissions 1768// even though chrome://thumb (and everything that's not chrome://favicon with 1769// a chrome:// scheme) is not a valid permission. 1770// More details here: crbug/246314. 1771TEST(PermissionsTest, ChromeURLs) { 1772 URLPatternSet allowed_hosts; 1773 allowed_hosts.AddPattern( 1774 URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/")); 1775 allowed_hosts.AddPattern( 1776 URLPattern(URLPattern::SCHEME_ALL, "chrome://favicon/")); 1777 allowed_hosts.AddPattern( 1778 URLPattern(URLPattern::SCHEME_ALL, "chrome://thumb/")); 1779 scoped_refptr<PermissionSet> permissions( 1780 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), 1781 allowed_hosts, URLPatternSet())); 1782 PermissionMessageProvider::Get()-> 1783 GetPermissionMessages(permissions, Manifest::TYPE_EXTENSION); 1784} 1785 1786TEST(PermissionsTest, IsPrivilegeIncrease_DeclarativeWebRequest) { 1787 scoped_refptr<Extension> extension( 1788 LoadManifest("permissions", "permissions_all_urls.json")); 1789 scoped_refptr<const PermissionSet> permissions( 1790 extension->permissions_data()->active_permissions()); 1791 1792 scoped_refptr<Extension> extension_dwr( 1793 LoadManifest("permissions", "web_request_all_host_permissions.json")); 1794 scoped_refptr<const PermissionSet> permissions_dwr( 1795 extension_dwr->permissions_data()->active_permissions()); 1796 1797 EXPECT_FALSE(PermissionMessageProvider::Get()-> 1798 IsPrivilegeIncrease(permissions.get(), 1799 permissions_dwr.get(), 1800 extension->GetType())); 1801} 1802 1803} // namespace extensions 1804