tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_permmanager_remote.js (11934B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 https://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 ChromeUtils.defineESModuleGetters(this, {
      7  RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
      8 });
      9 
     10 const COLLECTION_NAME = "remote-permissions";
     11 const ORIGIN_1 = "https://example.com";
     12 const PRINCIPAL_1 = Services.scriptSecurityManager.createContentPrincipal(
     13  Services.io.newURI(ORIGIN_1),
     14  {}
     15 );
     16 const PRINCIPAL_1_PB = Services.scriptSecurityManager.createContentPrincipal(
     17  Services.io.newURI(ORIGIN_1),
     18  { privateBrowsingId: 1 }
     19 );
     20 const ORIGIN_2 = "https://example.org";
     21 const PRINCIPAL_2 = Services.scriptSecurityManager.createContentPrincipal(
     22  Services.io.newURI(ORIGIN_2),
     23  {}
     24 );
     25 const PRINCIPAL_2_PB = Services.scriptSecurityManager.createContentPrincipal(
     26  Services.io.newURI(ORIGIN_2),
     27  { privateBrowsingId: 1 }
     28 );
     29 const ORIGIN_INVALID = "not a valid origin";
     30 const TEST_PERMISSION_1 = "test-permission-1";
     31 const TEST_PERMISSION_2 = "test-permission-2";
     32 
     33 let rs = RemoteSettings(COLLECTION_NAME);
     34 let pm = Services.perms;
     35 let rps = Cc["@mozilla.org/remote-permission-service;1"].getService(
     36  Ci.nsIRemotePermissionService
     37 );
     38 
     39 async function remoteSettingsSync({ created, updated, deleted }) {
     40  await rs.emit("sync", {
     41    data: {
     42      created,
     43      updated,
     44      deleted,
     45    },
     46  });
     47 }
     48 
     49 function expectPermissions(perms) {
     50  Assert.deepEqual(
     51    pm.all
     52      .map(({ principal, type, capability }) => ({
     53        principal: principal.siteOrigin,
     54        type,
     55        capability,
     56      }))
     57      .sort((a, b) => a.principal.localeCompare(b.principal)),
     58    perms
     59      .map(({ principal, type, capability }) => ({
     60        principal: principal.siteOrigin,
     61        type,
     62        capability,
     63      }))
     64      .sort((a, b) => a.principal.localeCompare(b.principal)),
     65    "Permission manager should have expected permissions"
     66  );
     67 }
     68 
     69 add_setup(async function () {
     70  Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
     71  do_get_profile();
     72 
     73  // This needs to be restored on cleanup
     74  let originalPermissionValues = structuredClone(
     75    rps.testAllowedPermissionValues
     76  );
     77 
     78  await rps.isInitialized;
     79 
     80  // Make sure we start off "empty". Any RemoteSettings values must be
     81  // purged now to comply with test expectations.
     82  Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
     83 
     84  registerCleanupFunction(async () => {
     85    info("Cleaning up");
     86    rps.testAllowedPermissionValues = originalPermissionValues;
     87    Services.prefs.clearUserPref("permissions.manager.defaultsUrl");
     88    Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
     89    Services.perms.removeAll();
     90  });
     91 
     92  // Allow setting everything
     93  rps.testAllowedPermissionValues = {
     94    "*": ["*"],
     95  };
     96 });
     97 
     98 add_task(async function test_create_permission() {
     99  info("Creating permission");
    100 
    101  await remoteSettingsSync({
    102    created: [
    103      {
    104        origin: ORIGIN_1,
    105        type: TEST_PERMISSION_1,
    106        capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    107      },
    108    ],
    109  });
    110 
    111  expectPermissions([
    112    {
    113      principal: PRINCIPAL_1,
    114      type: TEST_PERMISSION_1,
    115      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    116    },
    117    {
    118      principal: PRINCIPAL_1_PB,
    119      type: TEST_PERMISSION_1,
    120      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    121    },
    122  ]);
    123 });
    124 
    125 add_task(async function test_update_permission_value() {
    126  info("Updating permission value");
    127 
    128  await remoteSettingsSync({
    129    updated: [
    130      {
    131        old: {
    132          origin: ORIGIN_1,
    133          type: TEST_PERMISSION_1,
    134          capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    135        },
    136        new: {
    137          origin: ORIGIN_1,
    138          type: TEST_PERMISSION_1,
    139          capability: Ci.nsIPermissionManager.DENY_ACTION,
    140        },
    141      },
    142    ],
    143  });
    144 
    145  expectPermissions([
    146    {
    147      principal: PRINCIPAL_1,
    148      type: TEST_PERMISSION_1,
    149      capability: Ci.nsIPermissionManager.DENY_ACTION,
    150    },
    151    {
    152      principal: PRINCIPAL_1_PB,
    153      type: TEST_PERMISSION_1,
    154      capability: Ci.nsIPermissionManager.DENY_ACTION,
    155    },
    156  ]);
    157 });
    158 
    159 add_task(async function test_update_permission_origin() {
    160  info("Updating permission origin");
    161 
    162  await remoteSettingsSync({
    163    updated: [
    164      {
    165        old: {
    166          origin: ORIGIN_1,
    167          type: TEST_PERMISSION_1,
    168          capability: Ci.nsIPermissionManager.DENY_ACTION,
    169        },
    170        new: {
    171          origin: ORIGIN_2,
    172          type: TEST_PERMISSION_1,
    173          capability: Ci.nsIPermissionManager.DENY_ACTION,
    174        },
    175      },
    176    ],
    177  });
    178 
    179  expectPermissions([
    180    {
    181      principal: PRINCIPAL_2,
    182      type: TEST_PERMISSION_1,
    183      capability: Ci.nsIPermissionManager.DENY_ACTION,
    184    },
    185    {
    186      principal: PRINCIPAL_2_PB,
    187      type: TEST_PERMISSION_1,
    188      capability: Ci.nsIPermissionManager.DENY_ACTION,
    189    },
    190  ]);
    191 });
    192 
    193 add_task(async function test_user_permission_restoration() {
    194  info("Overriding with user permission");
    195 
    196  pm.addFromPrincipal(
    197    PRINCIPAL_2,
    198    TEST_PERMISSION_1,
    199    Ci.nsIPermissionManager.ALLOW_ACTION
    200  );
    201 
    202  expectPermissions([
    203    {
    204      principal: PRINCIPAL_2,
    205      type: TEST_PERMISSION_1,
    206      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    207    },
    208    {
    209      principal: PRINCIPAL_2_PB,
    210      type: TEST_PERMISSION_1,
    211      capability: Ci.nsIPermissionManager.DENY_ACTION,
    212    },
    213  ]);
    214 
    215  info("Removing user permission");
    216 
    217  pm.removeFromPrincipal(PRINCIPAL_2, TEST_PERMISSION_1);
    218 
    219  expectPermissions([
    220    {
    221      principal: PRINCIPAL_2,
    222      type: TEST_PERMISSION_1,
    223      capability: Ci.nsIPermissionManager.DENY_ACTION,
    224    },
    225    {
    226      principal: PRINCIPAL_2_PB,
    227      type: TEST_PERMISSION_1,
    228      capability: Ci.nsIPermissionManager.DENY_ACTION,
    229    },
    230  ]);
    231 });
    232 
    233 add_task(async function test_remove_all_restoration() {
    234  info("Overriding with user permission and adding new user permission");
    235 
    236  pm.addFromPrincipal(
    237    PRINCIPAL_1,
    238    TEST_PERMISSION_1,
    239    Ci.nsIPermissionManager.ALLOW_ACTION
    240  );
    241  pm.addFromPrincipal(
    242    PRINCIPAL_2,
    243    TEST_PERMISSION_1,
    244    Ci.nsIPermissionManager.ALLOW_ACTION
    245  );
    246 
    247  expectPermissions([
    248    {
    249      principal: PRINCIPAL_1,
    250      type: TEST_PERMISSION_1,
    251      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    252    },
    253    {
    254      principal: PRINCIPAL_2,
    255      type: TEST_PERMISSION_1,
    256      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    257    },
    258    {
    259      principal: PRINCIPAL_2_PB,
    260      type: TEST_PERMISSION_1,
    261      capability: Ci.nsIPermissionManager.DENY_ACTION,
    262    },
    263  ]);
    264 
    265  info("Removing all permissions");
    266 
    267  pm.removeAll();
    268 
    269  expectPermissions([
    270    {
    271      principal: PRINCIPAL_2,
    272      type: TEST_PERMISSION_1,
    273      capability: Ci.nsIPermissionManager.DENY_ACTION,
    274    },
    275    {
    276      principal: PRINCIPAL_2_PB,
    277      type: TEST_PERMISSION_1,
    278      capability: Ci.nsIPermissionManager.DENY_ACTION,
    279    },
    280  ]);
    281 });
    282 
    283 add_task(async function test_delete_permission() {
    284  info("Deleting permission");
    285 
    286  await remoteSettingsSync({
    287    deleted: [
    288      {
    289        origin: ORIGIN_2,
    290        type: TEST_PERMISSION_1,
    291        capability: Ci.nsIPermissionManager.DENY_ACTION,
    292      },
    293    ],
    294  });
    295 
    296  expectPermissions([]);
    297 });
    298 
    299 add_task(async function test_allowlist() {
    300  info("Only allowing TEST_PERMISSION_1 with value ALLOW_ACTION");
    301 
    302  rps.testAllowedPermissionValues = {
    303    [TEST_PERMISSION_1]: [Ci.nsIPermissionManager.ALLOW_ACTION],
    304  };
    305 
    306  info("Trying to add all sorts of default permissions");
    307 
    308  await remoteSettingsSync({
    309    created: [ORIGIN_1, ORIGIN_2].flatMap(origin =>
    310      [TEST_PERMISSION_1, TEST_PERMISSION_2].flatMap(type =>
    311        [
    312          Ci.nsIPermissionManager.ALLOW_ACTION,
    313          Ci.nsIPermissionManager.DENY_ACTION,
    314          Ci.nsIPermissionManager.PROMPT_ACTION,
    315        ].flatMap(capability => ({ origin, type, capability }))
    316      )
    317    ),
    318  });
    319 
    320  expectPermissions([
    321    {
    322      principal: PRINCIPAL_1,
    323      type: TEST_PERMISSION_1,
    324      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    325    },
    326    {
    327      principal: PRINCIPAL_1_PB,
    328      type: TEST_PERMISSION_1,
    329      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    330    },
    331    {
    332      principal: PRINCIPAL_2,
    333      type: TEST_PERMISSION_1,
    334      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    335    },
    336    {
    337      principal: PRINCIPAL_2_PB,
    338      type: TEST_PERMISSION_1,
    339      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    340    },
    341  ]);
    342 
    343  rps.testAllowedPermissionValues = {
    344    "*": ["*"],
    345  };
    346 });
    347 
    348 add_task(async function test_defaults_url() {
    349  info("Testing interaction with permissions.manager.defaultsUrl");
    350 
    351  info("Setting up permissions.manager.defaultsUrl");
    352 
    353  let file = do_get_tempdir();
    354  file.append("test_default_permissions");
    355  let ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
    356    Ci.nsIFileOutputStream
    357  );
    358  ostream.init(file, -1, 0o666, 0);
    359  let conv = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(
    360    Ci.nsIConverterOutputStream
    361  );
    362  conv.init(ostream, "UTF-8");
    363  conv.writeString(
    364    [
    365      "host",
    366      TEST_PERMISSION_1,
    367      Ci.nsIPermissionManager.ALLOW_ACTION,
    368      ORIGIN_1,
    369    ].join("\t") + "\n"
    370  );
    371  conv.writeString(
    372    [
    373      "host",
    374      TEST_PERMISSION_2,
    375      Ci.nsIPermissionManager.ALLOW_ACTION,
    376      ORIGIN_1,
    377    ].join("\t") + "\n"
    378  );
    379  ostream.close();
    380 
    381  Services.prefs.setCharPref(
    382    "permissions.manager.defaultsUrl",
    383    "file://" + file.path
    384  );
    385 
    386  info("Re-initializing permission manager");
    387 
    388  // Start from a clean slate with our new default permissions from
    389  // permissions.manager.defaultsUrl
    390  Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
    391  Services.perms.removeAll();
    392 
    393  expectPermissions([
    394    {
    395      principal: PRINCIPAL_1,
    396      type: TEST_PERMISSION_1,
    397      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    398    },
    399    {
    400      principal: PRINCIPAL_1_PB,
    401      type: TEST_PERMISSION_1,
    402      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    403    },
    404    {
    405      principal: PRINCIPAL_1,
    406      type: TEST_PERMISSION_2,
    407      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    408    },
    409    {
    410      principal: PRINCIPAL_1_PB,
    411      type: TEST_PERMISSION_2,
    412      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    413    },
    414  ]);
    415 
    416  info("Overriding permissions from permissions.manager.defaultsUrl");
    417 
    418  await remoteSettingsSync({
    419    created: [
    420      {
    421        origin: ORIGIN_1,
    422        type: TEST_PERMISSION_1,
    423        capability: Ci.nsIPermissionManager.DENY_ACTION,
    424      },
    425      {
    426        origin: ORIGIN_1,
    427        type: TEST_PERMISSION_2,
    428        capability: Ci.nsIPermissionManager.UNKNOWN_ACTION,
    429      },
    430    ],
    431  });
    432 
    433  expectPermissions([
    434    {
    435      principal: PRINCIPAL_1,
    436      type: TEST_PERMISSION_1,
    437      capability: Ci.nsIPermissionManager.DENY_ACTION,
    438    },
    439    {
    440      principal: PRINCIPAL_1_PB,
    441      type: TEST_PERMISSION_1,
    442      capability: Ci.nsIPermissionManager.DENY_ACTION,
    443    },
    444  ]);
    445 });
    446 
    447 add_task(async function test_malformed_origin() {
    448  info(
    449    "Testing that import will continue after encountering a malformed origin"
    450  );
    451 
    452  await remoteSettingsSync({
    453    created: [
    454      {
    455        origin: ORIGIN_INVALID,
    456        type: TEST_PERMISSION_1,
    457        capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    458      },
    459      // TEST_PERMISSION_1 still exists for ORIGIN_1 from the previous step, but
    460      // for simplicity we act like it is new here. We will see if the value has
    461      // changed from deny to allow.
    462      {
    463        origin: ORIGIN_1,
    464        type: TEST_PERMISSION_1,
    465        capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    466      },
    467    ],
    468  });
    469 
    470  expectPermissions([
    471    {
    472      principal: PRINCIPAL_1,
    473      type: TEST_PERMISSION_1,
    474      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    475    },
    476    {
    477      principal: PRINCIPAL_1_PB,
    478      type: TEST_PERMISSION_1,
    479      capability: Ci.nsIPermissionManager.ALLOW_ACTION,
    480    },
    481  ]);
    482 });