Intermediate commit

This commit is contained in:
Michael Zanetti 2022-01-21 16:17:00 +01:00
parent 72f6f185b8
commit 8f015aeee3
11 changed files with 207 additions and 17 deletions

View File

@ -56,11 +56,20 @@ NymeaConfiguration::NymeaConfiguration(JsonRpcClient *client, QObject *parent):
client->registerNotificationHandler(this, "Configuration", "notificationReceived");
}
bool NymeaConfiguration::fetchingData() const
{
return m_fetchingData;
}
void NymeaConfiguration::init()
{
m_fetchingData = true;
emit fetchingDataChanged();
m_tcpServerConfigurations->clear();
m_webSocketServerConfigurations->clear();
m_mqttServerConfigurations->clear();
m_tunnelProxyServerConfigurations->clear();
m_client->sendCommand("Configuration.GetConfigurations", this, "getConfigurationsResponse");
m_client->sendCommand("Configuration.GetMqttServerConfigurations", this, "getMqttServerConfigsReply");
m_client->sendCommand("Configuration.GetMqttPolicies", this, "getMqttPoliciesReply");
@ -151,6 +160,11 @@ WebServerConfiguration *NymeaConfiguration::createWebServerConfiguration(const Q
return ret;
}
TunnelProxyServerConfiguration *NymeaConfiguration::createTunnelProxyServerConfiguration(const QString &address, int port, bool authEnabled, bool sslEnabled, bool ignoreSslErrors)
{
return new TunnelProxyServerConfiguration(QUuid::createUuid().toString(), address, port, authEnabled, sslEnabled, ignoreSslErrors);
}
MqttPolicy *NymeaConfiguration::createMqttPolicy() const
{
return new MqttPolicy(QString(), QString(), QString(), {"#"}, {"#"});
@ -318,6 +332,9 @@ void NymeaConfiguration::getConfigurationsResponse(int commandId, const QVariant
TunnelProxyServerConfiguration *config = new TunnelProxyServerConfiguration(tunnelProxyServerConfigMap.value("id").toString(), tunnelProxyServerConfigMap.value("address").toString(), tunnelProxyServerConfigMap.value("port").toInt(), tunnelProxyServerConfigMap.value("authenticationEnabled").toBool(), tunnelProxyServerConfigMap.value("sslEnabled").toBool(), tunnelProxyServerConfigMap.value("ignoreSslErrors").toBool());
m_tunnelProxyServerConfigurations->addConfiguration(config);
}
m_fetchingData = false;
emit fetchingDataChanged();
}
void NymeaConfiguration::setServerNameResponse(int commandId, const QVariantMap &params)
@ -436,6 +453,7 @@ void NymeaConfiguration::deleteMqttPolicyReply(int commandId, const QVariantMap
void NymeaConfiguration::notificationReceived(const QVariantMap &notification)
{
QString notif = notification.value("notification").toString();
qWarning() << "Config notification received" << notif;
if (notif == "Configuration.BasicConfigurationChanged") {
QVariantMap params = notification.value("params").toMap().value("basicConfiguration").toMap();
m_debugServerEnabled = params.value("debugServerEnabled").toBool();
@ -465,6 +483,10 @@ void NymeaConfiguration::notificationReceived(const QVariantMap &notification)
configModel = m_webSocketServerConfigurations;
params = notification.value("params").toMap().value("webSocketServerConfiguration").toMap();
}
if (notif == "Configuration.TunnelProxyServerConfigurationChanged") {
configModel = m_tunnelProxyServerConfigurations;
params = notification.value("params").toMap().value("tunnelProxyServerConfiguration").toMap();
}
if (notif == "Configuration.WebServerConfigurationChanged") {
configModel = m_webServerConfigurations;
params = notification.value("params").toMap().value("webServerConfiguration").toMap();
@ -487,6 +509,8 @@ void NymeaConfiguration::notificationReceived(const QVariantMap &notification)
if (!serverConfig) {
if (notif == "Configuration.WebServerConfigurationChanged") {
serverConfig = new WebServerConfiguration(params.value("id").toString());
} else if (notif == "Configuration.TunnelProxyServerConfigurationChanged") {
serverConfig = new TunnelProxyServerConfiguration(params.value("id").toString());
} else {
serverConfig = new ServerConfiguration(params.value("id").toString());
}
@ -510,6 +534,10 @@ void NymeaConfiguration::notificationReceived(const QVariantMap &notification)
m_webSocketServerConfigurations->removeConfiguration(notification.value("params").toMap().value("id").toString());
return;
}
if (notif == "Configuration.TunnelProxyServerConfigurationRemoved") {
m_tunnelProxyServerConfigurations->removeConfiguration(notification.value("params").toMap().value("id").toString());
return;
}
if (notif == "Configuration.WebServerConfigurationRemoved") {
m_webServerConfigurations->removeConfiguration(notification.value("params").toMap().value("id").toString());
return;

View File

@ -47,6 +47,8 @@ class NymeaConfiguration : public QObject
{
Q_OBJECT
Q_PROPERTY(bool fetchingData READ fetchingData NOTIFY fetchingDataChanged)
Q_PROPERTY(QString serverName READ serverName WRITE setServerName NOTIFY serverNameChanged)
Q_PROPERTY(bool cloudEnabled READ cloudEnabled WRITE setCloudEnabled NOTIFY cloudEnabledChanged)
@ -63,6 +65,8 @@ class NymeaConfiguration : public QObject
public:
explicit NymeaConfiguration(JsonRpcClient* client, QObject *parent = nullptr);
bool fetchingData() const;
QString serverName() const;
void setServerName(const QString &serverName);
@ -89,6 +93,7 @@ public:
Q_INVOKABLE ServerConfiguration* createServerConfiguration(const QString &address = "0.0.0.0", int port = 0, bool authEnabled = false, bool sslEnabled = false);
Q_INVOKABLE WebServerConfiguration* createWebServerConfiguration(const QString &address = "0.0.0.0", int port = 0, bool authEnabled = false, bool sslEnabled = false, const QString &publicFolder = QString());
Q_INVOKABLE TunnelProxyServerConfiguration* createTunnelProxyServerConfiguration(const QString &address, int port, bool authEnabled = true, bool sslEnabled = true, bool ignoreSslErrors = false);
Q_INVOKABLE MqttPolicy* createMqttPolicy() const;
Q_INVOKABLE void setTcpServerConfiguration(ServerConfiguration *configuration);
@ -132,6 +137,7 @@ private:
Q_INVOKABLE void notificationReceived(const QVariantMap &notification);
signals:
void fetchingDataChanged();
void debugServerEnabledChanged();
void serverNameChanged();
void cloudEnabledChanged();
@ -139,6 +145,7 @@ signals:
private:
JsonRpcClient* m_client = nullptr;
bool m_fetchingData = false;
bool m_debugServerEnabled = false;
QString m_serverName;
bool m_cloudEnabled = false;

View File

@ -152,7 +152,6 @@ void NymeaDiscovery::cacheHost(NymeaHost *host)
QList<Connection*> connections;
Connection *remoteConnection = host->connections()->bestMatch(Connection::BearerTypeCloud);
if (remoteConnection) {
qCritical() << "*********** caching" << remoteConnection->url();
connections.append(remoteConnection);
}
Connection *loopbackConnection = host->connections()->bestMatch(Connection::BearerTypeLoopback);

View File

@ -247,6 +247,12 @@ Connection *Connections::bestMatch(Connection::BearerTypes bearerTypes) const
return best;
}
void Connections::addConnection(const QUrl &url, Connection::BearerType bearerType, bool secure, const QString &displayName)
{
Connection *connection = new Connection(url, bearerType, secure, displayName);
addConnection(connection);
}
QHash<int, QByteArray> Connections::roleNames() const
{
QHash<int, QByteArray> roles;
@ -265,7 +271,7 @@ Connection::Connection(const QUrl &url, Connection::BearerType bearerType, bool
m_secure(secure),
m_displayName(displayName)
{
qRegisterMetaType<Connection::BearerType>("Connection.BearerType");
}
Connection::~Connection()

View File

@ -109,14 +109,16 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
void addConnection(Connection *connection);
void removeConnection(Connection *connection);
void removeConnection(int index);
Q_INVOKABLE Connection* find(const QUrl &url) const;
Q_INVOKABLE Connection* get(int index) const;
Q_INVOKABLE Connection* bestMatch(Connection::BearerTypes bearerTypes = Connection::BearerTypeAll) const;
void addConnection(Connection *connection);
Q_INVOKABLE void addConnection(const QUrl &url, Connection::BearerType bearerType, bool secure, const QString &displayName);
Q_INVOKABLE void removeConnection(Connection *connection);
Q_INVOKABLE void removeConnection(int index);
signals:
void countChanged();
void connectionAdded(Connection *connection);

View File

@ -31,6 +31,7 @@
#include "tunnelproxytransport.h"
#include <QCoreApplication>
#include <QUrlQuery>
using namespace remoteproxyclient;
@ -58,14 +59,15 @@ TunnelProxyTransport::TunnelProxyTransport(QObject *parent) :
bool TunnelProxyTransport::connect(const QUrl &url)
{
m_url = url;
QUrl serverUrl;
serverUrl.setScheme(url.scheme() == "tunnels" ? "ssl" : "tcp");
serverUrl.setHost(url.host());
serverUrl.setPort(url.port());
QUuid serverUuid = QUrlQuery(url).queryItemValue("uuid");
QUrl serverUrl = QUrl("ssl://dev-remoteproxy.nymea.io:2213");
QUuid serverUuid = url.host();
qCritical() << "Calling connect";
qCritical() << "Calling connect on" << serverUrl << serverUuid;
return m_remoteConnection->connectServer(serverUrl, serverUuid);
}
@ -145,5 +147,5 @@ NymeaTransportInterface *TunnelProxyTransportFactory::createTransport(QObject *p
QStringList TunnelProxyTransportFactory::supportedSchemes() const
{
return { "tunnel" };
return { "tunnel", "tunnels" };
}

View File

@ -645,7 +645,7 @@ void JsonRpcClient::dataReceived(const QByteArray &data)
JsonRpcReply *reply = m_replies.take(commandId);
if (reply) {
reply->deleteLater();
qWarning() << QString("JsonRpc: got response for %1.%2: %3").arg(reply->nameSpace(), reply->method(), QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Indented))) << reply->callback() << reply->callback();
// qWarning() << QString("JsonRpc: got response for %1.%2: %3").arg(reply->nameSpace(), reply->method(), QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Indented))) << reply->callback() << reply->callback();
if (dataMap.value("status").toString() == "unauthorized") {
qWarning() << "Something's off with the token";

View File

@ -274,5 +274,6 @@
<file>ui/components/NymeaToolTip.qml</file>
<file>ui/components/SettingsTile.qml</file>
<file>ui/components/NymeaTextField.qml</file>
<file>ui/system/TunnelProxyServerConfigurationDialog.qml</file>
</qresource>
</RCC>

View File

@ -312,7 +312,6 @@ Item {
onConnectedChanged: {
print("json client connected changed", engine.jsonRpcClient.connected, engine.jsonRpcClient.serverUuid)
if (engine.jsonRpcClient.connected) {
engine.jsonRpcClient.currentHost.addTunnelConnection();
nymeaDiscovery.cacheHost(engine.jsonRpcClient.currentHost)
configuredHost.uuid = engine.jsonRpcClient.serverUuid
// tabSettings.lastConnectedHost = engine.jsonRpcClient.serverUuid
@ -345,6 +344,38 @@ Item {
}
}
Connections {
target: engine.nymeaConfiguration
onFetchingDataChanged: {
if (!engine.nymeaConfiguration.fetchingData) {
syncRemoteConnection()
}
}
}
Connections {
target: engien.nymeaConfiguration.tunnelProxyServerConfigurations
onCountChanged: syncRemoteConnection();
}
function syncRemoteConnection() {
for (var i = 0; i < engine.jsonRpcClient.currentHost.connections.count; i++) {
var connection = engine.jsonRpcClient.currentHost.connections.get(i)
if (connection.url.toString().startsWith("tunnel")) {
engine.jsonRpcClient.currentHost.connections.removeConnection(i--);
}
}
for (var i = 0; i < engine.nymeaConfiguration.tunnelProxyServerConfigurations.count; i++) {
var tunnelProxyConfig = engine.nymeaConfiguration.tunnelProxyServerConfigurations.get(i);
var url = tunnelProxyConfig.sslEnabled ? "tunnels://" : "tunnel://";
url += tunnelProxyConfig.address
url += ":" + tunnelProxyConfig.port
url += "?uuid=" + engine.jsonRpcClient.currentHost.uuid
engine.jsonRpcClient.currentHost.connections.addConnection(url, Connection.BearerTypeCloud, tunnelProxyConfig.sslEnabled, "Remote proxy connection");
}
nymeaDiscovery.cacheHost(engine.jsonRpcClient.currentHost)
}
Connections {
target: Qt.application
enabled: engine.jsonRpcClient.connected && settings.returnToHome

View File

@ -150,7 +150,7 @@ SettingsPageBase {
&& engine.jsonRpcClient.currentConnection.port === model.port
canDelete: !inUse
onClicked: {
var component = Qt.createComponent(Qt.resolvedUrl("ServerConfigurationDialog.qml"));
var component = Qt.createComponent(Qt.resolvedUrl("TunnelProxyServerConfigurationDialog.qml"));
var popup = component.createObject(root, { serverConfiguration: engine.nymeaConfiguration.tunnelProxyServerConfigurations.get(index).clone() });
popup.accepted.connect(function() {
print("configuring:", popup.serverConfiguration.port)
@ -172,11 +172,11 @@ SettingsPageBase {
Layout.margins: app.margins
text: qsTr("Add")
onClicked: {
var config = engine.nymeaConfiguration.createTunnelProxyServerConfiguration("0.0.0.0", 4444 + engine.nymeaConfiguration.webSocketServerConfigurations.count, false, false);
var component = Qt.createComponent(Qt.resolvedUrl("ServerConfigurationDialog.qml"));
var config = engine.nymeaConfiguration.createTunnelProxyServerConfiguration("dev-remoteproxy.nymea.io", 2213, true, true, false);
var component = Qt.createComponent(Qt.resolvedUrl("TunnelProxyServerConfigurationDialog.qml"));
var popup = component.createObject(root, { serverConfiguration: config });
popup.accepted.connect(function() {
engine.nymeaConfiguration.setWebSocketServerConfiguration(popup.serverConfiguration)
engine.nymeaConfiguration.setTunnelProxyServerConfiguration(popup.serverConfiguration)
popup.serverConfiguration.destroy();
})
popup.rejected.connect(function() {

View File

@ -0,0 +1,114 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project 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
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
import QtQuick 2.9
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.1
import Nymea 1.0
Dialog {
id: root
title: qsTr("Proxy server configuration")
width: parent.width * .8
x: (parent.width - width) / 2
y: (parent.height - height) / 2
property ServerConfiguration serverConfiguration: null
standardButtons: Dialog.Ok | Dialog.Cancel
ColumnLayout {
anchors { left: parent.left; top: parent.top; right: parent.right }
RowLayout {
Label {
text: qsTr("Proxy server address:")
Layout.fillWidth: true
}
TextField {
id: addressTextField
Layout.fillWidth: true
text: root.serverConfiguration ? root.serverConfiguration.address : ""
onEditingFinished: root.serverConfiguration.address = text
}
}
RowLayout {
Label {
text: qsTr("Port:")
Layout.fillWidth: true
}
TextField {
inputMethodHints: Qt.ImhDigitsOnly
text: root.serverConfiguration ? root.serverConfiguration.port : 0
validator: IntValidator { bottom: 0; top: 65535 }
onEditingFinished: root.serverConfiguration.port = text
}
}
RowLayout {
Label {
Layout.fillWidth: true
text: qsTr("Require login")
}
CheckBox {
checkState: root.serverConfiguration && root.serverConfiguration.authenticationEnabled ? Qt.Checked : Qt.Unchecked
onClicked: root.serverConfiguration.authenticationEnabled = checked
}
}
Label {
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: qsTr("Not requiring a login for the remote connection will allow anyone on the internet to connect to your %1 system.").arg(Configuration.systemName)
color: Style.red
visible: root.serverConfiguration && !root.serverConfiguration.authenticationEnabled
}
RowLayout {
Label {
Layout.fillWidth: true
text: qsTr("SSL enabled")
}
CheckBox {
checkState: root.serverConfiguration && root.serverConfiguration.sslEnabled ? Qt.Checked : Qt.Unchecked
onClicked: root.serverConfiguration.sslEnabled = checked
}
}
RowLayout {
Label {
Layout.fillWidth: true
text: qsTr("Ignore SSL errors")
}
CheckBox {
checkState: root.serverConfiguration && root.serverConfiguration.ignoreSslErrors ? Qt.Checked : Qt.Unchecked
onClicked: root.serverConfiguration.ignoreSslErrors = checked
}
}
}
}