Bug 1196512 - Use principals to test for push permissions. r=nsm

--HG--
extra : commitid : 7scu10UsEc9
extra : rebase_source : ce8993d0662dfea702b82abf54b98a3f318c386f
extra : amend_source : 0ce3c201cebb227a2e16be35e907f42f73426e03
This commit is contained in:
Kit Cambridge 2015-08-19 16:03:15 -07:00
Родитель a737f6fe28
Коммит 1acca57a40
2 изменённых файлов: 54 добавлений и 15 удалений

Просмотреть файл

@ -19,11 +19,14 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
"resource://gre/modules/BrowserUtils.jsm");
this.EXPORTED_SYMBOLS = ["PushRecord"];
const prefs = new Preferences("dom.push.");
// History transition types that can fire an `pushsubscriptionchange` event
// History transition types that can fire a `pushsubscriptionchange` event
// when the user visits a site with expired push registrations. Visits only
// count if the user sees the origin in the address bar. This excludes embedded
// resources, downloads, and framed links.
@ -38,7 +41,6 @@ const QUOTA_REFRESH_TRANSITIONS_SQL = [
function PushRecord(props) {
this.pushEndpoint = props.pushEndpoint;
this.scope = props.scope;
this.origin = Services.io.newURI(this.scope, null, null).prePath;
this.originAttributes = props.originAttributes;
this.pushCount = props.pushCount || 0;
this.lastPush = props.lastPush || 0;
@ -116,8 +118,8 @@ PushRecord.prototype = {
`,
{
// Restrict the query to all pages for this origin.
urlLowerBound: this.origin,
urlUpperBound: this.origin + "\x7f"
urlLowerBound: this.uri.prePath,
urlUpperBound: this.uri.prePath + "\x7f",
}
);
}).then(rows => {
@ -143,7 +145,7 @@ PushRecord.prototype = {
for (let tab of tabs) {
// `linkedBrowser` on Desktop; `browser` on Fennec.
let tabURI = (tab.linkedBrowser || tab.browser).currentURI;
if (tabURI.prePath == this.origin) {
if (tabURI.prePath == this.uri.prePath) {
return true;
}
}
@ -151,6 +153,24 @@ PushRecord.prototype = {
return false;
},
/**
* Returns the push permission state for the principal associated with
* this registration.
*/
pushPermission() {
return Services.perms.testExactPermissionFromPrincipal(
this.principal, "push");
},
/**
* Indicates whether the registration can deliver push messages to its
* associated service worker.
*/
hasPermission() {
let permission = this.pushPermission();
return permission == Ci.nsIPermissionManager.ALLOW_ACTION;
},
quotaApplies() {
return Number.isFinite(this.quota);
},
@ -174,10 +194,31 @@ PushRecord.prototype = {
},
};
// Mark the `origin` property as non-enumerable to avoid storing the
// registration origin in IndexedDB.
Object.defineProperty(PushRecord.prototype, "origin", {
configurable: true,
enumerable: false,
writable: true,
// Define lazy getters for the principal and scope URI. IndexedDB can't store
// `nsIPrincipal` objects, so we keep them in a private weak map.
let principals = new WeakMap();
Object.defineProperties(PushRecord.prototype, {
principal: {
get() {
let principal = principals.get(this);
if (!principal) {
let url = this.scope;
if (this.originAttributes) {
// Allow tests to omit origin attributes.
url += this.originAttributes;
}
principal = BrowserUtils.principalFromOrigin(url);
principals.set(this, principal);
}
return principal;
},
configurable: true,
},
uri: {
get() {
return this.principal.URI;
},
configurable: true,
},
});

Просмотреть файл

@ -789,7 +789,6 @@ this.PushService = {
}
debug("notifyApp() " + aPushRecord.scope);
let scopeURI = Services.io.newURI(aPushRecord.scope, null, null);
// Notify XPCOM observers.
let notification = Cc["@mozilla.org/push/ObserverNotification;1"]
.createInstance(Ci.nsIPushObserverNotification);
@ -806,8 +805,7 @@ this.PushService = {
);
// If permission has been revoked, trash the message.
if (Services.perms.testExactPermission(scopeURI, "push") !=
Ci.nsIPermissionManager.ALLOW_ACTION) {
if (!aPushRecord.hasPermission()) {
debug("Does not have permission for push.");
return;
}
@ -1096,7 +1094,7 @@ this.PushService = {
let clear = (db, domain) => {
db.clearIf(record => {
return hasRootDomain(record.origin, domain);
return hasRootDomain(record.uri.prePath, domain);
});
}