mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-28 03:17:31 +09:00
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
This commit is contained in:
parent
23e0d82436
commit
e400f4130a
1564 changed files with 510348 additions and 0 deletions
347
mailnews/base/prefs/content/accountcreation/verifyConfig.js
Normal file
347
mailnews/base/prefs/content/accountcreation/verifyConfig.js
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* This checks a given config, by trying a real connection and login,
|
||||
* with username and password.
|
||||
*
|
||||
* TODO
|
||||
* - give specific errors, bug 555448
|
||||
* - return a working |Abortable| to allow cancel
|
||||
*
|
||||
* @param accountConfig {AccountConfig} The guessed account config.
|
||||
* username, password, realname, emailaddress etc. are not filled out,
|
||||
* but placeholders to be filled out via replaceVariables().
|
||||
* @param alter {boolean}
|
||||
* Try other usernames and login schemes, until login works.
|
||||
* Warning: Modifies |accountConfig|.
|
||||
*
|
||||
* This function is async.
|
||||
* @param successCallback function(accountConfig)
|
||||
* Called when we could guess the config.
|
||||
* For accountConfig, see below.
|
||||
* @param errorCallback function(ex)
|
||||
* Called when we could guess not the config, either
|
||||
* because we have not found anything or
|
||||
* because there was an error (e.g. no network connection).
|
||||
* The ex.message will contain a user-presentable message.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource:///modules/mailServices.js");
|
||||
Components.utils.import("resource://gre/modules/OAuth2Providers.jsm");
|
||||
|
||||
if (typeof gEmailWizardLogger == "undefined") {
|
||||
Cu.import("resource:///modules/gloda/log4moz.js");
|
||||
var gEmailWizardLogger = Log4Moz.getConfiguredLogger("mail.wizard");
|
||||
}
|
||||
|
||||
function verifyConfig(config, alter, msgWindow, successCallback, errorCallback)
|
||||
{
|
||||
ddump(debugObject(config, "config", 3));
|
||||
assert(config instanceof AccountConfig,
|
||||
"BUG: Arg 'config' needs to be an AccountConfig object");
|
||||
assert(typeof(alter) == "boolean");
|
||||
assert(typeof(successCallback) == "function");
|
||||
assert(typeof(errorCallback) == "function");
|
||||
|
||||
if (MailServices.accounts.findRealServer(config.incoming.username,
|
||||
config.incoming.hostname,
|
||||
sanitize.enum(config.incoming.type,
|
||||
["pop3", "imap", "nntp"]),
|
||||
config.incoming.port)) {
|
||||
errorCallback("Incoming server exists");
|
||||
return;
|
||||
}
|
||||
|
||||
// incoming server
|
||||
let inServer =
|
||||
MailServices.accounts.createIncomingServer(config.incoming.username,
|
||||
config.incoming.hostname,
|
||||
sanitize.enum(config.incoming.type,
|
||||
["pop3", "imap", "nntp"]));
|
||||
inServer.port = config.incoming.port;
|
||||
inServer.password = config.incoming.password;
|
||||
if (config.incoming.socketType == 1) // plain
|
||||
inServer.socketType = Ci.nsMsgSocketType.plain;
|
||||
else if (config.incoming.socketType == 2) // SSL
|
||||
inServer.socketType = Ci.nsMsgSocketType.SSL;
|
||||
else if (config.incoming.socketType == 3) // STARTTLS
|
||||
inServer.socketType = Ci.nsMsgSocketType.alwaysSTARTTLS;
|
||||
|
||||
gEmailWizardLogger.info("Setting incoming server authMethod to " +
|
||||
config.incoming.auth);
|
||||
inServer.authMethod = config.incoming.auth;
|
||||
|
||||
try {
|
||||
// Lookup issuer if needed.
|
||||
if (config.incoming.auth == Ci.nsMsgAuthMethod.OAuth2 ||
|
||||
config.outgoing.auth == Ci.nsMsgAuthMethod.OAuth2) {
|
||||
if (!config.oauthSettings)
|
||||
config.oauthSettings = {};
|
||||
if (!config.oauthSettings.issuer || !config.oauthSettings.scope) {
|
||||
// lookup issuer or scope from hostname
|
||||
let hostname = (config.incoming.auth == Ci.nsMsgAuthMethod.OAuth2) ?
|
||||
config.incoming.hostname : config.outgoing.hostname;
|
||||
let hostDetails = OAuth2Providers.getHostnameDetails(hostname);
|
||||
if (hostDetails)
|
||||
[config.oauthSettings.issuer, config.oauthSettings.scope] = hostDetails;
|
||||
if (!config.oauthSettings.issuer || !config.oauthSettings.scope)
|
||||
throw "Could not get issuer for oauth2 authentication";
|
||||
}
|
||||
gEmailWizardLogger.info("Saving oauth parameters for issuer " +
|
||||
config.oauthSettings.issuer);
|
||||
inServer.setCharValue("oauth2.scope", config.oauthSettings.scope);
|
||||
inServer.setCharValue("oauth2.issuer", config.oauthSettings.issuer);
|
||||
gEmailWizardLogger.info("OAuth2 issuer, scope is " +
|
||||
config.oauthSettings.issuer + ", " + config.oauthSettings.scope);
|
||||
}
|
||||
|
||||
if (inServer.password ||
|
||||
inServer.authMethod == Ci.nsMsgAuthMethod.OAuth2)
|
||||
verifyLogon(config, inServer, alter, msgWindow,
|
||||
successCallback, errorCallback);
|
||||
else {
|
||||
// Avoid pref pollution, clear out server prefs.
|
||||
MailServices.accounts.removeIncomingServer(inServer, true);
|
||||
successCallback(config);
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch (e) {
|
||||
gEmailWizardLogger.error("ERROR: verify logon shouldn't have failed");
|
||||
}
|
||||
// Avoid pref pollution, clear out server prefs.
|
||||
MailServices.accounts.removeIncomingServer(inServer, true);
|
||||
errorCallback(e);
|
||||
}
|
||||
|
||||
function verifyLogon(config, inServer, alter, msgWindow, successCallback,
|
||||
errorCallback)
|
||||
{
|
||||
gEmailWizardLogger.info("verifyLogon for server at " + inServer.hostName);
|
||||
// hack - save away the old callbacks.
|
||||
let saveCallbacks = msgWindow.notificationCallbacks;
|
||||
// set our own callbacks - this works because verifyLogon will
|
||||
// synchronously create the transport and use the notification callbacks.
|
||||
let listener = new urlListener(config, inServer, alter, msgWindow,
|
||||
successCallback, errorCallback);
|
||||
// our listener listens both for the url and cert errors.
|
||||
msgWindow.notificationCallbacks = listener;
|
||||
// try to work around bug where backend is clearing password.
|
||||
try {
|
||||
inServer.password = config.incoming.password;
|
||||
let uri = inServer.verifyLogon(listener, msgWindow);
|
||||
// clear msgWindow so url won't prompt for passwords.
|
||||
uri.QueryInterface(Ci.nsIMsgMailNewsUrl).msgWindow = null;
|
||||
}
|
||||
catch (e) { gEmailWizardLogger.error("verifyLogon failed: " + e); throw e;}
|
||||
finally {
|
||||
// restore them
|
||||
msgWindow.notificationCallbacks = saveCallbacks;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The url listener also implements nsIBadCertListener2. Its job is to prevent
|
||||
* "bad cert" security dialogs from being shown to the user. Currently it puts
|
||||
* up the cert override dialog, though we'd like to give the user more detailed
|
||||
* information in the future.
|
||||
*/
|
||||
|
||||
function urlListener(config, server, alter, msgWindow, successCallback,
|
||||
errorCallback)
|
||||
{
|
||||
this.mConfig = config;
|
||||
this.mServer = server;
|
||||
this.mAlter = alter;
|
||||
this.mSuccessCallback = successCallback;
|
||||
this.mErrorCallback = errorCallback;
|
||||
this.mMsgWindow = msgWindow;
|
||||
this.mCertError = false;
|
||||
this._log = Log4Moz.getConfiguredLogger("mail.wizard");
|
||||
}
|
||||
urlListener.prototype =
|
||||
{
|
||||
OnStartRunningUrl: function(aUrl)
|
||||
{
|
||||
this._log.info("Starting to test username");
|
||||
this._log.info(" username=" + (this.mConfig.incoming.username !=
|
||||
this.mConfig.identity.emailAddress) +
|
||||
", have savedUsername=" +
|
||||
(this.mConfig.usernameSaved ? "true" : "false"));
|
||||
this._log.info(" authMethod=" + this.mServer.authMethod);
|
||||
},
|
||||
|
||||
OnStopRunningUrl: function(aUrl, aExitCode)
|
||||
{
|
||||
this._log.info("Finished verifyConfig resulted in " + aExitCode);
|
||||
if (Components.isSuccessCode(aExitCode))
|
||||
{
|
||||
this._cleanup();
|
||||
this.mSuccessCallback(this.mConfig);
|
||||
}
|
||||
// Logon failed, and we aren't supposed to try other variations.
|
||||
else if (!this.mAlter)
|
||||
{
|
||||
this._cleanup();
|
||||
var errorMsg = getStringBundle(
|
||||
"chrome://messenger/locale/accountCreationModel.properties")
|
||||
.GetStringFromName("cannot_login.error");
|
||||
this.mErrorCallback(new Exception(errorMsg));
|
||||
}
|
||||
// Try other variations, unless there's a cert error, in which
|
||||
// case we'll see what the user chooses.
|
||||
else if (!this.mCertError)
|
||||
{
|
||||
this.tryNextLogon()
|
||||
}
|
||||
},
|
||||
|
||||
tryNextLogon: function()
|
||||
{
|
||||
this._log.info("tryNextLogon()");
|
||||
this._log.info(" username=" + (this.mConfig.incoming.username !=
|
||||
this.mConfig.identity.emailAddress) +
|
||||
", have savedUsername=" +
|
||||
(this.mConfig.usernameSaved ? "true" : "false"));
|
||||
this._log.info(" authMethod=" + this.mServer.authMethod);
|
||||
// check if we tried full email address as username
|
||||
if (this.mConfig.incoming.username != this.mConfig.identity.emailAddress)
|
||||
{
|
||||
this._log.info(" Changing username to email address.");
|
||||
this.mConfig.usernameSaved = this.mConfig.incoming.username;
|
||||
this.mConfig.incoming.username = this.mConfig.identity.emailAddress;
|
||||
this.mConfig.outgoing.username = this.mConfig.identity.emailAddress;
|
||||
this.mServer.username = this.mConfig.incoming.username;
|
||||
this.mServer.password = this.mConfig.incoming.password;
|
||||
verifyLogon(this.mConfig, this.mServer, this.mAlter, this.mMsgWindow,
|
||||
this.mSuccessCallback, this.mErrorCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.mConfig.usernameSaved)
|
||||
{
|
||||
this._log.info(" Re-setting username.");
|
||||
// If we tried the full email address as the username, then let's go
|
||||
// back to trying just the username before trying the other cases.
|
||||
this.mConfig.incoming.username = this.mConfig.usernameSaved;
|
||||
this.mConfig.outgoing.username = this.mConfig.usernameSaved;
|
||||
this.mConfig.usernameSaved = null;
|
||||
this.mServer.username = this.mConfig.incoming.username;
|
||||
this.mServer.password = this.mConfig.incoming.password;
|
||||
}
|
||||
|
||||
// sec auth seems to have failed, and we've tried both
|
||||
// varieties of user name, sadly.
|
||||
// So fall back to non-secure auth, and
|
||||
// again try the user name and email address as username
|
||||
assert(this.mConfig.incoming.auth == this.mServer.authMethod);
|
||||
this._log.info(" Using SSL: " +
|
||||
(this.mServer.socketType == Ci.nsMsgSocketType.SSL ||
|
||||
this.mServer.socketType == Ci.nsMsgSocketType.alwaysSTARTTLS));
|
||||
if (this.mConfig.incoming.authAlternatives &&
|
||||
this.mConfig.incoming.authAlternatives.length)
|
||||
// We may be dropping back to insecure auth methods here,
|
||||
// which is not good. But then again, we already warned the user,
|
||||
// if it is a config without SSL.
|
||||
{
|
||||
this._log.info(" auth alternatives = " +
|
||||
this.mConfig.incoming.authAlternatives.join(","));
|
||||
this._log.info(" Decreasing auth.");
|
||||
this._log.info(" Have password: " +
|
||||
(this.mServer.password ? "true" : "false"));
|
||||
let brokenAuth = this.mConfig.incoming.auth;
|
||||
// take the next best method (compare chooseBestAuthMethod() in guess)
|
||||
this.mConfig.incoming.auth =
|
||||
this.mConfig.incoming.authAlternatives.shift();
|
||||
this.mServer.authMethod = this.mConfig.incoming.auth;
|
||||
// Assume that SMTP server has same methods working as incoming.
|
||||
// Broken assumption, but we currently have no SMTP verification.
|
||||
// TODO implement real SMTP verification
|
||||
if (this.mConfig.outgoing.auth == brokenAuth &&
|
||||
this.mConfig.outgoing.authAlternatives.indexOf(
|
||||
this.mConfig.incoming.auth) != -1)
|
||||
this.mConfig.outgoing.auth = this.mConfig.incoming.auth;
|
||||
this._log.info(" outgoing auth: " + this.mConfig.outgoing.auth);
|
||||
verifyLogon(this.mConfig, this.mServer, this.mAlter, this.mMsgWindow,
|
||||
this.mSuccessCallback, this.mErrorCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
// Tried all variations we can. Give up.
|
||||
this._log.info("Giving up.");
|
||||
this._cleanup();
|
||||
let errorMsg = getStringBundle(
|
||||
"chrome://messenger/locale/accountCreationModel.properties")
|
||||
.GetStringFromName("cannot_login.error");
|
||||
this.mErrorCallback(new Exception(errorMsg));
|
||||
return;
|
||||
},
|
||||
|
||||
_cleanup : function()
|
||||
{
|
||||
try {
|
||||
// Avoid pref pollution, clear out server prefs.
|
||||
if (this.mServer) {
|
||||
MailServices.accounts.removeIncomingServer(this.mServer, true);
|
||||
this.mServer = null;
|
||||
}
|
||||
} catch (e) { this._log.error(e); }
|
||||
},
|
||||
|
||||
// Suppress any certificate errors
|
||||
notifyCertProblem: function(socketInfo, status, targetSite) {
|
||||
this.mCertError = true;
|
||||
this._log.error("cert error");
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
try {
|
||||
self.informUserOfCertError(socketInfo, status, targetSite);
|
||||
} catch (e) { logException(e); }
|
||||
}, 0);
|
||||
return true;
|
||||
},
|
||||
|
||||
informUserOfCertError : function(socketInfo, status, targetSite) {
|
||||
var params = {
|
||||
exceptionAdded : false,
|
||||
sslStatus : status,
|
||||
prefetchCert : true,
|
||||
location : targetSite,
|
||||
};
|
||||
window.openDialog("chrome://pippki/content/exceptionDialog.xul",
|
||||
"","chrome,centerscreen,modal", params);
|
||||
this._log.info("cert exception dialog closed");
|
||||
this._log.info("cert exceptionAdded = " + params.exceptionAdded);
|
||||
if (!params.exceptionAdded) {
|
||||
this._cleanup();
|
||||
let errorMsg = getStringBundle(
|
||||
"chrome://messenger/locale/accountCreationModel.properties")
|
||||
.GetStringFromName("cannot_login.error");
|
||||
this.mErrorCallback(new Exception(errorMsg));
|
||||
}
|
||||
else {
|
||||
// Retry the logon now that we've added the cert exception.
|
||||
verifyLogon(this.mConfig, this.mServer, this.mAlter, this.mMsgWindow,
|
||||
this.mSuccessCallback, this.mErrorCallback);
|
||||
}
|
||||
},
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
getInterface: function(iid) {
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
QueryInterface: function(iid) {
|
||||
if (!iid.equals(Components.interfaces.nsIBadCertListener2) &&
|
||||
!iid.equals(Components.interfaces.nsIInterfaceRequestor) &&
|
||||
!iid.equals(Components.interfaces.nsIUrlListener) &&
|
||||
!iid.equals(Components.interfaces.nsISupports))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue