diff --git a/resources/ews/ewssettings.cpp b/resources/ews/ewssettings.cpp index bb7bcfb30..766cb9285 100644 --- a/resources/ews/ewssettings.cpp +++ b/resources/ews/ewssettings.cpp @@ -1,196 +1,203 @@ /* - Copyright (C) 2017 Krzysztof Nowicki + Copyright (C) 2017-2018 Krzysztof Nowicki This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ewssettings.h" #include #include #include #include "ewsresource_debug.h" static const QString ewsWalletFolder = QStringLiteral("akonadi-ews"); // Allow unittest to override this to shorten test execution #ifdef EWSSETTINGS_UNITTEST constexpr int walletTimeout = 2000; #else constexpr int walletTimeout = 30000; #endif using namespace KWallet; EwsSettings::EwsSettings(WId windowId) - : EwsSettingsBase(), mWindowId(windowId), mWalletReadTimer(this), mWalletWriteTimer(this) + : EwsSettingsBase(), mWindowId(windowId), mWalletTimer(this) { - mWalletReadTimer.setInterval(walletTimeout); - mWalletReadTimer.setSingleShot(true); - connect(&mWalletReadTimer, &QTimer::timeout, this, [this]() { - qCWarning(EWSRES_LOG) << "Timeout waiting for wallet open for read"; - onWalletOpenedForRead(false); - }); - mWalletWriteTimer.setInterval(walletTimeout); - mWalletWriteTimer.setSingleShot(true); - connect(&mWalletWriteTimer, &QTimer::timeout, this, [this]() { - qCWarning(EWSRES_LOG) << "Timeout waiting for wallet open for write"; - onWalletOpenedForWrite(false); + mWalletTimer.setInterval(walletTimeout); + mWalletTimer.setSingleShot(true); + connect(&mWalletTimer, &QTimer::timeout, this, [this]() { + qCWarning(EWSRES_LOG) << "Timeout waiting for wallet open"; + onWalletOpened(false); }); } EwsSettings::~EwsSettings() { } +bool EwsSettings::requestWalletOpen() +{ + if (!mWallet) { + mWallet = Wallet::openWallet(Wallet::NetworkWallet(), + mWindowId, Wallet::Asynchronous); + if (mWallet) { + connect(mWallet.data(), &Wallet::walletOpened, this, + &EwsSettings::onWalletOpened); + mWalletTimer.start(); + return true; + } else { + qCWarning(EWSRES_LOG) << "Failed to open wallet"; + } + } + return false; +} + void EwsSettings::requestPassword(bool ask) { bool status = false; qCDebug(EWSRES_LOG) << "requestPassword: start"; if (!mPassword.isNull()) { qCDebug(EWSRES_LOG) << "requestPassword: password already set"; Q_EMIT passwordRequestFinished(mPassword); return; } - if (!mWallet) { - mWallet = Wallet::openWallet(Wallet::NetworkWallet(), - mWindowId, Wallet::Asynchronous); - if (mWallet) { - connect(mWallet.data(), &Wallet::walletOpened, this, - &EwsSettings::onWalletOpenedForRead); - mWalletReadTimer.start(); - return; - } else { - qCWarning(EWSRES_LOG) << "Failed to open wallet"; - } + if (requestWalletOpen()) { + mPasswordReadPending = true; + return; } + if (mWallet && mWallet->isOpen()) { mPassword = readPassword(); mWallet.clear(); status = true; } if (!status) { if (!ask) { qCDebug(EWSRES_LOG) << "requestPassword: Not allowed to ask"; } else { qCDebug(EWSRES_LOG) << "requestPassword: Requesting interactively"; mPasswordDlg = new KPasswordDialog(nullptr); mPasswordDlg->setModal(true); mPasswordDlg->setPrompt(i18n("Please enter password for user '%1' and Exchange account '%2'.", username(), email())); if (mPasswordDlg->exec() == QDialog::Accepted) { mPassword = mPasswordDlg->password(); setPassword(mPassword); } delete mPasswordDlg; } } Q_EMIT passwordRequestFinished(mPassword); - return; } QString EwsSettings::readPassword() const { QString password; if (mWallet->hasFolder(ewsWalletFolder)) { mWallet->setFolder(ewsWalletFolder); mWallet->readPassword(config()->name(), password); } else { mWallet->createFolder(ewsWalletFolder); } return password; } -void EwsSettings::onWalletOpenedForRead(bool success) +void EwsSettings::satisfyPasswordReadRequest(bool success) { - qCDebug(EWSRES_LOG) << "onWalletOpenedForRead: start" << success; - mWalletReadTimer.stop(); + if (success) { + if (mPassword.isNull()) { + mPassword = readPassword(); + } + qCDebug(EWSRES_LOG) << "satisfyPasswordReadRequest: got password"; + Q_EMIT passwordRequestFinished(mPassword); + } else { + qCDebug(EWSRES_LOG) << "satisfyPasswordReadRequest: failed to retrieve password"; + Q_EMIT passwordRequestFinished(QString()); + } + mPasswordReadPending = false; +} + +void EwsSettings::satisfyPasswordWriteRequest(bool success) +{ + if (success) { + if (!mWallet->hasFolder(ewsWalletFolder)) { + mWallet->createFolder(ewsWalletFolder); + } + mWallet->setFolder(ewsWalletFolder); + mWallet->writePassword(config()->name(), mPassword); + } + mPasswordWritePending = false; +} + +void EwsSettings::onWalletOpened(bool success) +{ + mWalletTimer.stop(); if (mWallet) { - if (success) { - if (mPassword.isNull()) { - mPassword = readPassword(); - } - qCDebug(EWSRES_LOG) << "onWalletOpenedForRead: got password"; - Q_EMIT passwordRequestFinished(mPassword); - } else { - qCDebug(EWSRES_LOG) << "onWalletOpenedForRead: failed to retrieve password"; - Q_EMIT passwordRequestFinished(QString()); + if (mPasswordReadPending) { + satisfyPasswordReadRequest(success); + } + if (mPasswordWritePending) { + satisfyPasswordWriteRequest(success); } mWallet.clear(); } } void EwsSettings::setPassword(const QString &password) { if (password.isNull()) { qCWarning(EWSRES_LOG) << "Trying to set a null password"; return; } mPassword = password; /* If a pending password request is running, satisfy it. */ - if (mWallet) { - onWalletOpenedForRead(true); + if (mWallet && mPasswordReadPending) { + satisfyPasswordReadRequest(true); } if (mPasswordDlg) { mPasswordDlg->reject(); } - mWallet = Wallet::openWallet(Wallet::NetworkWallet(), - mWindowId, Wallet::Asynchronous); - if (mWallet) { - connect(mWallet.data(), &Wallet::walletOpened, this, &EwsSettings::onWalletOpenedForWrite); - mWalletWriteTimer.start(); - } else { - qCWarning(EWSRES_LOG) << "Failed to open wallet"; - } -} - -void EwsSettings::onWalletOpenedForWrite(bool success) -{ - mWalletWriteTimer.stop(); - if (success) { - if (!mWallet->hasFolder(ewsWalletFolder)) { - mWallet->createFolder(ewsWalletFolder); - } - mWallet->setFolder(ewsWalletFolder); - mWallet->writePassword(config()->name(), mPassword); + if (requestWalletOpen()) { + mPasswordWritePending = true; + return; } - mWallet.clear(); } void EwsSettings::setTestPassword(const QString &password) { if (password.isNull()) { qCWarning(EWSRES_LOG) << "Trying to set a null password"; return; } mPassword = password; if (mWallet) { - onWalletOpenedForRead(true); + satisfyPasswordReadRequest(true); } if (mPasswordDlg) { mPasswordDlg->reject(); } } - diff --git a/resources/ews/ewssettings.h b/resources/ews/ewssettings.h index 90a3a1595..6b91bc004 100644 --- a/resources/ews/ewssettings.h +++ b/resources/ews/ewssettings.h @@ -1,65 +1,71 @@ /* - Copyright (C) 2017 Krzysztof Nowicki + Copyright (C) 2017-2018 Krzysztof Nowicki This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef EWSSETTINGS_H #define EWSSETTINGS_H #ifdef EWSSETTINGS_UNITTEST #include "ewssettings_ut_mock.h" #else #include "ewssettingsbase.h" #endif #include #include namespace KWallet { class Wallet; } class KPasswordDialog; class EwsSettings : public EwsSettingsBase { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.Ews.Wallet") public: explicit EwsSettings(WId windowId); ~EwsSettings() override; void requestPassword(bool ask); public Q_SLOTS: Q_SCRIPTABLE void setPassword(const QString &password); Q_SCRIPTABLE void setTestPassword(const QString &password); Q_SIGNALS: void passwordRequestFinished(const QString &password); private Q_SLOTS: - void onWalletOpenedForRead(bool success); - void onWalletOpenedForWrite(bool success); + void onWalletOpened(bool success); private: QString readPassword() const; + QMap readMap() const; + void satisfyPasswordReadRequest(bool success); + void satisfyPasswordWriteRequest(bool success); + bool requestWalletOpen(); WId mWindowId; + QString mPassword; + bool mPasswordReadPending; + bool mPasswordWritePending; + QPointer mWallet; - QTimer mWalletReadTimer; - QTimer mWalletWriteTimer; + QTimer mWalletTimer; QPointer mPasswordDlg; }; #endif