remove old cloud handler, cleanup more jsonrpc stuff from TransportInterface
This commit is contained in:
parent
f75a0e7a31
commit
6a4a481f88
@ -68,7 +68,7 @@ bool BluetoothServer::hardwareAvailable()
|
||||
}
|
||||
|
||||
/*! Send \a data to the client with the given \a clientId.*/
|
||||
void BluetoothServer::sendData(const QUuid &clientId, const QVariantMap &data)
|
||||
void BluetoothServer::sendData(const QUuid &clientId, const QByteArray &data)
|
||||
{
|
||||
QBluetoothSocket *client = 0;
|
||||
client = m_clientList.value(clientId);
|
||||
@ -77,7 +77,7 @@ void BluetoothServer::sendData(const QUuid &clientId, const QVariantMap &data)
|
||||
}
|
||||
|
||||
/*! Send the given \a data to the \a clients. */
|
||||
void BluetoothServer::sendData(const QList<QUuid> &clients, const QVariantMap &data)
|
||||
void BluetoothServer::sendData(const QList<QUuid> &clients, const QByteArray &data)
|
||||
{
|
||||
foreach (const QUuid &client, clients)
|
||||
sendData(client, data);
|
||||
|
||||
@ -38,8 +38,8 @@ public:
|
||||
|
||||
static bool hardwareAvailable();
|
||||
|
||||
void sendData(const QUuid &clientId, const QVariantMap &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QVariantMap &data) override;
|
||||
void sendData(const QUuid &clientId, const QByteArray &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QByteArray &data) override;
|
||||
|
||||
private:
|
||||
QBluetoothServer *m_server;
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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 ¶ms)
|
||||
{
|
||||
if (params.contains("authenticationError")) {
|
||||
if (params.value("authenticationError").toString() == "AuthenticationErrorNoError") {
|
||||
if (params.contains("connectionId")) {
|
||||
GuhCore::instance()->cloudManager()->onConnectionAuthentificationFinished(true, params.value("connectionId").toUuid());
|
||||
return;
|
||||
}
|
||||
}
|
||||
qCWarning(dcCloud()) << "Authentication error:" << params.value("authenticationError").toString();
|
||||
}
|
||||
|
||||
GuhCore::instance()->cloudManager()->onConnectionAuthentificationFinished(false, QUuid());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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;
|
||||
|
||||
public:
|
||||
enum CloudError {
|
||||
CloudErrorNoError,
|
||||
CloudErrorAuthenticationFailed,
|
||||
CloudErrorCloudConnectionDisabled,
|
||||
CloudErrorIdentityServerNotReachable,
|
||||
CloudErrorProxyServerNotReachable,
|
||||
CloudErrorLoginCredentialsMissing
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CLOUDAUTHENTICATIONHANDLER_H
|
||||
@ -1,350 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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 "cloudauthenticator.h"
|
||||
#include "guhsettings.h"
|
||||
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
CloudAuthenticator::CloudAuthenticator(QString clientId, QString clientSecret, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_clientId(clientId),
|
||||
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);
|
||||
connect(m_networkManager, &QNetworkAccessManager::sslErrors, this, &CloudAuthenticator::onSslErrors);
|
||||
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setSingleShot(false);
|
||||
|
||||
connect(m_timer, &QTimer::timeout, this, &CloudAuthenticator::refreshTimeout);
|
||||
}
|
||||
|
||||
QUrl CloudAuthenticator::url() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
void CloudAuthenticator::setUrl(const QUrl &url)
|
||||
{
|
||||
m_url = url;
|
||||
}
|
||||
|
||||
QUrlQuery CloudAuthenticator::query() const
|
||||
{
|
||||
return m_query;
|
||||
}
|
||||
|
||||
void CloudAuthenticator::setQuery(const QUrlQuery &query)
|
||||
{
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
QString CloudAuthenticator::username() const
|
||||
{
|
||||
return m_username;
|
||||
}
|
||||
|
||||
void CloudAuthenticator::setUsername(const QString &username)
|
||||
{
|
||||
GuhSettings settings(GuhSettings::SettingsRoleDevices);
|
||||
settings.beginGroup("Cloud");
|
||||
settings.setValue("userName", username);
|
||||
settings.endGroup();
|
||||
m_username = username;
|
||||
}
|
||||
|
||||
QString CloudAuthenticator::password() const
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
|
||||
void CloudAuthenticator::setPassword(const QString &password)
|
||||
{
|
||||
m_password = password;
|
||||
}
|
||||
|
||||
QString CloudAuthenticator::clientId() const
|
||||
{
|
||||
return m_clientId;
|
||||
}
|
||||
|
||||
void CloudAuthenticator::setClientId(const QString &clientId)
|
||||
{
|
||||
m_clientId = clientId;
|
||||
}
|
||||
|
||||
QString CloudAuthenticator::clientSecret() const
|
||||
{
|
||||
return m_clientSecret;
|
||||
}
|
||||
|
||||
void CloudAuthenticator::setClientSecret(const QString clientSecret)
|
||||
{
|
||||
m_clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
QString CloudAuthenticator::token() const
|
||||
{
|
||||
return m_token;
|
||||
}
|
||||
|
||||
bool CloudAuthenticator::authenticated() const
|
||||
{
|
||||
return m_authenticated;
|
||||
}
|
||||
|
||||
bool CloudAuthenticator::startAuthentication()
|
||||
{
|
||||
qCDebug(dcCloud()) << "Authenticator: Start authentication" << m_username;
|
||||
|
||||
// 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");
|
||||
|
||||
QNetworkReply *reply = m_networkManager->post(request, m_query.toString().toUtf8());
|
||||
m_tokenRequests.append(reply);
|
||||
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();
|
||||
|
||||
m_authenticated = authenticated;
|
||||
emit authenticationChanged();
|
||||
}
|
||||
|
||||
void CloudAuthenticator::setToken(const QString &token)
|
||||
{
|
||||
m_token = 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();
|
||||
|
||||
// token request
|
||||
if (m_tokenRequests.contains(reply)) {
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
m_tokenRequests.removeAll(reply);
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcCloud()) << "Authenticator: Request token reply error:" << status << reply->errorString();
|
||||
m_error = Cloud::CloudErrorIdentityServerNotReachable;
|
||||
setAuthenticated(false);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcCloud()) << "Authenticator: Request token reply HTTP error:" << status << reply->errorString();
|
||||
qCWarning(dcCloud()) << data;
|
||||
setAuthenticated(false);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
// check JSON
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcCloud()) << "Authenticator: Request token reply JSON error:" << error.errorString();
|
||||
setAuthenticated(false);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!jsonDoc.toVariant().toMap().contains("access_token")) {
|
||||
qCWarning(dcCloud()) << "Authenticator: Could not get access token" << jsonDoc.toJson();
|
||||
setAuthenticated(false);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
setToken(jsonDoc.toVariant().toMap().value("access_token").toString());
|
||||
setAuthenticated(true);
|
||||
|
||||
if (jsonDoc.toVariant().toMap().contains("expires_in") && jsonDoc.toVariant().toMap().contains("refresh_token")) {
|
||||
int expireTime = jsonDoc.toVariant().toMap().value("expires_in").toInt();
|
||||
setRefreshToken(jsonDoc.toVariant().toMap().value("refresh_token").toString());
|
||||
qCDebug(dcCloud()) << "Authenticator: Token will be refreshed in" << expireTime << "[s]";
|
||||
m_timer->start((expireTime - 20) * 1000);
|
||||
}
|
||||
|
||||
} else if (m_refreshTokenRequests.contains(reply)) {
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
m_refreshTokenRequests.removeAll(reply);
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcCloud()) << "Authenticator: Request token reply error:" << status << reply->errorString();
|
||||
m_error = Cloud::CloudErrorIdentityServerNotReachable;
|
||||
setAuthenticated(false);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcCloud()) << "Authenticator: Refresh token reply HTTP error:" << status << reply->errorString();
|
||||
setAuthenticated(false);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
// check JSON
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcCloud()) << "Authenticator: Refresh token reply JSON error:" << error.errorString();
|
||||
setAuthenticated(false);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!jsonDoc.toVariant().toMap().contains("access_token")) {
|
||||
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()) << "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();
|
||||
setRefreshToken(jsonDoc.toVariant().toMap().value("refresh_token").toString());
|
||||
qCDebug(dcCloud()) << "Authenticator: Token will be refreshed in" << expireTime << "[s]";
|
||||
m_timer->start((expireTime - 20) * 1000);
|
||||
}
|
||||
|
||||
setAuthenticated(true);
|
||||
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void CloudAuthenticator::refreshTimeout()
|
||||
{
|
||||
qCDebug(dcCloud()) << "Authenticator: Refresh authentication token for" << m_username;
|
||||
|
||||
QUrlQuery query;
|
||||
query.addQueryItem("grant_type", "refresh_token");
|
||||
query.addQueryItem("refresh_token", m_refreshToken);
|
||||
|
||||
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");
|
||||
|
||||
QNetworkReply *reply = m_networkManager->post(request, query.toString().toUtf8());
|
||||
m_refreshTokenRequests.append(reply);
|
||||
}
|
||||
|
||||
void CloudAuthenticator::onSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
||||
{
|
||||
// Ignore SSL errors, but inform in the logs
|
||||
reply->ignoreSslErrors();
|
||||
|
||||
if (m_refreshTokenRequests.contains(reply)) {
|
||||
qCWarning(dcCloud()) << "SSL errors occured for token refresh reply:";
|
||||
} else if (m_tokenRequests.contains(reply)) {
|
||||
qCWarning(dcCloud()) << "SSL errors occured for token reply:";
|
||||
} else {
|
||||
qCWarning(dcCloud()) << "SSL errors occured for unknown reply:";
|
||||
}
|
||||
|
||||
foreach (const QSslError &error, errors) {
|
||||
qCWarning(dcCloud()) << " " << (int)error.error() << error.errorString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,105 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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 CLOUDAUTHENTICATOR_H
|
||||
#define CLOUDAUTHENTICATOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include "loggingcategories.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class CloudAuthenticator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CloudAuthenticator(QString clientId, QString clientSecret, QObject *parent = 0);
|
||||
|
||||
QUrl url() const;
|
||||
void setUrl(const QUrl &url);
|
||||
|
||||
QUrlQuery query() const;
|
||||
void setQuery(const QUrlQuery &query);
|
||||
|
||||
QString username() const;
|
||||
void setUsername(const QString &username);
|
||||
|
||||
QString password() const;
|
||||
void setPassword(const QString &password);
|
||||
|
||||
QString clientId() const;
|
||||
void setClientId(const QString &clientId);
|
||||
|
||||
QString clientSecret() const;
|
||||
void setClientSecret(const QString clientSecret);
|
||||
|
||||
// Read only
|
||||
QString token() const;
|
||||
bool authenticated() const;
|
||||
|
||||
bool startAuthentication();
|
||||
void stopAuthentication();
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QTimer *m_timer;
|
||||
QList<QNetworkReply *> m_tokenRequests;
|
||||
QList<QNetworkReply *> m_refreshTokenRequests;
|
||||
|
||||
QUrl m_url;
|
||||
QUrlQuery m_query;
|
||||
QString m_username;
|
||||
QString m_password;
|
||||
QString m_clientId;
|
||||
QString m_clientSecret;
|
||||
|
||||
QString m_token;
|
||||
QString m_refreshToken;
|
||||
|
||||
bool m_authenticated;
|
||||
|
||||
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();
|
||||
void onSslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
|
||||
|
||||
signals:
|
||||
void authenticationChanged();
|
||||
void tokenChanged();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CLOUDAUTHENTICATOR_H
|
||||
@ -1,224 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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 "cloudconnection.h"
|
||||
#include "loggingcategories.h"
|
||||
#include "guhsettings.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
CloudConnection::CloudConnection(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_error(CloudConnectionErrorNoError),
|
||||
m_connected(false),
|
||||
m_authenticated(false)
|
||||
{
|
||||
// If not connected, try to reconnect
|
||||
m_reconnectionTimer = new QTimer(this);
|
||||
m_reconnectionTimer->setSingleShot(false);
|
||||
m_reconnectionTimer->setInterval(10000);
|
||||
connect(m_reconnectionTimer, &QTimer::timeout, this, &CloudConnection::reconnectionTimeout);
|
||||
|
||||
// Ping the server to make sure the connection is still alive
|
||||
m_pingTimer = new QTimer(this);
|
||||
m_pingTimer->setSingleShot(false);
|
||||
m_pingTimer->setInterval(30000);
|
||||
connect(m_pingTimer, &QTimer::timeout, this, &CloudConnection::onPingTimeout);
|
||||
|
||||
// Timer to check if ping response was received (if not, reconnect the socket)
|
||||
m_pingResponseTimer = new QTimer(this);
|
||||
m_pingResponseTimer->setSingleShot(true);
|
||||
m_pingResponseTimer->setInterval(5000);
|
||||
connect(m_pingResponseTimer, &QTimer::timeout, this, &CloudConnection::onPongTimeout);
|
||||
|
||||
m_connection = new QWebSocket("guhd", QWebSocketProtocol::Version13, this);
|
||||
connect(m_connection, SIGNAL(connected()), this, SLOT(onConnected()));
|
||||
connect(m_connection, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
|
||||
connect(m_connection, SIGNAL(textMessageReceived(QString)), this, SLOT(onTextMessageReceived(QString)));
|
||||
connect(m_connection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
|
||||
connect(m_connection, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
|
||||
connect(m_connection, SIGNAL(pong(quint64,QByteArray)), this, SLOT(onPong(quint64,QByteArray)));
|
||||
|
||||
m_authenticator = new CloudAuthenticator("6ac82de6a2ba454394f9022b6a733885", "d63eece1b725419f80961a9b1c49f8d4", this);
|
||||
m_authenticator->setUrl(m_authenticationServerUrl);
|
||||
|
||||
connect(m_authenticator, &CloudAuthenticator::authenticationChanged, this, &CloudConnection::onAuthenticationChanged);
|
||||
}
|
||||
|
||||
void CloudConnection::connectToCloud()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
bool CloudConnection::connected() const
|
||||
{
|
||||
return m_connected;
|
||||
}
|
||||
|
||||
bool CloudConnection::authenticated() const
|
||||
{
|
||||
return m_authenticated;
|
||||
}
|
||||
|
||||
void CloudConnection::sendData(const QByteArray &data)
|
||||
{
|
||||
m_connection->sendTextMessage(data);
|
||||
}
|
||||
|
||||
void CloudConnection::setConnected(const bool &connected)
|
||||
{
|
||||
m_connected = connected;
|
||||
emit connectedChanged();
|
||||
}
|
||||
|
||||
void CloudConnection::setAuthenticated(const bool &authenticated)
|
||||
{
|
||||
m_authenticated = authenticated;
|
||||
emit authenticatedChanged();
|
||||
}
|
||||
|
||||
void CloudConnection::onAuthenticationChanged()
|
||||
{
|
||||
setAuthenticated(m_authenticator->authenticated());
|
||||
|
||||
if (m_authenticated) {
|
||||
qCDebug(dcCloud()) << "Connecting to" << m_proxyUrl.toString();
|
||||
m_connection->open(m_proxyUrl);
|
||||
} else {
|
||||
m_error = m_authenticator->error();
|
||||
}
|
||||
emit authenticatedChanged();
|
||||
}
|
||||
|
||||
void CloudConnection::onConnected()
|
||||
{
|
||||
qCDebug(dcCloud()) << "Connected to cloud proxy server" << m_proxyUrl.toString();
|
||||
setConnected(true);
|
||||
m_pingTimer->start();
|
||||
m_reconnectionTimer->stop();
|
||||
}
|
||||
|
||||
void CloudConnection::onDisconnected()
|
||||
{
|
||||
if (!m_reconnectionTimer->isActive())
|
||||
qCDebug(dcCloud()) << "Disconnected from cloud:" << m_connection->closeReason();
|
||||
|
||||
setConnected(false);
|
||||
m_pingTimer->stop();
|
||||
m_pingResponseTimer->stop();
|
||||
m_reconnectionTimer->start();
|
||||
}
|
||||
|
||||
void CloudConnection::onError(const QAbstractSocket::SocketError &error)
|
||||
{
|
||||
if (!m_reconnectionTimer->isActive())
|
||||
qCWarning(dcCloud()) << "Websocket error:" << error << m_connection->errorString();
|
||||
m_reconnectionTimer->start(10000);
|
||||
}
|
||||
|
||||
void CloudConnection::onTextMessageReceived(const QString &message)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(message.toUtf8(), &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcCloud()) << "Could not parse json data from guh" << message.toUtf8() << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
emit dataReceived(jsonDoc.toVariant().toMap());
|
||||
}
|
||||
|
||||
void CloudConnection::onError(const QAbstractSocket::SocketError &error)
|
||||
{
|
||||
if (!m_reconnectionTimer->isActive())
|
||||
qCWarning(dcCloud()) << "Websocket error:" << error << m_connection->errorString();
|
||||
|
||||
m_connection->close();
|
||||
setConnected(false);
|
||||
m_error = Cloud::CloudErrorProxyServerNotReachable;
|
||||
}
|
||||
|
||||
void CloudConnection::onPingTimeout()
|
||||
{
|
||||
if (!connected())
|
||||
return;
|
||||
|
||||
m_connection->ping("Ping");
|
||||
m_pingResponseTimer->start();
|
||||
}
|
||||
|
||||
void CloudConnection::onPong(const quint64 elapsedTime, const QByteArray &payload)
|
||||
{
|
||||
Q_UNUSED(elapsedTime);
|
||||
Q_UNUSED(payload);
|
||||
m_pingResponseTimer->stop();
|
||||
}
|
||||
|
||||
void CloudConnection::onPongTimeout()
|
||||
{
|
||||
qCWarning(dcCloud()) << "Pong timeout: did not get a ping response from the server (after 5s): reconnecting to the server...";
|
||||
m_connection->close(QWebSocketProtocol::CloseCodeAbnormalDisconnection, "Ping timeout");
|
||||
if (authenticator()->authenticated()) {
|
||||
m_connection->open(m_proxyServerUrl);
|
||||
} else {
|
||||
m_authenticator->startAuthentication();
|
||||
}
|
||||
}
|
||||
|
||||
void CloudConnection::onStateChanged(const QAbstractSocket::SocketState &state)
|
||||
{
|
||||
qCDebug(dcCloud()) << "Socket:" << state;
|
||||
}
|
||||
|
||||
void CloudConnection::reconnectionTimeout()
|
||||
{
|
||||
if (m_authenticated) {
|
||||
m_connection->open(m_proxyUrl);
|
||||
} else {
|
||||
m_authenticator->startAuthentication();
|
||||
m_reconnectionTimer->stop();
|
||||
m_error = CloudConnectionErrorAuthenticationFailed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,104 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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 CLOUDCONNECTION_H
|
||||
#define CLOUDCONNECTION_H
|
||||
|
||||
#include <QUrl>
|
||||
#include <QUuid>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QWebSocket>
|
||||
|
||||
#include "cloudauthenticator.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class CloudConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(CloudConnectionError)
|
||||
|
||||
public:
|
||||
enum CloudConnectionError {
|
||||
CloudConnectionErrorNoError,
|
||||
CloudConnectionErrorAuthenticationFailed,
|
||||
CloudConnectionErrorCloudServerNotReachable
|
||||
};
|
||||
|
||||
explicit CloudConnection(QObject *parent = 0);
|
||||
|
||||
void connectToCloud();
|
||||
void disconnectFromCloud();
|
||||
|
||||
CloudAuthenticator *authenticator() const;
|
||||
|
||||
CloudConnectionError error() const;
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
bool connected() const;
|
||||
bool authenticated() const;
|
||||
|
||||
void sendData(const QByteArray &data);
|
||||
void sendRequest(const QVariantMap &request);
|
||||
|
||||
private:
|
||||
QWebSocket *m_connection;
|
||||
CloudAuthenticator *m_authenticator;
|
||||
CloudConnectionError m_error;
|
||||
|
||||
QTimer *m_reconnectionTimer;
|
||||
QTimer *m_pingTimer;
|
||||
QTimer *m_pingResponseTimer;
|
||||
|
||||
QUrl m_proxyUrl;
|
||||
QUrl m_keystoneUrl;
|
||||
|
||||
bool m_connected;
|
||||
bool m_authenticated;
|
||||
|
||||
void setConnected(const bool &connected);
|
||||
void setAuthenticated(const bool &authenticated);
|
||||
|
||||
signals:
|
||||
void dataReceived(const QVariantMap &data);
|
||||
void enabledChanged();
|
||||
void connectedChanged();
|
||||
void activeChanged();
|
||||
void authenticatedChanged();
|
||||
|
||||
private slots:
|
||||
void onAuthenticationChanged();
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onError(const QAbstractSocket::SocketError &error);
|
||||
void onStateChanged(const QAbstractSocket::SocketState &state);
|
||||
void onPingTimeout();
|
||||
void onPong(const quint64 elapsedTime, const QByteArray &payload);
|
||||
void onPongTimeout();
|
||||
|
||||
void reconnectionTimeout();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CLOUDCONNECTION_H
|
||||
@ -1,94 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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 ¶ms)
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
}
|
||||
|
||||
void CloudConnectionHandler::processGetTunnels(const QVariantMap ¶ms)
|
||||
{
|
||||
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 ¶ms)
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
}
|
||||
|
||||
void CloudConnectionHandler::processConnectionAdded(const QVariantMap ¶ms)
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
}
|
||||
|
||||
void CloudConnectionHandler::processConnectionRemoved(const QVariantMap ¶ms)
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
}
|
||||
|
||||
void CloudConnectionHandler::processTunnelAdded(const QVariantMap ¶ms)
|
||||
{
|
||||
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 ¶ms)
|
||||
{
|
||||
QUuid tunnelId = params.value("tunnelId").toUuid();
|
||||
GuhCore::instance()->cloudManager()->onTunnelRemoved(tunnelId);
|
||||
}
|
||||
|
||||
void CloudConnectionHandler::processDataReceived(const QVariantMap ¶ms)
|
||||
{
|
||||
QUuid tunnelId = params.value("tunnelId").toUuid();
|
||||
GuhCore::instance()->cloudManager()->onCloudDataReceived(tunnelId, params.value("data").toMap());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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 ¶ms);
|
||||
Q_INVOKABLE void processGetTunnels(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void processSendData(const QVariantMap ¶ms);
|
||||
|
||||
// API notifications
|
||||
Q_INVOKABLE void processConnectionAdded(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void processConnectionRemoved(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void processTunnelAdded(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void processTunnelRemoved(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void processDataReceived(const QVariantMap ¶ms);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CLOUDCONNECTIONHANDLER_H
|
||||
@ -1,126 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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
|
||||
{
|
||||
Q_OBJECT
|
||||
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
|
||||
@ -1,31 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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
|
||||
@ -1,66 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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
|
||||
@ -1,220 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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();
|
||||
|
||||
// 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);
|
||||
if (m_tunnelClients.isEmpty()) {
|
||||
qCDebug(dcCloud()) << "Remote connection inactive.";
|
||||
setActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
} else {
|
||||
qCDebug(dcCloud()) << "Disconnected";
|
||||
// Reset information
|
||||
setAuthenticated(false);
|
||||
setActive(false);
|
||||
m_connectionId = QUuid();
|
||||
|
||||
if (m_runningAuthentication) {
|
||||
m_runningAuthentication = false;
|
||||
emit authenticationFinished(m_cloudConnection->error());
|
||||
}
|
||||
|
||||
// Clean up all tunnels
|
||||
foreach (const QUuid &clientId, m_tunnelClients.keys()) {
|
||||
emit clientDisconnected(clientId);
|
||||
}
|
||||
m_tunnelClients.clear();
|
||||
|
||||
// Delete all replies
|
||||
qDeleteAll(m_replies.values());
|
||||
m_replies.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CloudManager::onAuthenticatedChanged()
|
||||
{
|
||||
if (!m_cloudConnection->authenticator()->authenticated()) {
|
||||
m_authenticated = false;
|
||||
emit authenticatedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,102 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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
|
||||
@ -379,12 +379,6 @@ WebSocketServer *GuhCore::webSocketServer() const
|
||||
return m_webSocketServer;
|
||||
}
|
||||
|
||||
/*! Returns a pointer to the \l{CloudManager} instance owned by GuhCore. */
|
||||
CloudManager *GuhCore::cloudManager() const
|
||||
{
|
||||
return m_cloudManager;
|
||||
}
|
||||
|
||||
/*! Returns a pointer to the \l{ServerManager} instance owned by GuhCore. */
|
||||
ServerManager *GuhCore::serverManager() const
|
||||
{
|
||||
@ -437,9 +431,6 @@ GuhCore::GuhCore(QObject *parent) :
|
||||
qCDebug(dcApplication) << "Creating Log Engine";
|
||||
m_logger = new LogEngine(this);
|
||||
|
||||
qCDebug(dcApplication) << "Creating Cloud Manager";
|
||||
m_cloudManager = new CloudManager(m_configuration->cloudEnabled(), m_configuration->cloudAuthenticationServer(), m_configuration->cloudProxyServer(), this);
|
||||
|
||||
qCDebug(dcApplication) << "Creating Device Manager";
|
||||
m_deviceManager = new DeviceManager(m_configuration->locale(), this);
|
||||
|
||||
@ -462,7 +453,6 @@ GuhCore::GuhCore(QObject *parent) :
|
||||
// Register transport interface in the JSON RPC server
|
||||
m_serverManager->jsonServer()->registerTransportInterface(m_tcpServer);
|
||||
m_serverManager->jsonServer()->registerTransportInterface(m_webSocketServer);
|
||||
m_serverManager->jsonServer()->registerTransportInterface(m_cloudManager);
|
||||
m_serverManager->jsonServer()->registerTransportInterface(m_bluetoothServer, m_configuration->bluetoothServerEnabled());
|
||||
|
||||
// Webserver setup
|
||||
@ -472,11 +462,6 @@ GuhCore::GuhCore(QObject *parent) :
|
||||
// Create the NetworkManager
|
||||
m_networkManager = new NetworkManager(this);
|
||||
|
||||
// Connect the configuration changes
|
||||
connect(m_configuration, &GuhConfiguration::cloudEnabledChanged, m_cloudManager, &CloudManager::onCloudEnabledChanged);
|
||||
connect(m_configuration, &GuhConfiguration::cloudProxyServerChanged, m_cloudManager, &CloudManager::onProxyServerUrlChanged);
|
||||
connect(m_configuration, &GuhConfiguration::cloudAuthenticationServerChanged, m_cloudManager, &CloudManager::onAuthenticationServerUrlChanged);
|
||||
|
||||
connect(m_configuration, &GuhConfiguration::localeChanged, this, &GuhCore::onLocaleChanged);
|
||||
|
||||
connect(m_deviceManager, &DeviceManager::pluginConfigChanged, this, &GuhCore::pluginConfigChanged);
|
||||
|
||||
@ -36,7 +36,6 @@
|
||||
#include "websocketserver.h"
|
||||
#include "bluetoothserver.h"
|
||||
|
||||
#include "cloud/cloudmanager.h"
|
||||
#include "time/timemanager.h"
|
||||
|
||||
#ifndef TESTING_ENABLED
|
||||
@ -84,7 +83,6 @@ public:
|
||||
TimeManager *timeManager() const;
|
||||
WebServer *webServer() const;
|
||||
WebSocketServer *webSocketServer() const;
|
||||
CloudManager *cloudManager() const;
|
||||
ServerManager *serverManager() const;
|
||||
BluetoothServer *bluetoothServer() const;
|
||||
NetworkManager *networkManager() const;
|
||||
@ -137,8 +135,6 @@ private:
|
||||
WebServer *m_webServer;
|
||||
BluetoothServer *m_bluetoothServer;
|
||||
|
||||
CloudManager *m_cloudManager;
|
||||
|
||||
QHash<ActionId, Action> m_pendingActions;
|
||||
|
||||
private slots:
|
||||
|
||||
@ -1,140 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*!
|
||||
\class guhserver::CloudHandler
|
||||
\brief This subclass of \l{JsonHandler} processes the JSON requests for the \tt Cloud namespace.
|
||||
|
||||
\ingroup json
|
||||
\inmodule core
|
||||
|
||||
This \l{JsonHandler} will be created in the \l{JsonRPCServer} and used to handle JSON-RPC requests
|
||||
for the \tt {Cloud} namespace of the API.
|
||||
|
||||
\sa JsonHandler, JsonRPCServer
|
||||
*/
|
||||
|
||||
/*! \fn void guhserver::CloudHandler::ConnectionStatusChanged(const QVariantMap ¶ms);
|
||||
This signal is emitted to the API notifications when the status of the \l{CloudManager} has changed.
|
||||
The \a params contains the map for the notification.
|
||||
*/
|
||||
|
||||
|
||||
#include "cloudhandler.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
/*! Constructs a new \l CloudHandler with the given \a parent. */
|
||||
CloudHandler::CloudHandler(QObject *parent) :
|
||||
JsonHandler(parent)
|
||||
{
|
||||
QVariantMap returns;
|
||||
QVariantMap params;
|
||||
|
||||
setDescription("Authenticate", "Connect and authenticate the cloud connection with the given username and password.");
|
||||
params.insert("username", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
params.insert("password", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
setParams("Authenticate", params);
|
||||
returns.insert("cloudConnectionError", JsonTypes::cloudConnectionErrorRef());
|
||||
setReturns("Authenticate", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("GetConnectionStatus", "Get the current status of the cloud connection.");
|
||||
setParams("GetConnectionStatus", params);
|
||||
returns.insert("enabled", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
returns.insert("connected", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
returns.insert("active", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
returns.insert("authenticated", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
setReturns("GetConnectionStatus", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("Enable", "Enable or disable the cloud connection.");
|
||||
params.insert("enable", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
setParams("Enable", params);
|
||||
returns.insert("cloudError", JsonTypes::cloudErrorRef());
|
||||
setReturns("Enable", returns);
|
||||
|
||||
// Notification
|
||||
params.clear(); returns.clear();
|
||||
setDescription("ConnectionStatusChanged", "Emitted whenever the status of the cloud connection changed.");
|
||||
params.insert("enabled", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
params.insert("connected", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
params.insert("active", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
params.insert("authenticated", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
setParams("ConnectionStatusChanged", params);
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
/*! Returns the name of the \l{CloudHandler}. In this case \b Cloud.*/
|
||||
QString CloudHandler::name() const
|
||||
{
|
||||
return "Cloud";
|
||||
}
|
||||
|
||||
JsonReply *CloudHandler::Authenticate(const QVariantMap ¶ms) const
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
|
||||
QString username = params.value("username").toString();
|
||||
QString password = params.value("password").toString();
|
||||
qCDebug(dcJsonRpc()) << "Authenticate cloud connection for user" << username;
|
||||
|
||||
GuhCore::instance()->cloudManager()->connectToCloud(username, password);
|
||||
|
||||
QVariantMap returns;
|
||||
returns.insert("cloudConnectionError", JsonTypes::cloudConnectionErrorToString(CloudConnection::CloudConnectionErrorNoError));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *CloudHandler::GetConnectionStatus(const QVariantMap ¶ms) const
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
|
||||
QVariantMap returns;
|
||||
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);
|
||||
}
|
||||
|
||||
JsonReply *CloudHandler::Enable(const QVariantMap ¶ms) const
|
||||
{
|
||||
bool enable = params.value("enable").toBool();
|
||||
GuhCore::instance()->configuration()->setCloudEnabled(enable);
|
||||
return createReply(statusToReply(Cloud::CloudErrorNoError));
|
||||
}
|
||||
|
||||
void CloudHandler::onConnectionStatusChanged()
|
||||
{
|
||||
QVariantMap params;
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* 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 CLOUDHANDLER_H
|
||||
#define CLOUDHANDLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "guhcore.h"
|
||||
#include "jsonhandler.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
class CloudHandler : public JsonHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CloudHandler(QObject *parent = 0);
|
||||
|
||||
QString name() const;
|
||||
|
||||
Q_INVOKABLE JsonReply *Authenticate(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply *GetConnectionStatus(const QVariantMap ¶ms) const;
|
||||
Q_INVOKABLE JsonReply *Enable(const QVariantMap ¶ms) const;
|
||||
|
||||
private:
|
||||
QList<JsonReply *> m_asyncAuthenticationReplies;
|
||||
|
||||
signals:
|
||||
void ConnectionStatusChanged(const QVariantMap ¶ms);
|
||||
|
||||
private slots:
|
||||
void onConnectionStatusChanged();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CLOUDHANDLER_H
|
||||
@ -204,14 +204,6 @@ QVariantMap JsonHandler::statusToReply(Logging::LoggingError status) const
|
||||
return returns;
|
||||
}
|
||||
|
||||
/*! Returns the formated error map for the given \a status. */
|
||||
QVariantMap JsonHandler::statusToReply(Cloud::CloudError status) const
|
||||
{
|
||||
QVariantMap returns;
|
||||
returns.insert("cloudError", JsonTypes::cloudErrorToString(status));
|
||||
return returns;
|
||||
}
|
||||
|
||||
/*! Returns the formated error map for the given \a status. */
|
||||
QVariantMap JsonHandler::statusToReply(GuhConfiguration::ConfigurationError status) const
|
||||
{
|
||||
|
||||
@ -111,7 +111,6 @@ protected:
|
||||
QVariantMap statusToReply(DeviceManager::DeviceError status) const;
|
||||
QVariantMap statusToReply(RuleEngine::RuleError status) const;
|
||||
QVariantMap statusToReply(Logging::LoggingError status) const;
|
||||
QVariantMap statusToReply(Cloud::CloudError status) const;
|
||||
QVariantMap statusToReply(GuhConfiguration::ConfigurationError status) const;
|
||||
QVariantMap statusToReply(NetworkManager::NetworkManagerError status) const;
|
||||
|
||||
|
||||
@ -55,7 +55,6 @@
|
||||
#include "logginghandler.h"
|
||||
#include "statehandler.h"
|
||||
#include "websocketserver.h"
|
||||
#include "cloudhandler.h"
|
||||
#include "configurationhandler.h"
|
||||
#include "networkmanagerhandler.h"
|
||||
|
||||
@ -164,6 +163,32 @@ void JsonRPCServer::registerTransportInterface(TransportInterface *interface, co
|
||||
m_interfaces.append(interface);
|
||||
}
|
||||
|
||||
/*! Send a JSON success response to the client with the given \a clientId,
|
||||
* \a commandId and \a params to the inerted \l{TransportInterface}.
|
||||
*/
|
||||
void JsonRPCServer::sendResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
QVariantMap response;
|
||||
response.insert("id", commandId);
|
||||
response.insert("status", "success");
|
||||
response.insert("params", params);
|
||||
|
||||
interface->sendData(clientId, QJsonDocument::fromVariant(response).toJson());
|
||||
}
|
||||
|
||||
/*! Send a JSON error response to the client with the given \a clientId,
|
||||
* \a commandId and \a error to the inerted \l{TransportInterface}.
|
||||
*/
|
||||
void JsonRPCServer::sendErrorResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QString &error)
|
||||
{
|
||||
QVariantMap errorResponse;
|
||||
errorResponse.insert("id", commandId);
|
||||
errorResponse.insert("status", "error");
|
||||
errorResponse.insert("error", error);
|
||||
|
||||
interface->sendData(clientId, QJsonDocument::fromVariant(errorResponse).toJson());
|
||||
}
|
||||
|
||||
void JsonRPCServer::setup()
|
||||
{
|
||||
registerHandler(this);
|
||||
@ -173,7 +198,6 @@ void JsonRPCServer::setup()
|
||||
registerHandler(new EventHandler(this));
|
||||
registerHandler(new LoggingHandler(this));
|
||||
registerHandler(new StateHandler(this));
|
||||
registerHandler(new CloudHandler(this));
|
||||
registerHandler(new ConfigurationHandler(this));
|
||||
registerHandler(new NetworkManagerHandler(this));
|
||||
}
|
||||
@ -186,7 +210,7 @@ void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &data)
|
||||
|
||||
if(error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcJsonRpc) << "Failed to parse JSON data" << data << ":" << error.errorString();
|
||||
interface->sendErrorResponse(clientId, -1, QString("Failed to parse JSON data: %1").arg(error.errorString()));
|
||||
sendErrorResponse(interface, clientId, -1, QString("Failed to parse JSON data: %1").arg(error.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -196,14 +220,14 @@ void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &data)
|
||||
int commandId = message.value("id").toInt(&success);
|
||||
if (!success) {
|
||||
qCWarning(dcJsonRpc) << "Error parsing command. Missing \"id\":" << message;
|
||||
interface->sendErrorResponse(clientId, commandId, "Error parsing command. Missing 'id'");
|
||||
sendErrorResponse(interface, clientId, commandId, "Error parsing command. Missing 'id'");
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList commandList = message.value("method").toString().split('.');
|
||||
if (commandList.count() != 2) {
|
||||
qCWarning(dcJsonRpc) << "Error parsing method.\nGot:" << message.value("method").toString() << "\nExpected: \"Namespace.method\"";
|
||||
interface->sendErrorResponse(clientId, commandId, QString("Error parsing method. Got: '%1'', Expected: 'Namespace.method'").arg(message.value("method").toString()));
|
||||
sendErrorResponse(interface, clientId, commandId, QString("Error parsing method. Got: '%1'', Expected: 'Namespace.method'").arg(message.value("method").toString()));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -212,11 +236,11 @@ void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &data)
|
||||
|
||||
JsonHandler *handler = m_handlers.value(targetNamespace);
|
||||
if (!handler) {
|
||||
interface->sendErrorResponse(clientId, commandId, "No such namespace");
|
||||
sendErrorResponse(interface, clientId, commandId, "No such namespace");
|
||||
return;
|
||||
}
|
||||
if (!handler->hasMethod(method)) {
|
||||
interface->sendErrorResponse(clientId, commandId, "No such method");
|
||||
sendErrorResponse(interface, clientId, commandId, "No such method");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -224,7 +248,7 @@ void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &data)
|
||||
|
||||
QPair<bool, QString> validationResult = handler->validateParams(method, params);
|
||||
if (!validationResult.first) {
|
||||
interface->sendErrorResponse(clientId, commandId, "Invalid params: " + validationResult.second);
|
||||
sendErrorResponse(interface, clientId, commandId, "Invalid params: " + validationResult.second);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -242,7 +266,7 @@ void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &data)
|
||||
} else {
|
||||
Q_ASSERT_X((targetNamespace == "JSONRPC" && method == "Introspect") || handler->validateReturns(method, reply->data()).first
|
||||
,"validating return value", formatAssertion(targetNamespace, method, handler, reply->data()).toLatin1().data());
|
||||
interface->sendResponse(clientId, commandId, reply->data());
|
||||
sendResponse(interface, clientId, commandId, reply->data());
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
@ -268,7 +292,7 @@ void JsonRPCServer::sendNotification(const QVariantMap ¶ms)
|
||||
notification.insert("params", params);
|
||||
|
||||
foreach (TransportInterface *interface, m_interfaces) {
|
||||
interface->sendData(m_clients.keys(true), notification);
|
||||
interface->sendData(m_clients.keys(true), QJsonDocument::fromVariant(notification).toJson());
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,9 +303,9 @@ void JsonRPCServer::asyncReplyFinished()
|
||||
if (!reply->timedOut()) {
|
||||
Q_ASSERT_X(reply->handler()->validateReturns(reply->method(), reply->data()).first
|
||||
,"validating return value", formatAssertion(reply->handler()->name(), reply->method(), reply->handler(), reply->data()).toLatin1().data());
|
||||
interface->sendResponse(reply->clientId(), reply->commandId(), reply->data());
|
||||
sendResponse(interface, reply->clientId(), reply->commandId(), reply->data());
|
||||
} else {
|
||||
interface->sendErrorResponse(reply->clientId(), reply->commandId(), "Command timed out");
|
||||
sendErrorResponse(interface, reply->clientId(), reply->commandId(), "Command timed out");
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
@ -313,7 +337,7 @@ void JsonRPCServer::clientConnected(const QUuid &clientId)
|
||||
handshake.insert("uuid", GuhCore::instance()->configuration()->serverUuid().toString());
|
||||
handshake.insert("language", GuhCore::instance()->configuration()->locale().name());
|
||||
handshake.insert("protocol version", JSON_PROTOCOL_VERSION);
|
||||
interface->sendData(clientId, handshake);
|
||||
interface->sendData(clientId, QJsonDocument::fromVariant(handshake).toJson());
|
||||
}
|
||||
|
||||
void JsonRPCServer::clientDisconnected(const QUuid &clientId)
|
||||
|
||||
@ -54,6 +54,10 @@ public:
|
||||
|
||||
void registerTransportInterface(TransportInterface *interface, const bool &enabled = true);
|
||||
|
||||
private:
|
||||
void sendResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QVariantMap ¶ms = QVariantMap());
|
||||
void sendErrorResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QString &error);
|
||||
|
||||
private slots:
|
||||
void setup();
|
||||
|
||||
|
||||
@ -82,7 +82,6 @@ QVariantList JsonTypes::s_loggingSource;
|
||||
QVariantList JsonTypes::s_loggingLevel;
|
||||
QVariantList JsonTypes::s_loggingEventType;
|
||||
QVariantList JsonTypes::s_repeatingMode;
|
||||
QVariantList JsonTypes::s_cloudError;
|
||||
QVariantList JsonTypes::s_configurationError;
|
||||
QVariantList JsonTypes::s_networkManagerError;
|
||||
QVariantList JsonTypes::s_networkManagerState;
|
||||
@ -138,7 +137,6 @@ void JsonTypes::init()
|
||||
s_loggingLevel = enumToStrings(Logging::staticMetaObject, "LoggingLevel");
|
||||
s_loggingEventType = enumToStrings(Logging::staticMetaObject, "LoggingEventType");
|
||||
s_repeatingMode = enumToStrings(RepeatingOption::staticMetaObject, "RepeatingMode");
|
||||
s_cloudError = enumToStrings(Cloud::staticMetaObject, "CloudError");
|
||||
s_configurationError = enumToStrings(GuhConfiguration::staticMetaObject, "ConfigurationError");
|
||||
s_networkManagerError = enumToStrings(NetworkManager::staticMetaObject, "NetworkManagerError");
|
||||
s_networkManagerState = enumToStrings(NetworkManager::staticMetaObject, "NetworkManagerState");
|
||||
@ -394,7 +392,6 @@ QVariantMap JsonTypes::allTypes()
|
||||
allTypes.insert("LoggingSource", loggingSource());
|
||||
allTypes.insert("LoggingEventType", loggingEventType());
|
||||
allTypes.insert("RepeatingMode", repeatingMode());
|
||||
allTypes.insert("CloudError", cloudError());
|
||||
allTypes.insert("ConfigurationError", configurationError());
|
||||
allTypes.insert("NetworkManagerError", networkManagerError());
|
||||
allTypes.insert("NetworkManagerState", networkManagerState());
|
||||
@ -1890,10 +1887,10 @@ QPair<bool, QString> JsonTypes::validateVariant(const QVariant &templateVariant,
|
||||
qCWarning(dcJsonRpc) << QString("Value %1 not allowed in %2").arg(variant.toString()).arg(repeatingModeRef());
|
||||
return result;
|
||||
}
|
||||
} else if (refName == cloudConnectionErrorRef()) {
|
||||
QPair<bool, QString> result = validateEnum(s_cloudConnectionError, variant);
|
||||
} else if (refName == removePolicyRef()) {
|
||||
QPair<bool, QString> result = validateEnum(s_removePolicy, variant);
|
||||
if (!result.first) {
|
||||
qCWarning(dcJsonRpc) << QString("Value %1 not allowed in %2").arg(variant.toString()).arg(cloudConnectionErrorRef());
|
||||
qCWarning(dcJsonRpc) << QString("Value %1 not allowed in %2").arg(variant.toString()).arg(removePolicyRef());
|
||||
return result;
|
||||
}
|
||||
} else if (refName == configurationErrorRef()) {
|
||||
|
||||
@ -45,8 +45,6 @@
|
||||
#include "time/timedescriptor.h"
|
||||
#include "time/timeeventitem.h"
|
||||
|
||||
#include "cloud/cloudconnection.h"
|
||||
|
||||
#include "networkmanager/networkmanager.h"
|
||||
#include "networkmanager/networkdevice.h"
|
||||
#include "networkmanager/wirednetworkdevice.h"
|
||||
@ -130,7 +128,6 @@ public:
|
||||
DECLARE_TYPE(loggingLevel, "LoggingLevel", Logging, LoggingLevel)
|
||||
DECLARE_TYPE(loggingEventType, "LoggingEventType", Logging, LoggingEventType)
|
||||
DECLARE_TYPE(repeatingMode, "RepeatingMode", RepeatingOption, RepeatingMode)
|
||||
DECLARE_TYPE(cloudError, "CloudError", Cloud, CloudError)
|
||||
DECLARE_TYPE(configurationError, "ConfigurationError", GuhConfiguration, ConfigurationError)
|
||||
DECLARE_TYPE(networkManagerError, "NetworkManagerError", NetworkManager, NetworkManagerError)
|
||||
DECLARE_TYPE(networkManagerState, "NetworkManagerState", NetworkManager, NetworkManagerState)
|
||||
|
||||
@ -23,7 +23,6 @@ HEADERS += $$top_srcdir/server/guhcore.h \
|
||||
$$top_srcdir/server/jsonrpc/eventhandler.h \
|
||||
$$top_srcdir/server/jsonrpc/statehandler.h \
|
||||
$$top_srcdir/server/jsonrpc/logginghandler.h \
|
||||
$$top_srcdir/server/jsonrpc/cloudhandler.h \
|
||||
$$top_srcdir/server/jsonrpc/configurationhandler.h \
|
||||
$$top_srcdir/server/jsonrpc/networkmanagerhandler.h \
|
||||
$$top_srcdir/server/logging/logging.h \
|
||||
@ -49,15 +48,6 @@ HEADERS += $$top_srcdir/server/guhcore.h \
|
||||
$$top_srcdir/server/time/repeatingoption.h \
|
||||
$$top_srcdir/server/time/timeeventitem.h \
|
||||
$$top_srcdir/server/time/timemanager.h \
|
||||
$$top_srcdir/server/cloud/cloudconnection.h \
|
||||
$$top_srcdir/server/cloud/cloudauthenticator.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 \
|
||||
$$top_srcdir/server/cloud/cloud.h \
|
||||
$$top_srcdir/server/networkmanager/dbus-interfaces.h \
|
||||
$$top_srcdir/server/networkmanager/networkmanager.h \
|
||||
$$top_srcdir/server/networkmanager/networkdevice.h \
|
||||
@ -90,7 +80,6 @@ SOURCES += $$top_srcdir/server/guhcore.cpp \
|
||||
$$top_srcdir/server/jsonrpc/eventhandler.cpp \
|
||||
$$top_srcdir/server/jsonrpc/statehandler.cpp \
|
||||
$$top_srcdir/server/jsonrpc/logginghandler.cpp \
|
||||
$$top_srcdir/server/jsonrpc/cloudhandler.cpp \
|
||||
$$top_srcdir/server/jsonrpc/configurationhandler.cpp \
|
||||
$$top_srcdir/server/jsonrpc/networkmanagerhandler.cpp \
|
||||
$$top_srcdir/server/logging/logengine.cpp \
|
||||
@ -115,14 +104,6 @@ SOURCES += $$top_srcdir/server/guhcore.cpp \
|
||||
$$top_srcdir/server/time/repeatingoption.cpp \
|
||||
$$top_srcdir/server/time/timeeventitem.cpp \
|
||||
$$top_srcdir/server/time/timemanager.cpp \
|
||||
$$top_srcdir/server/cloud/cloudconnection.cpp \
|
||||
$$top_srcdir/server/cloud/cloudauthenticator.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 \
|
||||
$$top_srcdir/server/networkmanager/networkmanager.cpp \
|
||||
$$top_srcdir/server/networkmanager/networkdevice.cpp \
|
||||
$$top_srcdir/server/networkmanager/wirelessaccesspoint.cpp \
|
||||
|
||||
@ -37,10 +37,8 @@
|
||||
#include "loggingcategories.h"
|
||||
#include "guhsettings.h"
|
||||
#include "guhcore.h"
|
||||
#include "jsonrpcserver.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
@ -68,7 +66,7 @@ TcpServer::~TcpServer()
|
||||
}
|
||||
|
||||
/*! Sending \a data to a list of \a clients.*/
|
||||
void TcpServer::sendData(const QList<QUuid> &clients, const QVariantMap &data)
|
||||
void TcpServer::sendData(const QList<QUuid> &clients, const QByteArray &data)
|
||||
{
|
||||
foreach (const QUuid &client, clients) {
|
||||
sendData(client, data);
|
||||
@ -76,12 +74,12 @@ void TcpServer::sendData(const QList<QUuid> &clients, const QVariantMap &data)
|
||||
}
|
||||
|
||||
/*! Sending \a data to the client with the given \a clientId.*/
|
||||
void TcpServer::sendData(const QUuid &clientId, const QVariantMap &data)
|
||||
void TcpServer::sendData(const QUuid &clientId, const QByteArray &data)
|
||||
{
|
||||
QTcpSocket *client = 0;
|
||||
client = m_clientList.value(clientId);
|
||||
if (client) {
|
||||
client->write(QJsonDocument::fromVariant(data).toJson());
|
||||
client->write(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,8 +41,8 @@ public:
|
||||
explicit TcpServer(const QHostAddress &host, const uint &port, QObject *parent = 0);
|
||||
~TcpServer();
|
||||
|
||||
void sendData(const QUuid &clientId, const QVariantMap &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QVariantMap &data) override;
|
||||
void sendData(const QUuid &clientId, const QByteArray &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QByteArray &data) override;
|
||||
|
||||
private:
|
||||
QTimer *m_timer;
|
||||
|
||||
@ -88,30 +88,4 @@ TransportInterface::~TransportInterface()
|
||||
{
|
||||
}
|
||||
|
||||
/*! Send a JSON success response to the client with the given \a clientId,
|
||||
* \a commandId and \a params to the inerted \l{TransportInterface}.
|
||||
*/
|
||||
void TransportInterface::sendResponse(const QUuid &clientId, int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
QVariantMap response;
|
||||
response.insert("id", commandId);
|
||||
response.insert("status", "success");
|
||||
response.insert("params", params);
|
||||
|
||||
sendData(clientId, response);
|
||||
}
|
||||
|
||||
/*! Send a JSON error response to the client with the given \a clientId,
|
||||
* \a commandId and \a error to the inerted \l{TransportInterface}.
|
||||
*/
|
||||
void TransportInterface::sendErrorResponse(const QUuid &clientId, int commandId, const QString &error)
|
||||
{
|
||||
QVariantMap errorResponse;
|
||||
errorResponse.insert("id", commandId);
|
||||
errorResponse.insert("status", "error");
|
||||
errorResponse.insert("error", error);
|
||||
|
||||
sendData(clientId, errorResponse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -35,11 +35,8 @@ public:
|
||||
explicit TransportInterface(QObject *parent = 0);
|
||||
virtual ~TransportInterface() = 0;
|
||||
|
||||
virtual void sendData(const QUuid &clientId, const QVariantMap &data) = 0;
|
||||
virtual void sendData(const QList<QUuid> &clients, const QVariantMap &data) = 0;
|
||||
|
||||
void sendResponse(const QUuid &clientId, int commandId, const QVariantMap ¶ms = QVariantMap());
|
||||
void sendErrorResponse(const QUuid &clientId, int commandId, const QString &error);
|
||||
virtual void sendData(const QUuid &clientId, const QByteArray &data) = 0;
|
||||
virtual void sendData(const QList<QUuid> &clients, const QByteArray &data) = 0;
|
||||
|
||||
signals:
|
||||
void clientConnected(const QUuid &clientId);
|
||||
|
||||
@ -52,7 +52,6 @@
|
||||
#include "websocketserver.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QSslConfiguration>
|
||||
|
||||
namespace guhserver {
|
||||
@ -86,12 +85,12 @@ WebSocketServer::~WebSocketServer()
|
||||
*
|
||||
* \sa TransportInterface::sendData()
|
||||
*/
|
||||
void WebSocketServer::sendData(const QUuid &clientId, const QVariantMap &data)
|
||||
void WebSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
|
||||
{
|
||||
QWebSocket *client = 0;
|
||||
client = m_clientList.value(clientId);
|
||||
if (client) {
|
||||
client->sendTextMessage(QJsonDocument::fromVariant(data).toJson());
|
||||
client->sendTextMessage(data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,7 +98,7 @@ void WebSocketServer::sendData(const QUuid &clientId, const QVariantMap &data)
|
||||
*
|
||||
* \sa TransportInterface::sendData()
|
||||
*/
|
||||
void WebSocketServer::sendData(const QList<QUuid> &clients, const QVariantMap &data)
|
||||
void WebSocketServer::sendData(const QList<QUuid> &clients, const QByteArray &data)
|
||||
{
|
||||
foreach (const QUuid &client, clients) {
|
||||
sendData(client, data);
|
||||
|
||||
@ -45,8 +45,8 @@ public:
|
||||
explicit WebSocketServer(const QHostAddress &address, const uint &port, const bool &sslEnabled, QObject *parent = 0);
|
||||
~WebSocketServer();
|
||||
|
||||
void sendData(const QUuid &clientId, const QVariantMap &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QVariantMap &data) override;
|
||||
void sendData(const QUuid &clientId, const QByteArray &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QByteArray &data) override;
|
||||
|
||||
private:
|
||||
QWebSocketServer *m_server;
|
||||
|
||||
@ -223,7 +223,7 @@ QVariant GuhTestBase::injectAndWait(const QString &method, const QVariantMap &pa
|
||||
QJsonParseError error;
|
||||
jsonDoc = QJsonDocument::fromJson(spy.at(i).last().toByteArray(), &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qWarning() << "JSON parser error" << error.errorString();
|
||||
qWarning() << "JSON parser error" << error.errorString() << spy.at(i).last().toByteArray();
|
||||
return QVariant();
|
||||
}
|
||||
QVariantMap response = jsonDoc.toVariant().toMap();
|
||||
|
||||
@ -42,12 +42,12 @@ MockTcpServer::~MockTcpServer()
|
||||
s_allServers.removeAll(this);
|
||||
}
|
||||
|
||||
void MockTcpServer::sendData(const QUuid &clientId, const QVariantMap &data)
|
||||
void MockTcpServer::sendData(const QUuid &clientId, const QByteArray &data)
|
||||
{
|
||||
emit outgoingData(clientId, QJsonDocument::fromVariant(data).toJson());
|
||||
emit outgoingData(clientId, data);
|
||||
}
|
||||
|
||||
void MockTcpServer::sendData(const QList<QUuid> &clients, const QVariantMap &data)
|
||||
void MockTcpServer::sendData(const QList<QUuid> &clients, const QByteArray &data)
|
||||
{
|
||||
foreach (const QUuid &clientId, clients) {
|
||||
sendData(clientId, data);
|
||||
@ -64,26 +64,6 @@ void MockTcpServer::injectData(const QUuid &clientId, const QByteArray &data)
|
||||
emit dataAvailable(clientId, data);
|
||||
}
|
||||
|
||||
void MockTcpServer::sendResponse(const QUuid &clientId, int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
QVariantMap response;
|
||||
response.insert("id", commandId);
|
||||
response.insert("status", "success");
|
||||
response.insert("params", params);
|
||||
|
||||
sendData(clientId, response);
|
||||
}
|
||||
|
||||
void MockTcpServer::sendErrorResponse(const QUuid &clientId, int commandId, const QString &error)
|
||||
{
|
||||
QVariantMap errorResponse;
|
||||
errorResponse.insert("id", commandId);
|
||||
errorResponse.insert("status", "error");
|
||||
errorResponse.insert("error", error);
|
||||
|
||||
sendData(clientId, errorResponse);
|
||||
}
|
||||
|
||||
bool MockTcpServer::reconfigureServer(const QHostAddress &address, const uint &port)
|
||||
{
|
||||
Q_UNUSED(address)
|
||||
|
||||
@ -38,8 +38,8 @@ public:
|
||||
explicit MockTcpServer(QObject *parent = 0);
|
||||
~MockTcpServer();
|
||||
|
||||
void sendData(const QUuid &clientId, const QVariantMap &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QVariantMap &data) override;
|
||||
void sendData(const QUuid &clientId, const QByteArray &data) override;
|
||||
void sendData(const QList<QUuid> &clients, const QByteArray &data) override;
|
||||
|
||||
/************** Used for testing **************************/
|
||||
static QList<MockTcpServer*> servers();
|
||||
@ -48,10 +48,6 @@ signals:
|
||||
void outgoingData(const QUuid &clientId, const QByteArray &data);
|
||||
/************** Used for testing **************************/
|
||||
|
||||
public:
|
||||
void sendResponse(const QUuid &clientId, int commandId, const QVariantMap ¶ms = QVariantMap());
|
||||
void sendErrorResponse(const QUuid &clientId, int commandId, const QString &error);
|
||||
|
||||
public slots:
|
||||
bool reconfigureServer(const QHostAddress &address, const uint &port);
|
||||
bool startServer() override;
|
||||
|
||||
Reference in New Issue
Block a user