summaryrefslogtreecommitdiff
path: root/dom/permission/PermissionSettings.js
blob: 0921554ea2b20059473bcf07bd59b04e8649622f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* 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/. */

"use strict";

function debug(aMsg) {
  //dump("-*- PermissionSettings.js: " + aMsg + "\n");
}

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;

Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PermissionsTable.jsm");

var cpm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);

// PermissionSettings

const PERMISSIONSETTINGS_CONTRACTID = "@mozilla.org/permissionSettings;1";
const PERMISSIONSETTINGS_CID        = Components.ID("{cd2cf7a1-f4c1-487b-8c1b-1a71c7097431}");

function PermissionSettings()
{
  debug("Constructor");
}

XPCOMUtils.defineLazyServiceGetter(this,
                                   "appsService",
                                   "@mozilla.org/AppsService;1",
                                   "nsIAppsService");

PermissionSettings.prototype = {
  get: function get(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
    debug("Get called with: " + aPermName + ", " + aManifestURL + ", " + aOrigin + ", " + aBrowserFlag);
    let uri = Services.io.newURI(aOrigin, null, null);
    let appID = appsService.getAppLocalIdByManifestURL(aManifestURL);
    let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(uri, appID, aBrowserFlag);
    let result = Services.perms.testExactPermanentPermission(principal, aPermName);

    switch (result)
    {
      case Ci.nsIPermissionManager.UNKNOWN_ACTION:
        return "unknown";
      case Ci.nsIPermissionManager.ALLOW_ACTION:
        return "allow";
      case Ci.nsIPermissionManager.DENY_ACTION:
        return "deny";
      case Ci.nsIPermissionManager.PROMPT_ACTION:
        return "prompt";
      default:
        dump("Unsupported PermissionSettings Action!\n");
        return "unknown";
    }
  },

  isExplicit: function isExplicit(aPermName, aManifestURL, aOrigin,
                                  aBrowserFlag) {
    debug("isExplicit: " + aPermName + ", " + aManifestURL + ", " + aOrigin);
    let uri = Services.io.newURI(aOrigin, null, null);
    let app = appsService.getAppByManifestURL(aManifestURL);
    let principal = Services.scriptSecurityManager
      .getAppCodebasePrincipal(uri, app.localId, aBrowserFlag);

    return isExplicitInPermissionsTable(aPermName,
                                        principal.appStatus,
                                        app.kind);
  },

  set: function set(aPermName, aPermValue, aManifestURL, aOrigin,
                    aBrowserFlag) {
    debug("Set called with: " + aPermName + ", " + aManifestURL + ", " +
          aOrigin + ",  " + aPermValue + ", " + aBrowserFlag);
    let currentPermValue = this.get(aPermName, aManifestURL, aOrigin,
                                    aBrowserFlag);
    let action;
    // Check for invalid calls so that we throw an exception rather than get
    // killed by parent process
    if (currentPermValue === "unknown" ||
        aPermValue === "unknown" ||
        !this.isExplicit(aPermName, aManifestURL, aOrigin, aBrowserFlag)) {
      let errorMsg = "PermissionSettings.js: '" + aPermName + "'" +
                     " is an implicit permission for '" + aManifestURL +
                     "' or the permission isn't set";
      Cu.reportError(errorMsg);
      throw new Components.Exception(errorMsg);
    }

    cpm.sendSyncMessage("PermissionSettings:AddPermission", {
      type: aPermName,
      origin: aOrigin,
      manifestURL: aManifestURL,
      value: aPermValue,
      browserFlag: aBrowserFlag
    });
  },

  remove: function remove(aPermName, aManifestURL, aOrigin) {
    let uri = Services.io.newURI(aOrigin, null, null);
    let appID = appsService.getAppLocalIdByManifestURL(aManifestURL);
    let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(uri, appID, true);

    if (principal.appStatus !== Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
      let errorMsg = "PermissionSettings.js: '" + aOrigin + "'" +
                     " is installed or permission is implicit, cannot remove '" +
                     aPermName + "'.";
      Cu.reportError(errorMsg);
      throw new Components.Exception(errorMsg);
    }

    // PermissionSettings.jsm handles delete when value is "unknown"
    cpm.sendSyncMessage("PermissionSettings:AddPermission", {
      type: aPermName,
      origin: aOrigin,
      manifestURL: aManifestURL,
      value: "unknown",
      browserFlag: true
    });
  },

  classID : PERMISSIONSETTINGS_CID,
  QueryInterface : XPCOMUtils.generateQI([])
}

this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PermissionSettings])