From: Janne Koschinski Date: Sun, 27 Aug 2017 02:29:53 +0000 (+0200) Subject: Add initial implementation for showing and kicking connected clients X-Git-Tag: travis-deploy-test~227 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=c1722505b4906fe59c48aad54e6545a17afb78d7 Add initial implementation for showing and kicking connected clients Adds the possibility to show a list of connected clients, and allow to kick other (or your own) clients of the same user. --- diff --git a/src/client/client.cpp b/src/client/client.cpp index 343ad854..0a19351e 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -160,6 +160,8 @@ void Client::init() p->attachSignal(this, SIGNAL(requestPasswordChange(PeerPtr,QString,QString,QString)), SIGNAL(changePassword(PeerPtr,QString,QString,QString))); p->attachSlot(SIGNAL(passwordChanged(PeerPtr,bool)), this, SLOT(corePasswordChanged(PeerPtr,bool))); + p->attachSignal(this, SIGNAL(requestKickClient(int)), SIGNAL(kickClient(int))); + //connect(mainUi(), SIGNAL(connectToCore(const QVariantMap &)), this, SLOT(connectToCore(const QVariantMap &))); connect(mainUi(), SIGNAL(disconnectFromCore()), this, SLOT(disconnectFromCore())); connect(this, SIGNAL(connected()), mainUi(), SLOT(connectedToCore())); @@ -685,6 +687,11 @@ void Client::changePassword(const QString &oldPassword, const QString &newPasswo } +void Client::kickClient(int peerId) { + emit instance()->requestKickClient(peerId); +} + + void Client::corePasswordChanged(PeerPtr, bool success) { if (success) diff --git a/src/client/client.h b/src/client/client.h index 23f7d327..4b83d909 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -149,6 +149,7 @@ public: static void purgeKnownBufferIds(); static void changePassword(const QString &oldPassword, const QString &newPassword); + static void kickClient(int peerId); #if QT_VERSION < 0x050000 static void logMessage(QtMsgType type, const char *msg); @@ -201,6 +202,8 @@ signals: //! Requests a password change (user name must match the currently logged in user) void requestPasswordChange(PeerPtr peer, const QString &userName, const QString &oldPassword, const QString &newPassword); + + void requestKickClient(int peerId); void passwordChanged(bool success); public slots: diff --git a/src/common/peer.h b/src/common/peer.h index 2bbbf72c..8c17811d 100644 --- a/src/common/peer.h +++ b/src/common/peer.h @@ -50,6 +50,11 @@ public: virtual int lag() const = 0; + int _id = -1; + + QString _buildDate; + QString _clientVersion; + public slots: /* Handshake messages */ virtual void dispatch(const Protocol::RegisterClient &) = 0; diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index deb78ad1..45f3b50a 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -288,7 +288,12 @@ bool SignalProxy::addPeer(Peer *peer) if (!peer->parent()) peer->setParent(this); + if (peer->_id < 0) { + peer->_id = nextPeerId(); + } + _peers.insert(peer); + _peerMap[peer->_id] = peer; peer->setSignalProxy(this); @@ -331,6 +336,7 @@ void SignalProxy::removePeer(Peer *peer) disconnect(peer, 0, this, 0); peer->setSignalProxy(0); + _peerMap.remove(peer->_id); _peers.remove(peer); emit peerRemoved(peer); @@ -810,6 +816,24 @@ void SignalProxy::updateSecureState() emit secureStateChanged(_secure); } +QVariantList SignalProxy::peerData() { + QVariantList result; + for (auto peer : _peers) { + QVariantMap data; + data["id"] = peer->_id; + data["buildData"] = peer->_buildDate; + data["clientVersion"] = peer->_clientVersion; + data["description"] = peer->description(); + data["secure"] = peer->isSecure(); + result << data; + } + return result; +} + +Peer *SignalProxy::peerById(int peerId) { + return _peerMap[peerId]; +} + // ================================================== // ExtendedMetaObject diff --git a/src/common/signalproxy.h b/src/common/signalproxy.h index c07a86b0..dce008ab 100644 --- a/src/common/signalproxy.h +++ b/src/common/signalproxy.h @@ -78,6 +78,9 @@ public: void dumpProxyStats(); void dumpSyncMap(SyncableObject *object); inline int peerCount() const { return _peers.size(); } + QVariantList peerData(); + + Peer *peerById(int peerId); public slots: void detachObject(QObject *obj); @@ -117,6 +120,10 @@ private: void removePeer(Peer *peer); void removeAllPeers(); + int nextPeerId() { + return _lastPeerId++; + } + template void dispatch(const T &protoMessage); template @@ -140,6 +147,7 @@ private: static void disconnectDevice(QIODevice *dev, const QString &reason = QString()); QSet _peers; + QHash _peerMap; // containg a list of argtypes for fast access QHash _extendedMetaObjects; @@ -162,6 +170,8 @@ private: bool _secure; // determines if all connections are in a secured state (using ssl or internal connections) + int _lastPeerId = 0; + friend class SignalRelay; friend class SyncableObject; friend class Peer; diff --git a/src/core/coreauthhandler.cpp b/src/core/coreauthhandler.cpp index 6f454fa3..aa1d9571 100644 --- a/src/core/coreauthhandler.cpp +++ b/src/core/coreauthhandler.cpp @@ -183,6 +183,9 @@ void CoreAuthHandler::handle(const RegisterClient &msg) // XXX: FIXME: use client features here: we cannot pass authenticators if the client is too old! _peer->dispatch(ClientRegistered(Quassel::features(), configured, backends, useSsl, authenticators)); + _peer->_buildDate = msg.buildDate; + _peer->_clientVersion = msg.clientVersion; + if (_legacy && useSsl) startSsl(); diff --git a/src/core/corecoreinfo.cpp b/src/core/corecoreinfo.cpp index 3c1d5fe2..fb5d1fbc 100644 --- a/src/core/corecoreinfo.cpp +++ b/src/core/corecoreinfo.cpp @@ -40,5 +40,6 @@ QVariantMap CoreCoreInfo::coreData() const data["quasselBuildDate"] = Quassel::buildInfo().commitDate; // "BuildDate" for compatibility data["startTime"] = Core::instance()->startTime(); data["sessionConnectedClients"] = _coreSession->signalProxy()->peerCount(); + data["sessionConnectedClientData"] = _coreSession->signalProxy()->peerData(); return data; } diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index 3782f71d..635067a5 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -105,6 +105,8 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) p->attachSlot(SIGNAL(changePassword(PeerPtr,QString,QString,QString)), this, SLOT(changePassword(PeerPtr,QString,QString,QString))); p->attachSignal(this, SIGNAL(passwordChanged(PeerPtr,bool))); + p->attachSlot(SIGNAL(kickClient(int)), this, SLOT(kickClient(int))); + loadSettings(); initScriptEngine(); @@ -717,3 +719,11 @@ void CoreSession::changePassword(PeerPtr peer, const QString &userName, const QS emit passwordChanged(peer, success); } + +void CoreSession::kickClient(int peerId) { + auto peer = signalProxy()->peerById(peerId); + if (!peer) { + qWarning() << "Invalid peer Id: " << peerId; + } + peer->close("Terminated by user action"); +} diff --git a/src/core/coresession.h b/src/core/coresession.h index d7b2cebb..c4de8cc9 100644 --- a/src/core/coresession.h +++ b/src/core/coresession.h @@ -131,6 +131,8 @@ public slots: void changePassword(PeerPtr peer, const QString &userName, const QString &oldPassword, const QString &newPassword); + void kickClient(int peerId); + QHash persistentChannels(NetworkId) const; /** diff --git a/src/qtui/coreinfodlg.cpp b/src/qtui/coreinfodlg.cpp index 8aa738c5..030d1d09 100644 --- a/src/qtui/coreinfodlg.cpp +++ b/src/qtui/coreinfodlg.cpp @@ -40,6 +40,23 @@ void CoreInfoDlg::coreInfoAvailable() ui.labelCoreVersion->setText(_coreInfo["quasselVersion"].toString()); ui.labelCoreVersionDate->setText(_coreInfo["quasselBuildDate"].toString()); // "BuildDate" for compatibility ui.labelClientCount->setNum(_coreInfo["sessionConnectedClients"].toInt()); + + /* + qWarning() << _coreInfo["sessionConnectedClientData"]; + + int lastPeerId = -1; + QMap lastPeerData; + for (const auto &peerData : _coreInfo["sessionConnectedClientData"].toList()) { + lastPeerData = peerData.toMap(); + lastPeerId = lastPeerData["id"].toInt(); + } + + if (lastPeerId != -1) { + qWarning() << "Kicking client " << lastPeerId; + Client::kickClient(lastPeerId); + } + */ + updateUptime(); startTimer(1000); }