Add first online test

This commit is contained in:
Simon Stürz 2018-08-15 14:56:23 +02:00
parent 8f5cc9b6cb
commit 6622fa1265
33 changed files with 679 additions and 227 deletions

2
.gitignore vendored
View File

@ -73,3 +73,5 @@ Thumbs.db
coverage-html
client/nymea-remoteproxy-client
tests/test-offline/nymea-remoteproxy-tests-offline
tests/test-online/nymea-remoteproxy-tests-online

308
README.md
View File

@ -0,0 +1,308 @@
# nymea remote proxy server
----------------------------------------------
The nymea remote proxy server is the meeting point of nymea servers and nymea clients in order to establishing a secure remote connection.
# Build
In order to build the proxy server you need to install the qt default package.
apt install qt5-default
Change into the source directory and run following commands
cd nymea-remoteproxy
mkdir build
cd build
qmake ../
make -j$(nproc)
In the build directory you can find the resulting library and binary files.
If you want to start the proxy server from the build directory, you need to export the library path before starting the application:
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/libnymea-remoteproxy:$(pwd)/libnymea-remoteproxyclient
$ ./server/nymea-remoteproxy -c ../nymea-remoteproxy/tests/test-certificate.crt -k ../nymea-remoteproxy/tests/test-certificate.key
## AWS SDK
Get the latest source code and build dependecies
$ apt update
$ apt install git build-essential cmake libcurl4-openssl-dev libssl-dev uuid-dev zlib1g-dev libpulse-dev
$ git clone https://github.com/aws/aws-sdk-cpp.git
Create the build and install folder
$ cd aws-sdk-cpp
$ mkdir -p build/install
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_ONLY="lambda" -DCMAKE_INSTALL_PREFIX=$(pwd)/install ../
$ make -j$(nproc)
Install build output into install directory
$ make install
#### Building debian package
$ git clone https://github.com/aws/aws-sdk-cpp.git
$ cd aws-sdk-cpp
$ git clone git@gitlab.guh.io:cloud/aws-sdk-cpp-debian.git debian
$ crossbuilder
# Install
# Configure
# Test
In order to run the test, you can call `make check` in the build directory or run the resulting executable:
$ nymea-remoteproxy-tests
## Test coverage report
If you want to create a line coverage report from the tests simply run following command in the source directory:
$ apt install lcov gcovr
$ ./create-coverage-html.sh
The resulting coverage report will be place in the `coverage-html` directory.
# Usage
In order to get information about the server you can start the command with the `--help` parameter.
$ nymea-remoteproxy --help
Usage: nymea-remoteproxy [options]
The nymea remote proxy server. This server allowes nymea-cloud users and registered nymea deamons to establish a tunnel connection.
Server version: 0.0.1
API version: 0.1
Copyright © 2018 Simon Stürz <simon.stuerz@guh.io>
Options:
-h, --help Displays this help.
-v, --version Displays version information.
-l, --logging <logfile> Write log file to the given logfile.
-s, --server <hostaddress> The server address this proxy will
listen on. Default is 127.0.0.1
-p, --port <port> The proxy server port. Default is
1212
-c, --certificate <certificate> The path to the SSL certificate used
for this proxy server.
-k, --certificate-key <certificate-key> The path to the SSL certificate key
used for this proxy server.
-a, --authentication-server <url> The server url of the AWS
authentication server.
# Server API
Once a client connects to the proxy server, he must authenticate him self by passing the token received from the nymea-cloud mqtt connection request.
## Message format
#### Request
{
"id": integer,
"method": "Namespace.Method",
"o:params" { }
}
#### Response
{
"id": integer,
"status": "string",
"o:params" { },
"o:error": "string"
}
#### Notification
{
"id": integer,
"notification": "Namespace.Notification",
"o:params" { }
}
## Say Hello
#### Request
{
"id": 0,
"method": "RemoteProxy.Hello"
}
#### Response
{
"id": 0,
"params": {
"apiVersion": "0.1",
"name": "nymea-remoteproxy-testserver",
"server": "nymea-remoteproxy",
"version": "0.0.1"
},
"status": "success"
}
## Authenticate the connection
The first data a client **must** send to the proxy server is the authentication request. This request contains the token which will be verified agains the nymea-cloud infrastructure.
#### Request
{
"id": 1,
"method": "Authentication.Authenticate",
"params": {
"id": "string",
"name": "string",
"token": "tokenstring"
}
}
#### Response
* **On Success**: If the token was authenticated successfully, the response will look like this:
{
"id": 1,
"status": "success"
}
* **On Failure** If the token was invalid, the response will look like this and the server will close the connection immediatly:
{
"id": 1,
"status": "error",
"error": "Invalid token. You are not allowed to use this server."
}
#### Tunnel established
Once the other client is here and ready, the server will send a notification to the clients indicating that the tunnel has been established successfully. This message is the last data comming from the proxy server.
> **Important:** Any data traffic following after this notification comes from the tunnel endpoint, __not__ from the __proxy server__ any more.
{
"id": "0",
"notification": "RemoteProxy.TunnelEstablished",
"params": {
"name": "String",
"uuid": "String"
}
}
## Introspect the API
#### Request
{
"id": 0,
"method": "RemoteProxy.Introspect"
}
#### Response
{
"id": 0,
"params": {
"methods": {
"Authentication.Authenticate": {
"description": "Authenticate this connection. The returned AuthenticationError informs about the result. If the authentication was not successfull, the server will close the connection immediatly after sending the error response. The given id should be a unique id the other tunnel client can understand. Once the authentication was successfull, you can wait for the RemoteProxy.TunnelEstablished notification. If you send any data before getting this notification, the server will close the connection. If the tunnel client does not show up within 10 seconds, the server will close the connection.",
"params": {
"name": "String",
"token": "String",
"uuid": "String"
},
"returns": {
"authenticationError": "$ref:AuthenticationError"
}
},
"RemoteProxy.Hello": {
"description": "Once connected to this server, a client can get information about the server by saying Hello. The response informs the client about this proxy server.",
"params": {
},
"returns": {
"apiVersion": "String",
"name": "String",
"server": "String",
"version": "String"
}
},
"RemoteProxy.Introspect": {
"description": "Introspect this API.",
"params": {
},
"returns": {
"methods": "Object",
"notifications": "Object",
"types": "Object"
}
}
},
"notifications": {
"RemoteProxy.TunnelEstablished": {
"description": "Emitted whenever the tunnel has been established successfully. This is the last message from the remote proxy server! Any following data will be from the other tunnel client until the connection will be closed. The parameter contain some information about the other tunnel client.",
"params": {
"name": "String",
"uuid": "String"
}
}
},
"types": {
"AuthenticationError": [
"AuthenticationErrorNoError",
"AuthenticationErrorUnknown",
"AuthenticationErrorTimeout",
"AuthenticationErrorAborted",
"AuthenticationErrorAuthenticationFailed",
"AuthenticationErrorAuthenticationServerNotResponding"
],
"BasicType": [
"Uuid",
"String",
"Int",
"UInt",
"Double",
"Bool",
"Variant",
"Object"
]
}
},
"status": "success"
}
# License
This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.

