add cloud JSON RPC

basic functionality working
This commit is contained in:
Simon Stürz 2016-06-16 09:18:56 +02:00 committed by Michael Zanetti
parent 4080ac3b9c
commit 69a8d881d2
25 changed files with 1104 additions and 185 deletions

View File

@ -0,0 +1,53 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudauthenticationhandler.h"
#include "loggingcategories.h"
#include "guhcore.h"
#include <QUuid>
namespace guhserver {
CloudAuthenticationHandler::CloudAuthenticationHandler(QObject *parent) :
CloudJsonHandler(parent)
{
}
QString CloudAuthenticationHandler::nameSpace() const
{
return "Authentication";
}
void CloudAuthenticationHandler::processAuthenticate(const QVariantMap &params)
{
if (params.contains("authenticationError")) {
if (params.value("authenticationError").toString() == "AuthenticationErrorSuccess") {
if (params.contains("connectionId"))
GuhCore::instance()->cloudManager()->onConnectionAuthentificationFinished(true, params.value("connectionId").toUuid());
} else {
GuhCore::instance()->cloudManager()->onConnectionAuthentificationFinished(false, QUuid());
}
}
}
}

View File

@ -0,0 +1,45 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CLOUDAUTHENTICATIONHANDLER_H
#define CLOUDAUTHENTICATIONHANDLER_H
#include <QObject>
#include "cloudjsonhandler.h"
namespace guhserver {
class CloudAuthenticationHandler : public CloudJsonHandler
{
Q_OBJECT
public:
explicit CloudAuthenticationHandler(QObject *parent = 0);
QString nameSpace() const;
// API methods
Q_INVOKABLE void processAuthenticate(const QVariantMap &params);
};
}
#endif // CLOUDAUTHENTICATIONHANDLER_H

View File

