fune/browser/components/migration/tests/unit/test_Chrome_passwords.js

200 lines
7 KiB
JavaScript

"use strict";
Cu.import("resource://gre/modules/OSCrypto.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const PROFILE = {
id: "Default",
name: "Person 1",
};
const TEST_LOGINS = [
{
id: 1, // id of the row in the chrome login db
username: "username",
password: "password",
hostname: "https://c9.io",
formSubmitURL: "https://c9.io",
httpRealm: null,
usernameField: "inputEmail",
passwordField: "inputPassword",
timeCreated: 1437418416037,
timePasswordChanged: 1437418416037,
timesUsed: 1,
},
{
id: 2,
username: "username@gmail.com",
password: "password2",
hostname: "https://accounts.google.com",
formSubmitURL: "https://accounts.google.com",
httpRealm: null,
usernameField: "Email",
passwordField: "Passwd",
timeCreated: 1437418446598,
timePasswordChanged: 1437418446598,
timesUsed: 6,
},
{
id: 3,
username: "username",
password: "password3",
hostname: "https://www.facebook.com",
formSubmitURL: "https://www.facebook.com",
httpRealm: null,
usernameField: "email",
passwordField: "pass",
timeCreated: 1437418478851,
timePasswordChanged: 1437418478851,
timesUsed: 1,
},
{
id: 4,
username: "user",
password: "password",
hostname: "http://httpbin.org",
formSubmitURL: null,
httpRealm: "me@kennethreitz.com", // Digest auth.
usernameField: "",
passwordField: "",
timeCreated: 1437787462368,
timePasswordChanged: 1437787462368,
timesUsed: 1,
},
{
id: 5,
username: "buser",
password: "bpassword",
hostname: "http://httpbin.org",
formSubmitURL: null,
httpRealm: "Fake Realm", // Basic auth.
usernameField: "",
passwordField: "",
timeCreated: 1437787539233,
timePasswordChanged: 1437787539233,
timesUsed: 1,
},
];
var crypto = new OSCrypto();
var dbConn;
function promiseSetPassword(login) {
let passwordValue = new Uint8Array(crypto.stringToArray(crypto.encryptData(login.password)));
return dbConn.execute(`UPDATE logins
SET password_value = :password_value
WHERE rowid = :rowid
`, { password_value: passwordValue,
rowid: login.id });
}
function checkLoginsAreEqual(passwordManagerLogin, chromeLogin, id) {
passwordManagerLogin.QueryInterface(Ci.nsILoginMetaInfo);
Assert.equal(passwordManagerLogin.username, chromeLogin.username,
"The two logins ID " + id + " have the same username");
Assert.equal(passwordManagerLogin.password, chromeLogin.password,
"The two logins ID " + id + " have the same password");
Assert.equal(passwordManagerLogin.hostname, chromeLogin.hostname,
"The two logins ID " + id + " have the same hostname");
Assert.equal(passwordManagerLogin.formSubmitURL, chromeLogin.formSubmitURL,
"The two logins ID " + id + " have the same formSubmitURL");
Assert.equal(passwordManagerLogin.httpRealm, chromeLogin.httpRealm,
"The two logins ID " + id + " have the same httpRealm");
Assert.equal(passwordManagerLogin.usernameField, chromeLogin.usernameField,
"The two logins ID " + id + " have the same usernameElement");
Assert.equal(passwordManagerLogin.passwordField, chromeLogin.passwordField,
"The two logins ID " + id + " have the same passwordElement");
Assert.equal(passwordManagerLogin.timeCreated, chromeLogin.timeCreated,
"The two logins ID " + id + " have the same timeCreated");
Assert.equal(passwordManagerLogin.timePasswordChanged, chromeLogin.timePasswordChanged,
"The two logins ID " + id + " have the same timePasswordChanged");
Assert.equal(passwordManagerLogin.timesUsed, chromeLogin.timesUsed,
"The two logins ID " + id + " have the same timesUsed");
}
function generateDifferentLogin(login) {
let newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo);
newLogin.init(login.hostname, login.formSubmitURL, null,
login.username, login.password + 1, login.usernameField + 1,
login.passwordField + 1);
newLogin.QueryInterface(Ci.nsILoginMetaInfo);
newLogin.timeCreated = login.timeCreated + 1;
newLogin.timePasswordChanged = login.timePasswordChanged + 1;
newLogin.timesUsed = login.timesUsed + 1;
return newLogin;
}
add_task(async function setup() {
let loginDataFile = do_get_file("AppData/Local/Google/Chrome/User Data/Default/Login Data");
dbConn = await Sqlite.openConnection({ path: loginDataFile.path });
registerFakePath("LocalAppData", do_get_file("AppData/Local/"));
do_register_cleanup(() => {
Services.logins.removeAllLogins();
crypto.finalize();
return dbConn.close();
});
});
add_task(async function test_importIntoEmptyDB() {
for (let login of TEST_LOGINS) {
await promiseSetPassword(login);
}
let migrator = MigrationUtils.getMigrator("chrome");
Assert.ok(migrator.sourceExists, "Sanity check the source exists");
let logins = Services.logins.getAllLogins({});
Assert.equal(logins.length, 0, "There are no logins initially");
// Migrate the logins.
await promiseMigration(migrator, MigrationUtils.resourceTypes.PASSWORDS, PROFILE);
logins = Services.logins.getAllLogins({});
Assert.equal(logins.length, TEST_LOGINS.length, "Check login count after importing the data");
Assert.equal(logins.length, MigrationUtils._importQuantities.logins,
"Check telemetry matches the actual import.");
for (let i = 0; i < TEST_LOGINS.length; i++) {
checkLoginsAreEqual(logins[i], TEST_LOGINS[i], i + 1);
}
});
// Test that existing logins for the same primary key don't get overwritten
add_task(async function test_importExistingLogins() {
let migrator = MigrationUtils.getMigrator("chrome");
Assert.ok(migrator.sourceExists, "Sanity check the source exists");
Services.logins.removeAllLogins();
let logins = Services.logins.getAllLogins({});
Assert.equal(logins.length, 0, "There are no logins after removing all of them");
let newLogins = [];
// Create 3 new logins that are different but where the key properties are still the same.
for (let i = 0; i < 3; i++) {
newLogins.push(generateDifferentLogin(TEST_LOGINS[i]));
Services.logins.addLogin(newLogins[i]);
}
logins = Services.logins.getAllLogins({});
Assert.equal(logins.length, newLogins.length, "Check login count after the insertion");
for (let i = 0; i < newLogins.length; i++) {
checkLoginsAreEqual(logins[i], newLogins[i], i + 1);
}
// Migrate the logins.
await promiseMigration(migrator, MigrationUtils.resourceTypes.PASSWORDS, PROFILE);
logins = Services.logins.getAllLogins({});
Assert.equal(logins.length, TEST_LOGINS.length,
"Check there are still the same number of logins after re-importing the data");
Assert.equal(logins.length, MigrationUtils._importQuantities.logins,
"Check telemetry matches the actual import.");
for (let i = 0; i < newLogins.length; i++) {
checkLoginsAreEqual(logins[i], newLogins[i], i + 1);
}
});