forked from mirrors/gecko-dev
Automatic changes by ESLint, except for manual corrections for .xml files. Differential Revision: https://phabricator.services.mozilla.com/D4439 --HG-- extra : moz-landing-system : lando
186 lines
6.5 KiB
JavaScript
186 lines
6.5 KiB
JavaScript
/**
|
|
* When "privacy.resistFingerprinting" is set to true, user permission is
|
|
* required for canvas data extraction.
|
|
* This tests whether the site permission prompt for canvas data extraction
|
|
* works properly.
|
|
*/
|
|
"use strict";
|
|
|
|
const kUrl = "https://example.com/";
|
|
const kPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(Services.io.newURI(kUrl), {});
|
|
const kPermission = "canvas";
|
|
|
|
function initTab() {
|
|
let contentWindow = content.wrappedJSObject;
|
|
|
|
let drawCanvas = (fillStyle, id) => {
|
|
let contentDocument = contentWindow.document;
|
|
let width = 64, height = 64;
|
|
let canvas = contentDocument.createElement("canvas");
|
|
if (id) {
|
|
canvas.setAttribute("id", id);
|
|
}
|
|
canvas.setAttribute("width", width);
|
|
canvas.setAttribute("height", height);
|
|
contentDocument.body.appendChild(canvas);
|
|
|
|
let context = canvas.getContext("2d");
|
|
context.fillStyle = fillStyle;
|
|
context.fillRect(0, 0, width, height);
|
|
|
|
if (id) {
|
|
let button = contentDocument.createElement("button");
|
|
button.addEventListener("click", function() { canvas.toDataURL(); });
|
|
button.setAttribute("id", "clickme");
|
|
button.innerHTML = "Click Me!";
|
|
contentDocument.body.appendChild(button);
|
|
}
|
|
|
|
return canvas;
|
|
};
|
|
|
|
let placeholder = drawCanvas("white");
|
|
contentWindow.kPlaceholderData = placeholder.toDataURL();
|
|
let canvas = drawCanvas("cyan", "canvas-id-canvas");
|
|
isnot(canvas.toDataURL(), contentWindow.kPlaceholderData,
|
|
"privacy.resistFingerprinting = false, canvas data != placeholder data");
|
|
}
|
|
|
|
function enableResistFingerprinting(autoDeclineNoInput) {
|
|
return SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["privacy.resistFingerprinting", true],
|
|
["privacy.resistFingerprinting.autoDeclineNoUserInputCanvasPrompts", autoDeclineNoInput],
|
|
],
|
|
});
|
|
}
|
|
|
|
function promisePopupShown() {
|
|
return BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
|
|
}
|
|
|
|
function promisePopupHidden() {
|
|
return BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
|
|
}
|
|
|
|
function extractCanvasData(grantPermission) {
|
|
let contentWindow = content.wrappedJSObject;
|
|
let canvas = contentWindow.document.getElementById("canvas-id-canvas");
|
|
let canvasData = canvas.toDataURL();
|
|
if (grantPermission) {
|
|
isnot(canvasData, contentWindow.kPlaceholderData,
|
|
"privacy.resistFingerprinting = true, permission granted, canvas data != placeholderdata");
|
|
} else if (grantPermission === false) {
|
|
is(canvasData, contentWindow.kPlaceholderData,
|
|
"privacy.resistFingerprinting = true, permission denied, canvas data == placeholderdata");
|
|
} else {
|
|
is(canvasData, contentWindow.kPlaceholderData,
|
|
"privacy.resistFingerprinting = true, requesting permission, canvas data == placeholderdata");
|
|
}
|
|
}
|
|
|
|
function triggerCommand(button) {
|
|
let notifications = PopupNotifications.panel.children;
|
|
let notification = notifications[0];
|
|
EventUtils.synthesizeMouseAtCenter(notification[button], {});
|
|
}
|
|
|
|
function triggerMainCommand() {
|
|
triggerCommand("button");
|
|
}
|
|
|
|
function triggerSecondaryCommand() {
|
|
triggerCommand("secondaryButton");
|
|
}
|
|
|
|
function testPermission() {
|
|
return Services.perms.testPermissionFromPrincipal(kPrincipal, kPermission);
|
|
}
|
|
|
|
async function withNewTabNoInput(grantPermission, browser) {
|
|
await ContentTask.spawn(browser, null, initTab);
|
|
await enableResistFingerprinting(false);
|
|
let popupShown = promisePopupShown();
|
|
await ContentTask.spawn(browser, null, extractCanvasData);
|
|
await popupShown;
|
|
let popupHidden = promisePopupHidden();
|
|
if (grantPermission) {
|
|
triggerMainCommand();
|
|
await popupHidden;
|
|
is(testPermission(), Services.perms.ALLOW_ACTION, "permission granted");
|
|
} else {
|
|
triggerSecondaryCommand();
|
|
await popupHidden;
|
|
is(testPermission(), Services.perms.DENY_ACTION, "permission denied");
|
|
}
|
|
await ContentTask.spawn(browser, grantPermission, extractCanvasData);
|
|
await SpecialPowers.popPrefEnv();
|
|
}
|
|
|
|
async function doTestNoInput(grantPermission) {
|
|
Services.perms.removeFromPrincipal(kPrincipal, kPermission);
|
|
await BrowserTestUtils.withNewTab(kUrl, withNewTabNoInput.bind(null, grantPermission));
|
|
}
|
|
|
|
// With auto-declining disabled (not the default)
|
|
// Tests clicking "Don't Allow" button of the permission prompt.
|
|
add_task(doTestNoInput.bind(null, false));
|
|
|
|
// Tests clicking "Allow" button of the permission prompt.
|
|
add_task(doTestNoInput.bind(null, true));
|
|
|
|
// I don't know how to write a test for "Make sure a prompt is not shown"...
|
|
// But ideally we would have one of those...
|
|
|
|
function extractCanvasDataUserInput(grantPermission) {
|
|
let contentWindow = content.wrappedJSObject;
|
|
let canvas = contentWindow.document.getElementById("canvas-id-canvas");
|
|
let canvasData = canvas.toDataURL();
|
|
if (grantPermission) {
|
|
isnot(canvasData, contentWindow.kPlaceholderData,
|
|
"privacy.resistFingerprinting = true, permission granted, canvas data != placeholderdata");
|
|
} else if (grantPermission === false) {
|
|
is(canvasData, contentWindow.kPlaceholderData,
|
|
"privacy.resistFingerprinting = true, permission denied, canvas data == placeholderdata");
|
|
} else {
|
|
is(canvasData, contentWindow.kPlaceholderData,
|
|
"privacy.resistFingerprinting = true, requesting permission, canvas data == placeholderdata");
|
|
}
|
|
}
|
|
|
|
async function withNewTabInput(grantPermission, browser) {
|
|
await ContentTask.spawn(browser, null, initTab);
|
|
await enableResistFingerprinting(true);
|
|
let popupShown = promisePopupShown();
|
|
await ContentTask.spawn(browser, null, function(host) {
|
|
E10SUtils.wrapHandlingUserInput(content, true, function() {
|
|
var button = content.document.getElementById("clickme");
|
|
button.click();
|
|
});
|
|
});
|
|
await popupShown;
|
|
let popupHidden = promisePopupHidden();
|
|
if (grantPermission) {
|
|
triggerMainCommand();
|
|
await popupHidden;
|
|
is(testPermission(), Services.perms.ALLOW_ACTION, "permission granted");
|
|
} else {
|
|
triggerSecondaryCommand();
|
|
await popupHidden;
|
|
is(testPermission(), Services.perms.DENY_ACTION, "permission denied");
|
|
}
|
|
await ContentTask.spawn(browser, grantPermission, extractCanvasDataUserInput);
|
|
await SpecialPowers.popPrefEnv();
|
|
}
|
|
|
|
async function doTestInput(grantPermission, autoDeclineNoInput) {
|
|
Services.perms.removeFromPrincipal(kPrincipal, kPermission);
|
|
await BrowserTestUtils.withNewTab(kUrl, withNewTabInput.bind(null, grantPermission));
|
|
}
|
|
|
|
// With auto-declining enabled (the default)
|
|
// Tests clicking "Don't Allow" button of the permission prompt.
|
|
add_task(doTestInput.bind(null, false));
|
|
|
|
// Tests clicking "Allow" button of the permission prompt.
|
|
add_task(doTestInput.bind(null, true));
|