diff --git a/src/kpasswdserver/autotests/kpasswdservertest.cpp b/src/kpasswdserver/autotests/kpasswdservertest.cpp --- a/src/kpasswdserver/autotests/kpasswdservertest.cpp +++ b/src/kpasswdserver/autotests/kpasswdservertest.cpp @@ -18,23 +18,23 @@ Boston, MA 02110-1301, USA. */ -#include #include -#include -#include #include +#include +#include +#include -static const char* sigQueryAuthInfoResult = SIGNAL(queryAuthInfoAsyncResult(qlonglong,qlonglong,KIO::AuthInfo)); -static const char* sigCheckAuthInfoResult = SIGNAL(checkAuthInfoAsyncResult(qlonglong,qlonglong,KIO::AuthInfo)); +static const char *sigQueryAuthInfoResult = SIGNAL(queryAuthInfoAsyncResult(qlonglong, qlonglong, KIO::AuthInfo)); +static const char *sigCheckAuthInfoResult = SIGNAL(checkAuthInfoAsyncResult(qlonglong, qlonglong, KIO::AuthInfo)); // For the retry dialog (and only that one) static QDialogButtonBox::StandardButton s_buttonYes = QDialogButtonBox::Yes; static QDialogButtonBox::StandardButton s_buttonCancel = QDialogButtonBox::Cancel; Q_DECLARE_METATYPE(QDialogButtonBox::StandardButton) Q_DECLARE_METATYPE(QDialog::DialogCode) -static QString getUserNameFrom(const KIO::AuthInfo& auth) +static QString getUserNameFrom(const KIO::AuthInfo &auth) { if (auth.username.isEmpty() && !auth.url.userName().isEmpty()) { return auth.url.userName(); @@ -103,15 +103,16 @@ QSignalSpy spyQuery(&server, sigQueryAuthInfoResult); const qlonglong windowId = 42; const qlonglong seqNr = 2; - const qlonglong id = server.queryAuthInfoAsync( - info, - QStringLiteral(""), // magic string to avoid a dialog - windowId, seqNr, 16 /*usertime*/); + const qlonglong id = server.queryAuthInfoAsync(info, + QStringLiteral(""), // magic string to avoid a dialog + windowId, + seqNr, + 16 /*usertime*/); // Before it is processed, do a check, it will reply delayed. QSignalSpy spyCheck(&server, sigCheckAuthInfoResult); const qlonglong idCheck = server.checkAuthInfoAsync(info, windowId, 17 /*usertime*/); - QCOMPARE(idCheck, 0LL); // always + QCOMPARE(idCheck, 0LL); // always QCOMPARE(spyCheck.count(), 0); // no reply yet // Wait for the query to be processed @@ -122,7 +123,7 @@ // Now the check will have replied QCOMPARE(spyCheck.count(), 1); - QCOMPARE(spyCheck[0][0].toLongLong(), id+1); // it was the next request after the query + QCOMPARE(spyCheck[0][0].toLongLong(), id + 1); // it was the next request after the query KIO::AuthInfo resultCheck = spyCheck[0][2].value(); QCOMPARE(result.username, resultCheck.username); QCOMPARE(result.password, resultCheck.password); @@ -177,7 +178,7 @@ KPasswdServer server(this); server.setWalletDisabled(true); - // What the app would ask + // What the app would ask KIO::AuthInfo info; info.url = QUrl(QStringLiteral("http://www.example.com")); @@ -201,7 +202,7 @@ KPasswdServer server(this); server.setWalletDisabled(true); - // What the app would ask + // What the app would ask KIO::AuthInfo info; info.url = QUrl(QStringLiteral("http://www.example.com")); @@ -299,10 +300,10 @@ server.setWalletDisabled(true); QList authInfos; - for (int i=0; i < 10; ++i) { - KIO::AuthInfo info; - info.url = QUrl(QLatin1String("http://www.example.com/test") + QString::number(i) + QLatin1String(".html")); - authInfos << info; + for (int i = 0; i < 10; ++i) { + KIO::AuthInfo info; + info.url = QUrl(QLatin1String("http://www.example.com/test") + QString::number(i) + QLatin1String(".html")); + authInfos << info; } // What the user would type @@ -320,10 +321,10 @@ server.setWalletDisabled(true); QList authInfos; - for (int i=0; i < 10; ++i) { - KIO::AuthInfo info; - info.url = QUrl(QLatin1String("http://www.example.com/test") + QString::number(i) + QStringLiteral(".html")); - authInfos << info; + for (int i = 0; i < 10; ++i) { + KIO::AuthInfo info; + info.url = QUrl(QLatin1String("http://www.example.com/test") + QString::number(i) + QStringLiteral(".html")); + authInfos << info; } // What the user would type @@ -337,26 +338,22 @@ private: // Checks that no auth is available for @p info - bool noCheckAuth(KPasswdServer& server, const KIO::AuthInfo& info) + bool noCheckAuth(KPasswdServer &server, const KIO::AuthInfo &info) { KIO::AuthInfo result; checkAuth(server, info, result); - return (result.username == info.username) - && (result.password == info.password) - && !result.isModified(); + return (result.username == info.username) && (result.password == info.password) && !result.isModified(); } // Check that the auth is available and equal to @expectedInfo - bool successCheckAuth(KPasswdServer& server, const KIO::AuthInfo& info, const KIO::AuthInfo& expectedInfo) + bool successCheckAuth(KPasswdServer &server, const KIO::AuthInfo &info, const KIO::AuthInfo &expectedInfo) { KIO::AuthInfo result; checkAuth(server, info, result); - return (result.username == expectedInfo.username) - && (result.password == expectedInfo.password) - && result.isModified(); + return (result.username == expectedInfo.username) && (result.password == expectedInfo.password) && result.isModified(); } - void checkAuth(KPasswdServer& server, const KIO::AuthInfo& info, KIO::AuthInfo& result) + void checkAuth(KPasswdServer &server, const KIO::AuthInfo &info, KIO::AuthInfo &result) { QSignalSpy spy(&server, sigCheckAuthInfoResult); const qlonglong windowId = 42; @@ -368,160 +365,140 @@ QCOMPARE(spy.count(), 1); // kpasswdserver emits a requestId via dbus, we can't get that id here QVERIFY(spy[0][0].toLongLong() >= 0); - //QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr + // QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr result = spy[0][2].value(); } - void queryAuth(KPasswdServer& server, const KIO::AuthInfo& info, KIO::AuthInfo& result) + void queryAuth(KPasswdServer &server, const KIO::AuthInfo &info, KIO::AuthInfo &result) { QSignalSpy spy(&server, sigQueryAuthInfoResult); const qlonglong windowId = 42; const qlonglong seqNr = 2; - const qlonglong id = server.queryAuthInfoAsync( - info, - QStringLiteral(""), // magic string to avoid a dialog - windowId, seqNr, 16 /*usertime*/); + const qlonglong id = server.queryAuthInfoAsync(info, + QStringLiteral(""), // magic string to avoid a dialog + windowId, + seqNr, + 16 /*usertime*/); QVERIFY(id >= 0); // requestId, ever increasing if (spy.isEmpty()) QVERIFY(QSignalSpy(&server, sigQueryAuthInfoResult).wait(1000)); QCOMPARE(spy.count(), 1); QCOMPARE(spy[0][0].toLongLong(), id); - //QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr + // QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr result = spy[0][2].value(); } - void queryAuthWithDialog(KPasswdServer& server, const KIO::AuthInfo& info, - const KIO::AuthInfo& filledInfo, KIO::AuthInfo& result, + void queryAuthWithDialog(KPasswdServer &server, + const KIO::AuthInfo &info, + const KIO::AuthInfo &filledInfo, + KIO::AuthInfo &result, QDialogButtonBox::StandardButton retryButton = s_buttonYes, QDialog::DialogCode code = QDialog::Accepted, - const QString& errMsg = QString()) + const QString &errMsg = QString()) { QSignalSpy spy(&server, sigQueryAuthInfoResult); const qlonglong windowId = 42; const qlonglong seqNr = 2; - const qlonglong id = server.queryAuthInfoAsync( - info, - errMsg, - windowId, seqNr, 16 /*usertime*/); + const qlonglong id = server.queryAuthInfoAsync(info, errMsg, windowId, seqNr, 16 /*usertime*/); QVERIFY(id >= 0); // requestId, ever increasing QVERIFY(spy.isEmpty()); const bool hasErrorMessage = (!errMsg.isEmpty()); const bool isCancelRetryDialogTest = (hasErrorMessage && retryButton == s_buttonCancel); if (hasErrorMessage) { // Retry dialog only knows Yes/No - QMetaObject::invokeMethod(this, "checkRetryDialog", - Qt::QueuedConnection, Q_ARG(QDialogButtonBox::StandardButton, retryButton)); + QMetaObject::invokeMethod(this, "checkRetryDialog", Qt::QueuedConnection, Q_ARG(QDialogButtonBox::StandardButton, retryButton)); } if (!isCancelRetryDialogTest) { - QMetaObject::invokeMethod(this, "checkAndFillDialog", Qt::QueuedConnection, - Q_ARG(KIO::AuthInfo, info), - Q_ARG(KIO::AuthInfo, filledInfo), - Q_ARG(QDialog::DialogCode, code )); + QMetaObject::invokeMethod(this, "checkAndFillDialog", Qt::QueuedConnection, Q_ARG(KIO::AuthInfo, info), Q_ARG(KIO::AuthInfo, filledInfo), Q_ARG(QDialog::DialogCode, code)); } // Force KPasswdServer to process the request now, otherwise the checkAndFillDialog needs a timer too... server.processRequest(); if (spy.isEmpty()) QVERIFY(QSignalSpy(&server, sigQueryAuthInfoResult).wait(1000)); QCOMPARE(spy.count(), 1); QCOMPARE(spy[0][0].toLongLong(), id); - //QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr + // QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr result = spy[0][2].value(); const QString username = (isCancelRetryDialogTest ? QString() : filledInfo.username); const QString password = (isCancelRetryDialogTest ? QString() : filledInfo.password); QCOMPARE(result.username, username); QCOMPARE(result.password, password); - QCOMPARE(result.isModified(), retryButton == s_buttonYes && code == QDialog::Accepted); + QCOMPARE(result.isModified(), retryButton == s_buttonYes && code == QDialog::Accepted); } - void concurrentQueryAuthWithDialog(KPasswdServer& server, const QList& infos, - const KIO::AuthInfo& filledInfo, QList& results, - QDialog::DialogCode code = QDialog::Accepted) + void concurrentQueryAuthWithDialog(KPasswdServer &server, const QList &infos, const KIO::AuthInfo &filledInfo, QList &results, QDialog::DialogCode code = QDialog::Accepted) { QSignalSpy spy(&server, sigQueryAuthInfoResult); const qlonglong windowId = 42; qlonglong seqNr = 0; QList idList; - for (const KIO::AuthInfo& info : infos) { - const qlonglong id = server.queryAuthInfoAsync( - info, - QString(), - windowId, seqNr, 16 /*usertime*/); + for (const KIO::AuthInfo &info : infos) { + const qlonglong id = server.queryAuthInfoAsync(info, QString(), windowId, seqNr, 16 /*usertime*/); QVERIFY(id >= 0); // requestId, ever increasing idList << id; } QVERIFY(spy.isEmpty()); - QMetaObject::invokeMethod(this, "checkAndFillDialog", Qt::QueuedConnection, - Q_ARG(KIO::AuthInfo, infos.first()), - Q_ARG(KIO::AuthInfo,filledInfo), - Q_ARG(QDialog::DialogCode, code)); + QMetaObject::invokeMethod(this, "checkAndFillDialog", Qt::QueuedConnection, Q_ARG(KIO::AuthInfo, infos.first()), Q_ARG(KIO::AuthInfo, filledInfo), Q_ARG(QDialog::DialogCode, code)); // Force KPasswdServer to process the request now, otherwise the checkAndFillDialog needs a timer too... server.processRequest(); while (spy.count() < infos.count()) QVERIFY(QSignalSpy(&server, sigQueryAuthInfoResult).wait(1000)); QCOMPARE(spy.count(), infos.count()); - for(int i = 0, count = spy.count(); i < count; ++i) { + for (int i = 0, count = spy.count(); i < count; ++i) { QCOMPARE(spy[i][0].toLongLong(), idList.at(i)); - //QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr + // QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr KIO::AuthInfo result = spy[i][2].value(); QCOMPARE(result.username, filledInfo.username); QCOMPARE(result.password, filledInfo.password); QCOMPARE(result.isModified(), code == QDialog::Accepted); results << result; } } - void concurrentCheckAuthWithDialog(KPasswdServer& server, const QList& infos, - const KIO::AuthInfo& filledInfo, QList& results, - QDialog::DialogCode code = QDialog::Accepted) + void concurrentCheckAuthWithDialog(KPasswdServer &server, const QList &infos, const KIO::AuthInfo &filledInfo, QList &results, QDialog::DialogCode code = QDialog::Accepted) { QSignalSpy spy(&server, sigQueryAuthInfoResult); const qlonglong windowId = 42; qlonglong seqNr = 0; QList idList; - QListIterator it (infos); + QListIterator it(infos); if (it.hasNext()) { - const qlonglong id = server.queryAuthInfoAsync( - it.next(), - QString(), - windowId, seqNr, 16 /*usertime*/); + const qlonglong id = server.queryAuthInfoAsync(it.next(), QString(), windowId, seqNr, 16 /*usertime*/); QVERIFY(id >= 0); // requestId, ever increasing idList << id; } while (it.hasNext()) { - const qlonglong id = server.checkAuthInfoAsync(it.next(), windowId,16 /*usertime*/); + const qlonglong id = server.checkAuthInfoAsync(it.next(), windowId, 16 /*usertime*/); QVERIFY(id >= 0); // requestId, ever increasing idList << id; } QVERIFY(spy.isEmpty()); - QMetaObject::invokeMethod(this, "checkAndFillDialog", Qt::QueuedConnection, - Q_ARG(KIO::AuthInfo, infos.first()), - Q_ARG(KIO::AuthInfo,filledInfo), - Q_ARG(QDialog::DialogCode, code)); + QMetaObject::invokeMethod(this, "checkAndFillDialog", Qt::QueuedConnection, Q_ARG(KIO::AuthInfo, infos.first()), Q_ARG(KIO::AuthInfo, filledInfo), Q_ARG(QDialog::DialogCode, code)); // Force KPasswdServer to process the request now, otherwise the checkAndFillDialog needs a timer too... server.processRequest(); if (spy.isEmpty()) { QVERIFY(QSignalSpy(&server, sigQueryAuthInfoResult).wait(1000)); } - while ((spy.count()-1) < infos.count()) { + while ((spy.count() - 1) < infos.count()) { QVERIFY(QSignalSpy(&server, sigCheckAuthInfoResult).wait(1000)); } - for(int i = 0, count = spy.count(); i < count; ++i) { + for (int i = 0, count = spy.count(); i < count; ++i) { QCOMPARE(spy[i][0].toLongLong(), idList.at(i)); - //QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr + // QCOMPARE(spy[0][1].toLongLong(), 3LL); // seqNr KIO::AuthInfo result = spy[i][2].value(); QCOMPARE(result.username, filledInfo.username); QCOMPARE(result.password, filledInfo.password); @@ -531,11 +508,11 @@ } protected Q_SLOTS: - void checkAndFillDialog(const KIO::AuthInfo& info, const KIO::AuthInfo& filledInfo, QDialog::DialogCode code) + void checkAndFillDialog(const KIO::AuthInfo &info, const KIO::AuthInfo &filledInfo, QDialog::DialogCode code) { const QList widgetsList = QApplication::topLevelWidgets(); for (QWidget *widget : widgetsList) { - if (KPasswordDialog* dialog = qobject_cast(widget)) { + if (KPasswordDialog *dialog = qobject_cast(widget)) { if (code == QDialog::Accepted) { QCOMPARE(dialog->username(), getUserNameFrom(info)); QCOMPARE(dialog->password(), info.password); @@ -553,7 +530,7 @@ { const QList widgetsList = QApplication::topLevelWidgets(); for (QWidget *widget : widgetsList) { - QDialog* dialog = qobject_cast(widget); + QDialog *dialog = qobject_cast(widget); if (dialog && !dialog->inherits("KPasswordDialog")) { dialog->done(code); return; @@ -563,6 +540,6 @@ } }; -QTEST_MAIN( KPasswdServerTest ) +QTEST_MAIN(KPasswdServerTest) #include "kpasswdservertest.moc" diff --git a/src/kpasswdserver/kiod_kpasswdserver.cpp b/src/kpasswdserver/kiod_kpasswdserver.cpp --- a/src/kpasswdserver/kiod_kpasswdserver.cpp +++ b/src/kpasswdserver/kiod_kpasswdserver.cpp @@ -27,4 +27,3 @@ K_PLUGIN_CLASS_WITH_JSON(KPasswdServer, "kpasswdserver.json") #include "kiod_kpasswdserver.moc" - diff --git a/src/kpasswdserver/kpasswdserver.h b/src/kpasswdserver/kpasswdserver.h --- a/src/kpasswdserver/kpasswdserver.h +++ b/src/kpasswdserver/kpasswdserver.h @@ -25,113 +25,122 @@ #ifndef KPASSWDSERVER_H #define KPASSWDSERVER_H +#include +#include #include #include #include -#include -#include -#include #include +#include -namespace KWallet { - class Wallet; +namespace KWallet +{ +class Wallet; } class KPasswdServer : public KDEDModule, protected QDBusContext { - Q_OBJECT + Q_OBJECT public: - explicit KPasswdServer(QObject* parent, const QList& = QList()); - ~KPasswdServer(); + explicit KPasswdServer(QObject *parent, const QList & = QList()); + ~KPasswdServer(); - // Called by the unit test - void setWalletDisabled(bool d) { m_walletDisabled = d; } + // Called by the unit test + void setWalletDisabled(bool d) + { + m_walletDisabled = d; + } public Q_SLOTS: - qlonglong checkAuthInfoAsync(KIO::AuthInfo, qlonglong, qlonglong); - qlonglong queryAuthInfoAsync(const KIO::AuthInfo &, const QString &, qlonglong, qlonglong, qlonglong); - void addAuthInfo(const KIO::AuthInfo &, qlonglong); - void removeAuthInfo(const QString& host, const QString& protocol, const QString& user); + qlonglong checkAuthInfoAsync(KIO::AuthInfo, qlonglong, qlonglong); + qlonglong queryAuthInfoAsync(const KIO::AuthInfo &, const QString &, qlonglong, qlonglong, qlonglong); + void addAuthInfo(const KIO::AuthInfo &, qlonglong); + void removeAuthInfo(const QString &host, const QString &protocol, const QString &user); - // legacy methods provided for compatibility with old clients - QByteArray checkAuthInfo(const QByteArray &, qlonglong, qlonglong); - QByteArray queryAuthInfo(const QByteArray &, const QString &, qlonglong, qlonglong, qlonglong); - void addAuthInfo(const QByteArray &, qlonglong); + // legacy methods provided for compatibility with old clients + QByteArray checkAuthInfo(const QByteArray &, qlonglong, qlonglong); + QByteArray queryAuthInfo(const QByteArray &, const QString &, qlonglong, qlonglong, qlonglong); + void addAuthInfo(const QByteArray &, qlonglong); - void processRequest(); - // Remove all authentication info associated with windowId - void removeAuthForWindowId(qlonglong windowId); + void processRequest(); + // Remove all authentication info associated with windowId + void removeAuthForWindowId(qlonglong windowId); Q_SIGNALS: - void checkAuthInfoAsyncResult(qlonglong requestId, qlonglong seqNr, const KIO::AuthInfo &); - void queryAuthInfoAsyncResult(qlonglong requestId, qlonglong seqNr, const KIO::AuthInfo &); + void checkAuthInfoAsyncResult(qlonglong requestId, qlonglong seqNr, const KIO::AuthInfo &); + void queryAuthInfoAsyncResult(qlonglong requestId, qlonglong seqNr, const KIO::AuthInfo &); private Q_SLOTS: - void passwordDialogDone(int); - void retryDialogDone(int); - void windowRemoved(WId); + void passwordDialogDone(int); + void retryDialogDone(int); + void windowRemoved(WId); private: - struct AuthInfoContainer { - AuthInfoContainer() : expire( expNever ), seqNr( 0 ), isCanceled( false ) {} - - KIO::AuthInfo info; - QString directory; - - enum { expNever, expWindowClose, expTime } expire; - QList windowList; - qulonglong expireTime; - qlonglong seqNr; - - bool isCanceled; + struct AuthInfoContainer { + AuthInfoContainer() + : expire(expNever) + , seqNr(0) + , isCanceled(false) + { + } + + KIO::AuthInfo info; + QString directory; + + enum { expNever, expWindowClose, expTime } expire; + QList windowList; + qulonglong expireTime; + qlonglong seqNr; + + bool isCanceled; + + struct Sorter { + bool operator()(AuthInfoContainer *n1, AuthInfoContainer *n2) const; + }; + }; - struct Sorter { - bool operator() (AuthInfoContainer* n1, AuthInfoContainer* n2) const; + struct Request { + bool isAsync; // true for async requests + qlonglong requestId; // set for async requests only + QDBusMessage transaction; // set for sync requests only + QString key; + KIO::AuthInfo info; + QString errorMsg; + qlonglong windowId; + qlonglong seqNr; + bool prompt; }; - }; - - struct Request { - bool isAsync; // true for async requests - qlonglong requestId; // set for async requests only - QDBusMessage transaction; // set for sync requests only - QString key; - KIO::AuthInfo info; - QString errorMsg; - qlonglong windowId; - qlonglong seqNr; - bool prompt; - }; - - QString createCacheKey( const KIO::AuthInfo &info ); - const AuthInfoContainer *findAuthInfoItem(const QString &key, const KIO::AuthInfo &info); - void removeAuthInfoItem(const QString &key, const KIO::AuthInfo &info); - void addAuthInfoItem(const QString &key, const KIO::AuthInfo &info, qlonglong windowId, qlonglong seqNr, bool canceled); - void copyAuthInfo(const AuthInfoContainer*, KIO::AuthInfo&); - void updateAuthExpire(const QString &key, const AuthInfoContainer *, qlonglong windowId, bool keep); + + QString createCacheKey(const KIO::AuthInfo &info); + const AuthInfoContainer *findAuthInfoItem(const QString &key, const KIO::AuthInfo &info); + void removeAuthInfoItem(const QString &key, const KIO::AuthInfo &info); + void addAuthInfoItem(const QString &key, const KIO::AuthInfo &info, qlonglong windowId, qlonglong seqNr, bool canceled); + void copyAuthInfo(const AuthInfoContainer *, KIO::AuthInfo &); + void updateAuthExpire(const QString &key, const AuthInfoContainer *, qlonglong windowId, bool keep); #ifdef HAVE_KF5WALLET - bool openWallet( qlonglong windowId ); + bool openWallet(qlonglong windowId); #endif - bool hasPendingQuery(const QString &key, const KIO::AuthInfo &info); - void sendResponse (Request* request); - void showPasswordDialog(Request* request); - void updateCachedRequestKey(QList&, const QString& oldKey, const QString& newKey); - - typedef QList AuthInfoContainerList; - QHash m_authDict; - - QList m_authPending; - QList m_authWait; - QHash mWindowIdList; - QHash m_authInProgress; - QHash m_authRetryInProgress; - QStringList m_authPrompted; - KWallet::Wallet* m_wallet; - bool m_walletDisabled; - qlonglong m_seqNr; + bool hasPendingQuery(const QString &key, const KIO::AuthInfo &info); + void sendResponse(Request *request); + void showPasswordDialog(Request *request); + void updateCachedRequestKey(QList &, const QString &oldKey, const QString &newKey); + + typedef QList AuthInfoContainerList; + QHash m_authDict; + + QList m_authPending; + QList m_authWait; + QHash mWindowIdList; + QHash m_authInProgress; + QHash m_authRetryInProgress; + QStringList m_authPrompted; + KWallet::Wallet *m_wallet; + bool m_walletDisabled; + qlonglong m_seqNr; }; #endif diff --git a/src/kpasswdserver/kpasswdserver.cpp b/src/kpasswdserver/kpasswdserver.cpp --- a/src/kpasswdserver/kpasswdserver.cpp +++ b/src/kpasswdserver/kpasswdserver.cpp @@ -27,11 +27,11 @@ #include "kpasswdserveradaptor.h" +#include #include #include -#include #include -#include +#include #ifdef HAVE_KF5WALLET #include @@ -55,20 +55,18 @@ return nextRequestId++; } -bool -KPasswdServer::AuthInfoContainer::Sorter::operator ()(AuthInfoContainer* n1, AuthInfoContainer* n2) const +bool KPasswdServer::AuthInfoContainer::Sorter::operator()(AuthInfoContainer *n1, AuthInfoContainer *n2) const { - if (!n1 || !n2) - return 0; + if (!n1 || !n2) + return 0; - const int l1 = n1->directory.length(); - const int l2 = n2->directory.length(); - return l1 < l2; + const int l1 = n1->directory.length(); + const int l2 = n2->directory.length(); + return l1 < l2; } - -KPasswdServer::KPasswdServer(QObject* parent, const QList&) - : KDEDModule(parent) +KPasswdServer::KPasswdServer(QObject *parent, const QList &) + : KDEDModule(parent) { KIO::AuthInfo::registerMetaTypes(); @@ -78,16 +76,12 @@ KPasswdServerAdaptor *adaptor = new KPasswdServerAdaptor(this); // connect signals to the adaptor - connect(this, &KPasswdServer::checkAuthInfoAsyncResult, - adaptor, &KPasswdServerAdaptor::checkAuthInfoAsyncResult); - connect(this, &KPasswdServer::queryAuthInfoAsyncResult, - adaptor, &KPasswdServerAdaptor::queryAuthInfoAsyncResult); + connect(this, &KPasswdServer::checkAuthInfoAsyncResult, adaptor, &KPasswdServerAdaptor::checkAuthInfoAsyncResult); + connect(this, &KPasswdServer::queryAuthInfoAsyncResult, adaptor, &KPasswdServerAdaptor::queryAuthInfoAsyncResult); - connect(this, &KDEDModule::windowUnregistered, - this, &KPasswdServer::removeAuthForWindowId); + connect(this, &KDEDModule::windowUnregistered, this, &KPasswdServer::removeAuthForWindowId); - connect(KWindowSystem::self(), &KWindowSystem::windowRemoved, - this, &KPasswdServer::windowRemoved); + connect(KWindowSystem::self(), &KWindowSystem::windowRemoved, this, &KPasswdServer::windowRemoved); } KPasswdServer::~KPasswdServer() @@ -108,86 +102,84 @@ #ifdef HAVE_KF5WALLET // Helper - returns the wallet key to use for read/store/checking for existence. -static QString makeWalletKey( const QString& key, const QString& realm ) +static QString makeWalletKey(const QString &key, const QString &realm) { return realm.isEmpty() ? key : key + QLatin1Char('-') + realm; } // Helper for storeInWallet/readFromWallet -static QString makeMapKey( const char* key, int entryNumber ) +static QString makeMapKey(const char *key, int entryNumber) { - QString str = QLatin1String( key ); - if ( entryNumber > 1 ) - str += QLatin1Char('-') + QString::number( entryNumber ); + QString str = QLatin1String(key); + if (entryNumber > 1) + str += QLatin1Char('-') + QString::number(entryNumber); return str; } -static bool storeInWallet( KWallet::Wallet* wallet, const QString& key, const KIO::AuthInfo &info ) +static bool storeInWallet(KWallet::Wallet *wallet, const QString &key, const KIO::AuthInfo &info) { - if ( !wallet->hasFolder( KWallet::Wallet::PasswordFolder() ) ) - if ( !wallet->createFolder( KWallet::Wallet::PasswordFolder() ) ) + if (!wallet->hasFolder(KWallet::Wallet::PasswordFolder())) + if (!wallet->createFolder(KWallet::Wallet::PasswordFolder())) return false; - wallet->setFolder( KWallet::Wallet::PasswordFolder() ); + wallet->setFolder(KWallet::Wallet::PasswordFolder()); // Before saving, check if there's already an entry with this login. // If so, replace it (with the new password). Otherwise, add a new entry. - typedef QMap Map; + typedef QMap Map; int entryNumber = 1; Map map; - QString walletKey = makeWalletKey( key, info.realmValue ); + QString walletKey = makeWalletKey(key, info.realmValue); qCDebug(category) << "walletKey =" << walletKey << " reading existing map"; - if ( wallet->readMap( walletKey, map ) == 0 ) { + if (wallet->readMap(walletKey, map) == 0) { Map::ConstIterator end = map.constEnd(); - Map::ConstIterator it = map.constFind( QStringLiteral("login") ); - while ( it != end ) { - if ( it.value() == info.username ) { + Map::ConstIterator it = map.constFind(QStringLiteral("login")); + while (it != end) { + if (it.value() == info.username) { break; // OK, overwrite this entry } - it = map.constFind( QStringLiteral( "login-" ) + QString::number( ++entryNumber ) ); + it = map.constFind(QStringLiteral("login-") + QString::number(++entryNumber)); } // If no entry was found, create a new entry - entryNumber is set already. } - const QString loginKey = makeMapKey( "login", entryNumber ); - const QString passwordKey = makeMapKey( "password", entryNumber ); + const QString loginKey = makeMapKey("login", entryNumber); + const QString passwordKey = makeMapKey("password", entryNumber); qCDebug(category) << "writing to " << loginKey << "," << passwordKey; // note the overwrite=true by default - map.insert( loginKey, info.username ); - map.insert( passwordKey, info.password ); - wallet->writeMap( walletKey, map ); + map.insert(loginKey, info.username); + map.insert(passwordKey, info.password); + wallet->writeMap(walletKey, map); return true; } -static bool readFromWallet( KWallet::Wallet* wallet, const QString& key, const QString& realm, QString& username, QString& password, bool userReadOnly, QMap& knownLogins ) +static bool readFromWallet(KWallet::Wallet *wallet, const QString &key, const QString &realm, QString &username, QString &password, bool userReadOnly, QMap &knownLogins) { - //qCDebug(category) << "key =" << key << " username =" << username << " password =" /*<< password*/ << " userReadOnly =" << userReadOnly << " realm =" << realm; - if ( wallet->hasFolder( KWallet::Wallet::PasswordFolder() ) ) - { - wallet->setFolder( KWallet::Wallet::PasswordFolder() ); - - QMap map; - if ( wallet->readMap( makeWalletKey( key, realm ), map ) == 0 ) - { - typedef QMap Map; + // qCDebug(category) << "key =" << key << " username =" << username << " password =" /*<< password*/ << " userReadOnly =" << userReadOnly << " realm =" << realm; + if (wallet->hasFolder(KWallet::Wallet::PasswordFolder())) { + wallet->setFolder(KWallet::Wallet::PasswordFolder()); + + QMap map; + if (wallet->readMap(makeWalletKey(key, realm), map) == 0) { + typedef QMap Map; int entryNumber = 1; Map::ConstIterator end = map.constEnd(); - Map::ConstIterator it = map.constFind( QStringLiteral("login") ); - while ( it != end ) { - //qCDebug(category) << "found " << it.key() << "=" << it.value(); - Map::ConstIterator pwdIter = map.constFind( makeMapKey( "password", entryNumber ) ); - if ( pwdIter != end ) { - if ( it.value() == username ) + Map::ConstIterator it = map.constFind(QStringLiteral("login")); + while (it != end) { + // qCDebug(category) << "found " << it.key() << "=" << it.value(); + Map::ConstIterator pwdIter = map.constFind(makeMapKey("password", entryNumber)); + if (pwdIter != end) { + if (it.value() == username) password = pwdIter.value(); - knownLogins.insert( it.value(), pwdIter.value() ); + knownLogins.insert(it.value(), pwdIter.value()); } - it = map.constFind( QStringLiteral( "login-" ) + QString::number( ++entryNumber ) ); + it = map.constFind(QStringLiteral("login-") + QString::number(++entryNumber)); } - //qCDebug(category) << knownLogins.count() << " known logins"; + // qCDebug(category) << knownLogins.count() << " known logins"; - if ( !userReadOnly && !knownLogins.isEmpty() && username.isEmpty() ) { + if (!userReadOnly && !knownLogins.isEmpty() && username.isEmpty()) { // Pick one, any one... username = knownLogins.begin().key(); password = knownLogins.begin().value(); - //qCDebug(category) << "picked the first one:" << username; + // qCDebug(category) << "picked the first one:" << username; } return true; @@ -200,14 +192,14 @@ bool KPasswdServer::hasPendingQuery(const QString &key, const KIO::AuthInfo &info) { - const QString path2 (info.url.path().left(info.url.path().indexOf(QLatin1Char('/'))+1)); + const QString path2(info.url.path().left(info.url.path().indexOf(QLatin1Char('/')) + 1)); for (const Request *request : qAsConst(m_authPending)) { if (request->key != key) { continue; } if (info.verifyPath) { - const QString path1 (request->info.url.path().left(info.url.path().indexOf(QLatin1Char('/'))+1)); + const QString path1(request->info.url.path().left(info.url.path().indexOf(QLatin1Char('/')) + 1)); if (!path2.startsWith(path1)) { continue; } @@ -231,7 +223,7 @@ // if the check depends on a pending query, delay it // until that query is finished. - const QString key (createCacheKey(info)); + const QString key(createCacheKey(info)); if (hasPendingQuery(key, info)) { setDelayedReply(true); Request *pendingCheck = new Request; @@ -242,28 +234,20 @@ pendingCheck->key = key; pendingCheck->info = info; m_authWait.append(pendingCheck); - return data; // return value will be ignored + return data; // return value will be ignored } // qCDebug(category) << "key =" << key << "user =" << info.username << "windowId =" << windowId; const AuthInfoContainer *result = findAuthInfoItem(key, info); - if (!result || result->isCanceled) - { + if (!result || result->isCanceled) { #ifdef HAVE_KF5WALLET - if (!result && - !m_walletDisabled && - (info.username.isEmpty() || info.password.isEmpty()) && - !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), - KWallet::Wallet::PasswordFolder(), - makeWalletKey(key, info.realmValue))) - { + if (!result && !m_walletDisabled && (info.username.isEmpty() || info.password.isEmpty()) && + !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), KWallet::Wallet::PasswordFolder(), makeWalletKey(key, info.realmValue))) { QMap knownLogins; if (openWallet(windowId)) { - if (readFromWallet(m_wallet, key, info.realmValue, info.username, - info.password, info.readOnly, knownLogins)) - { + if (readFromWallet(m_wallet, key, info.realmValue, info.username, info.password, info.readOnly, knownLogins)) { info.setModified(true); - // fall through + // fall through } } } else { @@ -284,8 +268,7 @@ return data2; } -qlonglong KPasswdServer::checkAuthInfoAsync(KIO::AuthInfo info, qlonglong windowId, - qlonglong usertime) +qlonglong KPasswdServer::checkAuthInfoAsync(KIO::AuthInfo info, qlonglong windowId, qlonglong usertime) { if (usertime != 0) { KUserTimestamp::updateUserTimestamp(usertime); @@ -301,7 +284,7 @@ // if the check depends on a pending query, delay it // until that query is finished. - const QString key (createCacheKey(info)); + const QString key(createCacheKey(info)); if (hasPendingQuery(key, info)) { Request *pendingCheck = new Request; pendingCheck->isAsync = true; @@ -313,23 +296,15 @@ } const AuthInfoContainer *result = findAuthInfoItem(key, info); - if (!result || result->isCanceled) - { + if (!result || result->isCanceled) { #ifdef HAVE_KF5WALLET - if (!result && - !m_walletDisabled && - (info.username.isEmpty() || info.password.isEmpty()) && - !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), - KWallet::Wallet::PasswordFolder(), - makeWalletKey(key, info.realmValue))) - { + if (!result && !m_walletDisabled && (info.username.isEmpty() || info.password.isEmpty()) && + !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), KWallet::Wallet::PasswordFolder(), makeWalletKey(key, info.realmValue))) { QMap knownLogins; if (openWallet(windowId)) { - if (readFromWallet(m_wallet, key, info.realmValue, info.username, - info.password, info.readOnly, knownLogins)) - { + if (readFromWallet(m_wallet, key, info.realmValue, info.username, info.password, info.readOnly, knownLogins)) { info.setModified(true); - // fall through + // fall through } } } else { @@ -349,65 +324,57 @@ } // deprecated method, not used anymore. TODO KF6: REMOVE -QByteArray KPasswdServer::queryAuthInfo(const QByteArray &data, const QString &errorMsg, - qlonglong windowId, qlonglong seqNr, qlonglong usertime) +QByteArray KPasswdServer::queryAuthInfo(const QByteArray &data, const QString &errorMsg, qlonglong windowId, qlonglong seqNr, qlonglong usertime) { KIO::AuthInfo info; QDataStream stream(data); stream >> info; - qCDebug(category) << "User =" << info.username << ", WindowId =" << windowId - << "seqNr =" << seqNr << ", errorMsg =" << errorMsg; + qCDebug(category) << "User =" << info.username << ", WindowId =" << windowId << "seqNr =" << seqNr << ", errorMsg =" << errorMsg; - if ( !info.password.isEmpty() ) { // should we really allow the caller to pre-fill the password? + if (!info.password.isEmpty()) { // should we really allow the caller to pre-fill the password? qCDebug(category) << "password was set by caller"; } if (usertime != 0) { KUserTimestamp::updateUserTimestamp(usertime); } - const QString key (createCacheKey(info)); + const QString key(createCacheKey(info)); Request *request = new Request; setDelayedReply(true); request->isAsync = false; request->transaction = message(); request->key = key; request->info = info; request->windowId = windowId; request->seqNr = seqNr; - if (errorMsg == QLatin1String("")) - { - request->errorMsg.clear(); - request->prompt = false; - } - else - { - request->errorMsg = errorMsg; - request->prompt = true; + if (errorMsg == QLatin1String("")) { + request->errorMsg.clear(); + request->prompt = false; + } else { + request->errorMsg = errorMsg; + request->prompt = true; } m_authPending.append(request); if (m_authPending.count() == 1) - QTimer::singleShot(0, this, &KPasswdServer::processRequest); + QTimer::singleShot(0, this, &KPasswdServer::processRequest); - return QByteArray(); // return value is going to be ignored + return QByteArray(); // return value is going to be ignored } -qlonglong -KPasswdServer::queryAuthInfoAsync(const KIO::AuthInfo &info, const QString &errorMsg, - qlonglong windowId, qlonglong seqNr, qlonglong usertime) +qlonglong KPasswdServer::queryAuthInfoAsync(const KIO::AuthInfo &info, const QString &errorMsg, qlonglong windowId, qlonglong seqNr, qlonglong usertime) { - qCDebug(category) << "User =" << info.username << ", WindowId =" << windowId - << "seqNr =" << seqNr << ", errorMsg =" << errorMsg; + qCDebug(category) << "User =" << info.username << ", WindowId =" << windowId << "seqNr =" << seqNr << ", errorMsg =" << errorMsg; if (!info.password.isEmpty()) { qCDebug(category) << "password was set by caller"; } if (usertime != 0) { KUserTimestamp::updateUserTimestamp(usertime); } - const QString key (createCacheKey(info)); + const QString key(createCacheKey(info)); Request *request = new Request; request->isAsync = true; request->requestId = getRequestId(); @@ -431,20 +398,19 @@ return request->requestId; } -void -KPasswdServer::addAuthInfo(const KIO::AuthInfo &info, qlonglong windowId) +void KPasswdServer::addAuthInfo(const KIO::AuthInfo &info, qlonglong windowId) { qCDebug(category) << "User =" << info.username << ", Realm =" << info.realmValue << ", WindowId =" << windowId; - const QString key (createCacheKey(info)); + const QString key(createCacheKey(info)); m_seqNr++; #ifdef HAVE_KF5WALLET if (!m_walletDisabled && openWallet(windowId) && storeInWallet(m_wallet, key, info)) { // Since storing the password in the wallet succeeded, make sure the // password information is stored in memory only for the duration the // windows associated with it are still around. - KIO::AuthInfo authToken (info); + KIO::AuthInfo authToken(info); authToken.keepPassword = false; addAuthInfoItem(key, authToken, windowId, m_seqNr, false); return; @@ -463,64 +429,54 @@ addAuthInfo(info, windowId); } -void -KPasswdServer::removeAuthInfo(const QString& host, const QString& protocol, const QString& user) +void KPasswdServer::removeAuthInfo(const QString &host, const QString &protocol, const QString &user) { qCDebug(category) << protocol << host << user; - QHashIterator< QString, AuthInfoContainerList* > dictIterator(m_authDict); - while (dictIterator.hasNext()) - { + QHashIterator dictIterator(m_authDict); + while (dictIterator.hasNext()) { dictIterator.next(); const AuthInfoContainerList *authList = dictIterator.value(); if (!authList) continue; for (const AuthInfoContainer *current : *authList) { - qCDebug(category) << "Evaluating: " << current->info.url.scheme() - << current->info.url.host() - << current->info.username; - if (current->info.url.scheme() == protocol && - current->info.url.host() == host && - (current->info.username == user || user.isEmpty())) - { + qCDebug(category) << "Evaluating: " << current->info.url.scheme() << current->info.url.host() << current->info.username; + if (current->info.url.scheme() == protocol && current->info.url.host() == host && (current->info.username == user || user.isEmpty())) { qCDebug(category) << "Removing this entry"; removeAuthInfoItem(dictIterator.key(), current->info); } } } } #ifdef HAVE_KF5WALLET -bool -KPasswdServer::openWallet( qlonglong windowId ) +bool KPasswdServer::openWallet(qlonglong windowId) { - if ( m_wallet && !m_wallet->isOpen() ) { // forced closed + if (m_wallet && !m_wallet->isOpen()) { // forced closed delete m_wallet; m_wallet = nullptr; } - if ( !m_wallet ) - m_wallet = KWallet::Wallet::openWallet( - KWallet::Wallet::NetworkWallet(), (WId)(windowId)); + if (!m_wallet) + m_wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), (WId)(windowId)); return m_wallet != nullptr; } #endif -void -KPasswdServer::processRequest() +void KPasswdServer::processRequest() { if (m_authPending.isEmpty()) { return; } - QScopedPointer request (m_authPending.takeFirst()); + QScopedPointer request(m_authPending.takeFirst()); // Prevent multiple prompts originating from the same window or the same // key (server address). const QString windowIdStr = QString::number(request->windowId); if (m_authPrompted.contains(windowIdStr) || m_authPrompted.contains(request->key)) { - m_authPending.prepend(request.take()); // put it back. + m_authPending.prepend(request.take()); // put it back. return; } @@ -540,39 +496,29 @@ const AuthInfoContainer *result = findAuthInfoItem(request->key, request->info); qCDebug(category) << "key=" << request->key << ", user=" << info.username << "seqNr: request=" << request->seqNr << ", result=" << (result ? result->seqNr : -1); - if (!bypassCacheAndKWallet && result && (request->seqNr < result->seqNr)) - { + if (!bypassCacheAndKWallet && result && (request->seqNr < result->seqNr)) { qCDebug(category) << "auto retry!"; - if (result->isCanceled) - { - info.setModified(false); - } - else - { - updateAuthExpire(request->key, result, request->windowId, false); - copyAuthInfo(result, info); + if (result->isCanceled) { + info.setModified(false); + } else { + updateAuthExpire(request->key, result, request->windowId, false); + copyAuthInfo(result, info); } - } - else - { + } else { m_seqNr++; - if (result && !request->errorMsg.isEmpty()) - { - const QString prompt = request->errorMsg.trimmed() + QLatin1Char('\n') + - i18n("Do you want to retry?"); + if (result && !request->errorMsg.isEmpty()) { + const QString prompt = request->errorMsg.trimmed() + QLatin1Char('\n') + i18n("Do you want to retry?"); - QDialog* dlg = new QDialog; + QDialog *dlg = new QDialog; connect(dlg, &QDialog::finished, this, &KPasswdServer::retryDialogDone); connect(this, &QObject::destroyed, dlg, &QObject::deleteLater); dlg->setWindowTitle(i18n("Retry Authentication")); dlg->setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-password"))); dlg->setObjectName(QStringLiteral("warningOKCancel")); - QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Yes | QDialogButtonBox::Cancel); buttonBox->button(QDialogButtonBox::Yes)->setText(i18nc("@action:button filter-continue", "Retry")); - KMessageBox::createKMessageBox(dlg, buttonBox, QMessageBox::Warning, prompt, - QStringList(), QString(), nullptr, - (KMessageBox::Notify | KMessageBox::NoExec)); + KMessageBox::createKMessageBox(dlg, buttonBox, QMessageBox::Warning, prompt, QStringList(), QString(), nullptr, (KMessageBox::Notify | KMessageBox::NoExec)); dlg->setAttribute(Qt::WA_NativeWindow, true); KWindowSystem::setMainWindow(dlg->windowHandle(), request->windowId); @@ -583,223 +529,185 @@ return; } - if (request->prompt) - { + if (request->prompt) { showPasswordDialog(request.take()); return; - } - else - { - if (!bypassCacheAndKWallet && request->prompt) - { + } else { + if (!bypassCacheAndKWallet && request->prompt) { addAuthInfoItem(request->key, info, 0, m_seqNr, true); } - info.setModified( false ); + info.setModified(false); } } sendResponse(request.data()); } -QString KPasswdServer::createCacheKey( const KIO::AuthInfo &info ) +QString KPasswdServer::createCacheKey(const KIO::AuthInfo &info) { - if( !info.url.isValid() ) { + if (!info.url.isValid()) { // Note that a null key will break findAuthInfoItem later on... - qCWarning(category) << "createCacheKey: invalid URL " << info.url ; + qCWarning(category) << "createCacheKey: invalid URL " << info.url; return QString(); } // Generate the basic key sequence. QString key = info.url.scheme(); key += QLatin1Char('-'); - if (!info.url.userName().isEmpty()) - { - key += info.url.userName() + QLatin1Char('@'); + if (!info.url.userName().isEmpty()) { + key += info.url.userName() + QLatin1Char('@'); } key += info.url.host(); int port = info.url.port(); - if( port ) - { - key += QLatin1Char(':') + QString::number(port); + if (port) { + key += QLatin1Char(':') + QString::number(port); } return key; } -void KPasswdServer::copyAuthInfo(const AuthInfoContainer *i, KIO::AuthInfo& info) +void KPasswdServer::copyAuthInfo(const AuthInfoContainer *i, KIO::AuthInfo &info) { info = i->info; info.setModified(true); } -const KPasswdServer::AuthInfoContainer * -KPasswdServer::findAuthInfoItem(const QString &key, const KIO::AuthInfo &info) +const KPasswdServer::AuthInfoContainer *KPasswdServer::findAuthInfoItem(const QString &key, const KIO::AuthInfo &info) { - // qCDebug(category) << "key=" << key << ", user=" << info.username; - - AuthInfoContainerList *authList = m_authDict.value(key); - if (authList) - { - QString path2 = info.url.path().left(info.url.path().indexOf(QLatin1Char('/'))+1); - auto it = authList->begin(); - while (it != authList->end()) { - AuthInfoContainer *current = (*it); - if (current->expire == AuthInfoContainer::expTime && - static_cast(time(nullptr)) > current->expireTime) { - delete current; - it = authList->erase(it); - continue; - } - - if (info.verifyPath) - { - QString path1 = current->directory; - if (path2.startsWith(path1) && - (info.username.isEmpty() || info.username == current->info.username)) - return current; - } - else - { - if (current->info.realmValue == info.realmValue && - (info.username.isEmpty() || info.username == current->info.username)) - return current; // TODO: Update directory info, - } - - ++it; - } - } - return nullptr; + // qCDebug(category) << "key=" << key << ", user=" << info.username; + + AuthInfoContainerList *authList = m_authDict.value(key); + if (authList) { + QString path2 = info.url.path().left(info.url.path().indexOf(QLatin1Char('/')) + 1); + auto it = authList->begin(); + while (it != authList->end()) { + AuthInfoContainer *current = (*it); + if (current->expire == AuthInfoContainer::expTime && static_cast(time(nullptr)) > current->expireTime) { + delete current; + it = authList->erase(it); + continue; + } + + if (info.verifyPath) { + QString path1 = current->directory; + if (path2.startsWith(path1) && (info.username.isEmpty() || info.username == current->info.username)) + return current; + } else { + if (current->info.realmValue == info.realmValue && (info.username.isEmpty() || info.username == current->info.username)) + return current; // TODO: Update directory info, + } + + ++it; + } + } + return nullptr; } -void -KPasswdServer::removeAuthInfoItem(const QString &key, const KIO::AuthInfo &info) +void KPasswdServer::removeAuthInfoItem(const QString &key, const KIO::AuthInfo &info) { - AuthInfoContainerList *authList = m_authDict.value(key); - if (!authList) - return; - - auto it = authList->begin(); - while (it != authList->end()) { - if ((*it)->info.realmValue == info.realmValue) { - delete (*it); - it = authList->erase(it); - } else { - ++it; - } - } - if (authList->isEmpty()) - { - delete m_authDict.take(key); - } -} + AuthInfoContainerList *authList = m_authDict.value(key); + if (!authList) + return; + auto it = authList->begin(); + while (it != authList->end()) { + if ((*it)->info.realmValue == info.realmValue) { + delete (*it); + it = authList->erase(it); + } else { + ++it; + } + } + if (authList->isEmpty()) { + delete m_authDict.take(key); + } +} -void -KPasswdServer::addAuthInfoItem(const QString &key, const KIO::AuthInfo &info, qlonglong windowId, qlonglong seqNr, bool canceled) +void KPasswdServer::addAuthInfoItem(const QString &key, const KIO::AuthInfo &info, qlonglong windowId, qlonglong seqNr, bool canceled) { - qCDebug(category) << "key=" << key - << "window-id=" << windowId - << "username=" << info.username - << "realm=" << info.realmValue - << "seqNr=" << seqNr - << "keepPassword?" << info.keepPassword - << "canceled?" << canceled; - AuthInfoContainerList *authList = m_authDict.value(key); - if (!authList) - { - authList = new AuthInfoContainerList; - m_authDict.insert(key, authList); - } - AuthInfoContainer *authItem = nullptr; - auto it = authList->begin(); - while (it != authList->end()) { - if ((*it)->info.realmValue == info.realmValue) { - authItem = (*it); - it = authList->erase(it); - break; - } else { - ++it; - } - } - - if (!authItem) - { - qCDebug(category) << "Creating AuthInfoContainer"; - authItem = new AuthInfoContainer; - authItem->expire = AuthInfoContainer::expTime; - } - - authItem->info = info; - authItem->directory = info.url.path().left(info.url.path().indexOf(QLatin1Char('/'))+1); - authItem->seqNr = seqNr; - authItem->isCanceled = canceled; - - updateAuthExpire(key, authItem, windowId, (info.keepPassword && !canceled)); - - // Insert into list, keep the list sorted "longest path" first. - authList->append(authItem); - std::sort(authList->begin(), authList->end(), AuthInfoContainer::Sorter()); + qCDebug(category) << "key=" << key << "window-id=" << windowId << "username=" << info.username << "realm=" << info.realmValue << "seqNr=" << seqNr << "keepPassword?" << info.keepPassword << "canceled?" << canceled; + AuthInfoContainerList *authList = m_authDict.value(key); + if (!authList) { + authList = new AuthInfoContainerList; + m_authDict.insert(key, authList); + } + AuthInfoContainer *authItem = nullptr; + auto it = authList->begin(); + while (it != authList->end()) { + if ((*it)->info.realmValue == info.realmValue) { + authItem = (*it); + it = authList->erase(it); + break; + } else { + ++it; + } + } + + if (!authItem) { + qCDebug(category) << "Creating AuthInfoContainer"; + authItem = new AuthInfoContainer; + authItem->expire = AuthInfoContainer::expTime; + } + + authItem->info = info; + authItem->directory = info.url.path().left(info.url.path().indexOf(QLatin1Char('/')) + 1); + authItem->seqNr = seqNr; + authItem->isCanceled = canceled; + + updateAuthExpire(key, authItem, windowId, (info.keepPassword && !canceled)); + + // Insert into list, keep the list sorted "longest path" first. + authList->append(authItem); + std::sort(authList->begin(), authList->end(), AuthInfoContainer::Sorter()); } -void -KPasswdServer::updateAuthExpire(const QString &key, const AuthInfoContainer *auth, qlonglong windowId, bool keep) +void KPasswdServer::updateAuthExpire(const QString &key, const AuthInfoContainer *auth, qlonglong windowId, bool keep) { - AuthInfoContainer *current = const_cast(auth); - Q_ASSERT(current); - - qCDebug(category) << "key=" << key << "expire=" << current->expire << "window-id=" << windowId << "keep=" << keep; - - if (keep && !windowId) - { - current->expire = AuthInfoContainer::expNever; - } - else if (windowId && (current->expire != AuthInfoContainer::expNever)) - { - current->expire = AuthInfoContainer::expWindowClose; - if (!current->windowList.contains(windowId)) - current->windowList.append(windowId); - } - else if (current->expire == AuthInfoContainer::expTime) - { - current->expireTime = time(nullptr) + 10; - } - - // Update mWindowIdList - if (windowId) - { - QStringList& keysChanged = mWindowIdList[windowId]; // find or insert - if (!keysChanged.contains(key)) - keysChanged.append(key); - } + AuthInfoContainer *current = const_cast(auth); + Q_ASSERT(current); + + qCDebug(category) << "key=" << key << "expire=" << current->expire << "window-id=" << windowId << "keep=" << keep; + + if (keep && !windowId) { + current->expire = AuthInfoContainer::expNever; + } else if (windowId && (current->expire != AuthInfoContainer::expNever)) { + current->expire = AuthInfoContainer::expWindowClose; + if (!current->windowList.contains(windowId)) + current->windowList.append(windowId); + } else if (current->expire == AuthInfoContainer::expTime) { + current->expireTime = time(nullptr) + 10; + } + + // Update mWindowIdList + if (windowId) { + QStringList &keysChanged = mWindowIdList[windowId]; // find or insert + if (!keysChanged.contains(key)) + keysChanged.append(key); + } } -void -KPasswdServer::removeAuthForWindowId(qlonglong windowId) +void KPasswdServer::removeAuthForWindowId(qlonglong windowId) { - const QStringList keysChanged = mWindowIdList.value(windowId); - for (const QString &key : keysChanged) - { - AuthInfoContainerList *authList = m_authDict.value(key); - if (!authList) - continue; - - QMutableListIterator it (*authList); - while (it.hasNext()) - { - AuthInfoContainer* current = it.next(); - if (current->expire == AuthInfoContainer::expWindowClose) - { - if (current->windowList.removeAll(windowId) && current->windowList.isEmpty()) - { - delete current; - it.remove(); - } + const QStringList keysChanged = mWindowIdList.value(windowId); + for (const QString &key : keysChanged) { + AuthInfoContainerList *authList = m_authDict.value(key); + if (!authList) + continue; + + QMutableListIterator it(*authList); + while (it.hasNext()) { + AuthInfoContainer *current = it.next(); + if (current->expire == AuthInfoContainer::expWindowClose) { + if (current->windowList.removeAll(windowId) && current->windowList.isEmpty()) { + delete current; + it.remove(); + } + } } - } - } + } } -void KPasswdServer::showPasswordDialog (KPasswdServer::Request* request) +void KPasswdServer::showPasswordDialog(KPasswdServer::Request *request) { KIO::AuthInfo &info = request->info; QString username = info.username; @@ -809,36 +717,29 @@ #ifdef HAVE_KF5WALLET const bool bypassCacheAndKWallet = info.getExtraField(AUTHINFO_EXTRAFIELD_BYPASS_CACHE_AND_KWALLET).toBool(); - if ( !bypassCacheAndKWallet - && ( username.isEmpty() || password.isEmpty() ) - && !m_walletDisabled - && !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), KWallet::Wallet::PasswordFolder(), makeWalletKey( request->key, info.realmValue )) ) - { + if (!bypassCacheAndKWallet && (username.isEmpty() || password.isEmpty()) && !m_walletDisabled && + !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), KWallet::Wallet::PasswordFolder(), makeWalletKey(request->key, info.realmValue))) { // no login+pass provided, check if kwallet has one - if ( openWallet( request->windowId ) ) - hasWalletData = readFromWallet( m_wallet, request->key, info.realmValue, username, password, info.readOnly, knownLogins ); + if (openWallet(request->windowId)) + hasWalletData = readFromWallet(m_wallet, request->key, info.realmValue, username, password, info.readOnly, knownLogins); } #endif // assemble dialog-flags KPasswordDialog::KPasswordDialogFlags dialogFlags; - if (info.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) - { + if (info.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) { dialogFlags |= KPasswordDialog::ShowDomainLine; - if (info.getExtraFieldFlags(AUTHINFO_EXTRAFIELD_DOMAIN) & KIO::AuthInfo::ExtraFieldReadOnly) - { + if (info.getExtraFieldFlags(AUTHINFO_EXTRAFIELD_DOMAIN) & KIO::AuthInfo::ExtraFieldReadOnly) { dialogFlags |= KPasswordDialog::DomainReadOnly; } } - if (info.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid()) - { + if (info.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid()) { dialogFlags |= KPasswordDialog::ShowAnonymousLoginCheckBox; } - if (!info.getExtraField(AUTHINFO_EXTRAFIELD_HIDE_USERNAME_INPUT).toBool()) - { + if (!info.getExtraField(AUTHINFO_EXTRAFIELD_HIDE_USERNAME_INPUT).toBool()) { dialogFlags |= KPasswordDialog::ShowUsernameLine; } @@ -852,35 +753,35 @@ // instantiate dialog qCDebug(category) << "Widget for" << request->windowId << QWidget::find(request->windowId); - KPasswordDialog* dlg = new KPasswordDialog(nullptr, dialogFlags); + KPasswordDialog *dlg = new KPasswordDialog(nullptr, dialogFlags); connect(dlg, &QDialog::finished, this, &KPasswdServer::passwordDialogDone); connect(this, &QObject::destroyed, dlg, &QObject::deleteLater); dlg->setPrompt(info.prompt); dlg->setUsername(username); if (info.caption.isEmpty()) - dlg->setWindowTitle( i18n("Authentication Dialog") ); + dlg->setWindowTitle(i18n("Authentication Dialog")); else - dlg->setWindowTitle( info.caption ); + dlg->setWindowTitle(info.caption); - if ( !info.comment.isEmpty() ) - dlg->addCommentLine( info.commentLabel, info.comment ); + if (!info.comment.isEmpty()) + dlg->addCommentLine(info.commentLabel, info.comment); - if ( !password.isEmpty() ) - dlg->setPassword( password ); + if (!password.isEmpty()) + dlg->setPassword(password); if (info.readOnly) - dlg->setUsernameReadOnly( true ); + dlg->setUsernameReadOnly(true); else - dlg->setKnownLogins( knownLogins ); + dlg->setKnownLogins(knownLogins); if (hasWalletData) - dlg->setKeepPassword( true ); + dlg->setKeepPassword(true); - if (info.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid ()) + if (info.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) dlg->setDomain(info.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).toString()); - if (info.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid () && password.isEmpty() && username.isEmpty()) + if (info.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid() && password.isEmpty() && username.isEmpty()) dlg->setAnonymousMode(info.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).toBool()); #ifndef Q_OS_MACOS @@ -895,8 +796,7 @@ dlg->open(); } - -void KPasswdServer::sendResponse (KPasswdServer::Request* request) +void KPasswdServer::sendResponse(KPasswdServer::Request *request) { Q_ASSERT(request); if (!request) { @@ -915,26 +815,21 @@ // Check all requests in the wait queue. Request *waitRequest; - QMutableListIterator it(m_authWait); + QMutableListIterator it(m_authWait); while (it.hasNext()) { waitRequest = it.next(); - if (!hasPendingQuery(waitRequest->key, waitRequest->info)) - { - const AuthInfoContainer *result = findAuthInfoItem(waitRequest->key, - waitRequest->info); + if (!hasPendingQuery(waitRequest->key, waitRequest->info)) { + const AuthInfoContainer *result = findAuthInfoItem(waitRequest->key, waitRequest->info); QByteArray replyData; QDataStream stream2(&replyData, QIODevice::WriteOnly); KIO::AuthInfo rcinfo; - if (!result || result->isCanceled) - { + if (!result || result->isCanceled) { waitRequest->info.setModified(false); stream2 << waitRequest->info; - } - else - { + } else { updateAuthExpire(waitRequest->key, result, waitRequest->windowId, false); copyAuthInfo(result, rcinfo); stream2 << rcinfo; @@ -956,19 +851,19 @@ m_authPrompted.removeAll(request->key); if (!m_authPending.isEmpty()) - QTimer::singleShot(0, this, &KPasswdServer::processRequest); + QTimer::singleShot(0, this, &KPasswdServer::processRequest); } void KPasswdServer::passwordDialogDone(int result) { - KPasswordDialog* dlg = qobject_cast(sender()); + KPasswordDialog *dlg = qobject_cast(sender()); Q_ASSERT(dlg); - QScopedPointer request (m_authInProgress.take(dlg)); - Q_ASSERT(request); // request should never be nullptr. + QScopedPointer request(m_authInProgress.take(dlg)); + Q_ASSERT(request); // request should never be nullptr. if (request) { - KIO::AuthInfo& info = request->info; + KIO::AuthInfo &info = request->info; const bool bypassCacheAndKWallet = info.getExtraField(AUTHINFO_EXTRAFIELD_BYPASS_CACHE_AND_KWALLET).toBool(); qCDebug(category) << "dialog result=" << result << ", bypassCacheAndKWallet?" << bypassCacheAndKWallet; @@ -978,9 +873,9 @@ info.password = dlg->password(); info.keepPassword = dlg->keepPassword(); - if (info.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid ()) + if (info.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) info.setExtraField(AUTHINFO_EXTRAFIELD_DOMAIN, dlg->domain()); - if (info.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid ()) + if (info.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid()) info.setExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS, dlg->anonymousMode()); // When the user checks "keep password", that means: @@ -1012,19 +907,19 @@ #ifdef HAVE_KF5WALLET const bool skipAutoCaching = info.getExtraField(AUTHINFO_EXTRAFIELD_SKIP_CACHING_ON_QUERY).toBool(); if (!skipAutoCaching && info.keepPassword && openWallet(request->windowId)) { - if ( storeInWallet( m_wallet, request->key, info ) ) + if (storeInWallet(m_wallet, request->key, info)) // password is in wallet, don't keep it in memory after window is closed info.keepPassword = false; } #endif addAuthInfoItem(request->key, info, request->windowId, m_seqNr, false); } - info.setModified( true ); + info.setModified(true); } else { if (!bypassCacheAndKWallet && request->prompt) { addAuthInfoItem(request->key, info, 0, m_seqNr, true); } - info.setModified( false ); + info.setModified(false); } sendResponse(request.data()); @@ -1035,10 +930,10 @@ void KPasswdServer::retryDialogDone(int result) { - QDialog* dlg = qobject_cast(sender()); + QDialog *dlg = qobject_cast(sender()); Q_ASSERT(dlg); - QScopedPointer request (m_authRetryInProgress.take(dlg)); + QScopedPointer request(m_authRetryInProgress.take(dlg)); Q_ASSERT(request); if (request) { @@ -1051,25 +946,25 @@ // and used subsequently. // // TODO: decide whether it should be removed from the wallet too. - KIO::AuthInfo& info = request->info; + KIO::AuthInfo &info = request->info; removeAuthInfoItem(request->key, request->info); info.setModified(false); sendResponse(request.data()); } } } -void KPasswdServer::windowRemoved (WId id) +void KPasswdServer::windowRemoved(WId id) { bool foundMatch = false; if (!m_authInProgress.isEmpty()) { const qlonglong windowId = (qlonglong)(id); - QMutableHashIterator it (m_authInProgress); + QMutableHashIterator it(m_authInProgress); while (it.hasNext()) { it.next(); if (it.value()->windowId == windowId) { - Request* request = it.value(); - QObject* obj = it.key(); + Request *request = it.value(); + QObject *obj = it.key(); it.remove(); m_authPrompted.removeAll(QString::number(request->windowId)); m_authPrompted.removeAll(request->key); @@ -1082,28 +977,27 @@ if (!foundMatch && !m_authRetryInProgress.isEmpty()) { const qlonglong windowId = (qlonglong)(id); - QMutableHashIterator it (m_authRetryInProgress); + QMutableHashIterator it(m_authRetryInProgress); while (it.hasNext()) { it.next(); if (it.value()->windowId == windowId) { - Request* request = it.value(); - QObject* obj = it.key(); + Request *request = it.value(); + QObject *obj = it.key(); it.remove(); delete obj; delete request; } } } } -void KPasswdServer::updateCachedRequestKey (QList& list, const QString& oldKey, const QString& newKey) +void KPasswdServer::updateCachedRequestKey(QList &list, const QString &oldKey, const QString &newKey) { - QListIterator it (list); + QListIterator it(list); while (it.hasNext()) { - Request* r = it.next(); + Request *r = it.next(); if (r->key == oldKey) { r->key = newKey; } } } -