summaryrefslogtreecommitdiffstats
path: root/application/basilisk/modules/SitePermissions.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'application/basilisk/modules/SitePermissions.jsm')
-rw-r--r--application/basilisk/modules/SitePermissions.jsm616
1 files changed, 0 insertions, 616 deletions
diff --git a/application/basilisk/modules/SitePermissions.jsm b/application/basilisk/modules/SitePermissions.jsm
deleted file mode 100644
index 4d5673ef4..000000000
--- a/application/basilisk/modules/SitePermissions.jsm
+++ /dev/null
@@ -1,616 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-this.EXPORTED_SYMBOLS = [ "SitePermissions" ];
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var gStringBundle =
- Services.strings.createBundle("chrome://browser/locale/sitePermissions.properties");
-
-/**
- * A helper module to manage temporarily blocked permissions.
- *
- * Permissions are keyed by browser, so methods take a Browser
- * element to identify the corresponding permission set.
- *
- * This uses a WeakMap to key browsers, so that entries are
- * automatically cleared once the browser stops existing
- * (once there are no other references to the browser object);
- */
-const TemporaryBlockedPermissions = {
- // This is a three level deep map with the following structure:
- //
- // Browser => {
- // <prePath>: {
- // <permissionID>: {Number} <timeStamp>
- // }
- // }
- //
- // Only the top level browser elements are stored via WeakMap. The WeakMap
- // value is an object with URI prePaths as keys. The keys of that object
- // are ids that identify permissions that were set for the specific URI.
- // The final value is an object containing the timestamp of when the permission
- // was set (in order to invalidate after a certain amount of time has passed).
- _stateByBrowser: new WeakMap(),
-
- // Private helper method that bundles some shared behavior for
- // get() and getAll(), e.g. deleting permissions when they have expired.
- _get(entry, prePath, id, timeStamp) {
- if (timeStamp == null) {
- delete entry[prePath][id];
- return null;
- }
- if (timeStamp + SitePermissions.temporaryPermissionExpireTime < Date.now()) {
- delete entry[prePath][id];
- return null;
- }
- return {id, state: SitePermissions.BLOCK, scope: SitePermissions.SCOPE_TEMPORARY};
- },
-
- // Sets a new permission for the specified browser.
- set(browser, id) {
- if (!browser) {
- return;
- }
- if (!this._stateByBrowser.has(browser)) {
- this._stateByBrowser.set(browser, {});
- }
- let entry = this._stateByBrowser.get(browser);
- let prePath = browser.currentURI.prePath;
- if (!entry[prePath]) {
- entry[prePath] = {};
- }
- entry[prePath][id] = Date.now();
- },
-
- // Removes a permission with the specified id for the specified browser.
- remove(browser, id) {
- if (!browser) {
- return;
- }
- let entry = this._stateByBrowser.get(browser);
- let prePath = browser.currentURI.prePath;
- if (entry && entry[prePath]) {
- delete entry[prePath][id];
- }
- },
-
- // Gets a permission with the specified id for the specified browser.
- get(browser, id) {
- if (!browser || !browser.currentURI) {
- return null;
- }
- let entry = this._stateByBrowser.get(browser);
- let prePath = browser.currentURI.prePath;
- if (entry && entry[prePath]) {
- let permission = entry[prePath][id];
- return this._get(entry, prePath, id, permission);
- }
- return null;
- },
-
- // Gets all permissions for the specified browser.
- // Note that only permissions that apply to the current URI
- // of the passed browser element will be returned.
- getAll(browser) {
- let permissions = [];
- let entry = this._stateByBrowser.get(browser);
- let prePath = browser.currentURI.prePath;
- if (entry && entry[prePath]) {
- let timeStamps = entry[prePath];
- for (let id of Object.keys(timeStamps)) {
- let permission = this._get(entry, prePath, id, timeStamps[id]);
- // _get() returns null when the permission has expired.
- if (permission) {
- permissions.push(permission);
- }
- }
- }
- return permissions;
- },
-
- // Clears all permissions for the specified browser.
- // Unlike other methods, this does NOT clear only for
- // the currentURI but the whole browser state.
- clear(browser) {
- this._stateByBrowser.delete(browser);
- },
-
- // Copies the temporary permission state of one browser
- // into a new entry for the other browser.
- copy(browser, newBrowser) {
- let entry = this._stateByBrowser.get(browser);
- if (entry) {
- this._stateByBrowser.set(newBrowser, entry);
- }
- },
-};
-
-/**
- * A module to manage permanent and temporary permissions
- * by URI and browser.
- *
- * Some methods have the side effect of dispatching a "PermissionStateChange"
- * event on changes to temporary permissions, as mentioned in the respective docs.
- */
-this.SitePermissions = {
- // Permission states.
- UNKNOWN: Services.perms.UNKNOWN_ACTION,
- ALLOW: Services.perms.ALLOW_ACTION,
- BLOCK: Services.perms.DENY_ACTION,
- ALLOW_COOKIES_FOR_SESSION: Components.interfaces.nsICookiePermission.ACCESS_SESSION,
-
- // Permission scopes.
- SCOPE_REQUEST: "{SitePermissions.SCOPE_REQUEST}",
- SCOPE_TEMPORARY: "{SitePermissions.SCOPE_TEMPORARY}",
- SCOPE_SESSION: "{SitePermissions.SCOPE_SESSION}",
- SCOPE_PERSISTENT: "{SitePermissions.SCOPE_PERSISTENT}",
-
- /**
- * Gets all custom permissions for a given URI.
- * Install addon permission is excluded, check bug 1303108.
- *
- * @return {Array} a list of objects with the keys:
- * - id: the permissionId of the permission
- * - scope: the scope of the permission (e.g. SitePermissions.SCOPE_TEMPORARY)
- * - state: a constant representing the current permission state
- * (e.g. SitePermissions.ALLOW)
- */
- getAllByURI(uri) {
- let result = [];
- if (!this.isSupportedURI(uri)) {
- return result;
- }
-
- let permissions = Services.perms.getAllForURI(uri);
- while (permissions.hasMoreElements()) {
- let permission = permissions.getNext();
-
- // filter out unknown permissions
- if (gPermissionObject[permission.type]) {
- // XXX Bug 1303108 - Control Center should only show non-default permissions
- if (permission.type == "install") {
- continue;
- }
- let scope = this.SCOPE_PERSISTENT;
- if (permission.expireType == Services.perms.EXPIRE_SESSION) {
- scope = this.SCOPE_SESSION;
- }
- result.push({
- id: permission.type,
- scope,
- state: permission.capability,
- });
- }
- }
-
- return result;
- },
-
- /**
- * Returns all custom permissions for a given browser.
- *
- * To receive a more detailed, albeit less performant listing see
- * SitePermissions.getAllPermissionDetailsForBrowser().
- *
- * @param {Browser} browser
- * The browser to fetch permission for.
- *
- * @return {Array} a list of objects with the keys:
- * - id: the permissionId of the permission
- * - state: a constant representing the current permission state
- * (e.g. SitePermissions.ALLOW)
- * - scope: a constant representing how long the permission will
- * be kept.
- */
- getAllForBrowser(browser) {
- let permissions = {};
-
- for (let permission of TemporaryBlockedPermissions.getAll(browser)) {
- permission.scope = this.SCOPE_TEMPORARY;
- permissions[permission.id] = permission;
- }
-
- for (let permission of this.getAllByURI(browser.currentURI)) {
- permissions[permission.id] = permission;
- }
-
- return Object.values(permissions);
- },
-
- /**
- * Returns a list of objects with detailed information on all permissions
- * that are currently set for the given browser.
- *
- * @param {Browser} browser
- * The browser to fetch permission for.
- *
- * @return {Array<Object>} a list of objects with the keys:
- * - id: the permissionID of the permission
- * - state: a constant representing the current permission state
- * (e.g. SitePermissions.ALLOW)
- * - scope: a constant representing how long the permission will
- * be kept.
- * - label: the localized label
- */
- getAllPermissionDetailsForBrowser(browser) {
- return this.getAllForBrowser(browser).map(({id, scope, state}) =>
- ({id, scope, state, label: this.getPermissionLabel(id)}));
- },
-
- /**
- * Checks whether a UI for managing permissions should be exposed for a given
- * URI. This excludes file URIs, for instance, as they don't have a host,
- * even though nsIPermissionManager can still handle them.
- *
- * @param {nsIURI} uri
- * The URI to check.
- *
- * @return {boolean} if the URI is supported.
- */
- isSupportedURI(uri) {
- return uri && (uri.schemeIs("http") || uri.schemeIs("https"));
- },
-
- /**
- * Gets an array of all permission IDs.
- *
- * @return {Array<String>} an array of all permission IDs.
- */
- listPermissions() {
- return Object.keys(gPermissionObject);
- },
-
- /**
- * Returns an array of permission states to be exposed to the user for a
- * permission with the given ID.
- *
- * @param {string} permissionID
- * The ID to get permission states for.
- *
- * @return {Array<SitePermissions state>} an array of all permission states.
- */
- getAvailableStates(permissionID) {
- if (permissionID in gPermissionObject &&
- gPermissionObject[permissionID].states)
- return gPermissionObject[permissionID].states;
-
- if (this.getDefault(permissionID) == this.UNKNOWN)
- return [ SitePermissions.UNKNOWN, SitePermissions.ALLOW, SitePermissions.BLOCK ];
-
- return [ SitePermissions.ALLOW, SitePermissions.BLOCK ];
- },
-
- /**
- * Returns the default state of a particular permission.
- *
- * @param {string} permissionID
- * The ID to get the default for.
- *
- * @return {SitePermissions.state} the default state.
- */
- getDefault(permissionID) {
- if (permissionID in gPermissionObject &&
- gPermissionObject[permissionID].getDefault)
- return gPermissionObject[permissionID].getDefault();
-
- return this.UNKNOWN;
- },
-
- /**
- * Returns the state and scope of a particular permission for a given URI.
- *
- * This method will NOT dispatch a "PermissionStateChange" event on the specified
- * browser if a temporary permission was removed because it has expired.
- *
- * @param {nsIURI} uri
- * The URI to check.
- * @param {String} permissionID
- * The id of the permission.
- * @param {Browser} browser (optional)
- * The browser object to check for temporary permissions.
- *
- * @return {Object} an object with the keys:
- * - state: The current state of the permission
- * (e.g. SitePermissions.ALLOW)
- * - scope: The scope of the permission
- * (e.g. SitePermissions.SCOPE_PERSISTENT)
- */
- get(uri, permissionID, browser) {
- let result = { state: this.UNKNOWN, scope: this.SCOPE_PERSISTENT };
- if (this.isSupportedURI(uri)) {
- let permission = null;
- if (permissionID in gPermissionObject &&
- gPermissionObject[permissionID].exactHostMatch) {
- permission = Services.perms.getPermissionObjectForURI(uri, permissionID, true);
- } else {
- permission = Services.perms.getPermissionObjectForURI(uri, permissionID, false);
- }
-
- if (permission) {
- result.state = permission.capability;
- if (permission.expireType == Services.perms.EXPIRE_SESSION) {
- result.scope = this.SCOPE_SESSION;
- }
- }
- }
-
- if (!result.state) {
- // If there's no persistent permission saved, check if we have something
- // set temporarily.
- let value = TemporaryBlockedPermissions.get(browser, permissionID);
-
- if (value) {
- result.state = value.state;
- result.scope = this.SCOPE_TEMPORARY;
- }
- }
-
- return result;
- },
-
- /**
- * Sets the state of a particular permission for a given URI or browser.
- * This method will dispatch a "PermissionStateChange" event on the specified
- * browser if a temporary permission was set
- *
- * @param {nsIURI} uri
- * The URI to set the permission for.
- * Note that this will be ignored if the scope is set to SCOPE_TEMPORARY
- * @param {String} permissionID
- * The id of the permission.
- * @param {SitePermissions state} state
- * The state of the permission.
- * @param {SitePermissions scope} scope (optional)
- * The scope of the permission. Defaults to SCOPE_PERSISTENT.
- * @param {Browser} browser (optional)
- * The browser object to set temporary permissions on.
- * This needs to be provided if the scope is SCOPE_TEMPORARY!
- */
- set(uri, permissionID, state, scope = this.SCOPE_PERSISTENT, browser = null) {
- if (state == this.UNKNOWN) {
- this.remove(uri, permissionID, browser);
- return;
- }
-
- if (state == this.ALLOW_COOKIES_FOR_SESSION && permissionID != "cookie") {
- throw "ALLOW_COOKIES_FOR_SESSION can only be set on the cookie permission";
- }
-
- // Save temporary permissions.
- if (scope == this.SCOPE_TEMPORARY) {
- // We do not support setting temp ALLOW for security reasons.
- // In its current state, this permission could be exploited by subframes
- // on the same page. This is because for BLOCK we ignore the request
- // URI and only consider the current browser URI, to avoid notification spamming.
- //
- // If you ever consider removing this line, you likely want to implement
- // a more fine-grained TemporaryBlockedPermissions that temporarily blocks for the
- // entire browser, but temporarily allows only for specific frames.
- if (state != this.BLOCK) {
- throw "'Block' is the only permission we can save temporarily on a browser";
- }
-
- if (!browser) {
- throw "TEMPORARY scoped permissions require a browser object";
- }
-
- TemporaryBlockedPermissions.set(browser, permissionID);
-
- browser.dispatchEvent(new browser.ownerGlobal
- .CustomEvent("PermissionStateChange"));
- } else if (this.isSupportedURI(uri)) {
- let perms_scope = Services.perms.EXPIRE_NEVER;
- if (scope == this.SCOPE_SESSION) {
- perms_scope = Services.perms.EXPIRE_SESSION;
- }
-
- Services.perms.add(uri, permissionID, state, perms_scope);
- }
- },
-
- /**
- * Removes the saved state of a particular permission for a given URI and/or browser.
- * This method will dispatch a "PermissionStateChange" event on the specified
- * browser if a temporary permission was removed.
- *
- * @param {nsIURI} uri
- * The URI to remove the permission for.
- * @param {String} permissionID
- * The id of the permission.
- * @param {Browser} browser (optional)
- * The browser object to remove temporary permissions on.
- */
- remove(uri, permissionID, browser) {
- if (this.isSupportedURI(uri))
- Services.perms.remove(uri, permissionID);
-
- // TemporaryBlockedPermissions.get() deletes expired permissions automatically,
- if (TemporaryBlockedPermissions.get(browser, permissionID)) {
- // If it exists but has not expired, remove it explicitly.
- TemporaryBlockedPermissions.remove(browser, permissionID);
- // Send a PermissionStateChange event only if the permission hasn't expired.
- browser.dispatchEvent(new browser.ownerGlobal
- .CustomEvent("PermissionStateChange"));
- }
- },
-
- /**
- * Clears all permissions that were temporarily saved.
- *
- * @param {Browser} browser
- * The browser object to clear.
- */
- clearTemporaryPermissions(browser) {
- TemporaryBlockedPermissions.clear(browser);
- },
-
- /**
- * Copy all permissions that were temporarily saved on one
- * browser object to a new browser.
- *
- * @param {Browser} browser
- * The browser object to copy from.
- * @param {Browser} newBrowser
- * The browser object to copy to.
- */
- copyTemporaryPermissions(browser, newBrowser) {
- TemporaryBlockedPermissions.copy(browser, newBrowser);
- },
-
- /**
- * Returns the localized label for the permission with the given ID, to be
- * used in a UI for managing permissions.
- *
- * @param {string} permissionID
- * The permission to get the label for.
- *
- * @return {String} the localized label.
- */
- getPermissionLabel(permissionID) {
- let labelID = gPermissionObject[permissionID].labelID || permissionID;
- return gStringBundle.GetStringFromName("permission." + labelID + ".label");
- },
-
- /**
- * Returns the localized label for the given permission state, to be used in
- * a UI for managing permissions.
- *
- * @param {SitePermissions state} state
- * The state to get the label for.
- *
- * @return {String|null} the localized label or null if an
- * unknown state was passed.
- */
- getMultichoiceStateLabel(state) {
- switch (state) {
- case this.UNKNOWN:
- return gStringBundle.GetStringFromName("state.multichoice.alwaysAsk");
- case this.ALLOW:
- return gStringBundle.GetStringFromName("state.multichoice.allow");
- case this.ALLOW_COOKIES_FOR_SESSION:
- return gStringBundle.GetStringFromName("state.multichoice.allowForSession");
- case this.BLOCK:
- return gStringBundle.GetStringFromName("state.multichoice.block");
- default:
- return null;
- }
- },
-
- /**
- * Returns the localized label for a permission's current state.
- *
- * @param {SitePermissions state} state
- * The state to get the label for.
- * @param {SitePermissions scope} scope (optional)
- * The scope to get the label for.
- *
- * @return {String|null} the localized label or null if an
- * unknown state was passed.
- */
- getCurrentStateLabel(state, scope = null) {
- switch (state) {
- case this.ALLOW:
- if (scope && scope != this.SCOPE_PERSISTENT)
- return gStringBundle.GetStringFromName("state.current.allowedTemporarily");
- return gStringBundle.GetStringFromName("state.current.allowed");
- case this.ALLOW_COOKIES_FOR_SESSION:
- return gStringBundle.GetStringFromName("state.current.allowedForSession");
- case this.BLOCK:
- if (scope && scope != this.SCOPE_PERSISTENT)
- return gStringBundle.GetStringFromName("state.current.blockedTemporarily");
- return gStringBundle.GetStringFromName("state.current.blocked");
- default:
- return null;
- }
- },
-};
-
-var gPermissionObject = {
- /* Holds permission ID => options pairs.
- *
- * Supported options:
- *
- * - exactHostMatch
- * Allows sub domains to have their own permissions.
- * Defaults to false.
- *
- * - getDefault
- * Called to get the permission's default state.
- * Defaults to UNKNOWN, indicating that the user will be asked each time
- * a page asks for that permissions.
- *
- * - labelID
- * Use the given ID instead of the permission name for looking up strings.
- * e.g. "desktop-notification2" to use permission.desktop-notification2.label
- *
- * - states
- * Array of permission states to be exposed to the user.
- * Defaults to ALLOW, BLOCK and the default state (see getDefault).
- */
-
- "image": {
- getDefault() {
- return Services.prefs.getIntPref("permissions.default.image") == 2 ?
- SitePermissions.BLOCK : SitePermissions.ALLOW;
- }
- },
-
- "cookie": {
- states: [ SitePermissions.ALLOW, SitePermissions.ALLOW_COOKIES_FOR_SESSION, SitePermissions.BLOCK ],
- getDefault() {
- if (Services.prefs.getIntPref("network.cookie.cookieBehavior") == 2)
- return SitePermissions.BLOCK;
-
- if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == 2)
- return SitePermissions.ALLOW_COOKIES_FOR_SESSION;
-
- return SitePermissions.ALLOW;
- }
- },
-
- "desktop-notification": {
- exactHostMatch: true,
- labelID: "desktop-notification2",
- },
-
- "camera": {
- exactHostMatch: true,
- },
-
- "microphone": {
- exactHostMatch: true,
- },
-
- "screen": {
- exactHostMatch: true,
- states: [ SitePermissions.UNKNOWN, SitePermissions.BLOCK ],
- },
-
- "popup": {
- getDefault() {
- return Services.prefs.getBoolPref("dom.disable_open_during_load") ?
- SitePermissions.BLOCK : SitePermissions.ALLOW;
- }
- },
-
- "install": {
- getDefault() {
- return Services.prefs.getBoolPref("xpinstall.whitelist.required") ?
- SitePermissions.BLOCK : SitePermissions.ALLOW;
- }
- },
-
- "geo": {
- exactHostMatch: true
- },
-
- "indexedDB": {}
-};
-
-XPCOMUtils.defineLazyPreferenceGetter(SitePermissions, "temporaryPermissionExpireTime",
- "privacy.temporary_permission_expire_time_ms", 3600 * 1000);
-