diff --git a/libnymea-app/configuration/nymeaconfiguration.cpp b/libnymea-app/configuration/nymeaconfiguration.cpp index 097287d1..0122c35e 100644 --- a/libnymea-app/configuration/nymeaconfiguration.cpp +++ b/libnymea-app/configuration/nymeaconfiguration.cpp @@ -49,6 +49,7 @@ NymeaConfiguration::NymeaConfiguration(JsonRpcClient *client, QObject *parent): m_tcpServerConfigurations(new ServerConfigurations(this)), m_webSocketServerConfigurations(new ServerConfigurations(this)), m_webServerConfigurations(new WebServerConfigurations(this)), + m_tunnelProxyServerConfigurations(new TunnelProxyServerConfigurations(this)), m_mqttServerConfigurations(new ServerConfigurations(this)), m_mqttPolicies(new MqttPolicies(this)) { @@ -123,6 +124,11 @@ WebServerConfigurations *NymeaConfiguration::webServerConfigurations() const return m_webServerConfigurations; } +TunnelProxyServerConfigurations *NymeaConfiguration::tunnelProxyServerConfigurations() const +{ + return m_tunnelProxyServerConfigurations; +} + ServerConfigurations *NymeaConfiguration::mqttServerConfigurations() const { return m_mqttServerConfigurations; @@ -135,12 +141,12 @@ MqttPolicies *NymeaConfiguration::mqttPolicies() const ServerConfiguration *NymeaConfiguration::createServerConfiguration(const QString &address, int port, bool authEnabled, bool sslEnabled) { - return new ServerConfiguration(QUuid::createUuid().toString(), QHostAddress(address), port, authEnabled, sslEnabled); + return new ServerConfiguration(QUuid::createUuid().toString(), address, port, authEnabled, sslEnabled); } WebServerConfiguration *NymeaConfiguration::createWebServerConfiguration(const QString &address, int port, bool authEnabled, bool sslEnabled, const QString &publicFolder) { - auto ret = new WebServerConfiguration(QUuid::createUuid().toString(), QHostAddress(address), port, authEnabled, sslEnabled); + auto ret = new WebServerConfiguration(QUuid::createUuid().toString(), address, port, authEnabled, sslEnabled); ret->setPublicFolder(publicFolder); return ret; } @@ -190,6 +196,20 @@ void NymeaConfiguration::setWebServerConfiguration(WebServerConfiguration *confi m_client->sendCommand("Configuration.SetWebServerConfiguration", params, this, "setWebConfigReply"); } +void NymeaConfiguration::setTunnelProxyServerConfiguration(TunnelProxyServerConfiguration *configuration) +{ + QVariantMap params; + QVariantMap configurationMap; + configurationMap.insert("id", configuration->id()); + configurationMap.insert("address", configuration->address()); + configurationMap.insert("port", configuration->port()); + configurationMap.insert("authenticationEnabled", configuration->authenticationEnabled()); + configurationMap.insert("sslEnabled", configuration->sslEnabled()); + configurationMap.insert("ignoreSslErrors", configuration->ignoreSslErrors()); + params.insert("configuration", configurationMap); + m_client->sendCommand("Configuration.SetTunnelProxyServerConfiguration", params, this, "setTunnelProxyServerConfigReply"); +} + void NymeaConfiguration::setMqttServerConfiguration(ServerConfiguration *configuration) { QVariantMap params; @@ -224,6 +244,13 @@ void NymeaConfiguration::deleteWebServerConfiguration(const QString &id) m_client->sendCommand("Configuration.DeleteWebServerConfiguration", params, this, "deleteWebConfigReply"); } +void NymeaConfiguration::deleteTunnelProxyServerConfiguration(const QString &id) +{ + QVariantMap params; + params.insert("id", id); + m_client->sendCommand("Configuration.DeleteTunnelProxyServerConfiguration", params, this, "deleteTunnelProxyServerConfigReply"); +} + void NymeaConfiguration::deleteMqttServerConfiguration(const QString &id) { QVariantMap params; @@ -268,23 +295,29 @@ void NymeaConfiguration::getConfigurationsResponse(int commandId, const QVariant foreach (const QVariant &tcpServerVariant, params.value("tcpServerConfigurations").toList()) { // qDebug() << "tcp server config:" << tcpServerVariant; QVariantMap tcpConfigMap = tcpServerVariant.toMap(); - ServerConfiguration *config = new ServerConfiguration(tcpConfigMap.value("id").toString(), QHostAddress(tcpConfigMap.value("address").toString()), tcpConfigMap.value("port").toInt(), tcpConfigMap.value("authenticationEnabled").toBool(), tcpConfigMap.value("sslEnabled").toBool()); + ServerConfiguration *config = new ServerConfiguration(tcpConfigMap.value("id").toString(), tcpConfigMap.value("address").toString(), tcpConfigMap.value("port").toInt(), tcpConfigMap.value("authenticationEnabled").toBool(), tcpConfigMap.value("sslEnabled").toBool()); m_tcpServerConfigurations->addConfiguration(config); } webSocketServerConfigurations()->clear(); foreach (const QVariant &websocketServerVariant, params.value("webSocketServerConfigurations").toList()) { QVariantMap websocketConfigMap = websocketServerVariant.toMap(); - ServerConfiguration *config = new ServerConfiguration(websocketConfigMap.value("id").toString(), QHostAddress(websocketConfigMap.value("address").toString()), websocketConfigMap.value("port").toInt(), websocketConfigMap.value("authenticationEnabled").toBool(), websocketConfigMap.value("sslEnabled").toBool()); + ServerConfiguration *config = new ServerConfiguration(websocketConfigMap.value("id").toString(), websocketConfigMap.value("address").toString(), websocketConfigMap.value("port").toInt(), websocketConfigMap.value("authenticationEnabled").toBool(), websocketConfigMap.value("sslEnabled").toBool()); m_webSocketServerConfigurations->addConfiguration(config); } webServerConfigurations()->clear(); foreach (const QVariant &webServerVariant, params.value("webServerConfigurations").toList()) { QVariantMap webServerConfigMap = webServerVariant.toMap(); - WebServerConfiguration* config = new WebServerConfiguration(webServerConfigMap.value("id").toString(), QHostAddress(webServerConfigMap.value("address").toString()), webServerConfigMap.value("port").toInt(), webServerConfigMap.value("authenticationEnabled").toBool(), webServerConfigMap.value("sslEnabled").toBool()); + WebServerConfiguration* config = new WebServerConfiguration(webServerConfigMap.value("id").toString(), webServerConfigMap.value("address").toString(), webServerConfigMap.value("port").toInt(), webServerConfigMap.value("authenticationEnabled").toBool(), webServerConfigMap.value("sslEnabled").toBool()); config->setPublicFolder(webServerConfigMap.value("publicFolder").toString()); m_webServerConfigurations->addConfiguration(config); } + + foreach (const QVariant &tunnelProxyServerVariant, params.value("tunnelProxyServerConfigurations").toList()) { + QVariantMap tunnelProxyServerConfigMap = tunnelProxyServerVariant.toMap(); + 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); + } } void NymeaConfiguration::setServerNameResponse(int commandId, const QVariantMap ¶ms) @@ -342,13 +375,23 @@ void NymeaConfiguration::deleteWebSocketConfigReply(int commandId, const QVarian qDebug() << "Delete web socket server config reply" << commandId << params; } +void NymeaConfiguration::setTunnelProxyServerConfigReply(int commandId, const QVariantMap ¶ms) +{ + qDebug() << "Set tunnel proxy server config reply" << commandId << params; +} + +void NymeaConfiguration::deleteTunnelProxyServerConfigReply(int commandId, const QVariantMap ¶ms) +{ + qDebug() << "Delete tunnel proxy server config reply" << commandId << params; +} + void NymeaConfiguration::getMqttServerConfigsReply(int commandId, const QVariantMap ¶ms) { Q_UNUSED(commandId) m_mqttServerConfigurations->clear(); foreach (const QVariant &mqttServerVariant, params.value("mqttServerConfigurations").toList()) { QVariantMap mqttConfigMap = mqttServerVariant.toMap(); - ServerConfiguration *config = new ServerConfiguration(mqttConfigMap.value("id").toString(), QHostAddress(mqttConfigMap.value("address").toString()), mqttConfigMap.value("port").toInt(), mqttConfigMap.value("authenticationEnabled").toBool(), mqttConfigMap.value("sslEnabled").toBool()); + ServerConfiguration *config = new ServerConfiguration(mqttConfigMap.value("id").toString(), mqttConfigMap.value("address").toString(), mqttConfigMap.value("port").toInt(), mqttConfigMap.value("authenticationEnabled").toBool(), mqttConfigMap.value("sslEnabled").toBool()); m_mqttServerConfigurations->addConfiguration(config); } } diff --git a/libnymea-app/configuration/nymeaconfiguration.h b/libnymea-app/configuration/nymeaconfiguration.h index 9f752d03..9a6ca1c2 100644 --- a/libnymea-app/configuration/nymeaconfiguration.h +++ b/libnymea-app/configuration/nymeaconfiguration.h @@ -38,6 +38,8 @@ class ServerConfiguration; class ServerConfigurations; class WebServerConfiguration; class WebServerConfigurations; +class TunnelProxyServerConfiguration; +class TunnelProxyServerConfigurations; class MqttPolicy; class MqttPolicies; @@ -53,6 +55,7 @@ class NymeaConfiguration : public QObject Q_PROPERTY(ServerConfigurations* tcpServerConfigurations READ tcpServerConfigurations CONSTANT) Q_PROPERTY(ServerConfigurations* webSocketServerConfigurations READ webSocketServerConfigurations CONSTANT) Q_PROPERTY(WebServerConfigurations* webServerConfigurations READ webServerConfigurations CONSTANT) + Q_PROPERTY(TunnelProxyServerConfigurations* tunnelProxyServerConfigurations READ tunnelProxyServerConfigurations CONSTANT) Q_PROPERTY(ServerConfigurations* mqttServerConfigurations READ mqttServerConfigurations CONSTANT) Q_PROPERTY(MqttPolicies* mqttPolicies READ mqttPolicies CONSTANT) @@ -80,6 +83,7 @@ public: ServerConfigurations *tcpServerConfigurations() const; ServerConfigurations *webSocketServerConfigurations() const; WebServerConfigurations *webServerConfigurations() const; + TunnelProxyServerConfigurations *tunnelProxyServerConfigurations() const; ServerConfigurations *mqttServerConfigurations() const; MqttPolicies *mqttPolicies() const; @@ -90,11 +94,13 @@ public: Q_INVOKABLE void setTcpServerConfiguration(ServerConfiguration *configuration); Q_INVOKABLE void setWebSocketServerConfiguration(ServerConfiguration *configuration); Q_INVOKABLE void setWebServerConfiguration(WebServerConfiguration *configuration); + Q_INVOKABLE void setTunnelProxyServerConfiguration(TunnelProxyServerConfiguration *configuration); Q_INVOKABLE void setMqttServerConfiguration(ServerConfiguration *configuration); Q_INVOKABLE void deleteTcpServerConfiguration(const QString &id); Q_INVOKABLE void deleteWebSocketServerConfiguration(const QString &id); Q_INVOKABLE void deleteWebServerConfiguration(const QString &id); + Q_INVOKABLE void deleteTunnelProxyServerConfiguration(const QString &id); Q_INVOKABLE void deleteMqttServerConfiguration(const QString &id); Q_INVOKABLE void updateMqttPolicy(MqttPolicy* policy); @@ -112,6 +118,8 @@ private: Q_INVOKABLE void deleteTcpConfigReply(int commandId, const QVariantMap ¶ms); Q_INVOKABLE void setWebSocketConfigReply(int commandId, const QVariantMap ¶ms); Q_INVOKABLE void deleteWebSocketConfigReply(int commandId, const QVariantMap ¶ms); + Q_INVOKABLE void setTunnelProxyServerConfigReply(int commandId, const QVariantMap ¶ms); + Q_INVOKABLE void deleteTunnelProxyServerConfigReply(int commandId, const QVariantMap ¶ms); Q_INVOKABLE void setWebConfigReply(int commandId, const QVariantMap ¶ms); Q_INVOKABLE void deleteWebConfigReply(int commandId, const QVariantMap ¶ms); Q_INVOKABLE void getMqttServerConfigsReply(int commandId, const QVariantMap ¶ms); @@ -138,6 +146,7 @@ private: ServerConfigurations *m_tcpServerConfigurations = nullptr; ServerConfigurations *m_webSocketServerConfigurations = nullptr; WebServerConfigurations* m_webServerConfigurations = nullptr; + TunnelProxyServerConfigurations *m_tunnelProxyServerConfigurations = nullptr; ServerConfigurations *m_mqttServerConfigurations = nullptr; MqttPolicies *m_mqttPolicies = nullptr; diff --git a/libnymea-app/configuration/serverconfiguration.cpp b/libnymea-app/configuration/serverconfiguration.cpp index aac5e054..a12c2199 100644 --- a/libnymea-app/configuration/serverconfiguration.cpp +++ b/libnymea-app/configuration/serverconfiguration.cpp @@ -30,7 +30,7 @@ #include "serverconfiguration.h" -ServerConfiguration::ServerConfiguration(const QString &id, const QHostAddress &address, int port, bool authEnabled, bool sslEnabled, QObject *parent): +ServerConfiguration::ServerConfiguration(const QString &id, const QString &address, int port, bool authEnabled, bool sslEnabled, QObject *parent): QObject(parent), m_id(id), m_hostAddress(address), @@ -48,13 +48,13 @@ QString ServerConfiguration::id() const QString ServerConfiguration::address() const { - return m_hostAddress.toString(); + return m_hostAddress; } void ServerConfiguration::setAddress(const QString &address) { - if (m_hostAddress != QHostAddress(address)) { - m_hostAddress = QHostAddress(address); + if (m_hostAddress != address) { + m_hostAddress = address; emit addressChanged(); } } @@ -119,7 +119,26 @@ void WebServerConfiguration::setPublicFolder(const QString &publicFolder) ServerConfiguration *WebServerConfiguration::clone() const { - WebServerConfiguration *ret = new WebServerConfiguration(id(), QHostAddress(address()), port(), authenticationEnabled(), sslEnabled()); + WebServerConfiguration *ret = new WebServerConfiguration(id(), address(), port(), authenticationEnabled(), sslEnabled()); ret->setPublicFolder(m_publicFolder); return ret; } + +bool TunnelProxyServerConfiguration::ignoreSslErrors() const +{ + return m_ignoreSslErrors; +} + +void TunnelProxyServerConfiguration::setIgnoreSslErrors(bool ignoreSslErrors) +{ + if (m_ignoreSslErrors != ignoreSslErrors) { + m_ignoreSslErrors = ignoreSslErrors; + emit ignoreSslErrorsChanged(); + } +} + +ServerConfiguration *TunnelProxyServerConfiguration::clone() const +{ + TunnelProxyServerConfiguration *ret = new TunnelProxyServerConfiguration(id(), address(), port(), authenticationEnabled(), ignoreSslErrors()); + return ret; +} diff --git a/libnymea-app/configuration/serverconfiguration.h b/libnymea-app/configuration/serverconfiguration.h index e8c5a508..3ea194df 100644 --- a/libnymea-app/configuration/serverconfiguration.h +++ b/libnymea-app/configuration/serverconfiguration.h @@ -45,7 +45,7 @@ class ServerConfiguration : public QObject Q_PROPERTY(bool sslEnabled READ sslEnabled WRITE setSslEnabled NOTIFY sslEnabledChanged) public: - explicit ServerConfiguration(const QString &id, const QHostAddress &address = QHostAddress(), int port = 0, bool authEnabled = false, bool sslEnabled = false, QObject *parent = nullptr); + explicit ServerConfiguration(const QString &id, const QString &address = QString(), int port = 0, bool authEnabled = false, bool sslEnabled = false, QObject *parent = nullptr); QString id() const; @@ -71,7 +71,7 @@ signals: private: QString m_id; - QHostAddress m_hostAddress; + QString m_hostAddress; int m_port; bool m_authEnabled; bool m_sslEnabled; @@ -82,7 +82,7 @@ class WebServerConfiguration: public ServerConfiguration Q_OBJECT Q_PROPERTY(QString publicFolder READ publicFolder WRITE setPublicFolder NOTIFY publicFolderChanged) public: - explicit WebServerConfiguration(const QString &id, const QHostAddress &address = QHostAddress(), int port = 0, bool authEnabled = false, bool sslEnabled = false, QObject *parent = nullptr) + explicit WebServerConfiguration(const QString &id, const QString &address = QString(), int port = 0, bool authEnabled = false, bool sslEnabled = false, QObject *parent = nullptr) : ServerConfiguration(id, address, port, authEnabled, sslEnabled, parent) {} QString publicFolder() const; @@ -97,4 +97,25 @@ private: QString m_publicFolder; }; +class TunnelProxyServerConfiguration: public ServerConfiguration +{ + Q_OBJECT + Q_PROPERTY(bool ignoreSslErrors READ ignoreSslErrors WRITE setIgnoreSslErrors NOTIFY ignoreSslErrorsChanged) +public: + explicit TunnelProxyServerConfiguration(const QString &id, const QString &address = QString(), int port = 0, bool authenticationEnabled = false, bool sslEnabled = false, bool ignoreSslErrors = false, QObject *parent = nullptr) + : ServerConfiguration(id, address, port, authenticationEnabled, sslEnabled, parent), + m_ignoreSslErrors(ignoreSslErrors) {} + + bool ignoreSslErrors() const; + void setIgnoreSslErrors(bool ignoreSslErrors); + + Q_INVOKABLE ServerConfiguration* clone() const override; + +signals: + void ignoreSslErrorsChanged(); + +private: + bool m_ignoreSslErrors = false; +}; + #endif // SERVERCONFIGURATION_H diff --git a/libnymea-app/configuration/serverconfigurations.h b/libnymea-app/configuration/serverconfigurations.h index 634d27ea..90b3931e 100644 --- a/libnymea-app/configuration/serverconfigurations.h +++ b/libnymea-app/configuration/serverconfigurations.h @@ -84,4 +84,15 @@ public: } }; +class TunnelProxyServerConfigurations: public ServerConfigurations +{ + Q_OBJECT +public: + TunnelProxyServerConfigurations(QObject *parent = nullptr): ServerConfigurations(parent) {} + + Q_INVOKABLE TunnelProxyServerConfiguration* getTunnelProxyServerConfiguration(int index) const { + return dynamic_cast(m_list.at(index)); + } +}; + #endif // SERVERCONFIGURATIONS_H diff --git a/libnymea-app/libnymea-app-core.h b/libnymea-app/libnymea-app-core.h index 0c9afc61..7ca31376 100644 --- a/libnymea-app/libnymea-app-core.h +++ b/libnymea-app/libnymea-app-core.h @@ -256,6 +256,8 @@ void registerQmlTypes() { qmlRegisterUncreatableType(uri, 1, 0, "ServerConfigurations", "Get it from NymeaConfiguration"); qmlRegisterUncreatableType(uri, 1, 0, "WebServerConfiguration", "Get it from NymeaConfiguration"); qmlRegisterUncreatableType(uri, 1, 0, "WebServerConfigurations", "Get it from NymeaConfiguration"); + qmlRegisterUncreatableType(uri, 1, 0, "TunnelProxyServerConfiguration", "Get it from NymeaConfiguration"); + qmlRegisterUncreatableType(uri, 1, 0, "TunnelProxyServerConfigurations", "Get it from NymeaConfiguration"); qmlRegisterUncreatableType(uri, 1, 0, "MqttPolicy", "Get it from NymeaConfiguration"); qmlRegisterUncreatableType(uri, 1, 0, "MqttPolicies", "Get it from NymeaConfiguration"); diff --git a/nymea-app/ui/system/ConnectionInterfacesPage.qml b/nymea-app/ui/system/ConnectionInterfacesPage.qml index 90362107..6d7e8101 100644 --- a/nymea-app/ui/system/ConnectionInterfacesPage.qml +++ b/nymea-app/ui/system/ConnectionInterfacesPage.qml @@ -136,4 +136,53 @@ SettingsPageBase { popup.open() } } + SettingsPageSectionHeader { + text: qsTr("Remote connection server interfaces") + } + + Repeater { + model: engine.nymeaConfiguration.tunnelProxyServerConfigurations + delegate: ConnectionInterfaceDelegate { + Layout.fillWidth: true + text: qsTr("Server: %1").arg(model.address) + iconColor: inUse ? Style.accentColor : Style.iconColor + readonly property bool inUse: (engine.jsonRpcClient.currentConnection.hostAddress === model.address || model.address === "0.0.0.0") + && engine.jsonRpcClient.currentConnection.port === model.port + canDelete: !inUse + onClicked: { + var component = Qt.createComponent(Qt.resolvedUrl("ServerConfigurationDialog.qml")); + var popup = component.createObject(root, { serverConfiguration: engine.nymeaConfiguration.tunnelProxyServerConfigurations.get(index).clone() }); + popup.accepted.connect(function() { + print("configuring:", popup.serverConfiguration.port) + engine.nymeaConfiguration.setTunnelProxyServerConfiguration(popup.serverConfiguration) + popup.serverConfiguration.destroy(); + }) + popup.rejected.connect(function() { + popup.serverConfiguration.destroy(); + }) + popup.open() + } + onDeleteClicked: { + engine.nymeaConfiguration.deleteTunnelProxyServerConfiguration(model.id) + } + } + } + Button { + Layout.fillWidth: true + 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 popup = component.createObject(root, { serverConfiguration: config }); + popup.accepted.connect(function() { + engine.nymeaConfiguration.setWebSocketServerConfiguration(popup.serverConfiguration) + popup.serverConfiguration.destroy(); + }) + popup.rejected.connect(function() { + popup.serverConfiguration.destroy(); + }) + popup.open() + } + } }