Bug 1307577 - Switch to `createCodebasePrincipal` in `PushRecord`. r=mt draft
authorKit Cambridge <kit@yakshaving.ninja>
Thu, 20 Oct 2016 10:29:58 -0700
changeset 427808 b62001f997718455b2b6c7cb3074ee79fa68ec25
parent 426145 c22f0df11dd8dc7671017fb517f5a9deb3c6fce8
child 534558 ad4b518464e8bbacda0c6e50cd2d1de22c50025d
push id33118
push userbmo:kcambridge@mozilla.com
push dateThu, 20 Oct 2016 21:40:34 +0000
reviewersmt
bugs1307577
milestone52.0a1
Bug 1307577 - Switch to `createCodebasePrincipal` in `PushRecord`. r=mt `createCodebasePrincipalFromOrigin` mangles the origin after extracting the suffix. The proper long-term fix is to serialize and store the original principal, instead of reconstructing a new codebase principal from the scope and origin suffix. MozReview-Commit-ID: bS2lRx3n7j
dom/push/PushRecord.jsm
dom/push/test/xpcshell/test_record.js
--- a/dom/push/PushRecord.jsm
+++ b/dom/push/PushRecord.jsm
@@ -291,22 +291,22 @@ var principals = new WeakMap();
 Object.defineProperties(PushRecord.prototype, {
   principal: {
     get() {
       if (this.systemRecord) {
         return Services.scriptSecurityManager.getSystemPrincipal();
       }
       let principal = principals.get(this);
       if (!principal) {
-        let url = this.scope;
-        if (this.originAttributes) {
-          // Allow tests to omit origin attributes.
-          url += this.originAttributes;
-        }
-        principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(url);
+        let uri = Services.io.newURI(this.scope, null, null);
+        // Allow tests to omit origin attributes.
+        let originSuffix = this.originAttributes || "";
+        let originAttributes =
+        principal = Services.scriptSecurityManager.createCodebasePrincipal(uri,
+          ChromeUtils.createOriginAttributesFromOrigin(originSuffix));
         principals.set(this, principal);
       }
       return principal;
     },
     configurable: true,
   },
 
   uri: {
--- a/dom/push/test/xpcshell/test_record.js
+++ b/dom/push/test/xpcshell/test_record.js
@@ -44,10 +44,50 @@ add_task(function* test_systemRecord_upd
   systemRecord.updateQuota(Date.now() - 3 * MS_IN_ONE_DAY);
   equal(systemRecord.quota, Infinity,
     'System subscriptions should ignore quota updates');
   systemRecord.updateQuota(-1);
   equal(systemRecord.quota, Infinity,
     'System subscriptions should ignore the last visit time');
   systemRecord.reduceQuota();
   equal(systemRecord.quota, Infinity,
-    'SYstem subscriptions should ignore quota reductions');
+    'System subscriptions should ignore quota reductions');
 });
+
+function testPermissionCheck(props) {
+  let record = new PushRecord(props);
+  equal(record.uri.spec, props.scope,
+    `Record URI should match scope URL for ${JSON.stringify(props)}`);
+  if (props.originAttributes) {
+    let originSuffix = ChromeUtils.originAttributesToSuffix(
+      record.principal.originAttributes);
+    equal(originSuffix, props.originAttributes,
+      `Origin suffixes should match for ${JSON.stringify(props)}`);
+  }
+  ok(!record.hasPermission(), `Record ${
+    JSON.stringify(props)} should not have permission yet`);
+  let permURI = Services.io.newURI(props.scope, null, null);
+  Services.perms.add(permURI, 'desktop-notification',
+                     Ci.nsIPermissionManager.ALLOW_ACTION);
+  try {
+    ok(record.hasPermission(), `Record ${
+      JSON.stringify(props)} should have permission`);
+  } finally {
+    Services.perms.remove(permURI, 'desktop-notification');
+  }
+}
+
+add_task(function* test_principal_permissions() {
+  let testProps = [{
+    scope: 'https://example.com/',
+  }, {
+    scope: 'https://example.com/',
+    originAttributes: '^userContextId=1',
+  }, {
+    scope: 'https://блог.фанфрог.рф/',
+  }, {
+    scope: 'https://блог.фанфрог.рф/',
+    originAttributes: '^userContextId=1',
+  }];
+  for (let props of testProps) {
+    testPermissionCheck(props);
+  }
+});