gecko-dev/toolkit/components/extensions/parent/ext-permissions.js
Shane Caraveo 050ca2e7d4 Bug 1511636: update incognito support to use pref and permissions r=rpl,aswan,kmag
This changes the policy to use the pref and permissions rather than a boolean flag.  Using permissions gets us proper settings on startup without introducing any new overhead.  Going this way flips our tests around so rather than testing an override to turn off private browsing support, we test overrides to enable private browsing support.

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

--HG--
extra : moz-landing-system : lando
2019-01-28 18:10:47 +00:00

102 lines
3.4 KiB
JavaScript

"use strict";
ChromeUtils.defineModuleGetter(this, "ExtensionPermissions",
"resource://gre/modules/ExtensionPermissions.jsm");
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
var {
ExtensionError,
} = ExtensionUtils;
XPCOMUtils.defineLazyPreferenceGetter(this, "promptsEnabled",
"extensions.webextOptionalPermissionPrompts");
this.permissions = class extends ExtensionAPI {
getAPI(context) {
let {extension} = context;
return {
permissions: {
async request(perms) {
let {permissions, origins} = perms;
let manifestPermissions = context.extension.manifest.optional_permissions;
for (let perm of permissions) {
if (!manifestPermissions.includes(perm)) {
throw new ExtensionError(`Cannot request permission ${perm} since it was not declared in optional_permissions`);
}
}
let optionalOrigins = context.extension.optionalOrigins;
for (let origin of origins) {
if (!optionalOrigins.subsumes(new MatchPattern(origin))) {
throw new ExtensionError(`Cannot request origin permission for ${origin} since it was not declared in optional_permissions`);
}
}
if (promptsEnabled) {
permissions = permissions.filter(perm => !context.extension.hasPermission(perm));
origins = origins.filter(origin => !context.extension.whiteListedHosts.subsumes(new MatchPattern(origin)));
if (permissions.length == 0 && origins.length == 0) {
return true;
}
let browser = context.pendingEventBrowser || context.xulBrowser;
let allow = await new Promise(resolve => {
let subject = {
wrappedJSObject: {
browser,
name: context.extension.name,
icon: context.extension.iconURL,
permissions: {permissions, origins},
resolve,
},
};
Services.obs.notifyObservers(subject, "webextension-optional-permission-prompt");
});
if (!allow) {
return false;
}
}
// Unfortunately, we treat <all_urls> as an API permission as well.
if (origins.includes("<all_urls>")) {
perms.permissions.push("<all_urls>");
}
await ExtensionPermissions.add(extension.id, perms, extension);
return true;
},
async getAll() {
let perms = {...context.extension.activePermissions};
delete perms.apis;
perms.permissions = perms.permissions.filter(perm => !perm.startsWith("internal:"));
return perms;
},
async contains(permissions) {
for (let perm of permissions.permissions) {
if (!context.extension.hasPermission(perm)) {
return false;
}
}
for (let origin of permissions.origins) {
if (!context.extension.whiteListedHosts.subsumes(new MatchPattern(origin))) {
return false;
}
}
return true;
},
async remove(permissions) {
await ExtensionPermissions.remove(extension.id, permissions, extension);
return true;
},
},
};
}
};