482 lines
12 KiB
JavaScript
482 lines
12 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
https://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
|
|
});
|
|
|
|
const COLLECTION_NAME = "remote-permissions";
|
|
const ORIGIN_1 = "https://example.com";
|
|
const PRINCIPAL_1 = Services.scriptSecurityManager.createContentPrincipal(
|
|
Services.io.newURI(ORIGIN_1),
|
|
{}
|
|
);
|
|
const PRINCIPAL_1_PB = Services.scriptSecurityManager.createContentPrincipal(
|
|
Services.io.newURI(ORIGIN_1),
|
|
{ privateBrowsingId: 1 }
|
|
);
|
|
const ORIGIN_2 = "https://example.org";
|
|
const PRINCIPAL_2 = Services.scriptSecurityManager.createContentPrincipal(
|
|
Services.io.newURI(ORIGIN_2),
|
|
{}
|
|
);
|
|
const PRINCIPAL_2_PB = Services.scriptSecurityManager.createContentPrincipal(
|
|
Services.io.newURI(ORIGIN_2),
|
|
{ privateBrowsingId: 1 }
|
|
);
|
|
const ORIGIN_INVALID = "not a valid origin";
|
|
const TEST_PERMISSION_1 = "test-permission-1";
|
|
const TEST_PERMISSION_2 = "test-permission-2";
|
|
|
|
let rs = RemoteSettings(COLLECTION_NAME);
|
|
let pm = Services.perms;
|
|
let rps = Cc["@mozilla.org/remote-permission-service;1"].getService(
|
|
Ci.nsIRemotePermissionService
|
|
);
|
|
|
|
async function remoteSettingsSync({ created, updated, deleted }) {
|
|
await rs.emit("sync", {
|
|
data: {
|
|
created,
|
|
updated,
|
|
deleted,
|
|
},
|
|
});
|
|
}
|
|
|
|
function expectPermissions(perms) {
|
|
Assert.deepEqual(
|
|
pm.all
|
|
.map(({ principal, type, capability }) => ({
|
|
principal: principal.siteOrigin,
|
|
type,
|
|
capability,
|
|
}))
|
|
.sort((a, b) => a.principal.localeCompare(b.principal)),
|
|
perms
|
|
.map(({ principal, type, capability }) => ({
|
|
principal: principal.siteOrigin,
|
|
type,
|
|
capability,
|
|
}))
|
|
.sort((a, b) => a.principal.localeCompare(b.principal)),
|
|
"Permission manager should have expected permissions"
|
|
);
|
|
}
|
|
|
|
add_setup(async function () {
|
|
Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
|
|
do_get_profile();
|
|
|
|
// This needs to be restored on cleanup
|
|
let originalPermissionValues = structuredClone(
|
|
rps.testAllowedPermissionValues
|
|
);
|
|
|
|
await rps.isInitialized;
|
|
|
|
// Make sure we start off "empty". Any RemoteSettings values must be
|
|
// purged now to comply with test expectations.
|
|
Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
|
|
|
|
registerCleanupFunction(async () => {
|
|
info("Cleaning up");
|
|
rps.testAllowedPermissionValues = originalPermissionValues;
|
|
Services.prefs.clearUserPref("permissions.manager.defaultsUrl");
|
|
Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
|
|
Services.perms.removeAll();
|
|
});
|
|
|
|
// Allow setting everything
|
|
rps.testAllowedPermissionValues = {
|
|
"*": ["*"],
|
|
};
|
|
});
|
|
|
|
add_task(async function test_create_permission() {
|
|
info("Creating permission");
|
|
|
|
await remoteSettingsSync({
|
|
created: [
|
|
{
|
|
origin: ORIGIN_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
],
|
|
});
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_1_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
]);
|
|
});
|
|
|
|
add_task(async function test_update_permission_value() {
|
|
info("Updating permission value");
|
|
|
|
await remoteSettingsSync({
|
|
updated: [
|
|
{
|
|
old: {
|
|
origin: ORIGIN_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
new: {
|
|
origin: ORIGIN_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_1_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
]);
|
|
});
|
|
|
|
add_task(async function test_update_permission_origin() {
|
|
info("Updating permission origin");
|
|
|
|
await remoteSettingsSync({
|
|
updated: [
|
|
{
|
|
old: {
|
|
origin: ORIGIN_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
new: {
|
|
origin: ORIGIN_2,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_2,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_2_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
]);
|
|
});
|
|
|
|
add_task(async function test_user_permission_restoration() {
|
|
info("Overriding with user permission");
|
|
|
|
pm.addFromPrincipal(
|
|
PRINCIPAL_2,
|
|
TEST_PERMISSION_1,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION
|
|
);
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_2,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_2_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
]);
|
|
|
|
info("Removing user permission");
|
|
|
|
pm.removeFromPrincipal(PRINCIPAL_2, TEST_PERMISSION_1);
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_2,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_2_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
]);
|
|
});
|
|
|
|
add_task(async function test_remove_all_restoration() {
|
|
info("Overriding with user permission and adding new user permission");
|
|
|
|
pm.addFromPrincipal(
|
|
PRINCIPAL_1,
|
|
TEST_PERMISSION_1,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION
|
|
);
|
|
pm.addFromPrincipal(
|
|
PRINCIPAL_2,
|
|
TEST_PERMISSION_1,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION
|
|
);
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_2,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_2_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
]);
|
|
|
|
info("Removing all permissions");
|
|
|
|
pm.removeAll();
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_2,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_2_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
]);
|
|
});
|
|
|
|
add_task(async function test_delete_permission() {
|
|
info("Deleting permission");
|
|
|
|
await remoteSettingsSync({
|
|
deleted: [
|
|
{
|
|
origin: ORIGIN_2,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
],
|
|
});
|
|
|
|
expectPermissions([]);
|
|
});
|
|
|
|
add_task(async function test_allowlist() {
|
|
info("Only allowing TEST_PERMISSION_1 with value ALLOW_ACTION");
|
|
|
|
rps.testAllowedPermissionValues = {
|
|
[TEST_PERMISSION_1]: [Ci.nsIPermissionManager.ALLOW_ACTION],
|
|
};
|
|
|
|
info("Trying to add all sorts of default permissions");
|
|
|
|
await remoteSettingsSync({
|
|
created: [ORIGIN_1, ORIGIN_2].flatMap(origin =>
|
|
[TEST_PERMISSION_1, TEST_PERMISSION_2].flatMap(type =>
|
|
[
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
Ci.nsIPermissionManager.DENY_ACTION,
|
|
Ci.nsIPermissionManager.PROMPT_ACTION,
|
|
].flatMap(capability => ({ origin, type, capability }))
|
|
)
|
|
),
|
|
});
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_1_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_2,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_2_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
]);
|
|
|
|
rps.testAllowedPermissionValues = {
|
|
"*": ["*"],
|
|
};
|
|
});
|
|
|
|
add_task(async function test_defaults_url() {
|
|
info("Testing interaction with permissions.manager.defaultsUrl");
|
|
|
|
info("Setting up permissions.manager.defaultsUrl");
|
|
|
|
let file = do_get_tempdir();
|
|
file.append("test_default_permissions");
|
|
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
|
Ci.nsIFileOutputStream
|
|
);
|
|
ostream.init(file, -1, 0o666, 0);
|
|
let conv = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(
|
|
Ci.nsIConverterOutputStream
|
|
);
|
|
conv.init(ostream, "UTF-8");
|
|
conv.writeString(
|
|
[
|
|
"host",
|
|
TEST_PERMISSION_1,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
ORIGIN_1,
|
|
].join("\t") + "\n"
|
|
);
|
|
conv.writeString(
|
|
[
|
|
"host",
|
|
TEST_PERMISSION_2,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
ORIGIN_1,
|
|
].join("\t") + "\n"
|
|
);
|
|
ostream.close();
|
|
|
|
Services.prefs.setCharPref(
|
|
"permissions.manager.defaultsUrl",
|
|
"file://" + file.path
|
|
);
|
|
|
|
info("Re-initializing permission manager");
|
|
|
|
// Start from a clean slate with our new default permissions from
|
|
// permissions.manager.defaultsUrl
|
|
Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
|
|
Services.perms.removeAll();
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_1_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_1,
|
|
type: TEST_PERMISSION_2,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_1_PB,
|
|
type: TEST_PERMISSION_2,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
]);
|
|
|
|
info("Overriding permissions from permissions.manager.defaultsUrl");
|
|
|
|
await remoteSettingsSync({
|
|
created: [
|
|
{
|
|
origin: ORIGIN_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
{
|
|
origin: ORIGIN_1,
|
|
type: TEST_PERMISSION_2,
|
|
capability: Ci.nsIPermissionManager.UNKNOWN_ACTION,
|
|
},
|
|
],
|
|
});
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_1_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
|
},
|
|
]);
|
|
});
|
|
|
|
add_task(async function test_malformed_origin() {
|
|
info(
|
|
"Testing that import will continue after encountering a malformed origin"
|
|
);
|
|
|
|
await remoteSettingsSync({
|
|
created: [
|
|
{
|
|
origin: ORIGIN_INVALID,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
// TEST_PERMISSION_1 still exists for ORIGIN_1 from the previous step, but
|
|
// for simplicity we act like it is new here. We will see if the value has
|
|
// changed from deny to allow.
|
|
{
|
|
origin: ORIGIN_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
],
|
|
});
|
|
|
|
expectPermissions([
|
|
{
|
|
principal: PRINCIPAL_1,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
{
|
|
principal: PRINCIPAL_1_PB,
|
|
type: TEST_PERMISSION_1,
|
|
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
},
|
|
]);
|
|
});
|