forked from mirrors/gecko-dev
387 lines
10 KiB
JavaScript
387 lines
10 KiB
JavaScript
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set sts=2 sw=2 et tw=80: */
|
|
"use strict";
|
|
|
|
// TODO(Bug 1789718): adapt to synthetic addon type implemented by the SitePermAddonProvider
|
|
// or remove if redundant, after the deprecated XPIProvider-based implementation is also removed.
|
|
|
|
const { AddonManager } = ChromeUtils.import(
|
|
"resource://gre/modules/AddonManager.jsm"
|
|
);
|
|
const { TestUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/TestUtils.sys.mjs"
|
|
);
|
|
|
|
const { TelemetryController } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/TelemetryController.sys.mjs"
|
|
);
|
|
const { TelemetryTestUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/TelemetryTestUtils.sys.mjs"
|
|
);
|
|
|
|
AddonTestUtils.init(this);
|
|
AddonTestUtils.overrideCertDB();
|
|
AddonTestUtils.createAppInfo(
|
|
"xpcshell@tests.mozilla.org",
|
|
"XPCShell",
|
|
"42",
|
|
"42"
|
|
);
|
|
|
|
const BROWSER_PROPERTIES =
|
|
AppConstants.MOZ_APP_NAME == "thunderbird"
|
|
? "chrome://messenger/locale/addons.properties"
|
|
: "chrome://browser/locale/browser.properties";
|
|
|
|
// Lazily import ExtensionParent to allow AddonTestUtils.createAppInfo to
|
|
// override Services.appinfo.
|
|
ChromeUtils.defineModuleGetter(
|
|
this,
|
|
"ExtensionParent",
|
|
"resource://gre/modules/ExtensionParent.jsm"
|
|
);
|
|
|
|
async function _test_manifest(manifest, expectedError) {
|
|
ExtensionTestUtils.failOnSchemaWarnings(false);
|
|
let normalized = await ExtensionTestUtils.normalizeManifest(
|
|
manifest,
|
|
"manifest.WebExtensionSitePermissionsManifest"
|
|
);
|
|
ExtensionTestUtils.failOnSchemaWarnings(true);
|
|
|
|
if (expectedError) {
|
|
ok(
|
|
normalized.error.includes(expectedError),
|
|
`The manifest error ${JSON.stringify(
|
|
normalized.error
|
|
)} must contain ${JSON.stringify(expectedError)}`
|
|
);
|
|
} else {
|
|
equal(normalized.error, undefined, "Should not have an error");
|
|
}
|
|
equal(normalized.errors.length, 0, "Should have no warning");
|
|
}
|
|
|
|
add_setup(async () => {
|
|
// Telemetry test setup needed to ensure that the builtin events are defined
|
|
// and they can be collected and verified.
|
|
await TelemetryController.testSetup();
|
|
|
|
// This is actually only needed on Android, because it does not properly support unified telemetry
|
|
// and so, if not enabled explicitly here, it would make these tests to fail when running on
|
|
// release builds.
|
|
const oldCanRecordBase = Services.telemetry.canRecordBase;
|
|
Services.telemetry.canRecordBase = true;
|
|
registerCleanupFunction(() => {
|
|
Services.telemetry.canRecordBase = oldCanRecordBase;
|
|
});
|
|
});
|
|
|
|
add_task(async function test_manifest_site_permissions() {
|
|
await _test_manifest({
|
|
site_permissions: ["midi"],
|
|
install_origins: ["http://example.com"],
|
|
});
|
|
await _test_manifest({
|
|
site_permissions: ["midi-sysex"],
|
|
install_origins: ["http://example.com"],
|
|
});
|
|
await _test_manifest(
|
|
{
|
|
site_permissions: ["unknown_site_permission"],
|
|
install_origins: ["http://example.com"],
|
|
},
|
|
`Error processing site_permissions.0: Invalid enumeration value "unknown_site_permission"`
|
|
);
|
|
await _test_manifest(
|
|
{
|
|
site_permissions: ["unknown_site_permission"],
|
|
install_origins: [],
|
|
},
|
|
`Error processing install_origins: Array requires at least 1 items;`
|
|
);
|
|
await _test_manifest(
|
|
{
|
|
site_permissions: ["unknown_site_permission"],
|
|
},
|
|
`Property "install_origins" is required`
|
|
);
|
|
await _test_manifest(
|
|
{
|
|
install_origins: ["http://example.com"],
|
|
},
|
|
`Property "site_permissions" is required`
|
|
);
|
|
// test any extra manifest entries not part of a site permissions addon will cause an error.
|
|
await _test_manifest(
|
|
{
|
|
site_permissions: ["midi"],
|
|
install_origins: ["http://example.com"],
|
|
permissions: ["webRequest"],
|
|
},
|
|
`Unexpected property`
|
|
);
|
|
});
|
|
|
|
add_task(async function test_sitepermission_telemetry() {
|
|
await AddonTestUtils.promiseStartupManager();
|
|
|
|
Services.telemetry.clearEvents();
|
|
|
|
const addon_id = "webmidi@test";
|
|
const origin = "https://example.com";
|
|
const permName = "midi";
|
|
|
|
let site_permission = {
|
|
"manifest.json": {
|
|
name: "test Site Permission",
|
|
version: "1.0",
|
|
manifest_version: 2,
|
|
browser_specific_settings: {
|
|
gecko: { id: addon_id },
|
|
},
|
|
install_origins: [origin],
|
|
site_permissions: [permName],
|
|
},
|
|
};
|
|
|
|
let [, { addon }] = await Promise.all([
|
|
TestUtils.topicObserved("webextension-sitepermissions-startup"),
|
|
AddonTestUtils.promiseInstallXPI(site_permission),
|
|
]);
|
|
|
|
await addon.uninstall();
|
|
|
|
await TelemetryTestUtils.assertEvents(
|
|
[
|
|
[
|
|
"addonsManager",
|
|
"install",
|
|
"siteperm_deprecated",
|
|
/.*/,
|
|
{
|
|
step: "started",
|
|
addon_id,
|
|
},
|
|
],
|
|
[
|
|
"addonsManager",
|
|
"install",
|
|
"siteperm_deprecated",
|
|
/.*/,
|
|
{
|
|
step: "completed",
|
|
addon_id,
|
|
},
|
|
],
|
|
["addonsManager", "uninstall", "siteperm_deprecated", addon_id],
|
|
],
|
|
{
|
|
category: "addonsManager",
|
|
method: /^install|uninstall$/,
|
|
}
|
|
);
|
|
|
|
await AddonTestUtils.promiseShutdownManager();
|
|
});
|
|
|
|
async function _test_ext_site_permissions(site_permissions, install_origins) {
|
|
ExtensionTestUtils.failOnSchemaWarnings(false);
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
install_origins,
|
|
site_permissions,
|
|
},
|
|
});
|
|
await extension.startup();
|
|
await extension.unload();
|
|
ExtensionTestUtils.failOnSchemaWarnings(true);
|
|
}
|
|
|
|
add_task(async function test_ext_site_permissions() {
|
|
await _test_ext_site_permissions(["midi"], ["http://example.com"]);
|
|
|
|
await _test_ext_site_permissions(
|
|
["midi"],
|
|
["http://example.com", "http://foo.com"]
|
|
).catch(e => {
|
|
Assert.ok(
|
|
e.message.includes(
|
|
"Error processing install_origins: Array requires at most 1 items; you have 2"
|
|
),
|
|
"Site permissions can only contain one install origin: "
|
|
);
|
|
});
|
|
});
|
|
|
|
add_task(async function test_sitepermission_type() {
|
|
await AddonTestUtils.promiseStartupManager();
|
|
|
|
// Test more than one perm to make sure both are added.
|
|
// While this is allowed, midi-sysex overrides.
|
|
let perms = ["midi", "midi-sysex"];
|
|
let id = "@test-permission";
|
|
let origin = "http://example.com";
|
|
let uri = Services.io.newURI(origin);
|
|
let principal = Services.scriptSecurityManager.createContentPrincipal(
|
|
uri,
|
|
{}
|
|
);
|
|
|
|
// give the site some other permission (geo)
|
|
Services.perms.addFromPrincipal(
|
|
principal,
|
|
"geo",
|
|
Services.perms.ALLOW_ACTION,
|
|
Services.perms.EXPIRE_NEVER
|
|
);
|
|
|
|
let assertGeo = () => {
|
|
Assert.equal(
|
|
Services.perms.testExactPermissionFromPrincipal(principal, "geo"),
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
"site still has geo permission"
|
|
);
|
|
};
|
|
|
|
let checkPerms = (perms, action, msg) => {
|
|
for (let permName of perms) {
|
|
let permission = Services.perms.testExactPermissionFromPrincipal(
|
|
principal,
|
|
permName
|
|
);
|
|
Assert.equal(permission, action, `${permName}: ${msg}`);
|
|
}
|
|
};
|
|
|
|
checkPerms(
|
|
perms,
|
|
Ci.nsIPermissionManager.UNKNOWN_ACTION,
|
|
"no permission for site"
|
|
);
|
|
|
|
let site_permission = {
|
|
"manifest.json": {
|
|
name: "test Site Permission",
|
|
version: "1.0",
|
|
manifest_version: 2,
|
|
browser_specific_settings: {
|
|
gecko: {
|
|
id,
|
|
},
|
|
},
|
|
install_origins: [origin],
|
|
site_permissions: perms,
|
|
},
|
|
};
|
|
|
|
let [, { addon }] = await Promise.all([
|
|
TestUtils.topicObserved("webextension-sitepermissions-startup"),
|
|
AddonTestUtils.promiseInstallXPI(site_permission),
|
|
]);
|
|
|
|
checkPerms(
|
|
perms,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
"extension enabled permission for site"
|
|
);
|
|
assertGeo();
|
|
|
|
// Test the permission is retained on restart.
|
|
await AddonTestUtils.promiseRestartManager();
|
|
addon = await AddonManager.getAddonByID(id);
|
|
|
|
checkPerms(
|
|
perms,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
"extension enabled permission for site"
|
|
);
|
|
assertGeo();
|
|
|
|
// Test that a removed permission is added on restart
|
|
Services.perms.removeFromPrincipal(principal, perms[0]);
|
|
await AddonTestUtils.promiseRestartManager();
|
|
addon = await AddonManager.getAddonByID(id);
|
|
|
|
checkPerms(
|
|
perms,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
"extension enabled permission for site"
|
|
);
|
|
assertGeo();
|
|
|
|
// Test that a changed permission is not changed on restart
|
|
Services.perms.addFromPrincipal(
|
|
principal,
|
|
perms[0],
|
|
Services.perms.DENY_ACTION,
|
|
Services.perms.EXPIRE_NEVER
|
|
);
|
|
|
|
await AddonTestUtils.promiseRestartManager();
|
|
addon = await AddonManager.getAddonByID(id);
|
|
|
|
checkPerms(
|
|
[perms[0]],
|
|
Ci.nsIPermissionManager.DENY_ACTION,
|
|
"extension enabled permission for site"
|
|
);
|
|
checkPerms(
|
|
[perms[1]],
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
"extension enabled permission for site"
|
|
);
|
|
assertGeo();
|
|
|
|
// Test permission removal when addon disabled
|
|
await addon.disable();
|
|
|
|
checkPerms(
|
|
perms,
|
|
Ci.nsIPermissionManager.UNKNOWN_ACTION,
|
|
"no permission for site"
|
|
);
|
|
assertGeo();
|
|
|
|
// Enabling an addon will always force ALLOW_ACTION
|
|
await addon.enable();
|
|
|
|
checkPerms(
|
|
perms,
|
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
"extension enabled permission for site"
|
|
);
|
|
assertGeo();
|
|
|
|
// Test permission removal when addon uninstalled
|
|
await addon.uninstall();
|
|
|
|
checkPerms(
|
|
perms,
|
|
Ci.nsIPermissionManager.UNKNOWN_ACTION,
|
|
"no permission for site"
|
|
);
|
|
assertGeo();
|
|
});
|
|
|
|
add_task(async function test_site_permissions_have_localization_strings() {
|
|
await ExtensionParent.apiManager.lazyInit();
|
|
const SCHEMA_SITE_PERMISSIONS = Schemas.getPermissionNames([
|
|
"SitePermission",
|
|
]);
|
|
ok(SCHEMA_SITE_PERMISSIONS.length, "we have site permissions");
|
|
|
|
const bundle = Services.strings.createBundle(BROWSER_PROPERTIES);
|
|
|
|
for (const perm of SCHEMA_SITE_PERMISSIONS) {
|
|
try {
|
|
const str = bundle.GetStringFromName(
|
|
`webextSitePerms.description.${perm}`
|
|
);
|
|
|
|
ok(str.length, `Found localization string for '${perm}' site permission`);
|
|
} catch (e) {
|
|
ok(false, `Site permission missing '${perm}'`);
|
|
}
|
|
}
|
|
});
|