зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1875257 - Part 1: Generalize permission handling of storage-access to all permissions r=whimboo,webdriver-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D198836
This commit is contained in:
Родитель
2f27be1956
Коммит
96445c4f14
|
@ -3317,6 +3317,46 @@ GeckoDriver.prototype.setUserVerified = function (cmd) {
|
|||
|
||||
GeckoDriver.prototype.setPermission = async function (cmd) {
|
||||
const { descriptor, state, oneRealm = false } = cmd.parameters;
|
||||
const browsingContext = lazy.assert.open(this.getBrowsingContext());
|
||||
|
||||
// XXX: WPT should not have these but currently they do and we pass testing pref to
|
||||
// pass them, see bug 1875837.
|
||||
if (
|
||||
["clipboard-read", "clipboard-write"].includes(descriptor.name) &&
|
||||
state === "granted"
|
||||
) {
|
||||
if (
|
||||
Services.prefs.getBoolPref("dom.events.testing.asyncClipboard", false)
|
||||
) {
|
||||
// Okay, do nothing. The clipboard module will work without permission.
|
||||
return;
|
||||
}
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"setPermission: expected dom.events.testing.asyncClipboard to be set"
|
||||
);
|
||||
}
|
||||
|
||||
// XXX: We currently depend on camera/microphone tests throwing UnsupportedOperationError,
|
||||
// the fix is ongoing in bug 1609427.
|
||||
if (["camera", "microphone"].includes(descriptor.name)) {
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"setPermission: camera and microphone permissions are currently unsupported"
|
||||
);
|
||||
}
|
||||
|
||||
// This abuses permissions.query() to do the IDL conversion in step 1 in the spec:
|
||||
// https://w3c.github.io/permissions/#webdriver-command-set-permission
|
||||
// If this does not throw then the descriptor is valid.
|
||||
//
|
||||
// TODO: Currently we consume the original JS object later on, but we should
|
||||
// consume the IDL-converted dictionary instead.
|
||||
// For WPT purpose the current state is fine, but for general webdriver extension
|
||||
// this is not ideal as the script might get access to fields that are not in IDL.
|
||||
try {
|
||||
await this.curBrowser.window.navigator.permissions.query(descriptor);
|
||||
} catch (err) {
|
||||
throw new lazy.error.InvalidArgumentError(`setPermission: ${err.message}`);
|
||||
}
|
||||
|
||||
lazy.assert.boolean(oneRealm);
|
||||
lazy.assert.that(
|
||||
|
@ -3324,13 +3364,7 @@ GeckoDriver.prototype.setPermission = async function (cmd) {
|
|||
`state is ${state}, expected "granted", "denied", or "prompt"`
|
||||
)(state);
|
||||
|
||||
lazy.permissions.set(
|
||||
descriptor,
|
||||
state,
|
||||
oneRealm,
|
||||
this.getBrowsingContext(),
|
||||
this.getBrowsingContext({ top: true })
|
||||
);
|
||||
lazy.permissions.set(descriptor, state, oneRealm, browsingContext);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
assert: "chrome://remote/content/shared/webdriver/Assert.sys.mjs",
|
||||
error: "chrome://remote/content/shared/webdriver/Errors.sys.mjs",
|
||||
MarionettePrefs: "chrome://remote/content/marionette/prefs.sys.mjs",
|
||||
});
|
||||
|
@ -13,6 +12,46 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
|||
/** @namespace */
|
||||
export const permissions = {};
|
||||
|
||||
const specialPermissionNameMap = {
|
||||
geolocation: "geo",
|
||||
notifications: "desktop-notification",
|
||||
};
|
||||
|
||||
function mapToInternalPermissionParameters(browsingContext, descriptor) {
|
||||
const currentURI = browsingContext.currentWindowGlobal.documentURI;
|
||||
|
||||
const { name } = descriptor;
|
||||
|
||||
// storage-access is quite special...
|
||||
if (name === "storage-access") {
|
||||
const thirdPartyPrincipalSite = Services.eTLD.getSite(currentURI);
|
||||
|
||||
const topLevelURI = browsingContext.top.currentWindowGlobal.documentURI;
|
||||
const topLevelPrincipal =
|
||||
Services.scriptSecurityManager.createContentPrincipal(topLevelURI, {});
|
||||
|
||||
return {
|
||||
name: "3rdPartyFrameStorage^" + thirdPartyPrincipalSite,
|
||||
principal: topLevelPrincipal,
|
||||
};
|
||||
}
|
||||
|
||||
const currentPrincipal =
|
||||
Services.scriptSecurityManager.createContentPrincipal(currentURI, {});
|
||||
|
||||
if (name === "midi" && descriptor.sysex) {
|
||||
return {
|
||||
name: "midi-sysex",
|
||||
principal: currentPrincipal,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
name: specialPermissionNameMap[name] ?? name,
|
||||
principal: currentPrincipal,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a permission's state.
|
||||
* Note: Currently just a shim to support testdriver's set_permission.
|
||||
|
@ -23,107 +62,48 @@ export const permissions = {};
|
|||
* State of the permission. It can be `granted`, `denied` or `prompt`.
|
||||
* @param {boolean} oneRealm
|
||||
* Currently ignored
|
||||
* @param {browsingContext=} thirdPartyBrowsingContext
|
||||
* 3rd party browsing context object
|
||||
* @param {browsingContext=} topLevelBrowsingContext
|
||||
* Top level browsing context object
|
||||
* @param {browsingContext=} browsingContext
|
||||
* Current browsing context object
|
||||
* @throws {UnsupportedOperationError}
|
||||
* If `marionette.setpermission.enabled` is not set or
|
||||
* an unsupported permission is used.
|
||||
*/
|
||||
permissions.set = function (
|
||||
descriptor,
|
||||
state,
|
||||
oneRealm,
|
||||
thirdPartyBrowsingContext,
|
||||
topLevelBrowsingContext
|
||||
) {
|
||||
permissions.set = function (descriptor, state, oneRealm, browsingContext) {
|
||||
if (!lazy.MarionettePrefs.setPermissionEnabled) {
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"'Set Permission' is not available"
|
||||
);
|
||||
}
|
||||
|
||||
// This is not a real implementation of the permissions API.
|
||||
// Instead the purpose of this implementation is to have web-platform-tests
|
||||
// that use `set_permission()` not fail.
|
||||
// Each test needs the corresponding testing pref to make it actually work.
|
||||
const { name } = descriptor;
|
||||
|
||||
if (state === "prompt" && name !== "storage-access") {
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"'Set Permission' doesn't support prompt"
|
||||
);
|
||||
}
|
||||
if (["clipboard-write", "clipboard-read"].includes(name)) {
|
||||
if (
|
||||
Services.prefs.getBoolPref("dom.events.testing.asyncClipboard", false)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"'Set Permission' expected dom.events.testing.asyncClipboard to be set"
|
||||
);
|
||||
} else if (name === "notifications") {
|
||||
if (Services.prefs.getBoolPref("notification.prompt.testing", false)) {
|
||||
return;
|
||||
}
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"'Set Permission' expected notification.prompt.testing to be set"
|
||||
);
|
||||
} else if (name === "storage-access") {
|
||||
// Check if browsing context has a window global object
|
||||
lazy.assert.open(thirdPartyBrowsingContext);
|
||||
lazy.assert.open(topLevelBrowsingContext);
|
||||
|
||||
const thirdPartyURI =
|
||||
thirdPartyBrowsingContext.currentWindowGlobal.documentURI;
|
||||
const topLevelURI = topLevelBrowsingContext.currentWindowGlobal.documentURI;
|
||||
|
||||
const thirdPartyPrincipalSite = Services.eTLD.getSite(thirdPartyURI);
|
||||
|
||||
const topLevelPrincipal =
|
||||
Services.scriptSecurityManager.createContentPrincipal(topLevelURI, {});
|
||||
|
||||
switch (state) {
|
||||
case "granted": {
|
||||
Services.perms.addFromPrincipal(
|
||||
topLevelPrincipal,
|
||||
"3rdPartyFrameStorage^" + thirdPartyPrincipalSite,
|
||||
Services.perms.ALLOW_ACTION
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "denied": {
|
||||
Services.perms.addFromPrincipal(
|
||||
topLevelPrincipal,
|
||||
"3rdPartyFrameStorage^" + thirdPartyPrincipalSite,
|
||||
Services.perms.DENY_ACTION
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "prompt": {
|
||||
Services.perms.removeFromPrincipal(
|
||||
topLevelPrincipal,
|
||||
"3rdPartyFrameStorage^" + thirdPartyPrincipalSite
|
||||
);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
`'Set Permission' did not work for storage-access'`
|
||||
);
|
||||
}
|
||||
} else if (name === "screen-wake-lock") {
|
||||
if (Services.prefs.getBoolPref("dom.screenwakelock.testing", false)) {
|
||||
return;
|
||||
}
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"'Set Permission' expected dom.screenwakelock.testing to be set"
|
||||
);
|
||||
}
|
||||
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
`'Set Permission' doesn't support '${name}'`
|
||||
const { name, principal } = mapToInternalPermissionParameters(
|
||||
browsingContext,
|
||||
descriptor
|
||||
);
|
||||
|
||||
switch (state) {
|
||||
case "granted": {
|
||||
Services.perms.addFromPrincipal(
|
||||
principal,
|
||||
name,
|
||||
Services.perms.ALLOW_ACTION
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "denied": {
|
||||
Services.perms.addFromPrincipal(
|
||||
principal,
|
||||
name,
|
||||
Services.perms.DENY_ACTION
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "prompt": {
|
||||
Services.perms.removeFromPrincipal(principal, name);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"Unrecognized permission keyword for 'Set Permission' operation"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче