File indexing completed on 2024-06-02 05:20:57
0001 /* 0002 SPDX-FileCopyrightText: 2015-2016 Krzysztof Nowicki <krissn@op.pl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "ewsautodiscoveryjob.h" 0008 0009 #include "ewspoxautodiscoverrequest.h" 0010 #include "ewsresource_debug.h" 0011 0012 #include <KLocalizedString> 0013 0014 EwsAutodiscoveryJob::EwsAutodiscoveryJob(const QString &email, 0015 const QString &username, 0016 const QString &password, 0017 const QString &userAgent, 0018 bool enableNTLMv2, 0019 QObject *parent) 0020 : EwsJob(parent) 0021 , mEmail(email) 0022 , mUsername(username) 0023 , mPassword(password) 0024 , mUserAgent(userAgent) 0025 , mEnableNTLMv2(enableNTLMv2) 0026 { 0027 } 0028 0029 EwsAutodiscoveryJob::~EwsAutodiscoveryJob() = default; 0030 0031 void EwsAutodiscoveryJob::start() 0032 { 0033 parseEmail(); 0034 0035 if (!mUrlQueue.isEmpty()) { 0036 sendNextRequest(false); 0037 } 0038 } 0039 0040 void EwsAutodiscoveryJob::parseEmail() 0041 { 0042 const int atIndex = mEmail.indexOf(QLatin1Char('@')); 0043 if (atIndex < 0) { 0044 setErrorMsg(i18n("Incorrect email address")); 0045 emitResult(); 0046 return; 0047 } 0048 0049 const QString domain = mEmail.mid(atIndex + 1); 0050 if (domain.isEmpty()) { 0051 setErrorMsg(i18n("Incorrect email address")); 0052 emitResult(); 0053 return; 0054 } 0055 0056 addUrls(domain); 0057 } 0058 0059 void EwsAutodiscoveryJob::addUrls(const QString &domain) 0060 { 0061 mUrlQueue.enqueue(QStringLiteral("https://") + domain + QStringLiteral("/autodiscover/autodiscover.xml")); 0062 mUrlQueue.enqueue(QStringLiteral("https://autodiscover.") + domain + QStringLiteral("/autodiscover/autodiscover.xml")); 0063 mUrlQueue.enqueue(QStringLiteral("http://") + domain + QStringLiteral("/autodiscover/autodiscover.xml")); 0064 mUrlQueue.enqueue(QStringLiteral("http://autodiscover.") + domain + QStringLiteral("/autodiscover/autodiscover.xml")); 0065 } 0066 0067 void EwsAutodiscoveryJob::sendNextRequest(bool useCreds) 0068 { 0069 QUrl url(mUrlQueue.head()); 0070 if (useCreds) { 0071 url.setUserName(mUsername); 0072 url.setPassword(mPassword); 0073 } 0074 mUsedCreds = useCreds; 0075 auto req = new EwsPoxAutodiscoverRequest(url, mEmail, mUserAgent, mEnableNTLMv2, this); 0076 connect(req, &EwsPoxAutodiscoverRequest::result, this, &EwsAutodiscoveryJob::autodiscoveryRequestFinished); 0077 req->start(); 0078 } 0079 0080 void EwsAutodiscoveryJob::autodiscoveryRequestFinished(KJob *job) 0081 { 0082 auto req = qobject_cast<EwsPoxAutodiscoverRequest *>(job); 0083 if (!req) { 0084 setErrorMsg(QStringLiteral("Invalid EwsPoxAutodiscoverRequest job object")); 0085 emitResult(); 0086 return; 0087 } 0088 0089 if (req->error()) { 0090 if (req->error() == 401 && !mUsedCreds && req->lastHttpUrl().scheme() != QLatin1StringView("http")) { // Don't try authentication over HTTP 0091 /* The 401 error may have come from an URL different to the original one (due to 0092 * redirections). When the original URL is retried with credentials KIO HTTP will issue 0093 * a warning that an authenticated request is made to a host that never asked for it. 0094 * To fix this restart the request using the last URL that resulted in the 401 code. */ 0095 mUrlQueue.head() = req->lastHttpUrl().toString(); 0096 sendNextRequest(true); 0097 return; 0098 } else { 0099 mUrlQueue.removeFirst(); 0100 } 0101 0102 if (mUrlQueue.isEmpty()) { 0103 setErrorText(job->errorText()); 0104 setError(job->error()); 0105 emitResult(); 0106 } else { 0107 sendNextRequest(false); 0108 } 0109 } else { 0110 switch (req->action()) { 0111 case EwsPoxAutodiscoverRequest::Settings: { 0112 EwsPoxAutodiscoverRequest::Protocol proto = req->protocol(EwsPoxAutodiscoverRequest::ExchangeProto); 0113 if (!proto.isValid()) { 0114 setErrorMsg(i18n("Exchange protocol information not found")); 0115 } else { 0116 mEwsUrl = proto.ewsUrl(); 0117 mOabUrl = proto.oabUrl(); 0118 } 0119 emitResult(); 0120 break; 0121 } 0122 case EwsPoxAutodiscoverRequest::RedirectAddr: 0123 qCDebug(EWSRES_LOG) << "Redirected to e-mail addr" << req->redirectAddr(); 0124 mEmail = req->redirectAddr(); 0125 mUrlQueue.clear(); 0126 parseEmail(); 0127 if (!mUrlQueue.isEmpty()) { 0128 sendNextRequest(false); 0129 } 0130 break; 0131 case EwsPoxAutodiscoverRequest::RedirectUrl: 0132 qCDebug(EWSRES_LOG) << "Redirected to URL" << req->redirectUrl(); 0133 mUrlQueue.clear(); 0134 mUrlQueue.enqueue(req->redirectUrl()); 0135 sendNextRequest(false); 0136 break; 0137 } 0138 } 0139 } 0140 0141 #include "moc_ewsautodiscoveryjob.cpp"