summaryrefslogtreecommitdiffstats
path: root/browser/modules/SitePermissions.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'browser/modules/SitePermissions.jsm')
-rw-r--r--browser/modules/SitePermissions.jsm269
1 files changed, 269 insertions, 0 deletions
diff --git a/browser/modules/SitePermissions.jsm b/browser/modules/SitePermissions.jsm
new file mode 100644
index 000000000..d15ddb21b
--- /dev/null
+++ b/browser/modules/SitePermissions.jsm
@@ -0,0 +1,269 @@
+/* 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");
+
+var gStringBundle =
+ Services.strings.createBundle("chrome://browser/locale/sitePermissions.properties");
+
+this.SitePermissions = {
+
+ UNKNOWN: Services.perms.UNKNOWN_ACTION,
+ ALLOW: Services.perms.ALLOW_ACTION,
+ BLOCK: Services.perms.DENY_ACTION,
+ SESSION: Components.interfaces.nsICookiePermission.ACCESS_SESSION,
+
+ /* Returns all custom permissions for a given URI, the return
+ * type is 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)
+ *
+ * To receive a more detailed, albeit less performant listing see
+ * SitePermissions.getPermissionDetailsByURI().
+ *
+ * install addon permission is excluded, check bug 1303108
+ */
+ getAllByURI: function (aURI) {
+ let result = [];
+ if (!this.isSupportedURI(aURI)) {
+ return result;
+ }
+
+ let permissions = Services.perms.getAllForURI(aURI);
+ 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;
+ }
+ result.push({
+ id: permission.type,
+ state: permission.capability,
+ });
+ }
+ }
+
+ return result;
+ },
+
+ /* Returns an object representing the aId permission. It contains the
+ * following keys:
+ * - id: the permissionID of the permission
+ * - label: the localized label
+ * - state: a constant representing the aState permission state
+ * (e.g. SitePermissions.ALLOW), or the default if aState is omitted
+ * - availableStates: an array of all available states for that permission,
+ * represented as objects with the keys:
+ * - id: the state constant
+ * - label: the translated label of that state
+ */
+ getPermissionItem: function (aId, aState) {
+ let availableStates = this.getAvailableStates(aId).map(state => {
+ return { id: state, label: this.getStateLabel(aId, state) };
+ });
+ if (aState == undefined)
+ aState = this.getDefault(aId);
+ return {id: aId, label: this.getPermissionLabel(aId),
+ state: aState, availableStates};
+ },
+
+ /* Returns a list of objects representing all permissions that are currently
+ * set for the given URI. See getPermissionItem for the content of each object.
+ */
+ getPermissionDetailsByURI: function (aURI) {
+ let permissions = [];
+ for (let {state, id} of this.getAllByURI(aURI)) {
+ permissions.push(this.getPermissionItem(id, state));
+ }
+
+ return permissions;
+ },
+
+ /* 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.
+ */
+ isSupportedURI: function (aURI) {
+ return aURI.schemeIs("http") || aURI.schemeIs("https");
+ },
+
+ /* Returns an array of all permission IDs.
+ */
+ listPermissions: function () {
+ return Object.keys(gPermissionObject);
+ },
+
+ /* Returns an array of permission states to be exposed to the user for a
+ * permission with the given ID.
+ */
+ getAvailableStates: function (aPermissionID) {
+ if (aPermissionID in gPermissionObject &&
+ gPermissionObject[aPermissionID].states)
+ return gPermissionObject[aPermissionID].states;
+
+ if (this.getDefault(aPermissionID) == this.UNKNOWN)
+ return [ SitePermissions.UNKNOWN, SitePermissions.ALLOW, SitePermissions.BLOCK ];
+
+ return [ SitePermissions.ALLOW, SitePermissions.BLOCK ];
+ },
+
+ /* Returns the default state of a particular permission.
+ */
+ getDefault: function (aPermissionID) {
+ if (aPermissionID in gPermissionObject &&
+ gPermissionObject[aPermissionID].getDefault)
+ return gPermissionObject[aPermissionID].getDefault();
+
+ return this.UNKNOWN;
+ },
+
+ /* Returns the state of a particular permission for a given URI.
+ */
+ get: function (aURI, aPermissionID) {
+ if (!this.isSupportedURI(aURI))
+ return this.UNKNOWN;
+
+ let state;
+ if (aPermissionID in gPermissionObject &&
+ gPermissionObject[aPermissionID].exactHostMatch)
+ state = Services.perms.testExactPermission(aURI, aPermissionID);
+ else
+ state = Services.perms.testPermission(aURI, aPermissionID);
+ return state;
+ },
+
+ /* Sets the state of a particular permission for a given URI.
+ */
+ set: function (aURI, aPermissionID, aState) {
+ if (!this.isSupportedURI(aURI))
+ return;
+
+ if (aState == this.UNKNOWN) {
+ this.remove(aURI, aPermissionID);
+ return;
+ }
+
+ Services.perms.add(aURI, aPermissionID, aState);
+ },
+
+ /* Removes the saved state of a particular permission for a given URI.
+ */
+ remove: function (aURI, aPermissionID) {
+ if (!this.isSupportedURI(aURI))
+ return;
+
+ Services.perms.remove(aURI, aPermissionID);
+ },
+
+ /* Returns the localized label for the permission with the given ID, to be
+ * used in a UI for managing permissions.
+ */
+ getPermissionLabel: function (aPermissionID) {
+ let labelID = gPermissionObject[aPermissionID].labelID || aPermissionID;
+ return gStringBundle.GetStringFromName("permission." + labelID + ".label");
+ },
+
+ /* Returns the localized label for the given permission state, to be used in
+ * a UI for managing permissions.
+ */
+ getStateLabel: function (aPermissionID, aState, aInUse = false) {
+ switch (aState) {
+ case this.UNKNOWN:
+ if (aInUse)
+ return gStringBundle.GetStringFromName("allowTemporarily");
+ return gStringBundle.GetStringFromName("alwaysAsk");
+ case this.ALLOW:
+ return gStringBundle.GetStringFromName("allow");
+ case this.SESSION:
+ return gStringBundle.GetStringFromName("allowForSession");
+ case this.BLOCK:
+ return gStringBundle.GetStringFromName("block");
+ 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: function () {
+ return Services.prefs.getIntPref("permissions.default.image") == 2 ?
+ SitePermissions.BLOCK : SitePermissions.ALLOW;
+ }
+ },
+
+ "cookie": {
+ states: [ SitePermissions.ALLOW, SitePermissions.SESSION, SitePermissions.BLOCK ],
+ getDefault: function () {
+ if (Services.prefs.getIntPref("network.cookie.cookieBehavior") == 2)
+ return SitePermissions.BLOCK;
+
+ if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == 2)
+ return SitePermissions.SESSION;
+
+ return SitePermissions.ALLOW;
+ }
+ },
+
+ "desktop-notification": {
+ exactHostMatch: true,
+ labelID: "desktop-notification2",
+ },
+
+ "camera": {},
+ "microphone": {},
+ "screen": {
+ states: [ SitePermissions.UNKNOWN, SitePermissions.BLOCK ],
+ },
+
+ "popup": {
+ getDefault: function () {
+ return Services.prefs.getBoolPref("dom.disable_open_during_load") ?
+ SitePermissions.BLOCK : SitePermissions.ALLOW;
+ }
+ },
+
+ "install": {
+ getDefault: function () {
+ return Services.prefs.getBoolPref("xpinstall.whitelist.required") ?
+ SitePermissions.BLOCK : SitePermissions.ALLOW;
+ }
+ },
+
+ "geo": {
+ exactHostMatch: true
+ },
+
+ "indexedDB": {}
+};
+
+const kPermissionIDs = Object.keys(gPermissionObject);