8000 feat: implement allowFileAccess loadExtension option by nornagon · Pull Request #27703 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: implement allowFileAccess loadExtension option #27703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/api/browser-window.md
8000
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ The method will also not return if the extension's manifest is missing or incomp
is emitted.

**Note:** This method is deprecated. Instead, use
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
[`ses.loadExtension(path)`](session.md#sesloadextensionpath-options).

#### `BrowserWindow.removeExtension(name)` _Deprecated_

Expand Down Expand Up @@ -775,7 +775,7 @@ The method will also not return if the extension's manifest is missing or incomp
is emitted.

**Note:** This method is deprecated. Instead, use
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
[`ses.loadExtension(path)`](session.md#sesloadextensionpath-options).

#### `BrowserWindow.removeDevToolsExtension(name)` _Deprecated_

Expand Down
2 changes: 1 addition & 1 deletion docs/api/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension capabilities.

Electron only supports loading unpacked extensions (i.e., `.crx` files do not
work). Extensions are installed per-`session`. To load an extension, call
[`ses.loadExtension`](session.md#sesloadextensionpath):
[`ses.loadExtension`](session.md#sesloadextensionpath-options):

```js
const { session } = require('electron')
Expand Down
12 changes: 10 additions & 2 deletions docs/api/session.md
Original file line number Diff line number Diff line change
Expand Up @@ -568,9 +568,13 @@ will not work on non-persistent (in-memory) sessions.

**Note:** On macOS and Windows 10 this word will be removed from the OS custom dictionary as well

#### `ses.loadExtension(path)`
#### `ses.loadExtension(path[, options])`

* `path` String - Path to a directory containing an unpacked Chrome extension
* `options` Object (optional)
* `allowFileAccess` Boolean - Whether to allow the extension to read local files over `file://`
protocol and inject content scripts into `file://` pages. This is required e.g. for loading
devtools extensions on `file://` URLs. Defaults to false.

Returns `Promise<Extension>` - resolves when the extension is loaded.

Expand All @@ -593,7 +597,11 @@ const { app, session } = require('electron')
const path = require('path')

app.on('ready', async () => {
await session.defaultSession.loadExtension(path.join(__dirname, 'react-devtools'))
await session.defaultSession.loadExtension(
path.join(__dirname, 'react-devtools'),
// allowFileAccess is required to load the devtools extension on file:// URLs.
{ allowFileAccess: true }
)
// Note that in order to use the React DevTools extension, you'll need to
// download and unzip a copy of the extension.
})
Expand Down
14 changes: 12 additions & 2 deletions shell/browser/api/electron_api_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,8 @@ std::vector<base::FilePath::StringType> Session::GetPreloads() const {

#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
v8::Local<v8::Promise> Session::LoadExtension(
const base::FilePath& extension_path) {
const base::FilePath& extension_path,
gin::Arguments* args) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
gin_helper::Promise<const extensions::Extension*> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();
Expand All @@ -697,10 +698,19 @@ v8::Local<v8::Promise> Session::LoadExtension(
return handle;
}

int load_flags = extensions::Extension::FOLLOW_SYMLINKS_ANYWHERE;
gin_helper::Dictionary options;
if (args->GetNext(&options)) {
bool allowFileAccess = false;
options.Get("allowFileAccess", &allowFileAccess);
if (allowFileAccess)
load_flags |= extensions::Extension::ALLOW_FILE_ACCESS;
}

auto* extension_system = static_cast<extensions::ElectronExtensionSystem*>(
extensions::ExtensionSystem::Get(browser_context()));
extension_system->LoadExtension(
extension_path,
extension_path, load_flags,
base::BindOnce(
[](gin_helper::Promise<const extensions::Extension*> promise,
const extensions::Extension* extension,
Expand Down
3 changes: 2 additions & 1 deletion shell/browser/api/electron_api_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ class Session : public gin::Wrappable<Session>,
#endif

#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
v8::Local<v8::Promise> LoadExtension(const base::FilePath& extension_path);
v8::Local<v8::Promise> LoadExtension(const base::FilePath& extension_path,
gin::Arguments* args);
void RemoveExtension(const std::string& extension_id);
v8::Local<v8::Value> GetExtension(const std::string& extension_id);
v8::Local<v8::Value> GetAllExtensions();
Expand Down
13 changes: 9 additions & 4 deletions shell/browser/extensions/electron_extension_loader.cc
< 9E88 td id="diff-4fde23c4dd9b89775e3c7828137112ad0aa25d0c2aa04479e3fd4021173309b3L180" data-line-number="180" class="blob-num blob-num-deletion js-linkable-line-number">
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ using LoadErrorBehavior = ExtensionRegistrar::LoadErrorBehavior;
namespace {

std::pair<scoped_refptr<const Extension>, std::string> LoadUnpacked(
const base::FilePath& extension_dir) {
const base::FilePath& extension_dir,
int load_flags) {
// app_shell only supports unpacked extensions.
// NOTE: If you add packed extension support consider removing the flag
// FOLLOW_SYMLINKS_ANYWHERE below. Packed extensions should not have symlinks.
Expand All @@ -40,7 +41,6 @@ std::pair<scoped_refptr<const Extension>, std::string> LoadUnpacked(
return std::make_pair(nullptr, err);
}

int load_flags = Extension::FOLLOW_SYMLINKS_ANYWHERE;
std::string load_error;
scoped_refptr<Extension> extension = file_util::LoadExtension(
extension_dir, Manifest::COMMAND_LINE, load_flags, &load_error);
Expand Down Expand Up @@ -76,10 +76,11 @@ ElectronExtensionLoader::~ElectronExtensionLoader() = default;

void ElectronExtensionLoader::LoadExtension(
const base::FilePath& extension_dir,
int load_flags,
base::OnceCallback<void(const Extension*, const std::string&)> cb) {
base::PostTaskAndReplyWithResult(
GetExtensionFileTaskRunner().get(), FROM_HERE,
base::BindOnce(&LoadUnpacked, extension_dir),
base::BindOnce(&LoadUnpacked, extension_dir, load_flags),
base::BindOnce(&ElectronExtensionLoader::FinishExtensionLoad,
weak_factory_.GetWeakPtr(), std::move(cb)));
}
Expand Down Expand Up @@ -175,9 +176,13 @@ void ElectronExtensionLoader::LoadExtensionForReload(
LoadErrorBehavior load_error_behavior) {
CHECK(!path.empty());

// TODO(nornagon): we should save whether file access was granted
// when loading this extension and retain it here. As is, reloading an
// extension will cause the file access permission to be dropped.
int load_flags = Extension::FOLLOW_SYMLINKS_ANYWHERE;
base::PostTaskAndReplyWithResult(
GetExtensionFileTaskRunner().get(), FROM_HERE,
base::BindOnce(&LoadUnpacked, path),
base::BindOnce(&LoadUnpacked, path, load_flags),
base::BindOnce(&ElectronExtensionLoader::FinishExtensionReload,
weak_factory_.GetWeakPtr(), extension_id));
did_schedule_reload_ = true;
Expand Down
1 change: 1 addition & 0 deletions shell/browser/extensions/electron_extension_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ElectronExtensionLoader : public ExtensionRegistrar::Delegate {
// Loads an unpacked extension from a directory synchronously. Returns the
// extension on success, or nullptr otherwise.
void LoadExtension(const base::FilePath& extension_dir,
int load_flags,
base::OnceCallback<void(const Extension* extension,
const std::string&)> cb);

Expand Down
3 changes: 2 additions & 1 deletion shell/browser/extensions/electron_extension_system.cc
< B7A6 th scope="col">Diff line change
Original file line number Diff line number
Expand Up @@ -56,8 +56,9 @@ ElectronExtensionSystem::~ElectronExtensionSystem() = default;

void ElectronExtensionSystem::LoadExtension(
const base::FilePath& extension_dir,
int load_flags,
base::OnceCallback<void(const Extension*, const std::string&)> cb) {
extension_loader_->LoadExtension(extension_dir, std::move(cb));
extension_loader_->LoadExtension(extension_dir, load_flags, std::move(cb));
}

void ElectronExtensionSystem::FinishInitialization() {
Expand Down
1 change: 1 addition & 0 deletions shell/browser/extensions/electron_extension_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ElectronExtensionSystem : public ExtensionSystem {
// success, or nullptr otherwise.
void LoadExtension(
const base::FilePath& extension_dir,
int load_flags,
base::OnceCallback<void(const Extension*, const std::string&)> cb);

// Finish initialization for the shell extension system.
Expand Down
0