Commit 17ec7e69 authored by Raymes Khoury's avatar Raymes Khoury Committed by Commit Bot

Whitelist usage of management.installReplacementWebApp

This whitelists management.installReplacementWebApp to specific
extensions as restrictions to ensure apps are related aren't yet
implemented on the Webstore.

For tests we need to generate manifest.json files based on the URL of
the related app. Hence we can't check in a static crx/extension. This
means that we need to provide a private key when generating the crx to
ensure that the extension ID stays the same across test runs.

Bug: 968407
Change-Id: Ieceadeaf59011b7209fece3de06e89f2bea4b9e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1635118
Commit-Queue: Raymes Khoury <raymes@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarBen Wells <benwells@chromium.org>
Cr-Commit-Position: refs/heads/master@{#665044}
parent 1a737994
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
#include "extensions/browser/test_management_policy.h" #include "extensions/browser/test_management_policy.h"
#include "extensions/common/manifest.h" #include "extensions/common/manifest.h"
#include "extensions/common/switches.h"
#include "extensions/test/extension_test_message_listener.h" #include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h" #include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h" #include "extensions/test/test_extension_dir.h"
...@@ -163,9 +164,17 @@ class InstallReplacementWebAppApiTest : public ExtensionManagementApiTest { ...@@ -163,9 +164,17 @@ class InstallReplacementWebAppApiTest : public ExtensionManagementApiTest {
ASSERT_TRUE(https_test_server_.Start()); ASSERT_TRUE(https_test_server_.Start());
} }
void SetUpCommandLine(base::CommandLine* command_line) override {
ExtensionManagementApiTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(
extensions::switches::kWhitelistedExtensionID,
"odfeghegfpmohakomgihhcnoboeecemb");
}
void RunTest(const char* web_app_path, void RunTest(const char* web_app_path,
const char* background_script, const char* background_script,
bool from_webstore) { bool from_webstore,
bool whitelisted) {
static constexpr char kManifest[] = static constexpr char kManifest[] =
R"({ R"({
"name": "Management API Test", "name": "Management API Test",
...@@ -174,19 +183,56 @@ class InstallReplacementWebAppApiTest : public ExtensionManagementApiTest { ...@@ -174,19 +183,56 @@ class InstallReplacementWebAppApiTest : public ExtensionManagementApiTest {
"background": { "scripts": ["background.js"] }, "background": { "scripts": ["background.js"] },
"replacement_web_app": "%s" "replacement_web_app": "%s"
})"; })";
static constexpr char kPem[] =
"-----BEGIN PRIVATE KEY-----"
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCs5ycnzJEUSwlN"
"U7yAuywl8vro4dXew7Eijdd+gYwHAtaQyKxpeJHy09eusWKTfHEaOdqfqssqPMnl"
"XqoC+Tyt/24xM6rw6uSyAV78DRSAl7AxiyemxTh5P2rzaN4ytJayLpZDzwi38zeZ"
"QJC4TcSk04bclB2zfLFmMe8W53oxdE8vV6Xa2TPFigR6PV0FcRE40cCPHFhRTDwz"
"C04b/qW30Ceix2AeLPT4+qsGroq5kLt7zTgvaA+QToKeZNX41snk1w2u/IhOXG+J"
"0jyZnFU1lgnA9ScMW0laA+Ba2WXB5tLPgyRyyABRRaT5oiJCxRLQc+HFnMdUftGK"
"D4MKnf+/AgMBAAECggEADJ+/8x7zhMjJwBSaEcgYvBiWi0RZ6i7dkwlKL5lj0Os7"
"IU0VkYnVFiaze7TF3sDaPTD2Lmw48zeHAjE8NoVeEdIxiHQeSgLMedaxybNmyNDK"
"c4OWfI2vxuKDe4wvlQIscowGOqM2HsAqUg0tw9chwWsUUKyb0owLI8wHieOSv2OA"
"w8UlhflqkXLBUc4Mx3iqkIwAyrxQXT/vlA0M8/QvikK/zfeZYZ4f8tg23m3T0fV3"
"HC4k/Q09MFyUvURVYNpbPHrL83/ZbaHBniEjy+qBX4POO4xrKhow77tr/znB8bsA"
"T3mRwrEnYoIZmkwxlAdOMNxSYcAKZh4jPWOut0VQ0QKBgQDk341ysCaNzRq7nscR"
"RzDtpAA+UPcS2vcssXKDRjhsTp31qsUsVsYjTX+O/sv2uyb4HikYiFZOe3iPIfOl"
"ni7ZfhYFMMIZFjjP0cjQ7C/+ArxGb96DcTbRf7SNTDOLTtZy1jZSgIRek+2vvcr1"
"a/xPUMCxLEZdUPu+AVhKYHKHOQKBgQDBZVr04r4s5/BygRR3NhFgquI8ffdPHZzC"
"riEO1X/YOucTs+F+qwTvr25kRozpEjFsZJUibJTDngX9OziatAQdnjt5CtabOXd/"
"1rSgUadWEvRrcy/aaouCE1J+1unX6Kk5RHmIsK1YP3wC6JrHmqfnEVq9kaoUubTC"
"WHZfgjQGtwKBgF3B0nD8Bh8quVvIlGXYkwuWll7wzfYUaxMM8gsi1fRQVFcSCMm8"
"FljZ43pRmH5PdoxH1q/tEeX+oImJ8ASVgz2ncB/aNHkQaF+B4dDsIFDfD/+Ozkls"
"NHen5+/GGotj1WefpwsvCIqx8LmAd0cIYIihXP53U6/gf+/7Hw8A6YnJAoGAEbhs"
"xiWEkW7LLGLBck7k9ruRsUNFht1KwNfdtZNAfJqhE8AWuFmJQUEM12lTfgOpvanV"
"tGrIksgG+nYTsLEv81rNTkD8+wof9fnBYTM6Jvvjo3jReKzsjYWhuHeOw7bQ0quA"
"i1LM/1oJzeZsUD/OhLClZNtU/0Mo2enrJsMyay8CgYEApCQ8BDMYewQj2MCM92Vw"
"DWDzqQpfaGIG/eDAeEtdicbfdih3zUWfhEVOpnvf7s7nS8bMVpAo9pGW6sT/s8eX"
"POGiP9efxb2uHsX06pkAYZm9nddIliWnm0/eDBmSSXPymAZaNYFrex4wxMII20K/"
"ZX1nuseC+Lx0yzxa/c+iCWg="
"-----END PRIVATE KEY-----";
extensions::TestExtensionDir extension_dir; extensions::TestExtensionDir extension_dir;
extension_dir.WriteManifest(base::StringPrintf( extension_dir.WriteManifest(base::StringPrintf(
kManifest, https_test_server_.GetURL(web_app_path).spec().c_str())); kManifest, https_test_server_.GetURL(web_app_path).spec().c_str()));
extension_dir.WriteFile(FILE_PATH_LITERAL("background.js"), extension_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
background_script); background_script);
base::FilePath crx;
if (whitelisted)
crx = extension_dir.PackWithPem(kPem);
else
crx = extension_dir.Pack();
extensions::ResultCatcher catcher; extensions::ResultCatcher catcher;
if (from_webstore) { if (from_webstore) {
// |expected_change| is the expected change in the number of installed // |expected_change| is the expected change in the number of installed
// extensions. // extensions.
ASSERT_TRUE(InstallExtensionFromWebstore(extension_dir.UnpackedPath(), ASSERT_TRUE(InstallExtensionFromWebstore(crx, 1 /* expected_change */));
1 /* expected_change */));
} else { } else {
ASSERT_TRUE(LoadExtension(extension_dir.UnpackedPath())); ASSERT_TRUE(LoadExtension(crx));
} }
ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
...@@ -195,6 +241,16 @@ class InstallReplacementWebAppApiTest : public ExtensionManagementApiTest { ...@@ -195,6 +241,16 @@ class InstallReplacementWebAppApiTest : public ExtensionManagementApiTest {
net::EmbeddedTestServer https_test_server_; net::EmbeddedTestServer https_test_server_;
}; };
IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotWhitelisted) {
static constexpr char kBackground[] = R"(
chrome.test.assertEq(undefined, chrome.management.installReplacementWebApp);
chrome.test.notifyPass();
)";
RunTest("/management/install_replacement_web_app/good_web_app/index.html",
kBackground, true /* from_webstore */, false /* whitelisted */);
}
IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotWebstore) { IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotWebstore) {
static constexpr char kBackground[] = R"( static constexpr char kBackground[] = R"(
chrome.management.installReplacementWebApp(function() { chrome.management.installReplacementWebApp(function() {
...@@ -204,7 +260,7 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotWebstore) { ...@@ -204,7 +260,7 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotWebstore) {
});)"; });)";
RunTest("/management/install_replacement_web_app/good_web_app/index.html", RunTest("/management/install_replacement_web_app/good_web_app/index.html",
kBackground, false /* from_webstore */); kBackground, false /* from_webstore */, true /* whitelisted */);
} }
IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NoGesture) { IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NoGesture) {
...@@ -216,7 +272,7 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NoGesture) { ...@@ -216,7 +272,7 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NoGesture) {
});)"; });)";
RunTest("/management/install_replacement_web_app/good_web_app/index.html", RunTest("/management/install_replacement_web_app/good_web_app/index.html",
kBackground, true /* from_webstore */); kBackground, true /* from_webstore */, true /* whitelisted */);
} }
IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotInstallableWebApp) { IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotInstallableWebApp) {
...@@ -230,7 +286,7 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotInstallableWebApp) { ...@@ -230,7 +286,7 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, NotInstallableWebApp) {
});)"; });)";
RunTest("/management/install_replacement_web_app/bad_web_app/index.html", RunTest("/management/install_replacement_web_app/bad_web_app/index.html",
kBackground, true /* from_webstore */); kBackground, true /* from_webstore */, true /* whitelisted */);
} }
IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, InstallableWebApp) { IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, InstallableWebApp) {
...@@ -264,7 +320,8 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, InstallableWebApp) { ...@@ -264,7 +320,8 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, InstallableWebApp) {
web_app::WebAppProviderBase::GetProviderBase(browser()->profile()); web_app::WebAppProviderBase::GetProviderBase(browser()->profile());
EXPECT_FALSE(provider->registrar().IsInstalled(good_web_app_url)); EXPECT_FALSE(provider->registrar().IsInstalled(good_web_app_url));
RunTest(kGoodWebAppURL, kBackground, true /* from_webstore */); RunTest(kGoodWebAppURL, kBackground, true /* from_webstore */,
true /* whitelisted */);
EXPECT_TRUE(provider->registrar().IsInstalled(good_web_app_url)); EXPECT_TRUE(provider->registrar().IsInstalled(good_web_app_url));
chrome::SetAutoAcceptPWAInstallConfirmationForTesting(false); chrome::SetAutoAcceptPWAInstallConfirmationForTesting(false);
} }
......
...@@ -298,7 +298,16 @@ ...@@ -298,7 +298,16 @@
"management.installReplacementWebApp": { "management.installReplacementWebApp": {
"dependencies": ["manifest:replacement_web_app"], "dependencies": ["manifest:replacement_web_app"],
"channel": "stable", "channel": "stable",
"extension_types": ["extension"] "extension_types": ["extension"],
"whitelist": [
"E7E2461CE072DF036CF9592740196159E2D7C089", // https://crbug.com/968407
"A74A4D44C7CFCD8844830E6140C8D763E12DD8F3", // https://crbug.com/968407
"312745D9BF916161191143F6490085EEA0434997", // https://crbug.com/968407
"53041A2FA309EECED01FFC751E7399186E860B2C", // https://crbug.com/968407
"A07A5B743CD82A1C2579DB77D353C98A23201EEF", // https://crbug.com/968407
"2D22CDB6583FD0A13758AEBE8B15E45208B4E9A7", // https://crbug.com/968407
"0F42756099D914A026DADFA182871C015735DD95" // https://crbug.com/968407
]
}, },
"management.uninstallSelf": { "management.uninstallSelf": {
"dependencies": [], "dependencies": [],
......
...@@ -46,15 +46,21 @@ void TestExtensionDir::WriteFile(const base::FilePath::StringType& filename, ...@@ -46,15 +46,21 @@ void TestExtensionDir::WriteFile(const base::FilePath::StringType& filename,
contents.size())); contents.size()));
} }
// This function packs the extension into a .crx, and returns the path to that
// .crx. Multiple calls to Pack() will produce extensions with the same ID.
base::FilePath TestExtensionDir::Pack() { base::FilePath TestExtensionDir::Pack() {
return PackWithPem(base::StringPiece());
}
base::FilePath TestExtensionDir::PackWithPem(base::StringPiece pem) {
base::ScopedAllowBlockingForTesting allow_blocking; base::ScopedAllowBlockingForTesting allow_blocking;
ExtensionCreator creator; ExtensionCreator creator;
base::FilePath crx_path = base::FilePath crx_path =
crx_dir_.GetPath().Append(FILE_PATH_LITERAL("ext.crx")); crx_dir_.GetPath().Append(FILE_PATH_LITERAL("ext.crx"));
base::FilePath pem_path = base::FilePath pem_path =
crx_dir_.GetPath().Append(FILE_PATH_LITERAL("ext.pem")); crx_dir_.GetPath().Append(FILE_PATH_LITERAL("ext.pem"));
if (!pem.empty())
base::WriteFile(pem_path, pem.data(), pem.size());
base::FilePath pem_in_path, pem_out_path; base::FilePath pem_in_path, pem_out_path;
if (base::PathExists(pem_path)) if (base::PathExists(pem_path))
pem_in_path = pem_path; pem_in_path = pem_path;
......
...@@ -38,6 +38,9 @@ class TestExtensionDir { ...@@ -38,6 +38,9 @@ class TestExtensionDir {
// .crx. Multiple calls to Pack() will produce extensions with the same ID. // .crx. Multiple calls to Pack() will produce extensions with the same ID.
base::FilePath Pack(); base::FilePath Pack();
// The same as Pack() but allows the caller to provide a private key.
base::FilePath PackWithPem(base::StringPiece pem);
// Returns the path to the unpacked directory. // Returns the path to the unpacked directory.
base::FilePath UnpackedPath(); base::FilePath UnpackedPath();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment