You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
267 lines
8.2 KiB
267 lines
8.2 KiB
/* 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 |
|
}, |
|
}; |
|
|
|
const kPermissionIDs = Object.keys(gPermissionObject);
|
|
|