View File

@ -4,7 +4,7 @@
ProxyClient::ProxyClient(QObject *parent) :
QObject(parent)
{
m_connection = new RemoteProxyConnection(QUuid::createUuid(), "nymea-remoteproxy-client", RemoteProxyConnection::ConnectionTypeWebSocket, this);
m_connection = new RemoteProxyConnection(QUuid::createUuid(), "nymea-remoteproxy-client", this);
m_connection->setInsecureConnection(true);
connect(m_connection, &RemoteProxyConnection::ready, this, &ProxyClient::onClientReady);
connect(m_connection, &RemoteProxyConnection::authenticated, this, &ProxyClient::onAuthenticationFinished);

View File

@ -8,9 +8,28 @@ qmake CONFIG+=coverage
make -j$(nproc)
make coverage-html
# Clean up source directory
rm -v libnymea-remoteproxy/libnymea-remoteproxy.so*
rm -v libnymea-remoteproxyclient/libnymea-remoteproxyclient.so*
rm -v server/nymea-remoteproxy
rm -v tests/nymea-remoteproxy-tests
# Clean build
make clean
# Clean source directory
rm -v Makefile
rm -v libnymea-remoteproxy/libnymea-remoteproxy.so*
rm -v libnymea-remoteproxy/Makefile
rm -v libnymea-remoteproxyclient/libnymea-remoteproxyclient.so*
rm -v libnymea-remoteproxyclient/Makefile
rm -v server/nymea-remoteproxy
rm -v server/Makefile
rm -v tests/Makefile
rm -v tests/test-offline/nymea-remoteproxy-tests-offline
rm -v tests/test-offline/Makefile
rm -v tests/test-online/nymea-remoteproxy-tests-online
rm -v tests/test-online/Makefile
rm -v client/nymea-remoteproxy-client
rm -v client/Makefile

View File

View File

@ -52,7 +52,7 @@ void AuthenticationReply::onTimeout()
m_error = Authenticator::AuthenticationErrorTimeout;
m_timer->stop();
m_process->kill();
emit finished();
QTimer::singleShot(0, this, &AuthenticationReply::finished);
}
void AuthenticationReply::abort()
@ -60,7 +60,7 @@ void AuthenticationReply::abort()
m_error = Authenticator::AuthenticationErrorAborted;
m_timer->stop();
m_process->kill();
emit finished();
QTimer::singleShot(0, this, &AuthenticationReply::finished);
}
}

View File

@ -30,7 +30,7 @@ void AwsAuthenticator::onAuthenticationProcessFinished(Authenticator::Authentica
setReplyError(reply, error);
setReplyFinished(reply);
qCDebug(dcAuthentication()) << "" << error;
qCDebug(dcAuthentication()) << name() << "finished with error" << error;
}
AuthenticationReply *AwsAuthenticator::authenticate(ProxyClient *proxyClient)

View File

