From fe05340629fb2ea2233317cec425e7f445a5d2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 3 Sep 2018 17:00:25 +0200 Subject: [PATCH] Add nonce option to client and improve test coverage --- client/main.cpp | 5 +- client/proxyclient.cpp | 5 +- client/proxyclient.h | 3 +- .../nymea-remoteproxy-tests-offline.cpp | 74 ++++++++++++++++++- 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/client/main.cpp b/client/main.cpp index 5586ac5..8dd3521 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -104,6 +104,9 @@ int main(int argc, char *argv[]) QCommandLineOption tokenOption(QStringList() << "t" << "token", "The AWS token for authentication.", "token"); parser.addOption(tokenOption); + QCommandLineOption nonceOption(QStringList() << "n" << "nonce", "The shared connection unique nonce for this tunnel.", "nonce"); + parser.addOption(nonceOption); + QCommandLineOption insecureOption(QStringList() << "i" << "igore-ssl", "Ignore SSL certificate errors."); parser.addOption(insecureOption); @@ -159,7 +162,7 @@ int main(int argc, char *argv[]) ProxyClient client(parser.value(nameOption), uuid); client.setInsecure(parser.isSet(insecureOption)); client.setPingpong(parser.isSet(pingPongOption)); - client.start(serverUrl, parser.value(tokenOption)); + client.start(serverUrl, parser.value(tokenOption), parser.value(nonceOption)); return application.exec(); } diff --git a/client/proxyclient.cpp b/client/proxyclient.cpp index 6cb1430..4800d2c 100644 --- a/client/proxyclient.cpp +++ b/client/proxyclient.cpp @@ -61,7 +61,7 @@ void ProxyClient::onClientReady() { qCDebug(dcProxyClient()) << "Connected to proxy server" << m_connection->serverUrl().toString(); qCDebug(dcProxyClient()) << "Start authentication"; - m_connection->authenticate(m_token); + m_connection->authenticate(m_token, m_nonce); } void ProxyClient::onAuthenticationFinished() @@ -111,8 +111,9 @@ void ProxyClient::sendPing() m_connection->sendData(data); } -void ProxyClient::start(const QUrl &url, const QString &token) +void ProxyClient::start(const QUrl &url, const QString &token, const QString &nonce) { m_token = token; + m_nonce = nonce; m_connection->connectServer(url); } diff --git a/client/proxyclient.h b/client/proxyclient.h index abf9c58..f401797 100644 --- a/client/proxyclient.h +++ b/client/proxyclient.h @@ -44,6 +44,7 @@ private: QString m_name; QUuid m_uuid; QString m_token; + QString m_nonce; bool m_insecure = false; bool m_pingpong = false; @@ -61,7 +62,7 @@ private slots: void sendPing(); public slots: - void start(const QUrl &url, const QString &token); + void start(const QUrl &url, const QString &token, const QString &nonce); }; diff --git a/tests/test-offline/nymea-remoteproxy-tests-offline.cpp b/tests/test-offline/nymea-remoteproxy-tests-offline.cpp index eef6296..76a8d3e 100644 --- a/tests/test-offline/nymea-remoteproxy-tests-offline.cpp +++ b/tests/test-offline/nymea-remoteproxy-tests-offline.cpp @@ -81,8 +81,78 @@ void RemoteProxyOfflineTests::monitorServer() startServer(); QVERIFY(Engine::instance()->monitorServer()->running()); - QLocalSocket *monitor = new QLocalSocket(this); + // Create a tunnel + // Configure mock authenticator + m_mockAuthenticator->setTimeoutDuration(100); + m_mockAuthenticator->setExpectedAuthenticationError(); + + QString nameConnectionOne = "Test client one"; + QUuid uuidConnectionOne = QUuid::createUuid(); + + QString nameConnectionTwo = "Test client two"; + QUuid uuidConnectionTwo = QUuid::createUuid(); + + QByteArray dataOne = "Hello from client one :-)"; + QByteArray dataTwo = "Hello from client two :-)"; + + // Create two connection + RemoteProxyConnection *connectionOne = new RemoteProxyConnection(uuidConnectionOne, nameConnectionOne, this); + connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); + + RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(uuidConnectionTwo, nameConnectionTwo, this); + connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); + + // Connect one + QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); + QVERIFY(connectionOne->connectServer(m_serverUrl)); + connectionOneReadySpy.wait(); + QVERIFY(connectionOneReadySpy.count() == 1); + QVERIFY(connectionOne->isConnected()); + + // Connect two + QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); + QVERIFY(connectionTwo->connectServer(m_serverUrl)); + 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::StateAuthenticated); + + // 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(500); + remoteConnectionEstablishedTwo.wait(500); + + QVERIFY(remoteConnectionEstablishedOne.count() == 1); + QVERIFY(remoteConnectionEstablishedTwo.count() == 1); + QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); + QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); + + QCOMPARE(connectionOne->tunnelPartnerName(), nameConnectionTwo); + QCOMPARE(connectionOne->tunnelPartnerUuid(), uuidConnectionTwo.toString()); + QCOMPARE(connectionTwo->tunnelPartnerName(), nameConnectionOne); + QCOMPARE(connectionTwo->tunnelPartnerUuid(), uuidConnectionOne.toString()); + + + // Get monitor data + QLocalSocket *monitor = new QLocalSocket(this); QSignalSpy connectedSpy(monitor, &QLocalSocket::connected); monitor->connectToServer(m_configuration->monitorSocketFileName()); connectedSpy.wait(200); @@ -102,6 +172,8 @@ void RemoteProxyOfflineTests::monitorServer() // Clean up monitor->deleteLater(); + connectionOne->deleteLater(); + connectionTwo->deleteLater(); stopServer(); }