mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 382437 nsLoginManagerPrompter.js needs to implement nsIAuthPrompt. r=dolske,gavin,sr=dveditz,approval1.9b4=beltzner
This commit is contained in:
parent
b922061526
commit
505e7ffa51
@ -42,7 +42,7 @@ interface nsIPrompt;
|
||||
/**
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(2f977d45-5485-11d4-87e2-0010a4e75ef2)]
|
||||
[scriptable, uuid(310fae75-191c-412d-be7f-6190df509e3c)]
|
||||
interface nsIAuthPrompt : nsISupports
|
||||
{
|
||||
const PRUint32 SAVE_PASSWORD_NEVER = 0;
|
||||
@ -51,6 +51,16 @@ interface nsIAuthPrompt : nsISupports
|
||||
|
||||
/**
|
||||
* Puts up a text input dialog with OK and Cancel buttons.
|
||||
* Note: prompt uses separate args for the "in" and "out" values of the
|
||||
* input field, whereas the other functions use a single inout arg.
|
||||
* @param dialogText The title for the dialog.
|
||||
* @param text The text to display in the dialog.
|
||||
* @param passwordRealm The "realm" the password belongs to: e.g.
|
||||
* ldap://localhost/dc=test
|
||||
* @param savePassword One of the SAVE_PASSWORD_* options above.
|
||||
* @param defaultText The default text to display in the text input box.
|
||||
* @param result The value entered by the user if OK was
|
||||
* selected.
|
||||
* @return true for OK, false for Cancel
|
||||
*/
|
||||
boolean prompt(in wstring dialogTitle,
|
||||
@ -62,6 +72,15 @@ interface nsIAuthPrompt : nsISupports
|
||||
|
||||
/**
|
||||
* Puts up a username/password dialog with OK and Cancel buttons.
|
||||
* Puts up a password dialog with OK and Cancel buttons.
|
||||
* @param dialogText The title for the dialog.
|
||||
* @param text The text to display in the dialog.
|
||||
* @param passwordRealm The "realm" the password belongs to: e.g.
|
||||
* ldap://localhost/dc=test
|
||||
* @param savePassword One of the SAVE_PASSWORD_* options above.
|
||||
* @param user The username entered in the dialog.
|
||||
* @param pwd The password entered by the user if OK was
|
||||
* selected.
|
||||
* @return true for OK, false for Cancel
|
||||
*/
|
||||
boolean promptUsernameAndPassword(in wstring dialogTitle,
|
||||
@ -69,15 +88,22 @@ interface nsIAuthPrompt : nsISupports
|
||||
in wstring passwordRealm,
|
||||
in PRUint32 savePassword,
|
||||
out wstring user,
|
||||
out wstring pwd);
|
||||
inout wstring pwd);
|
||||
|
||||
/**
|
||||
* Puts up a password dialog with OK and Cancel buttons.
|
||||
* @param dialogText The title for the dialog.
|
||||
* @param text The text to display in the dialog.
|
||||
* @param passwordRealm The "realm" the password belongs to: e.g.
|
||||
* ldap://localhost/dc=test
|
||||
* @param savePassword One of the SAVE_PASSWORD_* options above.
|
||||
* @param pwd The password entered by the user if OK was
|
||||
* selected.
|
||||
* @return true for OK, false for Cancel
|
||||
*/
|
||||
boolean promptPassword(in wstring dialogTitle,
|
||||
in wstring text,
|
||||
in wstring passwordRealm,
|
||||
in PRUint32 savePassword,
|
||||
out wstring pwd);
|
||||
inout wstring pwd);
|
||||
};
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
@ -76,10 +77,15 @@ LoginManagerPromptFactory.prototype = {
|
||||
/*
|
||||
* LoginManagerPrompter
|
||||
*
|
||||
* Implements nsIAuthPrompt2 and nsILoginManagerPrompter.
|
||||
* nsIAuthPrompt2 usage is invoked by a channel for protocol-based
|
||||
* authentication (eg HTTP Authenticate, FTP login). nsILoginManagerPrompter
|
||||
* is invoked by Login Manager for saving/changing a login.
|
||||
* Implements interfaces for prompting the user to enter/save/change auth info.
|
||||
*
|
||||
* nsIAuthPrompt: Used by SeaMonkey, Thunderbird, but not Firefox.
|
||||
*
|
||||
* nsIAuthPrompt2: Is invoked by a channel for protocol-based authentication
|
||||
* (eg HTTP Authenticate, FTP login).
|
||||
*
|
||||
* nsILoginManagerPrompter: Used by Login Manager for saving/changing logins
|
||||
* found in HTML forms.
|
||||
*/
|
||||
function LoginManagerPrompter() {}
|
||||
|
||||
@ -88,8 +94,9 @@ LoginManagerPrompter.prototype = {
|
||||
classDescription : "LoginManagerPrompter",
|
||||
contractID : "@mozilla.org/login-manager/prompter;1",
|
||||
classID : Components.ID("{8aa66d77-1bbb-45a6-991e-b8f47751c291}"),
|
||||
QueryInterface : XPCOMUtils.generateQI(
|
||||
[Ci.nsIAuthPrompt2, Ci.nsILoginManagerPrompter]),
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIAuthPrompt,
|
||||
Ci.nsIAuthPrompt2,
|
||||
Ci.nsILoginManagerPrompter]),
|
||||
|
||||
_window : null,
|
||||
_debug : false, // mirrors signon.debug
|
||||
@ -150,6 +157,15 @@ LoginManagerPrompter.prototype = {
|
||||
},
|
||||
|
||||
|
||||
__ioService: null, // IO service for string -> nsIURI conversion
|
||||
get _ioService() {
|
||||
if (!this.__ioService)
|
||||
this.__ioService = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
return this.__ioService;
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* log
|
||||
*
|
||||
@ -166,6 +182,163 @@ LoginManagerPrompter.prototype = {
|
||||
|
||||
|
||||
|
||||
/* ---------- nsIAuthPrompt prompts ---------- */
|
||||
|
||||
|
||||
/*
|
||||
* prompt
|
||||
*
|
||||
* Wrapper around the prompt service prompt. Saving random fields here
|
||||
* doesn't really make sense and therefore isn't implemented.
|
||||
*/
|
||||
prompt : function (aDialogTitle, aText, aPasswordRealm,
|
||||
aSavePassword, aDefaultText, aResult) {
|
||||
if (aSavePassword != Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER)
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
this.log("===== prompt() called =====");
|
||||
|
||||
if (aDefaultText) {
|
||||
aResult.value = aDefaultText;
|
||||
}
|
||||
|
||||
return this._promptService.prompt(this._window,
|
||||
aDialogTitle, aText, aResult, null, {});
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* promptUsernameAndPassword
|
||||
*
|
||||
* Looks up a username and password in the database. Will prompt the user
|
||||
* with a dialog, even if a username and password are found.
|
||||
*/
|
||||
promptUsernameAndPassword : function (aDialogTitle, aText, aPasswordRealm,
|
||||
aSavePassword, aUsername, aPassword) {
|
||||
if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
var checkBox = { value : false };
|
||||
var checkBoxLabel = null;
|
||||
var hostname = this._getFormattedHostname(aPasswordRealm);
|
||||
|
||||
this.log("===== promptUsernameAndPassword() called =====");
|
||||
|
||||
var canRememberLogin = (aSavePassword ==
|
||||
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) &&
|
||||
this._pwmgr.getLoginSavingEnabled(hostname);
|
||||
|
||||
// if checkBoxLabel is null, the checkbox won't be shown at all.
|
||||
if (canRememberLogin)
|
||||
checkBoxLabel = this._getLocalizedString("rememberPassword");
|
||||
|
||||
if (!aUsername.value && !aPassword.value) {
|
||||
// Look for existing logins.
|
||||
var foundLogins = this._pwmgr.findLogins({}, hostname, null,
|
||||
|
||||
aPasswordRealm);
|
||||
|
||||
// XXX Like the original code, we can't deal with multiple
|
||||
// account selection. (bug 227632)
|
||||
if (foundLogins.length > 0) {
|
||||
// We've got a login, but don't return straight away because
|
||||
// the old wallet code didn't either.
|
||||
aUsername.value = foundLogins[0].username;
|
||||
aPassword.value = foundLogins[0].password;
|
||||
}
|
||||
}
|
||||
|
||||
var ok = this._promptService.promptUsernameAndPassword(this._window,
|
||||
aDialogTitle, aText, aUsername, aPassword,
|
||||
checkBoxLabel, checkBox);
|
||||
|
||||
if (ok && checkBox.value) {
|
||||
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
newLogin.init(hostname, null, aPasswordRealm,
|
||||
aUsername.value, aPassword.value,
|
||||
"", "");
|
||||
|
||||
this.log("New login seen for " + aPasswordRealm);
|
||||
|
||||
this._pwmgr.addLogin(newLogin);
|
||||
}
|
||||
|
||||
return ok;
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* promptPassword
|
||||
*
|
||||
* If a password is found in the database for the password realm, it is
|
||||
* returned straight away without displaying a dialog.
|
||||
*
|
||||
* If a password is not found in the database, the user will be prompted
|
||||
* with a dialog with a text field and ok/cancel buttons. If the user
|
||||
* allows it, then the password will be saved in the database.
|
||||
*/
|
||||
promptPassword : function (aDialogTitle, aText, aPasswordRealm,
|
||||
aSavePassword, aPassword) {
|
||||
if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
var checkBox = { value : false };
|
||||
var checkBoxLabel = null;
|
||||
var [hostname, username, pathname] = this._decomposeURI(aPasswordRealm);
|
||||
var newRealm = hostname + pathname;
|
||||
|
||||
this.log("===== promptPassword called() =====");
|
||||
|
||||
var canRememberLogin = (aSavePassword ==
|
||||
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) &&
|
||||
this._pwmgr.getLoginSavingEnabled(hostname);
|
||||
|
||||
// if checkBoxLabel is null, the checkbox won't be shown at all.
|
||||
if (canRememberLogin)
|
||||
checkBoxLabel = this._getLocalizedString("rememberPassword");
|
||||
|
||||
if (!aPassword.value) {
|
||||
// Look for existing logins.
|
||||
var foundLogins = this._pwmgr.findLogins({}, hostname, null,
|
||||
|
||||
newRealm);
|
||||
|
||||
var i;
|
||||
// XXX Like the original code, we can't deal with multiple
|
||||
// account selection (bug 227632). We can deal with finding the
|
||||
// account based on the supplied username - but in this case we'll
|
||||
// just return the first match.
|
||||
for (i = 0; i < foundLogins.length; ++i) {
|
||||
if (foundLogins[i].username == username) {
|
||||
aPassword.value = foundLogins[i].password;
|
||||
// wallet returned straight away, so this mimics that code
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ok = this._promptService.promptPassword(this._window, aDialogTitle,
|
||||
aText, aPassword,
|
||||
checkBoxLabel, checkBox);
|
||||
|
||||
if (ok && checkBox.value) {
|
||||
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
newLogin.init(hostname, null, newRealm, username,
|
||||
aPassword.value, "", "");
|
||||
|
||||
this.log("New login seen for " + newRealm);
|
||||
|
||||
this._pwmgr.addLogin(newLogin);
|
||||
}
|
||||
|
||||
return ok;
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
/* ---------- nsIAuthPrompt2 prompts ---------- */
|
||||
|
||||
|
||||
@ -736,21 +909,27 @@ LoginManagerPrompter.prototype = {
|
||||
/*
|
||||
* _getFormattedHostname
|
||||
*
|
||||
* The aURI parameter may either be a string uri, or an nsIURI instance.
|
||||
*
|
||||
* Returns the hostname to use in a nsILoginInfo object (for example,
|
||||
* "http://example.com").
|
||||
*/
|
||||
_getFormattedHostname : function (aURI) {
|
||||
var scheme = aURI.scheme;
|
||||
var uri;
|
||||
if (aURI instanceof Ci.nsIURI) {
|
||||
uri = aURI;
|
||||
} else {
|
||||
uri = this._ioService.newURI(aURI, null, null);
|
||||
}
|
||||
var scheme = uri.scheme;
|
||||
|
||||
var hostname = scheme + "://" + aURI.host;
|
||||
var hostname = scheme + "://" + uri.host;
|
||||
|
||||
// If the URI explicitly specified a port, only include it when
|
||||
// it's not the default. (We never want "http://foo.com:80")
|
||||
port = aURI.port;
|
||||
port = uri.port;
|
||||
if (port != -1) {
|
||||
var ioService = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
var handler = ioService.getProtocolHandler(scheme);
|
||||
var handler = this._ioService.getProtocolHandler(scheme);
|
||||
if (port != handler.defaultPort)
|
||||
hostname += ":" + port;
|
||||
}
|
||||
@ -758,6 +937,19 @@ LoginManagerPrompter.prototype = {
|
||||
return hostname;
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts a hostname, username and a pathname from a string based URI
|
||||
* via a standard URI implementation.
|
||||
*/
|
||||
_decomposeURI: function (aURIString) {
|
||||
var uri = this._ioService.newURI(aURIString, null, null);
|
||||
var pathname = "";
|
||||
|
||||
if (uri.path != "/")
|
||||
pathname = uri.path;
|
||||
|
||||
return [this._getFormattedHostname(uri), uri.username, pathname];
|
||||
},
|
||||
|
||||
/*
|
||||
* _getAuthTarget
|
||||
|
Loading…
Reference in New Issue
Block a user