@ -32,9 +32,6 @@ bool Engine::exists()
void Engine::start(ProxyConfiguration *configuration)
{
// Make sure an authenticator was registered
Q_ASSERT_X(m_authenticator != nullptr, "Engine", "There is no authenticator registerd.");
if (!m_running)
qCDebug(dcEngine()) << "Start server engine";
@ -42,10 +39,13 @@ void Engine::start(ProxyConfiguration *configuration)
clean();
m_configuration = configuration;
Q_ASSERT_X(configuration != nullptr, "Engine", "There is no configuration set.");
qCDebug(dcApplication()) << "Using configuration" << m_configuration;
// Make sure an authenticator was registered
Q_ASSERT_X(m_authenticator != nullptr, "Engine", "There is no authenticator registerd.");
m_proxyServer = new ProxyServer(this);
m_webSocketServer = new WebSocketServer(m_sslConfiguration, this);
m_webSocketServer = new WebSocketServer(m_configuration->sslConfiguration(), this);
QUrl websocketServerUrl;
websocketServerUrl.setScheme("wss");
@ -84,32 +84,7 @@ bool Engine::developerMode() const
QString Engine::serverName() const
{
return m_serverName;
}
void Engine::setServerName(const QString &serverName)
{
m_serverName = serverName;
}
void Engine::setConfiguration(ProxyConfiguration *configuration)
{
m_configuration = configuration;
qCDebug(dcApplication()) << "Set configuration" << m_configuration;
}
void Engine::setSslConfiguration(const QSslConfiguration &configuration)
{
m_sslConfiguration = configuration;
qCDebug(dcEngine()) << "SSL certificate information:";
qCDebug(dcEngine()) << " Common name:" << m_sslConfiguration.localCertificate().issuerInfo(QSslCertificate::CommonName);
qCDebug(dcEngine()) << " Organisation:" << m_sslConfiguration.localCertificate().issuerInfo(QSslCertificate::Organization);
qCDebug(dcEngine()) << " Organisation unit name:" << m_sslConfiguration.localCertificate().issuerInfo(QSslCertificate::OrganizationalUnitName);
qCDebug(dcEngine()) << " Country name:" << m_sslConfiguration.localCertificate().issuerInfo(QSslCertificate::CountryName);
qCDebug(dcEngine()) << " Locality name:" << m_sslConfiguration.localCertificate().issuerInfo(QSslCertificate::LocalityName);
qCDebug(dcEngine()) << " State/Province:" << m_sslConfiguration.localCertificate().issuerInfo(QSslCertificate::StateOrProvinceName);
qCDebug(dcEngine()) << " Email address:" << m_sslConfiguration.localCertificate().issuerInfo(QSslCertificate::EmailAddress);
return m_configuration->serverName();
}
void Engine::setAuthenticator(Authenticator *authenticator)

View File

@ -29,12 +29,8 @@ public:
bool developerMode() const;
QString serverName() const;
void setServerName(const QString &serverName);
void setConfiguration(ProxyConfiguration *configuration);
void setSslConfiguration(const QSslConfiguration &configuration);
void setAuthenticator(Authenticator *authenticator);
void setDeveloperModeEnabled(bool enabled);
Authenticator *authenticator() const;
@ -48,9 +44,7 @@ private:
bool m_running = false;
bool m_developerMode = false;
QString m_serverName;
QSslConfiguration m_sslConfiguration;
ProxyConfiguration *m_configuration = nullptr;
Authenticator *m_authenticator = nullptr;
ProxyServer *m_proxyServer = nullptr;

View File

@ -1,7 +1,10 @@
#include "loggingcategories.h"
#include "proxyconfiguration.h"
#include <QFile>
#include <QSslKey>
#include <QFileInfo>
#include <QSslCertificate>
namespace remoteproxy {
@ -26,6 +29,7 @@ bool ProxyConfiguration::loadConfiguration(const QString &fileName)
QSettings settings(fileName, QSettings::IniFormat);
setServerName(settings.value("name", "nymea-remoteproxy").toString());
setWriteLogFile(settings.value("writeLogs", false).toBool());
setLogFileName(settings.value("logFile", "/var/log/nymea-remoteproxy.log").toString());
setSslCertificateFileName(settings.value("certificate", "/etc/ssl/certs/ssl-cert-snakeoil.pem").toString());
@ -41,9 +45,50 @@ bool ProxyConfiguration::loadConfiguration(const QString &fileName)
setTcpServerPort(static_cast<quint16>(settings.value("port", 1213).toInt()));
settings.endGroup();
// Load ssl configuration
QSslConfiguration sslConfiguration;
// Load certificate
QFile certFile(sslCertificateFileName());
if (!certFile.open(QIODevice::ReadOnly)) {
qCWarning(dcApplication()) << "Could not open certificate file" << sslCertificateFileName() << certFile.errorString();
return false;
}
QSslCertificate certificate(&certFile, QSsl::Pem);
qCDebug(dcApplication()) << "Loaded successfully certificate" << sslCertificateFileName();
certFile.close();
// Create SSL configuration
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
sslConfiguration.setLocalCertificate(certificate);
sslConfiguration.setProtocol(QSsl::TlsV1_2OrLater);
// SSL key
QFile certKeyFile(sslCertificateKeyFileName());
if (!certKeyFile.open(QIODevice::ReadOnly)) {
qCWarning(dcApplication()) << "Could not open certificate key file:" << sslCertificateKeyFileName() << certKeyFile.errorString();
return false;
}
QSslKey sslKey(&certKeyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
qCDebug(dcApplication()) << "Loaded successfully certificate key" << sslCertificateKeyFileName();
certKeyFile.close();
sslConfiguration.setPrivateKey(sslKey);
m_sslConfiguration = sslConfiguration;
return true;
}
QString ProxyConfiguration::serverName() const
{
return m_serverName;
}
void ProxyConfiguration::setServerName(const QString &serverName)
{
m_serverName = serverName;
}
bool ProxyConfiguration::writeLogFile() const
{
return m_writeLogFile;
@ -84,6 +129,11 @@ void ProxyConfiguration::setSslCertificateKeyFileName(const QString &fileName)
m_sslCertificateKeyFileName = fileName;
}
QSslConfiguration ProxyConfiguration::sslConfiguration() const
{
return m_sslConfiguration;
}
QHostAddress ProxyConfiguration::webSocketServerHost() const
{
return m_webSocketServerHost;
@ -128,10 +178,19 @@ QDebug operator<<(QDebug debug, ProxyConfiguration *configuration)
{
debug.nospace() << endl << "========== ProxyConfiguration ==========" << endl;
debug.nospace() << "General" << endl;
debug.nospace() << " - name:" << configuration->serverName() << endl;
debug.nospace() << " - write logfile:" << configuration->writeLogFile() << endl;
debug.nospace() << " - logfile:" << configuration->logFileName() << endl;
debug.nospace() << " - certificate:" << configuration->sslCertificateFileName() << endl;
debug.nospace() << " - certificate key:" << configuration->sslCertificateKeyFileName() << endl;
debug.nospace() << " - SSL certificate information:";
debug.nospace() << " Common name:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::CommonName);
debug.nospace() << " Organisation:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::Organization);
debug.nospace() << " Organisation unit name:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::OrganizationalUnitName);
debug.nospace() << " Country name:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::CountryName);
debug.nospace() << " Locality name:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::LocalityName);
debug.nospace() << " State/Province:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::StateOrProvinceName);
debug.nospace() << " Email address:" << configuration->sslConfiguration().localCertificate().issuerInfo(QSslCertificate::EmailAddress);
debug.nospace() << "WebSocketServer" << endl;
debug.nospace() << " - host:" << configuration->webSocketServerHost().toString() << endl;
debug.nospace() << " - port:" << configuration->webSocketServerPort() << endl;

View File

@ -4,6 +4,7 @@
#include <QObject>
#include <QSettings>
#include <QHostAddress>
#include <QSslConfiguration>
namespace remoteproxy {
@ -16,6 +17,9 @@ public:
bool loadConfiguration(const QString &fileName);
// General
QString serverName() const;
void setServerName(const QString &serverName);
bool writeLogFile() const;
void setWriteLogFile(bool enabled);
@ -28,6 +32,8 @@ public:
QString sslCertificateKeyFileName() const;
void setSslCertificateKeyFileName(const QString &fileName);
QSslConfiguration sslConfiguration() const;
// WebSocketServer
QHostAddress webSocketServerHost() const;
void setWebSocketServerHost(const QHostAddress &address);
@ -44,10 +50,12 @@ public:
private:
// General
QString m_serverName;
bool m_writeLogFile = false;
QString m_logFileName = "/var/log/nymea-remoteproxy.log";
QString m_sslCertificateFileName = "/etc/ssl/certs/ssl-cert-snakeoil.pem";
QString m_sslCertificateKeyFileName = "/etc/ssl/private/ssl-cert-snakeoil.key";
QSslConfiguration m_sslConfiguration;
// WebSocketServer
QHostAddress m_webSocketServerHost = QHostAddress::LocalHost;

View File

@ -46,7 +46,7 @@ void WebSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
client = m_clientList.value(clientId);
if (client) {
qCDebug(dcWebSocketServerTraffic()) << "--> Sending data to client:" << data;
client->sendTextMessage(data + '\n');
client->sendTextMessage(data);
} else {
qCWarning(dcWebSocketServer()) << "Client" << clientId << "unknown to this transport";
}

View File

@ -32,7 +32,7 @@ JsonReply *JsonRpcClient::callAuthenticate(const QUuid &clientUuid, const QStrin
params.insert("token", token);
JsonReply *reply = new JsonReply(m_commandId, "Authentication", "Authenticate", params, this);
qCDebug(dcRemoteProxyClientJsonRpc()) << "Calling" << QString("%1.%2").arg(reply->nameSpace()).arg(reply->method()) << params;
qCDebug(dcRemoteProxyClientJsonRpc()) << "Calling" << QString("%1.%2").arg(reply->nameSpace()).arg(reply->method()) << reply->params();
sendRequest(reply->requestMap());
m_replies.insert(m_commandId, reply);
return reply;
@ -45,11 +45,6 @@ void JsonRpcClient::sendRequest(const QVariantMap &request)
m_connection->sendData(data);
}
void JsonRpcClient::onConnectedChanged(bool connected)
{
Q_UNUSED(connected)
}
void JsonRpcClient::processData(const QByteArray &data)
{
qCDebug(dcRemoteProxyClientJsonRpcTraffic()) << "Received data:" << qUtf8Printable(data);

View File

@ -36,7 +36,6 @@ signals:
void tunnelEstablished(const QString clientName, const QString &clientUuid);
public slots:
void onConnectedChanged(bool connected);
void processData(const QByteArray &data);
};

View File

@ -1,16 +1,15 @@
#include "remoteproxyconnection.h"
#include "websocketconnection.h"
#include "proxyjsonrpcclient.h"
#include "proxyconnection.h"
#include "proxyjsonrpcclient.h"
#include "websocketconnection.h"
#include "remoteproxyconnection.h"
Q_LOGGING_CATEGORY(dcRemoteProxyClientConnection, "RemoteProxyClientConnection")
Q_LOGGING_CATEGORY(dcRemoteProxyClientConnectionTraffic, "RemoteProxyClientConnectionTraffic")
namespace remoteproxyclient {
RemoteProxyConnection::RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, ConnectionType connectionType, QObject *parent) :
RemoteProxyConnection::RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, QObject *parent) :
QObject(parent),
m_connectionType(connectionType),
m_clientUuid(clientUuid),
m_clientName(clientName)
{
@ -82,6 +81,11 @@ RemoteProxyConnection::ConnectionType RemoteProxyConnection::connectionType() co
return m_connectionType;
}
void RemoteProxyConnection::setConnectionType(RemoteProxyConnection::ConnectionType connectionType)
{
m_connectionType = connectionType;
}
QHostAddress RemoteProxyConnection::serverAddress() const
{
return m_serverAddress;
@ -150,7 +154,6 @@ void RemoteProxyConnection::cleanUp()
m_connection = nullptr;
}
m_error = ErrorNoError;
m_serverName = QString();
m_proxyServerName = QString();
m_proxyServerVersion = QString();
@ -164,8 +167,8 @@ void RemoteProxyConnection::setState(RemoteProxyConnection::State state)
if (m_state == state)
return;
qCDebug(dcRemoteProxyClientConnection()) << "State changed" << state;
m_state = state;
qCDebug(dcRemoteProxyClientConnection()) << "State changed" << m_state;
emit stateChanged(m_state);
}
@ -174,8 +177,8 @@ void RemoteProxyConnection::setError(RemoteProxyConnection::Error error)
if (m_error == error)
return;
qCDebug(dcRemoteProxyClientConnection()) << "Error occured" << error;
m_error = error;
qCDebug(dcRemoteProxyClientConnection()) << "Error occured" << m_error << errorString();
emit errorOccured(m_error);
}
@ -234,7 +237,7 @@ void RemoteProxyConnection::onHelloFinished()
reply->deleteLater();
QVariantMap response = reply->response();
qCDebug(dcRemoteProxyClientConnection()) << "Hello response ready" << response;
qCDebug(dcRemoteProxyClientConnectionTraffic()) << "Hello response ready" << reply->commandId() << response;
if (response.value("status").toString() != "success") {
qCWarning(dcRemoteProxyClientConnection()) << "Could not get initial information from proxy server.";
@ -258,12 +261,21 @@ void RemoteProxyConnection::onHelloFinished()
void RemoteProxyConnection::onAuthenticateFinished()
{
JsonReply *reply = static_cast<JsonReply *>(sender());
QVariantMap response = reply->response();
qCDebug(dcRemoteProxyClientConnection()) << "Authentication response ready" << response;
reply->deleteLater();
// TODO: verify success
setState(StateWaitTunnel);
emit authenticated();
QVariantMap response = reply->response();
qCDebug(dcRemoteProxyClientConnectionTraffic()) << "Authentication response ready" << reply->commandId() << response;
QVariantMap responseParams = response.value("params").toMap();
if (responseParams.value("authenticationError").toString() != "AuthenticationErrorNoError") {
qCWarning(dcRemoteProxyClientConnection()) << "Authentication request finished with error" << responseParams.value("authenticationError").toString();
setError(RemoteProxyConnection::ErrorProxyAuthenticationFailed);
m_connection->disconnectServer();
} else {
qCDebug(dcRemoteProxyClientConnection()) << "Successfully authenticated.";
setState(StateWaitTunnel);
emit authenticated();
}
}
void RemoteProxyConnection::onTunnelEstablished(const QString &clientName, const QString &clientUuid)
@ -277,6 +289,7 @@ bool RemoteProxyConnection::connectServer(const QHostAddress &serverAddress, qui
{
m_serverAddress = serverAddress;
m_serverPort = port;
m_error = ErrorNoError;
cleanUp();
@ -295,7 +308,7 @@ bool RemoteProxyConnection::connectServer(const QHostAddress &serverAddress, qui
m_jsonClient = new JsonRpcClient(m_connection, this);
connect(m_jsonClient, &JsonRpcClient::tunnelEstablished, this, &RemoteProxyConnection::onTunnelEstablished);
qCDebug(dcRemoteProxyClientConnection()) << "Connecting to" << m_connection->serverUrl().toString();
qCDebug(dcRemoteProxyClientConnection()) << "Connecting to" << QString("%1:%2").arg(serverAddress.toString()).arg(port);
m_connection->connectServer(serverAddress, port);
setState(StateConnecting);

View File

@ -46,7 +46,7 @@ public:
};
Q_ENUM(Error)
explicit RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, ConnectionType connectionType = RemoteProxyConnection::ConnectionTypeWebSocket, QObject *parent = nullptr);
explicit RemoteProxyConnection(const QUuid &clientUuid, const QString &clientName, QObject *parent = nullptr);
~RemoteProxyConnection();
RemoteProxyConnection::State state() const;
@ -58,6 +58,8 @@ public:
bool isRemoteConnected() const;
RemoteProxyConnection::ConnectionType connectionType() const;
void setConnectionType(RemoteProxyConnection::ConnectionType connectionType);
QHostAddress serverAddress() const;
quint16 serverPort() const;

View File

@ -1,4 +1,4 @@
[General]
name=nymea-remoteproxy
writeLogs=false
logFile=/var/log/nymea-remoteproxy.log
certificate=/etc/ssl/certs/ssl-cert-snakeoil.pem

View File

@ -167,37 +167,8 @@ int main(int argc, char *argv[])
exit(-1);
}
// SSL certificate
QSslConfiguration sslConfiguration;
// Load certificate
QFile certFile(configuration->sslCertificateFileName());
if (!certFile.open(QIODevice::ReadOnly)) {
qCCritical(dcApplication()) << "Could not open certificate file" << configuration->sslCertificateFileName() << certFile.errorString();
exit(-1);
}
QSslCertificate certificate(&certFile, QSsl::Pem);
qCDebug(dcApplication()) << "Loaded successfully certificate" << configuration->sslCertificateFileName();
certFile.close();
// Create SSL configuration
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
sslConfiguration.setLocalCertificate(certificate);
sslConfiguration.setProtocol(QSsl::TlsV1_2OrLater);
// SSL key
QFile certKeyFile(configuration->sslCertificateKeyFileName());
if (!certKeyFile.open(QIODevice::ReadOnly)) {
qCCritical(dcApplication()) << "Could not open certificate key file:" << configuration->sslCertificateKeyFileName() << certKeyFile.errorString();
exit(-1);
}
QSslKey sslKey(&certKeyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
qCDebug(dcApplication()) << "Loaded successfully certificate key" << configuration->sslCertificateKeyFileName();
certKeyFile.close();
sslConfiguration.setPrivateKey(sslKey);
if (sslConfiguration.isNull()) {
// Verify SSL configuration
if (configuration->sslConfiguration().isNull()) {
qCCritical(dcApplication()) << "No SSL configuration specified. The server does not suppoert insecure connections.";
exit(-1);
}
@ -224,11 +195,8 @@ int main(int argc, char *argv[])
}
// Configure and start the engines
Engine::instance()->setConfiguration(configuration);
Engine::instance()->setDeveloperModeEnabled(parser.isSet(developmentOption));
Engine::instance()->setSslConfiguration(sslConfiguration);
Engine::instance()->setAuthenticator(authenticator);
Engine::instance()->setDeveloperModeEnabled(parser.isSet(developmentOption));
Engine::instance()->start(configuration);
return application.exec();

View File

@ -1,2 +0,0 @@
include(../../nymea-remoteproxy.pri)

View File

@ -2,5 +2,6 @@
<qresource>
<file>test-certificate.crt</file>
<file>test-certificate.key</file>
<file>test-configuration.conf</file>
</qresource>
</RCC>

View File

@ -0,0 +1,13 @@
name=test-nymea-remoteproxy
writeLogs=false
logFile=/var/log/nymea-remoteproxy.log
certificate=:/test-certificate.crt
certificateKey=:/test-certificate.key
[WebSocketServer]
host=127.0.0.1
port=1212
[TcpServer]
host=127.0.0.1
port=1213

View File

@ -10,27 +10,24 @@
#include <QJsonDocument>
#include <QWebSocketServer>
RemoteProxyTests::RemoteProxyTests(QObject *parent) :
RemoteProxyOfflineTests::RemoteProxyOfflineTests(QObject *parent) :
BaseTest(parent)
{
}
void RemoteProxyTests::startStopServer()
void RemoteProxyOfflineTests::startStopServer()
{
startServer();
stopServer();
}
void RemoteProxyTests::dummyAuthenticator()
void RemoteProxyOfflineTests::dummyAuthenticator()
{
cleanUpEngine();
DummyAuthenticator *dummyAuthenticator = new DummyAuthenticator(this);
// Start proxy webserver
Engine::instance()->setAuthenticator(dummyAuthenticator);
Engine::instance()->setSslConfiguration(m_sslConfiguration);
Engine::instance()->setAuthenticator(m_dummyAuthenticator);
QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged);
Engine::instance()->start(m_configuration);
runningSpy.wait();
@ -53,22 +50,18 @@ void RemoteProxyTests::dummyAuthenticator()
qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented));
verifyAuthenticationError(response);
dummyAuthenticator->deleteLater();
cleanUpEngine();
}
void RemoteProxyTests::webserverConnectionBlocked()
void RemoteProxyOfflineTests::webserverConnectionBlocked()
{
// Create a dummy server which blocks the port
QWebSocketServer dummyServer("dummy-server", QWebSocketServer::NonSecureMode);
dummyServer.listen(QHostAddress::LocalHost, m_port);
// Start proxy webserver
Engine::instance()->setConfiguration(m_configuration);
Engine::instance()->setAuthenticator(m_authenticator);
Engine::instance()->setSslConfiguration(m_sslConfiguration);
QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged);
Engine::instance()->setAuthenticator(m_authenticator);
Engine::instance()->start(m_configuration);
runningSpy.wait();
@ -93,12 +86,7 @@ void RemoteProxyTests::webserverConnectionBlocked()
stopServer();
}
void RemoteProxyTests::webserverConnection()
{
}
void RemoteProxyTests::getIntrospect()
void RemoteProxyOfflineTests::getIntrospect()
{
// Start the server
startServer();
@ -110,7 +98,7 @@ void RemoteProxyTests::getIntrospect()
stopServer();
}
void RemoteProxyTests::getHello()
void RemoteProxyOfflineTests::getHello()
{
// Start the server
startServer();
@ -122,7 +110,7 @@ void RemoteProxyTests::getHello()
stopServer();
}
void RemoteProxyTests::apiBasicCalls_data()
void RemoteProxyOfflineTests::apiBasicCalls_data()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<bool>("valid");
@ -137,7 +125,7 @@ void RemoteProxyTests::apiBasicCalls_data()
QTest::newRow("invalid params") << QByteArray("{\"id\":42, \"method\":\"RemoteProxy.Hello\", \"params\":{\"törööö\":\"chooo-chooo\"}}") << false;
}
void RemoteProxyTests::apiBasicCalls()
void RemoteProxyOfflineTests::apiBasicCalls()
{
QFETCH(QByteArray, data);
QFETCH(bool, valid);
@ -154,7 +142,7 @@ void RemoteProxyTests::apiBasicCalls()
stopServer();
}
void RemoteProxyTests::authenticate_data()
void RemoteProxyOfflineTests::authenticate_data()
{
QTest::addColumn<QString>("uuid");
QTest::addColumn<QString>("name");
@ -180,7 +168,7 @@ void RemoteProxyTests::authenticate_data()
}
void RemoteProxyTests::authenticate()
void RemoteProxyOfflineTests::authenticate()
{
QFETCH(QString, uuid);
QFETCH(QString, name);
@ -192,8 +180,8 @@ void RemoteProxyTests::authenticate()
startServer();
// Configure result
m_authenticator->setExpectedAuthenticationError(expectedError);
m_authenticator->setTimeoutDuration(timeout);
m_mockAuthenticator->setExpectedAuthenticationError(expectedError);
m_mockAuthenticator->setTimeoutDuration(timeout);
// Create request
QVariantMap params;
@ -209,17 +197,17 @@ void RemoteProxyTests::authenticate()
stopServer();
}
void RemoteProxyTests::clientConnection()
void RemoteProxyOfflineTests::clientConnection()
{
// Start the server
startServer();
// Configure moch authenticator
m_authenticator->setTimeoutDuration(100);
m_authenticator->setExpectedAuthenticationError();
m_mockAuthenticator->setTimeoutDuration(100);
m_mockAuthenticator->setExpectedAuthenticationError();
// Connect to the server (insecure disabled)
RemoteProxyConnection *connection = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", RemoteProxyConnection::ConnectionTypeWebSocket, this);
RemoteProxyConnection *connection = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", this);
connection->setInsecureConnection(true);
// Connect to server (insecue enabled for testing)
@ -260,20 +248,20 @@ void RemoteProxyTests::clientConnection()
stopServer();
}
void RemoteProxyTests::remoteConnection()
void RemoteProxyOfflineTests::remoteConnection()
{
// Start the server
startServer();
// Configure moch authenticator
m_authenticator->setTimeoutDuration(100);
m_authenticator->setExpectedAuthenticationError();
m_mockAuthenticator->setTimeoutDuration(100);
m_mockAuthenticator->setExpectedAuthenticationError();
// Create two connection
RemoteProxyConnection *connectionOne = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", RemoteProxyConnection::ConnectionTypeWebSocket, this);
RemoteProxyConnection *connectionOne = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", this);
connectionOne->setInsecureConnection(true);
RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(QUuid::createUuid(), "Test client two", RemoteProxyConnection::ConnectionTypeWebSocket, this);
RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(QUuid::createUuid(), "Test client two", this);
connectionTwo->setInsecureConnection(true);
// Connect one
@ -310,8 +298,8 @@ void RemoteProxyTests::remoteConnection()
QVERIFY(connectionTwo->isAuthenticated());
// Wait for both to be connected
remoteConnectionEstablishedOne.wait();
remoteConnectionEstablishedTwo.wait();
remoteConnectionEstablishedOne.wait(500);
remoteConnectionEstablishedTwo.wait(500);
QVERIFY(remoteConnectionEstablishedOne.count() == 1);
QVERIFY(remoteConnectionEstablishedTwo.count() == 1);
@ -326,14 +314,16 @@ void RemoteProxyTests::remoteConnection()
QByteArray dataTwo = "Hello from client two :-)";
connectionOne->sendData(dataOne);
remoteConnectionDataTwo.wait();
remoteConnectionDataTwo.wait(500);
QVERIFY(remoteConnectionDataTwo.count() == 1);
QCOMPARE(remoteConnectionDataTwo.at(0).at(0).toByteArray(), dataOne);
// verify if data is the same
connectionTwo->sendData(dataTwo);
remoteConnectionDataOne.wait();
remoteConnectionDataOne.wait(500);
QVERIFY(remoteConnectionDataOne.count() == 1);
QCOMPARE(remoteConnectionDataOne.at(0).at(0).toByteArray(), dataTwo);
// verify if data is the same
@ -344,59 +334,59 @@ void RemoteProxyTests::remoteConnection()
stopServer();
}
void RemoteProxyTests::sslConfigurations()
void RemoteProxyOfflineTests::sslConfigurations()
{
// // Start the server
// startServer();
// Start the server
startServer();
// // 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);
// Connect to the server (insecure disabled)
RemoteProxyConnection *connector = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", this);
QSignalSpy spyError(connector, &RemoteProxyConnection::errorOccured);
QVERIFY(connector->connectServer(QHostAddress::LocalHost, m_port));
spyError.wait();
QVERIFY(spyError.count() == 2);
QVERIFY(connector->error() == RemoteProxyConnection::ErrorSocketError);
QVERIFY(connector->state() == RemoteProxyConnection::StateDisconnected);
// // Connect to server (insecue enabled)
// QSignalSpy spyConnected(connector, &RemoteProxyConnection::connected);
// connector->setInsecureConnection(true);
// connector->connectServer(QHostAddress::LocalHost, m_port);
// spyConnected.wait();
// Connect to server (insecue enabled)
QSignalSpy spyConnected(connector, &RemoteProxyConnection::connected);
connector->setInsecureConnection(true);
connector->connectServer(QHostAddress::LocalHost, m_port);
spyConnected.wait();
// QVERIFY(connector->isConnected());
QVERIFY(connector->isConnected());
// // Disconnect and clean up
// connector->disconnectServer();
// QVERIFY(!connector->isConnected());
// Disconnect and clean up
connector->disconnectServer();
QVERIFY(!connector->isConnected());
// connector->deleteLater();
// stopServer();
connector->deleteLater();
stopServer();
}
void RemoteProxyTests::timeout()
void RemoteProxyOfflineTests::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_mockAuthenticator->setExpectedAuthenticationError();
m_mockAuthenticator->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)
QTEST_MAIN(RemoteProxyOfflineTests)

