summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_ext_permissions_migrate.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_permissions_migrate.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/test_ext_permissions_migrate.js268
1 files changed, 268 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_permissions_migrate.js b/toolkit/components/extensions/test/xpcshell/test_ext_permissions_migrate.js
new file mode 100644
index 0000000000..fff4fd43d0
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_permissions_migrate.js
@@ -0,0 +1,268 @@
+"use strict";
+
+const { ExtensionPermissions } = ChromeUtils.importESModule(
+ "resource://gre/modules/ExtensionPermissions.sys.mjs"
+);
+
+AddonTestUtils.init(this);
+AddonTestUtils.overrideCertDB();
+AddonTestUtils.createAppInfo(
+ "xpcshell@tests.mozilla.org",
+ "XPCShell",
+ "1",
+ "42"
+);
+
+add_task(async function setup() {
+ // Bug 1646182: Force ExtensionPermissions to run in rkv mode, the legacy
+ // storage mode will run in xpcshell-legacy-ep.toml
+ await ExtensionPermissions._uninit();
+
+ Services.prefs.setBoolPref(
+ "extensions.webextOptionalPermissionPrompts",
+ false
+ );
+ registerCleanupFunction(() => {
+ Services.prefs.clearUserPref("extensions.webextOptionalPermissionPrompts");
+ });
+ await AddonTestUtils.promiseStartupManager();
+ AddonTestUtils.usePrivilegedSignatures = false;
+});
+
+async function test_migrated_permission_to_optional({ manifest_version }) {
+ let id = "permission-upgrade@test";
+ let extensionData = {
+ manifest: {
+ version: "1.0",
+ browser_specific_settings: { gecko: { id } },
+ permissions: [
+ "webRequest",
+ "tabs",
+ "http://example.net/*",
+ "http://example.com/*",
+ ],
+ },
+ useAddonManager: "permanent",
+ };
+
+ function checkPermissions() {
+ let policy = WebExtensionPolicy.getByID(id);
+ ok(policy.hasPermission("webRequest"), "addon has webRequest permission");
+ ok(policy.hasPermission("tabs"), "addon has tabs permission");
+ ok(
+ policy.canAccessURI(Services.io.newURI("http://example.net/")),
+ "addon has example.net host permission"
+ );
+ ok(
+ policy.canAccessURI(Services.io.newURI("http://example.com/")),
+ "addon has example.com host permission"
+ );
+ ok(
+ !policy.canAccessURI(Services.io.newURI("http://other.com/")),
+ "addon does not have other.com host permission"
+ );
+ }
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+ checkPermissions();
+
+ extensionData.manifest.manifest_version = manifest_version;
+
+ // Move to using optional permission
+ extensionData.manifest.version = "2.0";
+ extensionData.manifest.permissions = ["tabs"];
+
+ // The ExtensionTestCommon.generateFiles() test helper will normalize (move)
+ // host permissions into the `permissions` key for the MV2 test.
+ extensionData.manifest.host_permissions = ["http://example.net/*"];
+
+ extensionData.manifest.optional_permissions = [
+ "webRequest",
+ "http://example.com/*",
+ "http://other.com/*",
+ ];
+
+ // Restart the addon manager to flush the AddonInternal instance created
+ // when installing the addon above. See bug 1622117.
+ await AddonTestUtils.promiseRestartManager();
+ await extension.upgrade(extensionData);
+
+ equal(extension.version, "2.0", "Expected extension version");
+ checkPermissions();
+
+ await extension.unload();
+}
+
+add_task(function test_migrated_permission_to_optional_mv2() {
+ return test_migrated_permission_to_optional({ manifest_version: 2 });
+});
+
+// Test migration of mv2 (required) to mv3 (optional) host permissions.
+add_task(function test_migrated_permission_to_optional_mv3() {
+ return test_migrated_permission_to_optional({ manifest_version: 3 });
+});
+
+// This tests that settings are removed if a required permission is removed.
+// We use two settings APIs to make sure the one we keep permission to is not
+// removed inadvertantly.
+add_task(async function test_required_permissions_removed() {
+ function cacheIsEnabled() {
+ return (
+ Services.prefs.getBoolPref("browser.cache.disk.enable") &&
+ Services.prefs.getBoolPref("browser.cache.memory.enable")
+ );
+ }
+
+ let extData = {
+ background() {
+ if (browser.browserSettings) {
+ browser.browserSettings.cacheEnabled.set({ value: false });
+ }
+ browser.privacy.services.passwordSavingEnabled.set({ value: false });
+ },
+ manifest: {
+ browser_specific_settings: { gecko: { id: "pref-test@test" } },
+ permissions: ["tabs", "browserSettings", "privacy", "http://test.com/*"],
+ },
+ useAddonManager: "permanent",
+ };
+ let extension = ExtensionTestUtils.loadExtension(extData);
+ ok(
+ Services.prefs.getBoolPref("signon.rememberSignons"),
+ "privacy setting intial value as expected"
+ );
+ await extension.startup();
+ ok(!cacheIsEnabled(), "setting is set after startup");
+
+ extData.manifest.permissions = ["tabs"];
+ extData.manifest.optional_permissions = ["privacy"];
+ await extension.upgrade(extData);
+ ok(cacheIsEnabled(), "setting is reset after upgrade");
+ ok(
+ !Services.prefs.getBoolPref("signon.rememberSignons"),
+ "privacy setting is still set after upgrade"
+ );
+
+ await extension.unload();
+});
+
+// This tests that settings are removed if a granted permission is removed.
+// We use two settings APIs to make sure the one we keep permission to is not
+// removed inadvertantly.
+add_task(async function test_granted_permissions_removed() {
+ function cacheIsEnabled() {
+ return (
+ Services.prefs.getBoolPref("browser.cache.disk.enable") &&
+ Services.prefs.getBoolPref("browser.cache.memory.enable")
+ );
+ }
+
+ let extData = {
+ async background() {
+ browser.test.onMessage.addListener(async msg => {
+ await browser.permissions.request({ permissions: msg.permissions });
+ if (browser.browserSettings) {
+ browser.browserSettings.cacheEnabled.set({ value: false });
+ }
+ browser.privacy.services.passwordSavingEnabled.set({ value: false });
+ browser.test.sendMessage("done");
+ });
+ },
+ // "tabs" is never granted, it is included to exercise the removal code
+ // that called during the upgrade.
+ manifest: {
+ browser_specific_settings: { gecko: { id: "pref-test@test" } },
+ optional_permissions: [
+ "tabs",
+ "browserSettings",
+ "privacy",
+ "http://test.com/*",
+ ],
+ },
+ useAddonManager: "permanent",
+ };
+ let extension = ExtensionTestUtils.loadExtension(extData);
+ ok(
+ Services.prefs.getBoolPref("signon.rememberSignons"),
+ "privacy setting intial value as expected"
+ );
+ await extension.startup();
+ await withHandlingUserInput(extension, async () => {
+ extension.sendMessage({ permissions: ["browserSettings", "privacy"] });
+ await extension.awaitMessage("done");
+ });
+ ok(!cacheIsEnabled(), "setting is set after startup");
+
+ extData.manifest.permissions = ["privacy"];
+ delete extData.manifest.optional_permissions;
+ await extension.upgrade(extData);
+ ok(cacheIsEnabled(), "setting is reset after upgrade");
+ ok(
+ !Services.prefs.getBoolPref("signon.rememberSignons"),
+ "privacy setting is still set after upgrade"
+ );
+
+ await extension.unload();
+});
+
+// Test an update where an add-on becomes a theme.
+add_task(async function test_addon_to_theme_update() {
+ let id = "theme-test@test";
+ let extData = {
+ manifest: {
+ browser_specific_settings: { gecko: { id } },
+ version: "1.0",
+ optional_permissions: ["tabs"],
+ },
+ async background() {
+ browser.test.onMessage.addListener(async msg => {
+ await browser.permissions.request({ permissions: msg.permissions });
+ browser.test.sendMessage("done");
+ });
+ },
+ useAddonManager: "permanent",
+ };
+ let extension = ExtensionTestUtils.loadExtension(extData);
+ await extension.startup();
+
+ await withHandlingUserInput(extension, async () => {
+ extension.sendMessage({ permissions: ["tabs"] });
+ await extension.awaitMessage("done");
+ });
+
+ let policy = WebExtensionPolicy.getByID(id);
+ ok(policy.hasPermission("tabs"), "addon has tabs permission");
+
+ await extension.upgrade({
+ manifest: {
+ browser_specific_settings: { gecko: { id } },
+ version: "2.0",
+ theme: {
+ images: {
+ theme_frame: "image1.png",
+ },
+ },
+ },
+ useAddonManager: "permanent",
+ });
+ // When a theme is installed, it starts off in disabled mode, as seen in
+ // toolkit/mozapps/extensions/test/xpcshell/test_update_theme.js .
+ // But if we upgrade from an enabled extension, the theme is enabled.
+ equal(extension.addon.userDisabled, false, "Theme is enabled");
+
+ policy = WebExtensionPolicy.getByID(id);
+ ok(!policy.hasPermission("tabs"), "addon tabs permission was removed");
+ let perms = await ExtensionPermissions._get(id);
+ ok(!perms?.permissions?.length, "no retained permissions");
+
+ extData.manifest.version = "3.0";
+ extData.manifest.permissions = ["privacy"];
+ await extension.upgrade(extData);
+
+ policy = WebExtensionPolicy.getByID(id);
+ ok(!policy.hasPermission("tabs"), "addon tabs permission not added");
+ ok(policy.hasPermission("privacy"), "addon privacy permission added");
+
+ await extension.unload();
+});