dom/apps/src/PermissionsTable.jsm

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/apps/src/PermissionsTable.jsm	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,486 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +"use strict";
     1.9 +
    1.10 +const Ci = Components.interfaces;
    1.11 +const Cu = Components.utils;
    1.12 +
    1.13 +this.EXPORTED_SYMBOLS = [
    1.14 +  "PermissionsTable",
    1.15 +  "PermissionsReverseTable",
    1.16 +  "expandPermissions",
    1.17 +  "appendAccessToPermName",
    1.18 +  "isExplicitInPermissionsTable"
    1.19 +];
    1.20 +
    1.21 +// Permission access flags
    1.22 +const READONLY = "readonly";
    1.23 +const CREATEONLY = "createonly";
    1.24 +const READCREATE = "readcreate";
    1.25 +const READWRITE = "readwrite";
    1.26 +
    1.27 +const UNKNOWN_ACTION = Ci.nsIPermissionManager.UNKNOWN_ACTION;
    1.28 +const ALLOW_ACTION = Ci.nsIPermissionManager.ALLOW_ACTION;
    1.29 +const DENY_ACTION = Ci.nsIPermissionManager.DENY_ACTION;
    1.30 +const PROMPT_ACTION = Ci.nsIPermissionManager.PROMPT_ACTION;
    1.31 +
    1.32 +// Permissions Matrix: https://docs.google.com/spreadsheet/ccc?key=0Akyz_Bqjgf5pdENVekxYRjBTX0dCXzItMnRyUU1RQ0E#gid=0
    1.33 +
    1.34 +// Permissions that are implicit:
    1.35 +// battery-status, network-information, vibration,
    1.36 +// device-capabilities
    1.37 +
    1.38 +this.PermissionsTable =  { geolocation: {
    1.39 +                             app: PROMPT_ACTION,
    1.40 +                             privileged: PROMPT_ACTION,
    1.41 +                             certified: PROMPT_ACTION
    1.42 +                           },
    1.43 +                           camera: {
    1.44 +                             app: DENY_ACTION,
    1.45 +                             privileged: PROMPT_ACTION,
    1.46 +                             certified: ALLOW_ACTION
    1.47 +                           },
    1.48 +                           alarms: {
    1.49 +                             app: ALLOW_ACTION,
    1.50 +                             privileged: ALLOW_ACTION,
    1.51 +                             certified: ALLOW_ACTION
    1.52 +                           },
    1.53 +                           "tcp-socket": {
    1.54 +                             app: DENY_ACTION,
    1.55 +                             privileged: ALLOW_ACTION,
    1.56 +                             certified: ALLOW_ACTION
    1.57 +                           },
    1.58 +                           "network-events": {
    1.59 +                             app: DENY_ACTION,
    1.60 +                             privileged: DENY_ACTION,
    1.61 +                             certified: ALLOW_ACTION
    1.62 +                           },
    1.63 +                           contacts: {
    1.64 +                             app: DENY_ACTION,
    1.65 +                             privileged: PROMPT_ACTION,
    1.66 +                             certified: ALLOW_ACTION,
    1.67 +                             access: ["read", "write", "create"]
    1.68 +                           },
    1.69 +                           "device-storage:apps": {
    1.70 +                             app: DENY_ACTION,
    1.71 +                             privileged: DENY_ACTION,
    1.72 +                             certified: ALLOW_ACTION,
    1.73 +                             access: ["read"]
    1.74 +                           },
    1.75 +                           "device-storage:crashes": {
    1.76 +                             app: DENY_ACTION,
    1.77 +                             privileged: DENY_ACTION,
    1.78 +                             certified: ALLOW_ACTION,
    1.79 +                             access: ["read"]
    1.80 +                           },
    1.81 +                           "device-storage:pictures": {
    1.82 +                             app: DENY_ACTION,
    1.83 +                             privileged: PROMPT_ACTION,
    1.84 +                             certified: ALLOW_ACTION,
    1.85 +                             access: ["read", "write", "create"]
    1.86 +                           },
    1.87 +                           "device-storage:videos": {
    1.88 +                             app: DENY_ACTION,
    1.89 +                             privileged: PROMPT_ACTION,
    1.90 +                             certified: ALLOW_ACTION,
    1.91 +                             access: ["read", "write", "create"]
    1.92 +                           },
    1.93 +                           "device-storage:music": {
    1.94 +                             app: DENY_ACTION,
    1.95 +                             privileged: PROMPT_ACTION,
    1.96 +                             certified: ALLOW_ACTION,
    1.97 +                             access: ["read", "write", "create"]
    1.98 +                           },
    1.99 +                           "device-storage:sdcard": {
   1.100 +                             app: DENY_ACTION,
   1.101 +                             privileged: PROMPT_ACTION,
   1.102 +                             certified: ALLOW_ACTION,
   1.103 +                             access: ["read", "write", "create"]
   1.104 +                           },
   1.105 +                           sms: {
   1.106 +                             app: DENY_ACTION,
   1.107 +                             privileged: DENY_ACTION,
   1.108 +                             certified: ALLOW_ACTION
   1.109 +                           },
   1.110 +                           telephony: {
   1.111 +                             app: DENY_ACTION,
   1.112 +                             privileged: DENY_ACTION,
   1.113 +                             certified: ALLOW_ACTION
   1.114 +                           },
   1.115 +                           browser: {
   1.116 +                             app: DENY_ACTION,
   1.117 +                             privileged: ALLOW_ACTION,
   1.118 +                             certified: ALLOW_ACTION
   1.119 +                           },
   1.120 +                           bluetooth: {
   1.121 +                             app: DENY_ACTION,
   1.122 +                             privileged: DENY_ACTION,
   1.123 +                             certified: ALLOW_ACTION
   1.124 +                           },
   1.125 +                           mobileconnection: {
   1.126 +                             app: DENY_ACTION,
   1.127 +                             privileged: DENY_ACTION,
   1.128 +                             certified: ALLOW_ACTION
   1.129 +                           },
   1.130 +                           mobilenetwork: {
   1.131 +                             app: DENY_ACTION,
   1.132 +                             privileged: ALLOW_ACTION,
   1.133 +                             certified: ALLOW_ACTION
   1.134 +                           },
   1.135 +                           power: {
   1.136 +                             app: DENY_ACTION,
   1.137 +                             privileged: DENY_ACTION,
   1.138 +                             certified: ALLOW_ACTION
   1.139 +                           },
   1.140 +                           push: {
   1.141 +                            app: ALLOW_ACTION,
   1.142 +                            privileged: ALLOW_ACTION,
   1.143 +                            certified: ALLOW_ACTION
   1.144 +                           },
   1.145 +                           settings: {
   1.146 +                             app: DENY_ACTION,
   1.147 +                             privileged: DENY_ACTION,
   1.148 +                             certified: ALLOW_ACTION,
   1.149 +                             access: ["read", "write"],
   1.150 +                             additional: ["indexedDB-chrome-settings"]
   1.151 +                           },
   1.152 +                           permissions: {
   1.153 +                             app: DENY_ACTION,
   1.154 +                             privileged: DENY_ACTION,
   1.155 +                             certified: ALLOW_ACTION
   1.156 +                           },
   1.157 +                           phonenumberservice: {
   1.158 +                             app: DENY_ACTION,
   1.159 +                             privileged: DENY_ACTION,
   1.160 +                             certified: ALLOW_ACTION
   1.161 +                           },
   1.162 +                           fmradio: {
   1.163 +                             app: DENY_ACTION,
   1.164 +                             privileged: ALLOW_ACTION,
   1.165 +                             certified: ALLOW_ACTION
   1.166 +                           },
   1.167 +                           attention: {
   1.168 +                             app: DENY_ACTION,
   1.169 +                             privileged: DENY_ACTION,
   1.170 +                             certified: ALLOW_ACTION
   1.171 +                           },
   1.172 +                           "webapps-manage": {
   1.173 +                             app: DENY_ACTION,
   1.174 +                             privileged: DENY_ACTION,
   1.175 +                             certified: ALLOW_ACTION
   1.176 +                           },
   1.177 +                           "backgroundservice": {
   1.178 +                             app: DENY_ACTION,
   1.179 +                             privileged: DENY_ACTION,
   1.180 +                             certified: ALLOW_ACTION
   1.181 +                           },
   1.182 +                           "desktop-notification": {
   1.183 +                             app: ALLOW_ACTION,
   1.184 +                             privileged: ALLOW_ACTION,
   1.185 +                             certified: ALLOW_ACTION
   1.186 +                           },
   1.187 +                           "networkstats-manage": {
   1.188 +                             app: DENY_ACTION,
   1.189 +                             privileged: DENY_ACTION,
   1.190 +                             certified: ALLOW_ACTION
   1.191 +                           },
   1.192 +                           "wifi-manage": {
   1.193 +                             app: DENY_ACTION,
   1.194 +                             privileged: DENY_ACTION,
   1.195 +                             certified: ALLOW_ACTION
   1.196 +                           },
   1.197 +                           "systemXHR": {
   1.198 +                             app: DENY_ACTION,
   1.199 +                             privileged: ALLOW_ACTION,
   1.200 +                             certified: ALLOW_ACTION
   1.201 +                           },
   1.202 +                           "voicemail": {
   1.203 +                             app: DENY_ACTION,
   1.204 +                             privileged: DENY_ACTION,
   1.205 +                             certified: ALLOW_ACTION
   1.206 +                           },
   1.207 +                           "deprecated-hwvideo": {
   1.208 +                             app: DENY_ACTION,
   1.209 +                             privileged: DENY_ACTION,
   1.210 +                             certified: ALLOW_ACTION
   1.211 +                           },
   1.212 +                           "idle": {
   1.213 +                             app: DENY_ACTION,
   1.214 +                             privileged: DENY_ACTION,
   1.215 +                             certified: ALLOW_ACTION
   1.216 +                           },
   1.217 +                           "time": {
   1.218 +                             app: DENY_ACTION,
   1.219 +                             privileged: DENY_ACTION,
   1.220 +                             certified: ALLOW_ACTION
   1.221 +                           },
   1.222 +                           "embed-apps": {
   1.223 +                             app: DENY_ACTION,
   1.224 +                             privileged: DENY_ACTION,
   1.225 +                             certified: ALLOW_ACTION
   1.226 +                           },
   1.227 +                           "storage": {
   1.228 +                             app: ALLOW_ACTION,
   1.229 +                             privileged: ALLOW_ACTION,
   1.230 +                             certified: ALLOW_ACTION,
   1.231 +                             substitute: [
   1.232 +                               "indexedDB-unlimited",
   1.233 +                               "default-persistent-storage"
   1.234 +                             ]
   1.235 +                           },
   1.236 +                           "background-sensors": {
   1.237 +                             app: DENY_ACTION,
   1.238 +                             privileged: DENY_ACTION,
   1.239 +                             certified: ALLOW_ACTION
   1.240 +                           },
   1.241 +                           cellbroadcast: {
   1.242 +                             app: DENY_ACTION,
   1.243 +                             privileged: DENY_ACTION,
   1.244 +                             certified: ALLOW_ACTION
   1.245 +                           },
   1.246 +                           "audio-channel-normal": {
   1.247 +                             app: ALLOW_ACTION,
   1.248 +                             privileged: ALLOW_ACTION,
   1.249 +                             certified: ALLOW_ACTION
   1.250 +                           },
   1.251 +                           "audio-channel-content": {
   1.252 +                             app: ALLOW_ACTION,
   1.253 +                             privileged: ALLOW_ACTION,
   1.254 +                             certified: ALLOW_ACTION
   1.255 +                           },
   1.256 +                           "audio-channel-notification": {
   1.257 +                             app: DENY_ACTION,
   1.258 +                             privileged: ALLOW_ACTION,
   1.259 +                             certified: ALLOW_ACTION
   1.260 +                           },
   1.261 +                           "audio-channel-alarm": {
   1.262 +                             app: DENY_ACTION,
   1.263 +                             privileged: ALLOW_ACTION,
   1.264 +                             certified: ALLOW_ACTION
   1.265 +                           },
   1.266 +                           "audio-channel-telephony": {
   1.267 +                             app: DENY_ACTION,
   1.268 +                             privileged: DENY_ACTION,
   1.269 +                             certified: ALLOW_ACTION
   1.270 +                           },
   1.271 +                           "audio-channel-ringer": {
   1.272 +                             app: DENY_ACTION,
   1.273 +                             privileged: DENY_ACTION,
   1.274 +                             certified: ALLOW_ACTION
   1.275 +                           },
   1.276 +                           "audio-channel-publicnotification": {
   1.277 +                             app: DENY_ACTION,
   1.278 +                             privileged: DENY_ACTION,
   1.279 +                             certified: ALLOW_ACTION
   1.280 +                           },
   1.281 +                           "open-remote-window": {
   1.282 +                             app: DENY_ACTION,
   1.283 +                             privileged: DENY_ACTION,
   1.284 +                             certified: ALLOW_ACTION
   1.285 +                           },
   1.286 +                           "input": {
   1.287 +                             app: DENY_ACTION,
   1.288 +                             privileged: ALLOW_ACTION,
   1.289 +                             certified: ALLOW_ACTION
   1.290 +                           },
   1.291 +                           "input-manage": {
   1.292 +                             app: DENY_ACTION,
   1.293 +                             privileged: DENY_ACTION,
   1.294 +                             certified: ALLOW_ACTION
   1.295 +                           },
   1.296 +                           "wappush": {
   1.297 +                             app: DENY_ACTION,
   1.298 +                             privileged: DENY_ACTION,
   1.299 +                             certified: ALLOW_ACTION
   1.300 +                           },
   1.301 +                           "audio-capture": {
   1.302 +                             app: PROMPT_ACTION,
   1.303 +                             privileged: PROMPT_ACTION,
   1.304 +                             certified: PROMPT_ACTION
   1.305 +                           },
   1.306 +                           "nfc": {
   1.307 +                             app: DENY_ACTION,
   1.308 +                             privileged: DENY_ACTION,
   1.309 +                             certified: ALLOW_ACTION,
   1.310 +                             access: ["read", "write"]
   1.311 +                           },
   1.312 +                           "nfc-manager": {
   1.313 +                             app: DENY_ACTION,
   1.314 +                             privileged: DENY_ACTION,
   1.315 +                             certified: ALLOW_ACTION
   1.316 +                           },
   1.317 +                           "speaker-control": {
   1.318 +                             app: DENY_ACTION,
   1.319 +                             privileged: ALLOW_ACTION,
   1.320 +                             certified: ALLOW_ACTION
   1.321 +                           },
   1.322 +                           "downloads": {
   1.323 +                             app: DENY_ACTION,
   1.324 +                             privileged: DENY_ACTION,
   1.325 +                             certified: ALLOW_ACTION
   1.326 +                           },
   1.327 +                           "video-capture": {
   1.328 +                             app: PROMPT_ACTION,
   1.329 +                             privileged: PROMPT_ACTION,
   1.330 +                             certified: PROMPT_ACTION
   1.331 +                           },
   1.332 +                         };
   1.333 +
   1.334 +/**
   1.335 + * Append access modes to the permission name as suffixes.
   1.336 + *   e.g. permission name 'contacts' with ['read', 'write'] =
   1.337 + *   ['contacts-read', contacts-write']
   1.338 + * @param string aPermName
   1.339 + * @param array aAccess
   1.340 + * @returns array containing access-appended permission names.
   1.341 + **/
   1.342 +this.appendAccessToPermName = function appendAccessToPermName(aPermName, aAccess) {
   1.343 +  if (aAccess.length == 0) {
   1.344 +    return [aPermName];
   1.345 +  }
   1.346 +  return aAccess.map(function(aMode) {
   1.347 +    return aPermName + "-" + aMode;
   1.348 +  });
   1.349 +};
   1.350 +
   1.351 +/**
   1.352 + * Expand an access string into multiple permission names,
   1.353 + *   e.g: permission name 'contacts' with 'readwrite' =
   1.354 + *   ['contacts-read', 'contacts-create', 'contacts-write']
   1.355 + * @param string aPermName
   1.356 + * @param string aAccess (optional)
   1.357 + * @returns array containing expanded permission names.
   1.358 + **/
   1.359 +this.expandPermissions = function expandPermissions(aPermName, aAccess) {
   1.360 +  if (!PermissionsTable[aPermName]) {
   1.361 +    let errorMsg =
   1.362 +      "PermissionsTable.jsm: expandPermissions: Unknown Permission: " + aPermName;
   1.363 +    Cu.reportError(errorMsg);
   1.364 +    dump(errorMsg);
   1.365 +    return [];
   1.366 +  }
   1.367 +
   1.368 +  const tableEntry = PermissionsTable[aPermName];
   1.369 +
   1.370 +  if (tableEntry.substitute && tableEntry.additional) {
   1.371 +    let errorMsg =
   1.372 +      "PermissionsTable.jsm: expandPermissions: Can't handle both 'substitute' " +
   1.373 +      "and 'additional' entries for permission: " + aPermName;
   1.374 +    Cu.reportError(errorMsg);
   1.375 +    dump(errorMsg);
   1.376 +    return [];
   1.377 +  }
   1.378 +
   1.379 +  if (!aAccess && tableEntry.access ||
   1.380 +      aAccess && !tableEntry.access) {
   1.381 +    let errorMsg =
   1.382 +      "PermissionsTable.jsm: expandPermissions: Invalid access for permission " +
   1.383 +      aPermName + ": " + aAccess + "\n";
   1.384 +    Cu.reportError(errorMsg);
   1.385 +    dump(errorMsg);
   1.386 +    return [];
   1.387 +  }
   1.388 +
   1.389 +  let expandedPermNames = [];
   1.390 +
   1.391 +  if (tableEntry.access && aAccess) {
   1.392 +    let requestedSuffixes = [];
   1.393 +    switch (aAccess) {
   1.394 +    case READONLY:
   1.395 +      requestedSuffixes.push("read");
   1.396 +      break;
   1.397 +    case CREATEONLY:
   1.398 +      requestedSuffixes.push("create");
   1.399 +      break;
   1.400 +    case READCREATE:
   1.401 +      requestedSuffixes.push("read", "create");
   1.402 +      break;
   1.403 +    case READWRITE:
   1.404 +      requestedSuffixes.push("read", "create", "write");
   1.405 +      break;
   1.406 +    default:
   1.407 +      return [];
   1.408 +    }
   1.409 +
   1.410 +    let permArr = appendAccessToPermName(aPermName, requestedSuffixes);
   1.411 +
   1.412 +    // Add the same suffix to each of the additions.
   1.413 +    if (tableEntry.additional) {
   1.414 +      for each (let additional in tableEntry.additional) {
   1.415 +        permArr = permArr.concat(appendAccessToPermName(additional, requestedSuffixes));
   1.416 +      }
   1.417 +    }
   1.418 +
   1.419 +    // Only add the suffixed version if the suffix exists in the table.
   1.420 +    for (let idx in permArr) {
   1.421 +      let suffix = requestedSuffixes[idx % requestedSuffixes.length];
   1.422 +      if (tableEntry.access.indexOf(suffix) != -1) {
   1.423 +        expandedPermNames.push(permArr[idx]);
   1.424 +      }
   1.425 +    }
   1.426 +  } else if (tableEntry.substitute) {
   1.427 +    expandedPermNames = expandedPermNames.concat(tableEntry.substitute);
   1.428 +  } else {
   1.429 +    expandedPermNames.push(aPermName);
   1.430 +    // Include each of the additions exactly as they appear in the table.
   1.431 +    if (tableEntry.additional) {
   1.432 +      expandedPermNames = expandedPermNames.concat(tableEntry.additional);
   1.433 +    }
   1.434 +  }
   1.435 +
   1.436 +  return expandedPermNames;
   1.437 +};
   1.438 +
   1.439 +this.PermissionsReverseTable = (function () {
   1.440 +  // PermissionsTable as it is works well for direct searches, but not
   1.441 +  // so well for reverse ones (that is, if I get something like
   1.442 +  // device-storage:music-read or indexedDB-chrome-settings-read how
   1.443 +  // do I know which permission it really is? Hence this table is
   1.444 +  // born. The idea is that
   1.445 +  // reverseTable[device-storage:music-read] should return
   1.446 +  // device-storage:music
   1.447 +  let reverseTable = {};
   1.448 +
   1.449 +  for (let permName in PermissionsTable) {
   1.450 +    let permAliases;
   1.451 +    if (PermissionsTable[permName].access) {
   1.452 +      permAliases = expandPermissions(permName, "readwrite");
   1.453 +    } else {
   1.454 +      permAliases = expandPermissions(permName);
   1.455 +    }
   1.456 +    for (let i = 0; i < permAliases.length; i++) {
   1.457 +      reverseTable[permAliases[i]] = permName;
   1.458 +    }
   1.459 +  }
   1.460 +
   1.461 +  return reverseTable;
   1.462 +
   1.463 +})();
   1.464 +
   1.465 +this.isExplicitInPermissionsTable = function(aPermName, aIntStatus) {
   1.466 +
   1.467 +  // Check to see if the 'webapp' is app/privileged/certified.
   1.468 +  let appStatus;
   1.469 +  switch (aIntStatus) {
   1.470 +    case Ci.nsIPrincipal.APP_STATUS_CERTIFIED:
   1.471 +      appStatus = "certified";
   1.472 +      break;
   1.473 +    case Ci.nsIPrincipal.APP_STATUS_PRIVILEGED:
   1.474 +      appStatus = "privileged";
   1.475 +      break;
   1.476 +    default: // If it isn't certified or privileged, it's app
   1.477 +      appStatus = "app";
   1.478 +      break;
   1.479 +  }
   1.480 +
   1.481 +  let realPerm = PermissionsReverseTable[aPermName];
   1.482 +
   1.483 +  if (realPerm) {
   1.484 +    return (PermissionsTable[realPerm][appStatus] ==
   1.485 +            Ci.nsIPermissionManager.PROMPT_ACTION);
   1.486 +  } else {
   1.487 +    return false;
   1.488 +  }
   1.489 +}

mercurial