View File

@ -1,5 +1,5 @@
#ifndef NYMEA_REMOTEPROXY_TESTS_H
#define NYMEA_REMOTEPROXY_TESTS_H
#ifndef NYMEA_REMOTEPROXY_TESTS_OFFLINE_H
#define NYMEA_REMOTEPROXY_TESTS_OFFLINE_H
#include <QUrl>
#include <QtTest>
@ -15,11 +15,11 @@
using namespace remoteproxy;
using namespace remoteproxyclient;
class RemoteProxyTests : public BaseTest
class RemoteProxyOfflineTests : public BaseTest
{
Q_OBJECT
public:
explicit RemoteProxyTests(QObject *parent = nullptr);
explicit RemoteProxyOfflineTests(QObject *parent = nullptr);
private slots:
// Basic stuff
@ -28,7 +28,6 @@ private slots:
// WebSocket connection
void webserverConnectionBlocked();
void webserverConnection();
// Api
void getIntrospect();
@ -48,4 +47,4 @@ private slots:
};
#endif // NYMEA_REMOTEPROXY_TESTS_H
#endif // NYMEA_REMOTEPROXY_TESTS_OFFLINE_H

View File

@ -0,0 +1,71 @@
#include "engine.h"
#include "loggingcategories.h"
#include "remoteproxyconnection.h"
#include "nymea-remoteproxy-tests-online.h"
#include <QMetaType>
#include <QSignalSpy>
#include <QWebSocket>
#include <QJsonDocument>
#include <QWebSocketServer>
RemoteProxyOnlineTests::RemoteProxyOnlineTests(QObject *parent) :
BaseTest(parent)
{
m_authenticator = qobject_cast<Authenticator *>(m_awsAuthenticator);
}
void RemoteProxyOnlineTests::awsStaticCredentials()
{
startServer();
// Connect to the server (insecure disabled)
RemoteProxyConnection *connection = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", 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 errorSpy(connection, &RemoteProxyConnection::errorOccured);
QSignalSpy spyDisconnected(connection, &RemoteProxyConnection::disconnected);
QVERIFY(connection->authenticate("foobar"));
errorSpy.wait();
QVERIFY(errorSpy.count() == 1);
QVERIFY(connection->error() == RemoteProxyConnection::ErrorProxyAuthenticationFailed);
// Disconnect and clean up
connection->disconnectServer();
// FIXME: check why it waits the full time here
spyDisconnected.wait(100);
QVERIFY(spyDisconnected.count() == 1);
QVERIFY(!connection->isConnected());
connection->deleteLater();
stopServer();
}
void RemoteProxyOnlineTests::awsDynamicCredentials()
{
}
QTEST_MAIN(RemoteProxyOnlineTests)

