tenfourfox/extensions/cookie/test/unit/test_permmanager_defaults.js
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

254 lines
11 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// The origin we use in most of the tests.
const TEST_ORIGIN = NetUtil.newURI("http://example.org");
const TEST_ORIGIN_HTTPS = NetUtil.newURI("https://example.org");
const TEST_ORIGIN_2 = NetUtil.newURI("http://example.com");
const TEST_ORIGIN_3 = NetUtil.newURI("https://example2.com:8080");
const TEST_PERMISSION = "test-permission";
Components.utils.import("resource://gre/modules/Promise.jsm");
function promiseTimeout(delay) {
let deferred = Promise.defer();
do_timeout(delay, deferred.resolve);
return deferred.promise;
}
function run_test() {
run_next_test();
}
add_task(function* do_test() {
// setup a profile.
do_get_profile();
// create a file in the temp directory with the defaults.
let file = do_get_tempdir();
file.append("test_default_permissions");
// write our test data to it.
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream);
ostream.init(file, -1, 0666, 0);
let conv = Cc["@mozilla.org/intl/converter-output-stream;1"].
createInstance(Ci.nsIConverterOutputStream);
conv.init(ostream, "UTF-8", 0, 0);
conv.writeString("# this is a comment\n");
conv.writeString("\n"); // a blank line!
conv.writeString("host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN.host + "\n");
conv.writeString("host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN_2.host + "\n");
conv.writeString("origin\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN_3.spec + "\n");
conv.writeString("origin\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN.spec + "^appId=1000&inBrowser=1\n");
ostream.close();
// Set the preference used by the permission manager so the file is read.
Services.prefs.setCharPref("permissions.manager.defaultsUrl", "file://" + file.path);
// initialize the permission manager service - it will read that default.
let pm = Cc["@mozilla.org/permissionmanager;1"].
getService(Ci.nsIPermissionManager);
// test the default permission was applied.
let principal = Services.scriptSecurityManager.createCodebasePrincipal(TEST_ORIGIN, {});
let principalHttps = Services.scriptSecurityManager.createCodebasePrincipal(TEST_ORIGIN_HTTPS, {});
let principal2 = Services.scriptSecurityManager.createCodebasePrincipal(TEST_ORIGIN_2, {});
let principal3 = Services.scriptSecurityManager.createCodebasePrincipal(TEST_ORIGIN_3, {});
let attrs = {appId: 1000, inBrowser: true};
let principal4 = Services.scriptSecurityManager.createCodebasePrincipal(TEST_ORIGIN, attrs);
let principal5 = Services.scriptSecurityManager.createCodebasePrincipal(TEST_ORIGIN_3, attrs);
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principalHttps, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal3, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal4, TEST_PERMISSION));
// Didn't add
do_check_eq(Ci.nsIPermissionManager.UNKNOWN_ACTION,
pm.testPermissionFromPrincipal(principal5, TEST_PERMISSION));
// the permission should exist in the enumerator.
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, findCapabilityViaEnum(TEST_ORIGIN));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, findCapabilityViaEnum(TEST_ORIGIN_3));
// but should not have been written to the DB
yield checkCapabilityViaDB(null);
// remove all should not throw and the default should remain
pm.removeAll();
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal3, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal4, TEST_PERMISSION));
// Asking for this permission to be removed should result in that permission
// having UNKNOWN_ACTION
pm.removeFromPrincipal(principal, TEST_PERMISSION);
do_check_eq(Ci.nsIPermissionManager.UNKNOWN_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
// and we should have this UNKNOWN_ACTION reflected in the DB
yield checkCapabilityViaDB(Ci.nsIPermissionManager.UNKNOWN_ACTION);
// but the permission should *not* appear in the enumerator.
do_check_eq(null, findCapabilityViaEnum());
// and a subsequent RemoveAll should restore the default
pm.removeAll();
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
// and allow it to again be seen in the enumerator.
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, findCapabilityViaEnum());
// now explicitly add a permission - this too should override the default.
pm.addFromPrincipal(principal, TEST_PERMISSION, Ci.nsIPermissionManager.DENY_ACTION);
// it should be reflected in a permission check, in the enumerator and the DB
do_check_eq(Ci.nsIPermissionManager.DENY_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.DENY_ACTION, findCapabilityViaEnum());
yield checkCapabilityViaDB(Ci.nsIPermissionManager.DENY_ACTION);
// explicitly add a different permission - in this case we are no longer
// replacing the default, but instead replacing the replacement!
pm.addFromPrincipal(principal, TEST_PERMISSION, Ci.nsIPermissionManager.PROMPT_ACTION);
// it should be reflected in a permission check, in the enumerator and the DB
do_check_eq(Ci.nsIPermissionManager.PROMPT_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.PROMPT_ACTION, findCapabilityViaEnum());
yield checkCapabilityViaDB(Ci.nsIPermissionManager.PROMPT_ACTION);
// --------------------------------------------------------------
// check default permissions and removeAllSince work as expected.
pm.removeAll(); // ensure only defaults are there.
// default for both principals is allow.
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION));
// Add a default override for TEST_ORIGIN_2 - this one should *not* be
// restored in removeAllSince()
pm.addFromPrincipal(principal2, TEST_PERMISSION, Ci.nsIPermissionManager.DENY_ACTION);
do_check_eq(Ci.nsIPermissionManager.DENY_ACTION,
pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION));
yield promiseTimeout(20);
let since = Number(Date.now());
yield promiseTimeout(20);
// explicitly add a permission which overrides the default for the first
// principal - this one *should* be removed by removeAllSince.
pm.addFromPrincipal(principal, TEST_PERMISSION, Ci.nsIPermissionManager.DENY_ACTION);
do_check_eq(Ci.nsIPermissionManager.DENY_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
// do a removeAllSince.
pm.removeAllSince(since);
// the default for the first principal should re-appear as we modified it
// later then |since|
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
// but the permission for principal2 should remain as we added that before |since|.
do_check_eq(Ci.nsIPermissionManager.DENY_ACTION,
pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION));
// remove the temp file we created.
file.remove(false);
});
// use an enumerator to find the requested permission. Returns the permission
// value (ie, the "capability" in nsIPermission parlance) or null if it can't
// be found.
function findCapabilityViaEnum(origin = TEST_ORIGIN, type = TEST_PERMISSION) {
let result = undefined;
let e = Services.perms.enumerator;
while (e.hasMoreElements()) {
let perm = e.getNext().QueryInterface(Ci.nsIPermission);
if (perm.matchesURI(origin, true) &&
perm.type == type) {
if (result !== undefined) {
// we've already found one previously - that's bad!
do_throw("enumerator found multiple entries");
}
result = perm.capability;
}
}
return result || null;
}
// A function to check the DB has the specified capability. As the permission
// manager uses async DB operations without a completion callback, the
// distinct possibility exists that our checking of the DB will happen before
// the permission manager update has completed - so we just retry a few times.
// Returns a promise.
function checkCapabilityViaDB(expected, origin = TEST_ORIGIN, type = TEST_PERMISSION) {
let deferred = Promise.defer();
let count = 0;
let max = 20;
let do_check = () => {
let got = findCapabilityViaDB(origin, type);
if (got == expected) {
// the do_check_eq() below will succeed - which is what we want.
do_check_eq(got, expected, "The database has the expected value");
deferred.resolve();
return;
}
// value isn't correct - see if we've retried enough
if (count++ == max) {
// the do_check_eq() below will fail - which is what we want.
do_check_eq(got, expected, "The database wasn't updated with the expected value");
deferred.resolve();
return;
}
// we can retry...
do_timeout(100, do_check);
}
do_check();
return deferred.promise;
}
// use the DB to find the requested permission. Returns the permission
// value (ie, the "capability" in nsIPermission parlance) or null if it can't
// be found.
function findCapabilityViaDB(origin = TEST_ORIGIN, type = TEST_PERMISSION) {
let principal = Services.scriptSecurityManager.createCodebasePrincipal(origin, {});
let originStr = principal.origin;
let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append("permissions.sqlite");
let storage = Cc["@mozilla.org/storage/service;1"]
.getService(Ci.mozIStorageService);
let connection = storage.openDatabase(file);
let query = connection.createStatement(
"SELECT permission FROM moz_perms WHERE origin = :origin AND type = :type");
query.bindByName("origin", originStr);
query.bindByName("type", type);
if (!query.executeStep()) {
// no row
return null;
}
let result = query.getInt32(0);
if (query.executeStep()) {
// this is bad - we never expect more than 1 row here.
do_throw("More than 1 row found!")
}
return result;
}