Chromium Code Reviews| Index: chrome/browser/extensions/extension_webstore_private_api.cc |
| diff --git a/chrome/browser/extensions/extension_webstore_private_api.cc b/chrome/browser/extensions/extension_webstore_private_api.cc |
| index 3e9a605cfaa4274808788940b089f9da654d5eee..2df362fb106e8ddf76d209ef4b092306c0a1bb28 100644 |
| --- a/chrome/browser/extensions/extension_webstore_private_api.cc |
| +++ b/chrome/browser/extensions/extension_webstore_private_api.cc |
| @@ -73,6 +73,23 @@ bool IsWebStoreURL(Profile* profile, const GURL& url) { |
| return (service->GetExtensionByWebExtent(url) == store); |
| } |
| +// Whitelists extension IDs for use by webstorePrivate.silentlyInstall. |
| +const char* test_trusted_id = NULL; |
| + |
| +bool IsTrustedForSilentInstall(const std::string& id) { |
| + return (test_trusted_id && id == std::string(test_trusted_id)) || |
| + id == std::string("jgoepmocgafhnchmokaimcmlojpnlkhp") || |
|
Aaron Boodman
2011/11/01 17:24:34
Nit: I don't think you need the std::string wrappe
jstritar
2011/11/01 19:43:05
Done.
|
| + id == std::string("cpembckmhnjipbgbnfiocbgnkpjdokdd") || |
| + id == std::string("boemmnepglcoinjcdlfcpcbmhiecichi") || |
| + id == std::string("flibmgiapaohcbondaoopaalfejliklp") || |
| + id == std::string("dlppkpafhbajpcmmoheippocdidnckmm") || |
| + id == std::string("hmglfmpefabcafaimbpldpambdfomanl") || |
| + id == std::string("idfijlieiecpfcjckpkliefekpokhhnd") || |
| + id == std::string("jaokjbijaokooelpahnlmbciccldmfla") || |
| + id == std::string("kdjeommiakphmeionoojjljlecmpaldd") || |
| + id == std::string("lpdeojkfhenboeibhkjhiancceeboknd"); |
| +} |
| + |
| // Helper to create a dictionary with login and token properties set from |
| // the appropriate values in the passed-in |profile|. |
| DictionaryValue* CreateLoginResult(Profile* profile) { |
| @@ -109,6 +126,11 @@ void WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting( |
| test_webstore_installer_delegate = delegate; |
| } |
| +// static |
| +void WebstorePrivateApi::SetTrustedIDForTesting(const char* extension_id) { |
| + test_trusted_id = extension_id; |
| +} |
| + |
| BeginInstallWithManifestFunction::BeginInstallWithManifestFunction() |
| : use_app_installed_bubble_(false) {} |
| @@ -345,6 +367,115 @@ bool CompleteInstallFunction::RunImpl() { |
| return true; |
| } |
| +SilentlyInstallFunction::SilentlyInstallFunction() {} |
| +SilentlyInstallFunction::~SilentlyInstallFunction() {} |
| + |
| +bool SilentlyInstallFunction::RunImpl() { |
| + if (!IsWebStoreURL(profile_, source_url())) { |
| + SetResult(PERMISSION_DENIED); |
| + return false; |
| + } |
| + |
| + DictionaryValue* details = NULL; |
| + EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
| + CHECK(details); |
| + |
| + EXTENSION_FUNCTION_VALIDATE(details->GetString(kIdKey, &id_)); |
| + if (!IsTrustedForSilentInstall(id_)) { |
| + SetResult(INVALID_ID); |
| + error_ = kInvalidIdError; |
| + return false; |
| + } |
| + |
| + EXTENSION_FUNCTION_VALIDATE(details->GetString(kManifestKey, &manifest_)); |
| + |
| + // Matched in OnWebstoreParseFailure, OnExtensionInstall{Success,Failure}. |
| + AddRef(); |
| + |
| + scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper( |
| + this, id_, manifest_, std::string(), GURL(), NULL); |
| + helper->Start(); |
| + |
| + return true; |
| +} |
| + |
| +void SilentlyInstallFunction::OnWebstoreParseSuccess( |
| + const std::string& id, |
| + const SkBitmap& icon, |
| + base::DictionaryValue* parsed_manifest) { |
| + CHECK_EQ(id_, id); |
| + |
| + // This lets CrxInstaller bypass the permission confirmation UI for the |
| + // extension. The whitelist entry gets cleared in |
| + // CrxInstaller::ConfirmInstall. |
| + CrxInstaller::WhitelistEntry* entry = new CrxInstaller::WhitelistEntry; |
| + entry->parsed_manifest.reset(parsed_manifest); |
| + entry->use_app_installed_bubble = false; |
| + entry->skip_post_install_ui = true; |
| + CrxInstaller::SetWhitelistEntry(id_, entry); |
| + |
| + scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( |
| + profile(), this, |
| + &(dispatcher()->delegate()->GetAssociatedTabContents()->controller()), |
| + id_, WebstoreInstaller::FLAG_NONE); |
| + installer->Start(); |
| +} |
| + |
| +void SilentlyInstallFunction::OnWebstoreParseFailure( |
| + const std::string& id, |
| + InstallHelperResultCode result_code, |
| + const std::string& error_message) { |
| + CHECK_EQ(id_, id); |
| + |
| + // Map from WebstoreInstallHelper's result codes to ours. |
| + if (WebstoreInstallHelper::Delegate::MANIFEST_ERROR) |
|
Aaron Boodman
2011/11/01 17:24:34
I think this will always be true.
jstritar
2011/11/01 19:43:05
Oops, I meant to compare that to result_code. Done
|
| + SetResult(MANIFEST_ERROR); |
| + else |
| + SetResult(UNKNOWN_ERROR); |
| + |
| + error_ = error_message; |
| + SendResponse(false); |
| + |
| + Release(); // Matches the AddRef() in RunImpl(). |
| +} |
| + |
| +void SilentlyInstallFunction::OnExtensionInstallSuccess(const std::string& id) { |
| + CHECK_EQ(id_, id); |
| + SetResult(ERROR_NONE); |
| + SendResponse(true); |
| + |
| + Release(); // Matches the AddRef() in RunImpl(). |
| +} |
| + |
| +void SilentlyInstallFunction::OnExtensionInstallFailure( |
| + const std::string& id, const std::string& error) { |
| + CHECK_EQ(id_, id); |
| + SetResult(UNKNOWN_ERROR); |
| + error_ = error; |
| + SendResponse(false); |
| + |
| + Release(); // Matches the AddRef() in RunImpl(). |
| +} |
| + |
| +void SilentlyInstallFunction::SetResult(ResultCode code) { |
| + switch (code) { |
| + case ERROR_NONE: |
| + result_.reset(Value::CreateStringValue("")); |
| + break; |
| + case UNKNOWN_ERROR: |
| + result_.reset(Value::CreateStringValue("unknown_error")); |
|
Aaron Boodman
2011/11/01 17:24:34
We don't usually send both a result and an error.
jstritar
2011/11/01 19:43:05
I did this to be consistent with BeginInstallWithM
Aaron Boodman
2011/11/02 04:16:55
Less code sgtm
|
| + break; |
| + case INVALID_ID: |
| + result_.reset(Value::CreateStringValue("invalid_id")); |
| + break; |
| + case PERMISSION_DENIED: |
| + result_.reset(Value::CreateStringValue("permission_denied")); |
| + break; |
| + default: |
| + CHECK(false); |
| + } |
| +} |
| + |
| bool GetBrowserLoginFunction::RunImpl() { |
| if (!IsWebStoreURL(profile_, source_url())) |
| return false; |