@ -19,6 +19,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudauthenticator.h"
#include "guhsettings.h"
#include <QJsonParseError>
#include <QJsonDocument>
@ -31,6 +32,9 @@ CloudAuthenticator::CloudAuthenticator(QString clientId, QString clientSecret, Q
m_clientSecret(clientSecret),
m_authenticated(false)
{
m_refreshToken = loadRefreshToken();
m_username = loadUserName();
m_networkManager = new QNetworkAccessManager(this);
connect(m_networkManager, &QNetworkAccessManager::finished, this, &CloudAuthenticator::replyFinished);
@ -67,6 +71,10 @@ QString CloudAuthenticator::username() const
void CloudAuthenticator::setUsername(const QString &username)
{
GuhSettings settings(GuhSettings::SettingsRoleDevices);
settings.beginGroup("Cloud");
settings.setValue("userName", username);
settings.endGroup();
m_username = username;
}
@ -100,16 +108,6 @@ void CloudAuthenticator::setClientSecret(const QString clientSecret)
m_clientSecret = clientSecret;
}
QString CloudAuthenticator::scope() const
{
return m_scope;
}
void CloudAuthenticator::setScope(const QString &scope)
{
m_scope = scope;
}
QString CloudAuthenticator::token() const
{
return m_token;
@ -120,30 +118,47 @@ bool CloudAuthenticator::authenticated() const
return m_authenticated;
}
void CloudAuthenticator::startAuthentication()
bool CloudAuthenticator::startAuthentication()
{
qCDebug(dcCloud()) << "Start authentication" << m_username;
qCDebug(dcCloud()) << "Authenticator: Start authentication" << m_username;
QUrlQuery query;
query.addQueryItem("grant_type", "password");
query.addQueryItem("username", m_username);
query.addQueryItem("password", m_password);
setQuery(query);
// Check if we have username and password
if(!m_username.isEmpty() && !m_password.isEmpty()) {
QUrlQuery query;
query.addQueryItem("grant_type", "password");
query.addQueryItem("username", m_username);
query.addQueryItem("password", m_password);
setQuery(query);
QNetworkRequest request(m_url);
QByteArray data = QString(m_clientId + ":" + m_clientSecret).toUtf8().toBase64();
QString header = "Basic " + data;
request.setRawHeader("Authorization", header.toLocal8Bit());
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QNetworkRequest request(m_url);
QByteArray data = QString(m_clientId + ":" + m_clientSecret).toUtf8().toBase64();
QString header = "Basic " + data;
request.setRawHeader("Authorization", header.toLocal8Bit());
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
m_tokenRequests.append(m_networkManager->post(request, m_query.toString().toUtf8()));
m_tokenRequests.append(m_networkManager->post(request, m_query.toString().toUtf8()));
return true;
} else if (!m_refreshToken.isEmpty()) {
// Use the refreshtoken if there is any
refreshTimeout();
return true;
}
qCWarning(dcCloud()) << "Authenticator: Cannot start authentication. There is no refresh token, username or password around.";
stopAuthentication();
return false;
}
void CloudAuthenticator::stopAuthentication()
{
m_timer->stop();
}
void CloudAuthenticator::setAuthenticated(const bool &authenticated)
{
if (!authenticated) {
m_timer->stop();
qCWarning(dcCloud()) << "Authentication failed" << m_username;
qCWarning(dcCloud()) << "Authenticator: Authentication failed" << m_username;
}
m_authenticated = authenticated;
emit authenticationChanged();
@ -155,6 +170,35 @@ void CloudAuthenticator::setToken(const QString &token)
emit tokenChanged();
}
void CloudAuthenticator::setRefreshToken(const QString &refreshToken)
{
GuhSettings settings(GuhSettings::SettingsRoleDevices);
settings.beginGroup("Cloud");
settings.setValue("refreshToken", refreshToken);
settings.endGroup();
m_refreshToken = refreshToken;
}
QString CloudAuthenticator::loadRefreshToken() const
{
QString refreshToken;
GuhSettings settings(GuhSettings::SettingsRoleDevices);
settings.beginGroup("Cloud");
refreshToken = settings.value("refreshToken", QString()).toString();
settings.endGroup();
return refreshToken;
}
QString CloudAuthenticator::loadUserName() const
{
QString userName;
GuhSettings settings(GuhSettings::SettingsRoleDevices);
settings.beginGroup("Cloud");
userName = settings.value("userName", QString()).toString();
settings.endGroup();
return userName;
}
void CloudAuthenticator::replyFinished(QNetworkReply *reply)
{
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@ -167,7 +211,7 @@ void CloudAuthenticator::replyFinished(QNetworkReply *reply)
// check HTTP status code
if (status != 200) {
qCWarning(dcCloud()) << "Request token reply HTTP error:" << status << reply->errorString();
qCWarning(dcCloud()) << "Authenticator: Request token reply HTTP error:" << status << reply->errorString();
qCWarning(dcCloud()) << data;
setAuthenticated(false);
reply->deleteLater();
@ -178,14 +222,14 @@ void CloudAuthenticator::replyFinished(QNetworkReply *reply)
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcCloud()) << "Request token reply JSON error:" << error.errorString();
qCWarning(dcCloud()) << "Authenticator: Request token reply JSON error:" << error.errorString();
setAuthenticated(false);
reply->deleteLater();
return;
}
if (!jsonDoc.toVariant().toMap().contains("access_token")) {
qCWarning(dcCloud()) << "Could not get access token" << jsonDoc.toJson();
qCWarning(dcCloud()) << "Authenticator: Could not get access token" << jsonDoc.toJson();
setAuthenticated(false);
reply->deleteLater();
return;
@ -196,8 +240,8 @@ void CloudAuthenticator::replyFinished(QNetworkReply *reply)
if (jsonDoc.toVariant().toMap().contains("expires_in") && jsonDoc.toVariant().toMap().contains("refresh_token")) {
int expireTime = jsonDoc.toVariant().toMap().value("expires_in").toInt();
m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toString();
qCDebug(dcCloud()) << "Token will be refreshed in" << expireTime << "[s]";
setRefreshToken(jsonDoc.toVariant().toMap().value("refresh_token").toString());
qCDebug(dcCloud()) << "Authenticator: Token will be refreshed in" << expireTime << "[s]";
m_timer->start((expireTime - 20) * 1000);
}
@ -208,8 +252,7 @@ void CloudAuthenticator::replyFinished(QNetworkReply *reply)
// check HTTP status code
if (status != 200) {
qCWarning(dcCloud()) << "Refresh token reply HTTP error:" << status << reply->errorString();
qCWarning(dcCloud()) << data;
qCWarning(dcCloud()) << "Authenticator: Refresh token reply HTTP error:" << status << reply->errorString();
setAuthenticated(false);
reply->deleteLater();
return;
@ -219,26 +262,26 @@ void CloudAuthenticator::replyFinished(QNetworkReply *reply)
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcCloud()) << "Refresh token reply JSON error:" << error.errorString();
qCWarning(dcCloud()) << "Authenticator: Refresh token reply JSON error:" << error.errorString();
setAuthenticated(false);
reply->deleteLater();
return;
}
if (!jsonDoc.toVariant().toMap().contains("access_token")) {
qCWarning(dcCloud()) << "Could not get access token after refresh" << jsonDoc.toJson();
qCWarning(dcCloud()) << "Authenticator: Could not get access token after refresh" << jsonDoc.toJson();
setAuthenticated(false);
reply->deleteLater();
return;
}
setToken(jsonDoc.toVariant().toMap().value("access_token").toString());
qCDebug(dcCloud()) << "Token refreshed successfully";
qCDebug(dcCloud()) << "Authenticator: Token refreshed successfully";
if (jsonDoc.toVariant().toMap().contains("expires_in") && jsonDoc.toVariant().toMap().contains("refresh_token")) {
int expireTime = jsonDoc.toVariant().toMap().value("expires_in").toInt();
m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toString();
qCDebug(dcCloud()) << "Token will be refreshed in" << expireTime << "[s]";
setRefreshToken(jsonDoc.toVariant().toMap().value("refresh_token").toString());
qCDebug(dcCloud()) << "Authenticator: Token will be refreshed in" << expireTime << "[s]";
m_timer->start((expireTime - 20) * 1000);
}
@ -251,13 +294,11 @@ void CloudAuthenticator::replyFinished(QNetworkReply *reply)
void CloudAuthenticator::refreshTimeout()
{
qCDebug(dcCloud()) << "Refresh authentication token for" << m_username;
qCDebug(dcCloud()) << "Authenticator: Refresh authentication token for" << m_username;
QUrlQuery query;
query.addQueryItem("grant_type", "refresh_token");
query.addQueryItem("refresh_token", m_refreshToken);
query.addQueryItem("client_id", m_clientId);
query.addQueryItem("client_secret", m_clientSecret);
QNetworkRequest request(m_url);
QByteArray data = QString(m_clientId + ":" + m_clientSecret).toUtf8().toBase64();

View File

@ -57,14 +57,12 @@ public:
QString clientSecret() const;
void setClientSecret(const QString clientSecret);
QString scope() const;
void setScope(const QString &scope);
// Read only
QString token() const;
bool authenticated() const;
void startAuthentication();
bool startAuthentication();
void stopAuthentication();
private:
QNetworkAccessManager *m_networkManager;
@ -78,7 +76,6 @@ private:
QString m_password;
QString m_clientId;
QString m_clientSecret;
QString m_scope;
QString m_token;
QString m_refreshToken;
@ -88,6 +85,10 @@ private:
void setAuthenticated(const bool &authenticated);
void setToken(const QString &token);
void setRefreshToken(const QString &refreshToken);
QString loadRefreshToken() const;
QString loadUserName() const;
private slots:
void replyFinished(QNetworkReply *reply);
void refreshTimeout();

View File

@ -1,8 +0,0 @@
#include "cloudclient.h"
CloudClient::CloudClient(QObject *parent) :
QObject(parent)
{
}

View File

@ -1,17 +0,0 @@
#ifndef CLOUDCLIENT_H
#define CLOUDCLIENT_H
#include <QObject>
class CloudClient : public QObject
{
Q_OBJECT
public:
explicit CloudClient(QObject *parent = 0);
signals:
public slots:
};
#endif // CLOUDCLIENT_H

View File

@ -29,22 +29,15 @@ namespace guhserver {
CloudConnection::CloudConnection(QObject *parent) :
QObject(parent),
m_error(CloudConnectionErrorNoError),
m_enabled(false),
m_connected(false),
m_active(false),
m_authenticated(false)
{
m_proxyUrl = QUrl("ws://127.0.0.1:1212");
m_keystoneUrl = QUrl("http://localhost:8000/oauth2/token");
GuhSettings settings(GuhSettings::SettingsRoleDevices);
settings.beginGroup("guhd");
m_guhUuid = settings.value("uuid", QVariant()).toUuid();
if (m_guhUuid.isNull()) {
m_guhUuid = QUuid::createUuid().toString();
settings.setValue("uuid", m_guhUuid);
}
settings.endGroup();
m_reconnectionTimer = new QTimer(this);
m_reconnectionTimer->setSingleShot(false);
connect(m_reconnectionTimer, &QTimer::timeout, this, &CloudConnection::reconnectionTimeout);
m_connection = new QWebSocket("guhd", QWebSocketProtocol::Version13, this);
connect(m_connection, SIGNAL(connected()), this, SLOT(onConnected()));
@ -56,56 +49,46 @@ CloudConnection::CloudConnection(QObject *parent) :
m_authenticator->setUrl(m_keystoneUrl);
connect(m_authenticator, &CloudAuthenticator::authenticationChanged, this, &CloudConnection::onAuthenticationChanged);
connectToCloud("simon.stuerz@guh.guru", "wshslwshsl");
}
void CloudConnection::connectToCloud(const QString &username, const QString &password)
void CloudConnection::connectToCloud()
{
m_authenticator->setUsername(username);
m_authenticator->setPassword(password);
if (m_connection->state() == QAbstractSocket::ConnectedState) {
disconnectFromCloud();
}
m_authenticator->startAuthentication();
}
void CloudConnection::disconnectFromCloud()
{
m_authenticator->stopAuthentication();
m_connection->close(QWebSocketProtocol::CloseCodeNormal, "Disconnecting");
}
CloudAuthenticator *CloudConnection::authenticator() const
{
return m_authenticator;
}
CloudConnection::CloudConnectionError CloudConnection::error() const
{
return m_error;
}
void CloudConnection::enable()
{
m_enabled = true;
}
void CloudConnection::disable()
{
m_enabled = false;
}
bool CloudConnection::enabled() const
{
return m_enabled;
}
bool CloudConnection::connected() const
{
return m_connected;
}
bool CloudConnection::active() const
{
return m_active;
}
bool CloudConnection::authenticated() const
{
return m_authenticated;
}
void CloudConnection::setEnabled(const bool &enabled)
void CloudConnection::sendData(const QByteArray &data)
{
m_enabled = enabled;
emit enabledChanged();
m_connection->sendTextMessage(data);
}
void CloudConnection::setConnected(const bool &connected)
@ -114,12 +97,6 @@ void CloudConnection::setConnected(const bool &connected)
emit connectedChanged();
}
void CloudConnection::setActive(const bool &active)
{
m_active = active;
emit activeChanged();
}
void CloudConnection::setAuthenticated(const bool &authenticated)
{
m_authenticated = authenticated;
@ -128,7 +105,6 @@ void CloudConnection::setAuthenticated(const bool &authenticated)
void CloudConnection::onAuthenticationChanged()
{
qCDebug(dcCloud()) << "Authentication changed" << m_authenticator->authenticated();
setAuthenticated(m_authenticator->authenticated());
if (m_authenticated) {
@ -143,42 +119,49 @@ void CloudConnection::onConnected()
{
qCDebug(dcCloud()) << "Connected to cloud proxy server" << m_proxyUrl.toString();
setConnected(true);
QVariantMap introspectMap;
introspectMap.insert("id", 0);
introspectMap.insert("method", "Interface.Introspect");
m_connection->sendTextMessage(QJsonDocument::fromVariant(introspectMap).toJson());
QVariantMap authenticationMap;
authenticationMap.insert("id", 1);
authenticationMap.insert("method", "Authentication.Authenticate");
QVariantMap params;
// TODO: use server name
params.insert("name", "guhIO");
params.insert("id", m_guhUuid);
params.insert("token", m_authenticator->token());
params.insert("type", "ConnectionTypeServer");
authenticationMap.insert("params", params);
m_connection->sendTextMessage(QJsonDocument::fromVariant(authenticationMap).toJson());
m_reconnectionTimer->stop();
}
void CloudConnection::onDisconnected()
{
qCDebug(dcCloud()) << "Disconnected from cloud:" << m_connection->closeReason();
if (!m_reconnectionTimer->isActive())
qCDebug(dcCloud()) << "Disconnected from cloud:" << m_connection->closeReason();
setConnected(false);
m_reconnectionTimer->start(10000);
}
void CloudConnection::onError(const QAbstractSocket::SocketError &error)
{
qCWarning(dcCloud()) << "Websocket error:" << error << m_connection->errorString();
if (!m_reconnectionTimer->isActive())
qCWarning(dcCloud()) << "Websocket error:" << error << m_connection->errorString();
m_reconnectionTimer->start(10000);
}
void CloudConnection::onTextMessageReceived(const QString &message)
{
qCDebug(dcCloud()) << "Cloud message -> " << qUtf8Printable(message.toUtf8());
//qCDebug(dcCloud()) << "Cloud message -> " << qUtf8Printable(message.toUtf8());
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(message.toUtf8(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcCloud()) << "Could not parse json data from guh" << qUtf8Printable(message.toUtf8()) << error.errorString();
return;
}
emit dataReceived(jsonDoc.toVariant().toMap());
}
void CloudConnection::reconnectionTimeout()
{
if (m_authenticated) {
m_connection->open(m_proxyUrl);
} else {
m_reconnectionTimer->stop();
m_error = CloudConnectionErrorAuthenticationFailed;
}
}
}

View File

@ -24,6 +24,7 @@
#include <QUrl>
#include <QUuid>
#include <QObject>
#include <QTimer>
#include <QWebSocket>
#include "cloudauthenticator.h"
@ -44,37 +45,39 @@ public:
explicit CloudConnection(QObject *parent = 0);
void connectToCloud(const QString &username, const QString &password);
void connectToCloud();
void disconnectFromCloud();
CloudAuthenticator *authenticator() const;
CloudConnectionError error() const;
void enable();
void disable();
bool enabled() const;
bool connected() const;
bool active() const;
bool authenticated() const;
void sendData(const QByteArray &data);
void sendRequest(const QVariantMap &request);
private:
QWebSocket *m_connection;
CloudAuthenticator *m_authenticator;
CloudConnectionError m_error;
QUuid m_guhUuid;
QTimer *m_reconnectionTimer;
QUrl m_proxyUrl;
QUrl m_keystoneUrl;
bool m_enabled;
bool m_connected;
bool m_active;
bool m_authenticated;
void setEnabled(const bool &enabled);
void setConnected(const bool &connected);
void setActive(const bool &active);
void setAuthenticated(const bool &authenticated);
signals:
void dataReceived(const QVariantMap &data);
void enabledChanged();
void connectedChanged();
void activeChanged();
@ -87,7 +90,10 @@ private slots:
void onError(const QAbstractSocket::SocketError &error);
void onTextMessageReceived(const QString &message);
void reconnectionTimeout();
};
}
#endif // CLOUDCONNECTION_H

View File

@ -0,0 +1,94 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudconnectionhandler.h"
#include "loggingcategories.h"
#include "guhcore.h"
namespace guhserver {
CloudConnectionHandler::CloudConnectionHandler(QObject *parent) :
CloudJsonHandler(parent)
{
}
QString CloudConnectionHandler::nameSpace() const
{
return "Connection";
}
void CloudConnectionHandler::processGetConnections(const QVariantMap &params)
{
Q_UNUSED(params)
}
void CloudConnectionHandler::processGetTunnels(const QVariantMap &params)
{
foreach (const QVariant &tunnelVariant, params.value("tunnel").toList()) {
QVariantMap tunnelMap = tunnelVariant.toMap();
QUuid tunnelId = tunnelMap.value("id").toUuid();
QUuid serverId = tunnelMap.value("serverConnection").toMap().value("id").toUuid();
QUuid clientId = tunnelMap.value("clientConnection").toMap().value("id").toUuid();
GuhCore::instance()->cloudManager()->onTunnelAdded(tunnelId, serverId, clientId);
}
}
void CloudConnectionHandler::processSendData(const QVariantMap &params)
{
Q_UNUSED(params)
}
void CloudConnectionHandler::processConnectionAdded(const QVariantMap &params)
{
Q_UNUSED(params)
}
void CloudConnectionHandler::processConnectionRemoved(const QVariantMap &params)
{
Q_UNUSED(params)
}
void CloudConnectionHandler::processTunnelAdded(const QVariantMap &params)
{
QVariantMap tunnelMap = params.value("tunnel").toMap();
QUuid tunnelId = tunnelMap.value("id").toUuid();
QUuid serverId = tunnelMap.value("serverConnection").toMap().value("id").toUuid();
QUuid clientId = tunnelMap.value("clientConnection").toMap().value("id").toUuid();
GuhCore::instance()->cloudManager()->onTunnelAdded(tunnelId, serverId, clientId);
}
void CloudConnectionHandler::processTunnelRemoved(const QVariantMap &params)
{
QUuid tunnelId = params.value("tunnelId").toUuid();
GuhCore::instance()->cloudManager()->onTunnelRemoved(tunnelId);
}
void CloudConnectionHandler::processDataReceived(const QVariantMap &params)
{
QUuid tunnelId = params.value("tunnelId").toUuid();
GuhCore::instance()->cloudManager()->onCloudDataReceived(tunnelId, params.value("data").toMap());
}
}

View File

@ -0,0 +1,54 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CLOUDCONNECTIONHANDLER_H
#define CLOUDCONNECTIONHANDLER_H
#include <QObject>
#include "cloudjsonhandler.h"
namespace guhserver {
class CloudConnectionHandler : public CloudJsonHandler
{
Q_OBJECT
public:
explicit CloudConnectionHandler(QObject *parent = 0);
QString nameSpace() const;
// API methods
Q_INVOKABLE void processGetConnections(const QVariantMap &params);
Q_INVOKABLE void processGetTunnels(const QVariantMap &params);
Q_INVOKABLE void processSendData(const QVariantMap &params);
// API notifications
Q_INVOKABLE void processConnectionAdded(const QVariantMap &params);
Q_INVOKABLE void processConnectionRemoved(const QVariantMap &params);
Q_INVOKABLE void processTunnelAdded(const QVariantMap &params);
Q_INVOKABLE void processTunnelRemoved(const QVariantMap &params);
Q_INVOKABLE void processDataReceived(const QVariantMap &params);
};
}
#endif // CLOUDCONNECTIONHANDLER_H

View File

@ -1,8 +1,126 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudinterface.h"
#include "loggingcategories.h"
#include "guhsettings.h"
#include "guhcore.h"
namespace guhserver {
CloudInterface::CloudInterface(QObject *parent) :
QObject(parent)
{
GuhSettings settings(GuhSettings::SettingsRoleDevices);
settings.beginGroup("guhd");
m_guhUuid = settings.value("uuid", QVariant()).toUuid();
if (m_guhUuid.isNull()) {
m_guhUuid = QUuid::createUuid().toString();
settings.setValue("uuid", m_guhUuid);
}
settings.endGroup();
m_authenticationHandler = new CloudAuthenticationHandler(this);
m_connectionHandler = new CloudConnectionHandler(this);
m_handlers.insert(m_authenticationHandler->nameSpace(), m_authenticationHandler);
m_handlers.insert(m_connectionHandler->nameSpace(), m_connectionHandler);
}
void CloudInterface::authenticateConnection(const QString &token)
{
qCDebug(dcCloud()) << "Start cloud connection authentication" << token;
QVariantMap params;
// TODO: use server/station name
params.insert("name", "guhIO");
params.insert("id", m_guhUuid);
params.insert("token", token);
params.insert("type", "ConnectionTypeServer");
CloudJsonReply *reply = createReply("Authentication", "Authenticate", params);
GuhCore::instance()->cloudManager()->sendCloudData(reply->requestMap());
m_replies.insert(reply->commandId(), reply);
}
void CloudInterface::getTunnels()
{
CloudJsonReply *reply = createReply("Connection", "GetTunnels");
GuhCore::instance()->cloudManager()->sendCloudData(reply->requestMap());
m_replies.insert(reply->commandId(), reply);
}
void CloudInterface::sendApiData(const QUuid &tunnelId, const QVariantMap &data)
{
//qCDebug(dcCloud()) << "Send API data" << tunnelId.toString() << data;
QVariantMap params;
params.insert("tunnelId", tunnelId.toString());
params.insert("data", data);
CloudJsonReply *reply = createReply("Connection", "SendData", params);
GuhCore::instance()->cloudManager()->sendCloudData(reply->requestMap());
m_replies.insert(reply->commandId(), reply);
}
CloudJsonReply *CloudInterface::createReply(QString nameSpace, QString method, QVariantMap params)
{
m_id++;
return new CloudJsonReply(m_id, nameSpace, method, params, this);
}
void CloudInterface::dataReceived(const QVariantMap &data)
{
int commandId = data.value("id").toInt();
QPointer<CloudJsonReply> reply = m_replies.take(commandId);
QVariantMap params = data.value("params").toMap();
// check if this is a reply to a request
if (!reply.isNull() && !data.contains("notification")) {
qCDebug(dcCloud()) << "JsonRpc: got response for" << QString("%1.%2").arg(reply->nameSpace(), reply->method());
CloudJsonHandler *handler = m_handlers.value(reply->nameSpace());
if (!QMetaObject::invokeMethod(handler, QString("process" + reply->method()).toLatin1().data(), Q_ARG(QVariantMap, params)))
qCWarning(dcCloud()) << "JsonRpc: method not implemented:" << reply->method();
reply->deleteLater();
return;
}
// check if this is a notification
if (data.contains("notification")) {
QStringList notification = data.value("notification").toString().split(".");
QString nameSpace = notification.first();
QString method = notification.last();
CloudJsonHandler *handler = m_handlers.value(nameSpace);
if (!handler) {
qCWarning(dcCloud()) << "JsonRpc: handler not implemented:" << nameSpace;
return;
}
if (!QMetaObject::invokeMethod(handler, QString("process" + method).toLatin1().data(), Q_ARG(QVariantMap, params)))
qCWarning(dcCloud()) << "JsonRpc: Method not implemented";
}
}
}

View File

@ -1,7 +1,36 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CLOUDINTERFACE_H
#define CLOUDINTERFACE_H
#include <QHash>
#include <QUuid>
#include <QObject>
#include <QVariantMap>
#include "cloudjsonreply.h"
#include "cloudconnectionhandler.h"
#include "cloudauthenticationhandler.h"
namespace guhserver {
class CloudInterface : public QObject
{
@ -9,9 +38,30 @@ class CloudInterface : public QObject
public:
explicit CloudInterface(QObject *parent = 0);
Q_INVOKABLE void authenticateConnection(const QString &token);
Q_INVOKABLE void getTunnels();
Q_INVOKABLE void sendApiData(const QUuid &tunnelId, const QVariantMap &data);
private:
int m_id;
QUuid m_guhUuid;
QHash<QString, CloudJsonHandler *> m_handlers;
QHash<int, CloudJsonReply *> m_replies;
CloudJsonReply *createReply(QString nameSpace, QString method, QVariantMap params = QVariantMap());
CloudAuthenticationHandler *m_authenticationHandler;
CloudConnectionHandler *m_connectionHandler;
signals:
void responseReceived(const int &commandId, const QVariantMap &response);
public slots:
void dataReceived(const QVariantMap &data);
};
}
#endif // CLOUDINTERFACE_H

View File

@ -0,0 +1,31 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudjsonhandler.h"
namespace guhserver {
CloudJsonHandler::CloudJsonHandler(QObject *parent) :
QObject(parent)
{
}
}

View File

@ -0,0 +1,39 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CLOUDJSONHANDLER_H
#define CLOUDJSONHANDLER_H
#include <QObject>
namespace guhserver {
class CloudJsonHandler : public QObject
{
Q_OBJECT
public:
explicit CloudJsonHandler(QObject *parent = 0);
virtual QString nameSpace() const = 0;
};
}
#endif // CLOUDJSONHANDLER_H

View File

@ -0,0 +1,66 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudjsonreply.h"
namespace guhserver {
CloudJsonReply::CloudJsonReply(int commandId, QString nameSpace, QString method, QVariantMap params, QObject *parent) :
QObject(parent),
m_commandId(commandId),
m_nameSpace(nameSpace),
m_method(method),
m_params(params)
{
}
int CloudJsonReply::commandId() const
{
return m_commandId;
}
QString CloudJsonReply::nameSpace() const
{
return m_nameSpace;
}
QString CloudJsonReply::method() const
{
return m_method;
}
QVariantMap CloudJsonReply::params() const
{
return m_params;
}
QVariantMap CloudJsonReply::requestMap()
{
QVariantMap request;
request.insert("id", m_commandId);
request.insert("method", m_nameSpace + "." + m_method);
if (!m_params.isEmpty())
request.insert("params", m_params);
return request;
}
}

View File

@ -0,0 +1,51 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CLOUDJSONREPLY_H
#define CLOUDJSONREPLY_H
#include <QObject>
#include <QVariantMap>
namespace guhserver {
class CloudJsonReply : public QObject
{
Q_OBJECT
public:
explicit CloudJsonReply(int commandId, QString nameSpace, QString method, QVariantMap params = QVariantMap(), QObject *parent = 0);
int commandId() const;
QString nameSpace() const;
QString method() const;
QVariantMap params() const;
QVariantMap requestMap();
private:
int m_commandId;
QString m_nameSpace;
QString m_method;
QVariantMap m_params;
};
}
#endif // CLOUDJSONREPLY_H

View File

@ -0,0 +1,197 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudmanager.h"
#include "jsonhandler.h"
#include "guhcore.h"
#include <QJsonDocument>
#include <QJsonParseError>
namespace guhserver {
CloudManager::CloudManager(QObject *parent) :
TransportInterface(parent),
m_enabled(true),
m_authenticated(false)
{
m_cloudConnection = new CloudConnection(this);
connect(m_cloudConnection, &CloudConnection::authenticatedChanged, this, &CloudManager::onAuthenticatedChanged);
connect(m_cloudConnection, &CloudConnection::connectedChanged, this, &CloudManager::onConnectedChanged);
m_interface = new CloudInterface(this);
connect(m_cloudConnection, &CloudConnection::dataReceived, m_interface, &CloudInterface::dataReceived);
}
CloudManager::~CloudManager()
{
qCDebug(dcApplication) << "Shutting down \"Cloud Manager\"";
stopServer();
}
void CloudManager::connectToCloud(const QString &username, const QString &password)
{
m_cloudConnection->authenticator()->setUsername(username);
m_cloudConnection->authenticator()->setPassword(password);
m_cloudConnection->connectToCloud();
}
void CloudManager::sendData(const QUuid &clientId, const QVariantMap &data)
{
// Used from the JsonRpcServer
m_interface->sendApiData(m_tunnelClients.value(clientId), data);
}
void CloudManager::sendData(const QList<QUuid> &clients, const QVariantMap &data)
{
// Used from the JsonRpcServer
foreach (const QUuid &clientId, clients) {
sendData(clientId, data);
}
}
bool CloudManager::enabled() const
{
return m_enabled;
}
bool CloudManager::connected() const
{
return m_cloudConnection->connected();
}
bool CloudManager::active() const
{
return m_active;
}
bool CloudManager::authenticated() const
{
return m_authenticated;
}
bool CloudManager::startServer()
{
m_cloudConnection->connectToCloud();
return true;
}
bool CloudManager::stopServer()
{
m_cloudConnection->disconnectFromCloud();
return true;
}
void CloudManager::sendCloudData(const QVariantMap &data)
{
m_cloudConnection->sendData(QJsonDocument::fromVariant(data).toJson());
}
void CloudManager::onConnectionAuthentificationFinished(const bool &authenticated, const QUuid &connectionId)
{
qCDebug(dcCloud()) << "Cloud connection authenticated" << authenticated;
if (authenticated) {
m_authenticated = true;
m_connectionId = connectionId;
qCDebug(dcCloud()) << "Connection ID:" << connectionId.toString();
emit authenticatedChanged();
// Get tunnel connections
m_interface->getTunnels();
} else {
m_authenticated = false;
authenticatedChanged();
}
}
void CloudManager::onTunnelAdded(const QUuid &tunnelId, const QUuid &serverId, const QUuid &clientId)
{
if (serverId == m_connectionId) {
qCDebug(dcCloud()) << "New tunnel connection from" << clientId.toString();
m_tunnelClients.insert(clientId, tunnelId);
emit clientConnected(clientId);
}
}
void CloudManager::onTunnelRemoved(const QUuid &tunnelId)
{
if (m_tunnelClients.values().contains(tunnelId)) {
QUuid clientId = m_tunnelClients.key(tunnelId);
m_tunnelClients.remove(clientId);
emit clientDisconnected(clientId);
}
}
void CloudManager::onCloudDataReceived(const QUuid &tunnelId, const QVariantMap &data)
{
if (m_tunnelClients.values().contains(tunnelId)) {
QUuid clientId = m_tunnelClients.key(tunnelId);
bool success;
int commandId = data.value("id").toInt(&success);
if (!success) {
qCWarning(dcCloud()) << "TunnelData: Error parsing command. Missing \"id\":" << data;
sendErrorResponse(clientId, commandId, "Error parsing command. Missing 'id'");
return;
}
QStringList commandList = data.value("method").toString().split('.');
if (commandList.count() != 2) {
qCWarning(dcCloud()) << "TunnelData: Error parsing method.\nGot:" << data.value("method").toString() << "\nExpected: \"Namespace.method\"";
return;
}
QString targetNamespace = commandList.first();
QString method = commandList.last();
JsonHandler *handler = GuhCore::instance()->jsonRPCServer()->handlers().value(targetNamespace);
if (!handler) {
sendErrorResponse(clientId, commandId, "No such namespace");
return;
}
if (!handler->hasMethod(method)) {
sendErrorResponse(clientId, commandId, "No such method");
return;
}
emit dataAvailable(clientId, targetNamespace, method, data);
}
}
void CloudManager::onConnectedChanged()
{
// Start authentication if connected
if (m_cloudConnection->connected()) {
m_interface->authenticateConnection(m_cloudConnection->authenticator()->token());
emit connectedChanged();
}
}
void CloudManager::onAuthenticatedChanged()
{
if (!m_cloudConnection->authenticator()->authenticated()) {
m_authenticated = false;
emit authenticatedChanged();
}
}
}

102
server/cloud/cloudmanager.h Normal file
View File

@ -0,0 +1,102 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh 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 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CLOUDMANAGER_H
#define CLOUDMANAGER_H
#include <QObject>
#include "transportinterface.h"
#include "cloudinterface.h"
#include "cloudauthenticator.h"
#include "cloudconnection.h"
namespace guhserver {
class CloudManager : public TransportInterface
{
Q_OBJECT
public:
friend class CloudInterface;
friend class CloudConnectionHandler;
friend class CloudAuthenticationHandler;
explicit CloudManager(QObject *parent = 0);
~CloudManager();
void connectToCloud(const QString &username, const QString &password) ;
void sendData(const QUuid &clientId, const QVariantMap &data) override;
void sendData(const QList<QUuid> &clients, const QVariantMap &data) override;
bool enabled() const;
bool connected() const;
bool connectionAuthenticated() const;
bool active() const;
bool authenticated() const;
public slots:
bool startServer() override;
bool stopServer() override;
private:
CloudConnection *m_cloudConnection;
CloudInterface *m_interface;
QList<QUuid> m_clients;
QHash<int, CloudJsonReply *> m_replies;
QHash<QUuid, QUuid> m_tunnelClients;
QUuid m_connectionId;
bool m_enabled;
bool m_active;
bool m_authenticated;
protected:
void sendCloudData(const QVariantMap &data);
void onConnectionAuthentificationFinished(const bool &status, const QUuid &connectionId);
void onTunnelAdded(const QUuid &tunnelId, const QUuid &serverId, const QUuid &clientId);
void onTunnelRemoved(const QUuid &tunnelId);
void onCloudDataReceived(const QUuid &tunnelId, const QVariantMap &data);
signals:
void enabledChanged();
void connectedChanged();
void activeChanged();
void authenticatedChanged();
// Transport interface signals
void clientConnected(const QUuid &clientId);
void clientDisconnected(const QUuid &clientId);
void dataAvailable(const QUuid &clientId, const QString &targetNamespace, const QString &method, const QVariantMap &message);
private slots:
void onConnectedChanged();
void onAuthenticatedChanged();
};
}
#endif // CLOUDMANAGER_H

View File

@ -362,9 +362,9 @@ TimeManager *GuhCore::timeManager() const
return m_timeManager;
}
CloudConnection *GuhCore::cloudConnection() const
CloudManager *GuhCore::cloudManager() const
{
return m_cloudConnection;
return m_cloudManager;
}
/*! Constructs GuhCore with the given \a parent. This is private.
@ -378,8 +378,8 @@ GuhCore::GuhCore(QObject *parent) :
qCDebug(dcApplication) << "Creating Log Engine";
m_logger = new LogEngine(this);
qCDebug(dcApplication) << "Creating Cloud Connection";
m_cloudConnection = new CloudConnection(this);
qCDebug(dcApplication) << "Creating Cloud Manager";
m_cloudManager = new CloudManager(this);
qCDebug(dcApplication) << "Creating Device Manager";
m_deviceManager = new DeviceManager(this);
@ -390,6 +390,9 @@ GuhCore::GuhCore(QObject *parent) :
qCDebug(dcApplication) << "Creating Server Manager";
m_serverManager = new ServerManager(this);
// Register cloud connection transport interface
m_serverManager->jsonServer()->registerTransportInterface(m_cloudManager);
connect(m_deviceManager, &DeviceManager::eventTriggered, this, &GuhCore::gotEvent);
connect(m_deviceManager, &DeviceManager::deviceStateChanged, this, &GuhCore::deviceStateChanged);
connect(m_deviceManager, &DeviceManager::deviceAdded, this, &GuhCore::deviceAdded);

View File

@ -32,7 +32,7 @@
#include "ruleengine.h"
#include "servermanager.h"
#include "cloud/cloudconnection.h"
#include "cloud/cloudmanager.h"
#include "time/timemanager.h"
#include <QObject>
@ -71,7 +71,7 @@ public:
DeviceManager *deviceManager() const;
RuleEngine *ruleEngine() const;
TimeManager *timeManager() const;
CloudConnection *cloudConnection() const;
CloudManager *cloudManager() const;
signals:
void eventTriggered(const Event &event);
@ -100,7 +100,7 @@ private:
RuleEngine *m_ruleEngine;
LogEngine *m_logger;
TimeManager *m_timeManager;
CloudConnection *m_cloudConnection;
CloudManager *m_cloudManager;
QHash<ActionId, Action> m_pendingActions;

View File

@ -53,10 +53,10 @@ CloudHandler::CloudHandler(QObject *parent) :
params.insert("authenticated", JsonTypes::basicTypeToString(JsonTypes::Bool));
setParams("ConnectionStatusChanged", params);
connect(GuhCore::instance()->cloudConnection(), SIGNAL(enabledChanged()), this, SLOT(onConnectionStatusChanged()));
connect(GuhCore::instance()->cloudConnection(), SIGNAL(connectedChanged()), this, SLOT(onConnectionStatusChanged()));
connect(GuhCore::instance()->cloudConnection(), SIGNAL(activeChanged()), this, SLOT(onConnectionStatusChanged()));
connect(GuhCore::instance()->cloudConnection(), SIGNAL(authenticatedChanged()), this, SLOT(onConnectionStatusChanged()));
connect(GuhCore::instance()->cloudManager(), SIGNAL(enabledChanged()), this, SLOT(onConnectionStatusChanged()));
connect(GuhCore::instance()->cloudManager(), SIGNAL(connectedChanged()), this, SLOT(onConnectionStatusChanged()));
connect(GuhCore::instance()->cloudManager(), SIGNAL(activeChanged()), this, SLOT(onConnectionStatusChanged()));
connect(GuhCore::instance()->cloudManager(), SIGNAL(authenticatedChanged()), this, SLOT(onConnectionStatusChanged()));
}
QString CloudHandler::name() const
@ -72,7 +72,7 @@ JsonReply *CloudHandler::Authenticate(const QVariantMap &params) const
QString password = params.value("password").toString();
qCDebug(dcJsonRpc()) << "Authenticate cloud connection for user" << username;
GuhCore::instance()->cloudConnection()->connectToCloud(username, password);
GuhCore::instance()->cloudManager()->connectToCloud(username, password);
QVariantMap returns;
returns.insert("cloudConnectionError", JsonTypes::cloudConnectionErrorToString(CloudConnection::CloudConnectionErrorNoError));
@ -84,20 +84,20 @@ JsonReply *CloudHandler::GetConnectionStatus(const QVariantMap &params) const
Q_UNUSED(params)
QVariantMap returns;
returns.insert("enabled", GuhCore::instance()->cloudConnection()->enabled());
returns.insert("connected", GuhCore::instance()->cloudConnection()->connected());
returns.insert("active", GuhCore::instance()->cloudConnection()->active());
returns.insert("authenticated", GuhCore::instance()->cloudConnection()->authenticated());
returns.insert("enabled", GuhCore::instance()->cloudManager()->enabled());
returns.insert("connected", GuhCore::instance()->cloudManager()->connected());
returns.insert("active", GuhCore::instance()->cloudManager()->active());
returns.insert("authenticated", GuhCore::instance()->cloudManager()->authenticated());
return createReply(returns);
}
void CloudHandler::onConnectionStatusChanged()
{
QVariantMap params;
params.insert("enabled", GuhCore::instance()->cloudConnection()->enabled());
params.insert("connected", GuhCore::instance()->cloudConnection()->connected());
params.insert("active", GuhCore::instance()->cloudConnection()->active());
params.insert("authenticated", GuhCore::instance()->cloudConnection()->authenticated());
params.insert("enabled", GuhCore::instance()->cloudManager()->enabled());
params.insert("connected", GuhCore::instance()->cloudManager()->connected());
params.insert("active", GuhCore::instance()->cloudManager()->active());
params.insert("authenticated", GuhCore::instance()->cloudManager()->authenticated());
emit ConnectionStatusChanged(params);
}

View File

@ -105,20 +105,8 @@ JsonRPCServer::JsonRPCServer(const QSslConfiguration &sslConfiguration, QObject
returns.insert("enabled", JsonTypes::basicTypeToString(JsonTypes::Bool));
setReturns("SetNotificationStatus", returns);
// Now set up the logic
connect(m_tcpServer, SIGNAL(clientConnected(const QUuid &)), this, SLOT(clientConnected(const QUuid &)));
connect(m_tcpServer, SIGNAL(clientDisconnected(const QUuid &)), this, SLOT(clientDisconnected(const QUuid &)));
connect(m_tcpServer, SIGNAL(dataAvailable(QUuid, QString, QString, QVariantMap)), this, SLOT(processData(QUuid, QString, QString, QVariantMap)));
m_tcpServer->startServer();
m_interfaces.append(m_tcpServer);
connect(m_websocketServer, SIGNAL(clientConnected(const QUuid &)), this, SLOT(clientConnected(const QUuid &)));
connect(m_websocketServer, SIGNAL(clientDisconnected(const QUuid &)), this, SLOT(clientDisconnected(const QUuid &)));
connect(m_websocketServer, SIGNAL(dataAvailable(QUuid, QString, QString, QVariantMap)), this, SLOT(processData(QUuid, QString, QString, QVariantMap)));
m_websocketServer->startServer();
m_interfaces.append(m_websocketServer);
registerTransportInterface(m_tcpServer);
registerTransportInterface(m_websocketServer);
QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection);
}
@ -175,6 +163,16 @@ QHash<QString, JsonHandler *> JsonRPCServer::handlers() const
return m_handlers;
}
void JsonRPCServer::registerTransportInterface(TransportInterface *interface)
{
// Now set up the logic
connect(interface, SIGNAL(clientConnected(const QUuid &)), this, SLOT(clientConnected(const QUuid &)));
connect(interface, SIGNAL(clientDisconnected(const QUuid &)), this, SLOT(clientDisconnected(const QUuid &)));
connect(interface, SIGNAL(dataAvailable(QUuid, QString, QString, QVariantMap)), this, SLOT(processData(QUuid, QString, QString, QVariantMap)));
interface->startServer();
m_interfaces.append(interface);
}
void JsonRPCServer::setup()
{
registerHandler(this);

View File

@ -63,6 +63,8 @@ public:
QHash<QString, JsonHandler*> handlers() const;
void registerTransportInterface(TransportInterface *interface);
private slots:
void setup();
@ -83,6 +85,7 @@ private:
#endif
WebSocketServer *m_websocketServer;
QList<TransportInterface *> m_interfaces;
QHash<QString, JsonHandler *> m_handlers;
QHash<JsonReply *, TransportInterface *> m_asyncReplies;

View File

@ -83,6 +83,7 @@ static void consoleLogHandler(QtMsgType type, const QMessageLogContext& context,
fprintf(stdout, " F | %s: %s\n", context.category, message.toUtf8().data());
break;
}
fflush(stdout);
QFile logFile(GuhSettings::consoleLogPath());
if (!logFile.open(QIODevice::WriteOnly | QIODevice::Append)) {

View File

@ -41,8 +41,12 @@ HEADERS += $$top_srcdir/server/guhcore.h \
$$top_srcdir/server/time/timemanager.h \
$$top_srcdir/server/cloud/cloudconnection.h \
$$top_srcdir/server/cloud/cloudauthenticator.h \
$$PWD/cloud/cloudinterface.h \
$$PWD/cloud/cloudclient.h
$$top_srcdir/server/cloud/cloudinterface.h \
$$top_srcdir/server/cloud/cloudjsonreply.h \
$$top_srcdir/server/cloud/cloudauthenticationhandler.h \
$$top_srcdir/server/cloud/cloudconnectionhandler.h \
$$top_srcdir/server/cloud/cloudjsonhandler.h \
$$top_srcdir/server/cloud/cloudmanager.h \
SOURCES += $$top_srcdir/server/guhcore.cpp \
@ -84,5 +88,9 @@ SOURCES += $$top_srcdir/server/guhcore.cpp \
$$top_srcdir/server/time/timemanager.cpp \
$$top_srcdir/server/cloud/cloudconnection.cpp \
$$top_srcdir/server/cloud/cloudauthenticator.cpp \
$$PWD/cloud/cloudinterface.cpp \
$$PWD/cloud/cloudclient.cpp
$$top_srcdir/server/cloud/cloudinterface.cpp \
$$top_srcdir/server/cloud/cloudjsonreply.cpp \
$$top_srcdir/server/cloud/cloudauthenticationhandler.cpp \
$$top_srcdir/server/cloud/cloudconnectionhandler.cpp \
$$top_srcdir/server/cloud/cloudjsonhandler.cpp \
$$top_srcdir/server/cloud/cloudmanager.cpp \