forked from mirrors/gecko-dev
Mainly automated changes. Some manual ESLint fixes and whitespace cleanup. Differential Revision: https://phabricator.services.mozilla.com/D158452
269 lines
8.4 KiB
JavaScript
269 lines
8.4 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
const ORIGIN = "https://example.com";
|
|
const CROSS_SUBFRAME_PAGE =
|
|
getRootDirectory(gTestPath).replace("chrome://mochitests/content", ORIGIN) +
|
|
"temporary_permissions_subframe.html";
|
|
|
|
const CROSS_FRAME_PAGE =
|
|
getRootDirectory(gTestPath).replace("chrome://mochitests/content", ORIGIN) +
|
|
"temporary_permissions_frame.html";
|
|
|
|
const PromptResult = {
|
|
ALLOW: "allow",
|
|
DENY: "deny",
|
|
PROMPT: "prompt",
|
|
};
|
|
|
|
var Perms = Services.perms;
|
|
var uri = NetUtil.newURI(ORIGIN);
|
|
var principal = Services.scriptSecurityManager.createContentPrincipal(uri, {});
|
|
|
|
async function checkNotificationBothOrigins(
|
|
firstPartyOrigin,
|
|
thirdPartyOrigin
|
|
) {
|
|
// Notification is shown, check label and deny to clean
|
|
let popuphidden = BrowserTestUtils.waitForEvent(
|
|
PopupNotifications.panel,
|
|
"popuphidden"
|
|
);
|
|
|
|
let notification = PopupNotifications.panel.firstElementChild;
|
|
// Check the label of the notificaiton should be the first party
|
|
is(
|
|
PopupNotifications.getNotification("geolocation").options.name,
|
|
firstPartyOrigin,
|
|
"Use first party's origin"
|
|
);
|
|
|
|
// Check the second name of the notificaiton should be the third party
|
|
is(
|
|
PopupNotifications.getNotification("geolocation").options.secondName,
|
|
thirdPartyOrigin,
|
|
"Use third party's origin"
|
|
);
|
|
|
|
// Check remember checkbox is hidden
|
|
let checkbox = notification.checkbox;
|
|
ok(!!checkbox, "checkbox is present");
|
|
ok(checkbox.hidden, "checkbox is not visible");
|
|
ok(!checkbox.checked, "checkbox not checked");
|
|
|
|
EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
|
|
await popuphidden;
|
|
}
|
|
|
|
async function checkGeolocation(browser, frameId, expect) {
|
|
let isPrompt = expect == PromptResult.PROMPT;
|
|
let waitForPrompt;
|
|
if (isPrompt) {
|
|
waitForPrompt = BrowserTestUtils.waitForEvent(
|
|
PopupNotifications.panel,
|
|
"popupshown"
|
|
);
|
|
}
|
|
|
|
await SpecialPowers.spawn(
|
|
browser,
|
|
[{ frameId, expect, isPrompt }],
|
|
async args => {
|
|
let frame = content.document.getElementById(args.frameId);
|
|
|
|
let waitForNoPrompt = new Promise(resolve => {
|
|
function onMessage(event) {
|
|
// Check the result right here because there's no notification
|
|
Assert.equal(
|
|
event.data,
|
|
args.expect,
|
|
"Correct expectation for third party"
|
|
);
|
|
content.window.removeEventListener("message", onMessage);
|
|
resolve();
|
|
}
|
|
|
|
if (!args.isPrompt) {
|
|
content.window.addEventListener("message", onMessage);
|
|
}
|
|
});
|
|
|
|
await content.SpecialPowers.spawn(frame, [], async () => {
|
|
const { E10SUtils } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/E10SUtils.sys.mjs"
|
|
);
|
|
|
|
E10SUtils.wrapHandlingUserInput(this.content, true, function() {
|
|
let frameDoc = this.content.document;
|
|
frameDoc.getElementById("geo").click();
|
|
});
|
|
});
|
|
|
|
if (!args.isPrompt) {
|
|
await waitForNoPrompt;
|
|
}
|
|
}
|
|
);
|
|
|
|
if (isPrompt) {
|
|
await waitForPrompt;
|
|
}
|
|
}
|
|
|
|
add_setup(async function() {
|
|
await new Promise(r => {
|
|
SpecialPowers.pushPrefEnv(
|
|
{
|
|
set: [
|
|
["dom.security.featurePolicy.header.enabled", true],
|
|
["dom.security.featurePolicy.webidl.enabled", true],
|
|
["permissions.delegation.enabled", true],
|
|
],
|
|
},
|
|
r
|
|
);
|
|
});
|
|
});
|
|
|
|
// Test that temp blocked permissions in first party affect the third party
|
|
// iframe.
|
|
add_task(async function testUseTempPermissionsFirstParty() {
|
|
await BrowserTestUtils.withNewTab(CROSS_SUBFRAME_PAGE, async function(
|
|
browser
|
|
) {
|
|
SitePermissions.setForPrincipal(
|
|
principal,
|
|
"geo",
|
|
SitePermissions.BLOCK,
|
|
SitePermissions.SCOPE_TEMPORARY,
|
|
browser
|
|
);
|
|
|
|
await checkGeolocation(browser, "frame", PromptResult.DENY);
|
|
|
|
SitePermissions.removeFromPrincipal(principal, "geo", browser);
|
|
});
|
|
});
|
|
|
|
// Test that persistent permissions in first party affect the third party
|
|
// iframe.
|
|
add_task(async function testUsePersistentPermissionsFirstParty() {
|
|
await BrowserTestUtils.withNewTab(CROSS_SUBFRAME_PAGE, async function(
|
|
browser
|
|
) {
|
|
async function checkPermission(aPermission, aExpect) {
|
|
PermissionTestUtils.add(uri, "geo", aPermission);
|
|
await checkGeolocation(browser, "frame", aExpect);
|
|
|
|
if (aExpect == PromptResult.PROMPT) {
|
|
// Notification is shown, check label and deny to clean
|
|
let popuphidden = BrowserTestUtils.waitForEvent(
|
|
PopupNotifications.panel,
|
|
"popuphidden"
|
|
);
|
|
|
|
let notification = PopupNotifications.panel.firstElementChild;
|
|
// Check the label of the notificaiton should be the first party
|
|
is(
|
|
PopupNotifications.getNotification("geolocation").options.name,
|
|
uri.host,
|
|
"Use first party's origin"
|
|
);
|
|
|
|
EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
|
|
|
|
await popuphidden;
|
|
SitePermissions.removeFromPrincipal(null, "geo", browser);
|
|
}
|
|
|
|
PermissionTestUtils.remove(uri, "geo");
|
|
}
|
|
|
|
await checkPermission(Perms.PROMPT_ACTION, PromptResult.PROMPT);
|
|
await checkPermission(Perms.DENY_ACTION, PromptResult.DENY);
|
|
await checkPermission(Perms.ALLOW_ACTION, PromptResult.ALLOW);
|
|
});
|
|
});
|
|
|
|
// Test that we do not prompt for maybe unsafe permission delegation if the
|
|
// origin of the page is the original src origin.
|
|
add_task(async function testPromptInMaybeUnsafePermissionDelegation() {
|
|
await BrowserTestUtils.withNewTab(CROSS_SUBFRAME_PAGE, async function(
|
|
browser
|
|
) {
|
|
// Persistent allow top level origin
|
|
PermissionTestUtils.add(uri, "geo", Perms.ALLOW_ACTION);
|
|
|
|
await checkGeolocation(browser, "frameAllowsAll", PromptResult.ALLOW);
|
|
|
|
SitePermissions.removeFromPrincipal(null, "geo", browser);
|
|
PermissionTestUtils.remove(uri, "geo");
|
|
});
|
|
});
|
|
|
|
// Test that we should prompt if we are in unsafe permission delegation and
|
|
// change location to origin which is not explicitly trusted. The prompt popup
|
|
// should include both first and third party origin.
|
|
add_task(async function testPromptChangeLocationUnsafePermissionDelegation() {
|
|
await BrowserTestUtils.withNewTab(CROSS_SUBFRAME_PAGE, async function(
|
|
browser
|
|
) {
|
|
// Persistent allow top level origin
|
|
PermissionTestUtils.add(uri, "geo", Perms.ALLOW_ACTION);
|
|
|
|
let iframe = await SpecialPowers.spawn(browser, [], () => {
|
|
return content.document.getElementById("frameAllowsAll").browsingContext;
|
|
});
|
|
|
|
let otherURI =
|
|
"https://test1.example.com/browser/browser/base/content/test/permissions/permissions.html";
|
|
let loaded = BrowserTestUtils.browserLoaded(browser, true, otherURI);
|
|
await SpecialPowers.spawn(iframe, [otherURI], async function(_otherURI) {
|
|
content.location = _otherURI;
|
|
});
|
|
await loaded;
|
|
|
|
await checkGeolocation(browser, "frameAllowsAll", PromptResult.PROMPT);
|
|
await checkNotificationBothOrigins(uri.host, "test1.example.com");
|
|
|
|
SitePermissions.removeFromPrincipal(null, "geo", browser);
|
|
PermissionTestUtils.remove(uri, "geo");
|
|
});
|
|
});
|
|
|
|
// If we are in unsafe permission delegation and the origin is explicitly
|
|
// trusted in ancestor chain. Do not need prompt
|
|
add_task(async function testExplicitlyAllowedInChain() {
|
|
await BrowserTestUtils.withNewTab(CROSS_FRAME_PAGE, async function(browser) {
|
|
// Persistent allow top level origin
|
|
PermissionTestUtils.add(uri, "geo", Perms.ALLOW_ACTION);
|
|
|
|
let iframeAncestor = await SpecialPowers.spawn(browser, [], () => {
|
|
return content.document.getElementById("frameAncestor").browsingContext;
|
|
});
|
|
|
|
let iframe = await SpecialPowers.spawn(iframeAncestor, [], () => {
|
|
return content.document.getElementById("frameAllowsAll").browsingContext;
|
|
});
|
|
|
|
// Change location to check that we actually look at the ancestor chain
|
|
// instead of just considering the "same origin as src" rule.
|
|
let otherURI =
|
|
"https://test2.example.com/browser/browser/base/content/test/permissions/permissions.html";
|
|
let loaded = BrowserTestUtils.browserLoaded(browser, true, otherURI);
|
|
await SpecialPowers.spawn(iframe, [otherURI], async function(_otherURI) {
|
|
content.location = _otherURI;
|
|
});
|
|
await loaded;
|
|
|
|
await checkGeolocation(
|
|
iframeAncestor,
|
|
"frameAllowsAll",
|
|
PromptResult.ALLOW
|
|
);
|
|
|
|
PermissionTestUtils.remove(uri, "geo");
|
|
});
|
|
});
|