mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 10:15:41 +00:00
Bug 479894 - Add a property-bag based searchLogins API to login manager. r=dolske, sr=vlad
This commit is contained in:
parent
506999dce8
commit
68ccc3549c
@ -42,8 +42,9 @@ interface nsILoginInfo;
|
||||
interface nsIAutoCompleteResult;
|
||||
interface nsIDOMHTMLInputElement;
|
||||
interface nsIDOMHTMLFormElement;
|
||||
interface nsIPropertyBag;
|
||||
|
||||
[scriptable, uuid(9c78bfc1-422b-4f4f-ba09-f7eb3c4e72b2)]
|
||||
[scriptable, uuid(30534ff7-fb95-45c5-8336-5448638f2aa1)]
|
||||
|
||||
interface nsILoginManager : nsISupports {
|
||||
|
||||
@ -239,6 +240,28 @@ interface nsILoginManager : nsISupports {
|
||||
* @return Success of attempt fill form
|
||||
*/
|
||||
boolean fillForm(in nsIDOMHTMLFormElement aForm);
|
||||
|
||||
/**
|
||||
* Search for logins in the login manager. An array is always returned;
|
||||
* if there are no logins the array is empty.
|
||||
*
|
||||
* @param count
|
||||
* The number of elements in the array. JS callers can simply use
|
||||
* the array's .length property, and supply an dummy object for
|
||||
* this out param. For example: |searchLogins({}, matchData)|
|
||||
* @param matchData
|
||||
* The data used to search. This does not follow the same
|
||||
* requirements as findLogins for those fields. Wildcard matches are
|
||||
* simply not specified.
|
||||
* @param logins
|
||||
* An array of nsILoginInfo objects.
|
||||
*
|
||||
* NOTE: This can be called from JS as:
|
||||
* var logins = pwmgr.searchLogins({}, matchData);
|
||||
* (|logins| is an array).
|
||||
*/
|
||||
void searchLogins(out unsigned long count, in nsIPropertyBag matchData,
|
||||
[retval, array, size_is(count)] out nsILoginInfo logins);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -39,8 +39,9 @@
|
||||
|
||||
interface nsIFile;
|
||||
interface nsILoginInfo;
|
||||
interface nsIPropertyBag;
|
||||
|
||||
[scriptable, uuid(199ebbff-4656-4a18-8da9-9401c64619f9)]
|
||||
[scriptable, uuid(e66c97cd-3bcf-4eee-9937-38f650372d77)]
|
||||
|
||||
/*
|
||||
* NOTE: This interface is intended to be implemented by modules
|
||||
@ -164,6 +165,29 @@ interface nsILoginManagerStorage : nsISupports {
|
||||
[retval, array, size_is(count)] out nsILoginInfo logins);
|
||||
|
||||
|
||||
/**
|
||||
* Search for logins in the login manager. An array is always returned;
|
||||
* if there are no logins the array is empty.
|
||||
*
|
||||
* @param count
|
||||
* The number of elements in the array. JS callers can simply use
|
||||
* the array's .length property, and supply an dummy object for
|
||||
* this out param. For example: |searchLogins({}, matchData)|
|
||||
* @param matchData
|
||||
* The data used to search. This does not follow the same
|
||||
* requirements as findLogins for those fields. Wildcard matches are
|
||||
* simply not specified.
|
||||
* @param logins
|
||||
* An array of nsILoginInfo objects.
|
||||
*
|
||||
* NOTE: This can be called from JS as:
|
||||
* var logins = pwmgr.searchLogins({}, matchData);
|
||||
* (|logins| is an array).
|
||||
*/
|
||||
void searchLogins(out unsigned long count, in nsIPropertyBag matchData,
|
||||
[retval, array, size_is(count)] out nsILoginInfo logins);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain a list of all hosts for which password saving is disabled.
|
||||
*
|
||||
|
@ -509,6 +509,21 @@ LoginManager.prototype = {
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* searchLogins
|
||||
*
|
||||
* Public wrapper around _searchLogins to convert the nsIPropertyBag to a
|
||||
* JavaScript object and decrypt the results.
|
||||
*
|
||||
* Returns an array of decrypted nsILoginInfo.
|
||||
*/
|
||||
searchLogins : function(count, matchData) {
|
||||
this.log("Searching for logins");
|
||||
|
||||
return this._storage.searchLogins(count, matchData);
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* countLogins
|
||||
*
|
||||
|
@ -373,6 +373,18 @@ LoginManagerStorage_legacy.prototype = {
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* searchLogins
|
||||
*
|
||||
* Not implemented. This interface was added to perform arbitrary searches.
|
||||
* Since the legacy storage module is no longer used, there is no need to
|
||||
* implement it here.
|
||||
*/
|
||||
searchLogins : function (count, matchData) {
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* removeAllLogins
|
||||
*
|
||||
|
@ -135,6 +135,7 @@ LoginManagerStorage_mozStorage.prototype = {
|
||||
"guid TEXT," +
|
||||
"encType INTEGER",
|
||||
// Changes must be reflected in this._dbAreExpectedColumnsPresent
|
||||
// and this._searchLogins
|
||||
moz_disabledHosts: "id INTEGER PRIMARY KEY," +
|
||||
"hostname TEXT UNIQUE ON CONFLICT REPLACE",
|
||||
},
|
||||
@ -480,11 +481,11 @@ LoginManagerStorage_mozStorage.prototype = {
|
||||
/*
|
||||
* getAllLogins
|
||||
*
|
||||
* Returns an array of nsAccountInfo.
|
||||
* Returns an array of nsILoginInfo.
|
||||
*/
|
||||
getAllLogins : function (count) {
|
||||
let userCanceled;
|
||||
let [logins, ids] = this._queryLogins("", "", "");
|
||||
let [logins, ids] = this._searchLogins({});
|
||||
|
||||
// decrypt entries for caller.
|
||||
[logins, userCanceled] = this._decryptLogins(logins);
|
||||
@ -511,6 +512,120 @@ LoginManagerStorage_mozStorage.prototype = {
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* searchLogins
|
||||
*
|
||||
* Public wrapper around _searchLogins to convert the nsIPropertyBag to a
|
||||
* JavaScript object and decrypt the results.
|
||||
*
|
||||
* Returns an array of decrypted nsILoginInfo.
|
||||
*/
|
||||
searchLogins : function(count, matchData) {
|
||||
let realMatchData = {};
|
||||
// Convert nsIPropertyBag to normal JS object
|
||||
let propEnum = matchData.enumerator;
|
||||
while (propEnum.hasMoreElements()) {
|
||||
let prop = propEnum.getNext().QueryInterface(Ci.nsIProperty);
|
||||
realMatchData[prop.name] = prop.value;
|
||||
}
|
||||
|
||||
let [logins, ids] = this._searchLogins(realMatchData);
|
||||
|
||||
let userCanceled;
|
||||
// Decrypt entries found for the caller.
|
||||
[logins, userCanceled] = this._decryptLogins(logins);
|
||||
|
||||
if (userCanceled)
|
||||
throw "User canceled Master Password entry";
|
||||
|
||||
count.value = logins.length; // needed for XPCOM
|
||||
return logins;
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* _searchLogins
|
||||
*
|
||||
* Private method to perform arbitrary searches on any field. Decryption is
|
||||
* left to the caller.
|
||||
*
|
||||
* Returns [logins, ids] for logins that match the arguments, where logins
|
||||
* is an array of encrypted nsLoginInfo and ids is an array of associated
|
||||
* ids in the database.
|
||||
*/
|
||||
_searchLogins : function (matchData) {
|
||||
let conditions = [], params = {};
|
||||
|
||||
for (field in matchData) {
|
||||
let value = matchData[field];
|
||||
switch (field) {
|
||||
// Historical compatibility requires this special case
|
||||
case "formSubmitURL":
|
||||
if (value != null) {
|
||||
conditions.push("formSubmitURL = :formSubmitURL OR formSubmitURL = ''");
|
||||
params["formSubmitURL"] = value;
|
||||
break;
|
||||
}
|
||||
// Normal cases.
|
||||
case "hostname":
|
||||
case "httpRealm":
|
||||
case "id":
|
||||
case "usernameField":
|
||||
case "passwordField":
|
||||
case "encryptedUsername":
|
||||
case "encryptedPassword":
|
||||
case "guid":
|
||||
case "encType":
|
||||
if (value == null) {
|
||||
conditions.push(field + " isnull");
|
||||
} else {
|
||||
conditions.push(field + " = :" + field);
|
||||
params[field] = value;
|
||||
}
|
||||
break;
|
||||
// Fail if caller requests an unknown property.
|
||||
default:
|
||||
throw "Unexpected field: " + field;
|
||||
}
|
||||
}
|
||||
|
||||
// Build query
|
||||
let query = "SELECT * FROM moz_logins";
|
||||
if (conditions.length) {
|
||||
conditions = conditions.map(function(c) "(" + c + ")");
|
||||
query += " WHERE " + conditions.join(" AND ");
|
||||
}
|
||||
|
||||
let stmt;
|
||||
let logins = [], ids = [];
|
||||
try {
|
||||
stmt = this._dbCreateStatement(query, params);
|
||||
// We can't execute as usual here, since we're iterating over rows
|
||||
while (stmt.step()) {
|
||||
// Create the new nsLoginInfo object, push to array
|
||||
let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
login.init(stmt.row.hostname, stmt.row.formSubmitURL,
|
||||
stmt.row.httpRealm, stmt.row.encryptedUsername,
|
||||
stmt.row.encryptedPassword, stmt.row.usernameField,
|
||||
stmt.row.passwordField);
|
||||
// set nsILoginMetaInfo values
|
||||
login.QueryInterface(Ci.nsILoginMetaInfo);
|
||||
login.guid = stmt.row.guid;
|
||||
logins.push(login);
|
||||
ids.push(stmt.row.id);
|
||||
}
|
||||
} catch (e) {
|
||||
this.log("_searchLogins failed: " + e.name + " : " + e.message);
|
||||
} finally {
|
||||
stmt.reset();
|
||||
}
|
||||
|
||||
this.log("_searchLogins: returning " + logins.length + " logins");
|
||||
return [logins, ids];
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* removeAllLogins
|
||||
*
|
||||
@ -600,8 +715,16 @@ LoginManagerStorage_mozStorage.prototype = {
|
||||
*/
|
||||
findLogins : function (count, hostname, formSubmitURL, httpRealm) {
|
||||
let userCanceled;
|
||||
let [logins, ids] =
|
||||
this._queryLogins(hostname, formSubmitURL, httpRealm);
|
||||
let loginData = {
|
||||
hostname: hostname,
|
||||
formSubmitURL: formSubmitURL,
|
||||
httpRealm: httpRealm
|
||||
};
|
||||
let matchData = { };
|
||||
for each (field in ["hostname", "formSubmitURL", "httpRealm"])
|
||||
if (loginData[field] != '')
|
||||
matchData[field] = loginData[field];
|
||||
let [logins, ids] = this._searchLogins(matchData);
|
||||
|
||||
// Decrypt entries found for the caller.
|
||||
[logins, userCanceled] = this._decryptLogins(logins);
|
||||
@ -679,8 +802,12 @@ LoginManagerStorage_mozStorage.prototype = {
|
||||
* stored login (useful for looking at the actual nsILoginMetaInfo values).
|
||||
*/
|
||||
_getIdForLogin : function (login) {
|
||||
let [logins, ids] =
|
||||
this._queryLogins(login.hostname, login.formSubmitURL, login.httpRealm);
|
||||
let matchData = { };
|
||||
for each (field in ["hostname", "formSubmitURL", "httpRealm"])
|
||||
if (login[field] != '')
|
||||
matchData[field] = login[field];
|
||||
let [logins, ids] = this._searchLogins(matchData);
|
||||
|
||||
let id = null;
|
||||
let foundLogin = null;
|
||||
|
||||
@ -708,58 +835,6 @@ LoginManagerStorage_mozStorage.prototype = {
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* _queryLogins
|
||||
*
|
||||
* Returns [logins, ids] for logins that match the arguments, where logins
|
||||
* is an array of encrypted nsLoginInfo and ids is an array of associated
|
||||
* ids in the database.
|
||||
*/
|
||||
_queryLogins : function (hostname, formSubmitURL, httpRealm, encType) {
|
||||
let logins = [], ids = [];
|
||||
|
||||
let query = "SELECT * FROM moz_logins";
|
||||
let [conditions, params] =
|
||||
this._buildConditionsAndParams(hostname, formSubmitURL, httpRealm);
|
||||
|
||||
if (typeof encType != "undefined") {
|
||||
conditions.push("encType = :encType");
|
||||
params.encType = encType;
|
||||
}
|
||||
|
||||
if (conditions.length) {
|
||||
conditions = conditions.map(function(c) "(" + c + ")");
|
||||
query += " WHERE " + conditions.join(" AND ");
|
||||
}
|
||||
|
||||
let stmt;
|
||||
try {
|
||||
stmt = this._dbCreateStatement(query, params);
|
||||
// We can't execute as usual here, since we're iterating over rows
|
||||
while (stmt.step()) {
|
||||
// Create the new nsLoginInfo object, push to array
|
||||
let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
login.init(stmt.row.hostname, stmt.row.formSubmitURL,
|
||||
stmt.row.httpRealm, stmt.row.encryptedUsername,
|
||||
stmt.row.encryptedPassword, stmt.row.usernameField,
|
||||
stmt.row.passwordField);
|
||||
// set nsILoginMetaInfo values
|
||||
login.QueryInterface(Ci.nsILoginMetaInfo);
|
||||
login.guid = stmt.row.guid;
|
||||
logins.push(login);
|
||||
ids.push(stmt.row.id);
|
||||
}
|
||||
} catch (e) {
|
||||
this.log("_queryLogins failed: " + e.name + " : " + e.message);
|
||||
} finally {
|
||||
stmt.reset();
|
||||
}
|
||||
|
||||
return [logins, ids];
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* _queryDisabledHosts
|
||||
*
|
||||
@ -1067,8 +1142,7 @@ LoginManagerStorage_mozStorage.prototype = {
|
||||
// Ignore failures, will try again next session...
|
||||
|
||||
try {
|
||||
let [logins, ids] =
|
||||
this._queryLogins("", "", "", 0);
|
||||
let [logins, ids] = this._searchLogins({ encType: 0 });
|
||||
|
||||
if (!logins.length)
|
||||
return;
|
||||
|
@ -150,37 +150,40 @@ const LoginTest = {
|
||||
* Compare info from component to what we expected.
|
||||
*/
|
||||
checkStorageData : function (storage, ref_disabledHosts, ref_logins) {
|
||||
this.checkLogins(ref_logins, storage.getAllLogins({}));
|
||||
this.checkDisabledHosts(ref_disabledHosts, storage.getAllDisabledHosts({}));
|
||||
},
|
||||
|
||||
var stor_disabledHosts = storage.getAllDisabledHosts({});
|
||||
do_check_eq(ref_disabledHosts.length, stor_disabledHosts.length);
|
||||
|
||||
var stor_logins = storage.getAllLogins({});
|
||||
do_check_eq(ref_logins.length, stor_logins.length);
|
||||
|
||||
/*
|
||||
* Check values of the disabled list.
|
||||
*/
|
||||
var i, j, found;
|
||||
for (i = 0; i < ref_disabledHosts.length; i++) {
|
||||
found = false;
|
||||
for (j = 0; !found && j < stor_disabledHosts.length; j++) {
|
||||
found = (ref_disabledHosts[i] == stor_disabledHosts[j]);
|
||||
/*
|
||||
* checkLogins
|
||||
*
|
||||
* Check values of the logins list.
|
||||
*/
|
||||
checkLogins : function (expectedLogins, actualLogins) {
|
||||
do_check_eq(expectedLogins.length, actualLogins.length);
|
||||
for (let i = 0; i < expectedLogins.length; i++) {
|
||||
let found = false;
|
||||
for (let j = 0; !found && j < actualLogins.length; j++) {
|
||||
found = expectedLogins[i].equals(actualLogins[j]);
|
||||
}
|
||||
do_check_true(found);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Check values of the logins list.
|
||||
*/
|
||||
var ref, stor;
|
||||
for (i = 0; i < ref_logins.length; i++) {
|
||||
found = false;
|
||||
for (j = 0; !found && j < stor_logins.length; j++) {
|
||||
found = ref_logins[i].equals(stor_logins[j]);
|
||||
/*
|
||||
* checkDisabledHosts
|
||||
*
|
||||
* Check values of the disabled list.
|
||||
*/
|
||||
checkDisabledHosts : function (expectedHosts, actualHosts) {
|
||||
do_check_eq(expectedHosts.length, actualHosts.length);
|
||||
for (let i = 0; i < expectedHosts.length; i++) {
|
||||
let found = false;
|
||||
for (let j = 0; !found && j < actualHosts.length; j++) {
|
||||
found = (expectedHosts[i] == actualHosts[j]);
|
||||
}
|
||||
do_check_true(found);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Test suite for storage-mozStorage.js -- Testing searchLogins.
|
||||
*
|
||||
* This test interfaces directly with the mozStorage login storage module,
|
||||
* bypassing the normal login manager usage.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
const STORAGE_TYPE = "mozStorage";
|
||||
|
||||
function run_test() {
|
||||
|
||||
try {
|
||||
|
||||
var storage, testnum = 0;
|
||||
|
||||
|
||||
/* ========== 1 ========== */
|
||||
testnum++;
|
||||
var testdesc = "Create nsILoginInfo instances for testing with"
|
||||
|
||||
var dummyuser1 = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
var dummyuser2 = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
var dummyuser3 = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
var dummyuser4 = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
|
||||
dummyuser1.init("http://dummyhost.mozilla.org", "", null,
|
||||
"testuser1", "testpass1", "put_user_here", "put_pw_here");
|
||||
|
||||
dummyuser2.init("http://dummyhost2.mozilla.org", "", null,
|
||||
"testuser2", "testpass2", "put_user2_here", "put_pw2_here");
|
||||
|
||||
dummyuser3.init("http://dummyhost2.mozilla.org", "http://dummyhost2.mozilla.org", null,
|
||||
"testuser3", "testpass3", "put_user3_here", "put_pw3_here");
|
||||
|
||||
dummyuser4.init("http://dummyhost3.mozilla.org", null, null,
|
||||
"testuser4", "testpass4", "put_user4_here", "put_pw4_here");
|
||||
|
||||
|
||||
/* ========== 2 ========== */
|
||||
testnum++;
|
||||
|
||||
testdesc = "checking that searchLogins works with values passed"
|
||||
storage = LoginTest.initStorage(INDIR, null,
|
||||
OUTDIR, "output-searchLogins-1.sqlite");
|
||||
|
||||
storage.addLogin(dummyuser1);
|
||||
storage.addLogin(dummyuser2);
|
||||
storage.addLogin(dummyuser3);
|
||||
|
||||
LoginTest.checkStorageData(storage, [], [dummyuser1, dummyuser2, dummyuser3]);
|
||||
|
||||
let matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("id", "1");
|
||||
let logins = storage.searchLogins({}, matchData);
|
||||
do_check_eq(1, logins.length, "expecting single login with id");
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
do_check_eq(3, logins.length, "should match all logins");
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("hostname", "http://dummyhost2.mozilla.org");
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
do_check_eq(2, logins.length, "should match some logins");
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("hostname", "http://dummyhost2.mozilla.org");
|
||||
matchData.setPropertyAsAString("httpRealm", null);
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
do_check_eq(2, logins.length, "should match some logins");
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("formSubmitURL", "");
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
do_check_eq(2, logins.length, "should match some logins");
|
||||
|
||||
|
||||
/* ========== 3 ========== */
|
||||
testnum++;
|
||||
|
||||
// uses storage from test #2
|
||||
testdesc = "checking that searchLogins throws when it's supposed"
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("id", "100");
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
do_check_eq(0, logins.length, "bogus value should return 0 results");
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("error", "value");
|
||||
try {
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
LoginTest.checkExpectedError(/Unexpected field/, error, "nonexistant field should throw");
|
||||
|
||||
LoginTest.deleteFile(OUTDIR, "output-searchLogins-1.sqlite");
|
||||
|
||||
|
||||
/* ========== 4 ========== */
|
||||
testnum++;
|
||||
|
||||
testdesc = "checking that searchLogins works as findLogins"
|
||||
storage = LoginTest.initStorage(INDIR, null,
|
||||
OUTDIR, "output-searchLogins-3.sqlite");
|
||||
|
||||
storage.addLogin(dummyuser1);
|
||||
storage.addLogin(dummyuser2);
|
||||
storage.addLogin(dummyuser3);
|
||||
storage.addLogin(dummyuser4);
|
||||
|
||||
LoginTest.checkStorageData(storage, [], [dummyuser1, dummyuser2, dummyuser3, dummyuser4]);
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
loginsF = storage.findLogins({}, "", "", "");
|
||||
LoginTest.checkLogins(loginsF, logins);
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("hostname", "http://dummyhost2.mozilla.org");
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
loginsF = storage.findLogins({}, "http://dummyhost2.mozilla.org", "", "");
|
||||
LoginTest.checkLogins(loginsF, logins);
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("hostname", "http://dummyhost2.mozilla.org");
|
||||
matchData.setPropertyAsAString("formSubmitURL", "http://dummyhost2.mozilla.org");
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
loginsF = storage.findLogins({}, "http://dummyhost2.mozilla.org", "http://dummyhost2.mozilla.org", "");
|
||||
LoginTest.checkLogins(loginsF, logins);
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("formSubmitURL", "http://dummyhost2.mozilla.org");
|
||||
matchData.setPropertyAsAString("httpRealm", null);
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
loginsF = storage.findLogins({}, "", "http://dummyhost2.mozilla.org", null);
|
||||
LoginTest.checkLogins(loginsF, logins);
|
||||
|
||||
matchData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
|
||||
matchData.setPropertyAsAString("formSubmitURL", null);
|
||||
matchData.setPropertyAsAString("httpRealm", null);
|
||||
logins = storage.searchLogins({}, matchData);
|
||||
loginsF = storage.findLogins({}, "", null, null);
|
||||
LoginTest.checkLogins(loginsF, logins);
|
||||
|
||||
LoginTest.deleteFile(OUTDIR, "output-searchLogins-3.sqlite");
|
||||
|
||||
|
||||
/* ========== end ========== */
|
||||
} catch (e) {
|
||||
throw ("FAILED in test #" + testnum + " -- " + testdesc + ": " + e);
|
||||
}
|
||||
|
||||
};
|
Loading…
Reference in New Issue
Block a user