blob: 9b861c1d385717874cde98c934ee6418c39cadb2 [file] [log] [blame]
[email protected]35385332012-03-28 02:32:031// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]a01e00632010-11-05 16:58:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
mtomaszf7d99a5c2014-09-15 16:23:465#include "chrome/browser/extensions/crx_installer.h"
6
avia2f4804a2015-12-24 23:11:137#include <stddef.h>
dchengc963c7142016-04-08 03:55:228
dcheng1fc00f12015-12-26 22:18:039#include <utility>
avia2f4804a2015-12-24 23:11:1310
[email protected]5a145e82014-05-29 22:19:0711#include "base/at_exit.h"
kalmanae342c92014-12-12 22:04:2312#include "base/files/file_path.h"
Minh X. Nguyen2c17b3982017-10-13 18:32:2913#include "base/files/scoped_temp_dir.h"
avia2f4804a2015-12-24 23:11:1314#include "base/macros.h"
dchengc963c7142016-04-08 03:55:2215#include "base/memory/ptr_util.h"
[email protected]f8636f92013-08-09 21:02:3716#include "base/memory/ref_counted.h"
gabf64a25e2017-05-12 19:42:5617#include "base/message_loop/message_loop.h"
Gabriel Charette53a9ef812017-07-26 12:36:2318#include "base/run_loop.h"
[email protected]253fc2bb2014-07-10 04:21:1819#include "base/strings/utf_string_conversions.h"
jam3f2d3932017-04-26 20:28:5120#include "base/threading/thread_restrictions.h"
avia2f4804a2015-12-24 23:11:1321#include "build/build_config.h"
[email protected]bf2fcd52012-04-16 22:59:3922#include "chrome/browser/download/download_crx_util.h"
[email protected]52b76592013-11-02 17:59:0323#include "chrome/browser/extensions/browser_action_test_util.h"
[email protected]a01e00632010-11-05 16:58:1424#include "chrome/browser/extensions/extension_browsertest.h"
[email protected]c82da8c42012-06-08 19:49:1125#include "chrome/browser/extensions/extension_install_prompt.h"
pkotwicz2f181782014-10-29 17:33:4526#include "chrome/browser/extensions/extension_install_prompt_show_params.h"
[email protected]eaa7dd182010-12-14 11:09:0027#include "chrome/browser/extensions/extension_service.h"
mekc95f9d062015-01-10 00:52:0428#include "chrome/browser/extensions/extension_tab_util.h"
[email protected]658eae52014-06-14 20:28:0529#include "chrome/browser/extensions/extension_util.h"
[email protected]3f2a2fa2013-09-24 02:55:2530#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
gpdavis.chromium48f08c42014-09-18 22:09:3431#include "chrome/browser/extensions/test_extension_dir.h"
[email protected]8ecad5e2010-12-02 21:18:3332#include "chrome/browser/profiles/profile.h"
[email protected]2ad4a902010-11-17 06:05:1333#include "chrome/browser/ui/browser.h"
[email protected]619f86182012-07-03 21:30:1834#include "chrome/browser/ui/browser_window.h"
[email protected]91e51d612012-10-21 23:03:0535#include "chrome/browser/ui/tabs/tab_strip_model.h"
dominickn675536f2015-11-06 03:25:3836#include "chrome/common/web_application_info.h"
[email protected]af39f002014-08-22 10:18:1837#include "chrome/grit/generated_resources.h"
[email protected]af44e7fb2011-07-29 18:32:3238#include "chrome/test/base/ui_test_utils.h"
[email protected]5a145e82014-05-29 22:19:0739#include "content/public/browser/browser_thread.h"
[email protected]f34efa22013-03-05 19:14:2340#include "content/public/browser/download_manager.h"
[email protected]52b76592013-11-02 17:59:0341#include "content/public/browser/render_view_host.h"
[email protected]8ffad4e2014-01-02 23:18:2642#include "content/public/test/browser_test_utils.h"
[email protected]49b264f2012-08-14 17:12:2643#include "content/public/test/download_test_observer.h"
mtomaszf7d99a5c2014-09-15 16:23:4644#include "content/public/test/test_utils.h"
rdevlin.croninca5bf2da2015-12-17 21:21:0845#include "extensions/browser/extension_dialog_auto_confirm.h"
[email protected]dccba4f82014-05-29 00:52:5646#include "extensions/browser/extension_prefs.h"
gpdavis.chromium48f08c42014-09-18 22:09:3447#include "extensions/browser/extension_registry.h"
[email protected]59b0e602014-01-30 00:41:2448#include "extensions/browser/extension_system.h"
ginkage47e603e2015-02-27 08:42:4149#include "extensions/browser/install/crx_install_error.h"
[email protected]253fc2bb2014-07-10 04:21:1850#include "extensions/browser/management_policy.h"
[email protected]adf5a102014-07-31 12:44:0651#include "extensions/browser/notification_types.h"
[email protected]e4452d32013-11-15 23:07:4152#include "extensions/common/extension.h"
Minh X. Nguyen30975342017-12-04 22:02:4153#include "extensions/common/extension_builder.h"
[email protected]5ef835a2013-11-08 20:42:5754#include "extensions/common/feature_switch.h"
[email protected]85df9d12014-04-15 17:02:1455#include "extensions/common/file_util.h"
kalmanae342c92014-12-12 22:04:2356#include "extensions/common/permissions/api_permission.h"
[email protected]5a55f3f2013-10-29 01:08:2957#include "extensions/common/permissions/permission_set.h"
kalmanae342c92014-12-12 22:04:2358#include "extensions/common/permissions/permissions_data.h"
[email protected]c8d02992013-07-31 22:16:5159#include "extensions/common/switches.h"
dominickn675536f2015-11-06 03:25:3860#include "third_party/skia/include/core/SkBitmap.h"
[email protected]a9736892012-05-30 15:58:0561#include "ui/base/l10n/l10n_util.h"
[email protected]a01e00632010-11-05 16:58:1462
[email protected]14a18bf2013-09-26 08:42:3063#if defined(OS_CHROMEOS)
merkulova793f3022015-02-04 10:18:3064#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
[email protected]5a145e82014-05-29 22:19:0765#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
66#include "chromeos/chromeos_switches.h"
Xiyuan Xiadfe3a9f2017-11-13 21:46:2667#include "components/user_manager/scoped_user_manager.h"
[email protected]14a18bf2013-09-26 08:42:3068#endif
69
[email protected]7a5452f2010-12-13 23:03:1970class SkBitmap;
71
dominickn675536f2015-11-06 03:25:3872namespace {
73
74const char kAppUrl[] = "http://www.google.com";
75const char kAppTitle[] = "Test title";
76const char kAppDescription[] = "Test description";
77
78} // anonymous namespace
79
[email protected]bf3d9df2012-07-24 23:20:2780namespace extensions {
[email protected]b70a2d92012-06-28 19:51:2181
[email protected]a01e00632010-11-05 16:58:1482namespace {
83
[email protected]f8636f92013-08-09 21:02:3784class MockInstallPrompt;
85
86// This class holds information about things that happen with a
87// MockInstallPrompt. We create the MockInstallPrompt but need to pass
88// ownership of it to CrxInstaller, so it isn't safe to hang this data on
89// MockInstallPrompt itself becuase we can't guarantee it's lifetime.
rdevlin.croninca5bf2da2015-12-17 21:21:0890class MockPromptProxy {
[email protected]f8636f92013-08-09 21:02:3791 public:
92 explicit MockPromptProxy(content::WebContents* web_contents);
rdevlin.croninca5bf2da2015-12-17 21:21:0893 ~MockPromptProxy();
[email protected]f8636f92013-08-09 21:02:3794
95 bool did_succeed() const { return !extension_id_.empty(); }
96 const std::string& extension_id() { return extension_id_; }
97 bool confirmation_requested() const { return confirmation_requested_; }
[email protected]439f1e32013-12-09 20:09:0998 const base::string16& error() const { return error_; }
[email protected]f8636f92013-08-09 21:02:3799
[email protected]f8636f92013-08-09 21:02:37100 void set_extension_id(const std::string& id) { extension_id_ = id; }
rdevlin.croninca5bf2da2015-12-17 21:21:08101 void set_confirmation_requested(bool requested) {
102 confirmation_requested_ = requested;
103 }
[email protected]439f1e32013-12-09 20:09:09104 void set_error(const base::string16& error) { error_ = error; }
[email protected]f8636f92013-08-09 21:02:37105
dchengc963c7142016-04-08 03:55:22106 std::unique_ptr<ExtensionInstallPrompt> CreatePrompt();
[email protected]f8636f92013-08-09 21:02:37107
108 private:
[email protected]f8636f92013-08-09 21:02:37109
110 // Data used to create a prompt.
111 content::WebContents* web_contents_;
[email protected]f8636f92013-08-09 21:02:37112
113 // Data reported back to us by the prompt we created.
114 bool confirmation_requested_;
115 std::string extension_id_;
[email protected]439f1e32013-12-09 20:09:09116 base::string16 error_;
rdevlin.croninca5bf2da2015-12-17 21:21:08117
dchengc963c7142016-04-08 03:55:22118 std::unique_ptr<ScopedTestDialogAutoConfirm> auto_confirm;
rdevlin.croninca5bf2da2015-12-17 21:21:08119
120 DISALLOW_COPY_AND_ASSIGN(MockPromptProxy);
[email protected]f8636f92013-08-09 21:02:37121};
[email protected]bf2fcd52012-04-16 22:59:39122
dominickn675536f2015-11-06 03:25:38123SkBitmap CreateSquareBitmap(int size) {
124 SkBitmap bitmap;
125 bitmap.allocN32Pixels(size, size);
126 bitmap.eraseColor(SK_ColorRED);
127 return bitmap;
128}
129
130WebApplicationInfo::IconInfo CreateIconInfoWithBitmap(int size) {
131 WebApplicationInfo::IconInfo icon_info;
132 icon_info.width = size;
133 icon_info.height = size;
134 icon_info.data = CreateSquareBitmap(size);
135 return icon_info;
136}
137
138WebApplicationInfo CreateWebAppInfo(const char* title,
139 const char* description,
140 const char* app_url,
141 int size) {
142 WebApplicationInfo web_app_info;
143 web_app_info.title = base::UTF8ToUTF16(title);
144 web_app_info.description = base::UTF8ToUTF16(description);
145 web_app_info.app_url = GURL(app_url);
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15146 web_app_info.scope = GURL(app_url);
dominickn675536f2015-11-06 03:25:38147
148 web_app_info.icons.push_back(CreateIconInfoWithBitmap(size));
149
150 return web_app_info;
151}
152
[email protected]c82da8c42012-06-08 19:49:11153class MockInstallPrompt : public ExtensionInstallPrompt {
[email protected]a01e00632010-11-05 16:58:14154 public:
[email protected]f8636f92013-08-09 21:02:37155 MockInstallPrompt(content::WebContents* web_contents,
156 MockPromptProxy* proxy) :
[email protected]91e51d612012-10-21 23:03:05157 ExtensionInstallPrompt(web_contents),
[email protected]f8636f92013-08-09 21:02:37158 proxy_(proxy) {}
[email protected]a01e00632010-11-05 16:58:14159
[email protected]a01e00632010-11-05 16:58:14160 // Overriding some of the ExtensionInstallUI API.
dchengae36a4a2014-10-21 12:36:36161 void OnInstallSuccess(const Extension* extension, SkBitmap* icon) override {
[email protected]f8636f92013-08-09 21:02:37162 proxy_->set_extension_id(extension->id());
rdevlin.croninca5bf2da2015-12-17 21:21:08163 proxy_->set_confirmation_requested(did_call_show_dialog());
[email protected]a01e00632010-11-05 16:58:14164 }
ginkage47e603e2015-02-27 08:42:41165 void OnInstallFailure(const CrxInstallError& error) override {
[email protected]f8636f92013-08-09 21:02:37166 proxy_->set_error(error.message());
rdevlin.croninca5bf2da2015-12-17 21:21:08167 proxy_->set_confirmation_requested(did_call_show_dialog());
[email protected]a01e00632010-11-05 16:58:14168 }
169
170 private:
rdevlin.croninca5bf2da2015-12-17 21:21:08171 MockPromptProxy* proxy_;
172
173 DISALLOW_COPY_AND_ASSIGN(MockInstallPrompt);
[email protected]a01e00632010-11-05 16:58:14174};
175
[email protected]658eae52014-06-14 20:28:05176MockPromptProxy::MockPromptProxy(content::WebContents* web_contents)
rdevlin.croninca5bf2da2015-12-17 21:21:08177 : web_contents_(web_contents),
178 confirmation_requested_(false),
179 auto_confirm(new ScopedTestDialogAutoConfirm(
180 ScopedTestDialogAutoConfirm::ACCEPT)) {
[email protected]f8636f92013-08-09 21:02:37181}
182
183MockPromptProxy::~MockPromptProxy() {}
184
dchengc963c7142016-04-08 03:55:22185std::unique_ptr<ExtensionInstallPrompt> MockPromptProxy::CreatePrompt() {
186 return std::unique_ptr<MockInstallPrompt>(
[email protected]f8636f92013-08-09 21:02:37187 new MockInstallPrompt(web_contents_, this));
[email protected]f8636f92013-08-09 21:02:37188}
189
dchengc963c7142016-04-08 03:55:22190std::unique_ptr<MockPromptProxy> CreateMockPromptProxyForBrowser(
[email protected]f8636f92013-08-09 21:02:37191 Browser* browser) {
ricea91d6fc122016-08-30 08:47:14192 return base::MakeUnique<MockPromptProxy>(
193 browser->tab_strip_model()->GetActiveWebContents());
[email protected]619f86182012-07-03 21:30:18194}
195
[email protected]253fc2bb2014-07-10 04:21:18196class ManagementPolicyMock : public extensions::ManagementPolicy::Provider {
197 public:
198 ManagementPolicyMock() {}
199
dchengae36a4a2014-10-21 12:36:36200 std::string GetDebugPolicyProviderName() const override {
[email protected]253fc2bb2014-07-10 04:21:18201 return "ManagementPolicyMock";
202 }
203
dchengae36a4a2014-10-21 12:36:36204 bool UserMayLoad(const Extension* extension,
205 base::string16* error) const override {
Karan Bhatia2a117232017-08-23 00:24:56206 if (error)
207 *error = base::UTF8ToUTF16("Dummy error message");
[email protected]253fc2bb2014-07-10 04:21:18208 return false;
209 }
210};
211
[email protected]a01e00632010-11-05 16:58:14212} // namespace
213
214class ExtensionCrxInstallerTest : public ExtensionBrowserTest {
kalmanae342c92014-12-12 22:04:23215 protected:
dchengc963c7142016-04-08 03:55:22216 std::unique_ptr<WebstoreInstaller::Approval> GetApproval(
[email protected]85290822013-08-23 20:27:38217 const char* manifest_dir,
[email protected]b70a2d92012-06-28 19:51:21218 const std::string& id,
[email protected]85290822013-08-23 20:27:38219 bool strict_manifest_checks) {
dchengc963c7142016-04-08 03:55:22220 std::unique_ptr<WebstoreInstaller::Approval> result;
[email protected]85290822013-08-23 20:27:38221
Minh X. Nguyen2c17b3982017-10-13 18:32:29222 base::ScopedAllowBlockingForTesting allow_io;
[email protected]85290822013-08-23 20:27:38223 base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir);
224 std::string error;
dchengc963c7142016-04-08 03:55:22225 std::unique_ptr<base::DictionaryValue> parsed_manifest(
[email protected]85df9d12014-04-15 17:02:14226 file_util::LoadManifest(ext_path, &error));
[email protected]85290822013-08-23 20:27:38227 if (!parsed_manifest.get() || !error.empty())
dcheng1fc00f12015-12-26 22:18:03228 return result;
[email protected]85290822013-08-23 20:27:38229
230 return WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
dcheng1fc00f12015-12-26 22:18:03231 browser()->profile(), id, std::move(parsed_manifest),
[email protected]85290822013-08-23 20:27:38232 strict_manifest_checks);
233 }
234
Minh X. Nguyen30975342017-12-04 22:02:41235 ExtensionService* extension_service() {
236 return extensions::ExtensionSystem::Get(browser()->profile())
237 ->extension_service();
238 }
239
240 const Extension* GetInstalledExtension(const std::string& extension_id) {
241 return extension_service()->GetInstalledExtension(extension_id);
242 }
243
244 std::unique_ptr<base::ScopedTempDir> UnpackedCrxTempDir() {
245 auto temp_dir = std::make_unique<base::ScopedTempDir>();
246 EXPECT_TRUE(temp_dir->CreateUniqueTempDir());
247 EXPECT_TRUE(base::PathExists(temp_dir->GetPath()));
248
249 base::FilePath unpacked_path = test_data_dir_.AppendASCII("good_unpacked");
250 EXPECT_TRUE(base::PathExists(unpacked_path));
251 EXPECT_TRUE(base::CopyDirectory(unpacked_path, temp_dir->GetPath(), false));
252
253 return temp_dir;
254 }
255
256 // Helper function that creates a file at |relative_path| within |directory|
257 // and fills it with |content|.
258 bool AddFileToDirectory(const base::FilePath& directory,
259 const base::FilePath& relative_path,
260 const std::string& content) const {
261 const base::FilePath full_path = directory.Append(relative_path);
262 if (!CreateDirectory(full_path.DirName()))
263 return false;
264 const int result =
265 base::WriteFile(full_path, content.data(), content.size());
266 return (static_cast<size_t>(result) == content.size());
267 }
268
269 void AddExtension(const std::string& extension_id,
270 const std::string& version) {
271 base::ScopedTempDir temp_dir;
272 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
273 ASSERT_TRUE(base::PathExists(temp_dir.GetPath()));
274
275 base::FilePath foo_js(FILE_PATH_LITERAL("foo.js"));
276 base::FilePath bar_html(FILE_PATH_LITERAL("bar/bar.html"));
277 ASSERT_TRUE(AddFileToDirectory(temp_dir.GetPath(), foo_js, "hello"))
278 << "Failed to write " << temp_dir.GetPath().value() << "/"
279 << foo_js.value();
280 ASSERT_TRUE(AddFileToDirectory(temp_dir.GetPath(), bar_html, "world"));
281
282 ExtensionBuilder builder;
283 builder.SetManifest(DictionaryBuilder()
284 .Set("name", "My First Extension")
285 .Set("version", version)
286 .Set("manifest_version", 2)
287 .Build());
288 builder.SetID(extension_id);
289 builder.SetPath(temp_dir.GetPath());
290 ExtensionRegistry::Get(browser()->profile())->AddEnabled(builder.Build());
291
292 const Extension* extension = GetInstalledExtension(extension_id);
293 ASSERT_NE(nullptr, extension);
294 ASSERT_EQ(version, extension->VersionString());
295 }
296
297 static void InstallerCallback(base::OnceClosure quit_closure,
298 CrxInstaller::InstallerResultCallback callback,
299 bool success) {
300 if (!callback.is_null())
301 std::move(callback).Run(success);
302 std::move(quit_closure).Run();
303 }
304
[email protected]85290822013-08-23 20:27:38305 void RunCrxInstaller(const WebstoreInstaller::Approval* approval,
dchengc963c7142016-04-08 03:55:22306 std::unique_ptr<ExtensionInstallPrompt> prompt,
Minh X. Nguyen2c17b3982017-10-13 18:32:29307 CrxInstaller::InstallerResultCallback callback,
[email protected]85290822013-08-23 20:27:38308 const base::FilePath& crx_path) {
Minh X. Nguyen30975342017-12-04 22:02:41309 base::RunLoop run_loop;
310
[email protected]a01e00632010-11-05 16:58:14311 scoped_refptr<CrxInstaller> installer(
Minh X. Nguyen30975342017-12-04 22:02:41312 CrxInstaller::Create(extension_service(), std::move(prompt), approval));
[email protected]a01e00632010-11-05 16:58:14313 installer->set_allow_silent_install(true);
[email protected]b1f04cc2010-11-10 22:59:30314 installer->set_is_gallery_install(true);
Minh X. Nguyen30975342017-12-04 22:02:41315 installer->set_installer_callback(
316 base::BindOnce(&ExtensionCrxInstallerTest::InstallerCallback,
317 run_loop.QuitWhenIdleClosure(), std::move(callback)));
[email protected]85290822013-08-23 20:27:38318 installer->InstallCrx(crx_path);
Minh X. Nguyen30975342017-12-04 22:02:41319
320 run_loop.Run();
[email protected]85290822013-08-23 20:27:38321 }
322
Minh X. Nguyen2c17b3982017-10-13 18:32:29323 void RunCrxInstallerFromUnpackedDirectory(
324 std::unique_ptr<ExtensionInstallPrompt> prompt,
325 CrxInstaller::InstallerResultCallback callback,
326 const std::string& extension_id,
327 const std::string& public_key,
328 const base::FilePath& crx_directory) {
Minh X. Nguyen30975342017-12-04 22:02:41329 base::RunLoop run_loop;
330
Minh X. Nguyen2c17b3982017-10-13 18:32:29331 scoped_refptr<CrxInstaller> installer(
Minh X. Nguyen30975342017-12-04 22:02:41332 CrxInstaller::Create(extension_service(), std::move(prompt)));
Minh X. Nguyen2c17b3982017-10-13 18:32:29333 installer->set_allow_silent_install(true);
334 installer->set_is_gallery_install(true);
Minh X. Nguyen30975342017-12-04 22:02:41335 installer->set_installer_callback(
336 base::BindOnce(&ExtensionCrxInstallerTest::InstallerCallback,
337 run_loop.QuitWhenIdleClosure(), std::move(callback)));
Minh X. Nguyen2c17b3982017-10-13 18:32:29338 installer->set_delete_source(true);
339 installer->InstallUnpackedCrx(extension_id, public_key, crx_directory);
Minh X. Nguyen30975342017-12-04 22:02:41340
341 run_loop.Run();
342 }
343
344 void RunUpdateExtension(std::unique_ptr<ExtensionInstallPrompt> prompt,
345 const std::string& extension_id,
346 const std::string& public_key,
347 const base::FilePath& unpacked_dir,
348 CrxInstaller::InstallerResultCallback callback) {
349 base::RunLoop run_loop;
350
351 scoped_refptr<CrxInstaller> installer(
352 CrxInstaller::Create(extension_service(), std::move(prompt)));
353 installer->set_delete_source(true);
354 installer->set_installer_callback(
355 base::BindOnce(&ExtensionCrxInstallerTest::InstallerCallback,
356 run_loop.QuitWhenIdleClosure(), std::move(callback)));
357 installer->UpdateExtensionFromUnpackedCrx(extension_id, public_key,
358 unpacked_dir);
359
360 run_loop.Run();
Minh X. Nguyen2c17b3982017-10-13 18:32:29361 }
362
[email protected]85290822013-08-23 20:27:38363 // Installs a crx from |crx_relpath| (a path relative to the extension test
364 // data dir) with expected id |id|.
365 void InstallWithPrompt(const char* ext_relpath,
366 const std::string& id,
Minh X. Nguyen2c17b3982017-10-13 18:32:29367 CrxInstaller::InstallerResultCallback callback,
rdevlin.croninca5bf2da2015-12-17 21:21:08368 MockPromptProxy* mock_install_prompt) {
[email protected]85290822013-08-23 20:27:38369 base::FilePath ext_path = test_data_dir_.AppendASCII(ext_relpath);
370
dchengc963c7142016-04-08 03:55:22371 std::unique_ptr<WebstoreInstaller::Approval> approval;
[email protected]85290822013-08-23 20:27:38372 if (!id.empty())
373 approval = GetApproval(ext_relpath, id, true);
374
375 base::FilePath crx_path = PackExtension(ext_path);
376 EXPECT_FALSE(crx_path.empty());
377 RunCrxInstaller(approval.get(), mock_install_prompt->CreatePrompt(),
Minh X. Nguyen2c17b3982017-10-13 18:32:29378 std::move(callback), crx_path);
[email protected]a01e00632010-11-05 16:58:14379
[email protected]c82da8c42012-06-08 19:49:11380 EXPECT_TRUE(mock_install_prompt->did_succeed());
[email protected]b70a2d92012-06-28 19:51:21381 }
382
383 // Installs an extension and checks that it has scopes granted IFF
384 // |record_oauth2_grant| is true.
Minh X. Nguyen2c17b3982017-10-13 18:32:29385 void CheckHasEmptyScopesAfterInstall(
386 const std::string& ext_relpath,
387 CrxInstaller::InstallerResultCallback callback,
388 bool record_oauth2_grant) {
dchengc963c7142016-04-08 03:55:22389 std::unique_ptr<MockPromptProxy> mock_prompt =
[email protected]f8636f92013-08-09 21:02:37390 CreateMockPromptProxyForBrowser(browser());
391
Minh X. Nguyen2c17b3982017-10-13 18:32:29392 InstallWithPrompt("browsertest/scopes", std::string(), std::move(callback),
393 mock_prompt.get());
[email protected]b70a2d92012-06-28 19:51:21394
dchengc963c7142016-04-08 03:55:22395 std::unique_ptr<const PermissionSet> permissions =
[email protected]7c82539c2014-02-19 06:09:17396 ExtensionPrefs::Get(browser()->profile())
397 ->GetGrantedPermissions(mock_prompt->extension_id());
[email protected]b70a2d92012-06-28 19:51:21398 ASSERT_TRUE(permissions.get());
[email protected]a01e00632010-11-05 16:58:14399 }
kalmanae342c92014-12-12 22:04:23400
dominickn675536f2015-11-06 03:25:38401 void InstallWebAppAndVerifyNoErrors() {
dominickn675536f2015-11-06 03:25:38402 scoped_refptr<CrxInstaller> crx_installer(
Minh X. Nguyen30975342017-12-04 22:02:41403 CrxInstaller::CreateSilent(extension_service()));
dominickn675536f2015-11-06 03:25:38404 crx_installer->set_error_on_unsupported_requirements(true);
405 crx_installer->InstallWebApp(
406 CreateWebAppInfo(kAppTitle, kAppDescription, kAppUrl, 64));
407 EXPECT_TRUE(WaitForCrxInstallerDone());
408 ASSERT_TRUE(crx_installer->extension());
dominickn675536f2015-11-06 03:25:38409 }
[email protected]a01e00632010-11-05 16:58:14410};
411
voodoo6ede9072016-03-09 07:47:53412class ExtensionCrxInstallerTestWithExperimentalApis
413 : public ExtensionCrxInstallerTest {
414 protected:
415 void SetUpCommandLine(base::CommandLine* command_line) override {
416 ExtensionCrxInstallerTest::SetUpCommandLine(command_line);
417 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
418 }
419};
420
[email protected]fc38935a2011-10-31 23:53:28421IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
kalmanae342c92014-12-12 22:04:23422 ExperimentalExtensionFromGallery) {
423 // Gallery-installed extensions should have their experimental permission
424 // preserved, since we allow the Webstore to make that decision.
voodoo6ede9072016-03-09 07:47:53425 const Extension* extension = InstallExtensionFromWebstore(
426 test_data_dir_.AppendASCII("experimental.crx"), 1);
kalmanae342c92014-12-12 22:04:23427 ASSERT_TRUE(extension);
428 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
429 APIPermission::kExperimental));
430}
[email protected]240cc92a2011-12-01 01:22:24431
kalmanae342c92014-12-12 22:04:23432IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
433 ExperimentalExtensionFromOutsideGallery) {
434 // Non-gallery-installed extensions should lose their experimental
435 // permission if the flag isn't enabled.
voodoo6ede9072016-03-09 07:47:53436 const Extension* extension = InstallExtension(
437 test_data_dir_.AppendASCII("experimental.crx"), 1);
kalmanae342c92014-12-12 22:04:23438 ASSERT_TRUE(extension);
439 EXPECT_FALSE(extension->permissions_data()->HasAPIPermission(
440 APIPermission::kExperimental));
441}
[email protected]240cc92a2011-12-01 01:22:24442
voodoo6ede9072016-03-09 07:47:53443IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
kalmanae342c92014-12-12 22:04:23444 ExperimentalExtensionFromOutsideGalleryWithFlag) {
445 // Non-gallery-installed extensions should maintain their experimental
446 // permission if the flag is enabled.
voodoo6ede9072016-03-09 07:47:53447 const Extension* extension = InstallExtension(
448 test_data_dir_.AppendASCII("experimental.crx"), 1);
kalmanae342c92014-12-12 22:04:23449 ASSERT_TRUE(extension);
450 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
451 APIPermission::kExperimental));
[email protected]fc38935a2011-10-31 23:53:28452}
[email protected]ee14cad2012-03-29 01:59:37453
voodoo6ede9072016-03-09 07:47:53454IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
455 PlatformAppCrx) {
[email protected]ee14cad2012-03-29 01:59:37456 EXPECT_TRUE(InstallExtension(
[email protected]dc37b002012-04-23 23:02:26457 test_data_dir_.AppendASCII("minimal_platform_app.crx"), 1));
[email protected]ee14cad2012-03-29 01:59:37458}
[email protected]bf2fcd52012-04-16 22:59:39459
meacerb040d3a2016-09-09 03:20:20460IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, BlockedFileTypes) {
461 const Extension* extension =
462 InstallExtension(test_data_dir_.AppendASCII("blocked_file_types.crx"), 1);
Minh X. Nguyen2c17b3982017-10-13 18:32:29463 base::ScopedAllowBlockingForTesting allow_io;
meacerb040d3a2016-09-09 03:20:20464 EXPECT_TRUE(base::PathExists(extension->path().AppendASCII("test.html")));
465 EXPECT_TRUE(base::PathExists(extension->path().AppendASCII("test.nexe")));
466 EXPECT_FALSE(base::PathExists(extension->path().AppendASCII("test1.EXE")));
467 EXPECT_FALSE(base::PathExists(extension->path().AppendASCII("test2.exe")));
468}
469
meacerbd735062016-09-28 19:58:37470IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowedThemeFileTypes) {
471 const Extension* extension = InstallExtension(
472 test_data_dir_.AppendASCII("theme_with_extension.crx"), 1);
473 ASSERT_TRUE(extension);
474 const base::FilePath& path = extension->path();
Minh X. Nguyen2c17b3982017-10-13 18:32:29475 base::ScopedAllowBlockingForTesting allow_io;
meacerbd735062016-09-28 19:58:37476 EXPECT_TRUE(
477 base::PathExists(path.AppendASCII("images/theme_frame_camo.PNG")));
478 EXPECT_TRUE(
479 base::PathExists(path.AppendASCII("images/theme_ntp_background.png")));
480 EXPECT_TRUE(base::PathExists(
481 path.AppendASCII("images/theme_ntp_background_norepeat.png")));
482 EXPECT_TRUE(
483 base::PathExists(path.AppendASCII("images/theme_toolbar_camo.png")));
484 EXPECT_TRUE(base::PathExists(path.AppendASCII("images/redirect_target.GIF")));
485 EXPECT_TRUE(base::PathExists(path.AppendASCII("test.image.bmp")));
486 EXPECT_TRUE(
487 base::PathExists(path.AppendASCII("test_image_with_no_extension")));
488
489 EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test.html")));
490 EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test.nexe")));
491 EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test1.EXE")));
492 EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test2.exe")));
493 EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test.txt")));
494 EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test.css")));
495}
496
rdevlin.cronin10f34542017-02-06 18:22:47497IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
498 PackAndInstallExtensionFromDownload) {
499 std::unique_ptr<base::AutoReset<bool>> allow_offstore_install =
500 download_crx_util::OverrideOffstoreInstallAllowedForTesting(true);
[email protected]89019d62012-05-17 18:47:09501
[email protected]bf2fcd52012-04-16 22:59:39502 const int kNumDownloadsExpected = 1;
[email protected]bf2fcd52012-04-16 22:59:39503
[email protected]650b2d52013-02-10 03:41:45504 base::FilePath crx_path = PackExtension(
[email protected]bf2fcd52012-04-16 22:59:39505 test_data_dir_.AppendASCII("common/background_page"));
506 ASSERT_FALSE(crx_path.empty());
507 std::string crx_path_string(crx_path.value().begin(), crx_path.value().end());
508 GURL url = GURL(std::string("file:///").append(crx_path_string));
509
dchengc963c7142016-04-08 03:55:22510 std::unique_ptr<MockPromptProxy> mock_prompt =
[email protected]f8636f92013-08-09 21:02:37511 CreateMockPromptProxyForBrowser(browser());
512 download_crx_util::SetMockInstallPromptForTesting(
513 mock_prompt->CreatePrompt());
[email protected]bf2fcd52012-04-16 22:59:39514
[email protected]bf2fcd52012-04-16 22:59:39515 content::DownloadManager* download_manager =
[email protected]b441a8492012-06-06 14:55:57516 content::BrowserContext::GetDownloadManager(browser()->profile());
[email protected]bf2fcd52012-04-16 22:59:39517
dchengc963c7142016-04-08 03:55:22518 std::unique_ptr<content::DownloadTestObserver> observer(
[email protected]49b264f2012-08-14 17:12:26519 new content::DownloadTestObserverTerminal(
[email protected]47665442012-07-27 02:31:22520 download_manager, kNumDownloadsExpected,
[email protected]49b264f2012-08-14 17:12:26521 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
nick3b04f322016-08-31 19:29:19522 ui_test_utils::NavigateToURLWithDisposition(
523 browser(), url, WindowOpenDisposition::CURRENT_TAB,
[email protected]bf2fcd52012-04-16 22:59:39524 ui_test_utils::BROWSER_TEST_NONE);
525
[email protected]8c6af5b2012-06-15 20:10:26526 EXPECT_TRUE(WaitForCrxInstallerDone());
[email protected]c82da8c42012-06-08 19:49:11527 EXPECT_TRUE(mock_prompt->confirmation_requested());
[email protected]bf2fcd52012-04-16 22:59:39528}
[email protected]a9736892012-05-30 15:58:05529
[email protected]b70a2d92012-06-28 19:51:21530// Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is
531// true.
[email protected]7a561912012-08-21 21:06:05532#if defined(OS_WIN)
[email protected]1e09ec82012-12-21 22:48:09533#define MAYBE_GrantScopes DISABLED_GrantScopes
Minh X. Nguyen2c17b3982017-10-13 18:32:29534#define MAYBE_GrantScopes_WithCallback DISABLED_GrantScopes_WithCallback
[email protected]7a561912012-08-21 21:06:05535#else
536#define MAYBE_GrantScopes GrantScopes
Minh X. Nguyen2c17b3982017-10-13 18:32:29537#define MAYBE_GrantScopes_WithCallback GrantScopes_WithCallback
[email protected]7a561912012-08-21 21:06:05538#endif
voodoo6ede9072016-03-09 07:47:53539IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
540 MAYBE_GrantScopes) {
Minh X. Nguyen2c17b3982017-10-13 18:32:29541 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall(
542 "browsertest/scopes", CrxInstaller::InstallerResultCallback(), true));
543}
544
545IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
546 MAYBE_GrantScopes_WithCallback) {
547 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall(
548 "browsertest/scopes",
549 base::BindOnce([](bool success) { EXPECT_TRUE(success); }), true));
[email protected]b70a2d92012-06-28 19:51:21550}
551
voodoo6ede9072016-03-09 07:47:53552IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
553 DoNotGrantScopes) {
Minh X. Nguyen2c17b3982017-10-13 18:32:29554 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall(
555 "browsertest/scopes", CrxInstaller::InstallerResultCallback(), false));
556}
557
558IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
559 DoNotGrantScopes_WithCallback) {
560 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall(
561 "browsertest/scopes",
562 base::BindOnce([](bool success) { EXPECT_TRUE(success); }), false));
[email protected]b70a2d92012-06-28 19:51:21563}
564
[email protected]d4b4d7af2014-08-20 10:45:15565IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowOffStore) {
[email protected]a9736892012-05-30 15:58:05566 const bool kTestData[] = {false, true};
567
568 for (size_t i = 0; i < arraysize(kTestData); ++i) {
dchengc963c7142016-04-08 03:55:22569 std::unique_ptr<MockPromptProxy> mock_prompt =
[email protected]f8636f92013-08-09 21:02:37570 CreateMockPromptProxyForBrowser(browser());
571
[email protected]a9736892012-05-30 15:58:05572 scoped_refptr<CrxInstaller> crx_installer(
Minh X. Nguyen30975342017-12-04 22:02:41573 CrxInstaller::Create(extension_service(), mock_prompt->CreatePrompt()));
[email protected]7224dbd2012-06-05 15:21:50574 crx_installer->set_install_cause(
575 extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
[email protected]d9039812012-06-09 06:05:48576
577 if (kTestData[i]) {
578 crx_installer->set_off_store_install_allow_reason(
579 CrxInstaller::OffStoreInstallAllowedInTest);
580 }
[email protected]a9736892012-05-30 15:58:05581
Minh X. Nguyen30975342017-12-04 22:02:41582 base::RunLoop run_loop;
583 crx_installer->set_installer_callback(
584 base::BindOnce(&ExtensionCrxInstallerTest::InstallerCallback,
585 run_loop.QuitWhenIdleClosure(),
586 CrxInstaller::InstallerResultCallback()));
[email protected]a9736892012-05-30 15:58:05587 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
[email protected]d4b4d7af2014-08-20 10:45:15588 // The |mock_prompt| will quit running the loop once the |crx_installer|
589 // is done.
Minh X. Nguyen30975342017-12-04 22:02:41590 run_loop.Run();
[email protected]c82da8c42012-06-08 19:49:11591 EXPECT_EQ(kTestData[i], mock_prompt->did_succeed());
592 EXPECT_EQ(kTestData[i], mock_prompt->confirmation_requested()) <<
593 kTestData[i];
[email protected]a9736892012-05-30 15:58:05594 if (kTestData[i]) {
[email protected]b959d7d42013-12-13 17:26:37595 EXPECT_EQ(base::string16(), mock_prompt->error()) << kTestData[i];
[email protected]a9736892012-05-30 15:58:05596 } else {
597 EXPECT_EQ(l10n_util::GetStringUTF16(
598 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE),
[email protected]c82da8c42012-06-08 19:49:11599 mock_prompt->error()) << kTestData[i];
[email protected]a9736892012-05-30 15:58:05600 }
601 }
[email protected]a9736892012-05-30 15:58:05602}
[email protected]bf3d9df2012-07-24 23:20:27603
[email protected]90d3c042013-06-06 10:10:39604IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) {
605 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx");
606 crx_path = crx_path.AppendASCII("theme_hidpi.crx");
607
[email protected]658eae52014-06-14 20:28:05608 ASSERT_TRUE(InstallExtension(crx_path, 1));
[email protected]90d3c042013-06-06 10:10:39609
610 const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm");
gpdavis.chromium48f08c42014-09-18 22:09:34611 ExtensionRegistry* registry = ExtensionRegistry::Get(
612 browser()->profile());
[email protected]90d3c042013-06-06 10:10:39613 const extensions::Extension* extension =
gpdavis.chromium48f08c42014-09-18 22:09:34614 registry->enabled_extensions().GetByID(extension_id);
[email protected]90d3c042013-06-06 10:10:39615 ASSERT_TRUE(extension);
616 EXPECT_EQ(extension_id, extension->id());
617
618 UninstallExtension(extension_id);
gpdavis.chromium48f08c42014-09-18 22:09:34619 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id));
[email protected]90d3c042013-06-06 10:10:39620}
621
[email protected]9e9c1d12013-07-31 01:58:12622IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
mekc95f9d062015-01-10 00:52:04623 InstallDelayedUntilNextUpdate) {
[email protected]9e9c1d12013-07-31 01:58:12624 const std::string extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf");
mekc95f9d062015-01-10 00:52:04625 base::FilePath base_path = test_data_dir_.AppendASCII("delayed_install");
626
Minh X. Nguyen30975342017-12-04 22:02:41627 ExtensionService* service = extension_service();
[email protected]9e9c1d12013-07-31 01:58:12628 ASSERT_TRUE(service);
gpdavis.chromium48f08c42014-09-18 22:09:34629 ExtensionRegistry* registry = ExtensionRegistry::Get(
630 browser()->profile());
631 ASSERT_TRUE(registry);
[email protected]9e9c1d12013-07-31 01:58:12632
633 // Install version 1 of the test extension. This extension does not have
634 // a background page but does have a browser action.
mekc95f9d062015-01-10 00:52:04635 base::FilePath v1_path = PackExtension(base_path.AppendASCII("v1"));
636 ASSERT_FALSE(v1_path.empty());
637 ASSERT_TRUE(InstallExtension(v1_path, 1));
[email protected]9e9c1d12013-07-31 01:58:12638 const extensions::Extension* extension =
gpdavis.chromium48f08c42014-09-18 22:09:34639 registry->enabled_extensions().GetByID(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12640 ASSERT_TRUE(extension);
641 ASSERT_EQ(extension_id, extension->id());
Devlin Cronin03bf2d22017-12-20 08:21:05642 ASSERT_EQ("1.0", extension->version().GetString());
[email protected]9e9c1d12013-07-31 01:58:12643
mekc95f9d062015-01-10 00:52:04644 // Make test extension non-idle by opening the extension's options page.
645 ExtensionTabUtil::OpenOptionsPage(extension, browser());
646 WaitForExtensionNotIdle(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12647
648 // Install version 2 of the extension and check that it is indeed delayed.
mekc95f9d062015-01-10 00:52:04649 base::FilePath v2_path = PackExtension(base_path.AppendASCII("v2"));
650 ASSERT_FALSE(v2_path.empty());
651 ASSERT_TRUE(UpdateExtensionWaitForIdle(extension_id, v2_path, 0));
[email protected]9e9c1d12013-07-31 01:58:12652
653 ASSERT_EQ(1u, service->delayed_installs()->size());
gpdavis.chromium48f08c42014-09-18 22:09:34654 extension = registry->enabled_extensions().GetByID(extension_id);
Devlin Cronin03bf2d22017-12-20 08:21:05655 ASSERT_EQ("1.0", extension->version().GetString());
[email protected]9e9c1d12013-07-31 01:58:12656
mekc95f9d062015-01-10 00:52:04657 // Make the extension idle again by navigating away from the options page.
658 // This should not trigger the delayed install.
659 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
660 WaitForExtensionIdle(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12661 ASSERT_EQ(1u, service->delayed_installs()->size());
mekc95f9d062015-01-10 00:52:04662 extension = registry->enabled_extensions().GetByID(extension_id);
Devlin Cronin03bf2d22017-12-20 08:21:05663 ASSERT_EQ("1.0", extension->version().GetString());
[email protected]9e9c1d12013-07-31 01:58:12664
665 // Install version 3 of the extension. Because the extension is idle,
666 // this install should succeed.
mekc95f9d062015-01-10 00:52:04667 base::FilePath v3_path = PackExtension(base_path.AppendASCII("v3"));
668 ASSERT_FALSE(v3_path.empty());
669 ASSERT_TRUE(UpdateExtensionWaitForIdle(extension_id, v3_path, 0));
gpdavis.chromium48f08c42014-09-18 22:09:34670 extension = registry->enabled_extensions().GetByID(extension_id);
Devlin Cronin03bf2d22017-12-20 08:21:05671 ASSERT_EQ("3.0", extension->version().GetString());
[email protected]9e9c1d12013-07-31 01:58:12672
673 // The version 2 delayed install should be cleaned up, and finishing
674 // delayed extension installation shouldn't break anything.
675 ASSERT_EQ(0u, service->delayed_installs()->size());
676 service->MaybeFinishDelayedInstallations();
gpdavis.chromium48f08c42014-09-18 22:09:34677 extension = registry->enabled_extensions().GetByID(extension_id);
Devlin Cronin03bf2d22017-12-20 08:21:05678 ASSERT_EQ("3.0", extension->version().GetString());
[email protected]9e9c1d12013-07-31 01:58:12679}
680
[email protected]e3767aa2013-11-08 23:49:07681#if defined(FULL_SAFE_BROWSING)
[email protected]9f3c8532013-07-31 19:52:07682IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) {
[email protected]3f2a2fa2013-09-24 02:55:25683 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
684 new FakeSafeBrowsingDatabaseManager(true));
685 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
[email protected]9f3c8532013-07-31 19:52:07686
[email protected]3f2a2fa2013-09-24 02:55:25687 blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm");
[email protected]9f3c8532013-07-31 19:52:07688
689 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx")
690 .AppendASCII("theme_hidpi.crx");
691 EXPECT_FALSE(InstallExtension(crx_path, 0));
692}
[email protected]e3767aa2013-11-08 23:49:07693#endif
[email protected]9f3c8532013-07-31 19:52:07694
[email protected]85290822013-08-23 20:27:38695IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) {
dchengc963c7142016-04-08 03:55:22696 std::unique_ptr<MockPromptProxy> mock_prompt =
[email protected]85290822013-08-23 20:27:38697 CreateMockPromptProxyForBrowser(browser());
698
699 // We want to simulate the case where the webstore sends a more recent
700 // version of the manifest, but the downloaded .crx file is old since
701 // the newly published version hasn't fully propagated to all the download
702 // servers yet. So load the v2 manifest, but then install the v1 crx file.
703 std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp";
dchengc963c7142016-04-08 03:55:22704 std::unique_ptr<WebstoreInstaller::Approval> approval =
[email protected]85290822013-08-23 20:27:38705 GetApproval("crx_installer/v2_no_permission_change/", id, false);
706
707 RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(),
Minh X. Nguyen2c17b3982017-10-13 18:32:29708 CrxInstaller::InstallerResultCallback(),
[email protected]85290822013-08-23 20:27:38709 test_data_dir_.AppendASCII("crx_installer/v1.crx"));
710
711 EXPECT_TRUE(mock_prompt->did_succeed());
712}
713
Minh X. Nguyen2c17b3982017-10-13 18:32:29714IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
715 NonStrictManifestCheck_WithCallback) {
716 std::unique_ptr<MockPromptProxy> mock_prompt =
717 CreateMockPromptProxyForBrowser(browser());
718
719 // We want to simulate the case where the webstore sends a more recent
720 // version of the manifest, but the downloaded .crx file is old since
721 // the newly published version hasn't fully propagated to all the download
722 // servers yet. So load the v2 manifest, but then install the v1 crx file.
723 const std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp";
724 std::unique_ptr<WebstoreInstaller::Approval> approval =
725 GetApproval("crx_installer/v2_no_permission_change/", id, false);
726
727 RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(),
728 base::BindOnce([](bool success) { EXPECT_TRUE(success); }),
729 test_data_dir_.AppendASCII("crx_installer/v1.crx"));
730
731 EXPECT_TRUE(mock_prompt->did_succeed());
732}
733
734IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
735 InstallUnpackedCrx_FolderDoesNotExist) {
736 base::ScopedAllowBlockingForTesting allow_io;
737 std::unique_ptr<MockPromptProxy> mock_prompt =
738 CreateMockPromptProxyForBrowser(browser());
739
740 base::ScopedTempDir temp_dir;
741 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
742
743 const base::FilePath folder = temp_dir.GetPath().AppendASCII("abcdef");
744 EXPECT_FALSE(base::PathExists(folder));
745
746 const std::string public_key = "123456";
747 RunCrxInstallerFromUnpackedDirectory(
748 mock_prompt->CreatePrompt(),
749 base::BindOnce([](bool success) { EXPECT_FALSE(success); }),
750 std::string(), public_key, folder);
751
752 EXPECT_FALSE(mock_prompt->did_succeed());
753}
754
755IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
756 InstallUnpackedCrx_EmptyFolder) {
757 base::ScopedAllowBlockingForTesting allow_io;
758 std::unique_ptr<MockPromptProxy> mock_prompt =
759 CreateMockPromptProxyForBrowser(browser());
760
761 base::ScopedTempDir temp_dir;
762 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
763 EXPECT_TRUE(base::PathExists(temp_dir.GetPath()));
764
765 const std::string public_key = "123456";
766 RunCrxInstallerFromUnpackedDirectory(
767 mock_prompt->CreatePrompt(),
768 base::BindOnce([](bool success) { EXPECT_FALSE(success); }),
769 std::string(), public_key, temp_dir.GetPath());
770
771 EXPECT_FALSE(mock_prompt->did_succeed());
772 EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
773}
774
775IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
776 InstallUnpackedCrx_InvalidPublicKey) {
777 base::ScopedAllowBlockingForTesting allow_io;
778 std::unique_ptr<MockPromptProxy> mock_prompt =
779 CreateMockPromptProxyForBrowser(browser());
780
781 base::ScopedTempDir temp_dir;
782 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
783 EXPECT_TRUE(base::PathExists(temp_dir.GetPath()));
784
785 const base::FilePath unpacked_path =
786 test_data_dir_.AppendASCII("good_unpacked");
787 EXPECT_TRUE(base::PathExists(unpacked_path));
788 EXPECT_TRUE(base::CopyDirectory(unpacked_path, temp_dir.GetPath(), false));
789
790 const std::string public_key = "123456";
791 RunCrxInstallerFromUnpackedDirectory(
792 mock_prompt->CreatePrompt(),
793 base::BindOnce([](bool success) { EXPECT_FALSE(success); }),
794 std::string(), public_key, temp_dir.GetPath());
795
796 EXPECT_FALSE(mock_prompt->did_succeed());
797 EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
798}
799
800IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallUnpackedCrx_Success) {
801 base::ScopedAllowBlockingForTesting allow_io;
802 std::unique_ptr<MockPromptProxy> mock_prompt =
803 CreateMockPromptProxyForBrowser(browser());
804
805 base::ScopedTempDir temp_dir;
806 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
807 EXPECT_TRUE(base::PathExists(temp_dir.GetPath()));
808
809 const base::FilePath unpacked_path =
810 test_data_dir_.AppendASCII("good_unpacked");
811 EXPECT_TRUE(base::PathExists(unpacked_path));
812 EXPECT_TRUE(base::CopyDirectory(unpacked_path, temp_dir.GetPath(), false));
813
814 const std::string public_key =
815 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/"
816 "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j"
817 "kDuI7caxEGUucpP7GJRRHnm8Sx+"
818 "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB";
819 RunCrxInstallerFromUnpackedDirectory(
820 mock_prompt->CreatePrompt(),
821 base::BindOnce([](bool success) { EXPECT_TRUE(success); }), std::string(),
822 public_key, temp_dir.GetPath());
823
824 EXPECT_TRUE(mock_prompt->did_succeed());
825 EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
826}
827
Minh X. Nguyen30975342017-12-04 22:02:41828IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
829 UpdateExtensionFromUnpackedCrx_NewExtension) {
830 base::ScopedAllowBlockingForTesting allow_io;
831 std::unique_ptr<MockPromptProxy> mock_prompt =
832 CreateMockPromptProxyForBrowser(browser());
833
834 // Update won't work as the extension doesn't exist.
835 const std::string extension_id = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
836 const std::string public_key =
837 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/"
838 "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j"
839 "kDuI7caxEGUucpP7GJRRHnm8Sx+"
840 "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB";
841 ASSERT_EQ(nullptr, GetInstalledExtension(extension_id));
842 auto temp_dir = UnpackedCrxTempDir();
843 RunUpdateExtension(mock_prompt->CreatePrompt(), extension_id, public_key,
844 temp_dir->GetPath(), base::BindOnce([](bool success) {
845 EXPECT_FALSE(success);
846 }));
847
848 // The unpacked folder should be deleted.
849 EXPECT_FALSE(mock_prompt->did_succeed());
850 EXPECT_FALSE(base::PathExists(temp_dir->GetPath()));
851 EXPECT_EQ(nullptr, GetInstalledExtension(extension_id));
852}
853
854IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
855 UpdateExtensionFromUnpackedCrx_UpdateExistingExtension) {
856 base::ScopedAllowBlockingForTesting allow_io;
857 std::unique_ptr<MockPromptProxy> mock_prompt =
858 CreateMockPromptProxyForBrowser(browser());
859
860 const std::string extension_id = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
861 const std::string public_key =
862 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/"
863 "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j"
864 "kDuI7caxEGUucpP7GJRRHnm8Sx+"
865 "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB";
866
867 // Test updating an existing extension.
868 AddExtension(extension_id, "0.0");
869
870 auto temp_dir = UnpackedCrxTempDir();
871 RunUpdateExtension(mock_prompt->CreatePrompt(), extension_id, public_key,
872 temp_dir->GetPath(), base::BindOnce([](bool success) {
873 EXPECT_TRUE(success);
874 }));
875
876 EXPECT_TRUE(mock_prompt->did_succeed());
877
878 // The unpacked folder should be deleted.
879 EXPECT_FALSE(base::PathExists(temp_dir->GetPath()));
880
881 const Extension* extension = GetInstalledExtension(extension_id);
882 ASSERT_NE(nullptr, extension);
883 EXPECT_EQ("1.0", extension->VersionString());
884}
885
886IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
887 UpdateExtensionFromUnpackedCrx_InvalidPublicKey) {
888 base::ScopedAllowBlockingForTesting allow_io;
889 std::unique_ptr<MockPromptProxy> mock_prompt =
890 CreateMockPromptProxyForBrowser(browser());
891
892 const std::string extension_id = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
893 const std::string public_key = "invalid public key";
894
895 // Test updating an existing extension.
896 AddExtension(extension_id, "0.0");
897
898 auto temp_dir = UnpackedCrxTempDir();
899 RunUpdateExtension(mock_prompt->CreatePrompt(), extension_id, public_key,
900 temp_dir->GetPath(), base::BindOnce([](bool success) {
901 EXPECT_FALSE(success);
902 }));
903
904 EXPECT_FALSE(mock_prompt->did_succeed());
905
906 // The unpacked folder should be deleted.
907 EXPECT_FALSE(base::PathExists(temp_dir->GetPath()));
908
909 const Extension* extension = GetInstalledExtension(extension_id);
910 ASSERT_NE(nullptr, extension);
911 EXPECT_EQ("0.0", extension->VersionString());
912}
913
914IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
915 UpdateExtensionFromUnpackedCrx_WrongPublicKey) {
916 base::ScopedAllowBlockingForTesting allow_io;
917 std::unique_ptr<MockPromptProxy> mock_prompt =
918 CreateMockPromptProxyForBrowser(browser());
919
920 const std::string extension_id = "gllekhaobjnhgeagipipnkpmmmpchacm";
921 const std::string public_key =
922 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/"
923 "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j"
924 "kDuI7caxEGUucpP7GJRRHnm8Sx+"
925 "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB";
926
927 // Test updating an existing extension.
928 AddExtension(extension_id, "0.0");
929
930 auto temp_dir = UnpackedCrxTempDir();
931 RunUpdateExtension(mock_prompt->CreatePrompt(), extension_id, public_key,
932 temp_dir->GetPath(), base::BindOnce([](bool success) {
933 EXPECT_FALSE(success);
934 }));
935
936 EXPECT_FALSE(mock_prompt->did_succeed());
937
938 // The unpacked folder should be deleted.
939 EXPECT_FALSE(base::PathExists(temp_dir->GetPath()));
940
941 const Extension* extension = GetInstalledExtension(extension_id);
942 ASSERT_NE(nullptr, extension);
943 EXPECT_EQ("0.0", extension->VersionString());
944}
945
limasdfebff7fd02015-12-25 14:45:31946#if defined(OS_CHROMEOS)
[email protected]14a18bf2013-09-26 08:42:30947IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) {
limasdfebff7fd02015-12-25 14:45:31948 // kiosk_only is whitelisted from non-chromeos.
[email protected]14a18bf2013-09-26 08:42:30949 base::FilePath crx_path =
950 test_data_dir_.AppendASCII("kiosk/kiosk_only.crx");
951 EXPECT_FALSE(InstallExtension(crx_path, 0));
[email protected]14a18bf2013-09-26 08:42:30952 // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over
953 // lifetime of |user_manager|.
merkulova793f3022015-02-04 10:18:30954 chromeos::FakeChromeUserManager* fake_user_manager =
955 new chromeos::FakeChromeUserManager();
alemate3ffbde6f2015-11-03 02:02:55956 const AccountId account_id(AccountId::FromUserEmail("[email protected]"));
957 fake_user_manager->AddKioskAppUser(account_id);
958 fake_user_manager->LoginUser(account_id);
Xiyuan Xiadfe3a9f2017-11-13 21:46:26959 user_manager::ScopedUserManager scoped_user_manager(
960 base::WrapUnique(fake_user_manager));
[email protected]14a18bf2013-09-26 08:42:30961 EXPECT_TRUE(InstallExtension(crx_path, 1));
[email protected]14a18bf2013-09-26 08:42:30962}
963
dpolukhincbd48d192015-06-04 14:09:37964IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallToSharedLocation) {
avi3ef9ec9e2014-12-22 22:50:17965 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]5a145e82014-05-29 22:19:07966 chromeos::switches::kEnableExtensionAssetsSharing);
967 base::ScopedTempDir cache_dir;
968 ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
969 ExtensionAssetsManagerChromeOS::SetSharedInstallDirForTesting(
vabr9142fe22016-09-08 13:19:22970 cache_dir.GetPath());
[email protected]5a145e82014-05-29 22:19:07971
972 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
973 const extensions::Extension* extension = InstallExtension(
974 crx_path, 1, extensions::Manifest::EXTERNAL_PREF);
975 base::FilePath extension_path = extension->path();
vabr9142fe22016-09-08 13:19:22976 EXPECT_TRUE(cache_dir.GetPath().IsParent(extension_path));
Minh X. Nguyen2c17b3982017-10-13 18:32:29977 base::ScopedAllowBlockingForTesting allow_io;
[email protected]5a145e82014-05-29 22:19:07978 EXPECT_TRUE(base::PathExists(extension_path));
979
980 std::string extension_id = extension->id();
981 UninstallExtension(extension_id);
gpdavis.chromium48f08c42014-09-18 22:09:34982 ExtensionRegistry* registry = ExtensionRegistry::Get(
983 browser()->profile());
984 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id));
[email protected]5a145e82014-05-29 22:19:07985
Gabriel Charette01507a22017-09-27 21:30:08986 content::RunAllTasksUntilIdle();
[email protected]5a145e82014-05-29 22:19:07987
988 EXPECT_FALSE(base::PathExists(extension_path));
989}
990#endif
991
[email protected]658eae52014-06-14 20:28:05992IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotSync) {
[email protected]658eae52014-06-14 20:28:05993 scoped_refptr<CrxInstaller> crx_installer(
Minh X. Nguyen30975342017-12-04 22:02:41994 CrxInstaller::CreateSilent(extension_service()));
[email protected]c30bda262014-06-19 04:10:13995 crx_installer->set_do_not_sync(true);
[email protected]658eae52014-06-14 20:28:05996 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
997 EXPECT_TRUE(WaitForCrxInstallerDone());
998 ASSERT_TRUE(crx_installer->extension());
999
1000 const ExtensionPrefs* extension_prefs =
1001 ExtensionPrefs::Get(browser()->profile());
1002 EXPECT_TRUE(extension_prefs->DoNotSync(crx_installer->extension()->id()));
treibc644a1c2015-07-13 08:37:041003 EXPECT_FALSE(extensions::util::ShouldSync(crx_installer->extension(),
1004 browser()->profile()));
[email protected]658eae52014-06-14 20:28:051005}
1006
[email protected]253fc2bb2014-07-10 04:21:181007IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) {
1008 ManagementPolicyMock policy;
1009 extensions::ExtensionSystem::Get(profile())
1010 ->management_policy()
1011 ->RegisterProvider(&policy);
1012
1013 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
1014 EXPECT_FALSE(InstallExtension(crx_path, 0));
1015}
1016
dominickn675536f2015-11-06 03:25:381017IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallWebApp) {
1018 InstallWebAppAndVerifyNoErrors();
1019}
1020
1021IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
1022 InstallWebAppSucceedsWithBlockPolicy) {
1023 // Verify that the install still works when a management policy blocking
1024 // extension installation is in force. Bookmark apps are special-cased to skip
1025 // these checks (see https://crbug.com/545541).
1026 ManagementPolicyMock policy;
1027 extensions::ExtensionSystem::Get(profile())
1028 ->management_policy()
1029 ->RegisterProvider(&policy);
1030
1031 InstallWebAppAndVerifyNoErrors();
1032}
1033
robbc66c4b2016-02-13 09:38:571034IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, UpdateWithFileAccess) {
1035 base::FilePath ext_source =
1036 test_data_dir_.AppendASCII("permissions").AppendASCII("files");
1037 base::FilePath crx_with_file_permission = PackExtension(ext_source);
1038 ASSERT_FALSE(crx_with_file_permission.empty());
1039
Minh X. Nguyen30975342017-12-04 22:02:411040 ExtensionService* service = extension_service();
robbc66c4b2016-02-13 09:38:571041
1042 const std::string extension_id("bdkapipdccfifhdghmblnenbbncfcpid");
1043 {
1044 // Install extension.
1045 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service));
1046 installer->InstallCrx(crx_with_file_permission);
1047 EXPECT_TRUE(WaitForCrxInstallerDone());
1048 const Extension* extension = installer->extension();
1049 ASSERT_TRUE(extension);
1050 // IDs must match, otherwise the test doesn't make any sense.
1051 ASSERT_EQ(extension_id, extension->id());
1052 // Sanity check: File access should be disabled by default.
1053 EXPECT_FALSE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
1054 EXPECT_FALSE(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS);
1055 }
1056
1057 {
1058 // Uninstall and re-install the extension. Any previously granted file
1059 // permissions should be gone.
1060 ExtensionPrefs::Get(profile())->SetAllowFileAccess(extension_id, true);
1061 EXPECT_TRUE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
1062 UninstallExtension(extension_id);
1063 EXPECT_FALSE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
1064
1065 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service));
1066 installer->InstallCrx(crx_with_file_permission);
1067 EXPECT_TRUE(WaitForCrxInstallerDone());
1068 const Extension* extension = installer->extension();
1069 ASSERT_TRUE(extension);
1070 ASSERT_EQ(extension_id, extension->id());
1071 EXPECT_FALSE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
1072 EXPECT_FALSE(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS);
1073 }
1074
1075 {
1076 // Grant file access and update the extension. File access should be kept.
1077 ExtensionPrefs::Get(profile())->SetAllowFileAccess(extension_id, true);
1078 EXPECT_TRUE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
1079 base::FilePath crx_update_with_file_permission = PackExtension(ext_source);
1080
1081 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service));
1082 installer->InstallCrx(crx_update_with_file_permission);
1083 EXPECT_TRUE(WaitForCrxInstallerDone());
1084 const Extension* extension = installer->extension();
1085 ASSERT_TRUE(extension);
1086 ASSERT_EQ(extension_id, extension->id());
1087 EXPECT_TRUE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
1088 EXPECT_TRUE(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS);
1089 }
1090}
1091
[email protected]bf3d9df2012-07-24 23:20:271092} // namespace extensions