forked from mirrors/gecko-dev
This patch was generated as follows: Run: `./mach esmify --imports . --prefix=toolkit/mozapps/extensions/AddonManager` In the output there are linter/prettifier errors due to unused XPCOMUtils or separate importESModule calls. These have been fixed manually and verified with `./mach lint --outgoing`. The `esmify` script also inserts many unwanted newlines around imports that are broken on two lines due to length. Due to the number of these, I fixed them programatically. 1. Create patch from the changes so far. 2. From the patch, delete all lines that consist of "+" (i.e. added blank line). 3. Reset the working dir and apply the revised patch. 4. Verify that the diff between step 1 and 3 looks reasonable. 5. Verify that this patch as a whole looks reasonable. Commands: ``` git diff > rename.diff :%g/^+$/d git commit -va -m WIP-rename git revert HEAD git apply --recount rename.diff git diff HEAD^ # and verify that the removed lines are ok. git commit -va # one last review to verify correctness of whole patch. git rebase -i HEAD~3 # drop the WIP + reverted commit, pick only the last. ``` `git apply` has the `--recount` option to force it to ignore mismatches in line counts, which happens because we deleted added lines (^+$) without fixing up the line counts in the file headers. Differential Revision: https://phabricator.services.mozilla.com/D179874
385 lines
10 KiB
JavaScript
385 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.importESModule(
|
|
"resource://gre/modules/AddonManager.sys.mjs"
|
|
);
|
|
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 l10n = new Localization([
|
|
"toolkit/global/extensions.ftl",
|
|
"toolkit/global/extensionPermissions.ftl",
|
|
"branding/brand.ftl",
|
|
]);
|
|
// Localization resources need to be first iterated outside a test
|
|
l10n.formatValue("webext-perms-sideload-text");
|
|
|
|
// Lazily import ExtensionParent to allow AddonTestUtils.createAppInfo to
|
|
// override Services.appinfo.
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
ExtensionParent: "resource://gre/modules/ExtensionParent.sys.mjs",
|
|
});
|
|
|
|
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");
|
|
|
|
for (const perm of SCHEMA_SITE_PERMISSIONS) {
|
|
const l10nId = `webext-site-perms-${perm}`;
|
|
try {
|
|
const str = await l10n.formatValue(l10nId);
|
|
|
|
ok(str.length, `Found localization string for '${perm}' site permission`);
|
|
} catch (e) {
|
|
ok(false, `Site permission missing '${perm}'`);
|
|
}
|
|
}
|
|
});
|