| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 #include <vector> | 6 #include <vector> |
| 7 | 7 |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/json_reader.h" | 10 #include "base/json_reader.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "chrome/common/notification_registrar.h" | 24 #include "chrome/common/notification_registrar.h" |
| 25 #include "chrome/common/notification_service.h" | 25 #include "chrome/common/notification_service.h" |
| 26 #include "chrome/common/notification_type.h" | 26 #include "chrome/common/notification_type.h" |
| 27 #include "chrome/test/testing_profile.h" | 27 #include "chrome/test/testing_profile.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 29 #include "testing/platform_test.h" | 29 #include "testing/platform_test.h" |
| 30 | 30 |
| 31 namespace { | 31 namespace { |
| 32 | 32 |
| 33 // Extension ids used during testing. | 33 // Extension ids used during testing. |
| 34 const char* const all_zero = "0000000000000000000000000000000000000000"; | 34 const char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
| 35 const char* const zero_n_one = "0000000000000000000000000000000000000001"; | 35 const char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"; |
| 36 const char* const good0 = "fc6f6ba6693faf6773c13701019f2e7a12f0febe"; | 36 const char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj"; |
| 37 const char* const good1 = "e5ead92b2c6795c1d2b92df9c5cb37de5582471a"; | 37 const char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk"; |
| 38 const char* const good2 = "a37fed892f622823f4daaec4426a32fc7f6147dc"; | 38 const char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa"; |
| 39 const char* const good_crx = "b3dd733cd71a98fa83f387455e12f5c5501c519e"; | 39 const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; |
| 40 const char* const page_action = "a4ca7d01469a010acb200568a0b8f4d9b3ac1f91"; | 40 const char* const page_action = "kemkhnabegjkabakmlcaafgikalipenj"; |
| 41 const char* const theme_crx = "80c45f5ae9e0f839d105c6a6d2461a036bc40a04"; | 41 const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad"; |
| 42 const char* const theme2_crx = "f9f6c52c01efdd5edd7c396b5f995a15fc7ad6d1"; | 42 const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; |
| 43 | 43 |
| 44 struct ExtensionsOrder { | 44 struct ExtensionsOrder { |
| 45 bool operator()(const Extension* a, const Extension* b) { | 45 bool operator()(const Extension* a, const Extension* b) { |
| 46 return a->name() < b->name(); | 46 return a->name() < b->name(); |
| 47 } | 47 } |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 static std::vector<std::string> GetErrors() { | 50 static std::vector<std::string> GetErrors() { |
| 51 const std::vector<std::string>* errors = | 51 const std::vector<std::string>* errors = |
| 52 ExtensionErrorReporter::GetInstance()->GetErrors(); | 52 ExtensionErrorReporter::GetInstance()->GetErrors(); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 | 387 |
| 388 // Make sure the dictionary is empty. | 388 // Make sure the dictionary is empty. |
| 389 ValidatePrefKeyCount(0); | 389 ValidatePrefKeyCount(0); |
| 390 | 390 |
| 391 EXPECT_TRUE(MatchPattern(GetErrors()[0], | 391 EXPECT_TRUE(MatchPattern(GetErrors()[0], |
| 392 std::string("Could not load extension from '*'. * ") + | 392 std::string("Could not load extension from '*'. * ") + |
| 393 JSONReader::kBadRootElementType)) << GetErrors()[0]; | 393 JSONReader::kBadRootElementType)) << GetErrors()[0]; |
| 394 | 394 |
| 395 EXPECT_TRUE(MatchPattern(GetErrors()[1], | 395 EXPECT_TRUE(MatchPattern(GetErrors()[1], |
| 396 std::string("Could not load extension from '*'. ") + | 396 std::string("Could not load extension from '*'. ") + |
| 397 Extension::kMissingFileError)) << GetErrors()[1]; | 397 Extension::kInvalidManifestError)) << GetErrors()[1]; |
| 398 | 398 |
| 399 EXPECT_TRUE(MatchPattern(GetErrors()[2], | 399 EXPECT_TRUE(MatchPattern(GetErrors()[2], |
| 400 std::string("Could not load extension from '*'. ") + | 400 std::string("Could not load extension from '*'. ") + |
| 401 Extension::kInvalidManifestError)) << GetErrors()[2]; | 401 Extension::kMissingFileError)) << GetErrors()[2]; |
| 402 }; | 402 }; |
| 403 | 403 |
| 404 // Test that partially deleted extensions are cleaned up during startup | 404 // Test that partially deleted extensions are cleaned up during startup |
| 405 // Test loading bad extensions from the profile directory. | 405 // Test loading bad extensions from the profile directory. |
| 406 TEST_F(ExtensionsServiceTest, CleanupOnStartup) { | 406 TEST_F(ExtensionsServiceTest, CleanupOnStartup) { |
| 407 FilePath source_path; | 407 FilePath source_path; |
| 408 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path)); | 408 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path)); |
| 409 source_path = source_path.AppendASCII("extensions"); | 409 source_path = source_path.AppendASCII("extensions"); |
| 410 source_path = source_path.AppendASCII("good"); | 410 source_path = source_path.AppendASCII("good"); |
| 411 | 411 |
| 412 FilePath dest_path = profile_->GetPath().AppendASCII("Extensions"); | 412 FilePath dest_path = profile_->GetPath().AppendASCII("Extensions"); |
| 413 file_util::CopyDirectory(source_path, dest_path, true); // Recursive. | 413 file_util::CopyDirectory(source_path, dest_path, true); // Recursive. |
| 414 | 414 |
| 415 // Simulate that one of them got partially deleted by deling the | 415 // Simulate that one of them got partially deleted by deling the |
| 416 // Current Version file. | 416 // Current Version file. |
| 417 dest_path = dest_path.AppendASCII("extension1") | 417 dest_path = dest_path.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") |
| 418 .AppendASCII(ExtensionsService::kCurrentVersionFileName); | 418 .AppendASCII(ExtensionsService::kCurrentVersionFileName); |
| 419 ASSERT_TRUE(file_util::Delete(dest_path, false)); // not recursive | 419 ASSERT_TRUE(file_util::Delete(dest_path, false)); // not recursive |
| 420 | 420 |
| 421 service_->Init(); | 421 service_->Init(); |
| 422 loop_.RunAllPending(); | 422 loop_.RunAllPending(); |
| 423 | 423 |
| 424 // We should have only gotten two extensions now. | 424 // We should have only gotten two extensions now. |
| 425 EXPECT_EQ(2u, loaded_.size()); | 425 EXPECT_EQ(2u, loaded_.size()); |
| 426 | 426 |
| 427 // And extension1 dir should now be toast. | 427 // And extension1 dir should now be toast. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 path = extensions_path.AppendASCII("bad_magic.crx"); | 479 path = extensions_path.AppendASCII("bad_magic.crx"); |
| 480 InstallExtension(path, false); | 480 InstallExtension(path, false); |
| 481 ValidatePrefKeyCount(pref_count); | 481 ValidatePrefKeyCount(pref_count); |
| 482 | 482 |
| 483 // TODO(erikkay): add more tests for many of the failure cases. | 483 // TODO(erikkay): add more tests for many of the failure cases. |
| 484 // TODO(erikkay): add tests for upgrade cases. | 484 // TODO(erikkay): add tests for upgrade cases. |
| 485 } | 485 } |
| 486 | 486 |
| 487 #if defined(OS_WIN) // TODO(port) | 487 #if defined(OS_WIN) // TODO(port) |
| 488 // Test Packaging and installing an extension. | 488 // Test Packaging and installing an extension. |
| 489 // TODO(aa): add a test that uses an openssl-generate private key. | |
| 490 // TODO(rafaelw): add more tests for failure cases. | 489 // TODO(rafaelw): add more tests for failure cases. |
| 491 TEST_F(ExtensionsServiceTest, PackExtension) { | 490 TEST_F(ExtensionsServiceTest, PackExtension) { |
| 492 SetExtensionsEnabled(true); | 491 SetExtensionsEnabled(true); |
| 493 | 492 |
| 494 FilePath extensions_path; | 493 FilePath extensions_path; |
| 495 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); | 494 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); |
| 496 extensions_path = extensions_path.AppendASCII("extensions"); | 495 extensions_path = extensions_path.AppendASCII("extensions"); |
| 497 FilePath input_directory = extensions_path.AppendASCII("good") | 496 FilePath input_directory = extensions_path.AppendASCII("good") |
| 498 .AppendASCII("extension1").AppendASCII("1"); | 497 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj").AppendASCII("1.0.0.0"); |
| 499 | 498 |
| 500 FilePath output_directory; | 499 FilePath output_directory; |
| 501 file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_"), | 500 file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_"), |
| 502 &output_directory); | 501 &output_directory); |
| 503 FilePath crx_path(output_directory.AppendASCII("ex1.crx")); | 502 FilePath crx_path(output_directory.AppendASCII("ex1.crx")); |
| 504 FilePath privkey_path(output_directory.AppendASCII("privkey.pem")); | 503 FilePath privkey_path(output_directory.AppendASCII("privkey.pem")); |
| 505 | 504 |
| 506 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); | 505 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); |
| 507 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(), | 506 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(), |
| 508 privkey_path)); | 507 privkey_path)); |
| 509 | 508 |
| 510 ASSERT_TRUE(file_util::PathExists(privkey_path)); | 509 ASSERT_TRUE(file_util::PathExists(privkey_path)); |
| 511 | 510 InstallExtension(crx_path, true); |
| 512 // TODO(aa): Re-enable this when ExtensionUnpacker expects the same format we | |
| 513 // are generating in ExtensionCreator. | |
| 514 // InstallExtension(crx_path, true); | |
| 515 | 511 |
| 516 file_util::Delete(crx_path, false); | 512 file_util::Delete(crx_path, false); |
| 517 file_util::Delete(privkey_path, false); | 513 file_util::Delete(privkey_path, false); |
| 518 } | 514 } |
| 519 | 515 |
| 520 // Test Packaging and installing an extension using an openssl generated key. | 516 // Test Packaging and installing an extension using an openssl generated key. |
| 521 // The openssl is generated with the following: | 517 // The openssl is generated with the following: |
| 522 // > openssl genrsa -out privkey.pem 1024 | 518 // > openssl genrsa -out privkey.pem 1024 |
| 523 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem | 519 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem |
| 524 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a | 520 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a |
| 525 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects. | 521 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects. |
| 526 TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) { | 522 TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) { |
| 527 SetExtensionsEnabled(true); | 523 SetExtensionsEnabled(true); |
| 528 | 524 |
| 529 FilePath extensions_path; | 525 FilePath extensions_path; |
| 530 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); | 526 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); |
| 531 extensions_path = extensions_path.AppendASCII("extensions"); | 527 extensions_path = extensions_path.AppendASCII("extensions"); |
| 532 FilePath input_directory = extensions_path.AppendASCII("good") | 528 FilePath input_directory = extensions_path.AppendASCII("good") |
| 533 .AppendASCII("extension1").AppendASCII("1"); | 529 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj").AppendASCII("1.0.0.0"); |
| 534 FilePath privkey_path(extensions_path.AppendASCII( | 530 FilePath privkey_path(extensions_path.AppendASCII( |
| 535 "openssl_privkey_asn1.pem")); | 531 "openssl_privkey_asn1.pem")); |
| 536 ASSERT_TRUE(file_util::PathExists(privkey_path)); | 532 ASSERT_TRUE(file_util::PathExists(privkey_path)); |
| 537 | 533 |
| 538 FilePath output_directory; | 534 FilePath output_directory; |
| 539 file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_"), | 535 file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_"), |
| 540 &output_directory); | 536 &output_directory); |
| 541 FilePath crx_path(output_directory.AppendASCII("ex1.crx")); | 537 FilePath crx_path(output_directory.AppendASCII("ex1.crx")); |
| 542 | 538 |
| 543 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); | 539 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); |
| 544 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path, | 540 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path, |
| 545 FilePath())); | 541 FilePath())); |
| 546 | 542 |
| 547 // TODO(aa): Re-enable this when ExtensionUnpacker expects the same format we | 543 InstallExtension(crx_path, true); |
| 548 // are generating in ExtensionCreator. | |
| 549 // InstallExtension(crx_path, true); | |
| 550 | 544 |
| 551 file_util::Delete(crx_path, false); | 545 file_util::Delete(crx_path, false); |
| 552 } | 546 } |
| 553 #endif // defined(OS_WIN) | 547 #endif // defined(OS_WIN) |
| 554 | 548 |
| 555 TEST_F(ExtensionsServiceTest, InstallTheme) { | 549 TEST_F(ExtensionsServiceTest, InstallTheme) { |
| 556 FilePath extensions_path; | 550 FilePath extensions_path; |
| 557 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); | 551 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); |
| 558 extensions_path = extensions_path.AppendASCII("extensions"); | 552 extensions_path = extensions_path.AppendASCII("extensions"); |
| 559 | 553 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 ValidatePref(good_crx, L"state", Extension::DISABLED); | 719 ValidatePref(good_crx, L"state", Extension::DISABLED); |
| 726 ValidatePref(good_crx, L"location", Extension::INTERNAL); | 720 ValidatePref(good_crx, L"location", Extension::INTERNAL); |
| 727 } | 721 } |
| 728 | 722 |
| 729 // Tests loading single extensions (like --load-extension) | 723 // Tests loading single extensions (like --load-extension) |
| 730 TEST_F(ExtensionsServiceTest, LoadExtension) { | 724 TEST_F(ExtensionsServiceTest, LoadExtension) { |
| 731 FilePath extensions_path; | 725 FilePath extensions_path; |
| 732 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); | 726 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); |
| 733 extensions_path = extensions_path.AppendASCII("extensions"); | 727 extensions_path = extensions_path.AppendASCII("extensions"); |
| 734 | 728 |
| 735 FilePath ext1 = extensions_path.AppendASCII("good").AppendASCII("extension1") | 729 FilePath ext1 = extensions_path.AppendASCII("good") |
| 736 .AppendASCII("1"); | 730 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") |
| 731 .AppendASCII("1.0.0.0"); |
| 737 service_->LoadExtension(ext1); | 732 service_->LoadExtension(ext1); |
| 738 loop_.RunAllPending(); | 733 loop_.RunAllPending(); |
| 739 EXPECT_EQ(0u, GetErrors().size()); | 734 EXPECT_EQ(0u, GetErrors().size()); |
| 740 ASSERT_EQ(1u, loaded_.size()); | 735 ASSERT_EQ(1u, loaded_.size()); |
| 741 ASSERT_EQ(Extension::LOAD, loaded_[0]->location()); | 736 ASSERT_EQ(Extension::LOAD, loaded_[0]->location()); |
| 742 | 737 |
| 743 ValidatePrefKeyCount(1); | 738 ValidatePrefKeyCount(1); |
| 744 ValidatePref(good0, L"state", Extension::ENABLED); | 739 ValidatePref(good0, L"state", Extension::ENABLED); |
| 745 ValidatePref(good0, L"location", Extension::INTERNAL); | 740 ValidatePref(good0, L"location", Extension::INTERNAL); |
| 746 | 741 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 774 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); | 769 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); |
| 775 extensions_path = extensions_path.AppendASCII("extensions"); | 770 extensions_path = extensions_path.AppendASCII("extensions"); |
| 776 | 771 |
| 777 FilePath no_id_ext = extensions_path.AppendASCII("no_id"); | 772 FilePath no_id_ext = extensions_path.AppendASCII("no_id"); |
| 778 service_->LoadExtension(no_id_ext); | 773 service_->LoadExtension(no_id_ext); |
| 779 loop_.RunAllPending(); | 774 loop_.RunAllPending(); |
| 780 EXPECT_EQ(0u, GetErrors().size()); | 775 EXPECT_EQ(0u, GetErrors().size()); |
| 781 ASSERT_EQ(1u, loaded_.size()); | 776 ASSERT_EQ(1u, loaded_.size()); |
| 782 std::string id1 = loaded_[0]->id(); | 777 std::string id1 = loaded_[0]->id(); |
| 783 ASSERT_EQ(all_zero, id1); | 778 ASSERT_EQ(all_zero, id1); |
| 784 ASSERT_EQ("chrome-extension://0000000000000000000000000000000000000000/", | 779 ASSERT_EQ("chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/", |
| 785 loaded_[0]->url().spec()); | 780 loaded_[0]->url().spec()); |
| 786 | 781 |
| 787 ValidatePrefKeyCount(1); | 782 ValidatePrefKeyCount(1); |
| 788 ValidatePref(all_zero, L"state", Extension::ENABLED); | 783 ValidatePref(all_zero, L"state", Extension::ENABLED); |
| 789 ValidatePref(all_zero, L"location", Extension::INTERNAL); | 784 ValidatePref(all_zero, L"location", Extension::INTERNAL); |
| 790 | 785 |
| 791 service_->LoadExtension(no_id_ext); | 786 service_->LoadExtension(no_id_ext); |
| 792 loop_.RunAllPending(); | 787 loop_.RunAllPending(); |
| 793 std::string id2 = loaded_[1]->id(); | 788 std::string id2 = loaded_[1]->id(); |
| 794 ASSERT_EQ(zero_n_one, id2); | 789 ASSERT_EQ(zero_n_one, id2); |
| 795 ASSERT_EQ("chrome-extension://0000000000000000000000000000000000000001/", | 790 ASSERT_EQ("chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab/", |
| 796 loaded_[1]->url().spec()); | 791 loaded_[1]->url().spec()); |
| 797 | 792 |
| 798 ValidatePrefKeyCount(2); | 793 ValidatePrefKeyCount(2); |
| 799 ValidatePref(zero_n_one, L"state", Extension::ENABLED); | 794 ValidatePref(zero_n_one, L"state", Extension::ENABLED); |
| 800 ValidatePref(zero_n_one, L"location", Extension::INTERNAL); | 795 ValidatePref(zero_n_one, L"location", Extension::INTERNAL); |
| 801 } | 796 } |
| 802 | 797 |
| 803 // Tests the external installation feature | 798 // Tests the external installation feature |
| 804 #if defined(OS_WIN) | 799 #if defined(OS_WIN) |
| 805 | 800 |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 ValidatePrefKeyCount(1); | 1002 ValidatePrefKeyCount(1); |
| 1008 ValidatePref(good_crx, L"state", Extension::KILLBIT); | 1003 ValidatePref(good_crx, L"state", Extension::KILLBIT); |
| 1009 ValidatePref(good_crx, L"location", Extension::EXTERNAL_PREF); | 1004 ValidatePref(good_crx, L"location", Extension::EXTERNAL_PREF); |
| 1010 | 1005 |
| 1011 // The extension should also be gone from disk. | 1006 // The extension should also be gone from disk. |
| 1012 FilePath extension_path = install_path.DirName(); | 1007 FilePath extension_path = install_path.DirName(); |
| 1013 extension_path = extension_path.AppendASCII(good_crx); | 1008 extension_path = extension_path.AppendASCII(good_crx); |
| 1014 EXPECT_FALSE(file_util::PathExists(extension_path)) << | 1009 EXPECT_FALSE(file_util::PathExists(extension_path)) << |
| 1015 extension_path.ToWStringHack(); | 1010 extension_path.ToWStringHack(); |
| 1016 } | 1011 } |
| OLD | NEW |