View File

@ -0,0 +1,31 @@
#ifndef NYMEA_REMOTEPROXY_TESTS_ONLINE_H
#define NYMEA_REMOTEPROXY_TESTS_ONLINE_H
#include <QUrl>
#include <QtTest>
#include <QSslKey>
#include <QObject>
#include <QWebSocket>
#include <QHostAddress>
#include <QSslCertificate>
#include <QSslConfiguration>
#include "basetest.h"
using namespace remoteproxy;
using namespace remoteproxyclient;
class RemoteProxyOnlineTests : public BaseTest
{
Q_OBJECT
public:
explicit RemoteProxyOnlineTests(QObject *parent = nullptr);
private slots:
void awsStaticCredentials();
void awsDynamicCredentials();
};
#endif // NYMEA_REMOTEPROXY_TESTS_ONLINE_H

View File

@ -0,0 +1,13 @@
include(../../nymea-remoteproxy.pri)
include(../testbase/testbase.pri)
TARGET = nymea-remoteproxy-tests-online
HEADERS += nymea-remoteproxy-tests-online.h
SOURCES += nymea-remoteproxy-tests-online.cpp
target.path = /usr/bin
INSTALLS += target

View File

@ -14,30 +14,13 @@ BaseTest::BaseTest(QObject *parent) :
QObject(parent)
{
m_configuration = new ProxyConfiguration(this);
m_configuration->loadConfiguration(":/test-configuration.conf");
QFile certificateFile(":/test-certificate.crt");
if (!certificateFile.open(QIODevice::ReadOnly)) {
qWarning() << "Could not open resource file" << certificateFile.fileName();
exit(1);
}
m_mockAuthenticator = new MockAuthenticator(this);
m_dummyAuthenticator = new DummyAuthenticator(this);
m_awsAuthenticator = new AwsAuthenticator(this);
QByteArray certificateData = certificateFile.readAll();
//qDebug() << "Certificate:" << endl << qUtf8Printable(certificateData);
QFile keyFile(":/test-certificate.key");
if (!keyFile.open(QIODevice::ReadOnly)) {
qWarning() << "Could not open resource file" << keyFile.fileName();
exit(1);
}
QByteArray keyData = keyFile.readAll();
//qDebug() << "Certificate key:" << endl << qUtf8Printable(keyData);
m_authenticator = new MockAuthenticator(this);
m_sslConfiguration.setPrivateKey(QSslKey(keyData, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey));
m_sslConfiguration.setLocalCertificate(QSslCertificate(certificateData, QSsl::Pem));
m_sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
m_sslConfiguration.setProtocol(QSsl::TlsV1_2OrLater);
m_authenticator = qobject_cast<Authenticator *>(m_mockAuthenticator);
m_testToken = "eyJraWQiOiJXdnFFT3prVVh5VDlINzFyRUpoNWdxRnkxNFhnR2l3SFAzVEIzUFQ1V3ZrPSIsImFsZyI6IlJT"
"MjU2In0.eyJzdWIiOiJmZTJmZDNlNC1hMGJhLTQ1OTUtOWRiZS00ZDkxYjRiMjFlMzUiLCJhdWQiOiI4cmpoZ"
@ -54,6 +37,13 @@ BaseTest::BaseTest(QObject *parent) :
}
void BaseTest::loadConfiguration(const QString &fileName)
{
qDebug() << "Load test configurations" << fileName;
m_configuration->loadConfiguration(fileName);
restartEngine();
}
void BaseTest::cleanUpEngine()
{
if (Engine::exists()) {
@ -72,15 +62,9 @@ void BaseTest::restartEngine()
void BaseTest::startEngine()
{
if (!Engine::exists()) {
QString serverName = "nymea-remoteproxy-testserver";
Engine::instance()->setAuthenticator(m_authenticator);
Engine::instance()->setServerName(serverName);
Engine::instance()->setConfiguration(m_configuration);
Engine::instance()->setSslConfiguration(m_sslConfiguration);
Engine::instance()->setDeveloperModeEnabled(true);
QVERIFY(Engine::exists());
QVERIFY(Engine::instance()->serverName() == serverName);
}
}
@ -90,7 +74,6 @@ void BaseTest::startServer()
if (!Engine::instance()->running()) {
QSignalSpy runningSpy(Engine::instance(), &Engine::runningChanged);
Engine::instance()->setConfiguration(m_configuration);
Engine::instance()->setDeveloperModeEnabled(true);
Engine::instance()->start(m_configuration);
runningSpy.wait();

View File

@ -14,6 +14,7 @@
#include "mockauthenticator.h"
#include "proxyconfiguration.h"
#include "remoteproxyconnection.h"
#include "authentication/awsauthenticator.h"
#include "authentication/dummyauthenticator.h"
using namespace remoteproxy;
@ -32,11 +33,19 @@ protected:
QHostAddress m_serverAddress = QHostAddress::LocalHost;
QSslConfiguration m_sslConfiguration;
MockAuthenticator *m_authenticator = nullptr;
Authenticator *m_authenticator = nullptr;
MockAuthenticator *m_mockAuthenticator = nullptr;
DummyAuthenticator *m_dummyAuthenticator = nullptr;
AwsAuthenticator *m_awsAuthenticator = nullptr;
QString m_testToken;
int m_commandCounter = 0;
void loadConfiguration(const QString &fileName);
void setAuthenticator(Authenticator *authenticator);
void cleanUpEngine();
void restartEngine();
void startEngine();
@ -50,7 +59,6 @@ protected slots:
void initTestCase();
void cleanupTestCase();
public slots:
void sslErrors(const QList<QSslError> &) {
QWebSocket *socket = static_cast<QWebSocket*>(sender());

View File

@ -1,4 +1,7 @@
RESOURCES += ../certificate.qrc
RESOURCES += ../resources/resources.qrc
CONFIG += testcase
QT += testlib
INCLUDEPATH += $${PWD} $$top_srcdir/libnymea-remoteproxy $$top_srcdir/libnymea-remoteproxyclient
LIBS += -L$$top_builddir/libnymea-remoteproxy/ -lnymea-remoteproxy \

View File

@ -1,4 +1,4 @@
TEMPLATE=subdirs
SUBDIRS += offline
SUBDIRS += test-offline test-online