extension_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2013 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 "chrome/common/extensions/extension.h" 6 7#include "base/command_line.h" 8#include "base/file_util.h" 9#include "base/files/file_path.h" 10#include "base/format_macros.h" 11#include "base/json/json_file_value_serializer.h" 12#include "base/path_service.h" 13#include "base/stringprintf.h" 14#include "base/strings/string_number_conversions.h" 15#include "base/utf_string_conversions.h" 16#include "chrome/common/chrome_paths.h" 17#include "chrome/common/chrome_switches.h" 18#include "chrome/common/extensions/api/commands/commands_handler.h" 19#include "chrome/common/extensions/api/plugins/plugins_handler.h" 20#include "chrome/common/extensions/background_info.h" 21#include "chrome/common/extensions/command.h" 22#include "chrome/common/extensions/extension_file_util.h" 23#include "chrome/common/extensions/extension_manifest_constants.h" 24#include "chrome/common/extensions/features/feature.h" 25#include "chrome/common/extensions/incognito_handler.h" 26#include "chrome/common/extensions/manifest.h" 27#include "chrome/common/extensions/manifest_handler.h" 28#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" 29#include "chrome/common/extensions/permissions/api_permission.h" 30#include "chrome/common/extensions/permissions/permission_set.h" 31#include "chrome/common/extensions/permissions/socket_permission.h" 32#include "chrome/common/extensions/permissions/usb_device_permission.h" 33#include "chrome/common/url_constants.h" 34#include "extensions/common/error_utils.h" 35#include "extensions/common/extension_resource.h" 36#include "extensions/common/id_util.h" 37#include "googleurl/src/gurl.h" 38#include "net/base/mime_sniffer.h" 39#include "net/dns/mock_host_resolver.h" 40#include "skia/ext/image_operations.h" 41#include "testing/gtest/include/gtest/gtest.h" 42#include "third_party/skia/include/core/SkBitmap.h" 43#include "ui/gfx/codec/png_codec.h" 44 45using content::SocketPermissionRequest; 46 47namespace keys = extension_manifest_keys; 48namespace values = extension_manifest_values; 49namespace errors = extension_manifest_errors; 50 51namespace extensions { 52namespace { 53 54scoped_refptr<Extension> LoadManifestUnchecked( 55 const std::string& dir, 56 const std::string& test_file, 57 Manifest::Location location, 58 int extra_flags, 59 std::string* error) { 60 base::FilePath path; 61 PathService::Get(chrome::DIR_TEST_DATA, &path); 62 path = path.AppendASCII("extensions") 63 .AppendASCII(dir) 64 .AppendASCII(test_file); 65 66 JSONFileValueSerializer serializer(path); 67 scoped_ptr<Value> result(serializer.Deserialize(NULL, error)); 68 if (!result.get()) 69 return NULL; 70 71 scoped_refptr<Extension> extension = Extension::Create( 72 path.DirName(), location, *static_cast<DictionaryValue*>(result.get()), 73 extra_flags, error); 74 return extension; 75} 76 77static scoped_refptr<Extension> LoadManifest(const std::string& dir, 78 const std::string& test_file, 79 Manifest::Location location, 80 int extra_flags) { 81 std::string error; 82 scoped_refptr<Extension> extension = LoadManifestUnchecked(dir, test_file, 83 location, extra_flags, &error); 84 85 EXPECT_TRUE(extension) << test_file << ":" << error; 86 return extension; 87} 88 89static scoped_refptr<Extension> LoadManifest(const std::string& dir, 90 const std::string& test_file, 91 int extra_flags) { 92 return LoadManifest(dir, test_file, Manifest::INVALID_LOCATION, extra_flags); 93} 94 95static scoped_refptr<Extension> LoadManifest(const std::string& dir, 96 const std::string& test_file) { 97 return LoadManifest(dir, test_file, Extension::NO_FLAGS); 98} 99 100static scoped_refptr<Extension> LoadManifestStrict( 101 const std::string& dir, 102 const std::string& test_file) { 103 return LoadManifest(dir, test_file, Extension::NO_FLAGS); 104} 105 106} // namespace 107 108class ExtensionTest : public testing::Test { 109 protected: 110 virtual void SetUp() OVERRIDE { 111 testing::Test::SetUp(); 112 (new BackgroundManifestHandler)->Register(); 113 (new CommandsHandler)->Register(); 114 (new ContentScriptsHandler)->Register(); 115 (new PluginsHandler)->Register(); 116 (new IncognitoHandler)->Register(); 117 } 118 119 virtual void TearDown() OVERRIDE { 120 ManifestHandler::ClearRegistryForTesting(); 121 } 122}; 123 124// We persist location values in the preferences, so this is a sanity test that 125// someone doesn't accidentally change them. 126TEST_F(ExtensionTest, LocationValuesTest) { 127 ASSERT_EQ(0, Manifest::INVALID_LOCATION); 128 ASSERT_EQ(1, Manifest::INTERNAL); 129 ASSERT_EQ(2, Manifest::EXTERNAL_PREF); 130 ASSERT_EQ(3, Manifest::EXTERNAL_REGISTRY); 131 ASSERT_EQ(4, Manifest::UNPACKED); 132 ASSERT_EQ(5, Manifest::COMPONENT); 133 ASSERT_EQ(6, Manifest::EXTERNAL_PREF_DOWNLOAD); 134 ASSERT_EQ(7, Manifest::EXTERNAL_POLICY_DOWNLOAD); 135 ASSERT_EQ(8, Manifest::COMMAND_LINE); 136} 137 138TEST_F(ExtensionTest, LocationPriorityTest) { 139 for (int i = 0; i < Manifest::NUM_LOCATIONS; i++) { 140 Manifest::Location loc = static_cast<Manifest::Location>(i); 141 142 // INVALID is not a valid location. 143 if (loc == Manifest::INVALID_LOCATION) 144 continue; 145 146 // Comparing a location that has no rank will hit a CHECK. Do a 147 // compare with every valid location, to be sure each one is covered. 148 149 // Check that no install source can override a componenet extension. 150 ASSERT_EQ(Manifest::COMPONENT, 151 Manifest::GetHigherPriorityLocation(Manifest::COMPONENT, loc)); 152 ASSERT_EQ(Manifest::COMPONENT, 153 Manifest::GetHigherPriorityLocation(loc, Manifest::COMPONENT)); 154 155 // Check that any source can override a user install. This might change 156 // in the future, in which case this test should be updated. 157 ASSERT_EQ(loc, 158 Manifest::GetHigherPriorityLocation(Manifest::INTERNAL, loc)); 159 ASSERT_EQ(loc, 160 Manifest::GetHigherPriorityLocation(loc, Manifest::INTERNAL)); 161 } 162 163 // Check a few interesting cases that we know can happen: 164 ASSERT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, 165 Manifest::GetHigherPriorityLocation( 166 Manifest::EXTERNAL_POLICY_DOWNLOAD, 167 Manifest::EXTERNAL_PREF)); 168 169 ASSERT_EQ(Manifest::EXTERNAL_PREF, 170 Manifest::GetHigherPriorityLocation( 171 Manifest::INTERNAL, 172 Manifest::EXTERNAL_PREF)); 173} 174 175TEST_F(ExtensionTest, GetResourceURLAndPath) { 176 scoped_refptr<Extension> extension = LoadManifestStrict("empty_manifest", 177 "empty.json"); 178 EXPECT_TRUE(extension.get()); 179 180 EXPECT_EQ(extension->url().spec() + "bar/baz.js", 181 Extension::GetResourceURL(extension->url(), "bar/baz.js").spec()); 182 EXPECT_EQ(extension->url().spec() + "baz.js", 183 Extension::GetResourceURL(extension->url(), 184 "bar/../baz.js").spec()); 185 EXPECT_EQ(extension->url().spec() + "baz.js", 186 Extension::GetResourceURL(extension->url(), "../baz.js").spec()); 187 188 // Test that absolute-looking paths ("/"-prefixed) are pasted correctly. 189 EXPECT_EQ(extension->url().spec() + "test.html", 190 extension->GetResourceURL("/test.html").spec()); 191} 192 193TEST_F(ExtensionTest, GetAbsolutePathNoError) { 194 scoped_refptr<Extension> extension = LoadManifestStrict("absolute_path", 195 "absolute.json"); 196 EXPECT_TRUE(extension.get()); 197 std::string err; 198 std::vector<InstallWarning> warnings; 199 EXPECT_TRUE(extension_file_util::ValidateExtension(extension.get(), 200 &err, &warnings)); 201 EXPECT_EQ(0U, warnings.size()); 202 203 EXPECT_EQ(extension->path().AppendASCII("test.html").value(), 204 extension->GetResource("test.html").GetFilePath().value()); 205 EXPECT_EQ(extension->path().AppendASCII("test.js").value(), 206 extension->GetResource("test.js").GetFilePath().value()); 207} 208 209 210TEST_F(ExtensionTest, IdIsValid) { 211 EXPECT_TRUE(Extension::IdIsValid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); 212 EXPECT_TRUE(Extension::IdIsValid("pppppppppppppppppppppppppppppppp")); 213 EXPECT_TRUE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnop")); 214 EXPECT_TRUE(Extension::IdIsValid("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")); 215 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno")); 216 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnopa")); 217 EXPECT_FALSE(Extension::IdIsValid("0123456789abcdef0123456789abcdef")); 218 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnoq")); 219 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno0")); 220} 221 222 223// This test ensures that the mimetype sniffing code stays in sync with the 224// actual crx files that we test other parts of the system with. 225TEST_F(ExtensionTest, MimeTypeSniffing) { 226 base::FilePath path; 227 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); 228 path = path.AppendASCII("extensions").AppendASCII("good.crx"); 229 230 std::string data; 231 ASSERT_TRUE(file_util::ReadFileToString(path, &data)); 232 233 std::string result; 234 EXPECT_TRUE(net::SniffMimeType(data.c_str(), data.size(), 235 GURL("http://www.example.com/foo.crx"), "", &result)); 236 EXPECT_EQ(std::string(Extension::kMimeType), result); 237 238 data.clear(); 239 result.clear(); 240 path = path.DirName().AppendASCII("bad_magic.crx"); 241 ASSERT_TRUE(file_util::ReadFileToString(path, &data)); 242 EXPECT_TRUE(net::SniffMimeType(data.c_str(), data.size(), 243 GURL("http://www.example.com/foo.crx"), "", &result)); 244 EXPECT_EQ("application/octet-stream", result); 245} 246 247TEST_F(ExtensionTest, EffectiveHostPermissions) { 248 scoped_refptr<Extension> extension; 249 URLPatternSet hosts; 250 251 extension = LoadManifest("effective_host_permissions", "empty.json"); 252 EXPECT_EQ(0u, extension->GetEffectiveHostPermissions().patterns().size()); 253 EXPECT_FALSE(hosts.MatchesURL(GURL("http://www.google.com"))); 254 EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts()); 255 256 extension = LoadManifest("effective_host_permissions", "one_host.json"); 257 hosts = extension->GetEffectiveHostPermissions(); 258 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 259 EXPECT_FALSE(hosts.MatchesURL(GURL("https://www.google.com"))); 260 EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts()); 261 262 extension = LoadManifest("effective_host_permissions", 263 "one_host_wildcard.json"); 264 hosts = extension->GetEffectiveHostPermissions(); 265 EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com"))); 266 EXPECT_TRUE(hosts.MatchesURL(GURL("http://foo.google.com"))); 267 EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts()); 268 269 extension = LoadManifest("effective_host_permissions", "two_hosts.json"); 270 hosts = extension->GetEffectiveHostPermissions(); 271 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 272 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com"))); 273 EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts()); 274 275 extension = LoadManifest("effective_host_permissions", 276 "https_not_considered.json"); 277 hosts = extension->GetEffectiveHostPermissions(); 278 EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com"))); 279 EXPECT_TRUE(hosts.MatchesURL(GURL("https://google.com"))); 280 EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts()); 281 282 extension = LoadManifest("effective_host_permissions", 283 "two_content_scripts.json"); 284 hosts = extension->GetEffectiveHostPermissions(); 285 EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com"))); 286 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com"))); 287 EXPECT_TRUE(extension->GetActivePermissions()->HasEffectiveAccessToURL( 288 GURL("http://www.reddit.com"))); 289 EXPECT_TRUE(hosts.MatchesURL(GURL("http://news.ycombinator.com"))); 290 EXPECT_TRUE(extension->GetActivePermissions()->HasEffectiveAccessToURL( 291 GURL("http://news.ycombinator.com"))); 292 EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts()); 293 294 extension = LoadManifest("effective_host_permissions", "all_hosts.json"); 295 hosts = extension->GetEffectiveHostPermissions(); 296 EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/"))); 297 EXPECT_FALSE(hosts.MatchesURL(GURL("https://test/"))); 298 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 299 EXPECT_TRUE(extension->HasEffectiveAccessToAllHosts()); 300 301 extension = LoadManifest("effective_host_permissions", "all_hosts2.json"); 302 hosts = extension->GetEffectiveHostPermissions(); 303 EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/"))); 304 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 305 EXPECT_TRUE(extension->HasEffectiveAccessToAllHosts()); 306 307 extension = LoadManifest("effective_host_permissions", "all_hosts3.json"); 308 hosts = extension->GetEffectiveHostPermissions(); 309 EXPECT_FALSE(hosts.MatchesURL(GURL("http://test/"))); 310 EXPECT_TRUE(hosts.MatchesURL(GURL("https://test/"))); 311 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 312 EXPECT_TRUE(extension->HasEffectiveAccessToAllHosts()); 313} 314 315static bool CheckSocketPermission(scoped_refptr<Extension> extension, 316 SocketPermissionRequest::OperationType type, 317 const char* host, 318 int port) { 319 SocketPermission::CheckParam param(type, host, port); 320 return extension->CheckAPIPermissionWithParam( 321 APIPermission::kSocket, ¶m); 322} 323 324TEST_F(ExtensionTest, SocketPermissions) { 325 // Set feature current channel to appropriate value. 326 Feature::ScopedCurrentChannel scoped_channel( 327 chrome::VersionInfo::CHANNEL_DEV); 328 scoped_refptr<Extension> extension; 329 std::string error; 330 331 extension = LoadManifest("socket_permissions", "empty.json"); 332 EXPECT_FALSE(CheckSocketPermission(extension, 333 SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); 334 335 extension = LoadManifestUnchecked("socket_permissions", 336 "socket1.json", 337 Manifest::INTERNAL, Extension::NO_FLAGS, 338 &error); 339 EXPECT_TRUE(extension == NULL); 340 ASSERT_EQ(ErrorUtils::FormatErrorMessage( 341 errors::kInvalidPermission, "socket"), error); 342 343 extension = LoadManifest("socket_permissions", "socket2.json"); 344 EXPECT_TRUE(CheckSocketPermission(extension, 345 SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); 346 EXPECT_FALSE(CheckSocketPermission( 347 extension, SocketPermissionRequest::UDP_BIND, "", 80)); 348 EXPECT_TRUE(CheckSocketPermission( 349 extension, SocketPermissionRequest::UDP_BIND, "", 8888)); 350 351 EXPECT_FALSE(CheckSocketPermission( 352 extension, SocketPermissionRequest::UDP_SEND_TO, "example.com", 1900)); 353 EXPECT_TRUE(CheckSocketPermission( 354 extension, 355 SocketPermissionRequest::UDP_SEND_TO, 356 "239.255.255.250", 1900)); 357} 358 359// This tests the API permissions with an empty manifest (one that just 360// specifies a name and a version and nothing else). 361TEST_F(ExtensionTest, ApiPermissions) { 362 const struct { 363 const char* permission_name; 364 bool expect_success; 365 } kTests[] = { 366 // Negative test. 367 { "non_existing_permission", false }, 368 // Test default module/package permission. 369 { "browserAction", true }, 370 { "devtools", true }, 371 { "extension", true }, 372 { "i18n", true }, 373 { "pageAction", true }, 374 { "pageActions", true }, 375 { "test", true }, 376 // Some negative tests. 377 { "bookmarks", false }, 378 { "cookies", false }, 379 { "history", false }, 380 // Make sure we find the module name after stripping '.' and '/'. 381 { "browserAction/abcd/onClick", true }, 382 { "browserAction.abcd.onClick", true }, 383 // Test Tabs functions. 384 { "tabs.create", true}, 385 { "tabs.duplicate", true}, 386 { "tabs.onRemoved", true}, 387 { "tabs.remove", true}, 388 { "tabs.update", true}, 389 { "tabs.getSelected", true}, 390 { "tabs.onUpdated", true }, 391 // Test getPermissionWarnings functions. Only one requires permissions. 392 { "management.getPermissionWarningsById", false }, 393 { "management.getPermissionWarningsByManifest", true }, 394 }; 395 396 scoped_refptr<Extension> extension; 397 extension = LoadManifest("empty_manifest", "empty.json"); 398 399 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { 400 EXPECT_EQ(kTests[i].expect_success, 401 extension->HasAPIPermission(kTests[i].permission_name)) 402 << "Permission being tested: " << kTests[i].permission_name; 403 } 404} 405 406TEST_F(ExtensionTest, GetPermissionMessages_ManyApiPermissions) { 407 scoped_refptr<Extension> extension; 408 extension = LoadManifest("permissions", "many-apis.json"); 409 std::vector<string16> warnings = extension->GetPermissionMessageStrings(); 410 ASSERT_EQ(6u, warnings.size()); 411 EXPECT_EQ("Access your data on api.flickr.com", 412 UTF16ToUTF8(warnings[0])); 413 EXPECT_EQ("Read and modify your bookmarks", UTF16ToUTF8(warnings[1])); 414 EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[2])); 415 EXPECT_EQ("Read and modify your browsing history", UTF16ToUTF8(warnings[3])); 416 EXPECT_EQ("Access your tabs and browsing activity", UTF16ToUTF8(warnings[4])); 417 EXPECT_EQ("Manage your apps, extensions, and themes", 418 UTF16ToUTF8(warnings[5])); 419} 420 421TEST_F(ExtensionTest, GetPermissionMessages_ManyHosts) { 422 scoped_refptr<Extension> extension; 423 extension = LoadManifest("permissions", "many-hosts.json"); 424 std::vector<string16> warnings = extension->GetPermissionMessageStrings(); 425 ASSERT_EQ(1u, warnings.size()); 426 EXPECT_EQ("Access your data on encrypted.google.com and www.google.com", 427 UTF16ToUTF8(warnings[0])); 428} 429 430TEST_F(ExtensionTest, GetPermissionMessages_Plugins) { 431 scoped_refptr<Extension> extension; 432 extension = LoadManifest("permissions", "plugins.json"); 433 std::vector<string16> warnings = extension->GetPermissionMessageStrings(); 434 // We don't parse the plugins key on Chrome OS, so it should not ask for any 435 // permissions. 436#if defined(OS_CHROMEOS) 437 ASSERT_EQ(0u, warnings.size()); 438#else 439 ASSERT_EQ(1u, warnings.size()); 440 EXPECT_EQ("Access all data on your computer and the websites you visit", 441 UTF16ToUTF8(warnings[0])); 442#endif 443} 444 445TEST_F(ExtensionTest, WantsFileAccess) { 446 scoped_refptr<Extension> extension; 447 GURL file_url("file:///etc/passwd"); 448 449 // <all_urls> permission 450 extension = LoadManifest("permissions", "permissions_all_urls.json"); 451 EXPECT_TRUE(extension->wants_file_access()); 452 EXPECT_FALSE(extension->CanExecuteScriptOnPage( 453 file_url, file_url, -1, NULL, NULL)); 454 extension = LoadManifest( 455 "permissions", "permissions_all_urls.json", Extension::ALLOW_FILE_ACCESS); 456 EXPECT_TRUE(extension->wants_file_access()); 457 EXPECT_TRUE(extension->CanExecuteScriptOnPage( 458 file_url, file_url, -1, NULL, NULL)); 459 460 // file:///* permission 461 extension = LoadManifest("permissions", "permissions_file_scheme.json"); 462 EXPECT_TRUE(extension->wants_file_access()); 463 EXPECT_FALSE(extension->CanExecuteScriptOnPage( 464 file_url, file_url, -1, NULL, NULL)); 465 extension = LoadManifest("permissions", "permissions_file_scheme.json", 466 Extension::ALLOW_FILE_ACCESS); 467 EXPECT_TRUE(extension->wants_file_access()); 468 EXPECT_TRUE(extension->CanExecuteScriptOnPage( 469 file_url, file_url, -1, NULL, NULL)); 470 471 // http://* permission 472 extension = LoadManifest("permissions", "permissions_http_scheme.json"); 473 EXPECT_FALSE(extension->wants_file_access()); 474 EXPECT_FALSE(extension->CanExecuteScriptOnPage( 475 file_url, file_url, -1, NULL, NULL)); 476 extension = LoadManifest("permissions", "permissions_http_scheme.json", 477 Extension::ALLOW_FILE_ACCESS); 478 EXPECT_FALSE(extension->wants_file_access()); 479 EXPECT_FALSE(extension->CanExecuteScriptOnPage( 480 file_url, file_url, -1, NULL, NULL)); 481 482 // <all_urls> content script match 483 extension = LoadManifest("permissions", "content_script_all_urls.json"); 484 EXPECT_TRUE(extension->wants_file_access()); 485 EXPECT_FALSE(extension->CanExecuteScriptOnPage( 486 file_url, 487 file_url, 488 -1, 489 &ContentScriptsInfo::GetContentScripts(extension)[0], 490 NULL)); 491 extension = LoadManifest("permissions", "content_script_all_urls.json", 492 Extension::ALLOW_FILE_ACCESS); 493 EXPECT_TRUE(extension->wants_file_access()); 494 EXPECT_TRUE(extension->CanExecuteScriptOnPage( 495 file_url, 496 file_url, 497 -1, 498 &ContentScriptsInfo::GetContentScripts(extension)[0], 499 NULL)); 500 501 // file:///* content script match 502 extension = LoadManifest("permissions", "content_script_file_scheme.json"); 503 EXPECT_TRUE(extension->wants_file_access()); 504 EXPECT_FALSE(extension->CanExecuteScriptOnPage( 505 file_url, 506 file_url, 507 -1, 508 &ContentScriptsInfo::GetContentScripts(extension)[0], 509 NULL)); 510 extension = LoadManifest("permissions", "content_script_file_scheme.json", 511 Extension::ALLOW_FILE_ACCESS); 512 EXPECT_TRUE(extension->wants_file_access()); 513 EXPECT_TRUE(extension->CanExecuteScriptOnPage( 514 file_url, 515 file_url, 516 -1, 517 &ContentScriptsInfo::GetContentScripts(extension)[0], 518 NULL)); 519 520 // http://* content script match 521 extension = LoadManifest("permissions", "content_script_http_scheme.json"); 522 EXPECT_FALSE(extension->wants_file_access()); 523 EXPECT_FALSE(extension->CanExecuteScriptOnPage( 524 file_url, 525 file_url, 526 -1, 527 &ContentScriptsInfo::GetContentScripts(extension)[0], 528 NULL)); 529 extension = LoadManifest("permissions", "content_script_http_scheme.json", 530 Extension::ALLOW_FILE_ACCESS); 531 EXPECT_FALSE(extension->wants_file_access()); 532 EXPECT_FALSE(extension->CanExecuteScriptOnPage( 533 file_url, 534 file_url, 535 -1, 536 &ContentScriptsInfo::GetContentScripts(extension)[0], 537 NULL)); 538} 539 540TEST_F(ExtensionTest, ExtraFlags) { 541 scoped_refptr<Extension> extension; 542 extension = LoadManifest("app", "manifest.json", Extension::FROM_WEBSTORE); 543 EXPECT_TRUE(extension->from_webstore()); 544 545 extension = LoadManifest("app", "manifest.json", Extension::FROM_BOOKMARK); 546 EXPECT_TRUE(extension->from_bookmark()); 547 548 extension = LoadManifest("app", "manifest.json", Extension::NO_FLAGS); 549 EXPECT_FALSE(extension->from_bookmark()); 550 EXPECT_FALSE(extension->from_webstore()); 551} 552 553TEST_F(ExtensionTest, BrowserActionSynthesizesCommand) { 554 scoped_refptr<Extension> extension; 555 556 extension = LoadManifest("api_test/browser_action/synthesized", 557 "manifest.json"); 558 // An extension with a browser action but no extension command specified 559 // should get a command assigned to it. 560 const extensions::Command* command = 561 CommandsInfo::GetBrowserActionCommand(extension); 562 ASSERT_TRUE(command != NULL); 563 ASSERT_EQ(ui::VKEY_UNKNOWN, command->accelerator().key_code()); 564} 565 566// Base class for testing the CanExecuteScriptOnPage and CanCaptureVisiblePage 567// methods of Extension for extensions with various permissions. 568class ExtensionScriptAndCaptureVisibleTest : public testing::Test { 569 protected: 570 ExtensionScriptAndCaptureVisibleTest() 571 : http_url("http://www.google.com"), 572 http_url_with_path("http://www.google.com/index.html"), 573 https_url("https://www.google.com"), 574 file_url("file:///foo/bar"), 575 favicon_url("chrome://favicon/http://www.google.com"), 576 extension_url("chrome-extension://" + 577 id_util::GenerateIdForPath( 578 base::FilePath(FILE_PATH_LITERAL("foo")))), 579 settings_url("chrome://settings"), 580 about_url("about:flags") { 581 urls_.insert(http_url); 582 urls_.insert(http_url_with_path); 583 urls_.insert(https_url); 584 urls_.insert(file_url); 585 urls_.insert(favicon_url); 586 urls_.insert(extension_url); 587 urls_.insert(settings_url); 588 urls_.insert(about_url); 589 } 590 591 bool AllowedScript(const Extension* extension, const GURL& url, 592 const GURL& top_url) { 593 return extension->CanExecuteScriptOnPage(url, top_url, -1, NULL, NULL); 594 } 595 596 bool BlockedScript(const Extension* extension, const GURL& url, 597 const GURL& top_url) { 598 return !extension->CanExecuteScriptOnPage(url, top_url, -1, NULL, NULL); 599 } 600 601 bool Allowed(const Extension* extension, const GURL& url) { 602 return Allowed(extension, url, -1); 603 } 604 605 bool Allowed(const Extension* extension, const GURL& url, int tab_id) { 606 return (extension->CanExecuteScriptOnPage(url, url, tab_id, NULL, NULL) && 607 extension->CanCaptureVisiblePage(url, tab_id, NULL)); 608 } 609 610 bool CaptureOnly(const Extension* extension, const GURL& url) { 611 return CaptureOnly(extension, url, -1); 612 } 613 614 bool CaptureOnly(const Extension* extension, const GURL& url, int tab_id) { 615 return !extension->CanExecuteScriptOnPage(url, url, tab_id, NULL, NULL) && 616 extension->CanCaptureVisiblePage(url, tab_id, NULL); 617 } 618 619 bool Blocked(const Extension* extension, const GURL& url) { 620 return Blocked(extension, url, -1); 621 } 622 623 bool Blocked(const Extension* extension, const GURL& url, int tab_id) { 624 return !(extension->CanExecuteScriptOnPage(url, url, tab_id, NULL, NULL) || 625 extension->CanCaptureVisiblePage(url, tab_id, NULL)); 626 } 627 628 bool AllowedExclusivelyOnTab( 629 const Extension* extension, 630 const std::set<GURL>& allowed_urls, 631 int tab_id) { 632 bool result = true; 633 for (std::set<GURL>::iterator it = urls_.begin(); it != urls_.end(); ++it) { 634 const GURL& url = *it; 635 if (allowed_urls.count(url)) 636 result &= Allowed(extension, url, tab_id); 637 else 638 result &= Blocked(extension, url, tab_id); 639 } 640 return result; 641 } 642 643 // URLs that are "safe" to provide scripting and capture visible tab access 644 // to if the permissions allow it. 645 const GURL http_url; 646 const GURL http_url_with_path; 647 const GURL https_url; 648 const GURL file_url; 649 650 // We should allow host permission but not scripting permission for favicon 651 // urls. 652 const GURL favicon_url; 653 654 // URLs that regular extensions should never get access to. 655 const GURL extension_url; 656 const GURL settings_url; 657 const GURL about_url; 658 659 private: 660 // The set of all URLs above. 661 std::set<GURL> urls_; 662}; 663 664TEST_F(ExtensionScriptAndCaptureVisibleTest, Permissions) { 665 // Test <all_urls> for regular extensions. 666 scoped_refptr<Extension> extension = LoadManifestStrict("script_and_capture", 667 "extension_regular_all.json"); 668 669 EXPECT_TRUE(Allowed(extension, http_url)); 670 EXPECT_TRUE(Allowed(extension, https_url)); 671 EXPECT_TRUE(Blocked(extension, file_url)); 672 EXPECT_TRUE(Blocked(extension, settings_url)); 673 EXPECT_TRUE(CaptureOnly(extension, favicon_url)); 674 EXPECT_TRUE(Blocked(extension, about_url)); 675 EXPECT_TRUE(Blocked(extension, extension_url)); 676 677 // Test access to iframed content. 678 GURL within_extension_url = extension->GetResourceURL("page.html"); 679 EXPECT_TRUE(AllowedScript(extension, http_url, http_url_with_path)); 680 EXPECT_TRUE(AllowedScript(extension, https_url, http_url_with_path)); 681 EXPECT_TRUE(AllowedScript(extension, http_url, within_extension_url)); 682 EXPECT_TRUE(AllowedScript(extension, https_url, within_extension_url)); 683 EXPECT_TRUE(BlockedScript(extension, http_url, extension_url)); 684 EXPECT_TRUE(BlockedScript(extension, https_url, extension_url)); 685 686 EXPECT_FALSE(extension->HasHostPermission(settings_url)); 687 EXPECT_FALSE(extension->HasHostPermission(about_url)); 688 EXPECT_TRUE(extension->HasHostPermission(favicon_url)); 689 690 // Test * for scheme, which implies just the http/https schemes. 691 extension = LoadManifestStrict("script_and_capture", 692 "extension_wildcard.json"); 693 EXPECT_TRUE(Allowed(extension, http_url)); 694 EXPECT_TRUE(Allowed(extension, https_url)); 695 EXPECT_TRUE(Blocked(extension, settings_url)); 696 EXPECT_TRUE(Blocked(extension, about_url)); 697 EXPECT_TRUE(Blocked(extension, file_url)); 698 EXPECT_TRUE(Blocked(extension, favicon_url)); 699 extension = LoadManifest("script_and_capture", 700 "extension_wildcard_settings.json"); 701 EXPECT_TRUE(Blocked(extension, settings_url)); 702 703 // Having chrome://*/ should not work for regular extensions. Note that 704 // for favicon access, we require the explicit pattern chrome://favicon/*. 705 std::string error; 706 extension = LoadManifestUnchecked("script_and_capture", 707 "extension_wildcard_chrome.json", 708 Manifest::INTERNAL, Extension::NO_FLAGS, 709 &error); 710 EXPECT_TRUE(extension == NULL); 711 EXPECT_EQ(ErrorUtils::FormatErrorMessage( 712 errors::kInvalidPermissionScheme, "chrome://*/"), error); 713 714 // Having chrome://favicon/* should not give you chrome://* 715 extension = LoadManifestStrict("script_and_capture", 716 "extension_chrome_favicon_wildcard.json"); 717 EXPECT_TRUE(Blocked(extension, settings_url)); 718 EXPECT_TRUE(CaptureOnly(extension, favicon_url)); 719 EXPECT_TRUE(Blocked(extension, about_url)); 720 EXPECT_TRUE(extension->HasHostPermission(favicon_url)); 721 722 // Having http://favicon should not give you chrome://favicon 723 extension = LoadManifestStrict("script_and_capture", 724 "extension_http_favicon.json"); 725 EXPECT_TRUE(Blocked(extension, settings_url)); 726 EXPECT_TRUE(Blocked(extension, favicon_url)); 727 728 // Component extensions with <all_urls> should get everything. 729 extension = LoadManifest("script_and_capture", "extension_component_all.json", 730 Manifest::COMPONENT, Extension::NO_FLAGS); 731 EXPECT_TRUE(Allowed(extension, http_url)); 732 EXPECT_TRUE(Allowed(extension, https_url)); 733 EXPECT_TRUE(Allowed(extension, settings_url)); 734 EXPECT_TRUE(Allowed(extension, about_url)); 735 EXPECT_TRUE(Allowed(extension, favicon_url)); 736 EXPECT_TRUE(extension->HasHostPermission(favicon_url)); 737 738 // Component extensions should only get access to what they ask for. 739 extension = LoadManifest("script_and_capture", 740 "extension_component_google.json", Manifest::COMPONENT, 741 Extension::NO_FLAGS); 742 EXPECT_TRUE(Allowed(extension, http_url)); 743 EXPECT_TRUE(Blocked(extension, https_url)); 744 EXPECT_TRUE(Blocked(extension, file_url)); 745 EXPECT_TRUE(Blocked(extension, settings_url)); 746 EXPECT_TRUE(Blocked(extension, favicon_url)); 747 EXPECT_TRUE(Blocked(extension, about_url)); 748 EXPECT_TRUE(Blocked(extension, extension_url)); 749 EXPECT_FALSE(extension->HasHostPermission(settings_url)); 750} 751 752 753TEST_F(ExtensionScriptAndCaptureVisibleTest, PermissionsWithChromeURLsEnabled) { 754 CommandLine::ForCurrentProcess()->AppendSwitch( 755 switches::kExtensionsOnChromeURLs); 756 757 scoped_refptr<Extension> extension; 758 759 // Test <all_urls> for regular extensions. 760 extension = LoadManifestStrict("script_and_capture", 761 "extension_regular_all.json"); 762 EXPECT_TRUE(Allowed(extension, http_url)); 763 EXPECT_TRUE(Allowed(extension, https_url)); 764 EXPECT_TRUE(Blocked(extension, file_url)); 765 EXPECT_TRUE(Blocked(extension, settings_url)); 766 EXPECT_TRUE(Allowed(extension, favicon_url)); // chrome:// requested 767 EXPECT_TRUE(Blocked(extension, about_url)); 768 EXPECT_TRUE(Blocked(extension, extension_url)); 769 770 // Test access to iframed content. 771 GURL within_extension_url = extension->GetResourceURL("page.html"); 772 EXPECT_TRUE(AllowedScript(extension, http_url, http_url_with_path)); 773 EXPECT_TRUE(AllowedScript(extension, https_url, http_url_with_path)); 774 EXPECT_TRUE(AllowedScript(extension, http_url, within_extension_url)); 775 EXPECT_TRUE(AllowedScript(extension, https_url, within_extension_url)); 776 EXPECT_TRUE(BlockedScript(extension, http_url, extension_url)); 777 EXPECT_TRUE(BlockedScript(extension, https_url, extension_url)); 778 779 EXPECT_FALSE(extension->HasHostPermission(settings_url)); 780 EXPECT_FALSE(extension->HasHostPermission(about_url)); 781 EXPECT_TRUE(extension->HasHostPermission(favicon_url)); 782 783 // Test * for scheme, which implies just the http/https schemes. 784 extension = LoadManifestStrict("script_and_capture", 785 "extension_wildcard.json"); 786 EXPECT_TRUE(Allowed(extension, http_url)); 787 EXPECT_TRUE(Allowed(extension, https_url)); 788 EXPECT_TRUE(Blocked(extension, settings_url)); 789 EXPECT_TRUE(Blocked(extension, about_url)); 790 EXPECT_TRUE(Blocked(extension, file_url)); 791 EXPECT_TRUE(Blocked(extension, favicon_url)); 792 extension = LoadManifest("script_and_capture", 793 "extension_wildcard_settings.json"); 794 EXPECT_TRUE(Blocked(extension, settings_url)); 795 796 // Having chrome://*/ should work for regular extensions with the flag 797 // enabled. 798 std::string error; 799 extension = LoadManifestUnchecked("script_and_capture", 800 "extension_wildcard_chrome.json", 801 Manifest::INTERNAL, Extension::NO_FLAGS, 802 &error); 803 EXPECT_FALSE(extension == NULL); 804 EXPECT_TRUE(Blocked(extension, http_url)); 805 EXPECT_TRUE(Blocked(extension, https_url)); 806 EXPECT_TRUE(Allowed(extension, settings_url)); 807 EXPECT_TRUE(Blocked(extension, about_url)); 808 EXPECT_TRUE(Blocked(extension, file_url)); 809 EXPECT_TRUE(Allowed(extension, favicon_url)); // chrome:// requested 810 811 // Having chrome://favicon/* should not give you chrome://* 812 extension = LoadManifestStrict("script_and_capture", 813 "extension_chrome_favicon_wildcard.json"); 814 EXPECT_TRUE(Blocked(extension, settings_url)); 815 EXPECT_TRUE(Allowed(extension, favicon_url)); // chrome:// requested 816 EXPECT_TRUE(Blocked(extension, about_url)); 817 EXPECT_TRUE(extension->HasHostPermission(favicon_url)); 818 819 // Having http://favicon should not give you chrome://favicon 820 extension = LoadManifestStrict("script_and_capture", 821 "extension_http_favicon.json"); 822 EXPECT_TRUE(Blocked(extension, settings_url)); 823 EXPECT_TRUE(Blocked(extension, favicon_url)); 824 825 // Component extensions with <all_urls> should get everything. 826 extension = LoadManifest("script_and_capture", "extension_component_all.json", 827 Manifest::COMPONENT, Extension::NO_FLAGS); 828 EXPECT_TRUE(Allowed(extension, http_url)); 829 EXPECT_TRUE(Allowed(extension, https_url)); 830 EXPECT_TRUE(Allowed(extension, settings_url)); 831 EXPECT_TRUE(Allowed(extension, about_url)); 832 EXPECT_TRUE(Allowed(extension, favicon_url)); 833 EXPECT_TRUE(extension->HasHostPermission(favicon_url)); 834 835 // Component extensions should only get access to what they ask for. 836 extension = LoadManifest("script_and_capture", 837 "extension_component_google.json", Manifest::COMPONENT, 838 Extension::NO_FLAGS); 839 EXPECT_TRUE(Allowed(extension, http_url)); 840 EXPECT_TRUE(Blocked(extension, https_url)); 841 EXPECT_TRUE(Blocked(extension, file_url)); 842 EXPECT_TRUE(Blocked(extension, settings_url)); 843 EXPECT_TRUE(Blocked(extension, favicon_url)); 844 EXPECT_TRUE(Blocked(extension, about_url)); 845 EXPECT_TRUE(Blocked(extension, extension_url)); 846 EXPECT_FALSE(extension->HasHostPermission(settings_url)); 847} 848 849TEST_F(ExtensionScriptAndCaptureVisibleTest, TabSpecific) { 850 scoped_refptr<Extension> extension = 851 LoadManifestStrict("script_and_capture", "tab_specific.json"); 852 853 EXPECT_FALSE(extension->GetTabSpecificPermissions(0).get()); 854 EXPECT_FALSE(extension->GetTabSpecificPermissions(1).get()); 855 EXPECT_FALSE(extension->GetTabSpecificPermissions(2).get()); 856 857 std::set<GURL> no_urls; 858 859 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 0)); 860 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 1)); 861 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2)); 862 863 URLPatternSet allowed_hosts; 864 allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL, 865 http_url.spec())); 866 std::set<GURL> allowed_urls; 867 allowed_urls.insert(http_url); 868 // http_url_with_path() will also be allowed, because Extension should be 869 // considering the security origin of the URL not the URL itself, and 870 // http_url is in allowed_hosts. 871 allowed_urls.insert(http_url_with_path); 872 873 { 874 scoped_refptr<PermissionSet> permissions( 875 new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet())); 876 extension->UpdateTabSpecificPermissions(0, permissions); 877 EXPECT_EQ(permissions->explicit_hosts(), 878 extension->GetTabSpecificPermissions(0)->explicit_hosts()); 879 } 880 881 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, allowed_urls, 0)); 882 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 1)); 883 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2)); 884 885 extension->ClearTabSpecificPermissions(0); 886 EXPECT_FALSE(extension->GetTabSpecificPermissions(0).get()); 887 888 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 0)); 889 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 1)); 890 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2)); 891 892 std::set<GURL> more_allowed_urls = allowed_urls; 893 more_allowed_urls.insert(https_url); 894 URLPatternSet more_allowed_hosts = allowed_hosts; 895 more_allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL, 896 https_url.spec())); 897 898 { 899 scoped_refptr<PermissionSet> permissions( 900 new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet())); 901 extension->UpdateTabSpecificPermissions(0, permissions); 902 EXPECT_EQ(permissions->explicit_hosts(), 903 extension->GetTabSpecificPermissions(0)->explicit_hosts()); 904 905 permissions = new PermissionSet(APIPermissionSet(), 906 more_allowed_hosts, 907 URLPatternSet()); 908 extension->UpdateTabSpecificPermissions(1, permissions); 909 EXPECT_EQ(permissions->explicit_hosts(), 910 extension->GetTabSpecificPermissions(1)->explicit_hosts()); 911 } 912 913 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, allowed_urls, 0)); 914 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, more_allowed_urls, 1)); 915 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2)); 916 917 extension->ClearTabSpecificPermissions(0); 918 EXPECT_FALSE(extension->GetTabSpecificPermissions(0).get()); 919 920 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 0)); 921 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, more_allowed_urls, 1)); 922 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2)); 923 924 extension->ClearTabSpecificPermissions(1); 925 EXPECT_FALSE(extension->GetTabSpecificPermissions(1).get()); 926 927 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 0)); 928 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 1)); 929 EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2)); 930} 931 932namespace { 933enum SyncTestExtensionType { 934 EXTENSION, 935 APP, 936 USER_SCRIPT, 937 THEME 938}; 939 940static scoped_refptr<Extension> MakeSyncTestExtension( 941 SyncTestExtensionType type, 942 const GURL& update_url, 943 const GURL& launch_url, 944 Manifest::Location location, 945 int num_plugins, 946 const base::FilePath& extension_path, 947 int creation_flags) { 948 DictionaryValue source; 949 source.SetString(extension_manifest_keys::kName, 950 "PossiblySyncableExtension"); 951 source.SetString(extension_manifest_keys::kVersion, "0.0.0.0"); 952 if (type == APP) 953 source.SetString(extension_manifest_keys::kApp, "true"); 954 if (type == THEME) 955 source.Set(extension_manifest_keys::kTheme, new DictionaryValue()); 956 if (!update_url.is_empty()) { 957 source.SetString(extension_manifest_keys::kUpdateURL, 958 update_url.spec()); 959 } 960 if (!launch_url.is_empty()) { 961 source.SetString(extension_manifest_keys::kLaunchWebURL, 962 launch_url.spec()); 963 } 964 if (type != THEME) { 965 source.SetBoolean(extension_manifest_keys::kConvertedFromUserScript, 966 type == USER_SCRIPT); 967 ListValue* plugins = new ListValue(); 968 for (int i = 0; i < num_plugins; ++i) { 969 DictionaryValue* plugin = new DictionaryValue(); 970 plugin->SetString(extension_manifest_keys::kPluginsPath, ""); 971 plugins->Set(i, plugin); 972 } 973 source.Set(extension_manifest_keys::kPlugins, plugins); 974 } 975 976 std::string error; 977 scoped_refptr<Extension> extension = Extension::Create( 978 extension_path, location, source, creation_flags, &error); 979 EXPECT_TRUE(extension); 980 EXPECT_EQ("", error); 981 return extension; 982} 983 984static const char kValidUpdateUrl1[] = 985 "http://clients2.google.com/service/update2/crx"; 986static const char kValidUpdateUrl2[] = 987 "https://clients2.google.com/service/update2/crx"; 988} 989 990TEST_F(ExtensionTest, GetSyncTypeNormalExtensionNoUpdateUrl) { 991 scoped_refptr<Extension> extension( 992 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), 993 Manifest::INTERNAL, 0, base::FilePath(), 994 Extension::NO_FLAGS)); 995 EXPECT_NE(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 996} 997 998// http://crbug.com/172712 999TEST_F(ExtensionTest, DISABLED_GetSyncTypeUserScriptValidUpdateUrl) { 1000 scoped_refptr<Extension> extension( 1001 MakeSyncTestExtension(USER_SCRIPT, GURL(kValidUpdateUrl1), GURL(), 1002 Manifest::INTERNAL, 0, base::FilePath(), 1003 Extension::NO_FLAGS)); 1004 EXPECT_NE(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 1005} 1006 1007TEST_F(ExtensionTest, GetSyncTypeUserScriptNoUpdateUrl) { 1008 scoped_refptr<Extension> extension( 1009 MakeSyncTestExtension(USER_SCRIPT, GURL(), GURL(), 1010 Manifest::INTERNAL, 0, base::FilePath(), 1011 Extension::NO_FLAGS)); 1012 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 1013} 1014 1015TEST_F(ExtensionTest, GetSyncTypeThemeNoUpdateUrl) { 1016 scoped_refptr<Extension> extension( 1017 MakeSyncTestExtension(THEME, GURL(), GURL(), 1018 Manifest::INTERNAL, 0, base::FilePath(), 1019 Extension::NO_FLAGS)); 1020 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 1021} 1022 1023TEST_F(ExtensionTest, GetSyncTypeExtensionWithLaunchUrl) { 1024 scoped_refptr<Extension> extension( 1025 MakeSyncTestExtension(EXTENSION, GURL(), GURL("http://www.google.com"), 1026 Manifest::INTERNAL, 0, base::FilePath(), 1027 Extension::NO_FLAGS)); 1028 EXPECT_NE(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 1029} 1030 1031TEST_F(ExtensionTest, GetSyncTypeExtensionExternal) { 1032 scoped_refptr<Extension> extension( 1033 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), 1034 Manifest::EXTERNAL_PREF, 0, base::FilePath(), 1035 Extension::NO_FLAGS)); 1036 1037 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 1038} 1039 1040TEST_F(ExtensionTest, GetSyncTypeUserScriptThirdPartyUpdateUrl) { 1041 scoped_refptr<Extension> extension( 1042 MakeSyncTestExtension( 1043 USER_SCRIPT, GURL("http://third-party.update_url.com"), GURL(), 1044 Manifest::INTERNAL, 0, base::FilePath(), Extension::NO_FLAGS)); 1045 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 1046} 1047 1048TEST_F(ExtensionTest, OnlyDisplayAppsInLauncher) { 1049 scoped_refptr<Extension> extension( 1050 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), 1051 Manifest::INTERNAL, 0, base::FilePath(), 1052 Extension::NO_FLAGS)); 1053 1054 EXPECT_FALSE(extension->ShouldDisplayInAppLauncher()); 1055 EXPECT_FALSE(extension->ShouldDisplayInNewTabPage()); 1056 1057 scoped_refptr<Extension> app( 1058 MakeSyncTestExtension(APP, GURL(), GURL("http://www.google.com"), 1059 Manifest::INTERNAL, 0, base::FilePath(), 1060 Extension::NO_FLAGS)); 1061 EXPECT_TRUE(app->ShouldDisplayInAppLauncher()); 1062 EXPECT_TRUE(app->ShouldDisplayInNewTabPage()); 1063} 1064 1065TEST_F(ExtensionTest, DisplayInXManifestProperties) { 1066 DictionaryValue manifest; 1067 manifest.SetString(keys::kName, "TestComponentApp"); 1068 manifest.SetString(keys::kVersion, "0.0.0.0"); 1069 manifest.SetString(keys::kApp, "true"); 1070 manifest.SetString(keys::kPlatformAppBackgroundPage, ""); 1071 1072 std::string error; 1073 scoped_refptr<Extension> app; 1074 1075 // Default to true. 1076 app = Extension::Create( 1077 base::FilePath(), Manifest::COMPONENT, manifest, 0, &error); 1078 EXPECT_EQ(error, std::string()); 1079 EXPECT_TRUE(app->ShouldDisplayInAppLauncher()); 1080 EXPECT_TRUE(app->ShouldDisplayInNewTabPage()); 1081 1082 // Value display_in_NTP defaults to display_in_launcher. 1083 manifest.SetBoolean(keys::kDisplayInLauncher, false); 1084 app = Extension::Create( 1085 base::FilePath(), Manifest::COMPONENT, manifest, 0, &error); 1086 EXPECT_EQ(error, std::string()); 1087 EXPECT_FALSE(app->ShouldDisplayInAppLauncher()); 1088 EXPECT_FALSE(app->ShouldDisplayInNewTabPage()); 1089 1090 // Value display_in_NTP = true overriding display_in_launcher = false. 1091 manifest.SetBoolean(keys::kDisplayInNewTabPage, true); 1092 app = Extension::Create( 1093 base::FilePath(), Manifest::COMPONENT, manifest, 0, &error); 1094 EXPECT_EQ(error, std::string()); 1095 EXPECT_FALSE(app->ShouldDisplayInAppLauncher()); 1096 EXPECT_TRUE(app->ShouldDisplayInNewTabPage()); 1097 1098 // Value display_in_NTP = false only, overrides default = true. 1099 manifest.Remove(keys::kDisplayInLauncher, NULL); 1100 manifest.SetBoolean(keys::kDisplayInNewTabPage, false); 1101 app = Extension::Create( 1102 base::FilePath(), Manifest::COMPONENT, manifest, 0, &error); 1103 EXPECT_EQ(error, std::string()); 1104 EXPECT_TRUE(app->ShouldDisplayInAppLauncher()); 1105 EXPECT_FALSE(app->ShouldDisplayInNewTabPage()); 1106 1107 // Error checking. 1108 manifest.SetString(keys::kDisplayInNewTabPage, "invalid"); 1109 app = Extension::Create( 1110 base::FilePath(), Manifest::COMPONENT, manifest, 0, &error); 1111 EXPECT_EQ(error, std::string(errors::kInvalidDisplayInNewTabPage)); 1112} 1113 1114TEST_F(ExtensionTest, OnlySyncInternal) { 1115 scoped_refptr<Extension> extension_internal( 1116 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), 1117 Manifest::INTERNAL, 0, base::FilePath(), 1118 Extension::NO_FLAGS)); 1119 EXPECT_TRUE(extension_internal->IsSyncable()); 1120 1121 scoped_refptr<Extension> extension_noninternal( 1122 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), 1123 Manifest::COMPONENT, 0, base::FilePath(), 1124 Extension::NO_FLAGS)); 1125 EXPECT_FALSE(extension_noninternal->IsSyncable()); 1126} 1127 1128TEST_F(ExtensionTest, DontSyncDefault) { 1129 scoped_refptr<Extension> extension_default( 1130 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), 1131 Manifest::INTERNAL, 0, base::FilePath(), 1132 Extension::WAS_INSTALLED_BY_DEFAULT)); 1133 EXPECT_FALSE(extension_default->IsSyncable()); 1134} 1135 1136TEST_F(ExtensionTest, OptionalOnlyPermission) { 1137 // Set feature current channel to dev because the only permission that must 1138 // be optional (usbDevices) is only available on dev channel. 1139 Feature::ScopedCurrentChannel scoped_channel( 1140 chrome::VersionInfo::CHANNEL_DEV); 1141 1142 scoped_refptr<Extension> extension; 1143 std::string error; 1144 extension = LoadManifestUnchecked("optional_only_permission", 1145 "manifest1.json", 1146 Manifest::INTERNAL, Extension::NO_FLAGS, 1147 &error); 1148 EXPECT_TRUE(extension == NULL); 1149 ASSERT_EQ(ErrorUtils::FormatErrorMessage( 1150 errors::kPermissionMustBeOptional, "usbDevices"), error); 1151 1152 error.clear(); 1153 extension = LoadManifestUnchecked("optional_only_permission", 1154 "manifest2.json", 1155 Manifest::INTERNAL, Extension::NO_FLAGS, 1156 &error); 1157 EXPECT_TRUE(extension != NULL); 1158 EXPECT_TRUE(error.empty()); 1159} 1160 1161// These last 2 tests don't make sense on Chrome OS, where extension plugins 1162// are not allowed. 1163#if !defined(OS_CHROMEOS) 1164TEST_F(ExtensionTest, GetSyncTypeExtensionWithPlugin) { 1165 scoped_refptr<Extension> extension( 1166 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), 1167 Manifest::INTERNAL, 1, base::FilePath(), 1168 Extension::NO_FLAGS)); 1169 if (extension) 1170 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 1171} 1172 1173TEST_F(ExtensionTest, GetSyncTypeExtensionWithTwoPlugins) { 1174 scoped_refptr<Extension> extension( 1175 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), 1176 Manifest::INTERNAL, 2, base::FilePath(), 1177 Extension::NO_FLAGS)); 1178 if (extension) 1179 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); 1180} 1181#endif // !defined(OS_CHROMEOS) 1182 1183} // namespace extensions 1184