permissions.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. const UNKNOWN = nsIPermissionManager.UNKNOWN_ACTION; // 0
  5. const ALLOW = nsIPermissionManager.ALLOW_ACTION; // 1
  6. const DENY = nsIPermissionManager.DENY_ACTION; // 2
  7. const SESSION = nsICookiePermission.ACCESS_SESSION; // 8
  8. const IMAGE_DENY = 2;
  9. const COOKIE_DENY = 2;
  10. const COOKIE_SESSION = 2;
  11. var gPermURI;
  12. var gPermPrincipal;
  13. var gPrefs;
  14. var gUsageRequest;
  15. var gPermObj = {
  16. image: function()
  17. {
  18. if (gPrefs.getIntPref("permissions.default.image") == IMAGE_DENY) {
  19. return DENY;
  20. }
  21. return ALLOW;
  22. },
  23. popup: function()
  24. {
  25. if (gPrefs.getBoolPref("dom.disable_open_during_load")) {
  26. return DENY;
  27. }
  28. return ALLOW;
  29. },
  30. cookie: function()
  31. {
  32. if (gPrefs.getIntPref("network.cookie.cookieBehavior") == COOKIE_DENY) {
  33. return DENY;
  34. }
  35. if (gPrefs.getIntPref("network.cookie.lifetimePolicy") == COOKIE_SESSION) {
  36. return SESSION;
  37. }
  38. return ALLOW;
  39. },
  40. "desktop-notification": function()
  41. {
  42. if (!gPrefs.getBoolPref("dom.webnotifications.enabled")) {
  43. return DENY;
  44. }
  45. return UNKNOWN;
  46. },
  47. install: function()
  48. {
  49. if (Services.prefs.getBoolPref("xpinstall.whitelist.required")) {
  50. return DENY;
  51. }
  52. return ALLOW;
  53. },
  54. geo: function()
  55. {
  56. if (!gPrefs.getBoolPref("geo.enabled")) {
  57. return DENY;
  58. }
  59. return ALLOW;
  60. },
  61. plugins: function()
  62. {
  63. return UNKNOWN;
  64. },
  65. };
  66. var permissionObserver = {
  67. observe: function(aSubject, aTopic, aData)
  68. {
  69. if (aTopic == "perm-changed") {
  70. var permission = aSubject.QueryInterface(
  71. Components.interfaces.nsIPermission);
  72. if (permission.matchesURI(gPermURI, true)) {
  73. if (permission.type in gPermObj)
  74. initRow(permission.type);
  75. else if (permission.type.startsWith("plugin"))
  76. setPluginsRadioState();
  77. }
  78. }
  79. }
  80. };
  81. function onLoadPermission(principal)
  82. {
  83. gPrefs = Components.classes[PREFERENCES_CONTRACTID]
  84. .getService(Components.interfaces.nsIPrefBranch);
  85. var uri = gDocument.documentURIObject;
  86. var permTab = document.getElementById("permTab");
  87. if (/^https?$/.test(uri.scheme)) {
  88. gPermURI = uri;
  89. gPermPrincipal = principal;
  90. var hostText = document.getElementById("hostText");
  91. hostText.value = gPermURI.prePath;
  92. for (var i in gPermObj)
  93. initRow(i);
  94. var os = Components.classes["@mozilla.org/observer-service;1"]
  95. .getService(Components.interfaces.nsIObserverService);
  96. os.addObserver(permissionObserver, "perm-changed", false);
  97. onUnloadRegistry.push(onUnloadPermission);
  98. permTab.hidden = false;
  99. }
  100. else
  101. permTab.hidden = true;
  102. }
  103. function onUnloadPermission()
  104. {
  105. var os = Components.classes["@mozilla.org/observer-service;1"]
  106. .getService(Components.interfaces.nsIObserverService);
  107. os.removeObserver(permissionObserver, "perm-changed");
  108. if (gUsageRequest) {
  109. gUsageRequest.cancel();
  110. gUsageRequest = null;
  111. }
  112. }
  113. function initRow(aPartId)
  114. {
  115. if (aPartId == "plugins") {
  116. initPluginsRow();
  117. return;
  118. }
  119. var permissionManager = Components.classes[PERMISSION_CONTRACTID]
  120. .getService(nsIPermissionManager);
  121. var checkbox = document.getElementById(aPartId + "Def");
  122. var command = document.getElementById("cmd_" + aPartId + "Toggle");
  123. // Desktop Notification, Geolocation and PointerLock permission consumers
  124. // use testExactPermission, not testPermission.
  125. var perm;
  126. if (aPartId == "desktop-notification" || aPartId == "geo" || aPartId == "pointerLock")
  127. perm = permissionManager.testExactPermission(gPermURI, aPartId);
  128. else
  129. perm = permissionManager.testPermission(gPermURI, aPartId);
  130. if (perm) {
  131. checkbox.checked = false;
  132. command.removeAttribute("disabled");
  133. }
  134. else {
  135. checkbox.checked = true;
  136. command.setAttribute("disabled", "true");
  137. perm = gPermObj[aPartId]();
  138. }
  139. setRadioState(aPartId, perm);
  140. }
  141. function onCheckboxClick(aPartId)
  142. {
  143. var permissionManager = Components.classes[PERMISSION_CONTRACTID]
  144. .getService(nsIPermissionManager);
  145. var command = document.getElementById("cmd_" + aPartId + "Toggle");
  146. var checkbox = document.getElementById(aPartId + "Def");
  147. if (checkbox.checked) {
  148. permissionManager.remove(gPermURI, aPartId);
  149. command.setAttribute("disabled", "true");
  150. var perm = gPermObj[aPartId]();
  151. setRadioState(aPartId, perm);
  152. }
  153. else {
  154. onRadioClick(aPartId);
  155. command.removeAttribute("disabled");
  156. }
  157. }
  158. function onPluginRadioClick(aEvent) {
  159. onRadioClick(aEvent.originalTarget.getAttribute("id").split('#')[0]);
  160. }
  161. function onRadioClick(aPartId)
  162. {
  163. var permissionManager = Components.classes[PERMISSION_CONTRACTID]
  164. .getService(nsIPermissionManager);
  165. var radioGroup = document.getElementById(aPartId + "RadioGroup");
  166. var id = radioGroup.selectedItem.id;
  167. var permission = id.split('#')[1];
  168. if (permission == UNKNOWN) {
  169. permissionManager.remove(gPermURI, aPartId);
  170. } else {
  171. permissionManager.add(gPermURI, aPartId, permission);
  172. }
  173. }
  174. function setRadioState(aPartId, aValue)
  175. {
  176. var radio = document.getElementById(aPartId + "#" + aValue);
  177. radio.radioGroup.selectedItem = radio;
  178. }
  179. // XXX copied this from browser-plugins.js - is there a way to share?
  180. function makeNicePluginName(aName) {
  181. if (aName == "Shockwave Flash")
  182. return "Adobe Flash";
  183. // Clean up the plugin name by stripping off any trailing version numbers
  184. // or "plugin". EG, "Foo Bar Plugin 1.23_02" --> "Foo Bar"
  185. // Do this by first stripping the numbers, etc. off the end, and then
  186. // removing "Plugin" (and then trimming to get rid of any whitespace).
  187. // (Otherwise, something like "Java(TM) Plug-in 1.7.0_07" gets mangled)
  188. let newName = aName.replace(/[\s\d\.\-\_\(\)]+$/, "").replace(/\bplug-?in\b/i, "").trim();
  189. return newName;
  190. }
  191. function fillInPluginPermissionTemplate(aPermissionString, aPluginObject) {
  192. let permPluginTemplate = document.getElementById("permPluginTemplate")
  193. .cloneNode(true);
  194. permPluginTemplate.setAttribute("permString", aPermissionString);
  195. permPluginTemplate.setAttribute("tooltiptext", aPluginObject.description);
  196. let attrs = [];
  197. attrs.push([".permPluginTemplateLabel", "value", aPluginObject.name]);
  198. attrs.push([".permPluginTemplateRadioGroup", "id", aPermissionString + "RadioGroup"]);
  199. attrs.push([".permPluginTemplateRadioDefault", "id", aPermissionString + "#0"]);
  200. let permPluginTemplateRadioAsk = ".permPluginTemplateRadioAsk";
  201. if (Services.prefs.getBoolPref("plugins.click_to_play") ||
  202. aPluginObject.vulnerable) {
  203. attrs.push([permPluginTemplateRadioAsk, "id", aPermissionString + "#3"]);
  204. } else {
  205. permPluginTemplate.querySelector(permPluginTemplateRadioAsk)
  206. .setAttribute("disabled", "true");
  207. }
  208. attrs.push([".permPluginTemplateRadioAllow", "id", aPermissionString + "#1"]);
  209. attrs.push([".permPluginTemplateRadioBlock", "id", aPermissionString + "#2"]);
  210. for (let attr of attrs) {
  211. permPluginTemplate.querySelector(attr[0]).setAttribute(attr[1], attr[2]);
  212. }
  213. return permPluginTemplate;
  214. }
  215. function clearPluginPermissionTemplate() {
  216. let permPluginTemplate = document.getElementById("permPluginTemplate");
  217. permPluginTemplate.hidden = true;
  218. permPluginTemplate.removeAttribute("permString");
  219. permPluginTemplate.removeAttribute("tooltiptext");
  220. document.querySelector(".permPluginTemplateLabel").removeAttribute("value");
  221. document.querySelector(".permPluginTemplateRadioGroup").removeAttribute("id");
  222. document.querySelector(".permPluginTemplateRadioAsk").removeAttribute("id");
  223. document.querySelector(".permPluginTemplateRadioAllow").removeAttribute("id");
  224. document.querySelector(".permPluginTemplateRadioBlock").removeAttribute("id");
  225. }
  226. function initPluginsRow() {
  227. let vulnerableLabel = document.getElementById("browserBundle")
  228. .getString("pluginActivateVulnerable.label");
  229. let pluginHost = Components.classes["@mozilla.org/plugin/host;1"]
  230. .getService(Components.interfaces.nsIPluginHost);
  231. let tags = pluginHost.getPluginTags();
  232. let permissionMap = new Map();
  233. for (let plugin of tags) {
  234. if (plugin.disabled) {
  235. continue;
  236. }
  237. for (let mimeType of plugin.getMimeTypes()) {
  238. if (mimeType == "application/x-shockwave-flash" && plugin.name != "Shockwave Flash") {
  239. continue;
  240. }
  241. let permString = pluginHost.getPermissionStringForType(mimeType);
  242. if (!permissionMap.has(permString)) {
  243. let name = makeNicePluginName(plugin.name) + " " + plugin.version;
  244. let vulnerable = false;
  245. if (permString.startsWith("plugin-vulnerable:")) {
  246. name += " \u2014 " + vulnerableLabel;
  247. vulnerable = true;
  248. }
  249. permissionMap.set(permString, {
  250. "name": name,
  251. "description": plugin.description,
  252. "vulnerable": vulnerable
  253. });
  254. }
  255. }
  256. }
  257. // Tycho:
  258. // let entries = [
  259. // {
  260. // "permission": item[0],
  261. // "obj": item[1],
  262. // }
  263. // for (item of permissionMap)
  264. // ];
  265. let entries = [];
  266. for (let item of permissionMap) {
  267. entries.push({
  268. "permission": item[0],
  269. "obj": item[1]
  270. });
  271. }
  272. entries.sort(function(a, b) {
  273. return ((a.obj.name < b.obj.name) ? -1 : (a.obj.name == b.obj.name ? 0 : 1));
  274. });
  275. // Tycho:
  276. // let permissionEntries = [
  277. // fillInPluginPermissionTemplate(p.permission, p.obj) for (p of entries)
  278. // ];
  279. let permissionEntries = [];
  280. entries.forEach(function(p) {
  281. permissionEntries.push(fillInPluginPermissionTemplate(p.permission, p.obj));
  282. });
  283. let permPluginsRow = document.getElementById("permPluginsRow");
  284. clearPluginPermissionTemplate();
  285. if (permissionEntries.length < 1) {
  286. permPluginsRow.hidden = true;
  287. return;
  288. }
  289. for (let permissionEntry of permissionEntries) {
  290. permPluginsRow.appendChild(permissionEntry);
  291. }
  292. setPluginsRadioState();
  293. }
  294. function setPluginsRadioState() {
  295. var permissionManager = Components.classes[PERMISSION_CONTRACTID]
  296. .getService(nsIPermissionManager);
  297. let box = document.getElementById("permPluginsRow");
  298. for (let permissionEntry of box.childNodes) {
  299. if (permissionEntry.hasAttribute("permString")) {
  300. let permString = permissionEntry.getAttribute("permString");
  301. let permission = permissionManager.testPermission(gPermURI, permString);
  302. setRadioState(permString, permission);
  303. }
  304. }
  305. }