File indexing completed on 2025-02-16 04:50:08

0001 /*
0002     SPDX-FileCopyrightText: 2015-2018 Krzysztof Nowicki <krissn@op.pl>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "ewsconfigdialog.h"
0008 
0009 #include <KAuthorized>
0010 #include <KConfigDialogManager>
0011 #include <KMessageBox>
0012 #include <KWindowSystem>
0013 
0014 #include <QDialogButtonBox>
0015 #include <QPushButton>
0016 #include <QVBoxLayout>
0017 
0018 #include "auth/ewsoauth.h"
0019 #include "auth/ewspasswordauth.h"
0020 #include "ewsautodiscoveryjob.h"
0021 #include "ewsgetfolderrequest.h"
0022 #include "ewsprogressdialog.h"
0023 #include "ewsresource.h"
0024 #include "ewssettings.h"
0025 #include "ewssubscriptionwidget.h"
0026 #include "ui_ewsconfigdialog.h"
0027 
0028 using StringPair = QPair<QString, QString>;
0029 
0030 static const QList<StringPair> userAgents = {
0031     {QStringLiteral("Microsoft Outlook 2016"), QStringLiteral("Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.6326; Pro)")},
0032     {QStringLiteral("Microsoft Outlook 2013"), QStringLiteral("Microsoft Office/15.0 (Windows NT 6.1; Microsoft Outlook 15.0.4420; Pro)")},
0033     {QStringLiteral("Microsoft Outlook 2010"), QStringLiteral("Microsoft Office/14.0 (Windows NT 6.1; Microsoft Outlook 14.0.5128; Pro)")},
0034     {QStringLiteral("Microsoft Outlook 2011 for Mac"), QStringLiteral("MacOutlook/14.2.0.101115 (Intel Mac OS X 10.6.7)")},
0035     {QStringLiteral("Mozilla Thunderbird 38 for Windows (with ExQuilla)"),
0036      QStringLiteral("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0")},
0037     {QStringLiteral("Mozilla Thunderbird 38 for Linux (with ExQuilla)"),
0038      QStringLiteral("Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0")},
0039     {QStringLiteral("Mozilla Thunderbird 38 for Mac (with ExQuilla)"),
0040      QStringLiteral("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:38.0) Gecko/20100101 Thunderbird/38.2.0")}};
0041 
0042 static const QString pkeyPasswordMapKey = QStringLiteral("pkey-password");
0043 
0044 static bool execJob(KJob *job)
0045 {
0046     QEventLoop loop;
0047     QObject::connect(job, &KJob::finished, &loop, [&](KJob *j) {
0048         loop.exit(j->error());
0049     });
0050     job->start();
0051     return loop.exec() == 0;
0052 }
0053 
0054 EwsConfigDialog::EwsConfigDialog(EwsResource *parentResource, EwsClient &client, WId wId, EwsSettings *settings)
0055     : QDialog()
0056     , mParentResource(parentResource)
0057     , mSettings(settings)
0058 {
0059     if (wId) {
0060         setAttribute(Qt::WA_NativeWindow, true);
0061         KWindowSystem::setMainWindow(windowHandle(), wId);
0062     }
0063 
0064     auto mainLayout = new QVBoxLayout(this);
0065     auto mainWidget = new QWidget(this);
0066     mainLayout->addWidget(mainWidget);
0067 
0068     mButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
0069     QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok);
0070     okButton->setDefault(true);
0071     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0072     connect(mButtonBox, &QDialogButtonBox::accepted, this, &EwsConfigDialog::dialogAccepted);
0073     connect(mButtonBox, &QDialogButtonBox::rejected, this, &EwsConfigDialog::reject);
0074     mainLayout->addWidget(mButtonBox);
0075 
0076     setWindowTitle(i18nc("@title:window", "Microsoft Exchange Configuration"));
0077 
0078     mUi = new Ui::SetupServerView;
0079     mUi->setupUi(mainWidget);
0080     mUi->accountName->setText(parentResource->name());
0081     mUi->passwordEdit->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
0082 
0083     mSubWidget = new EwsSubscriptionWidget(client, mSettings.data(), this);
0084     mUi->subscriptionTabLayout->addWidget(mSubWidget);
0085 
0086     mConfigManager = new KConfigDialogManager(this, mSettings.data());
0087     mConfigManager->updateWidgets();
0088     switch (mSettings->retrievalMethod()) {
0089     case 0:
0090         mUi->pollRadioButton->setChecked(true);
0091         break;
0092     case 1:
0093         mUi->streamingRadioButton->setChecked(true);
0094         break;
0095     default:
0096         break;
0097     }
0098 
0099     const EwsServerVersion &serverVer = client.serverVersion();
0100     if (serverVer.isValid()) {
0101         mUi->serverStatusText->setText(i18nc("Server status", "OK"));
0102         mUi->serverVersionText->setText(serverVer.toString());
0103     }
0104 
0105     bool baseUrlEmpty = mUi->kcfg_BaseUrl->text().isEmpty();
0106     mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(!baseUrlEmpty);
0107     mUi->tryConnectButton->setEnabled(!baseUrlEmpty);
0108     mTryConnectNeeded = baseUrlEmpty;
0109 
0110     connect(mSettings.data(), &EwsSettings::passwordRequestFinished, mUi->passwordEdit, &KPasswordLineEdit::setPassword);
0111     mSettings->requestPassword();
0112     mUi->authOAuth2RadioButton->setEnabled(true);
0113     const auto authMode = mSettings->authMode();
0114     if (authMode == QLatin1StringView("username-password")) {
0115         mUi->authUsernameRadioButton->setChecked(true);
0116     } else if (authMode == QLatin1StringView("oauth2")) {
0117         mUi->authOAuth2RadioButton->setChecked(true);
0118         mUi->pkeyAuthGroupBox->setEnabled(true);
0119     }
0120     mUi->pkeyAuthCert->setText(mSettings->pKeyCert());
0121     mUi->pkeyAuthCert->setNameFilter(QStringLiteral("%1 (*.pem)").arg(i18n("PEM file")));
0122     mUi->pkeyAuthKey->setText(mSettings->pKeyKey());
0123     mUi->pkeyAuthKey->setNameFilter(QStringLiteral("%1 (*.pem)").arg(i18n("PEM file")));
0124 
0125     connect(mSettings.data(), &EwsSettings::mapRequestFinished, this, [&](const QMap<QString, QString> &map) {
0126         if (map.contains(pkeyPasswordMapKey)) {
0127             mUi->pkeyAuthPassword->setPassword(map[pkeyPasswordMapKey]);
0128         }
0129     });
0130     mSettings->requestMap();
0131 
0132     int selectedIndex = -1;
0133     int i = 0;
0134     for (const StringPair &item : std::as_const(userAgents)) {
0135         mUi->userAgentCombo->addItem(item.first, item.second);
0136         if (mSettings->userAgent() == item.second) {
0137             selectedIndex = i;
0138         }
0139         i++;
0140     }
0141     mUi->userAgentCombo->addItem(i18nc("User Agent", "Custom"));
0142     if (!mSettings->userAgent().isEmpty()) {
0143         mUi->userAgentGroupBox->setChecked(true);
0144         mUi->userAgentCombo->setCurrentIndex(selectedIndex >= 0 ? selectedIndex : mUi->userAgentCombo->count() - 1);
0145         mUi->userAgentEdit->setText(mSettings->userAgent());
0146     } else {
0147         mUi->userAgentCombo->setCurrentIndex(mUi->userAgentCombo->count());
0148     }
0149 
0150     QIcon ewsIcon = QIcon::fromTheme(QStringLiteral("akonadi-ews"));
0151     mUi->aboutIconLabel->setPixmap(ewsIcon.pixmap(96, 96, QIcon::Normal, QIcon::On));
0152     mUi->aboutTextLabel->setText(i18nc("@info", "Akonadi Resource for Microsoft Exchange Web Services (EWS)"));
0153     mUi->aboutCopyrightLabel->setText(i18nc("@info", "Copyright (c) Krzysztof Nowicki 2015-2020"));
0154     mUi->aboutVersionLabel->setText(i18nc("@info", "Version %1", QStringLiteral(AKONADI_EWS_VERSION)));
0155     mUi->aboutLicenseLabel->setText(i18nc("@info", "Distributed under the GNU Library General Public License version 2.0 or later."));
0156     mUi->aboutUrlLabel->setText(
0157         QStringLiteral("<a "
0158                        "href=\"https://invent.kde.org/pim/kdepim-runtime/-/tree/master/resources/ews\">https://invent.kde.org/pim/kdepim-runtime/-/tree/master/"
0159                        "resources/ews</a>"));
0160 
0161     mUi->pkeyAuthCert->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
0162     mUi->pkeyAuthKey->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
0163 
0164     connect(okButton, &QPushButton::clicked, this, &EwsConfigDialog::save);
0165     connect(mUi->autodiscoverButton, &QPushButton::clicked, this, &EwsConfigDialog::performAutoDiscovery);
0166     connect(mUi->kcfg_Username, &QLineEdit::textChanged, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
0167     connect(mUi->passwordEdit, &KPasswordLineEdit::passwordChanged, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
0168     connect(mUi->kcfg_Domain, &QLineEdit::textChanged, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
0169     connect(mUi->kcfg_HasDomain, &QCheckBox::toggled, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
0170     connect(mUi->kcfg_Email, &QLineEdit::textChanged, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
0171     connect(mUi->authUsernameRadioButton, &QRadioButton::toggled, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
0172     connect(mUi->authOAuth2RadioButton, &QRadioButton::toggled, this, &EwsConfigDialog::setAutoDiscoveryNeeded);
0173     connect(mUi->kcfg_BaseUrl, &QLineEdit::textChanged, this, &EwsConfigDialog::enableTryConnect);
0174     connect(mUi->tryConnectButton, &QPushButton::clicked, this, &EwsConfigDialog::tryConnect);
0175     connect(mUi->userAgentCombo, &QComboBox::currentIndexChanged, this, &EwsConfigDialog::userAgentChanged);
0176     connect(mUi->clearFolderTreeSyncStateButton, &QPushButton::clicked, mParentResource, &EwsResource::clearFolderTreeSyncState);
0177 }
0178 
0179 EwsConfigDialog::~EwsConfigDialog()
0180 {
0181     delete mUi;
0182 }
0183 
0184 void EwsConfigDialog::save()
0185 {
0186     mParentResource->setName(mUi->accountName->text());
0187     mConfigManager->updateSettings();
0188     if (mUi->pollRadioButton->isChecked()) {
0189         mSettings->setRetrievalMethod(0);
0190     } else {
0191         mSettings->setRetrievalMethod(1);
0192     }
0193 
0194     /* Erase the subscription id in case subscription is disabled or its parameters changed. This
0195      * fill force creation of a new subscription. */
0196     if (!mSubWidget->subscriptionEnabled() || (mSubWidget->subscribedList() != mSettings->serverSubscriptionList())) {
0197         mSettings->setEventSubscriptionId(QString());
0198         mSettings->setEventSubscriptionWatermark(QString());
0199     }
0200 
0201     mSettings->setServerSubscription(mSubWidget->subscriptionEnabled());
0202     if (mSubWidget->subscribedListValid()) {
0203         mSettings->setServerSubscriptionList(mSubWidget->subscribedList());
0204     }
0205 
0206     if (mUi->userAgentGroupBox->isChecked()) {
0207         mSettings->setUserAgent(mUi->userAgentEdit->text());
0208     } else {
0209         mSettings->setUserAgent(QString());
0210     }
0211 
0212     if (mUi->authUsernameRadioButton->isChecked()) {
0213         mSettings->setAuthMode(QStringLiteral("username-password"));
0214     }
0215     if (mUi->authOAuth2RadioButton->isChecked()) {
0216         mSettings->setAuthMode(QStringLiteral("oauth2"));
0217     }
0218     if (mUi->pkeyAuthGroupBox->isEnabled() && !mUi->pkeyAuthCert->text().isEmpty() && !mUi->pkeyAuthKey->text().isEmpty()) {
0219         mSettings->setPKeyCert(mUi->pkeyAuthCert->text());
0220         mSettings->setPKeyKey(mUi->pkeyAuthKey->text());
0221         const QMap<QString, QString> map = {{pkeyPasswordMapKey, mUi->pkeyAuthPassword->password()}};
0222         mSettings->setMap(map);
0223     }
0224 
0225     if (!mAuthMap.isEmpty()) {
0226         mSettings->setMap(mAuthMap);
0227     }
0228     mSettings->setPassword(mUi->passwordEdit->password());
0229     mSettings->save();
0230 }
0231 
0232 void EwsConfigDialog::performAutoDiscovery()
0233 {
0234     mAutoDiscoveryJob = new EwsAutodiscoveryJob(mUi->kcfg_Email->text(),
0235                                                 fullUsername(),
0236                                                 mUi->passwordEdit->password(),
0237                                                 mUi->userAgentGroupBox->isEnabled() ? mUi->userAgentEdit->text() : QString(),
0238                                                 mUi->kcfg_EnableNTLMv2->isChecked(),
0239                                                 this);
0240     connect(mAutoDiscoveryJob, &EwsAutodiscoveryJob::result, this, &EwsConfigDialog::autoDiscoveryFinished);
0241     mProgressDialog = new EwsProgressDialog(this, EwsProgressDialog::AutoDiscovery);
0242     connect(mProgressDialog, &QDialog::rejected, this, &EwsConfigDialog::autoDiscoveryCancelled);
0243     mProgressDialog->show();
0244     mAutoDiscoveryJob->start();
0245 }
0246 
0247 void EwsConfigDialog::autoDiscoveryFinished(KJob *job)
0248 {
0249     if (job->error() || job != mAutoDiscoveryJob) {
0250         KMessageBox::error(this, job->errorText(), i18nc("Exchange server autodiscovery", "Autodiscovery failed"));
0251         mProgressDialog->reject();
0252     } else {
0253         mProgressDialog->accept();
0254         mUi->kcfg_BaseUrl->setText(mAutoDiscoveryJob->ewsUrl());
0255     }
0256     mAutoDiscoveryJob->deleteLater();
0257     mAutoDiscoveryJob = nullptr;
0258     mProgressDialog->deleteLater();
0259     mProgressDialog = nullptr;
0260 }
0261 
0262 void EwsConfigDialog::tryConnectFinished(KJob *job)
0263 {
0264     if (job->error() || job != mTryConnectJob) {
0265         KMessageBox::error(this, job->errorText(), i18nc("Exchange server connection", "Connection failed"));
0266         mUi->serverStatusText->setText(i18nc("Exchange server status", "Failed"));
0267         mUi->serverVersionText->setText(i18nc("Exchange server version", "Unknown"));
0268         mProgressDialog->reject();
0269     } else {
0270         mUi->serverStatusText->setText(i18nc("Exchange server status", "OK"));
0271         mUi->serverVersionText->setText(mTryConnectJob->serverVersion().toString());
0272         mProgressDialog->accept();
0273     }
0274     // mTryConnectJob->deleteLater();
0275     mTryConnectJob = nullptr;
0276     // mProgressDialog->deleteLater();
0277     mProgressDialog = nullptr;
0278 }
0279 
0280 void EwsConfigDialog::autoDiscoveryCancelled()
0281 {
0282     if (mAutoDiscoveryJob) {
0283         mAutoDiscoveryJob->kill();
0284     }
0285     mProgressDialog->deleteLater();
0286     mProgressDialog = nullptr;
0287 }
0288 
0289 void EwsConfigDialog::tryConnectCancelled()
0290 {
0291     if (mTryConnectJob) {
0292         mTryConnectJob->kill();
0293     }
0294 
0295     mTryConnectJobCancelled = true;
0296 }
0297 
0298 void EwsConfigDialog::setAutoDiscoveryNeeded()
0299 {
0300     mAutoDiscoveryNeeded = true;
0301     mTryConnectNeeded = true;
0302     mAuthMap.clear();
0303 
0304     /* Enable the OK button when at least the e-mail and username fields are set. Additionally if
0305      * autodiscovery is disabled, enable the OK button only if the base URL is set. */
0306     bool okEnabled = !mUi->kcfg_Username->text().isEmpty() && !mUi->kcfg_Email->text().isEmpty();
0307     if (!mUi->kcfg_AutoDiscovery->isChecked() && mUi->kcfg_BaseUrl->text().isEmpty()) {
0308         okEnabled = false;
0309     }
0310     mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(okEnabled);
0311 
0312     mUi->pkeyAuthGroupBox->setEnabled(mUi->authOAuth2RadioButton->isChecked());
0313 }
0314 
0315 QString EwsConfigDialog::fullUsername() const
0316 {
0317     QString username = mUi->kcfg_Username->text();
0318     if (mUi->kcfg_HasDomain->isChecked()) {
0319         username.prepend(mUi->kcfg_Domain->text() + QStringLiteral("\\"));
0320     }
0321     return username;
0322 }
0323 
0324 void EwsConfigDialog::dialogAccepted()
0325 {
0326     if (mUi->kcfg_AutoDiscovery->isChecked() && mAutoDiscoveryNeeded) {
0327         mAutoDiscoveryJob = new EwsAutodiscoveryJob(mUi->kcfg_Email->text(),
0328                                                     fullUsername(),
0329                                                     mUi->passwordEdit->password(),
0330                                                     mUi->userAgentGroupBox->isEnabled() ? mUi->userAgentEdit->text() : QString(),
0331                                                     mUi->kcfg_EnableNTLMv2->isChecked(),
0332                                                     this);
0333         connect(mAutoDiscoveryJob, &EwsAutodiscoveryJob::result, this, &EwsConfigDialog::autoDiscoveryFinished);
0334         mProgressDialog = new EwsProgressDialog(this, EwsProgressDialog::AutoDiscovery);
0335         connect(mProgressDialog, &QDialog::rejected, this, &EwsConfigDialog::autoDiscoveryCancelled);
0336         mAutoDiscoveryJob->start();
0337         if (!mProgressDialog->exec()) {
0338             if (KMessageBox::questionTwoActions(
0339                     this,
0340                     i18n("Autodiscovery failed. This can be caused by incorrect parameters. Do you still want to save your settings?"),
0341                     i18n("Exchange server autodiscovery"),
0342                     KStandardGuiItem::save(),
0343                     KStandardGuiItem::cancel())
0344                 == KMessageBox::ButtonCode::PrimaryAction) {
0345                 accept();
0346             }
0347             return;
0348         }
0349     }
0350 
0351     if (mTryConnectNeeded) {
0352         EwsClient cli;
0353         cli.setUrl(mUi->kcfg_BaseUrl->text());
0354         const auto auth = prepareAuth();
0355         cli.setAuth(auth);
0356         if (mUi->userAgentGroupBox->isChecked()) {
0357             cli.setUserAgent(mUi->userAgentEdit->text());
0358         }
0359         cli.setEnableNTLMv2(mUi->kcfg_EnableNTLMv2->isChecked());
0360         mTryConnectJob = new EwsGetFolderRequest(cli, this);
0361         mTryConnectJob->setFolderShape(EwsFolderShape(EwsShapeIdOnly));
0362         mTryConnectJob->setFolderIds(EwsId::List() << EwsId(EwsDIdInbox));
0363         connect(mTryConnectJob, &EwsGetFolderRequest::result, this, &EwsConfigDialog::tryConnectFinished);
0364         mProgressDialog = new EwsProgressDialog(this, EwsProgressDialog::TryConnect);
0365         connect(mProgressDialog, &QDialog::rejected, this, &EwsConfigDialog::tryConnectCancelled);
0366         mTryConnectJob->start();
0367         if (!execJob(mTryConnectJob)) {
0368             if (!mTryConnectJobCancelled) {
0369                 if (KMessageBox::questionTwoActions(
0370                         this,
0371                         i18n("Connecting to Exchange failed. This can be caused by incorrect parameters. Do you still want to save your settings?"),
0372                         i18n("Exchange server connection"),
0373                         KStandardGuiItem::save(),
0374                         KStandardGuiItem::cancel())
0375                     == KMessageBox::ButtonCode::PrimaryAction) {
0376                     accept();
0377                 }
0378             }
0379             return;
0380         } else {
0381             accept();
0382         }
0383     }
0384 
0385     if (!mTryConnectNeeded && !mAutoDiscoveryNeeded) {
0386         accept();
0387     }
0388 }
0389 
0390 void EwsConfigDialog::enableTryConnect()
0391 {
0392     mTryConnectNeeded = true;
0393     bool baseUrlEmpty = mUi->kcfg_BaseUrl->text().isEmpty();
0394 
0395     /* Enable the OK button when at least the e-mail and username fields are set. Additionally if
0396      * autodiscovery is disabled, enable the OK button only if the base URL is set. */
0397     bool okEnabled = !mUi->kcfg_Username->text().isEmpty() && !mUi->kcfg_Email->text().isEmpty();
0398     if (!mUi->kcfg_AutoDiscovery->isChecked() && baseUrlEmpty) {
0399         okEnabled = false;
0400     }
0401     mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(okEnabled);
0402     mUi->tryConnectButton->setEnabled(!baseUrlEmpty);
0403 }
0404 
0405 void EwsConfigDialog::tryConnect()
0406 {
0407     EwsClient cli;
0408     cli.setUrl(mUi->kcfg_BaseUrl->text());
0409     const auto auth = prepareAuth();
0410     cli.setAuth(auth);
0411     if (mUi->userAgentGroupBox->isChecked()) {
0412         cli.setUserAgent(mUi->userAgentEdit->text());
0413     }
0414     cli.setEnableNTLMv2(mUi->kcfg_EnableNTLMv2->isChecked());
0415     mTryConnectJob = new EwsGetFolderRequest(cli, this);
0416     mTryConnectJob->setFolderShape(EwsFolderShape(EwsShapeIdOnly));
0417     mTryConnectJob->setFolderIds(EwsId::List() << EwsId(EwsDIdInbox));
0418     mTryConnectJobCancelled = false;
0419     mProgressDialog = new EwsProgressDialog(this, EwsProgressDialog::TryConnect);
0420     connect(mProgressDialog, &QDialog::rejected, this, &EwsConfigDialog::tryConnectCancelled);
0421     mProgressDialog->show();
0422     if (!execJob(mTryConnectJob)) {
0423         if (!mTryConnectJobCancelled) {
0424             mUi->serverStatusText->setText(i18nc("Exchange server status", "Failed"));
0425             mUi->serverVersionText->setText(i18nc("Exchange server version", "Unknown"));
0426             KMessageBox::error(this, mTryConnectJob->errorText(), i18n("Connection failed"));
0427         }
0428     } else {
0429         mUi->serverStatusText->setText(i18nc("Exchange server status", "OK"));
0430         mUi->serverVersionText->setText(mTryConnectJob->serverVersion().toString());
0431     }
0432     mProgressDialog->hide();
0433     mTryConnectJob = nullptr;
0434 }
0435 
0436 void EwsConfigDialog::userAgentChanged(int)
0437 {
0438     QString data = mUi->userAgentCombo->currentData().toString();
0439     mUi->userAgentEdit->setEnabled(data.isEmpty());
0440     if (!data.isEmpty()) {
0441         mUi->userAgentEdit->setText(data);
0442     }
0443 }
0444 
0445 EwsAbstractAuth *EwsConfigDialog::prepareAuth()
0446 {
0447     EwsAbstractAuth *auth = nullptr;
0448 
0449     if (mUi->authOAuth2RadioButton->isChecked()) {
0450         auth = new EwsOAuth(this, mUi->kcfg_Email->text(), mSettings->oAuth2AppId(), mSettings->oAuth2ReturnUri());
0451     } else if (mUi->authUsernameRadioButton->isChecked()) {
0452         auth = new EwsPasswordAuth(fullUsername(), this);
0453     } else {
0454         // Be sure that it will not crash.
0455         return auth;
0456     }
0457     auth->setAuthParentWidget(this);
0458 
0459     if (mUi->pkeyAuthGroupBox->isEnabled() && !mUi->pkeyAuthCert->text().isEmpty() && !mUi->pkeyAuthKey->text().isEmpty()) {
0460         auth->setPKeyAuthCertificateFiles(mUi->pkeyAuthCert->text(), mUi->pkeyAuthKey->text());
0461         mAuthMap[pkeyPasswordMapKey] = mUi->pkeyAuthPassword->password();
0462     }
0463 
0464     connect(auth, &EwsAbstractAuth::requestWalletPassword, this, [&](bool) {
0465         auth->walletPasswordRequestFinished(mUi->passwordEdit->password());
0466     });
0467     connect(auth, &EwsAbstractAuth::requestWalletMap, this, [&]() {
0468         auth->walletMapRequestFinished(mAuthMap);
0469     });
0470     connect(auth, &EwsAbstractAuth::setWalletMap, this, [&](const QMap<QString, QString> &map) {
0471         mAuthMap = map;
0472     });
0473 
0474     auth->init();
0475 
0476     QEventLoop loop;
0477     bool authFinished = false;
0478 
0479     connect(auth, &EwsAbstractAuth::authSucceeded, this, [&]() {
0480         authFinished = true;
0481         loop.exit(0);
0482     });
0483     connect(auth, &EwsAbstractAuth::authFailed, this, [&](const QString &) {
0484         authFinished = true;
0485         loop.exit(0);
0486     });
0487 
0488     if (auth->authenticate(true)) {
0489         if (!authFinished) {
0490             loop.exec();
0491         }
0492     }
0493 
0494     return auth;
0495 }
0496 
0497 #include "moc_ewsconfigdialog.cpp"