1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_EXTENSIONS_CHROME_TEST_EXTENSION_LOADER_H_
6 #define CHROME_BROWSER_EXTENSIONS_CHROME_TEST_EXTENSION_LOADER_H_
7 
8 #include <string>
9 
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/macros.h"
13 #include "base/optional.h"
14 #include "extensions/common/extension.h"
15 #include "extensions/common/manifest.h"
16 
17 namespace base {
18 class FilePath;
19 }
20 
21 namespace content {
22 class BrowserContext;
23 }
24 
25 namespace extensions {
26 class ExtensionRegistry;
27 class ExtensionService;
28 class ExtensionSystem;
29 
30 // A test class to help with loading packed or unpacked extensions. Designed to
31 // be used by both browser tests and unit tests. Note that this should be used
32 // for a single extension, and is designed to be used on the stack (rather than
33 // as a test suite member).
34 class ChromeTestExtensionLoader {
35  public:
36   explicit ChromeTestExtensionLoader(content::BrowserContext* browser_context);
37   ~ChromeTestExtensionLoader();
38 
39   // Loads the extension specified by |file_path|. Works for both packed and
40   // unpacked extensions.
41   scoped_refptr<const Extension> LoadExtension(const base::FilePath& file_path);
42 
43   // Myriad different settings. See the member variable declarations for
44   // explanations and defaults.
45   // Prefer using these setters rather than adding n different
46   // LoadExtensionWith* variants (that's not scalable).
set_expected_id(const std::string & expected_id)47   void set_expected_id(const std::string& expected_id) {
48     expected_id_ = expected_id;
49   }
add_creation_flag(Extension::InitFromValueFlags flag)50   void add_creation_flag(Extension::InitFromValueFlags flag) {
51     creation_flags_ |= flag;
52   }
set_creation_flags(int flags)53   void set_creation_flags(int flags) { creation_flags_ = flags; }
set_location(Manifest::Location location)54   void set_location(Manifest::Location location) { location_ = location; }
set_should_fail(bool should_fail)55   void set_should_fail(bool should_fail) { should_fail_ = should_fail; }
set_pack_extension(bool pack_extension)56   void set_pack_extension(bool pack_extension) {
57     pack_extension_ = pack_extension;
58   }
set_install_immediately(bool install_immediately)59   void set_install_immediately(bool install_immediately) {
60     install_immediately_ = install_immediately;
61   }
set_grant_permissions(bool grant_permissions)62   void set_grant_permissions(bool grant_permissions) {
63     grant_permissions_ = grant_permissions;
64   }
set_allow_file_access(bool allow_file_access)65   void set_allow_file_access(bool allow_file_access) {
66     allow_file_access_ = allow_file_access;
67   }
set_allow_incognito_access(bool allow_incognito_access)68   void set_allow_incognito_access(bool allow_incognito_access) {
69     allow_incognito_access_ = allow_incognito_access;
70   }
set_ignore_manifest_warnings(bool ignore_manifest_warnings)71   void set_ignore_manifest_warnings(bool ignore_manifest_warnings) {
72     ignore_manifest_warnings_ = ignore_manifest_warnings;
73   }
set_require_modern_manifest_version(bool require_modern_version)74   void set_require_modern_manifest_version(bool require_modern_version) {
75     require_modern_manifest_version_ = require_modern_version;
76   }
set_install_param(const std::string & install_param)77   void set_install_param(const std::string& install_param) {
78     install_param_ = install_param;
79   }
set_wait_for_renderers(bool wait_for_renderers)80   void set_wait_for_renderers(bool wait_for_renderers) {
81     wait_for_renderers_ = wait_for_renderers;
82   }
set_pem_path(const base::FilePath & pem_path)83   void set_pem_path(const base::FilePath& pem_path) { pem_path_ = pem_path; }
84 
85  private:
86   // Packs the extension at |unpacked_path| and returns the path to the created
87   // crx. Note that the created crx is tied to the lifetime of |this|.
88   base::FilePath PackExtension(const base::FilePath& unpacked_path);
89 
90   // Loads the crx pointed to by |crx_path|.
91   scoped_refptr<const Extension> LoadCrx(const base::FilePath& crx_path);
92 
93   // Loads the unpacked extension pointed to by |unpacked_path|.
94   scoped_refptr<const Extension> LoadUnpacked(
95       const base::FilePath& unpacked_path);
96 
97   // Checks that the permissions of the loaded extension are correct.
98   void CheckPermissions(const Extension* extension);
99 
100   // Checks for any install warnings associated with the extension.
101   bool CheckInstallWarnings(const Extension& extension);
102 
103   // Waits for the extension to finish setting up.
104   bool WaitForExtensionReady(const Extension& extension);
105 
106   // The associated context and services.
107   content::BrowserContext* browser_context_ = nullptr;
108   ExtensionSystem* extension_system_ = nullptr;
109   ExtensionService* extension_service_ = nullptr;
110   ExtensionRegistry* extension_registry_ = nullptr;
111 
112   // A temporary directory for packing extensions.
113   base::ScopedTempDir temp_dir_;
114 
115   // The extension id of the loaded extension.
116   std::string extension_id_;
117 
118   // A provided PEM path to use. If not provided, a temporary one will be
119   // created.
120   base::FilePath pem_path_;
121 
122   // The expected extension id, if any.
123   std::string expected_id_;
124 
125   // An install param to use with the loaded extension.
126   std::string install_param_;
127 
128   // Any creation flags (see Extension::InitFromValueFlags) to use for the
129   // extension. Only used for crx installs.
130   int creation_flags_ = Extension::NO_FLAGS;
131 
132   // The install location of the added extension. Not valid for unpacked
133   // extensions.
134   Manifest::Location location_ = Manifest::INTERNAL;
135 
136   // Whether or not the extension load should fail.
137   bool should_fail_ = false;
138 
139   // Whether or not to always pack the extension before loading it. Otherwise,
140   // the extension will be loaded as an unpacked extension.
141   bool pack_extension_ = false;
142 
143   // Whether or not to install the extension immediately. Only used for crx
144   // installs.
145   bool install_immediately_ = true;
146 
147   // Whether or not to automatically grant permissions to the installed
148   // extension. Only used for crx installs.
149   bool grant_permissions_ = true;
150 
151   // Whether or not to allow file access by default to the extension.
152   base::Optional<bool> allow_file_access_;
153 
154   // Whether or not to allow incognito access by default to the extension.
155   bool allow_incognito_access_ = false;
156 
157   // Whether or not to ignore manifest warnings during installation.
158   bool ignore_manifest_warnings_ = false;
159 
160   // Whether or not to enforce a minimum manifest version requirement.
161   bool require_modern_manifest_version_ = true;
162 
163   // Whether to wait for extension renderers to be ready before continuing.
164   // If unspecified, this will default to true if there is at least one existent
165   // renderer and false otherwise (this roughly maps to "true in browser tests,
166   // false in unit tests").
167   base::Optional<bool> wait_for_renderers_;
168 
169   DISALLOW_COPY_AND_ASSIGN(ChromeTestExtensionLoader);
170 };
171 
172 }  // namespace extensions
173 
174 #endif  // CHROME_BROWSER_EXTENSIONS_CHROME_TEST_EXTENSION_LOADER_H_
175