tor-browser

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

test_password_tracker.js (7945B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 const { PasswordEngine, LoginRec } = ChromeUtils.importESModule(
      5  "resource://services-sync/engines/passwords.sys.mjs"
      6 );
      7 const { Service } = ChromeUtils.importESModule(
      8  "resource://services-sync/service.sys.mjs"
      9 );
     10 
     11 let engine;
     12 let store;
     13 let tracker;
     14 
     15 add_task(async function setup() {
     16  await Service.engineManager.register(PasswordEngine);
     17  engine = Service.engineManager.get("passwords");
     18  store = engine._store;
     19  tracker = engine._tracker;
     20 });
     21 
     22 add_task(async function test_tracking() {
     23  let recordNum = 0;
     24 
     25  _("Verify we've got an empty tracker to work with.");
     26  let changes = await engine.getChangedIDs();
     27  do_check_empty(changes);
     28 
     29  let exceptionHappened = false;
     30  try {
     31    await tracker.getChangedIDs();
     32  } catch (ex) {
     33    exceptionHappened = true;
     34  }
     35  ok(exceptionHappened, "tracker does not keep track of changes");
     36 
     37  async function createPassword() {
     38    _("RECORD NUM: " + recordNum);
     39    let record = new LoginRec("passwords", "GUID" + recordNum);
     40    record.cleartext = {
     41      id: "GUID" + recordNum,
     42      hostname: "http://foo.bar.com",
     43      formSubmitURL: "http://foo.bar.com",
     44      username: "john" + recordNum,
     45      password: "smith",
     46      usernameField: "username",
     47      passwordField: "password",
     48    };
     49    recordNum++;
     50    let login = store._nsLoginInfoFromRecord(record);
     51    await Services.logins.addLoginAsync(login);
     52    await tracker.asyncObserver.promiseObserversComplete();
     53  }
     54 
     55  try {
     56    tracker.start();
     57    await createPassword();
     58    changes = await engine.getChangedIDs();
     59    do_check_attribute_count(changes, 1);
     60    Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
     61    Assert.equal(changes.GUID0.counter, 1);
     62    Assert.ok(typeof changes.GUID0.modified, "number");
     63 
     64    _("Starting twice won't do any harm.");
     65    tracker.start();
     66    await createPassword();
     67    changes = await engine.getChangedIDs();
     68    do_check_attribute_count(changes, 2);
     69    Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE * 2);
     70    Assert.equal(changes.GUID0.counter, 1);
     71    Assert.equal(changes.GUID1.counter, 1);
     72 
     73    // The tracker doesn't keep track of changes, so 3 changes
     74    // should still be returned, but the score is not updated.
     75    _("Let's stop tracking again.");
     76    tracker.resetScore();
     77    await tracker.stop();
     78    await createPassword();
     79    changes = await engine.getChangedIDs();
     80    do_check_attribute_count(changes, 3);
     81    Assert.equal(tracker.score, 0);
     82    Assert.equal(changes.GUID0.counter, 1);
     83    Assert.equal(changes.GUID1.counter, 1);
     84    Assert.equal(changes.GUID2.counter, 1);
     85 
     86    _("Stopping twice won't do any harm.");
     87    await tracker.stop();
     88    await createPassword();
     89    changes = await engine.getChangedIDs();
     90    do_check_attribute_count(changes, 4);
     91    Assert.equal(tracker.score, 0);
     92  } finally {
     93    _("Clean up.");
     94    await store.wipe();
     95    tracker.resetScore();
     96    await tracker.stop();
     97  }
     98 });
     99 
    100 add_task(async function test_onWipe() {
    101  _("Verify we've got an empty tracker to work with.");
    102  const changes = await engine.getChangedIDs();
    103  do_check_empty(changes);
    104  Assert.equal(tracker.score, 0);
    105 
    106  try {
    107    _("A store wipe should increment the score");
    108    tracker.start();
    109    await store.wipe();
    110    await tracker.asyncObserver.promiseObserversComplete();
    111 
    112    Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
    113  } finally {
    114    tracker.resetScore();
    115    await tracker.stop();
    116  }
    117 });
    118 
    119 add_task(async function test_removeAllLogins() {
    120  let recordNum = 0;
    121  _("Verify that all tracked logins are removed.");
    122 
    123  // Perform this test twice, the first time where a sync is not performed
    124  // between adding and removing items and the second time where a sync is
    125  // performed. In the former case, the logins will just be deleted because
    126  // they have never been synced, so they won't be detected as changes. In
    127  // the latter case, the logins have been synced so they will be marked for
    128  // deletion.
    129  for (let syncBeforeRemove of [false, true]) {
    130    async function createPassword() {
    131      _("RECORD NUM: " + recordNum);
    132      let record = new LoginRec("passwords", "GUID" + recordNum);
    133      record.cleartext = {
    134        id: "GUID" + recordNum,
    135        hostname: "http://foo.bar.com",
    136        formSubmitURL: "http://foo.bar.com",
    137        username: "john" + recordNum,
    138        password: "smith",
    139        usernameField: "username",
    140        passwordField: "password",
    141      };
    142      recordNum++;
    143      let login = store._nsLoginInfoFromRecord(record);
    144      await Services.logins.addLoginAsync(login);
    145 
    146      await tracker.asyncObserver.promiseObserversComplete();
    147    }
    148    try {
    149      _("Tell tracker to start tracking changes");
    150      tracker.start();
    151      await createPassword();
    152      await createPassword();
    153      let changes = await engine.getChangedIDs();
    154      do_check_attribute_count(changes, 2);
    155      Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE * 2);
    156 
    157      if (syncBeforeRemove) {
    158        let logins = await Services.logins.getAllLogins();
    159        for (let login of logins) {
    160          engine.markSynced(login.guid);
    161        }
    162      }
    163 
    164      _("Tell sync to remove all logins");
    165      Services.logins.removeAllUserFacingLogins();
    166      await tracker.asyncObserver.promiseObserversComplete();
    167      changes = await engine.getChangedIDs();
    168      do_check_attribute_count(changes, syncBeforeRemove ? 2 : 0);
    169      Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE * 5);
    170 
    171      let deletedGuids = await engine._store.getAllIDs();
    172      if (syncBeforeRemove) {
    173        for (let guid in deletedGuids) {
    174          let deletedLogin = await engine._store._getLoginFromGUID(guid);
    175 
    176          Assert.equal(deletedLogin.hostname, null, "deleted login hostname");
    177          Assert.equal(
    178            deletedLogin.formActionOrigin,
    179            null,
    180            "deleted login formActionOrigin"
    181          );
    182          Assert.equal(
    183            deletedLogin.formSubmitURL,
    184            null,
    185            "deleted login formSubmitURL"
    186          );
    187          Assert.equal(deletedLogin.httpRealm, null, "deleted login httpRealm");
    188          Assert.equal(deletedLogin.username, null, "deleted login username");
    189          Assert.equal(deletedLogin.password, null, "deleted login password");
    190          Assert.equal(
    191            deletedLogin.usernameField,
    192            "",
    193            "deleted login usernameField"
    194          );
    195          Assert.equal(
    196            deletedLogin.passwordField,
    197            "",
    198            "deleted login passwordField"
    199          );
    200          Assert.equal(
    201            deletedLogin.unknownFields,
    202            null,
    203            "deleted login unknownFields"
    204          );
    205          Assert.equal(
    206            deletedLogin.timeCreated,
    207            0,
    208            "deleted login timeCreated"
    209          );
    210          Assert.equal(
    211            deletedLogin.timeLastUsed,
    212            0,
    213            "deleted login timeLastUsed"
    214          );
    215          Assert.equal(deletedLogin.timesUsed, 0, "deleted login timesUsed");
    216 
    217          // These fields are not reset when the login is removed.
    218          Assert.ok(deletedLogin.guid.startsWith("GUID"), "deleted login guid");
    219          Assert.equal(
    220            deletedLogin.everSynced,
    221            true,
    222            "deleted login everSynced"
    223          );
    224          Assert.equal(
    225            deletedLogin.syncCounter,
    226            2,
    227            "deleted login syncCounter"
    228          );
    229          Assert.greater(
    230            deletedLogin.timePasswordChanged,
    231            0,
    232            "deleted login timePasswordChanged"
    233          );
    234        }
    235      } else {
    236        Assert.equal(
    237          Object.keys(deletedGuids).length,
    238          0,
    239          "no logins remain after removeAllUserFacingLogins"
    240        );
    241      }
    242    } finally {
    243      _("Clean up.");
    244      await store.wipe();
    245      tracker.resetScore();
    246      await tracker.stop();
    247    }
    248  }
    249 });