diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /toolkit/mozapps/extensions/test/xpcshell/test_update_isPrivileged.js | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/mozapps/extensions/test/xpcshell/test_update_isPrivileged.js')
-rw-r--r-- | toolkit/mozapps/extensions/test/xpcshell/test_update_isPrivileged.js | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_isPrivileged.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_isPrivileged.js new file mode 100644 index 0000000000..7177b27a97 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_isPrivileged.js @@ -0,0 +1,182 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +ChromeUtils.defineModuleGetter( + this, + "ExtensionParent", + "resource://gre/modules/ExtensionParent.jsm" +); + +AddonTestUtils.usePrivilegedSignatures = id => id === "privileged@ext"; + +const EXTENSION_API_IMPL = ` +this.extensionApiImpl = class extends ExtensionAPI { + onStartup() { + extensions.emit("test-ExtensionAPI-onStartup", { + extensionId: this.extension.id, + version: this.extension.manifest.version, + }); + } + static onUpdate(id, manifest) { + extensions.emit("test-ExtensionAPI-onUpdate", { + extensionId: id, + version: manifest.version, + }); + } +};`; + +function setupTestExtensionAPI() { + // The EXTENSION_API_IMPL script is going to be loaded in the main process, + // where only safe loads are permitted. So we generate a resource:-URL, to + // avoid the use of security.allow_parent_unrestricted_js_loads. + let resProto = Services.io + .getProtocolHandler("resource") + .QueryInterface(Ci.nsIResProtocolHandler); + resProto.setSubstitution( + "extensionApiImplJs", + Services.io.newURI(`data:,${encodeURIComponent(EXTENSION_API_IMPL)}`) + ); + registerCleanupFunction(() => { + resProto.setSubstitution("extensionApiImplJs", null); + }); + + const modules = { + extensionApiImpl: { + url: "resource://extensionApiImplJs", + events: ["startup", "update"], + }, + }; + + Services.catMan.addCategoryEntry( + "webextension-modules", + "test-register-extensionApiImpl", + `data:,${JSON.stringify(modules)}`, + false, + false + ); +} + +async function runInstallAndUpdate({ + extensionId, + expectPrivileged, + installExtensionData, +}) { + let extensionData = { + useAddonManager: "permanent", + manifest: { + browser_specific_settings: { gecko: { id: extensionId } }, + version: "1.1", + }, + }; + let events = []; + function onUpdated(type, params) { + params = { type, ...params }; + // resourceURI cannot be serialized for use with deepEqual. + delete params.resourceURI; + events.push(params); + } + function onExtensionAPI(type, params) { + events.push({ type, ...params }); + } + ExtensionParent.apiManager.on("update", onUpdated); + ExtensionParent.apiManager.on("test-ExtensionAPI-onStartup", onExtensionAPI); + ExtensionParent.apiManager.on("test-ExtensionAPI-onUpdate", onExtensionAPI); + + let { addon } = await installExtensionData(extensionData); + equal(addon.isPrivileged, expectPrivileged, "Expected isPrivileged"); + + extensionData.manifest.version = "2.22"; + extensionData.manifest.permissions = ["mozillaAddons"]; + // May warn about invalid permissions when the extension is not privileged. + ExtensionTestUtils.failOnSchemaWarnings(false); + let extension = await installExtensionData(extensionData); + ExtensionTestUtils.failOnSchemaWarnings(true); + await extension.unload(); + + ExtensionParent.apiManager.off("update", onUpdated); + ExtensionParent.apiManager.off("test-ExtensionAPI-onStartup", onExtensionAPI); + ExtensionParent.apiManager.off("test-ExtensionAPI-onUpdate", onExtensionAPI); + + // Verify that we have (1) installed and (2) updated the extension. + Assert.deepEqual( + events, + [ + { type: "test-ExtensionAPI-onStartup", extensionId, version: "1.1" }, + // The next two events show that ExtensionParent has run the onUpdate + // handler, during which ExtensionData has supposedly been constructed. + { type: "update", id: extensionId, isPrivileged: expectPrivileged }, + { type: "test-ExtensionAPI-onUpdate", extensionId, version: "2.22" }, + { type: "test-ExtensionAPI-onStartup", extensionId, version: "2.22" }, + ], + "Expected startup and update events" + ); +} + +add_task(async function setup() { + setupTestExtensionAPI(); + await ExtensionTestUtils.startAddonManager(); +}); + +// Tests that privileged extensions (e.g builtins) are always parsed with the +// correct isPrivileged flag. +add_task(async function test_install_and_update_builtin() { + let { messages } = await promiseConsoleOutput(async () => { + await runInstallAndUpdate({ + extensionId: "builtin@ext", + expectPrivileged: true, + async installExtensionData(extData) { + return installBuiltinExtension(extData); + }, + }); + }); + + AddonTestUtils.checkMessages(messages, { + expected: [{ message: /Addon with ID builtin@ext already installed,/ }], + forbidden: [{ message: /Invalid extension permission: mozillaAddons/ }], + }); +}); + +add_task(async function test_install_and_update_regular_ext() { + let { messages } = await promiseConsoleOutput(async () => { + await runInstallAndUpdate({ + extensionId: "regular@ext", + expectPrivileged: false, + async installExtensionData(extData) { + let extension = ExtensionTestUtils.loadExtension(extData); + await extension.startup(); + return extension; + }, + }); + }); + let errPattern = /Loading extension 'regular@ext': Reading manifest: Invalid extension permission: mozillaAddons/; + let permissionWarnings = messages.filter(msg => errPattern.test(msg.message)); + // Expected number of warnings after triggering the update: + // 1. Generated when the loaded by the Addons manager (ExtensionData). + // 2. Generated when read again before ExtensionAPI.onUpdate (ExtensionData). + // 3. Generated when the extension actually runs (Extension). + equal(permissionWarnings.length, 3, "Expected number of permission warnings"); +}); + +add_task(async function test_install_and_update_privileged_ext() { + let { messages } = await promiseConsoleOutput(async () => { + await runInstallAndUpdate({ + extensionId: "privileged@ext", + expectPrivileged: true, + async installExtensionData(extData) { + let extension = ExtensionTestUtils.loadExtension(extData); + await extension.startup(); + return extension; + }, + }); + }); + AddonTestUtils.checkMessages(messages, { + expected: [ + // First installation. + { message: /Starting install of privileged@ext / }, + // Second installation (update). + { message: /Starting install of privileged@ext / }, + ], + forbidden: [{ message: /Invalid extension permission: mozillaAddons/ }], + }); +}); |