forked from mirrors/gecko-dev
		
	Depends on D167988 Differential Revision: https://phabricator.services.mozilla.com/D169233
		
			
				
	
	
		
			709 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			709 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Any copyright is dedicated to the Public Domain.
 | 
						|
 * http://creativecommons.org/publicdomain/zero/1.0/
 | 
						|
 */
 | 
						|
"use strict";
 | 
						|
 | 
						|
const { SitePermissions } = ChromeUtils.import(
 | 
						|
  "resource:///modules/SitePermissions.jsm"
 | 
						|
);
 | 
						|
 | 
						|
const TemporaryPermissions = SitePermissions._temporaryPermissions;
 | 
						|
 | 
						|
const PERM_A = "foo";
 | 
						|
const PERM_B = "bar";
 | 
						|
const PERM_C = "foobar";
 | 
						|
 | 
						|
const BROWSER_A = createDummyBrowser("https://example.com/foo");
 | 
						|
const BROWSER_B = createDummyBrowser("https://example.org/foo");
 | 
						|
 | 
						|
const EXPIRY_MS_A = 1000000;
 | 
						|
const EXPIRY_MS_B = 1000001;
 | 
						|
 | 
						|
function createDummyBrowser(spec) {
 | 
						|
  let uri = Services.io.newURI(spec);
 | 
						|
  return {
 | 
						|
    currentURI: uri,
 | 
						|
    contentPrincipal: Services.scriptSecurityManager.createContentPrincipal(
 | 
						|
      uri,
 | 
						|
      {}
 | 
						|
    ),
 | 
						|
    dispatchEvent: () => {},
 | 
						|
    ownerGlobal: {
 | 
						|
      CustomEvent: class CustomEvent {},
 | 
						|
    },
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
function navigateDummyBrowser(browser, uri) {
 | 
						|
  // Callers may pass in either uri strings or nsIURI objects.
 | 
						|
  if (typeof uri == "string") {
 | 
						|
    uri = Services.io.newURI(uri);
 | 
						|
  }
 | 
						|
  browser.currentURI = uri;
 | 
						|
  browser.contentPrincipal = Services.scriptSecurityManager.createContentPrincipal(
 | 
						|
    browser.currentURI,
 | 
						|
    {}
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that temporary permissions with different block states are stored
 | 
						|
 * (set, overwrite, delete) correctly.
 | 
						|
 */
 | 
						|
add_task(async function testAllowBlock() {
 | 
						|
  // Set two temporary permissions on the same browser.
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_A,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_A,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_B,
 | 
						|
    SitePermissions.BLOCK,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_A,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
 | 
						|
  // Test that the permissions have been set correctly.
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_A, BROWSER_A),
 | 
						|
    {
 | 
						|
      state: SitePermissions.ALLOW,
 | 
						|
      scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    },
 | 
						|
    "SitePermissions returns expected permission state for perm A."
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_B, BROWSER_A),
 | 
						|
    {
 | 
						|
      state: SitePermissions.BLOCK,
 | 
						|
      scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    },
 | 
						|
    "SitePermissions returns expected permission state for perm B."
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    TemporaryPermissions.get(BROWSER_A, PERM_A),
 | 
						|
    {
 | 
						|
      id: PERM_A,
 | 
						|
      state: SitePermissions.ALLOW,
 | 
						|
      scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    },
 | 
						|
    "TemporaryPermissions returns expected permission state for perm A."
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    TemporaryPermissions.get(BROWSER_A, PERM_B),
 | 
						|
    {
 | 
						|
      id: PERM_B,
 | 
						|
      state: SitePermissions.BLOCK,
 | 
						|
      scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    },
 | 
						|
    "TemporaryPermissions returns expected permission state for perm B."
 | 
						|
  );
 | 
						|
 | 
						|
  // Test internal data structure of TemporaryPermissions.
 | 
						|
  let entry = TemporaryPermissions._stateByBrowser.get(BROWSER_A);
 | 
						|
  ok(entry, "Should have an entry for browser A");
 | 
						|
  ok(
 | 
						|
    !TemporaryPermissions._stateByBrowser.has(BROWSER_B),
 | 
						|
    "Should have no entry for browser B"
 | 
						|
  );
 | 
						|
 | 
						|
  let { browser, uriToPerm } = entry;
 | 
						|
  Assert.equal(
 | 
						|
    browser?.get(),
 | 
						|
    BROWSER_A,
 | 
						|
    "Entry should have a weak reference to the browser."
 | 
						|
  );
 | 
						|
 | 
						|
  ok(uriToPerm, "Entry should have uriToPerm object.");
 | 
						|
  Assert.equal(Object.keys(uriToPerm).length, 2, "uriToPerm has 2 entries.");
 | 
						|
 | 
						|
  let permissionsA = uriToPerm[BROWSER_A.contentPrincipal.origin];
 | 
						|
  let permissionsB =
 | 
						|
    uriToPerm[Services.eTLD.getBaseDomain(BROWSER_A.currentURI)];
 | 
						|
 | 
						|
  ok(permissionsA, "Allow should be keyed under origin");
 | 
						|
  ok(permissionsB, "Block should be keyed under baseDomain");
 | 
						|
 | 
						|
  let permissionA = permissionsA[PERM_A];
 | 
						|
  let permissionB = permissionsB[PERM_B];
 | 
						|
 | 
						|
  Assert.equal(
 | 
						|
    permissionA.state,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    "Should have correct state"
 | 
						|
  );
 | 
						|
  let expireTimeoutA = permissionA.expireTimeout;
 | 
						|
  Assert.ok(
 | 
						|
    Number.isInteger(expireTimeoutA),
 | 
						|
    "Should have valid expire timeout"
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.equal(
 | 
						|
    permissionB.state,
 | 
						|
    SitePermissions.BLOCK,
 | 
						|
    "Should have correct state"
 | 
						|
  );
 | 
						|
  let expireTimeoutB = permissionB.expireTimeout;
 | 
						|
  Assert.ok(
 | 
						|
    Number.isInteger(expireTimeoutB),
 | 
						|
    "Should have valid expire timeout"
 | 
						|
  );
 | 
						|
 | 
						|
  // Overwrite permission A.
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_A,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_A,
 | 
						|
    EXPIRY_MS_B
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.ok(
 | 
						|
    permissionsA[PERM_A].expireTimeout != expireTimeoutA,
 | 
						|
    "Overwritten permission A should have new timer"
 | 
						|
  );
 | 
						|
 | 
						|
  // Overwrite permission B - this time with a non-block state which means it
 | 
						|
  // should be keyed by origin now.
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_B,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_A,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
 | 
						|
  let baseDomainEntry =
 | 
						|
    uriToPerm[Services.eTLD.getBaseDomain(BROWSER_A.currentURI)];
 | 
						|
  Assert.ok(
 | 
						|
    !baseDomainEntry || !baseDomainEntry[PERM_B],
 | 
						|
    "Should not longer have baseDomain permission entry"
 | 
						|
  );
 | 
						|
 | 
						|
  permissionsB = uriToPerm[BROWSER_A.contentPrincipal.origin];
 | 
						|
  permissionB = permissionsB[PERM_B];
 | 
						|
  Assert.ok(
 | 
						|
    permissionsB && permissionB,
 | 
						|
    "Overwritten permission should be keyed under origin"
 | 
						|
  );
 | 
						|
  Assert.equal(
 | 
						|
    permissionB.state,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    "Should have correct updated state"
 | 
						|
  );
 | 
						|
  Assert.ok(
 | 
						|
    permissionB.expireTimeout != expireTimeoutB,
 | 
						|
    "Overwritten permission B should have new timer"
 | 
						|
  );
 | 
						|
 | 
						|
  // Remove permissions
 | 
						|
  SitePermissions.removeFromPrincipal(null, PERM_A, BROWSER_A);
 | 
						|
  SitePermissions.removeFromPrincipal(null, PERM_B, BROWSER_A);
 | 
						|
 | 
						|
  // Test that permissions have been removed correctly
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_A, BROWSER_A),
 | 
						|
    {
 | 
						|
      state: SitePermissions.UNKNOWN,
 | 
						|
      scope: SitePermissions.SCOPE_PERSISTENT,
 | 
						|
    },
 | 
						|
    "SitePermissions returns UNKNOWN state for A."
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_B, BROWSER_A),
 | 
						|
    {
 | 
						|
      state: SitePermissions.UNKNOWN,
 | 
						|
      scope: SitePermissions.SCOPE_PERSISTENT,
 | 
						|
    },
 | 
						|
    "SitePermissions returns UNKNOWN state for B."
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.equal(
 | 
						|
    TemporaryPermissions.get(BROWSER_A, PERM_A),
 | 
						|
    null,
 | 
						|
    "TemporaryPermissions returns null for perm A."
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.equal(
 | 
						|
    TemporaryPermissions.get(BROWSER_A, PERM_B),
 | 
						|
    null,
 | 
						|
    "TemporaryPermissions returns null for perm B."
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests TemporaryPermissions#getAll.
 | 
						|
 */
 | 
						|
add_task(async function testGetAll() {
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_A,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_A,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_B,
 | 
						|
    SitePermissions.BLOCK,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_B,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_C,
 | 
						|
    SitePermissions.PROMPT,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_B,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(TemporaryPermissions.getAll(BROWSER_A), [
 | 
						|
    {
 | 
						|
      id: PERM_A,
 | 
						|
      state: SitePermissions.ALLOW,
 | 
						|
      scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    },
 | 
						|
  ]);
 | 
						|
 | 
						|
  let permsBrowserB = TemporaryPermissions.getAll(BROWSER_B);
 | 
						|
  Assert.equal(
 | 
						|
    permsBrowserB.length,
 | 
						|
    2,
 | 
						|
    "There should be 2 permissions set for BROWSER_B"
 | 
						|
  );
 | 
						|
 | 
						|
  let permB;
 | 
						|
  let permC;
 | 
						|
 | 
						|
  if (permsBrowserB[0].id == PERM_B) {
 | 
						|
    permB = permsBrowserB[0];
 | 
						|
    permC = permsBrowserB[1];
 | 
						|
  } else {
 | 
						|
    permB = permsBrowserB[1];
 | 
						|
    permC = permsBrowserB[0];
 | 
						|
  }
 | 
						|
 | 
						|
  Assert.deepEqual(permB, {
 | 
						|
    id: PERM_B,
 | 
						|
    state: SitePermissions.BLOCK,
 | 
						|
    scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
  });
 | 
						|
  Assert.deepEqual(permC, {
 | 
						|
    id: PERM_C,
 | 
						|
    state: SitePermissions.PROMPT,
 | 
						|
    scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests SitePermissions#clearTemporaryBlockPermissions and
 | 
						|
 * TemporaryPermissions#clear.
 | 
						|
 */
 | 
						|
add_task(async function testClear() {
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_A,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_A,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_B,
 | 
						|
    SitePermissions.BLOCK,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_A,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_C,
 | 
						|
    SitePermissions.BLOCK,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_B,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
 | 
						|
  let stateByBrowser = SitePermissions._temporaryPermissions._stateByBrowser;
 | 
						|
 | 
						|
  Assert.ok(stateByBrowser.has(BROWSER_A), "Browser map should have BROWSER_A");
 | 
						|
  Assert.ok(stateByBrowser.has(BROWSER_B), "Browser map should have BROWSER_B");
 | 
						|
 | 
						|
  SitePermissions.clearTemporaryBlockPermissions(BROWSER_A);
 | 
						|
 | 
						|
  // We only clear block permissions, so we should still see PERM_A.
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_A, BROWSER_A),
 | 
						|
    {
 | 
						|
      state: SitePermissions.ALLOW,
 | 
						|
      scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    },
 | 
						|
    "SitePermissions returns ALLOW state for PERM_A."
 | 
						|
  );
 | 
						|
  // We don't clear BROWSER_B so it should still be there.
 | 
						|
  Assert.ok(stateByBrowser.has(BROWSER_B), "Should still have BROWSER_B.");
 | 
						|
 | 
						|
  // Now clear allow permissions for A explicitly.
 | 
						|
  SitePermissions._temporaryPermissions.clear(BROWSER_A, SitePermissions.ALLOW);
 | 
						|
 | 
						|
  Assert.ok(!stateByBrowser.has(BROWSER_A), "Should no longer have BROWSER_A.");
 | 
						|
  let browser = stateByBrowser.get(BROWSER_B);
 | 
						|
  Assert.ok(browser, "Should still have BROWSER_B");
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_A, BROWSER_A),
 | 
						|
    {
 | 
						|
      state: SitePermissions.UNKNOWN,
 | 
						|
      scope: SitePermissions.SCOPE_PERSISTENT,
 | 
						|
    },
 | 
						|
    "SitePermissions returns UNKNOWN state for PERM_A."
 | 
						|
  );
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_B, BROWSER_A),
 | 
						|
    {
 | 
						|
      state: SitePermissions.UNKNOWN,
 | 
						|
      scope: SitePermissions.SCOPE_PERSISTENT,
 | 
						|
    },
 | 
						|
    "SitePermissions returns UNKNOWN state for PERM_B."
 | 
						|
  );
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_C, BROWSER_B),
 | 
						|
    {
 | 
						|
      state: SitePermissions.BLOCK,
 | 
						|
      scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    },
 | 
						|
    "SitePermissions returns BLOCK state for PERM_C."
 | 
						|
  );
 | 
						|
 | 
						|
  SitePermissions._temporaryPermissions.clear(BROWSER_B);
 | 
						|
 | 
						|
  Assert.ok(!stateByBrowser.has(BROWSER_B), "Should no longer have BROWSER_B.");
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_C, BROWSER_B),
 | 
						|
    {
 | 
						|
      state: SitePermissions.UNKNOWN,
 | 
						|
      scope: SitePermissions.SCOPE_PERSISTENT,
 | 
						|
    },
 | 
						|
    "SitePermissions returns UNKNOWN state for PERM_C."
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that the temporary permissions setter calls the callback on permission
 | 
						|
 * expire with the associated browser.
 | 
						|
 */
 | 
						|
add_task(async function testCallbackOnExpiry() {
 | 
						|
  let promiseExpireA = new Promise(resolve => {
 | 
						|
    TemporaryPermissions.set(
 | 
						|
      BROWSER_A,
 | 
						|
      PERM_A,
 | 
						|
      SitePermissions.BLOCK,
 | 
						|
      100,
 | 
						|
      undefined,
 | 
						|
      resolve
 | 
						|
    );
 | 
						|
  });
 | 
						|
  let promiseExpireB = new Promise(resolve => {
 | 
						|
    TemporaryPermissions.set(
 | 
						|
      BROWSER_B,
 | 
						|
      PERM_A,
 | 
						|
      SitePermissions.BLOCK,
 | 
						|
      100,
 | 
						|
      BROWSER_B.contentPrincipal,
 | 
						|
      resolve
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  let [browserA, browserB] = await Promise.all([
 | 
						|
    promiseExpireA,
 | 
						|
    promiseExpireB,
 | 
						|
  ]);
 | 
						|
  Assert.equal(
 | 
						|
    browserA,
 | 
						|
    BROWSER_A,
 | 
						|
    "Should get callback with browser on expiry for A"
 | 
						|
  );
 | 
						|
  Assert.equal(
 | 
						|
    browserB,
 | 
						|
    BROWSER_B,
 | 
						|
    "Should get callback with browser on expiry for B"
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that the temporary permissions setter calls the callback on permission
 | 
						|
 * expire with the associated browser if the browser associated browser has
 | 
						|
 * changed after setting the permission.
 | 
						|
 */
 | 
						|
add_task(async function testCallbackOnExpiryUpdatedBrowser() {
 | 
						|
  let promiseExpire = new Promise(resolve => {
 | 
						|
    TemporaryPermissions.set(
 | 
						|
      BROWSER_A,
 | 
						|
      PERM_A,
 | 
						|
      SitePermissions.BLOCK,
 | 
						|
      200,
 | 
						|
      undefined,
 | 
						|
      resolve
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  TemporaryPermissions.copy(BROWSER_A, BROWSER_B);
 | 
						|
 | 
						|
  let browser = await promiseExpire;
 | 
						|
  Assert.equal(
 | 
						|
    browser,
 | 
						|
    BROWSER_B,
 | 
						|
    "Should get callback with updated browser on expiry."
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that the permission setter throws an exception if an invalid expiry
 | 
						|
 * time is passed.
 | 
						|
 */
 | 
						|
add_task(async function testInvalidExpiryTime() {
 | 
						|
  let expectedError = /expireTime must be a positive integer/;
 | 
						|
  Assert.throws(() => {
 | 
						|
    SitePermissions.setForPrincipal(
 | 
						|
      null,
 | 
						|
      PERM_A,
 | 
						|
      SitePermissions.ALLOW,
 | 
						|
      SitePermissions.SCOPE_TEMPORARY,
 | 
						|
      BROWSER_A,
 | 
						|
      null
 | 
						|
    );
 | 
						|
  }, expectedError);
 | 
						|
  Assert.throws(() => {
 | 
						|
    SitePermissions.setForPrincipal(
 | 
						|
      null,
 | 
						|
      PERM_A,
 | 
						|
      SitePermissions.ALLOW,
 | 
						|
      SitePermissions.SCOPE_TEMPORARY,
 | 
						|
      BROWSER_A,
 | 
						|
      0
 | 
						|
    );
 | 
						|
  }, expectedError);
 | 
						|
  Assert.throws(() => {
 | 
						|
    SitePermissions.setForPrincipal(
 | 
						|
      null,
 | 
						|
      PERM_A,
 | 
						|
      SitePermissions.ALLOW,
 | 
						|
      SitePermissions.SCOPE_TEMPORARY,
 | 
						|
      BROWSER_A,
 | 
						|
      -100
 | 
						|
    );
 | 
						|
  }, expectedError);
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that we block by base domain but allow by origin.
 | 
						|
 */
 | 
						|
add_task(async function testTemporaryPermissionScope() {
 | 
						|
  let states = {
 | 
						|
    strict: {
 | 
						|
      same: [
 | 
						|
        "https://example.com",
 | 
						|
        "https://example.com/sub/path",
 | 
						|
        "https://example.com:443",
 | 
						|
        "https://name:password@example.com",
 | 
						|
      ],
 | 
						|
      different: [
 | 
						|
        "https://example.com",
 | 
						|
        "https://test1.example.com",
 | 
						|
        "http://example.com",
 | 
						|
        "http://example.org",
 | 
						|
        "file:///tmp/localPageA.html",
 | 
						|
        "file:///tmp/localPageB.html",
 | 
						|
      ],
 | 
						|
    },
 | 
						|
    nonStrict: {
 | 
						|
      same: [
 | 
						|
        "https://example.com",
 | 
						|
        "https://example.com/sub/path",
 | 
						|
        "https://example.com:443",
 | 
						|
        "https://test1.example.com",
 | 
						|
        "http://test2.test1.example.com",
 | 
						|
        "https://name:password@example.com",
 | 
						|
        "http://example.com",
 | 
						|
      ],
 | 
						|
      different: [
 | 
						|
        "https://example.com",
 | 
						|
        "https://example.org",
 | 
						|
        "http://example.net",
 | 
						|
      ],
 | 
						|
    },
 | 
						|
  };
 | 
						|
 | 
						|
  for (let state of [SitePermissions.BLOCK, SitePermissions.ALLOW]) {
 | 
						|
    let matchStrict = state != SitePermissions.BLOCK;
 | 
						|
 | 
						|
    let lists = matchStrict ? states.strict : states.nonStrict;
 | 
						|
 | 
						|
    Object.entries(lists).forEach(([type, list]) => {
 | 
						|
      let expectSet = type == "same";
 | 
						|
 | 
						|
      for (let uri of list) {
 | 
						|
        let browser = createDummyBrowser(uri);
 | 
						|
        SitePermissions.setForPrincipal(
 | 
						|
          null,
 | 
						|
          PERM_A,
 | 
						|
          state,
 | 
						|
          SitePermissions.SCOPE_TEMPORARY,
 | 
						|
          browser,
 | 
						|
          EXPIRY_MS_A
 | 
						|
        );
 | 
						|
 | 
						|
        ok(true, "origin:" + browser.contentPrincipal.origin);
 | 
						|
 | 
						|
        for (let otherUri of list) {
 | 
						|
          if (uri == otherUri) {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
          navigateDummyBrowser(browser, otherUri);
 | 
						|
          ok(true, "new origin:" + browser.contentPrincipal.origin);
 | 
						|
 | 
						|
          Assert.deepEqual(
 | 
						|
            SitePermissions.getForPrincipal(null, PERM_A, browser),
 | 
						|
            {
 | 
						|
              state: expectSet ? state : SitePermissions.UNKNOWN,
 | 
						|
              scope: expectSet
 | 
						|
                ? SitePermissions.SCOPE_TEMPORARY
 | 
						|
                : SitePermissions.SCOPE_PERSISTENT,
 | 
						|
            },
 | 
						|
            `${
 | 
						|
              state == SitePermissions.BLOCK ? "Block" : "Allow"
 | 
						|
            } Permission originally set for ${uri} should ${
 | 
						|
              expectSet ? "not" : "also"
 | 
						|
            } be set for ${otherUri}.`
 | 
						|
          );
 | 
						|
        }
 | 
						|
 | 
						|
        SitePermissions._temporaryPermissions.clear(browser);
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that we can override the principal to use for keying temporary
 | 
						|
 * permissions.
 | 
						|
 */
 | 
						|
add_task(async function testOverrideBrowserURI() {
 | 
						|
  let testBrowser = createDummyBrowser("https://old.example.com/foo");
 | 
						|
  let overrideURI = Services.io.newURI("https://test.example.org/test/path");
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    Services.scriptSecurityManager.createContentPrincipal(overrideURI, {}),
 | 
						|
    PERM_A,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    testBrowser,
 | 
						|
    EXPIRY_MS_A
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_A, testBrowser),
 | 
						|
    {
 | 
						|
      state: SitePermissions.UNKNOWN,
 | 
						|
      scope: SitePermissions.SCOPE_PERSISTENT,
 | 
						|
    },
 | 
						|
    "Permission should not be set for old URI."
 | 
						|
  );
 | 
						|
 | 
						|
  // "Navigate" to new URI
 | 
						|
  navigateDummyBrowser(testBrowser, overrideURI);
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_A, testBrowser),
 | 
						|
    {
 | 
						|
      state: SitePermissions.ALLOW,
 | 
						|
      scope: SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    },
 | 
						|
    "Permission should be set for new URI."
 | 
						|
  );
 | 
						|
 | 
						|
  SitePermissions._temporaryPermissions.clear(testBrowser);
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * Tests that TemporaryPermissions does not throw for incompatible URI or
 | 
						|
 * browser.currentURI.
 | 
						|
 */
 | 
						|
add_task(async function testPermissionUnsupportedScheme() {
 | 
						|
  let aboutURI = Services.io.newURI("about:blank");
 | 
						|
 | 
						|
  // Incompatible override URI should not throw or store any permissions.
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    Services.scriptSecurityManager.createContentPrincipal(aboutURI, {}),
 | 
						|
    PERM_A,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    BROWSER_A,
 | 
						|
    EXPIRY_MS_B
 | 
						|
  );
 | 
						|
  Assert.ok(
 | 
						|
    SitePermissions._temporaryPermissions._stateByBrowser.has(BROWSER_A),
 | 
						|
    "Should not have stored permission for unsupported URI scheme."
 | 
						|
  );
 | 
						|
 | 
						|
  let browser = createDummyBrowser("https://example.com/");
 | 
						|
  // Set a permission so we get an entry in the browser map.
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_B,
 | 
						|
    SitePermissions.BLOCK,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    browser
 | 
						|
  );
 | 
						|
 | 
						|
  // Change browser URI to about:blank.
 | 
						|
  navigateDummyBrowser(browser, aboutURI);
 | 
						|
 | 
						|
  // Setting permission for browser with unsupported URI should not throw.
 | 
						|
  SitePermissions.setForPrincipal(
 | 
						|
    null,
 | 
						|
    PERM_A,
 | 
						|
    SitePermissions.ALLOW,
 | 
						|
    SitePermissions.SCOPE_TEMPORARY,
 | 
						|
    browser
 | 
						|
  );
 | 
						|
  Assert.ok(true, "Set should not throw for unsupported URI");
 | 
						|
 | 
						|
  SitePermissions.removeFromPrincipal(null, PERM_A, browser);
 | 
						|
  Assert.ok(true, "Remove should not throw for unsupported URI");
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    SitePermissions.getForPrincipal(null, PERM_A, browser),
 | 
						|
    {
 | 
						|
      state: SitePermissions.UNKNOWN,
 | 
						|
      scope: SitePermissions.SCOPE_PERSISTENT,
 | 
						|
    },
 | 
						|
    "Should return no permission set for unsupported URI."
 | 
						|
  );
 | 
						|
  Assert.ok(true, "Get should not throw for unsupported URI");
 | 
						|
 | 
						|
  // getAll should not throw, but return empty permissions array.
 | 
						|
  let permissions = SitePermissions.getAllForBrowser(browser);
 | 
						|
  Assert.ok(
 | 
						|
    Array.isArray(permissions) && !permissions.length,
 | 
						|
    "Should return empty array for browser on about:blank"
 | 
						|
  );
 | 
						|
 | 
						|
  SitePermissions._temporaryPermissions.clear(browser);
 | 
						|
});
 |