From bcd988c53c41408e80e4431ee780568563eac800 Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Fri, 17 Aug 2018 22:50:56 -0400 Subject: [PATCH] Redirect users to extension store for inline install requests Fix https://github.com/brave/brave-browser/issues/614 --- browser/extensions/BUILD.gn | 2 + .../brave_webstore_inline_installer.cc | 42 +++++++++++++ .../brave_webstore_inline_installer.h | 34 +++++++++++ ...e_webstore_inline_installer_browsertest.cc | 61 +++++++++++++++++++ ...webstore_inline_installer_factory.cc.patch | 23 +++++++ test/BUILD.gn | 1 + 6 files changed, 163 insertions(+) create mode 100644 browser/extensions/brave_webstore_inline_installer.cc create mode 100644 browser/extensions/brave_webstore_inline_installer.h create mode 100644 browser/extensions/brave_webstore_inline_installer_browsertest.cc create mode 100644 patches/chrome-browser-extensions-webstore_inline_installer_factory.cc.patch diff --git a/browser/extensions/BUILD.gn b/browser/extensions/BUILD.gn index 42fc1e5c68bc..ac72d42fdaf2 100644 --- a/browser/extensions/BUILD.gn +++ b/browser/extensions/BUILD.gn @@ -18,6 +18,8 @@ source_set("extensions") { "brave_extension_provider.h", "brave_tor_client_updater.cc", "brave_tor_client_updater.h", + "brave_webstore_inline_installer.cc", + "brave_webstore_inline_installer.h", ] deps = [ diff --git a/browser/extensions/brave_webstore_inline_installer.cc b/browser/extensions/brave_webstore_inline_installer.cc new file mode 100644 index 000000000000..e9be1e67f9fe --- /dev/null +++ b/browser/extensions/brave_webstore_inline_installer.cc @@ -0,0 +1,42 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/extensions/brave_webstore_inline_installer.h" + +#include "base/strings/stringprintf.h" +#include "base/values.h" +#include "content/public/browser/web_contents.h" + +namespace extensions { + +// The URL to the webstore page for a specific app. +const char kWebstoreUrlFormat[] = + "https://chrome.google.com/webstore/detail/%s"; + +BraveWebstoreInlineInstaller::BraveWebstoreInlineInstaller( + content::WebContents* web_contents, + content::RenderFrameHost* host, + const std::string& webstore_item_id, + const GURL& requestor_url, + const Callback& callback) + : WebstoreInlineInstaller(web_contents, host, + webstore_item_id, requestor_url, callback) { +} + +BraveWebstoreInlineInstaller::~BraveWebstoreInlineInstaller() {} + +bool BraveWebstoreInlineInstaller::CheckInlineInstallPermitted( + const base::DictionaryValue& webstore_data, + std::string* error) const { + // Open a URL corresponding to the extension ID. + GURL url(base::StringPrintf(kWebstoreUrlFormat, id().c_str())); + web_contents()->OpenURL(content::OpenURLParams( + url, content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_LINK, false)); + // Return an error so nothing else is processed + *error = kInlineInstallNotSupportedKey; + return false; +} + +} // namespace extensions diff --git a/browser/extensions/brave_webstore_inline_installer.h b/browser/extensions/brave_webstore_inline_installer.h new file mode 100644 index 000000000000..c09101bd22a0 --- /dev/null +++ b/browser/extensions/brave_webstore_inline_installer.h @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_EXTENSIONS_BRAVE_WEBSTORE_INLINE_INSTALLER_H_ +#define BRAVE_BROWSER_EXTENSIONS_BRAVE_WEBSTORE_INLINE_INSTALLER_H_ + +class BraveWebstoreBrowserTest; + +#include "chrome/browser/extensions/webstore_inline_installer.h" + +namespace extensions { + +extern const char kWebstoreUrlFormat[]; + +class BraveWebstoreInlineInstaller : public WebstoreInlineInstaller { + public: + BraveWebstoreInlineInstaller(content::WebContents* web_contents, + content::RenderFrameHost* host, + const std::string& webstore_item_id, + const GURL& requestor_url, + const Callback& callback); + + protected: + ~BraveWebstoreInlineInstaller() override; + friend class ::BraveWebstoreBrowserTest; + bool CheckInlineInstallPermitted(const base::DictionaryValue& webstore_data, + std::string* error) const override; + DISALLOW_IMPLICIT_CONSTRUCTORS(BraveWebstoreInlineInstaller); +}; + +} // namespace extensions + +#endif // BRAVE_BROWSER_EXTENSIONS_BRAVE_WEBSTORE_INLINE_INSTALLER_H_ diff --git a/browser/extensions/brave_webstore_inline_installer_browsertest.cc b/browser/extensions/brave_webstore_inline_installer_browsertest.cc new file mode 100644 index 000000000000..e26204c68f36 --- /dev/null +++ b/browser/extensions/brave_webstore_inline_installer_browsertest.cc @@ -0,0 +1,61 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/extensions/brave_webstore_inline_installer.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test_utils.h" + +void OnInstalled(bool success, const std::string& error, + extensions::webstore_install::Result result) { +} + +class BraveWebstoreBrowserTest : public InProcessBrowserTest { + public: + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + extension_id_ = "apdfllckaahabafndbhieahigkjlhalf"; + } + + content::WebContents* contents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + bool NavigateToURLUntilLoadStop(const GURL& url) { + ui_test_utils::NavigateToURL(browser(), url); + return WaitForLoadStop(contents()); + } + + int GetTabCount() const { + return browser()->tab_strip_model()->count(); + } + + bool CheckInlineInstallPermitted() { + base::DictionaryValue webstore_data; + std::string err; + auto* installer = new extensions::BraveWebstoreInlineInstaller(contents(), + contents()->GetMainFrame(), extension_id(), GURL(), + base::Bind(&OnInstalled)); + return installer->CheckInlineInstallPermitted(webstore_data, &err); + } + + std::string extension_id() const { + return extension_id_; + } + + protected: + std::string extension_id_; +}; + +IN_PROC_BROWSER_TEST_F(BraveWebstoreBrowserTest, + RedirectsUserToChromeWebStore) { + // Inline install should not be permitted. + ASSERT_FALSE(CheckInlineInstallPermitted()); + // Inline install should create a second tab for the web-contents. + GURL url(base::StringPrintf(extensions::kWebstoreUrlFormat, + extension_id().c_str())); + ASSERT_EQ(GetTabCount(), 2); + ASSERT_STREQ(browser()->tab_strip_model()->GetWebContentsAt(1)->GetVisibleURL().spec().c_str(), url.spec().c_str()); +} diff --git a/patches/chrome-browser-extensions-webstore_inline_installer_factory.cc.patch b/patches/chrome-browser-extensions-webstore_inline_installer_factory.cc.patch new file mode 100644 index 000000000000..827a12738b22 --- /dev/null +++ b/patches/chrome-browser-extensions-webstore_inline_installer_factory.cc.patch @@ -0,0 +1,23 @@ +diff --git a/chrome/browser/extensions/webstore_inline_installer_factory.cc b/chrome/browser/extensions/webstore_inline_installer_factory.cc +index 39e0b83a7aa1b2b75fa412a762134a163e3ae0d7..b61d998422a012fb7bdbe623108cc16b211eac1e 100644 +--- a/chrome/browser/extensions/webstore_inline_installer_factory.cc ++++ b/chrome/browser/extensions/webstore_inline_installer_factory.cc +@@ -6,6 +6,7 @@ + + #include + ++#include "brave/browser/extensions/brave_webstore_inline_installer.h" + #include "chrome/browser/extensions/webstore_inline_installer.h" + #include "content/public/browser/web_contents.h" + +@@ -17,8 +18,8 @@ WebstoreInlineInstaller* WebstoreInlineInstallerFactory::CreateInstaller( + const std::string& webstore_item_id, + const GURL& requestor_url, + const WebstoreStandaloneInstaller::Callback& callback) { +- return new WebstoreInlineInstaller(contents, host, webstore_item_id, +- requestor_url, callback); ++ return new BraveWebstoreInlineInstaller(contents, host, webstore_item_id, ++ requestor_url, callback); + } + + } // namespace extensions diff --git a/test/BUILD.gn b/test/BUILD.gn index b531048a80a6..2dbfe4e09340 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -158,6 +158,7 @@ test("brave_browser_tests") { "//brave/browser/brave_resources_browsertest.cc", "//brave/browser/extensions/brave_tor_client_updater_browsertest.cc", "//brave/browser/extensions/api/brave_shields_api_browsertest.cc", + "//brave/browser/extensions/brave_webstore_inline_installer_browsertest.cc", "//brave/browser/ui/content_settings/brave_autoplay_blocked_image_model_browsertest.cc", "//brave/browser/ui/content_settings/brave_widevine_blocked_image_model_browsertest.cc", "//brave/browser/ui/webui/brave_new_tab_ui_browsertest.cc",