Bug 1537542 - Hide addon preferences if the addon cannot access the current window. r=aswan

Differential Revision: https://phabricator.services.mozilla.com/D24534

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Luca Greco 2019-03-26 12:30:39 +00:00
parent c648004583
commit 002d4a5b48
3 changed files with 163 additions and 2 deletions

View File

@ -1580,6 +1580,17 @@ var gViewController = {
onEvent() {},
};
async function isAddonAllowedInCurrentWindow(aAddon) {
if (allowPrivateBrowsingByDefault ||
aAddon.type !== "extension" ||
!PrivateBrowsingUtils.isContentWindowPrivate(window)) {
return true;
}
const perms = await ExtensionPermissions.get(aAddon.id);
return perms.permissions.includes("internal:privateBrowsingAllowed");
}
function hasInlineOptions(aAddon) {
return aAddon.optionsType == AddonManager.OPTIONS_TYPE_INLINE_BROWSER ||
aAddon.type == "plugin";
@ -2991,6 +3002,7 @@ var gDetailView = {
// currently active.
let privateBrowsingRow = document.getElementById("detail-privateBrowsing-row");
let privateBrowsingFooterRow = document.getElementById("detail-privateBrowsing-row-footer");
if (allowPrivateBrowsingByDefault || aAddon.type != "extension" ||
!(aAddon.permissions & AddonManager.PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS)) {
this._privateBrowsing.hidden = true;
@ -3005,8 +3017,12 @@ var gDetailView = {
this._privateBrowsing.value = perms.permissions.includes("internal:privateBrowsingAllowed") ? "1" : "0";
}
document.getElementById("detail-prefs-btn").hidden = !aIsRemote &&
!gViewController.commands.cmd_showItemPreferences.isEnabled(aAddon);
// While updating the addon details view, also check if the preferences button should be disabled because
// we are in a private window and the addon is not allowed to access it.
let hidePreferences = (!aIsRemote &&
!gViewController.commands.cmd_showItemPreferences.isEnabled(aAddon)) ||
!await isAddonAllowedInCurrentWindow(aAddon);
document.getElementById("detail-prefs-btn").hidden = hidePreferences;
var gridRows = document.querySelectorAll("#detail-grid rows row");
let first = true;
@ -3286,6 +3302,12 @@ var gDetailView = {
const addon = this._addon;
await addon.startupPromise;
// Do not create the inline addon options if about:addons is opened in a private window
// and the addon is not allowed to access it.
if (!await isAddonAllowedInCurrentWindow(addon)) {
return;
}
const browserContainer = await this.createOptionsBrowser(rows);
if (browserContainer) {

View File

@ -907,6 +907,11 @@
ExtensionPermissions.get(this.mAddon.id).then((perms) => {
let allowed = perms.permissions.includes("internal:privateBrowsingAllowed");
this.setAttribute("privateBrowsing", allowed);
if (!allowed && PrivateBrowsingUtils.isContentWindowPrivate(window)) {
// Hide the preferences button if the current window is
// private and the addon is not allowed to access it.
this._preferencesBtn.hidden = true;
}
});
}

View File

@ -140,3 +140,137 @@ add_task(async function test_addon() {
Services.prefs.clearUserPref("extensions.allowPrivateBrowsingByDefault");
});
add_task(async function test_addon_preferences_button() {
await SpecialPowers.pushPrefEnv({set: [["extensions.allowPrivateBrowsingByDefault", false]]});
let addons = new Map([
["test-inline-options@mozilla.com", {
useAddonManager: "temporary",
manifest: {
name: "Extension with inline options",
applications: {gecko: {id: "test-inline-options@mozilla.com"}},
options_ui: {page: "options.html", open_in_tab: false},
},
}],
["test-newtab-options@mozilla.com", {
useAddonManager: "temporary",
manifest: {
name: "Extension with options page in a new tab",
applications: {gecko: {id: "test-newtab-options@mozilla.com"}},
options_ui: {page: "options.html", open_in_tab: true},
},
}],
["test-not-allowed@mozilla.com", {
useAddonManager: "temporary",
manifest: {
name: "Extension not allowed in PB windows",
incognito: "not_allowed",
applications: {gecko: {id: "test-not-allowed@mozilla.com"}},
options_ui: {page: "options.html", open_in_tab: true},
},
}],
]);
async function runTest(openInPrivateWin) {
const win = await BrowserTestUtils.openNewBrowserWindow({
private: openInPrivateWin,
});
gManagerWindow = await open_manager(
"addons://list/extension", undefined, undefined, undefined, win);
const doc = gManagerWindow.document;
const checkPrefsVisibility = (id, hasInlinePrefs, expectVisible) => {
if (!hasInlinePrefs) {
const detailsPrefBtn = doc.getElementById("detail-prefs-btn");
is(!detailsPrefBtn.hidden, expectVisible,
`The ${id} prefs button in the addon details has the expected visibility`);
} else {
const hasInlineOptionsBrowser = !!doc.getElementById("addon-options");
is(hasInlineOptionsBrowser, expectVisible,
`The ${id} inline prefs in the addon details has the expected visibility`);
}
};
const setAddonPrivateBrowsingAccess = async (id, allowPrivateBrowsing) => {
const privateBrowsing = doc.getElementById("detail-privateBrowsing");
is(privateBrowsing.value,
allowPrivateBrowsing ? "0" : "1",
`Private browsing should be initially ${allowPrivateBrowsing ? "off" : "on"}`);
// Get the DOM element we want to click on (to allow or disallow the
// addon on private browsing windows).
const controlEl = allowPrivateBrowsing ?
privateBrowsing.firstChild : privateBrowsing.lastChild;
EventUtils.synthesizeMouseAtCenter(controlEl, { clickCount: 1 }, gManagerWindow);
// Wait the private browsing access to be reflected in the about:addons
// addon details page.
await TestUtils.waitForCondition(
() => privateBrowsing.value == allowPrivateBrowsing ? "1" : "0",
"Waiting privateBrowsing value to be updated");
is(privateBrowsing.value,
allowPrivateBrowsing ? "1" : "0",
`Private browsing should be initially ${allowPrivateBrowsing ? "on" : "off"}`);
is(await hasPrivateAllowed(id), allowPrivateBrowsing,
`Private browsing permission ${allowPrivateBrowsing ? "added" : "removed"}`);
};
const extensions = [];
for (const definition of addons.values()) {
const extension = ExtensionTestUtils.loadExtension(definition);
extensions.push(extension);
await extension.startup();
}
const items = get_test_items();
for (const [id, definition] of addons.entries()) {
// Check the preferences button in the addon list page.
is(items[id]._preferencesBtn.hidden, openInPrivateWin,
`The ${id} prefs button in the addon list has the expected visibility`);
// Check the preferences button or inline frame in the addon
// details page.
info(`Opening addon details for ${id}`);
const hasInlinePrefs = !definition.manifest.options_ui.open_in_tab;
const onceViewChanged = BrowserTestUtils.waitForEvent(gManagerWindow, "ViewChanged");
gManagerWindow.loadView(`addons://detail/${encodeURIComponent(id)}`);
await onceViewChanged;
checkPrefsVisibility(id, hasInlinePrefs, !openInPrivateWin);
// While testing in a private window, also check that the preferences
// are going to be visible when we toggle the PB access for the addon.
if (openInPrivateWin && definition.manifest.incognito !== "not_allowed") {
await Promise.all([
BrowserTestUtils.waitForEvent(gManagerWindow, "ViewChanged"),
setAddonPrivateBrowsingAccess(id, true),
]);
checkPrefsVisibility(id, hasInlinePrefs, true);
await Promise.all([
BrowserTestUtils.waitForEvent(gManagerWindow, "ViewChanged"),
setAddonPrivateBrowsingAccess(id, false),
]);
checkPrefsVisibility(id, hasInlinePrefs, false);
}
}
for (const extension of extensions) {
await extension.unload();
}
await close_manager(gManagerWindow);
await BrowserTestUtils.closeWindow(win);
}
// run tests in private and non-private windows.
await runTest(true);
await runTest(false);
});