| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "extensions/common/manifest_url_handlers.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/files/file_util.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "extensions/common/error_utils.h" |
| #include "extensions/common/extension_urls.h" |
| #include "extensions/common/file_util.h" |
| #include "extensions/common/manifest.h" |
| #include "extensions/common/manifest_constants.h" |
| #include "extensions/common/manifest_handlers/shared_module_info.h" |
| #include "extensions/strings/grit/extensions_strings.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| namespace extensions { |
| |
| namespace keys = manifest_keys; |
| namespace errors = manifest_errors; |
| |
| // static |
| const GURL& ManifestURL::Get(const Extension* extension, |
| const std::string& key) { |
| ManifestURL* manifest_url = |
| static_cast<ManifestURL*>(extension->GetManifestData(key)); |
| return manifest_url ? manifest_url->url_ : GURL::EmptyGURL(); |
| } |
| |
| // static |
| const GURL ManifestURL::GetHomepageURL(const Extension* extension) { |
| const GURL& homepage_url = Get(extension, keys::kHomepageURL); |
| if (homepage_url.is_valid()) |
| return homepage_url; |
| return GetWebStoreURL(extension); |
| } |
| |
| // static |
| bool ManifestURL::SpecifiedHomepageURL(const Extension* extension) { |
| return Get(extension, keys::kHomepageURL).is_valid(); |
| } |
| |
| // static |
| const GURL ManifestURL::GetManifestHomePageURL(const Extension* extension) { |
| const GURL& homepage_url = Get(extension, keys::kHomepageURL); |
| return homepage_url.is_valid() ? homepage_url : GURL::EmptyGURL(); |
| } |
| |
| // static |
| const GURL ManifestURL::GetWebStoreURL(const Extension* extension) { |
| bool use_webstore_url = UpdatesFromGallery(extension) && |
| !SharedModuleInfo::IsSharedModule(extension); |
| return use_webstore_url |
| ? GURL(extension_urls::GetWebstoreItemDetailURLPrefix() + |
| extension->id()) |
| : GURL::EmptyGURL(); |
| } |
| |
| // static |
| const GURL& ManifestURL::GetUpdateURL(const Extension* extension) { |
| return Get(extension, keys::kUpdateURL); |
| } |
| |
| // static |
| bool ManifestURL::UpdatesFromGallery(const Extension* extension) { |
| return extension_urls::IsWebstoreUpdateUrl(GetUpdateURL(extension)); |
| } |
| |
| // static |
| bool ManifestURL::UpdatesFromGallery(const base::DictionaryValue* manifest) { |
| std::string url; |
| if (!manifest->GetString(keys::kUpdateURL, &url)) |
| return false; |
| return extension_urls::IsWebstoreUpdateUrl(GURL(url)); |
| } |
| |
| // static |
| const GURL& ManifestURL::GetAboutPage(const Extension* extension) { |
| return Get(extension, keys::kAboutPage); |
| } |
| |
| // static |
| const GURL ManifestURL::GetDetailsURL(const Extension* extension) { |
| return extension->from_webstore() ? |
| GURL(extension_urls::GetWebstoreItemDetailURLPrefix() + extension->id()) : |
| GURL::EmptyGURL(); |
| } |
| |
| HomepageURLHandler::HomepageURLHandler() { |
| } |
| |
| HomepageURLHandler::~HomepageURLHandler() { |
| } |
| |
| bool HomepageURLHandler::Parse(Extension* extension, base::string16* error) { |
| std::unique_ptr<ManifestURL> manifest_url(new ManifestURL); |
| std::string homepage_url_str; |
| if (!extension->manifest()->GetString(keys::kHomepageURL, |
| &homepage_url_str)) { |
| *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidHomepageURL, |
| std::string()); |
| return false; |
| } |
| manifest_url->url_ = GURL(homepage_url_str); |
| if (!manifest_url->url_.is_valid() || |
| !manifest_url->url_.SchemeIsHTTPOrHTTPS()) { |
| *error = ErrorUtils::FormatErrorMessageUTF16( |
| errors::kInvalidHomepageURL, homepage_url_str); |
| return false; |
| } |
| extension->SetManifestData(keys::kHomepageURL, std::move(manifest_url)); |
| return true; |
| } |
| |
| base::span<const char* const> HomepageURLHandler::Keys() const { |
| static constexpr const char* kKeys[] = {keys::kHomepageURL}; |
| return kKeys; |
| } |
| |
| UpdateURLHandler::UpdateURLHandler() { |
| } |
| |
| UpdateURLHandler::~UpdateURLHandler() { |
| } |
| |
| bool UpdateURLHandler::Parse(Extension* extension, base::string16* error) { |
| std::unique_ptr<ManifestURL> manifest_url(new ManifestURL); |
| std::string tmp_update_url; |
| |
| if (!extension->manifest()->GetString(keys::kUpdateURL, &tmp_update_url)) { |
| *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidUpdateURL, |
| std::string()); |
| return false; |
| } |
| |
| manifest_url->url_ = GURL(tmp_update_url); |
| if (!manifest_url->url_.is_valid() || |
| manifest_url->url_.has_ref()) { |
| *error = ErrorUtils::FormatErrorMessageUTF16( |
| errors::kInvalidUpdateURL, tmp_update_url); |
| return false; |
| } |
| |
| extension->SetManifestData(keys::kUpdateURL, std::move(manifest_url)); |
| return true; |
| } |
| |
| base::span<const char* const> UpdateURLHandler::Keys() const { |
| static constexpr const char* kKeys[] = {keys::kUpdateURL}; |
| return kKeys; |
| } |
| |
| AboutPageHandler::AboutPageHandler() { |
| } |
| |
| AboutPageHandler::~AboutPageHandler() { |
| } |
| |
| bool AboutPageHandler::Parse(Extension* extension, base::string16* error) { |
| std::unique_ptr<ManifestURL> manifest_url(new ManifestURL); |
| std::string about_str; |
| if (!extension->manifest()->GetString(keys::kAboutPage, &about_str)) { |
| *error = base::ASCIIToUTF16(errors::kInvalidAboutPage); |
| return false; |
| } |
| |
| GURL absolute(about_str); |
| if (absolute.is_valid()) { |
| *error = base::ASCIIToUTF16(errors::kInvalidAboutPageExpectRelativePath); |
| return false; |
| } |
| manifest_url->url_ = extension->GetResourceURL(about_str); |
| if (!manifest_url->url_.is_valid()) { |
| *error = base::ASCIIToUTF16(errors::kInvalidAboutPage); |
| return false; |
| } |
| extension->SetManifestData(keys::kAboutPage, std::move(manifest_url)); |
| return true; |
| } |
| |
| bool AboutPageHandler::Validate(const Extension* extension, |
| std::string* error, |
| std::vector<InstallWarning>* warnings) const { |
| // Validate path to the options page. |
| if (!extensions::ManifestURL::GetAboutPage(extension).is_empty()) { |
| const base::FilePath about_path = |
| extensions::file_util::ExtensionURLToRelativeFilePath( |
| extensions::ManifestURL::GetAboutPage(extension)); |
| const base::FilePath path = |
| extension->GetResource(about_path).GetFilePath(); |
| if (path.empty() || !base::PathExists(path)) { |
| *error = l10n_util::GetStringFUTF8(IDS_EXTENSION_LOAD_ABOUT_PAGE_FAILED, |
| about_path.LossyDisplayName()); |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| base::span<const char* const> AboutPageHandler::Keys() const { |
| static constexpr const char* kKeys[] = {keys::kAboutPage}; |
| return kKeys; |
| } |
| |
| } // namespace extensions |