commit 637bcd0503db Author: Tom Schuster Date: Thu Sep 28 12:46:09 2017 +0200 Bug 1403723 - Correct metadata when using management.get. r=mixedpuppy, a=ritu * * * Bug 1403721 - Limit management.get to allowed addon types. r=mixedpuppy --- toolkit/components/extensions/ext-management.js | 36 ++++++++++++++-------- .../test/xpcshell/test_ext_experiments.js | 25 +++++++++++++++ .../test/xpcshell/test_ext_management.js | 8 +++++ .../mozapps/extensions/internal/XPIProvider.jsm | 4 +++ 4 files changed, 61 insertions(+), 12 deletions(-) diff --git toolkit/components/extensions/ext-management.js toolkit/components/extensions/ext-management.js index 0e46732b201d..d86a15ceb6a1 100644 --- toolkit/components/extensions/ext-management.js +++ toolkit/components/extensions/ext-management.js @@ -91,6 +91,16 @@ const listenerMap = new WeakMap(); // Some management APIs are intentionally limited. const allowedTypes = ["theme", "extension"]; +function checkAllowedAddon(addon) { + if (addon.isSystem || addon.isAPIExtension) { + return false; + } + if (addon.type == "extension" && !addon.isWebExtension) { + return false; + } + return allowedTypes.includes(addon.type); +} + class AddonListener { constructor() { AddonManager.addAddonListener(this); @@ -106,33 +116,29 @@ class AddonListener { return getExtensionInfoForAddon(ext, addon); } - checkAllowed(addon) { - return !addon.isSystem && allowedTypes.includes(addon.type); - } - onEnabled(addon) { - if (!this.checkAllowed(addon)) { + if (!checkAllowedAddon(addon)) { return; } this.emit("onEnabled", this.getExtensionInfo(addon)); } onDisabled(addon) { - if (!this.checkAllowed(addon)) { + if (!checkAllowedAddon(addon)) { return; } this.emit("onDisabled", this.getExtensionInfo(addon)); } onInstalled(addon) { - if (!this.checkAllowed(addon)) { + if (!checkAllowedAddon(addon)) { return; } this.emit("onInstalled", this.getExtensionInfo(addon)); } onUninstalled(addon) { - if (!this.checkAllowed(addon)) { + if (!checkAllowedAddon(addon)) { return; } this.emit("onUninstalled", this.getExtensionInfo(addon)); @@ -167,16 +173,22 @@ this.management = class extends ExtensionAPI { management: { async get(id) { let addon = await AddonManager.getAddonByID(id); - if (!addon.isSystem) { - return getExtensionInfoForAddon(extension, addon); + if (!addon) { + throw new ExtensionError(`No such addon ${id}`); + } + if (!checkAllowedAddon(addon)) { + throw new ExtensionError("get not allowed for this addon"); } + // If the extension is enabled get it and use it for more data. + let ext = GlobalManager.extensionMap.get(addon.id); + return getExtensionInfoForAddon(ext, addon); }, async getAll() { let addons = await AddonManager.getAddonsByTypes(allowedTypes); - return addons.filter(addon => !addon.isSystem).map(addon => { + return addons.filter(checkAllowedAddon).map(addon => { // If the extension is enabled get it and use it for more data. - let ext = addon.isWebExtension && GlobalManager.extensionMap.get(addon.id); + let ext = GlobalManager.extensionMap.get(addon.id); return getExtensionInfoForAddon(ext, addon); }); }, diff --git toolkit/components/extensions/test/xpcshell/test_ext_experiments.js toolkit/components/extensions/test/xpcshell/test_ext_experiments.js index 343e1e50d983..c8d097decf90 100644 --- toolkit/components/extensions/test/xpcshell/test_ext_experiments.js +++ toolkit/components/extensions/test/xpcshell/test_ext_experiments.js @@ -148,6 +148,31 @@ add_task(async function test_experiments_api() { let hello = await promise; equal(hello, "Here I am", "Should get hello from add-on"); + // Install management test add-on. + let managementAddon = ExtensionTestUtils.loadExtension({ + manifest: { + applications: {gecko: {id: "management@web.extension"}}, + permissions: ["management"], + }, + async background() { + // Should find the simple extension. + let normalAddon = await browser.management.get("boring@web.extension"); + browser.test.assertEq(normalAddon.id, "boring@web.extension", "Found boring addon"); + + try { + // Not allowed to get the API experiment. + await browser.management.get("fooBar@experiments.addons.mozilla.org"); + } catch (e) { + browser.test.sendMessage("done"); + } + }, + useAddonManager: "temporary", + }); + + await managementAddon.startup(); + await managementAddon.awaitMessage("done"); + await managementAddon.unload(); + // Cleanup. apiAddon.uninstall(); diff --git toolkit/components/extensions/test/xpcshell/test_ext_management.js toolkit/components/extensions/test/xpcshell/test_ext_management.js index c1702042c054..975c14a566e4 100644 --- toolkit/components/extensions/test/xpcshell/test_ext_management.js +++ toolkit/components/extensions/test/xpcshell/test_ext_management.js @@ -22,6 +22,7 @@ add_task(async function test_management_getAll() { }, name: id, version: "1.0", + short_name: id, permissions: ["management"], }; } @@ -55,11 +56,18 @@ add_task(async function test_management_getAll() { for (let id of [id1, id2]) { let addon = addons.find(a => { return a.id === id; }); equal(addon.name, id, `The extension with id ${id} was returned by getAll.`); + equal(addon.shortName, id, "Additional extension metadata was correct"); } extension2.sendMessage("getAddon", id1); let addon = await extension2.awaitMessage("addon"); equal(addon.name, id1, `The extension with id ${id1} was returned by get.`); + equal(addon.shortName, id1, "Additional extension metadata was correct"); + + extension2.sendMessage("getAddon", id2); + addon = await extension2.awaitMessage("addon"); + equal(addon.name, id2, `The extension with id ${id2} was returned by get.`); + equal(addon.shortName, id2, "Additional extension metadata was correct"); await extension2.unload(); await extension1.unload(); diff --git toolkit/mozapps/extensions/internal/XPIProvider.jsm toolkit/mozapps/extensions/internal/XPIProvider.jsm index 0027e13e3804..56f3982e7214 100644 --- toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -5197,6 +5197,10 @@ AddonWrapper.prototype = { return isWebExtension(addonFor(this).type); }, + get isAPIExtension() { + return addonFor(this).type == "apiextension"; + }, + get temporarilyInstalled() { return addonFor(this)._installLocation == TemporaryInstallLocation; },