From c40aac680885a6b5ab4ffbea6cef72fad1e7f74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 10 Aug 2018 17:11:03 +0200 Subject: [PATCH] First tunnel connection --- .../authentication/awsauthenticator.cpp | 2 +- libnymea-remoteproxy/engine.cpp | 56 ++-- libnymea-remoteproxy/engine.h | 11 +- .../jsonrpc/authenticationhandler.cpp | 5 +- libnymea-remoteproxy/jsonrpcserver.cpp | 24 +- libnymea-remoteproxy/jsonrpcserver.h | 5 +- libnymea-remoteproxy/libnymea-remoteproxy.pro | 6 +- libnymea-remoteproxy/loggingcategories.cpp | 1 + libnymea-remoteproxy/loggingcategories.h | 1 + libnymea-remoteproxy/proxyclient.cpp | 10 +- libnymea-remoteproxy/proxyserver.cpp | 108 +++++++- libnymea-remoteproxy/proxyserver.h | 18 ++ libnymea-remoteproxy/tunnelconnection.cpp | 47 ++++ libnymea-remoteproxy/tunnelconnection.h | 28 ++ libnymea-remoteproxyclient/jsonrpcclient.cpp | 11 +- libnymea-remoteproxyclient/jsonrpcclient.h | 1 + .../proxyconnection.cpp | 1 - .../remoteproxyconnection.cpp | 70 +++-- .../remoteproxyconnection.h | 12 +- .../websocketconnection.cpp | 4 + tests/mockauthenticator.cpp | 1 - tests/nymea-remoteproxy-tests.cpp | 245 +++++++++++++----- tests/nymea-remoteproxy-tests.h | 4 +- 23 files changed, 505 insertions(+), 166 deletions(-) create mode 100644 libnymea-remoteproxy/tunnelconnection.cpp create mode 100644 libnymea-remoteproxy/tunnelconnection.h diff --git a/libnymea-remoteproxy/authentication/awsauthenticator.cpp b/libnymea-remoteproxy/authentication/awsauthenticator.cpp index bbd8860..5b601a7 100644 --- a/libnymea-remoteproxy/authentication/awsauthenticator.cpp +++ b/libnymea-remoteproxy/authentication/awsauthenticator.cpp @@ -17,7 +17,7 @@ QString AwsAuthenticator::name() const AuthenticationReply *AwsAuthenticator::authenticate(ProxyClient *proxyClient) { - qCDebug(dcAuthenticator()) << name() << "Start authenticating" << proxyClient << "using token" << proxyClient->token(); + qCDebug(dcAuthenticator()) << name() << "Start authenticating" << proxyClient << "using token" << proxyClient->token(); AuthenticationReply *reply = createAuthenticationReply(proxyClient, this); return reply; } diff --git a/libnymea-remoteproxy/engine.cpp b/libnymea-remoteproxy/engine.cpp index 34cf555..aba289e 100644 --- a/libnymea-remoteproxy/engine.cpp +++ b/libnymea-remoteproxy/engine.cpp @@ -35,26 +35,17 @@ void Engine::start() if (!m_running) qCDebug(dcEngine()) << "Start server engine"; - // Init proxy server - if (m_proxyServer) { - delete m_proxyServer; - m_proxyServer = nullptr; - } + // Clean up + clean(); + m_configuration = new ProxyConfiguration(this); m_proxyServer = new ProxyServer(this); - - // Init WebSocketServer - if (m_webSocketServer) { - delete m_webSocketServer; - m_webSocketServer = nullptr; - } + m_webSocketServer = new WebSocketServer(m_sslConfiguration, this); QUrl websocketServerUrl; websocketServerUrl.setScheme("wss"); websocketServerUrl.setHost(m_webSocketServerHostAddress.toString()); websocketServerUrl.setPort(m_webSocketServerPort); - - m_webSocketServer = new WebSocketServer(m_sslConfiguration, this); m_webSocketServer->setServerUrl(websocketServerUrl); m_proxyServer->registerTransportInterface(m_webSocketServer); @@ -65,7 +56,8 @@ void Engine::start() qCDebug(dcEngine()) << "Starting proxy server"; m_proxyServer->startServer(); - QTimer::singleShot(0, this, &Engine::run); + // Set tunning true in the next event loop + QMetaObject::invokeMethod(this, QString("setRunning").toLatin1().data(), Qt::QueuedConnection, Q_ARG(bool, true)); } void Engine::stop() @@ -73,17 +65,7 @@ void Engine::stop() if (m_running) qCDebug(dcEngine()) << "Stop server engine"; - if (m_proxyServer) { - m_proxyServer->stopServer(); - delete m_proxyServer; - m_proxyServer = nullptr; - } - - if (m_webSocketServer) { - delete m_webSocketServer; - m_webSocketServer = nullptr; - } - + clean(); setRunning(false); } @@ -176,6 +158,26 @@ Engine::~Engine() stop(); } +void Engine::clean() +{ + if (m_proxyServer) { + m_proxyServer->stopServer(); + delete m_proxyServer; + m_proxyServer = nullptr; + } + + if (m_webSocketServer) { + delete m_webSocketServer; + m_webSocketServer = nullptr; + } + + if (m_configuration) { + delete m_configuration; + m_configuration = nullptr; + } +} + + void Engine::setRunning(bool running) { if (m_running == running) @@ -186,9 +188,5 @@ void Engine::setRunning(bool running) emit runningChanged(m_running); } -void Engine::run() -{ - setRunning(true); -} } diff --git a/libnymea-remoteproxy/engine.h b/libnymea-remoteproxy/engine.h index 77538af..1228de2 100644 --- a/libnymea-remoteproxy/engine.h +++ b/libnymea-remoteproxy/engine.h @@ -8,6 +8,7 @@ #include "proxyserver.h" #include "websocketserver.h" +#include "proxyconfiguration.h" #include "authentication/authenticator.h" namespace remoteproxy { @@ -53,18 +54,18 @@ private: QSslConfiguration m_sslConfiguration; QUrl m_authenticationServerUrl; + ProxyConfiguration *m_configuration = nullptr; Authenticator *m_authenticator = nullptr; ProxyServer *m_proxyServer = nullptr; WebSocketServer *m_webSocketServer = nullptr; - void setRunning(bool running); - -private slots: - void run(); - signals: void runningChanged(bool running); +private slots: + void clean(); + void setRunning(bool running); + }; } diff --git a/libnymea-remoteproxy/jsonrpc/authenticationhandler.cpp b/libnymea-remoteproxy/jsonrpc/authenticationhandler.cpp index 0e2fe71..554fe4b 100644 --- a/libnymea-remoteproxy/jsonrpc/authenticationhandler.cpp +++ b/libnymea-remoteproxy/jsonrpc/authenticationhandler.cpp @@ -66,15 +66,16 @@ void AuthenticationHandler::onAuthenticationFinished() if (authenticationReply->error() != Authenticator::AuthenticationErrorNoError) { qCWarning(dcJsonRpc()) << "Authentication error occured" << authenticationReply->error(); jsonReply->setSuccess(false); - authenticationReply->proxyClient()->setAuthenticated(false); } else { // Successfully authenticated - authenticationReply->proxyClient()->setAuthenticated(true); jsonReply->setSuccess(true); } jsonReply->setData(errorToReply(authenticationReply->error())); jsonReply->finished(); + + // Set client authenticated + authenticationReply->proxyClient()->setAuthenticated(authenticationReply->error() == Authenticator::AuthenticationErrorNoError); } } diff --git a/libnymea-remoteproxy/jsonrpcserver.cpp b/libnymea-remoteproxy/jsonrpcserver.cpp index 4fdbb5f..386f5d0 100644 --- a/libnymea-remoteproxy/jsonrpcserver.cpp +++ b/libnymea-remoteproxy/jsonrpcserver.cpp @@ -100,18 +100,6 @@ JsonReply *JsonRpcServer::Introspect(const QVariantMap ¶ms, ProxyClient *pro return createReply(data); } -void JsonRpcServer::sendNotification(const QString &nameSpace, const QString &method, const QVariantMap ¶ms, ProxyClient *proxyClient) -{ - QVariantMap notification; - notification.insert("id", m_notificationId++); - notification.insert("notification", nameSpace + "." + method); - notification.insert("params", params); - - QByteArray data = QJsonDocument::fromVariant(notification).toJson(QJsonDocument::Compact); - qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data; - proxyClient->interface()->sendData(proxyClient->clientId(), data); -} - void JsonRpcServer::sendResponse(ProxyClient *client, int commandId, const QVariantMap ¶ms) { QVariantMap response; @@ -290,4 +278,16 @@ void JsonRpcServer::processData(ProxyClient *proxyClient, const QByteArray &data } } +void JsonRpcServer::sendNotification(const QString &nameSpace, const QString &method, const QVariantMap ¶ms, ProxyClient *proxyClient) +{ + QVariantMap notification; + notification.insert("id", m_notificationId++); + notification.insert("notification", nameSpace + "." + method); + notification.insert("params", params); + + QByteArray data = QJsonDocument::fromVariant(notification).toJson(QJsonDocument::Compact); + qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data; + proxyClient->interface()->sendData(proxyClient->clientId(), data); +} + } diff --git a/libnymea-remoteproxy/jsonrpcserver.h b/libnymea-remoteproxy/jsonrpcserver.h index 7f1e3e7..258db67 100644 --- a/libnymea-remoteproxy/jsonrpcserver.h +++ b/libnymea-remoteproxy/jsonrpcserver.h @@ -24,8 +24,6 @@ public: Q_INVOKABLE JsonReply *Hello(const QVariantMap ¶ms, ProxyClient *proxyClient = nullptr) const; Q_INVOKABLE JsonReply *Introspect(const QVariantMap ¶ms, ProxyClient *proxyClient = nullptr) const; - void sendNotification(const QString &nameSpace, const QString &method, const QVariantMap ¶ms, ProxyClient *proxyClient = nullptr); - signals: void TunnelEstablished(const QVariantMap ¶ms); @@ -33,7 +31,7 @@ private: QHash m_handlers; QHash m_asyncReplies; QList m_clients; - int m_notificationId; + int m_notificationId = 0; void sendResponse(ProxyClient *client, int commandId, const QVariantMap ¶ms = QVariantMap()); void sendErrorResponse(ProxyClient *client, int commandId, const QString &error); @@ -54,6 +52,7 @@ public slots: // Process data from client void processData(ProxyClient *proxyClient, const QByteArray &data); + void sendNotification(const QString &nameSpace, const QString &method, const QVariantMap ¶ms, ProxyClient *proxyClient = nullptr); }; diff --git a/libnymea-remoteproxy/libnymea-remoteproxy.pro b/libnymea-remoteproxy/libnymea-remoteproxy.pro index ebd0205..ec62305 100644 --- a/libnymea-remoteproxy/libnymea-remoteproxy.pro +++ b/libnymea-remoteproxy/libnymea-remoteproxy.pro @@ -18,7 +18,8 @@ HEADERS += \ authentication/authenticator.h \ authentication/awsauthenticator.h \ authentication/authenticationreply.h \ - proxyconfiguration.h + proxyconfiguration.h \ + tunnelconnection.h SOURCES += \ engine.cpp \ @@ -35,7 +36,8 @@ SOURCES += \ authentication/authenticator.cpp \ authentication/awsauthenticator.cpp \ authentication/authenticationreply.cpp \ - proxyconfiguration.cpp + proxyconfiguration.cpp \ + tunnelconnection.cpp # install header file with relative subdirectory diff --git a/libnymea-remoteproxy/loggingcategories.cpp b/libnymea-remoteproxy/loggingcategories.cpp index 1844aa9..f728eab 100644 --- a/libnymea-remoteproxy/loggingcategories.cpp +++ b/libnymea-remoteproxy/loggingcategories.cpp @@ -8,4 +8,5 @@ Q_LOGGING_CATEGORY(dcWebSocketServer, "WebSocketServer") Q_LOGGING_CATEGORY(dcWebSocketServerTraffic, "WebSocketServerTraffic") Q_LOGGING_CATEGORY(dcAuthenticator, "Authenticator") Q_LOGGING_CATEGORY(dcProxyServer, "ProxyServer") +Q_LOGGING_CATEGORY(dcProxyServerTraffic, "ProxyServerTraffic") diff --git a/libnymea-remoteproxy/loggingcategories.h b/libnymea-remoteproxy/loggingcategories.h index f7a70eb..6715c3e 100644 --- a/libnymea-remoteproxy/loggingcategories.h +++ b/libnymea-remoteproxy/loggingcategories.h @@ -12,5 +12,6 @@ Q_DECLARE_LOGGING_CATEGORY(dcWebSocketServer) Q_DECLARE_LOGGING_CATEGORY(dcWebSocketServerTraffic) Q_DECLARE_LOGGING_CATEGORY(dcAuthenticator) Q_DECLARE_LOGGING_CATEGORY(dcProxyServer) +Q_DECLARE_LOGGING_CATEGORY(dcProxyServerTraffic) #endif // LOGGINGCATEGORIES_H diff --git a/libnymea-remoteproxy/proxyclient.cpp b/libnymea-remoteproxy/proxyclient.cpp index ec5d533..dfab140 100644 --- a/libnymea-remoteproxy/proxyclient.cpp +++ b/libnymea-remoteproxy/proxyclient.cpp @@ -81,15 +81,7 @@ void ProxyClient::setToken(const QString &token) QDebug operator<<(QDebug debug, ProxyClient *proxyClient) { debug.nospace() << "ProxyClient(" << proxyClient->interface()->serverName(); - debug.nospace() << ", " << proxyClient->clientId().toString() << ") :" << endl; - debug.nospace() << " tunnel: " << proxyClient->isTunnelConnected() << endl; - debug.nospace() << " authenticated: " << proxyClient->isAuthenticated() << endl; - if (!proxyClient->name().isEmpty() && !proxyClient->token().isEmpty() && !proxyClient->uuid().isEmpty()) { - debug.nospace() << " name: " << proxyClient->name() << endl; - debug.nospace() << " uuid: " << proxyClient->uuid() << endl; - debug.nospace() << " token: " << proxyClient->token() << endl; - - } + debug.nospace() << ", " << proxyClient->clientId().toString() << ") "; return debug; } diff --git a/libnymea-remoteproxy/proxyserver.cpp b/libnymea-remoteproxy/proxyserver.cpp index e3c5914..2b8aafe 100644 --- a/libnymea-remoteproxy/proxyserver.cpp +++ b/libnymea-remoteproxy/proxyserver.cpp @@ -1,14 +1,15 @@ #include "proxyserver.h" #include "loggingcategories.h" +#include #include namespace remoteproxy { ProxyServer::ProxyServer(QObject *parent) : QObject(parent) { + qRegisterMetaType("ProxyClient *"); m_jsonRpcServer = new JsonRpcServer(this); - } ProxyServer::~ProxyServer() @@ -16,6 +17,11 @@ ProxyServer::~ProxyServer() qCDebug(dcProxyServer()) << "Shutting down proxy server"; } +bool ProxyServer::running() const +{ + return m_running; +} + void ProxyServer::registerTransportInterface(TransportInterface *interface) { qCDebug(dcProxyServer()) << "Register transport interface" << interface->serverName(); @@ -32,6 +38,30 @@ void ProxyServer::registerTransportInterface(TransportInterface *interface) m_transportInterfaces.append(interface); } +void ProxyServer::setRunning(bool running) +{ + if (m_running == running) + return; + + qCDebug(dcProxyServer()) << "The proxy server is now up and running"; + m_running = running; + emit runningChanged(); +} + +ProxyClient *ProxyServer::getRemoteClient(ProxyClient *proxyClient) +{ + if (!m_tunnels.contains(proxyClient->token())) + return nullptr; + + if (proxyClient == m_tunnels.value(proxyClient->token()).clientOne()) { + return m_tunnels.value(proxyClient->token()).clientTwo(); + } else if (proxyClient == m_tunnels.value(proxyClient->token()).clientTwo()) { + return m_tunnels.value(proxyClient->token()).clientOne(); + } + + return nullptr; +} + void ProxyServer::sendResponse(TransportInterface *interface, const QUuid &clientId, const QVariantMap &response) { QByteArray data = QJsonDocument::fromVariant(response).toJson(QJsonDocument::Compact); @@ -39,6 +69,48 @@ void ProxyServer::sendResponse(TransportInterface *interface, const QUuid &clien interface->sendData(clientId, data); } +void ProxyServer::establishTunnel(ProxyClient *firstClient, ProxyClient *secondClient) +{ + qCDebug(dcProxyServer()) << "Create tunnel between authenticated clients:"; + qCDebug(dcProxyServer()) << " -->" << firstClient << firstClient->name(); + qCDebug(dcProxyServer()) << " -->" << secondClient << secondClient->name(); + + TunnelConnection tunnel(firstClient, secondClient); + if (!tunnel.isValid()) { + qCWarning(dcProxyServer()) << "Invalid tunnel. Could not establish connection."; + // FIXME + } + + m_tunnels.insert(tunnel.token(), tunnel); + + // Tell both clients the tunnel has been established + QVariantMap notificationParamsFirst; + notificationParamsFirst.insert("name", tunnel.clientTwo()->name()); + notificationParamsFirst.insert("uuid", tunnel.clientTwo()->uuid()); + + QVariantMap notificationParamsSecond; + notificationParamsSecond.insert("name", tunnel.clientOne()->name()); + notificationParamsSecond.insert("uuid", tunnel.clientOne()->uuid()); + + // Make sure the proxy is the first one who knows that the tunnel is connected + firstClient->setTunnelConnected(true); + secondClient->setTunnelConnected(true); + + // Notify the clients in the next event loop + QMetaObject::invokeMethod(m_jsonRpcServer, QString("sendNotification").toLatin1().data(), Qt::QueuedConnection, + Q_ARG(QString, "ProxyServer"), + Q_ARG(QString, "TunnelEstablished"), + Q_ARG(QVariantMap, notificationParamsFirst), + Q_ARG(ProxyClient *, tunnel.clientOne())); + + + QMetaObject::invokeMethod(m_jsonRpcServer, QString("sendNotification").toLatin1().data(), Qt::QueuedConnection, + Q_ARG(QString, "ProxyServer"), + Q_ARG(QString, "TunnelEstablished"), + Q_ARG(QVariantMap, notificationParamsSecond), + Q_ARG(ProxyClient *, tunnel.clientTwo())); +} + void ProxyServer::onClientConnected(const QUuid &clientId) { TransportInterface *interface = static_cast(sender()); @@ -86,10 +158,9 @@ void ProxyServer::onClientDataAvailable(const QUuid &clientId, const QByteArray return; } - qCDebug(dcProxyServer()) << "Client data available" << proxyClient << qUtf8Printable(data); - // If this client is not authenticated yet, and not tunnel connected, pipe the traffic into the json rpc server if (!proxyClient->isAuthenticated() && !proxyClient->isTunnelConnected()) { + qCDebug(dcProxyServerTraffic()) << "Client data available" << proxyClient << qUtf8Printable(data); m_jsonRpcServer->processData(proxyClient, data); return; } @@ -105,15 +176,42 @@ void ProxyServer::onClientDataAvailable(const QUuid &clientId, const QByteArray } if (proxyClient->isAuthenticated() && proxyClient->isTunnelConnected()) { - // TODO: Pipe the traffic to the tunnel client + // Check if there is realy a tunnel for this client + if (!m_tunnels.contains(proxyClient->token())) { + // FIXME: kill all clients, something went wrong + } + + ProxyClient *remoteClient = getRemoteClient(proxyClient); + if (!remoteClient) { + // FIXME: kill all clients, something went wrong + } + + qCDebug(dcProxyServerTraffic()) << "Pipe data:"; + qCDebug(dcProxyServerTraffic()) << " --> from" << proxyClient; + qCDebug(dcProxyServerTraffic()) << " --> to" << remoteClient; + qCDebug(dcProxyServerTraffic()) << " --> data:" << qUtf8Printable(data); + + remoteClient->interface()->sendData(remoteClient->clientId(), data); } } void ProxyServer::onProxyClientAuthenticated() { ProxyClient *proxyClient = static_cast(sender()); + qCDebug(dcProxyServer()) << "Client authenticated" << proxyClient; - m_authenticatedClients.insert(proxyClient->token(), proxyClient); + qCDebug(dcProxyServer()) << " name:" << proxyClient->name(); + qCDebug(dcProxyServer()) << " uuid:" << proxyClient->uuid(); + + // Check if we have an other authenticated client with this token + if (m_authenticatedClients.keys().contains(proxyClient->token())) { + // Found a client with this token + ProxyClient *tunnelEnd = m_authenticatedClients.take(proxyClient->token()); + establishTunnel(tunnelEnd, proxyClient); + } else { + // Append and wait for the other client + m_authenticatedClients.insert(proxyClient->token(), proxyClient); + } } void ProxyServer::onProxyClientTunnelConnected() diff --git a/libnymea-remoteproxy/proxyserver.h b/libnymea-remoteproxy/proxyserver.h index 41bf295..7155b8c 100644 --- a/libnymea-remoteproxy/proxyserver.h +++ b/libnymea-remoteproxy/proxyserver.h @@ -7,6 +7,7 @@ #include "proxyclient.h" #include "jsonrpcserver.h" +#include "tunnelconnection.h" #include "transportinterface.h" namespace remoteproxy { @@ -18,16 +19,33 @@ public: explicit ProxyServer(QObject *parent = nullptr); ~ProxyServer(); + bool running() const; void registerTransportInterface(TransportInterface *interface); private: JsonRpcServer *m_jsonRpcServer = nullptr; QList m_transportInterfaces; + bool m_running = false; + + // Transport ClientId, ProxyClient QHash m_proxyClients; + + // Token, ProxyClient QHash m_authenticatedClients; + // Token, Tunnel + QHash m_tunnels; + + void setRunning(bool running); + + ProxyClient *getRemoteClient(ProxyClient *proxyClient); + void sendResponse(TransportInterface *interface, const QUuid &clientId, const QVariantMap &response = QVariantMap()); + void establishTunnel(ProxyClient *firstClient, ProxyClient *secondClient); + +signals: + void runningChanged(); private slots: void onClientConnected(const QUuid &clientId); diff --git a/libnymea-remoteproxy/tunnelconnection.cpp b/libnymea-remoteproxy/tunnelconnection.cpp new file mode 100644 index 0000000..1dde7bb --- /dev/null +++ b/libnymea-remoteproxy/tunnelconnection.cpp @@ -0,0 +1,47 @@ +#include "tunnelconnection.h" + +namespace remoteproxy { + +TunnelConnection::TunnelConnection(ProxyClient *clientOne, ProxyClient *clientTwo): + m_clientOne(clientOne), + m_clientTwo(clientTwo) +{ + +} + +QString TunnelConnection::token() const +{ + if (!isValid()) + return QString(); + + return m_clientOne->token(); +} + +ProxyClient *TunnelConnection::clientOne() const +{ + return m_clientOne; +} + +ProxyClient *TunnelConnection::clientTwo() const +{ + return m_clientTwo; +} + +bool TunnelConnection::isValid() const +{ + // Both clients have to be valid + if (!m_clientOne || !m_clientTwo) + return false; + + // Both clients need the same token + if (m_clientOne->token() != m_clientTwo->token()) + return false; + + // The clients need to be different + if (m_clientOne == m_clientTwo) + return false; + + return true; +} + +} diff --git a/libnymea-remoteproxy/tunnelconnection.h b/libnymea-remoteproxy/tunnelconnection.h new file mode 100644 index 0000000..d1fdd52 --- /dev/null +++ b/libnymea-remoteproxy/tunnelconnection.h @@ -0,0 +1,28 @@ +#ifndef TUNNELCONNECTION_H +#define TUNNELCONNECTION_H + +#include "proxyclient.h" + +namespace remoteproxy { + +class TunnelConnection +{ +public: + TunnelConnection(ProxyClient *clientOne = nullptr, ProxyClient *clientTwo = nullptr); + + QString token() const; + + ProxyClient *clientOne() const; + ProxyClient *clientTwo() const; + + bool isValid() const; + +private: + ProxyClient *m_clientOne = nullptr; + ProxyClient *m_clientTwo = nullptr; + +}; + +} + +#endif // TUNNELCONNECTION_H diff --git a/libnymea-remoteproxyclient/jsonrpcclient.cpp b/libnymea-remoteproxyclient/jsonrpcclient.cpp index e145f7b..94fd7ec 100644 --- a/libnymea-remoteproxyclient/jsonrpcclient.cpp +++ b/libnymea-remoteproxyclient/jsonrpcclient.cpp @@ -82,10 +82,17 @@ void JsonRpcClient::processData(const QByteArray &data) if (dataMap.contains("notification")) { QStringList notification = dataMap.value("notification").toString().split("."); QString nameSpace = notification.first(); + QString notificationName = notification.last(); + QVariantMap notificationParams = dataMap.value("params").toMap(); - qCDebug(dcRemoteProxyClientJsonRpc()) << "Notification received" << nameSpace << notification; + qCDebug(dcRemoteProxyClientJsonRpc()) << "Notification received" << nameSpace << notificationName; + + if (nameSpace == "ProxyServer" && notificationName == "TunnelEstablished") { + QString clientName = notificationParams.value("name").toString(); + QString clientUuid = notificationParams.value("uuid").toString(); + emit tunnelEstablished(clientName, clientUuid); + } } - } } diff --git a/libnymea-remoteproxyclient/jsonrpcclient.h b/libnymea-remoteproxyclient/jsonrpcclient.h index 205af9a..8d31427 100644 --- a/libnymea-remoteproxyclient/jsonrpcclient.h +++ b/libnymea-remoteproxyclient/jsonrpcclient.h @@ -33,6 +33,7 @@ private: void sendRequest(const QVariantMap &request); signals: + void tunnelEstablished(const QString clientName, const QString &clientUuid); public slots: void onConnectedChanged(bool connected); diff --git a/libnymea-remoteproxyclient/proxyconnection.cpp b/libnymea-remoteproxyclient/proxyconnection.cpp index 1ca9dc2..c18738c 100644 --- a/libnymea-remoteproxyclient/proxyconnection.cpp +++ b/libnymea-remoteproxyclient/proxyconnection.cpp @@ -22,5 +22,4 @@ void ProxyConnection::setAllowSslErrors(bool allowSslErrors) m_allowSslErrors = allowSslErrors; } - } diff --git a/libnymea-remoteproxyclient/remoteproxyconnection.cpp b/libnymea-remoteproxyclient/remoteproxyconnection.cpp index b5f5d99..7780b13 100644 --- a/libnymea-remoteproxyclient/remoteproxyconnection.cpp +++ b/libnymea-remoteproxyclient/remoteproxyconnection.cpp @@ -17,7 +17,7 @@ RemoteProxyConnection::RemoteProxyConnection(const QUuid &clientUuid, const QStr RemoteProxyConnection::~RemoteProxyConnection() { - cleanUp(); + } RemoteProxyConnection::State RemoteProxyConnection::state() const @@ -64,6 +64,12 @@ bool RemoteProxyConnection::isConnected() const || m_state == StateRemoteConnected; } +bool RemoteProxyConnection::isAuthenticated() const +{ + return m_state == StateWaitTunnel + || m_state == StateRemoteConnected; +} + bool RemoteProxyConnection::isRemoteConnected() const { return m_state == StateRemoteConnected; @@ -133,15 +139,21 @@ bool RemoteProxyConnection::sendData(const QByteArray &data) void RemoteProxyConnection::cleanUp() { if (m_jsonClient) { - delete m_jsonClient; + m_jsonClient->deleteLater(); m_jsonClient = nullptr; } if (m_connection) { - delete m_connection; + m_connection->deleteLater(); m_connection = nullptr; } + m_error = ErrorNoError; + m_serverName = QString(); + m_proxyServerName = QString(); + m_proxyServerVersion = QString(); + m_proxyServerApiVersion = QString(); + setState(StateDisconnected); } @@ -167,16 +179,19 @@ void RemoteProxyConnection::setError(RemoteProxyConnection::Error error) void RemoteProxyConnection::onConnectionChanged(bool isConnected) { - if (!isConnected) { - emit disconnected(); - cleanUp(); - } else { + if (isConnected) { + qCDebug(dcRemoteProxyClientConnection()) << "Connected from proxy server."; setState(StateConnected); emit connected(); setState(StateInitializing); JsonReply *reply = m_jsonClient->callHello(); connect(reply, &JsonReply::finished, this, &RemoteProxyConnection::onHelloFinished); + } else { + qCDebug(dcRemoteProxyClientConnection()) << "Disconnected from proxy server."; + emit disconnected(); + setState(StateDisconnected); + cleanUp(); } } @@ -188,6 +203,7 @@ void RemoteProxyConnection::onConnectionDataAvailable(const QByteArray &data) case StateInitializing: case StateReady: case StateAuthenticating: + case StateWaitTunnel: m_jsonClient->processData(data); break; case StateRemoteConnected: @@ -228,10 +244,10 @@ void RemoteProxyConnection::onHelloFinished() // TODO: verify success - m_serverName = response.value("server").toString(); - m_proxyServerName = response.value("name").toString(); - m_proxyServerVersion = response.value("version").toString(); - m_proxyServerApiVersion = response.value("apiVersion").toString(); + m_serverName = responseParams.value("server").toString(); + m_proxyServerName = responseParams.value("name").toString(); + m_proxyServerVersion = responseParams.value("version").toString(); + m_proxyServerApiVersion = responseParams.value("apiVersion").toString(); setState(StateReady); emit ready(); @@ -242,6 +258,17 @@ void RemoteProxyConnection::onAuthenticateFinished() JsonReply *reply = static_cast(sender()); QVariantMap response = reply->response(); qCDebug(dcRemoteProxyClientConnection()) << "Authentication response ready" << response; + + // TODO: verify success + setState(StateWaitTunnel); + emit authenticated(); +} + +void RemoteProxyConnection::onTunnelEstablished(const QString &clientName, const QString &clientUuid) +{ + qCDebug(dcRemoteProxyClientConnection()) << "####### Remote connection established with" << clientName << clientUuid; + setState(StateRemoteConnected); + emit remoteConnectionEstablished(); } bool RemoteProxyConnection::connectServer(const QHostAddress &serverAddress, quint16 port) @@ -249,15 +276,7 @@ bool RemoteProxyConnection::connectServer(const QHostAddress &serverAddress, qui m_serverAddress = serverAddress; m_serverPort = port; - if (m_connection) { - delete m_connection; - m_connection = nullptr; - } - - if (m_jsonClient) { - delete m_jsonClient; - m_jsonClient = nullptr; - } + cleanUp(); switch (m_connectionType) { case ConnectionTypeWebSocket: @@ -272,6 +291,7 @@ bool RemoteProxyConnection::connectServer(const QHostAddress &serverAddress, qui connect(m_connection, &ProxyConnection::sslErrorOccured, this, &RemoteProxyConnection::onConnectionSslError); m_jsonClient = new JsonRpcClient(m_connection, this); + connect(m_jsonClient, &JsonRpcClient::tunnelEstablished, this, &RemoteProxyConnection::onTunnelEstablished); qCDebug(dcRemoteProxyClientConnection()) << "Connecting to" << m_connection->serverUrl().toString(); m_connection->connectServer(serverAddress, port); @@ -288,6 +308,8 @@ bool RemoteProxyConnection::authenticate(const QString &token) return false; } + setState(StateAuthenticating); + qCDebug(dcRemoteProxyClientConnection()) << "Start authentication using token" << token; JsonReply *reply = m_jsonClient->callAuthenticate(m_clientUuid, m_clientName, token); connect(reply, &JsonReply::finished, this, &RemoteProxyConnection::onAuthenticateFinished); @@ -296,10 +318,10 @@ bool RemoteProxyConnection::authenticate(const QString &token) void RemoteProxyConnection::disconnectServer() { - if (m_connection) - qCDebug(dcRemoteProxyClientConnection()) << "Disconnect from" << m_connection->serverUrl().toString(); - - cleanUp(); + if (m_connection) { + qCDebug(dcRemoteProxyClientConnection()) << "Disconnecting from" << m_connection->serverUrl().toString(); + m_connection->disconnectServer(); + } } } diff --git a/libnymea-remoteproxyclient/remoteproxyconnection.h b/libnymea-remoteproxyclient/remoteproxyconnection.h index 4097d69..0872f02 100644 --- a/libnymea-remoteproxyclient/remoteproxyconnection.h +++ b/libnymea-remoteproxyclient/remoteproxyconnection.h @@ -46,7 +46,7 @@ public: }; Q_ENUM(Error) - explicit RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, ConnectionType connectionType = ConnectionTypeWebSocket, QObject *parent = nullptr); + explicit RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, ConnectionType connectionType = RemoteProxyConnection::ConnectionTypeWebSocket, QObject *parent = nullptr); ~RemoteProxyConnection(); RemoteProxyConnection::State state() const; @@ -54,6 +54,7 @@ public: QString errorString() const; bool isConnected() const; + bool isAuthenticated() const; bool isRemoteConnected() const; RemoteProxyConnection::ConnectionType connectionType() const; @@ -100,9 +101,11 @@ private: signals: void connected(); - void disconnected(); void ready(); - void remoteConnectedChanged(bool remoteConnected); + void authenticated(); + void remoteConnectionEstablished(); + void disconnected(); + void stateChanged(RemoteProxyConnection::State state); void errorOccured(RemoteProxyConnection::Error error); @@ -116,6 +119,7 @@ private slots: void onHelloFinished(); void onAuthenticateFinished(); + void onTunnelEstablished(const QString &clientName, const QString &clientUuid); public slots: bool connectServer(const QHostAddress &serverAddress, quint16 port); @@ -126,8 +130,8 @@ public slots: } -Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::State); Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::Error); +Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::State); Q_DECLARE_METATYPE(remoteproxyclient::RemoteProxyConnection::ConnectionType); #endif // REMOTEPROXYCONNECTOR_H diff --git a/libnymea-remoteproxyclient/websocketconnection.cpp b/libnymea-remoteproxyclient/websocketconnection.cpp index d689a61..1111a78 100644 --- a/libnymea-remoteproxyclient/websocketconnection.cpp +++ b/libnymea-remoteproxyclient/websocketconnection.cpp @@ -54,6 +54,7 @@ void WebSocketConnection::onDisconnected() void WebSocketConnection::onError(QAbstractSocket::SocketError error) { qCDebug(dcRemoteProxyClientWebSocket()) << "Socket error occured" << error << m_webSocket->errorString(); + emit errorOccured(); } void WebSocketConnection::onSslError(const QList &errors) @@ -104,6 +105,9 @@ void WebSocketConnection::connectServer(const QHostAddress &address, quint16 por void WebSocketConnection::disconnectServer() { + if (!isConnected()) + return; + qCDebug(dcRemoteProxyClientWebSocket()) << "Disconnecting from" << serverUrl().toString(); m_webSocket->close(); } diff --git a/tests/mockauthenticator.cpp b/tests/mockauthenticator.cpp index 2163369..2bec341 100644 --- a/tests/mockauthenticator.cpp +++ b/tests/mockauthenticator.cpp @@ -35,7 +35,6 @@ void MockAuthenticator::replyFinished() setReplyFinished(reply->authenticationReply()); } - AuthenticationReply *MockAuthenticator::authenticate(ProxyClient *proxyClient) { qCDebug(dcAuthenticator()) << name() << "Start authentication for" << proxyClient << "using token" << proxyClient->token(); diff --git a/tests/nymea-remoteproxy-tests.cpp b/tests/nymea-remoteproxy-tests.cpp index c30a251..b39c90b 100644 --- a/tests/nymea-remoteproxy-tests.cpp +++ b/tests/nymea-remoteproxy-tests.cpp @@ -36,6 +36,20 @@ RemoteProxyTests::RemoteProxyTests(QObject *parent) : m_sslConfiguration.setLocalCertificate(QSslCertificate(certificateData, QSsl::Pem)); m_sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); m_sslConfiguration.setProtocol(QSsl::TlsV1_2OrLater); + + m_testToken = "eyJraWQiOiJXdnFFT3prVVh5VDlINzFyRUpoNWdxRnkxNFhnR2l3SFAzVEIzUFQ1V3ZrPSIsImFsZyI6IlJT" + "MjU2In0.eyJzdWIiOiJmZTJmZDNlNC1hMGJhLTQ1OTUtOWRiZS00ZDkxYjRiMjFlMzUiLCJhdWQiOiI4cmpoZ" + "mRsZjlqZjFzdW9rMmpjcmx0ZDZ2IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImV2ZW50X2lkIjoiN2Y5NTRiNm" + "ItOTYyZi0xMWU4LWI0ZjItMzU5NWRiZmRiODVmIiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE1MzM" + "xOTkxMzgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5ldS13ZXN0LTEuYW1hem9uYXdzLmNvbVwvZXUt" + "d2VzdC0xXzZlWDZZam1YciIsImNvZ25pdG86dXNlcm5hbWUiOiIyYzE3YzUwZC0xZDFlLTRhM2UtYmFjOS0zZ" + "DI0YjQ1MTFiYWEiLCJleHAiOjE1MzMyMDI3MzgsImlhdCI6MTUzMzE5OTEzOCwiZW1haWwiOiJqZW5raW5zQG" + "d1aC5pbyJ9.hMMSvZMx7pMvV70PaUmTZOZgdez5WGX5yagRFPZojBm8jNWZND1lUmi0RFkybeD4HonDiKHxTF" + "_psyJoBVndgHbxYBBl3Np4gn0MxECWjvLxYzGxVBBkN24SqNUyAGkr0uFcZKkBecdtJlqNQnZN8Uk49twmODf" + "raRaRmGmKmRBAK1qDITpUgP6AWqH9xoJWaoDzt0kwJ3EtPxS7vL1PHqOaN8ggXA8Eq4iTCSfXU1HAXhIWJH9Y" + "pQbj58v1vktaAEATdmKmlzmcix-HJK9wWHRSuv3TsNa8DGxvcPOoeTu8Vql7krZ-y7Zu-s2WsgeP4VxyT80VE" + "T_xh6pMkOhE6g"; + } void RemoteProxyTests::cleanUpEngine() @@ -177,6 +191,8 @@ QVariant RemoteProxyTests::injectSocketData(const QByteArray &data) void RemoteProxyTests::initTestCase() { qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); qCDebug(dcApplication()) << "Init test case."; restartEngine(); @@ -301,19 +317,19 @@ void RemoteProxyTests::authenticate_data() QTest::addColumn("timeout"); QTest::addColumn("expectedError"); - QTest::newRow("success") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << "Hh5JrkdFVstVVyCnfE3vVT3zG_JTacXEhPLZhCei" + QTest::newRow("success") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << 100 << Authenticator::AuthenticationErrorNoError; - QTest::newRow("failed") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << "invalid_token_42" + QTest::newRow("failed") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << 100 << Authenticator::AuthenticationErrorAuthenticationFailed; - QTest::newRow("not responding") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << "invalid_token_42" + QTest::newRow("not responding") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << 200 << Authenticator::AuthenticationErrorAuthenticationServerNotResponding; - QTest::newRow("aborted") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << "invalid_token_42" + QTest::newRow("aborted") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << 100 << Authenticator::AuthenticationErrorAborted; - QTest::newRow("unknown") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << "invalid_token_42" + QTest::newRow("unknown") << QUuid::createUuid().toString() << "Testclient, hello form the test!" << m_testToken << 100 << Authenticator::AuthenticationErrorUnknown; } @@ -352,90 +368,189 @@ void RemoteProxyTests::clientConnection() // Start the server startServer(); - // Connect to the server (insecure disabled) - RemoteProxyConnection *connectorOne = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", RemoteProxyConnection::ConnectionTypeWebSocket, this); - connectorOne->setInsecureConnection(true); - - // Connect to server (insecue enabled for testing) - QSignalSpy readySpy(connectorOne, &RemoteProxyConnection::ready); - QVERIFY(connectorOne->connectServer(QHostAddress::LocalHost, m_port)); - readySpy.wait(); - QVERIFY(readySpy.count() == 1); - QVERIFY(connectorOne->isConnected()); - QVERIFY(connectorOne->state() == RemoteProxyConnection::StateReady); - - // Authenticate + // Configure moch authenticator m_authenticator->setTimeoutDuration(100); m_authenticator->setExpectedAuthenticationError(); - connectorOne->authenticate("foobar"); - QTest::qWait(1000); + // Connect to the server (insecure disabled) + RemoteProxyConnection *connection = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", RemoteProxyConnection::ConnectionTypeWebSocket, this); + connection->setInsecureConnection(true); + + // Connect to server (insecue enabled for testing) + QSignalSpy readySpy(connection, &RemoteProxyConnection::ready); + QVERIFY(connection->connectServer(QHostAddress::LocalHost, m_port)); + readySpy.wait(); + QVERIFY(readySpy.count() == 1); + QVERIFY(connection->isConnected()); + QVERIFY(!connection->isRemoteConnected()); + QVERIFY(connection->state() == RemoteProxyConnection::StateReady); + QVERIFY(connection->error() == RemoteProxyConnection::ErrorNoError); + QVERIFY(connection->serverAddress() == QHostAddress::LocalHost); + QVERIFY(connection->serverPort() == m_port); + QVERIFY(connection->connectionType() == RemoteProxyConnection::ConnectionTypeWebSocket); + QVERIFY(connection->insecureConnection() == true); + QVERIFY(connection->serverName() == SERVER_NAME_STRING); + QVERIFY(connection->proxyServerName() == Engine::instance()->serverName()); + QVERIFY(connection->proxyServerVersion() == SERVER_VERSION_STRING); + QVERIFY(connection->proxyServerApiVersion() == API_VERSION_STRING); + + QSignalSpy authenticatedSpy(connection, &RemoteProxyConnection::authenticated); + QVERIFY(connection->authenticate("foobar")); + authenticatedSpy.wait(); + QVERIFY(authenticatedSpy.count() == 1); + QVERIFY(connection->isConnected()); + QVERIFY(connection->isAuthenticated()); + QVERIFY(connection->state() == RemoteProxyConnection::StateWaitTunnel); // Disconnect and clean up - QSignalSpy spyDisconnected(connectorOne, &RemoteProxyConnection::disconnected); - connectorOne->disconnectServer(); - spyDisconnected.wait(); - QVERIFY(!connectorOne->isConnected()); + QSignalSpy spyDisconnected(connection, &RemoteProxyConnection::disconnected); + connection->disconnectServer(); + // FIXME: check why it waits the full time here + spyDisconnected.wait(100); + QVERIFY(spyDisconnected.count() == 1); + QVERIFY(!connection->isConnected()); - connectorOne->deleteLater(); + connection->deleteLater(); + stopServer(); +} + +void RemoteProxyTests::remoteConnection() +{ + // Start the server + startServer(); + + // Configure moch authenticator + m_authenticator->setTimeoutDuration(100); + m_authenticator->setExpectedAuthenticationError(); + + // Create two connection + RemoteProxyConnection *connectionOne = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", RemoteProxyConnection::ConnectionTypeWebSocket, this); + connectionOne->setInsecureConnection(true); + + RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(QUuid::createUuid(), "Test client two", RemoteProxyConnection::ConnectionTypeWebSocket, this); + connectionTwo->setInsecureConnection(true); + + // Connect one + QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); + QVERIFY(connectionOne->connectServer(QHostAddress::LocalHost, m_port)); + connectionOneReadySpy.wait(); + QVERIFY(connectionOneReadySpy.count() == 1); + QVERIFY(connectionOne->isConnected()); + + // Connect two + QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); + QVERIFY(connectionTwo->connectServer(QHostAddress::LocalHost, m_port)); + connectionTwoReadySpy.wait(); + QVERIFY(connectionTwoReadySpy.count() == 1); + QVERIFY(connectionTwo->isConnected()); + + // Authenticate one + QSignalSpy remoteConnectionEstablishedOne(connectionOne, &RemoteProxyConnection::remoteConnectionEstablished); + QSignalSpy connectionOneAuthenticatedSpy(connectionOne, &RemoteProxyConnection::authenticated); + QVERIFY(connectionOne->authenticate(m_testToken)); + connectionOneAuthenticatedSpy.wait(); + QVERIFY(connectionOneAuthenticatedSpy.count() == 1); + QVERIFY(connectionOne->isConnected()); + QVERIFY(connectionOne->isAuthenticated()); + QVERIFY(connectionOne->state() == RemoteProxyConnection::StateWaitTunnel); + + // Authenticate two + QSignalSpy remoteConnectionEstablishedTwo(connectionTwo, &RemoteProxyConnection::remoteConnectionEstablished); + QSignalSpy connectionTwoAuthenticatedSpy(connectionTwo, &RemoteProxyConnection::authenticated); + QVERIFY(connectionTwo->authenticate(m_testToken)); + connectionTwoAuthenticatedSpy.wait(); + QVERIFY(connectionTwoAuthenticatedSpy.count() == 1); + QVERIFY(connectionTwo->isConnected()); + QVERIFY(connectionTwo->isAuthenticated()); + + // Wait for both to be connected + remoteConnectionEstablishedOne.wait(); + remoteConnectionEstablishedTwo.wait(); + + QVERIFY(remoteConnectionEstablishedOne.count() == 1); + QVERIFY(remoteConnectionEstablishedTwo.count() == 1); + QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); + QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); + + // Pipe data trought the tunnel + QSignalSpy remoteConnectionDataOne(connectionOne, &RemoteProxyConnection::dataReady); + QSignalSpy remoteConnectionDataTwo(connectionTwo, &RemoteProxyConnection::dataReady); + + QByteArray dataOne = "Hello from client one :-)"; + QByteArray dataTwo = "Hello from client two :-)"; + + connectionOne->sendData(dataOne); + remoteConnectionDataTwo.wait(); + QVERIFY(remoteConnectionDataTwo.count() == 1); + + // verify if data is the same + + connectionTwo->sendData(dataTwo); + remoteConnectionDataOne.wait(); + QVERIFY(remoteConnectionDataOne.count() == 1); + + // verify if data is the same + + connectionOne->deleteLater(); + connectionTwo->deleteLater(); + + // Clean up stopServer(); } void RemoteProxyTests::sslConfigurations() { -// // Start the server -// startServer(); + // // Start the server + // startServer(); -// // Connect to the server (insecure disabled) -// RemoteProxyConnection *connector = new RemoteProxyConnection(RemoteProxyConnection::ConnectionTypeWebSocket, this); -// connector->setInsecureConnection(false); + // // Connect to the server (insecure disabled) + // RemoteProxyConnection *connector = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", RemoteProxyConnection::ConnectionTypeWebSocket, this); + // QSignalSpy spyError(connector, &RemoteProxyConnection::errorOccured); + // QVERIFY(connector->connectServer(QHostAddress::LocalHost, m_port)); + // spyError.wait(); + // QVERIFY(spyError.count() == 1); + // QVERIFY(connector->error() == RemoteProxyConnection::ErrorSslError); + // QVERIFY(connector->state() == RemoteProxyConnection::StateDisconnected); -// QSignalSpy spyError(connector, &RemoteProxyConnection::errorOccured); -// connector->connectServer(QHostAddress::LocalHost, m_port); -// spyError.wait(); + // // Connect to server (insecue enabled) + // QSignalSpy spyConnected(connector, &RemoteProxyConnection::connected); + // connector->setInsecureConnection(true); + // connector->connectServer(QHostAddress::LocalHost, m_port); + // spyConnected.wait(); -// QCOMPARE(connector->error(), RemoteProxyConnection::ErrorSslError); -// QCOMPARE(connector->state(), RemoteProxyConnection::StateDisconnected); + // QVERIFY(connector->isConnected()); -// // Connect to server (insecue enabled) -// QSignalSpy spyConnected(connector, &RemoteProxyConnection::connected); -// connector->setInsecureConnection(true); -// connector->connectServer(QHostAddress::LocalHost, m_port); -// spyConnected.wait(); + // // Disconnect and clean up + // connector->disconnectServer(); + // QVERIFY(!connector->isConnected()); -// QVERIFY(connector->isConnected()); - -// // Disconnect and clean up -// connector->disconnectServer(); -// QVERIFY(!connector->isConnected()); - -// connector->deleteLater(); -// stopServer(); + // connector->deleteLater(); + // stopServer(); } void RemoteProxyTests::timeout() { - // Start the server - startServer(); + // // Start the server + // startServer(); - // Configure result - // Start the server - startServer(); + // // Configure result + // // Start the server + // startServer(); - // Configure result - m_authenticator->setExpectedAuthenticationError(); - m_authenticator->setTimeoutDuration(6000); + // // Configure result + // m_authenticator->setExpectedAuthenticationError(); + // m_authenticator->setTimeoutDuration(6000); - // Create request - QVariantMap params; - params.insert("uuid", "uuid"); - params.insert("name", "name"); - params.insert("token", "token"); + // // Create request + // QVariantMap params; + // params.insert("uuid", "uuid"); + // params.insert("name", "name"); + // params.insert("token", "token"); - QVariant response = invokeApiCall("Authentication.Authenticate", params); - qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - // Clean up - stopServer(); + // QVariant response = invokeApiCall("Authentication.Authenticate", params); + // qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); + // // Clean up + // stopServer(); } QTEST_MAIN(RemoteProxyTests) diff --git a/tests/nymea-remoteproxy-tests.h b/tests/nymea-remoteproxy-tests.h index f689ab1..5764d54 100644 --- a/tests/nymea-remoteproxy-tests.h +++ b/tests/nymea-remoteproxy-tests.h @@ -28,6 +28,7 @@ private: QHostAddress m_serverAddress = QHostAddress::LocalHost; QSslConfiguration m_sslConfiguration; MockAuthenticator *m_authenticator = nullptr; + QString m_testToken; int m_commandCounter = 0; @@ -63,10 +64,11 @@ private slots: void authenticate(); // Client lib + void clientConnection(); + void remoteConnection(); void sslConfigurations(); void timeout(); - void clientConnection(); public slots: