mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 02:09:05 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			319 lines
		
	
	
	
		
			8.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			319 lines
		
	
	
	
		
			8.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Any copyright is dedicated to the Public Domain.
 | 
						|
 * http://creativecommons.org/publicdomain/zero/1.0/ */
 | 
						|
 | 
						|
"use strict";
 | 
						|
 | 
						|
// This function adds the quota storage by simpleDB (one of quota clients
 | 
						|
// managed by the QuotaManager). In this function, a directory
 | 
						|
// ${profile}/storage/default/${origin}/sdb/ and a file inside are expected to
 | 
						|
// be added.
 | 
						|
async function addQuotaStorage(principal) {
 | 
						|
  let connection = Cc["@mozilla.org/dom/sdb-connection;1"].createInstance(
 | 
						|
    Ci.nsISDBConnection
 | 
						|
  );
 | 
						|
 | 
						|
  connection.init(principal);
 | 
						|
 | 
						|
  await new Promise((aResolve, aReject) => {
 | 
						|
    let request = connection.open("db");
 | 
						|
    request.callback = request => {
 | 
						|
      if (request.resultCode == Cr.NS_OK) {
 | 
						|
        aResolve();
 | 
						|
      } else {
 | 
						|
        aReject(request.resultCode);
 | 
						|
      }
 | 
						|
    };
 | 
						|
  });
 | 
						|
 | 
						|
  await new Promise((aResolve, aReject) => {
 | 
						|
    let request = connection.write(new ArrayBuffer(1));
 | 
						|
    request.callback = request => {
 | 
						|
      if (request.resultCode == Cr.NS_OK) {
 | 
						|
        aResolve();
 | 
						|
      } else {
 | 
						|
        aReject(request.resultCode);
 | 
						|
      }
 | 
						|
    };
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
function getPrincipal(url, attr = {}) {
 | 
						|
  let uri = Services.io.newURI(url);
 | 
						|
  let ssm = Services.scriptSecurityManager;
 | 
						|
 | 
						|
  return ssm.createContentPrincipal(uri, attr);
 | 
						|
}
 | 
						|
 | 
						|
function getProfileDir() {
 | 
						|
  let directoryService = Services.dirsvc;
 | 
						|
 | 
						|
  return directoryService.get("ProfD", Ci.nsIFile);
 | 
						|
}
 | 
						|
 | 
						|
function getRelativeFile(relativePath) {
 | 
						|
  let profileDir = getProfileDir();
 | 
						|
 | 
						|
  let file = profileDir.clone();
 | 
						|
  relativePath.split("/").forEach(function (component) {
 | 
						|
    file.append(component);
 | 
						|
  });
 | 
						|
 | 
						|
  return file;
 | 
						|
}
 | 
						|
 | 
						|
function getPath(origin) {
 | 
						|
  // Sanitizing
 | 
						|
  let regex = /[:\/]/g;
 | 
						|
  return "storage/default/" + origin.replace(regex, "+");
 | 
						|
}
 | 
						|
 | 
						|
// This function checks if the origin has the quota storage by checking whether
 | 
						|
// the origin directory of that origin exists or not.
 | 
						|
function hasQuotaStorage(origin, attr) {
 | 
						|
  let path = getPath(origin);
 | 
						|
  if (attr) {
 | 
						|
    let principal = Services.scriptSecurityManager.createContentPrincipal(
 | 
						|
      Services.io.newURI(origin),
 | 
						|
      attr
 | 
						|
    );
 | 
						|
    path += principal.originSuffix;
 | 
						|
  }
 | 
						|
 | 
						|
  let file = getRelativeFile(path);
 | 
						|
  return file.exists();
 | 
						|
}
 | 
						|
 | 
						|
async function runTest(sites, deleteDataFunc) {
 | 
						|
  info(`Adding quota storage`);
 | 
						|
  for (let site of sites) {
 | 
						|
    const principal = getPrincipal(site.origin, site.originAttributes);
 | 
						|
    await addQuotaStorage(principal);
 | 
						|
  }
 | 
						|
 | 
						|
  info(`Verifying ${deleteDataFunc.name}`);
 | 
						|
  let site;
 | 
						|
  while ((site = sites.shift())) {
 | 
						|
    await new Promise(aResolve => {
 | 
						|
      deleteDataFunc(...site.args, value => {
 | 
						|
        Assert.equal(value, 0);
 | 
						|
        aResolve();
 | 
						|
      });
 | 
						|
    });
 | 
						|
 | 
						|
    ok(
 | 
						|
      !hasQuotaStorage(site.origin, site.originAttributes),
 | 
						|
      `${site.origin} has no quota storage`
 | 
						|
    );
 | 
						|
    sites.forEach(remainSite =>
 | 
						|
      ok(
 | 
						|
        hasQuotaStorage(remainSite.origin, remainSite.originAttributes),
 | 
						|
        `${remainSite.origin} has quota storage`
 | 
						|
      )
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
add_setup(async function () {
 | 
						|
  await SpecialPowers.pushPrefEnv({
 | 
						|
    set: [
 | 
						|
      ["dom.quotaManager.testing", true],
 | 
						|
      ["dom.simpleDB.enabled", true],
 | 
						|
    ],
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
const ORG_DOMAIN = "example.org";
 | 
						|
const ORG_DOMAIN_SUB = `test.${ORG_DOMAIN}`;
 | 
						|
const ORG_ORIGIN = `https://${ORG_DOMAIN}`;
 | 
						|
const ORG_ORIGIN_SUB = `https://${ORG_DOMAIN_SUB}`;
 | 
						|
const COM_DOMAIN = "example.com";
 | 
						|
const COM_ORIGIN = `https://${COM_DOMAIN}`;
 | 
						|
const LH_DOMAIN = "localhost";
 | 
						|
const FOO_DOMAIN = "foo.com";
 | 
						|
 | 
						|
add_task(async function test_deleteFromHost() {
 | 
						|
  const sites = [
 | 
						|
    {
 | 
						|
      args: [ORG_DOMAIN, true, Ci.nsIClearDataService.CLEAR_DOM_QUOTA],
 | 
						|
      origin: ORG_ORIGIN,
 | 
						|
    },
 | 
						|
    {
 | 
						|
      args: [COM_DOMAIN, true, Ci.nsIClearDataService.CLEAR_DOM_QUOTA],
 | 
						|
      origin: COM_ORIGIN,
 | 
						|
    },
 | 
						|
    {
 | 
						|
      args: [LH_DOMAIN, true, Ci.nsIClearDataService.CLEAR_DOM_QUOTA],
 | 
						|
      origin: `http://${LH_DOMAIN}:8000`,
 | 
						|
    },
 | 
						|
    {
 | 
						|
      args: [FOO_DOMAIN, true, Ci.nsIClearDataService.CLEAR_DOM_QUOTA],
 | 
						|
      origin: `http://${FOO_DOMAIN}`,
 | 
						|
      originAttributes: { userContextId: 1 },
 | 
						|
    },
 | 
						|
  ];
 | 
						|
 | 
						|
  await runTest(sites, Services.clearData.deleteDataFromHost);
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function test_deleteFromPrincipal() {
 | 
						|
  const sites = [
 | 
						|
    {
 | 
						|
      args: [
 | 
						|
        getPrincipal(ORG_ORIGIN),
 | 
						|
        true,
 | 
						|
        Ci.nsIClearDataService.CLEAR_DOM_QUOTA,
 | 
						|
      ],
 | 
						|
      origin: ORG_ORIGIN,
 | 
						|
    },
 | 
						|
    {
 | 
						|
      args: [
 | 
						|
        getPrincipal(COM_ORIGIN),
 | 
						|
        true,
 | 
						|
        Ci.nsIClearDataService.CLEAR_DOM_QUOTA,
 | 
						|
      ],
 | 
						|
      origin: COM_ORIGIN,
 | 
						|
    },
 | 
						|
  ];
 | 
						|
 | 
						|
  await runTest(sites, Services.clearData.deleteDataFromPrincipal);
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function test_deleteFromOriginAttributes() {
 | 
						|
  const ORG_OA = { userContextId: 1 };
 | 
						|
  const COM_OA = { userContextId: 2 };
 | 
						|
  const sites = [
 | 
						|
    {
 | 
						|
      args: [ORG_OA],
 | 
						|
      origin: ORG_ORIGIN,
 | 
						|
      originAttributes: ORG_OA,
 | 
						|
    },
 | 
						|
    {
 | 
						|
      args: [COM_OA],
 | 
						|
      origin: COM_ORIGIN,
 | 
						|
      originAttributes: COM_OA,
 | 
						|
    },
 | 
						|
  ];
 | 
						|
 | 
						|
  await runTest(
 | 
						|
    sites,
 | 
						|
    Services.clearData.deleteDataFromOriginAttributesPattern
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function test_deleteAll() {
 | 
						|
  info(`Adding quota storage`);
 | 
						|
  await addQuotaStorage(getPrincipal(ORG_ORIGIN));
 | 
						|
  await addQuotaStorage(getPrincipal(COM_ORIGIN));
 | 
						|
 | 
						|
  info(`Verifying deleteData`);
 | 
						|
  await new Promise(aResolve => {
 | 
						|
    Services.clearData.deleteData(
 | 
						|
      Ci.nsIClearDataService.CLEAR_DOM_QUOTA,
 | 
						|
      value => {
 | 
						|
        Assert.equal(value, 0);
 | 
						|
        aResolve();
 | 
						|
      }
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  ok(!hasQuotaStorage(ORG_ORIGIN), `${ORG_ORIGIN} has no quota storage`);
 | 
						|
  ok(!hasQuotaStorage(COM_ORIGIN), `${COM_ORIGIN} has no quota storage`);
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function test_deleteSubdomain() {
 | 
						|
  const ANOTHER_ORIGIN = `https://wwww.${ORG_DOMAIN}`;
 | 
						|
  info(`Adding quota storage`);
 | 
						|
  await addQuotaStorage(getPrincipal(ORG_ORIGIN));
 | 
						|
  await addQuotaStorage(getPrincipal(ANOTHER_ORIGIN));
 | 
						|
 | 
						|
  info(`Verifying deleteDataFromHost for subdomain`);
 | 
						|
  await new Promise(aResolve => {
 | 
						|
    Services.clearData.deleteDataFromHost(
 | 
						|
      ORG_DOMAIN,
 | 
						|
      true,
 | 
						|
      Ci.nsIClearDataService.CLEAR_DOM_QUOTA,
 | 
						|
      value => {
 | 
						|
        Assert.equal(value, 0);
 | 
						|
        aResolve();
 | 
						|
      }
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  ok(!hasQuotaStorage(ORG_ORIGIN), `${ORG_ORIGIN} has no quota storage`);
 | 
						|
  ok(!hasQuotaStorage(COM_ORIGIN), `${ANOTHER_ORIGIN} has no quota storage`);
 | 
						|
});
 | 
						|
 | 
						|
function getOAWithPartitionKey(topLevelBaseDomain, originAttributes = {}) {
 | 
						|
  if (!topLevelBaseDomain) {
 | 
						|
    return originAttributes;
 | 
						|
  }
 | 
						|
  return {
 | 
						|
    ...originAttributes,
 | 
						|
    partitionKey: `(https,${topLevelBaseDomain})`,
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
add_task(async function test_deleteBaseDomain() {
 | 
						|
  info("Adding quota storage");
 | 
						|
  await addQuotaStorage(getPrincipal(ORG_ORIGIN));
 | 
						|
  await addQuotaStorage(getPrincipal(ORG_ORIGIN_SUB));
 | 
						|
  await addQuotaStorage(getPrincipal(COM_ORIGIN));
 | 
						|
 | 
						|
  info("Adding partitioned quota storage");
 | 
						|
  // Partitioned
 | 
						|
  await addQuotaStorage(
 | 
						|
    getPrincipal(COM_ORIGIN, getOAWithPartitionKey(ORG_DOMAIN))
 | 
						|
  );
 | 
						|
  await addQuotaStorage(
 | 
						|
    getPrincipal(COM_ORIGIN, getOAWithPartitionKey(FOO_DOMAIN))
 | 
						|
  );
 | 
						|
  await addQuotaStorage(
 | 
						|
    getPrincipal(ORG_ORIGIN, getOAWithPartitionKey(COM_DOMAIN))
 | 
						|
  );
 | 
						|
 | 
						|
  info(`Verifying deleteDataFromSite`);
 | 
						|
  await new Promise(aResolve => {
 | 
						|
    Services.clearData.deleteDataFromSite(
 | 
						|
      ORG_DOMAIN,
 | 
						|
      {},
 | 
						|
      true,
 | 
						|
      Ci.nsIClearDataService.CLEAR_DOM_QUOTA,
 | 
						|
      value => {
 | 
						|
        Assert.equal(value, 0);
 | 
						|
        aResolve();
 | 
						|
      }
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  ok(!hasQuotaStorage(ORG_ORIGIN), `${ORG_ORIGIN} has no quota storage`);
 | 
						|
  ok(
 | 
						|
    !hasQuotaStorage(ORG_ORIGIN_SUB),
 | 
						|
    `${ORG_ORIGIN_SUB} has no quota storage`
 | 
						|
  );
 | 
						|
  ok(hasQuotaStorage(COM_ORIGIN), `${COM_ORIGIN} has quota storage`);
 | 
						|
 | 
						|
  // Partitioned
 | 
						|
  ok(
 | 
						|
    !hasQuotaStorage(COM_ORIGIN, getOAWithPartitionKey(ORG_DOMAIN)),
 | 
						|
    `${COM_ORIGIN} under ${ORG_DOMAIN} has no quota storage`
 | 
						|
  );
 | 
						|
  ok(
 | 
						|
    hasQuotaStorage(COM_ORIGIN, getOAWithPartitionKey(FOO_DOMAIN)),
 | 
						|
    `${COM_ORIGIN} under ${FOO_DOMAIN} has quota storage`
 | 
						|
  );
 | 
						|
  ok(
 | 
						|
    !hasQuotaStorage(ORG_ORIGIN, getOAWithPartitionKey(COM_DOMAIN)),
 | 
						|
    `${ORG_ORIGIN} under ${COM_DOMAIN} has no quota storage`
 | 
						|
  );
 | 
						|
 | 
						|
  // Cleanup
 | 
						|
  await new Promise(aResolve => {
 | 
						|
    Services.clearData.deleteData(
 | 
						|
      Ci.nsIClearDataService.CLEAR_DOM_QUOTA,
 | 
						|
      value => {
 | 
						|
        Assert.equal(value, 0);
 | 
						|
        aResolve();
 | 
						|
      }
 | 
						|
    );
 | 
						|
  });
 | 
						|
});
 |