-
Notifications
You must be signed in to change notification settings - Fork 15k
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
feat: implement allowFileAccess loadExtension option #25198
feat: implement allowFileAccess loadExtension option #25198
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the options
argument for ses.loadExtension
. Making use of ExtensionPrefs
should help with the remaining work on this PR. 👍
@@ -155,9 +156,10 @@ void ElectronExtensionLoader::LoadExtensionForReload( | |||
LoadErrorBehavior load_error_behavior) { | |||
CHECK(!path.empty()); | |||
|
|||
int load_flags = Extension::FOLLOW_SYMLINKS_ANYWHERE; // FIXME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a place where ExtensionPrefs
would be useful. Looking at Chrome's installed extension loader, they use this to store global and extension-specific preferences at runtime—including methods for getting/setting file access.
In Session::LoadExtension
, we could call ExtensionPrefs::SetAllowFileAccess
with the value of the allowFileAccess
option. Then ElectronExtensionLoader
can derive the load_flags
from ExtensionPrefs
. Chrome's InstalledLoader::GetCreationFlags
is a good example of how this could work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@samuelmaddock thanks for the feedback!
I thought about that, but the thing I noticed while testing (#24011 (comment)) is that:
- This preference doesn't appear to do anything on it's own, or it could do something I don't know yet.
- In Chromium, this is apparently not what is used.
- A call to
ExtensionPrefs::SetAllowFileAccess
writes to{profile}/Preferences
. - But in Chromium that doesn't happen when file access is enabled in extension preferences.
- Instead, Chromium stores that in
{profile}/Current Session
which is inexistent in Electron.
- A call to
My concern here is that as Chromium apparently doesn't use it in that scenario, perhaps ExtensionPrefs::SetAllowFileAccess
does something else and can have some other side effect?
Or is that not the case?
I can surely port to that if it would be safe to use it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking more into this, Chrome implements a private API on the chrome://extensions page with a function chrome.developerPrivate.updateExtensionConfiguration(config, callback)
. It's internal implementation calls a utility which in turn calls ExtensionPrefs::SetAllowFileAccess
.
After this function is called, the value will stay in memory and (I think) persist to disk soon after. An extension loader implements a GetCreationFlags
method to then derive flags from ExtensionPrefs
.
In my opinion, sticking with this pattern close to Chrome will allow us to more naturally build on the extension support in Electron later on.
As for the the location of prefs ({profile}/Preferences
), I'm not sure what the right path would be for us. I think we can go with the default and change it later if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe Electron persists such preferences to disk. Additionally, I'd prefer that the extensions loading stuff doesn't persist anything to disk internally, as that's often surprising for developers (e.g. "i removed the loadExtension(...)
line from my app, why is the react devtools extension still loading??" behavior that used to be present.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update on ExtensionPrefs
, they're mostly used by Chrome to persist extension settings for a profile.
- Whether an extension has file access or can run in incognito mode.
- The extension installation time.
- If an extension is disabled, the reason why.
- And many other Chrome-specific settings.
These aren't too relevant to an Electron app and could be managed outside of Electron internal code. However, special cases such as chrome.runtime.reload()
will cause this setting to be dropped without relying on storage such as ExtensionPrefs
.
Additionally, ExtensionPrefs
do end up persisting to disk using the same JsonPrefStore
as UserPrefs
which are setup in ElectronBrowserContext::InitPrefs
.
To avoid this behavior, I believe it will be necessary to create an InMemoryPrefStore
exclusively for ExtensionPrefs which would be returned from ElectronExtensionsBrowserClient::GetPrefServiceForContext
. Possibly a command-line flag could be used if a developer wanted to opt-in to persisting these settings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ChALkeR to followup, we can simplify this by avoiding ExtensionPrefs
altogether. Adding a map of
extensionId -> allowFileAccess
could be added to ElectronExtensionLoader
. When an extension is unloaded, we can clear it. That way we can allow persisting file access if an extension is reloaded.
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
The API WG reviewed this at the Sept 21, 2020 meeting |
I'm happy to land this without the fix for remembering file access across extension reload. The latter is a smaller bug than what this fixes. |
What's the status on this? |
Very important PR to my project. What are the remaining blockers? I'd like to help if possible. |
@ChALkeR would you still like to move this forward? |
This is a necessary feature, so hopefully it can be moved forward 😃. I'm willing to help too, if more help is needed. |
We really want this to be merged and are ready to help move this forward! |
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com> Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com> Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Thank you for going the extra mile here with the back ports! We really appreciate it! |
Yes yes, thank you thank you! <3 |
@nornagon Will the fix for this issue can be backported to electron v9 which is still on the supported line versions? |
@twitharshil no, we are only backporting security fixes to v9. |
Per electron/electron#23662 and electron/electron#25198 this is necessary to allow access to extensions via file:// Closes MarshallOfSound#161 Closes MarshallOfSound#162
Description of Change
Alternative to #25151.
Allows file access for extensions via an opt-in on per-extension basis.
Pre-9 this was essentially "enabled" by default, until 9.0.0 broke react devtools on local
file://
urls (#24011).LoadExtensionForReload()
-- not sure yet when that is triggered. Probably replacing that with an additional method that sets the flags for a certain extension id and is stored in-memory would be a better approach.Fixes: #24011.
Confirmed that react-devtools now works over
file://
ifallowFileAccess: true
is passed and doesn't work otherwise.cc @nornagon @samuelmaddock @RangerMauve
Thoughts? It would be helpful to hear which approach should be continued, this one or #25151.
Checklist
npm test
passesRelease Notes
Notes: Added
allowFileAccess
option toloadExtension()
API.