Git commit e01af01e7c2f8ee47d607ffadd36e59f6563ce4d by David Faure. Committed on 31/12/2016 at 20:30. Pushed by dfaure into branch 'master'. KIO: improve and export KPasswdServerClient class, the client API for kpass= wdserver. I need it in webenginepart to handle authenticationRequired(), since webeng= ine doesn't use kioslaves. This commit includes: - moving the handling of sequence numbers into the class, for convenience a= nd encapsulation - finishing to document all parameters to the methods - pass info as pointer rather than ref - moving KPasswdServerClient outside of the KIO namespace (since it already= has a K prefix, both would look weird) REVIEW: 129638 M +1 -0 src/core/CMakeLists.txt M +41 -19 src/core/kpasswdserverclient.cpp R +33 -22 src/core/kpasswdserverclient.h [from: src/core/kpasswdserver= client_p.h - 056% similarity] M +2 -7 src/core/kpasswdserverloop.cpp M +2 -7 src/core/kpasswdserverloop_p.h M +6 -17 src/core/slavebase.cpp https://commits.kde.org/kio/e01af01e7c2f8ee47d607ffadd36e59f6563ce4d diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d298e54c..f2dd0891 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -239,6 +239,7 @@ ecm_generate_headers(KIOCore_HEADERS KNFSShare KSambaShare KSambaShareData + KPasswdServerClient KProtocolInfo KProtocolManager KRecentDocument diff --git a/src/core/kpasswdserverclient.cpp b/src/core/kpasswdserverclien= t.cpp index ad7ed329..5c58ed84 100644 --- a/src/core/kpasswdserverclient.cpp +++ b/src/core/kpasswdserverclient.cpp @@ -19,9 +19,10 @@ * License along with this library. If not, see . */ = -#include "kpasswdserverclient_p.h" +#include "kpasswdserverclient.h" #include "kiocoredebug.h" = +#include #include #include #include @@ -29,22 +30,31 @@ #include "kpasswdserverloop_p.h" #include "kpasswdserver_interface.h" = -namespace KIO +class KPasswdServerClientPrivate { +public: + KPasswdServerClientPrivate() + : seqNr(0) {} + + qlonglong seqNr; + QString lastHost; +}; = KPasswdServerClient::KPasswdServerClient() : m_interface(new OrgKdeKPasswdServerInterface(QStringLiteral("org.kde= .kpasswdserver"), QStringLiteral("/modules/kpasswdserver"), - QDBusConnection::sessionBus())) + QDBusConnection::sessionBus())), + d(new KPasswdServerClientPrivate) { } = KPasswdServerClient::~KPasswdServerClient() { delete m_interface; + delete d; } = -bool KPasswdServerClient::checkAuthInfo(KIO::AuthInfo &info, qlonglong win= dowId, +bool KPasswdServerClient::checkAuthInfo(KIO::AuthInfo *info, qlonglong win= dowId, qlonglong usertime) { //qDebug() << "window-id=3D" << windowId << "url=3D" << info.url; @@ -59,7 +69,7 @@ bool KPasswdServerClient::checkAuthInfo(KIO::AuthInfo &in= fo, qlonglong windowId, QObject::connect(m_interface, SIGNAL(checkAuthInfoAsyncResult(qlonglon= g,qlonglong,KIO::AuthInfo)), &loop, SLOT(slotQueryResult(qlonglong,qlonglong,KIO::= AuthInfo))); = - QDBusReply reply =3D m_interface->checkAuthInfoAsync(info, = windowId, + QDBusReply reply =3D m_interface->checkAuthInfoAsync(*info,= windowId, usertime); if (!reply.isValid()) { qCWarning(KIO_CORE) << "Can't communicate with kiod_kpasswdserver = (for checkAuthInfo)!"; @@ -74,22 +84,27 @@ bool KPasswdServerClient::checkAuthInfo(KIO::AuthInfo &= info, qlonglong windowId, = if (loop.authInfo().isModified()) { //qDebug() << "username=3D" << info.username << "password=3D[hidde= n]"; - info =3D loop.authInfo(); + *info =3D loop.authInfo(); return true; } = return false; } = -qlonglong KPasswdServerClient::queryAuthInfo(KIO::AuthInfo &info, const QS= tring &errorMsg, - qlonglong windowId, qlonglong seqNr, - qlonglong usertime) +int KPasswdServerClient::queryAuthInfo(KIO::AuthInfo *info, const QString = &errorMsg, + qlonglong windowId, + qlonglong usertime) { + if (info->url.host() !=3D d->lastHost) { // see kpasswdserver/DESIGN + d->lastHost =3D info->url.host(); + d->seqNr =3D 0; + } + //qDebug() << "window-id=3D" << windowId; = if (!QCoreApplication::instance()) { qCWarning(KIO_CORE) << "kioslave is not a QCoreApplication! This i= s required for queryAuthInfo."; - return -1; + return KIO::ERR_PASSWD_SERVER; } = // create the loop for waiting for a result before sending the request @@ -97,25 +112,34 @@ qlonglong KPasswdServerClient::queryAuthInfo(KIO::Auth= Info &info, const QString QObject::connect(m_interface, SIGNAL(queryAuthInfoAsyncResult(qlonglon= g,qlonglong,KIO::AuthInfo)), &loop, SLOT(slotQueryResult(qlonglong,qlonglong,KIO::= AuthInfo))); = - QDBusReply reply =3D m_interface->queryAuthInfoAsync(info, = errorMsg, - windowId, seqNr, + QDBusReply reply =3D m_interface->queryAuthInfoAsync(*info,= errorMsg, + windowId, d->seqNr, usertime); if (!reply.isValid()) { qCWarning(KIO_CORE) << "Can't communicate with kiod_kpasswdserver = (for queryAuthInfo)!"; //qDebug() << reply.error().name() << reply.error().message(); - return -1; + return KIO::ERR_PASSWD_SERVER; } = if (!loop.waitForResult(reply.value())) { qCWarning(KIO_CORE) << "kiod_kpasswdserver died while waiting for = reply!"; - return -1; + return KIO::ERR_PASSWD_SERVER; } = - info =3D loop.authInfo(); + *info =3D loop.authInfo(); + + //qDebug() << "username=3D" << info->username << "password=3D[hidden]"; = - //qDebug() << "username=3D" << info.username << "password=3D[hidden]"; + const qlonglong newSeqNr =3D loop.seqNr(); = - return loop.seqNr(); + if (newSeqNr > 0) { + d->seqNr =3D newSeqNr; + if (info->isModified()) { + return KJob::NoError; + } + } + + return KIO::ERR_USER_CANCELED; } = void KPasswdServerClient::addAuthInfo(const KIO::AuthInfo &info, qlonglong= windowId) @@ -128,5 +152,3 @@ void KPasswdServerClient::removeAuthInfo(const QString = &host, const QString &pro { m_interface->removeAuthInfo(host, protocol, user); } - -} diff --git a/src/core/kpasswdserverclient_p.h b/src/core/kpasswdserverclien= t.h similarity index 56% rename from src/core/kpasswdserverclient_p.h rename to src/core/kpasswdserverclient.h index 37c924a6..229d8091 100644 --- a/src/core/kpasswdserverclient_p.h +++ b/src/core/kpasswdserverclient.h @@ -19,62 +19,74 @@ * License along with this library. If not, see . */ = -#ifndef KPASSWDSERVERCLIENT_P_H -#define KPASSWDSERVERCLIENT_P_H +#ifndef KPASSWDSERVERCLIENT_H +#define KPASSWDSERVERCLIENT_H = #include +#include = class QString; class OrgKdeKPasswdServerInterface; = namespace KIO { -class AuthInfo; + class AuthInfo; +} + +class KPasswdServerClientPrivate; = /** * Interface class for kpasswdserver. - * @internal - * @remarks This is currently only supposed to be used by KIO::SlaveBase - * but might be reused as public API in the future. + * KIOSlaves should not use this directly but via the SlaveBase API. + * @since 5.30 */ -class KPasswdServerClient +class KIOCORE_EXPORT KPasswdServerClient { public: + /** + * Creates a client instance for kpasswdserver. + * The instance should be kept for the lifetime of the process, not cr= eated for each request. + */ KPasswdServerClient(); + /** + * Destructor. + */ ~KPasswdServerClient(); = /** * Check if kpasswdserver has cached authentication information regard= ing * an AuthInfo object. * @param info information to check cache for - * @param windowId used as parent for dialogs - * @param usertime FIXME: I'd like to know as well :) + * @param windowId used as parent for dialogs, comes from QWidget::win= Id() on the toplevel widget + * @param usertime the X11 user time from the calling application, so = that any dialog + * (e.g. wallet password) respects focus-prevention ru= les. + * Use KUserTimestamp::userTimestamp in the GUI applic= ation from which the request originates. * @return true if kpasswdserver provided cached information, false if= not * @remarks info will contain the results of the check. To see if * information was retrieved, check info.isModified(). */ - bool checkAuthInfo(KIO::AuthInfo &info, qlonglong windowId, + bool checkAuthInfo(KIO::AuthInfo *info, qlonglong windowId, qlonglong usertime); = /** * Let kpasswdserver ask the user for authentication information. * @param info information to query the user for * @param errorMsg error message that will be displayed to the user - * @param seqNr sequence number to assign to this request - * @param windowId used as parent for dialogs - * @param usertime FIXME: I'd like to know as well :) - * @return kpasswdserver's sequence number or -1 on error - * @remarks info will contain the results of the check. To see if - * information was retrieved, check info.isModified(). + * @param windowId used as parent for dialogs, comes from QWidget::win= Id() on the toplevel widget + * @param usertime the X11 user time from the calling application, so = that the dialog + * (e.g. wallet password) respects focus-prevention ru= les. + * Use KUserTimestamp::userTimestamp in the GUI applic= ation from which the request originates. + * @return a KIO error code: KJob::NoError (0) on success, otherwise E= RR_USER_CANCELED if the user canceled, + * or ERR_PASSWD_SERVER if we couldn't communicate with kpasswdserver. + * @remarks If NoError is returned, then @p info will contain the auth= entication information that was retrieved. */ - qlonglong queryAuthInfo(KIO::AuthInfo &info, const QString &errorMsg, - qlonglong windowId, qlonglong seqNr, - qlonglong usertime); + int queryAuthInfo(KIO::AuthInfo *info, const QString &errorMsg, + qlonglong windowId, qlonglong usertime); = /** * Manually add authentication information to kpasswdserver's cache. * @param info information to add - * @param windowId used as parent window for dialogs + * @param windowId used as parent window for dialogs, comes from QWidg= et::winId() on the toplevel widget */ void addAuthInfo(const KIO::AuthInfo &info, qlonglong windowId); = @@ -89,8 +101,7 @@ public: = private: OrgKdeKPasswdServerInterface *m_interface; + KPasswdServerClientPrivate *d; }; = -} - #endif diff --git a/src/core/kpasswdserverloop.cpp b/src/core/kpasswdserverloop.cpp index d7ceab71..f810d270 100644 --- a/src/core/kpasswdserverloop.cpp +++ b/src/core/kpasswdserverloop.cpp @@ -24,9 +24,6 @@ #include #include = -namespace KIO -{ - KPasswdServerLoop::KPasswdServerLoop() : m_seqNr(-1) { QDBusServiceWatcher *watcher =3D new QDBusServiceWatcher(QStringLitera= l("org.kde.kpasswdserver"), QDBusConnection::sessionBus(), @@ -43,7 +40,7 @@ bool KPasswdServerLoop::waitForResult(qlonglong requestId) { m_requestId =3D requestId; m_seqNr =3D -1; - m_authInfo =3D AuthInfo(); + m_authInfo =3D KIO::AuthInfo(); return (exec() =3D=3D 0); } = @@ -52,7 +49,7 @@ qlonglong KPasswdServerLoop::seqNr() const return m_seqNr; } = -const AuthInfo &KPasswdServerLoop::authInfo() const +const KIO::AuthInfo &KPasswdServerLoop::authInfo() const { return m_authInfo; } @@ -72,6 +69,4 @@ void KPasswdServerLoop::kdedServiceUnregistered() exit(-1); } = -} - #include "moc_kpasswdserverloop_p.cpp" diff --git a/src/core/kpasswdserverloop_p.h b/src/core/kpasswdserverloop_p.h index 00bf7c61..0ef4e02b 100644 --- a/src/core/kpasswdserverloop_p.h +++ b/src/core/kpasswdserverloop_p.h @@ -26,9 +26,6 @@ #include #include = -namespace KIO -{ - // Wait for the result of an asynchronous D-Bus request to KPasswdServer. // Objects of this class are one-way ie. as soon as they have received // a result you can't call waitForResult() again. @@ -42,7 +39,7 @@ public: bool waitForResult(qlonglong requestId); = qlonglong seqNr() const; - const AuthInfo &authInfo() const; + const KIO::AuthInfo &authInfo() const; = public Q_SLOTS: void slotQueryResult(qlonglong requestId, qlonglong seqNr, const KIO::= AuthInfo &authInfo); @@ -53,9 +50,7 @@ private Q_SLOTS: private: qlonglong m_requestId; qlonglong m_seqNr; - AuthInfo m_authInfo; + KIO::AuthInfo m_authInfo; }; = -} - #endif diff --git a/src/core/slavebase.cpp b/src/core/slavebase.cpp index 44ecae55..fc9bdf31 100644 --- a/src/core/slavebase.cpp +++ b/src/core/slavebase.cpp @@ -50,7 +50,7 @@ #include "commands_p.h" #include "ioslave_defaults.h" #include "slaveinterface.h" -#include "kpasswdserverclient_p.h" +#include "kpasswdserverclient.h" #include "kiocoredebug.h" = #ifndef NDEBUG @@ -97,7 +97,6 @@ public: Connection appConnection; QString poolSocket; bool isConnectedToApp; - static qlonglong s_seqNr; = QString slaveid; bool resume: 1; @@ -166,7 +165,6 @@ public: } = static SlaveBase *globalSlave; -qlonglong SlaveBasePrivate::s_seqNr; = static volatile bool slaveWriteError =3D false; = @@ -959,18 +957,11 @@ int SlaveBase::openPasswordDialogV2(AuthInfo &info, c= onst QString &errorMsg) dlgInfo.setExtraField(QStringLiteral("skip-caching-on-query"), true); = KPasswdServerClient *passwdServerClient =3D d->passwdServerClient(); - qlonglong seqNr =3D passwdServerClient->queryAuthInfo(dlgInfo, errorMe= ssage, windowId, - SlaveBasePrivate::= s_seqNr, userTimestamp); - if (seqNr > 0) { - SlaveBasePrivate::s_seqNr =3D seqNr; - if (dlgInfo.isModified()) { - info =3D dlgInfo; - return KJob::NoError; - } - } else if (seqNr < 0) { - return ERR_PASSWD_SERVER; + const int errCode =3D passwdServerClient->queryAuthInfo(&dlgInfo, erro= rMessage, windowId, userTimestamp); + if (errCode =3D=3D KJob::NoError) { + info =3D dlgInfo; } - return ERR_USER_CANCELED; + return errCode; } = int SlaveBase::messageBox(MessageBoxType type, const QString &text, const = QString &caption, @@ -1074,8 +1065,6 @@ void SlaveBase::dispatch(int command, const QByteArra= y &data) = switch (command) { case CMD_HOST: { - // Reset s_seqNr, see kpasswdserver/DESIGN - SlaveBasePrivate::s_seqNr =3D 0; QString passwd; QString host, user; quint16 port; @@ -1314,7 +1303,7 @@ void SlaveBase::dispatch(int command, const QByteArra= y &data) bool SlaveBase::checkCachedAuthentication(AuthInfo &info) { KPasswdServerClient *passwdServerClient =3D d->passwdServerClient(); - return (passwdServerClient->checkAuthInfo(info, metaData(QStringLitera= l("window-id")).toLong(), + return (passwdServerClient->checkAuthInfo(&info, metaData(QStringLiter= al("window-id")).toLong(), metaData(QStringLiteral("user-time= stamp")).toULong())); } =20