Skip to content
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

browser(firefox): grant permissions to all origins #1405

Merged
merged 1 commit into from
Mar 17, 2020
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
2 changes: 1 addition & 1 deletion browser_patches/firefox/BUILD_NUMBER
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1042
1043
86 changes: 61 additions & 25 deletions browser_patches/firefox/patches/bootstrap.diff
Original file line number Diff line number Diff line change
Expand Up @@ -458,10 +458,10 @@ index 5de630a1db847a09651b310928bb7bc4d4f66f29..0268bc2bdfb3bfda2ef6e01a5dd24209
nsCOMPtr<nsIPrincipal> principal =
diff --git a/juggler/BrowserContextManager.js b/juggler/BrowserContextManager.js
new file mode 100644
index 0000000000000000000000000000000000000000..670ffa0bf10b3bdc98a732b740c41c217f0bc720
index 0000000000000000000000000000000000000000..6c3d918022f0e8ff84083cb20266c97902cd04d4
--- /dev/null
+++ b/juggler/BrowserContextManager.js
@@ -0,0 +1,199 @@
@@ -0,0 +1,214 @@
+"use strict";
+
+const {ContextualIdentityService} = ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm");
Expand Down Expand Up @@ -541,6 +541,8 @@ index 0000000000000000000000000000000000000000..670ffa0bf10b3bdc98a732b740c41c21
+ this.userContextId = identity.userContextId;
+ }
+ this._principals = [];
+ // Maps origins to the permission lists.
+ this._permissions = new Map();
+ this._manager._browserContextIdToBrowserContext.set(this.browserContextId, this);
+ this._manager._userContextIdToBrowserContext.set(this.userContextId, this);
+ this.options = options || {};
Expand All @@ -562,13 +564,7 @@ index 0000000000000000000000000000000000000000..670ffa0bf10b3bdc98a732b740c41c21
+ }
+
+ grantPermissions(origin, permissions) {
+ const attrs = { userContextId: this.userContextId || undefined };
+ const principal = Services.scriptSecurityManager.createContentPrincipal(NetUtil.newURI(origin), attrs);
+ this._principals.push(principal);
+ for (const permission of ALL_PERMISSIONS) {
+ const action = permissions.includes(permission) ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION;
+ Services.perms.addFromPrincipal(principal, permission, action, Ci.nsIPermissionManager.EXPIRE_NEVER, 0 /* expireTime */);
+ }
+ this._permissions.set(origin, permissions);
+ }
+
+ resetPermissions() {
Expand All @@ -577,6 +573,25 @@ index 0000000000000000000000000000000000000000..670ffa0bf10b3bdc98a732b740c41c21
+ Services.perms.removeFromPrincipal(principal, permission);
+ }
+ this._principals = [];
+ this._permissions.clear();
+ }
+
+ grantPermissionsToOrigin(url) {
+ let origin = Array.from(this._permissions.keys()).find(key => url.startsWith(key));
+ if (!origin)
+ origin = '*';
+
+ const permissions = this._permissions.get(origin);
+ if (!permissions)
+ return;
+
+ const attrs = { userContextId: this.userContextId || undefined };
+ const principal = Services.scriptSecurityManager.createContentPrincipal(NetUtil.newURI(url), attrs);
+ this._principals.push(principal);
+ for (const permission of ALL_PERMISSIONS) {
+ const action = permissions.includes(permission) ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION;
+ Services.perms.addFromPrincipal(principal, permission, action, Ci.nsIPermissionManager.EXPIRE_NEVER, 0 /* expireTime */);
+ }
+ }
+
+ setCookies(cookies) {
Expand Down Expand Up @@ -1612,10 +1627,10 @@ index 0000000000000000000000000000000000000000..ba34976ad05e7f5f1a99777f76ac08b1
+this.SimpleChannel = SimpleChannel;
diff --git a/juggler/TargetRegistry.js b/juggler/TargetRegistry.js
new file mode 100644
index 0000000000000000000000000000000000000000..98071c0e2c5429cfe8f29c390de3944f7f6e52a9
index 0000000000000000000000000000000000000000..eab73deee89cc7c8ab0a304f79126264de5c4f8e
--- /dev/null
+++ b/juggler/TargetRegistry.js
@@ -0,0 +1,250 @@
@@ -0,0 +1,264 @@
+const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
+const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
Expand Down Expand Up @@ -1673,11 +1688,10 @@ index 0000000000000000000000000000000000000000..98071c0e2c5429cfe8f29c390de3944f
+ Services.obs.addObserver(this, 'oop-frameloader-crashed');
+ }
+
+ async ensurePermissionsInContextPages(browserContextId, permissions) {
+ pageTargets(browserContextId) {
+ const browserContext = this._contextManager.browserContextForId(browserContextId);
+ const pageTargets = [...this._targets.values()].filter(target => target instanceof PageTarget);
+ const contextPages = pageTargets.filter(target => target._browserContext === browserContext);
+ await Promise.all(contextPages.map(page => page._channel.connect('').send('ensurePermissions', permissions).catch(e => void e)));
+ return pageTargets.filter(target => target._browserContext === browserContext);
+ }
+
+ async newPage({browserContextId}) {
Expand Down Expand Up @@ -1775,10 +1789,16 @@ index 0000000000000000000000000000000000000000..98071c0e2c5429cfe8f29c390de3944f
+ this._registry = registry;
+ this._tab = tab;
+ this._browserContext = browserContext;
+ this._url = '';
+ this._openerId = opener ? opener.id() : undefined;
+ this._channel = SimpleChannel.createForMessageManager(`browser::page[${this._targetId}]`, tab.linkedBrowser.messageManager);
+
+ const navigationListener = {
+ QueryInterface: ChromeUtils.generateQI([ Ci.nsIWebProgressListener]),
+ onLocationChange: (aWebProgress, aRequest, aLocation) => this._onNavigated(aLocation),
+ };
+ this._eventListeners = [
+ helper.addProgressListener(tab.linkedBrowser, navigationListener, Ci.nsIWebProgress.NOTIFY_LOCATION),
+ helper.addMessageListener(tab.linkedBrowser.messageManager, 'juggler:content-ready', {
+ receiveMessage: () => this._onContentReady()
+ }),
Expand Down Expand Up @@ -1839,6 +1859,15 @@ index 0000000000000000000000000000000000000000..98071c0e2c5429cfe8f29c390de3944f
+ };
+ }
+
+ _onNavigated(aLocation) {
+ this._url = aLocation.spec;
+ this._browserContext.grantPermissionsToOrigin(this._url);
+ }
+
+ async ensurePermissions(permissions) {
+ await this._channel.connect('').send('ensurePermissions', permissions).catch(e => void e);
+ }
+
+ dispose() {
+ helper.removeListeners(this._eventListeners);
+ }
Expand Down Expand Up @@ -4146,7 +4175,7 @@ index 0000000000000000000000000000000000000000..3a386425d3796d0a6786dea193b3402d
+
diff --git a/juggler/content/main.js b/juggler/content/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..212f1c1a218efebe8685b019e79fb553db720453
index 0000000000000000000000000000000000000000..6ce6eff8dc8852d7fbbac907421de6de39d8ed0e
--- /dev/null
+++ b/juggler/content/main.js
@@ -0,0 +1,129 @@
Expand All @@ -4163,7 +4192,7 @@ index 0000000000000000000000000000000000000000..212f1c1a218efebe8685b019e79fb553
+ 'geo',
+ 'microphone',
+ 'camera',
+ 'desktop-notifications',
+ 'desktop-notification',
+];
+
+const scrollbarManager = new ScrollbarManager(docShell);
Expand Down Expand Up @@ -4360,10 +4389,10 @@ index 0000000000000000000000000000000000000000..2f2b7ca247f6b6dff396fb4b644654de
+this.AccessibilityHandler = AccessibilityHandler;
diff --git a/juggler/protocol/BrowserHandler.js b/juggler/protocol/BrowserHandler.js
new file mode 100644
index 0000000000000000000000000000000000000000..060174f997f4a607c9e6d7bf4e1e204f07fe86c7
index 0000000000000000000000000000000000000000..a5f050cd024dfdd3d7b1366600273744f82c5cbb
--- /dev/null
+++ b/juggler/protocol/BrowserHandler.js
@@ -0,0 +1,163 @@
@@ -0,0 +1,172 @@
+"use strict";
+
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
Expand Down Expand Up @@ -4481,8 +4510,17 @@ index 0000000000000000000000000000000000000000..060174f997f4a607c9e6d7bf4e1e204f
+ }
+
+ async grantPermissions({browserContextId, origin, permissions}) {
+ this._contextManager.browserContextForId(browserContextId).grantPermissions(origin, permissions);
+ await this._targetRegistry.ensurePermissionsInContextPages(browserContextId, permissions);
+ const browserContext = this._contextManager.browserContextForId(browserContextId);
+ browserContext.grantPermissions(origin, permissions);
+ const contextPages = this._targetRegistry.pageTargets(browserContextId);
+ const promises = [];
+ for (const page of contextPages) {
+ if (origin === '*' || page._url.startsWith(origin)) {
+ browserContext.grantPermissionsToOrigin(page._url);
+ promises.push(page.ensurePermissions(permissions));
+ }
+ }
+ await Promise.all(promises);
+ }
+
+ resetPermissions({browserContextId}) {
Expand Down Expand Up @@ -5398,10 +5436,10 @@ index 0000000000000000000000000000000000000000..78b6601b91d0b7fcda61114e6846aa07
+this.EXPORTED_SYMBOLS = ['t', 'checkScheme'];
diff --git a/juggler/protocol/Protocol.js b/juggler/protocol/Protocol.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f7f4ce40454257ff83e8d39b278c1dbc1353991
index 0000000000000000000000000000000000000000..9b636b045df0737039d94b5a6efc8c4f004eb58a
--- /dev/null
+++ b/juggler/protocol/Protocol.js
@@ -0,0 +1,747 @@
@@ -0,0 +1,745 @@
+const {t, checkScheme} = ChromeUtils.import('chrome://juggler/content/protocol/PrimitiveTypes.js');
+
+// Protocol-specific types.
Expand Down Expand Up @@ -5662,9 +5700,7 @@ index 0000000000000000000000000000000000000000..9f7f4ce40454257ff83e8d39b278c1db
+ params: {
+ origin: t.String,
+ browserContextId: t.Optional(t.String),
+ permissions: t.Array(t.Enum([
+ 'geo', 'microphone', 'camera', 'desktop-notifications'
+ ])),
+ permissions: t.Array(t.String),
+ },
+ },
+ 'resetPermissions': {
Expand Down