Bug 1208145 - Back out changeset e4e3a8b66db4 (bug 1121291). rs=dolske

Generated via qbackout with no conflicts
This commit is contained in:
Matthew Noorenberghe 2016-01-12 11:38:54 -08:00
parent 97531bdf06
commit a7ba5a5d9d
8 changed files with 175 additions and 22 deletions

View File

@ -5,6 +5,7 @@
/*** =================== SAVED SIGNONS CODE =================== ***/
var kSignonBundle;
var showingPasswords = false;
var dateFormatter = new Intl.DateTimeFormat(undefined,
{ day: "numeric", month: "short", year: "numeric" });
var dateAndTimeFormatter = new Intl.DateTimeFormat(undefined,
@ -13,6 +14,8 @@ var dateAndTimeFormatter = new Intl.DateTimeFormat(undefined,
function SignonsStartup() {
kSignonBundle = document.getElementById("signonBundle");
document.getElementById("togglePasswords").label = kSignonBundle.getString("showPasswords");
document.getElementById("togglePasswords").accessKey = kSignonBundle.getString("showPasswordsAccessKey");
document.getElementById("signonsIntro").textContent = kSignonBundle.getString("loginsDescriptionAll");
let treecols = document.getElementsByTagName("treecols")[0];
@ -76,14 +79,9 @@ var signonsTreeView = {
}
},
isEditable : function(row, col) {
if (col.id == "userCol") {
if (col.id == "userCol" || col.id == "passwordCol") {
return true;
}
if (col.id == "passwordCol") {
return masterPasswordLogin();
}
return false;
},
isSeparator : function(index) { return false; },
@ -130,8 +128,7 @@ function LoadSignons() {
try {
signons = passwordmanager.getAllLogins();
} catch (e) {
window.close();
return;
signons = [];
}
signons.forEach(login => login.QueryInterface(Components.interfaces.nsILoginMetaInfo));
signonsTreeView.rowCount = signons.length;
@ -146,10 +143,13 @@ function LoadSignons() {
// disable "remove all signons" button if there are no signons
var element = document.getElementById("removeAllSignons");
var toggle = document.getElementById("togglePasswords");
if (signons.length == 0) {
element.setAttribute("disabled","true");
toggle.setAttribute("disabled","true");
} else {
element.removeAttribute("disabled");
toggle.removeAttribute("disabled");
}
return true;
@ -193,6 +193,34 @@ function DeleteAllSignons() {
Services.telemetry.getHistogramById("PWMGR_MANAGE_DELETED_ALL").add(1);
}
function TogglePasswordVisible() {
if (showingPasswords || masterPasswordLogin(AskUserShowPasswords)) {
showingPasswords = !showingPasswords;
document.getElementById("togglePasswords").label = kSignonBundle.getString(showingPasswords ? "hidePasswords" : "showPasswords");
document.getElementById("togglePasswords").accessKey = kSignonBundle.getString(showingPasswords ? "hidePasswordsAccessKey" : "showPasswordsAccessKey");
document.getElementById("passwordCol").hidden = !showingPasswords;
_filterPasswords();
}
// Notify observers that the password visibility toggling is
// completed. (Mostly useful for tests)
Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService)
.notifyObservers(null, "passwordmgr-password-toggle-complete", null);
Services.telemetry.getHistogramById("PWMGR_MANAGE_VISIBILITY_TOGGLED").add(showingPasswords);
}
function AskUserShowPasswords() {
var prompter = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
var dummy = { value: false };
// Confirm the user wants to display passwords
return prompter.confirmEx(window,
null,
kSignonBundle.getString("noMasterPasswordPrompt"), prompter.STD_YES_NO_BUTTONS,
null, null, null, null, dummy) == 0; // 0=="Yes" button
}
function FinalizeSignonDeletions(syncNeeded) {
for (var s=0; s<deletedSignons.length; s++) {
passwordmanager.removeLogin(deletedSignons[s]);
@ -306,7 +334,7 @@ function SignonMatchesFilter(aSignon, aFilterValue) {
if (aSignon.httpRealm &&
aSignon.httpRealm.toLowerCase().indexOf(aFilterValue) != -1)
return true;
if (Services.logins.isLoggedIn && aSignon.password &&
if (showingPasswords && aSignon.password &&
aSignon.password.toLowerCase().indexOf(aFilterValue) != -1)
return true;
@ -362,8 +390,9 @@ function _filterPasswords()
}
function CopyPassword() {
// Don't copy passwords if a master password hasn't been entered.
if (!masterPasswordLogin())
// Don't copy passwords if we aren't already showing the passwords & a master
// password hasn't been entered.
if (!showingPasswords && !masterPasswordLogin())
return;
// Copy selected signon's password to clipboard
var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"].
@ -416,7 +445,13 @@ function UpdateContextMenu() {
menuItems.get("context-editusername").removeAttribute("disabled");
menuItems.get("context-copypassword").removeAttribute("disabled");
menuItems.get("context-editpassword").removeAttribute("disabled");
// Disable "Edit Password" if the password column isn't showing.
if (!document.getElementById("passwordCol").hidden) {
menuItems.get("context-editpassword").removeAttribute("disabled");
} else {
menuItems.get("context-editpassword").setAttribute("disabled", "true");
}
}
function masterPasswordLogin(noPasswordCallback) {

View File

@ -82,8 +82,9 @@
data-field-name="username" persist="width"/>
<splitter class="tree-splitter"/>
<treecol id="passwordCol" label="&treehead.password.label;" flex="15"
data-field-name="password" persist="width hidden"
type="password"/>
ignoreincolumnpicker="true"
data-field-name="password" persist="width"
hidden="true"/>
<splitter class="tree-splitter"/>
<treecol id="timeCreatedCol" label="&treehead.timeCreated.label;" flex="10"
data-field-name="timeCreated" persist="width hidden"
@ -116,6 +117,8 @@
label="&import.label;"
oncommand="OpenMigrator();"/>
#endif
<button id="togglePasswords"
oncommand="TogglePasswordVisible();"/>
</hbox>
</vbox>
<hbox align="end">

View File

@ -50,7 +50,7 @@ function test() {
assertMenuitemEnabled("copyusername", false, "empty username");
assertMenuitemEnabled("editusername", true);
assertMenuitemEnabled("copypassword", true);
assertMenuitemEnabled("editpassword", true);
assertMenuitemEnabled("editpassword", false, "password column hidden");
info("Clear the selection");
selection.clearSelection();
@ -61,6 +61,7 @@ function test() {
info("Select the third row and making the password column visible");
selection.select(2);
doc.getElementById("passwordCol").hidden = false;
assertMenuitemEnabled("copyusername", true);
assertMenuitemEnabled("editusername", true);
assertMenuitemEnabled("copypassword", true);
@ -79,6 +80,7 @@ function test() {
Services.ww.registerNotification(function (aSubject, aTopic, aData) {
Services.ww.unregisterNotification(arguments.callee);
Services.logins.removeAllLogins();
doc.getElementById("passwordCol").hidden = true;
finish();
});
pwmgrdlg.close();

View File

@ -32,6 +32,11 @@ function synthesizeDblClickOnCell(aTree, column, row) {
aTree.ownerDocument.defaultView);
}
function* togglePasswords() {
pwmgrdlg.document.querySelector("#togglePasswords").doCommand();
yield new Promise(resolve => waitForFocus(resolve, pwmgrdlg));
}
function* editUsernamePromises(site, oldUsername, newUsername) {
is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login found");
let login = Services.logins.findLogins({}, site, "", "")[0];
@ -109,7 +114,9 @@ add_task(function* test_edit_multiple_logins() {
function* testLoginChange(site, oldUsername, oldPassword, newUsername, newPassword) {
addLogin(site, oldUsername, oldPassword);
yield* editUsernamePromises(site, oldUsername, newUsername);
yield* togglePasswords();
yield* editPasswordPromises(site, oldPassword, newPassword);
yield* togglePasswords();
}
yield* testLoginChange("http://c.tn/", "userC", "passC", "usernameC", "passwordC");

View File

@ -67,6 +67,35 @@ function test() {
let userCol = doc.getElementById("userCol");
let passwordCol = doc.getElementById("passwordCol");
let toggleCalls = 0;
function toggleShowPasswords(func) {
let toggleButton = doc.getElementById("togglePasswords");
let showMode = (toggleCalls++ % 2) == 0;
// only watch for a confirmation dialog every other time being called
if (showMode) {
Services.ww.registerNotification(function (aSubject, aTopic, aData) {
if (aTopic == "domwindowclosed")
Services.ww.unregisterNotification(arguments.callee);
else if (aTopic == "domwindowopened") {
let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
SimpleTest.waitForFocus(function() {
EventUtils.sendKey("RETURN", win);
}, win);
}
});
}
Services.obs.addObserver(function (aSubject, aTopic, aData) {
if (aTopic == "passwordmgr-password-toggle-complete") {
Services.obs.removeObserver(arguments.callee, aTopic);
func();
}
}, "passwordmgr-password-toggle-complete", false);
EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win);
}
function clickCol(col) {
EventUtils.synthesizeMouse(col, 20, 1, {}, win);
setTimeout(runNextTest, 0);
@ -173,6 +202,7 @@ function test() {
}
}
runNextTest();
// Toggle Show Passwords to display Password column, then start tests
toggleShowPasswords(runNextTest);
}
}

View File

@ -57,25 +57,57 @@ function test() {
// Prepare a set of tests
// filter: the text entered in the filter search box
// count: the number of logins which should match the respective filter
// count2: the number of logins which should match the respective filter
// if the passwords are being shown as well
// Note: if a test doesn't have count2 set, count is used instead.
let tests = [
{filter: "pass", count: 4},
{filter: "pass", count: 0, count2: 4},
{filter: "", count: 10}, // test clearing the filter
{filter: "moz", count: 7},
{filter: "mozi", count: 7},
{filter: "mozil", count: 7},
{filter: "mozill", count: 7},
{filter: "mozilla", count: 7},
{filter: "mozilla.com", count: 2},
{filter: "mozilla.com", count: 1, count2: 2},
{filter: "user", count: 4},
{filter: "user ", count: 1},
{filter: " user", count: 2},
{filter: "http", count: 10},
{filter: "https", count: 1},
{filter: "secret", count: 2},
{filter: "secret", count: 0, count2: 2},
{filter: "secret!", count: 0},
];
function runTests(endFunction) {
let toggleCalls = 0;
function toggleShowPasswords(func) {
let toggleButton = doc.getElementById("togglePasswords");
let showMode = (toggleCalls++ % 2) == 0;
// only watch for a confirmation dialog every other time being called
if (showMode) {
Services.ww.registerNotification(function (aSubject, aTopic, aData) {
if (aTopic == "domwindowclosed")
Services.ww.unregisterNotification(arguments.callee);
else if (aTopic == "domwindowopened") {
let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
SimpleTest.waitForFocus(function() {
EventUtils.sendKey("RETURN", win);
}, win);
}
});
}
Services.obs.addObserver(function (aSubject, aTopic, aData) {
if (aTopic == "passwordmgr-password-toggle-complete") {
Services.obs.removeObserver(arguments.callee, aTopic);
func();
}
}, "passwordmgr-password-toggle-complete", false);
EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win);
}
function runTests(mode, endFunction) {
let testCounter = 0;
function setFilter(string) {
@ -84,7 +116,29 @@ function test() {
}
function runOneTest(test) {
is(view.rowCount, test.count, test.count + " logins should match '" + test.filter + "'");
function tester() {
is(view.rowCount, expected, expected + " logins should match '" + test.filter + "'");
}
let expected;
switch (mode) {
case 1: // without showing passwords
expected = test.count;
break;
case 2: // showing passwords
expected = ("count2" in test) ? test.count2 : test.count;
break;
case 3: // toggle
expected = test.count;
tester();
toggleShowPasswords(function () {
expected = ("count2" in test) ? test.count2 : test.count;
tester();
toggleShowPasswords(proceed);
});
return;
}
tester();
proceed();
}
@ -106,7 +160,19 @@ function test() {
}
function step1() {
runTests(lastStep);
runTests(1, step2);
}
function step2() {
toggleShowPasswords(function() {
runTests(2, step3);
});
}
function step3() {
toggleShowPasswords(function() {
runTests(3, lastStep);
});
}
function lastStep() {

View File

@ -8652,6 +8652,11 @@
"kind": "count",
"description": "Reports the column that logins are sorted by"
},
"PWMGR_MANAGE_VISIBILITY_TOGGLED": {
"expires_in_version": "never",
"kind": "boolean",
"description": "Whether the visibility of passwords was toggled (0=Hide, 1=Show)"
},
"PWMGR_NUM_PASSWORDS_PER_HOSTNAME": {
"expires_in_version": "never",
"kind": "linear",

View File

@ -47,6 +47,11 @@ notifyBarUpdateButtonAccessKey = U
notifyBarDontChangeButtonText = Don't Change
notifyBarDontChangeButtonAccessKey = D
userSelectText = Please confirm which user you are changing the password for
hidePasswords=Hide Passwords
hidePasswordsAccessKey=P
showPasswords=Show Passwords
showPasswordsAccessKey=P
noMasterPasswordPrompt=Are you sure you wish to show your passwords?
removeAllPasswordsPrompt=Are you sure you wish to remove all passwords?
removeAllPasswordsTitle=Remove all passwords
removeLoginPrompt=Are you sure you wish to remove this login?