From 587d61ce551ebcc59c600cebb9f6803a80e2f8c6 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Mon, 3 Nov 2025 13:18:14 +0100 Subject: [PATCH] Implement backend access with SSO --- 3rdparty/QtZeroConf | 2 +- 3rdparty/qmsgpack | 2 +- evcharger-app/i18n/qml_de.ts | 2 +- evcharger-app/qml/OcppPage.qml | 5 + flotten-updater/CMakeLists.txt | 6 +- flotten-updater/deviceconnection.cpp | 209 ++++++++++---------- flotten-updater/deviceconnection.h | 16 +- flotten-updater/devicesmodel.cpp | 22 +-- flotten-updater/devicesmodel.h | 16 +- flotten-updater/flottenupdatersettings.cpp | 16 +- flotten-updater/flottenupdatersettings.h | 8 +- flotten-updater/importcertificatedialog.cpp | 157 --------------- flotten-updater/importcertificatedialog.h | 36 ---- flotten-updater/importcertificatedialog.ui | 184 ----------------- flotten-updater/importcredentialsdialog.cpp | 89 +++++++++ flotten-updater/importcredentialsdialog.h | 35 ++++ flotten-updater/importcredentialsdialog.ui | 114 +++++++++++ flotten-updater/main.cpp | 51 ++--- flotten-updater/mainwindow.cpp | 8 +- flotten-updater/mainwindow.h | 4 +- flotten-updater/requestdialog.cpp | 2 +- flotten-updater/requestdialog.h | 4 +- flotten-updater/requestmodel.cpp | 4 +- flotten-updater/requestmodel.h | 6 +- 24 files changed, 429 insertions(+), 569 deletions(-) delete mode 100644 flotten-updater/importcertificatedialog.cpp delete mode 100644 flotten-updater/importcertificatedialog.h delete mode 100644 flotten-updater/importcertificatedialog.ui create mode 100644 flotten-updater/importcredentialsdialog.cpp create mode 100644 flotten-updater/importcredentialsdialog.h create mode 100644 flotten-updater/importcredentialsdialog.ui diff --git a/3rdparty/QtZeroConf b/3rdparty/QtZeroConf index 2fbb52b..8f72314 160000 --- a/3rdparty/QtZeroConf +++ b/3rdparty/QtZeroConf @@ -1 +1 @@ -Subproject commit 2fbb52b70820a933ca954fdc3befaebc32072e3b +Subproject commit 8f723144071653ce35aa89eb41b376e5d7276217 diff --git a/3rdparty/qmsgpack b/3rdparty/qmsgpack index cd3fcec..05aa4b2 160000 --- a/3rdparty/qmsgpack +++ b/3rdparty/qmsgpack @@ -1 +1 @@ -Subproject commit cd3fcec745a4fe62e6da132588e39f149d3a9178 +Subproject commit 05aa4b2e0d50095e70663abcd6df5f0964b3e879 diff --git a/evcharger-app/i18n/qml_de.ts b/evcharger-app/i18n/qml_de.ts index 3f8820a..0eca4c5 100644 --- a/evcharger-app/i18n/qml_de.ts +++ b/evcharger-app/i18n/qml_de.ts @@ -1203,7 +1203,7 @@ - DevicesConnection + DeviceConnection diff --git a/evcharger-app/qml/OcppPage.qml b/evcharger-app/qml/OcppPage.qml index 4a06bc8..b22595b 100644 --- a/evcharger-app/qml/OcppPage.qml +++ b/evcharger-app/qml/OcppPage.qml @@ -160,6 +160,11 @@ NavigationPage { text: qsTr("Skip server cert verification") } + GeneralOnOffSwitch { + apiKey: "ocppt" + text: qsTr("Accept time from backend") + } + // TODO clientKey // TODO clientCert diff --git a/flotten-updater/CMakeLists.txt b/flotten-updater/CMakeLists.txt index 3547a2f..e0f7238 100644 --- a/flotten-updater/CMakeLists.txt +++ b/flotten-updater/CMakeLists.txt @@ -12,9 +12,9 @@ qt_add_executable(flotten-updater WIN32 MACOSX_BUNDLE devicesmodel.h flottenupdatersettings.cpp flottenupdatersettings.h - importcertificatedialog.cpp - importcertificatedialog.h - importcertificatedialog.ui + importcredentialsdialog.cpp + importcredentialsdialog.h + importcredentialsdialog.ui main.cpp mainwindow.cpp mainwindow.h diff --git a/flotten-updater/deviceconnection.cpp b/flotten-updater/deviceconnection.cpp index 1fd90e9..98e3ace 100644 --- a/flotten-updater/deviceconnection.cpp +++ b/flotten-updater/deviceconnection.cpp @@ -24,42 +24,44 @@ const constexpr QColor blue{150, 150, 255}; const constexpr QColor magenta{255, 150, 255}; } -DevicesConnection::DevicesConnection(const QSslKey &key, const QSslCertificate &cert, QString &&serial, QObject *parent) : +DeviceConnection::DeviceConnection(const QByteArray &username, const QByteArray &password, QString &&serial, QObject *parent) : QObject{parent}, m_serial(std::move(serial)), - m_key{key}, - m_cert{cert} + m_username{username}, + m_password{password} { init(); } -DevicesConnection::DevicesConnection(const QSslKey &key, const QSslCertificate &cert, const QString &serial, QObject *parent) : +DeviceConnection::DeviceConnection(const QByteArray &username, const QByteArray &password, const QString &serial, QObject *parent) : QObject{parent}, m_serial(serial), - m_key{key}, - m_cert{cert} + m_username{username}, + m_password{password} { init(); } -void DevicesConnection::start() +void DeviceConnection::start() { - const QUrl url{QString("wss://solalaweb.com/%0").arg(m_serial)}; - qDebug() << url; - m_websocket.open(url); + QNetworkRequest request{QString("wss://solalaweb.com/%0").arg(m_serial)}; + QString credentials = m_username + ':' + m_password; + QString base64 = credentials.toUtf8().toBase64(); + request.setRawHeader("Authorization", "Basic " + base64.toUtf8()); + m_websocket.open(request); } -void DevicesConnection::stop() +void DeviceConnection::stop() { m_websocket.close(); } -QString DevicesConnection::wsStatusText() const +QString DeviceConnection::wsStatusText() const { return QMetaEnum::fromType().valueToKey(m_websocket.state()); } -QBrush DevicesConnection::wsStatusBackground() const +QBrush DeviceConnection::wsStatusBackground() const { switch (m_websocket.state()) { @@ -72,7 +74,7 @@ QBrush DevicesConnection::wsStatusBackground() const return {}; } -QString DevicesConnection::statusText() const +QString DeviceConnection::statusText() const { switch (m_status) { @@ -84,7 +86,7 @@ QString DevicesConnection::statusText() const return QString::number(std::to_underlying(m_status)); } -QBrush DevicesConnection::statusBackground() const +QBrush DeviceConnection::statusBackground() const { switch (m_status) { @@ -95,7 +97,7 @@ QBrush DevicesConnection::statusBackground() const return {}; } -QString DevicesConnection::variantText() const +QString DeviceConnection::variantText() const { if (!m_fullStatus.contains("var")) return {}; @@ -103,7 +105,7 @@ QString DevicesConnection::variantText() const return m_fullStatus.value("var").toString(); } -QBrush DevicesConnection::variantBackground() const +QBrush DeviceConnection::variantBackground() const { if (!m_fullStatus.contains("var")) return {}; @@ -116,7 +118,7 @@ QBrush DevicesConnection::variantBackground() const return red; } -QString DevicesConnection::isGoText() const +QString DeviceConnection::isGoText() const { if (!m_fullStatus.contains("isgo")) return {}; @@ -124,7 +126,7 @@ QString DevicesConnection::isGoText() const return m_fullStatus.value("isgo").toBool() ? "yes" : "no"; } -QBrush DevicesConnection::isGoBackground() const +QBrush DeviceConnection::isGoBackground() const { if (!m_fullStatus.contains("isgo")) return {}; @@ -132,7 +134,7 @@ QBrush DevicesConnection::isGoBackground() const return m_fullStatus.value("isgo").toBool() ? blue : yellow; } -QString DevicesConnection::isAustralienText() const +QString DeviceConnection::isAustralienText() const { if (!m_fullStatus.contains("aus")) return {}; @@ -140,7 +142,7 @@ QString DevicesConnection::isAustralienText() const return m_fullStatus.value("aus").toBool() ? "yes" : "no"; } -QBrush DevicesConnection::isAustralienBackground() const +QBrush DeviceConnection::isAustralienBackground() const { if (!m_fullStatus.contains("aus")) return {}; @@ -148,7 +150,7 @@ QBrush DevicesConnection::isAustralienBackground() const return m_fullStatus.value("aus").toBool() ? yellow : blue; } -QString DevicesConnection::resetCardText() const +QString DeviceConnection::resetCardText() const { if (!m_fullStatus.contains("frci")) return {}; @@ -156,7 +158,7 @@ QString DevicesConnection::resetCardText() const return m_fullStatus.value("frci").toBool() ? "yes" : "no"; } -QBrush DevicesConnection::resetCardBackground() const +QBrush DeviceConnection::resetCardBackground() const { if (!m_fullStatus.contains("frci")) return {}; @@ -164,7 +166,7 @@ QBrush DevicesConnection::resetCardBackground() const return m_fullStatus.value("frci").toBool() ? green : red; } -QString DevicesConnection::connectedWifiText() const +QString DeviceConnection::connectedWifiText() const { if (!m_fullStatus.contains("ccw")) return {}; @@ -176,7 +178,7 @@ QString DevicesConnection::connectedWifiText() const return apd.value("ssid").toString(); } -QString DevicesConnection::projectText() const +QString DeviceConnection::projectText() const { if (!m_fullStatus.contains("apd")) return {}; @@ -188,7 +190,7 @@ QString DevicesConnection::projectText() const return apd.value("project_name").toString(); } -QString DevicesConnection::versionText() const +QString DeviceConnection::versionText() const { if (!m_fullStatus.contains("apd")) return {}; @@ -200,7 +202,7 @@ QString DevicesConnection::versionText() const return apd.value("version").toString(); } -QString DevicesConnection::idfVersionText() const +QString DeviceConnection::idfVersionText() const { if (!m_fullStatus.contains("apd")) return {}; @@ -212,7 +214,7 @@ QString DevicesConnection::idfVersionText() const return apd.value("idf_ver").toString(); } -QString DevicesConnection::updateText() const +QString DeviceConnection::updateText() const { if (!m_fullStatus.contains("ocs")) return {}; @@ -241,7 +243,7 @@ QString DevicesConnection::updateText() const return QString::number(ocs); } -QBrush DevicesConnection::updateBackground() const +QBrush DeviceConnection::updateBackground() const { if (!m_fullStatus.contains("ocs")) return {}; @@ -259,7 +261,7 @@ QBrush DevicesConnection::updateBackground() const return {}; } -std::optional DevicesConnection::uptime() const +std::optional DeviceConnection::uptime() const { if (!m_fullStatus.contains("rbt")) return {}; @@ -267,7 +269,7 @@ std::optional DevicesConnection::uptime() const return m_fullStatus.value("rbt").toULongLong(); } -QString DevicesConnection::uptimeText() const +QString DeviceConnection::uptimeText() const { if (!m_fullStatus.contains("rbt")) return {}; @@ -275,7 +277,7 @@ QString DevicesConnection::uptimeText() const return QString::number(m_fullStatus.value("rbt").toULongLong()); } -QString DevicesConnection::currentPartition() const +QString DeviceConnection::currentPartition() const { if (!m_fullStatus.contains("otap")) return {}; @@ -287,7 +289,7 @@ QString DevicesConnection::currentPartition() const return otap.value("label").toString(); } -std::optional DevicesConnection::reboots() const +std::optional DeviceConnection::reboots() const { if (!m_fullStatus.contains("rbc")) return {}; @@ -295,7 +297,7 @@ std::optional DevicesConnection::reboots() const return m_fullStatus.value("rbc").toInt(); } -QString DevicesConnection::rebootsText() const +QString DeviceConnection::rebootsText() const { if (!m_fullStatus.contains("rbc")) return {}; @@ -303,7 +305,7 @@ QString DevicesConnection::rebootsText() const return QString::number(m_fullStatus.value("rbc").toInt()); } -QString DevicesConnection::carStateText() const +QString DeviceConnection::carStateText() const { if (!m_fullStatus.contains("car")) return {}; @@ -315,7 +317,7 @@ QString DevicesConnection::carStateText() const return QString::number(car); } -std::optional DevicesConnection::energy() const +std::optional DeviceConnection::energy() const { if (!m_fullStatus.contains("eto")) return {}; @@ -323,7 +325,7 @@ std::optional DevicesConnection::energy() const return m_fullStatus.value("eto").toDouble(); } -QString DevicesConnection::energyText() const +QString DeviceConnection::energyText() const { if (!m_fullStatus.contains("eto")) return {}; @@ -331,7 +333,7 @@ QString DevicesConnection::energyText() const return QString("%0kWh").arg(m_fullStatus.value("eto").toDouble() / 1000.); } -QString DevicesConnection::livedataText() const +QString DeviceConnection::livedataText() const { if (!m_fullStatus.contains("nrg")) return {}; @@ -346,85 +348,94 @@ QString DevicesConnection::livedataText() const return {}; } -QVariant DevicesConnection::getApiKey(const QString &apiKey) const +QVariant DeviceConnection::getApiKey(const QString &apiKey) const { return m_fullStatus.value(apiKey); } -void DevicesConnection::sendMessage(const QJsonDocument &doc) +void DeviceConnection::sendMessage(const QJsonDocument &doc) { sendMessage(QString::fromUtf8(doc.toJson())); } -void DevicesConnection::sendMessage(const QJsonObject &obj) +void DeviceConnection::sendMessage(const QJsonObject &obj) { sendMessage(QJsonDocument{obj}); } -void DevicesConnection::sendMessage(const QString &msg) +void DeviceConnection::sendMessage(const QString &msg) { qDebug() << msg << m_websocket.errorString(); if (const auto written = m_websocket.sendTextMessage(msg); written != msg.size()) qCritical() << "sending message failed" << written << "(expected:" << msg.size() << ')'; } -void DevicesConnection::init() +QString DeviceConnection::errorString() const +{ + return m_websocket.errorString(); +} + +void DeviceConnection::init() { if (auto model = qobject_cast(parent())) { - connect(this, &DevicesConnection::wsStatusChanged, model, &DevicesModel::wsStatusChanged); - connect(this, &DevicesConnection::statusChanged, model, &DevicesModel::statusChanged); - connect(this, &DevicesConnection::variantChanged, model, &DevicesModel::variantChanged); - connect(this, &DevicesConnection::isGoChanged, model, &DevicesModel::isGoChanged); - connect(this, &DevicesConnection::isAustralienChanged, model, &DevicesModel::isAustralienChanged); - connect(this, &DevicesConnection::resetCardChanged, model, &DevicesModel::resetCardChanged); - connect(this, &DevicesConnection::connectedWifiChanged, model, &DevicesModel::connectedWifiChanged); - connect(this, &DevicesConnection::projectChanged, model, &DevicesModel::projectChanged); - connect(this, &DevicesConnection::versionChanged, model, &DevicesModel::versionChanged); - connect(this, &DevicesConnection::idfVersionChanged, model, &DevicesModel::idfVersionChanged); - connect(this, &DevicesConnection::updateChanged, model, &DevicesModel::updateChanged); - connect(this, &DevicesConnection::uptimeChanged, model, &DevicesModel::uptimeChanged); - connect(this, &DevicesConnection::currentPartitionChanged, model, &DevicesModel::currentPartitionChanged); - connect(this, &DevicesConnection::rebootsChanged, model, &DevicesModel::rebootsChanged); - connect(this, &DevicesConnection::carStateChanged, model, &DevicesModel::carStateChanged); - connect(this, &DevicesConnection::energyChanged, model, &DevicesModel::energyChanged); - connect(this, &DevicesConnection::livedataChanged, model, &DevicesModel::livedataChanged); - connect(this, &DevicesConnection::apiKeyChanged, model, &DevicesModel::apiKeyChanged); + connect(this, &DeviceConnection::wsStatusChanged, model, &DevicesModel::wsStatusChanged); + connect(this, &DeviceConnection::statusChanged, model, &DevicesModel::statusChanged); + connect(this, &DeviceConnection::variantChanged, model, &DevicesModel::variantChanged); + connect(this, &DeviceConnection::isGoChanged, model, &DevicesModel::isGoChanged); + connect(this, &DeviceConnection::isAustralienChanged, model, &DevicesModel::isAustralienChanged); + connect(this, &DeviceConnection::resetCardChanged, model, &DevicesModel::resetCardChanged); + connect(this, &DeviceConnection::connectedWifiChanged, model, &DevicesModel::connectedWifiChanged); + connect(this, &DeviceConnection::projectChanged, model, &DevicesModel::projectChanged); + connect(this, &DeviceConnection::versionChanged, model, &DevicesModel::versionChanged); + connect(this, &DeviceConnection::idfVersionChanged, model, &DevicesModel::idfVersionChanged); + connect(this, &DeviceConnection::updateChanged, model, &DevicesModel::updateChanged); + connect(this, &DeviceConnection::uptimeChanged, model, &DevicesModel::uptimeChanged); + connect(this, &DeviceConnection::currentPartitionChanged, model, &DevicesModel::currentPartitionChanged); + connect(this, &DeviceConnection::rebootsChanged, model, &DevicesModel::rebootsChanged); + connect(this, &DeviceConnection::carStateChanged, model, &DevicesModel::carStateChanged); + connect(this, &DeviceConnection::energyChanged, model, &DevicesModel::energyChanged); + connect(this, &DeviceConnection::livedataChanged, model, &DevicesModel::livedataChanged); + connect(this, &DeviceConnection::apiKeyChanged, model, &DevicesModel::apiKeyChanged); } else qWarning() << "unexpected parent"; - { - auto sslConfig = m_websocket.sslConfiguration(); - sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone); - //sslConfig.setPeerVerifyMode(QSslSocket::VerifyPeer); - { - auto caCerts = QSslCertificate::fromPath(":/goe-root-ca.pem"); - if (caCerts.empty()) - qFatal("could not parse root ca"); - for (const auto &caCert : std::as_const(caCerts)) - qDebug() << caCert.issuerDisplayName(); - sslConfig.setCaCertificates(std::move(caCerts)); - } - sslConfig.setPrivateKey(m_key); - sslConfig.setLocalCertificate(m_cert); - m_websocket.setSslConfiguration(sslConfig); - m_websocket.ignoreSslErrors(); - } + //{ + // auto sslConfig = m_websocket.sslConfiguration(); + // sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone); + // //sslConfig.setPeerVerifyMode(QSslSocket::VerifyPeer); + // { + // auto caCerts = QSslCertificate::fromPath(":/goe-root-ca.pem"); + // if (caCerts.empty()) + // qFatal("could not parse root ca"); + // for (const auto &caCert : std::as_const(caCerts)) + // qDebug() << caCert.issuerDisplayName(); + // sslConfig.setCaCertificates(std::move(caCerts)); + // } + // sslConfig.setPrivateKey(m_key); + // sslConfig.setLocalCertificate(m_cert); + // m_websocket.setSslConfiguration(sslConfig); + // m_websocket.ignoreSslErrors(); + //} - connect(&m_websocket, &QWebSocket::connected, this, &DevicesConnection::connected); - connect(&m_websocket, &QWebSocket::disconnected, this, &DevicesConnection::disconnected); - connect(&m_websocket, &QWebSocket::stateChanged, this, &DevicesConnection::stateChanged); - connect(&m_websocket, &QWebSocket::textMessageReceived, this, &DevicesConnection::textMessageReceived); - connect(&m_websocket, &QWebSocket::binaryMessageReceived, this, &DevicesConnection::binaryMessageReceived); - connect(&m_websocket, &QWebSocket::errorOccurred, this, &DevicesConnection::errorOccurred); - connect(&m_websocket, &QWebSocket::peerVerifyError, this, &DevicesConnection::peerVerifyError); - connect(&m_websocket, &QWebSocket::sslErrors, this, &DevicesConnection::sslErrors); - connect(&m_websocket, &QWebSocket::alertReceived, this, &DevicesConnection::alertReceived); - connect(&m_websocket, &QWebSocket::handshakeInterruptedOnError, this, &DevicesConnection::handshakeInterruptedOnError); + connect(&m_websocket, &QWebSocket::connected, this, &DeviceConnection::connectedSignal); + connect(&m_websocket, &QWebSocket::disconnected, this, &DeviceConnection::disconnectedSignal); + connect(&m_websocket, &QWebSocket::errorOccurred, this, &DeviceConnection::errorOccurredSignal); + + connect(&m_websocket, &QWebSocket::connected, this, &DeviceConnection::connected); + connect(&m_websocket, &QWebSocket::disconnected, this, &DeviceConnection::disconnected); + connect(&m_websocket, &QWebSocket::stateChanged, this, &DeviceConnection::stateChanged); + connect(&m_websocket, &QWebSocket::textMessageReceived, this, &DeviceConnection::textMessageReceived); + connect(&m_websocket, &QWebSocket::binaryMessageReceived, this, &DeviceConnection::binaryMessageReceived); + connect(&m_websocket, &QWebSocket::errorOccurred, this, &DeviceConnection::errorOccurred); + connect(&m_websocket, &QWebSocket::peerVerifyError, this, &DeviceConnection::peerVerifyError); + connect(&m_websocket, &QWebSocket::sslErrors, this, &DeviceConnection::sslErrors); + connect(&m_websocket, &QWebSocket::alertReceived, this, &DeviceConnection::alertReceived); + connect(&m_websocket, &QWebSocket::handshakeInterruptedOnError, this, &DeviceConnection::handshakeInterruptedOnError); } -void DevicesConnection::maintainStatus(const QJsonObject &msg, bool forceChange) +void DeviceConnection::maintainStatus(const QJsonObject &msg, bool forceChange) { bool variantChanged{forceChange}; bool isGoChanged{forceChange}; @@ -507,17 +518,17 @@ void DevicesConnection::maintainStatus(const QJsonObject &msg, bool forceChange) emit this->livedataChanged(); } -void DevicesConnection::connected() +void DeviceConnection::connected() { qDebug() << "called"; } -void DevicesConnection::disconnected() +void DeviceConnection::disconnected() { qDebug() << "called"; } -void DevicesConnection::stateChanged(QAbstractSocket::SocketState state) +void DeviceConnection::stateChanged(QAbstractSocket::SocketState state) { // qDebug() << "called" << state; @@ -533,7 +544,7 @@ void DevicesConnection::stateChanged(QAbstractSocket::SocketState state) emit wsStatusChanged(); } -void DevicesConnection::textMessageReceived(const QString &message) +void DeviceConnection::textMessageReceived(const QString &message) { // qDebug() << "called" << message; @@ -614,32 +625,32 @@ void DevicesConnection::textMessageReceived(const QString &message) qWarning() << "unknown message type" << msgObj; } -void DevicesConnection::binaryMessageReceived(const QByteArray &message) +void DeviceConnection::binaryMessageReceived(const QByteArray &message) { qDebug() << "called" << message; } -void DevicesConnection::errorOccurred(QAbstractSocket::SocketError error) +void DeviceConnection::errorOccurred(QAbstractSocket::SocketError error) { qDebug() << "called" << QMetaEnum::fromType().valueToKey(error) << m_websocket.errorString(); } -void DevicesConnection::peerVerifyError(const QSslError &error) +void DeviceConnection::peerVerifyError(const QSslError &error) { qDebug() << "called" << error; } -void DevicesConnection::sslErrors(const QList &errors) +void DeviceConnection::sslErrors(const QList &errors) { qDebug() << "called" << errors; } -void DevicesConnection::alertReceived(QSsl::AlertLevel level, QSsl::AlertType type, const QString &description) +void DeviceConnection::alertReceived(QSsl::AlertLevel level, QSsl::AlertType type, const QString &description) { qDebug() << "called" << std::to_underlying(level) << std::to_underlying(type) << description; } -void DevicesConnection::handshakeInterruptedOnError(const QSslError &error) +void DeviceConnection::handshakeInterruptedOnError(const QSslError &error) { qDebug() << "called" << error; } diff --git a/flotten-updater/deviceconnection.h b/flotten-updater/deviceconnection.h index c10f653..5dd5469 100644 --- a/flotten-updater/deviceconnection.h +++ b/flotten-updater/deviceconnection.h @@ -9,13 +9,13 @@ class QSslKey; class QSslCertificate; class QJsonObject; -class DevicesConnection : public QObject +class DeviceConnection : public QObject { Q_OBJECT public: - explicit DevicesConnection(const QSslKey &key, const QSslCertificate &cert, QString &&serial, QObject *parent = nullptr); - explicit DevicesConnection(const QSslKey &key, const QSslCertificate &cert, const QString &serial, QObject *parent = nullptr); + explicit DeviceConnection(const QByteArray &username, const QByteArray &password, QString &&serial, QObject *parent = nullptr); + explicit DeviceConnection(const QByteArray &username, const QByteArray &password, const QString &serial, QObject *parent = nullptr); void start(); void stop(); @@ -72,7 +72,13 @@ public: void sendMessage(const QJsonObject &obj); void sendMessage(const QString &msg); + QString errorString() const; + signals: + void connectedSignal(); + void disconnectedSignal(); + void errorOccurredSignal(QAbstractSocket::SocketError error); + void responseReceived(const QString &requestId, const QJsonObject &msg); void wsStatusChanged(); @@ -112,8 +118,8 @@ private slots: private: const QString m_serial; - const QSslKey &m_key; - const QSslCertificate &m_cert; + const QByteArray m_username; + const QByteArray m_password; enum Status { Unknown, diff --git a/flotten-updater/devicesmodel.cpp b/flotten-updater/devicesmodel.cpp index 69ca9d5..9394592 100644 --- a/flotten-updater/devicesmodel.cpp +++ b/flotten-updater/devicesmodel.cpp @@ -34,12 +34,12 @@ enum { }; } -DevicesModel::DevicesModel(FlottenUpdaterSettings &settings, const QSslKey &key, - const QSslCertificate &cert, QObject *parent) : +DevicesModel::DevicesModel(FlottenUpdaterSettings &settings, const QByteArray &username, + const QByteArray &password, QObject *parent) : QAbstractTableModel{parent}, m_settings{settings}, - m_key{key}, - m_cert{cert}, + m_username{username}, + m_password{password}, m_customColumns{settings.customColumns()} { for (const auto &serial : m_settings.serials()) @@ -47,7 +47,7 @@ DevicesModel::DevicesModel(FlottenUpdaterSettings &settings, const QSslKey &key, if (std::none_of(std::cbegin(m_devices), std::cend(m_devices), [&serial](auto &ptr){ return ptr->serial() == serial; })) - m_devices.emplace_back(std::make_shared(m_key, m_cert, serial, this)); + m_devices.emplace_back(std::make_shared(m_username, m_password, serial, this)); } } @@ -71,7 +71,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const return {}; } - const DevicesConnection &device = **std::next(std::begin(m_devices), index.row()); + const DeviceConnection &device = **std::next(std::begin(m_devices), index.row()); switch (index.column()) { @@ -332,7 +332,7 @@ bool DevicesModel::addClient(const QString &serial) beginInsertRows({}, m_devices.size(), m_devices.size()); - auto clientPtr = std::make_shared(m_key, m_cert, serial, this); + auto clientPtr = std::make_shared(m_username, m_password, serial, this); auto client = clientPtr.get(); m_devices.emplace_back(std::move(clientPtr)); @@ -343,7 +343,7 @@ bool DevicesModel::addClient(const QString &serial) return true; } -std::shared_ptr DevicesModel::getDevice(QModelIndex index) +std::shared_ptr DevicesModel::getDevice(QModelIndex index) { Q_ASSERT(!index.parent().isValid()); Q_ASSERT(index.row() >= 0 && index.row() < m_devices.size()); @@ -352,7 +352,7 @@ std::shared_ptr DevicesModel::getDevice(QModelIndex index) return device; } -std::shared_ptr DevicesModel::getDevice(QModelIndex index) const +std::shared_ptr DevicesModel::getDevice(QModelIndex index) const { Q_ASSERT(!index.parent().isValid()); return m_devices.at(index.row()); @@ -500,14 +500,14 @@ void DevicesModel::apiKeyChanged(const QString &apiKey) void DevicesModel::columnChanged(int column, const QList &roles) { - auto device = qobject_cast(sender()); + auto device = qobject_cast(sender()); if (!device) { qWarning() << "unknown sender" << sender(); return; } - auto iter = std::find_if(std::cbegin(m_devices), std::cend(m_devices), [&device](const std::shared_ptr &ptr){ return device == ptr.get(); }); + auto iter = std::find_if(std::cbegin(m_devices), std::cend(m_devices), [&device](const std::shared_ptr &ptr){ return device == ptr.get(); }); if (iter == std::cend(m_devices)) { qWarning() << "unknown sender" << device; diff --git a/flotten-updater/devicesmodel.h b/flotten-updater/devicesmodel.h index 16c58d3..8d0566f 100644 --- a/flotten-updater/devicesmodel.h +++ b/flotten-updater/devicesmodel.h @@ -9,7 +9,7 @@ class QSslKey; class QSslCertificate; class FlottenUpdaterSettings; -class DevicesConnection; +class DeviceConnection; class DevicesModel : public QAbstractTableModel { @@ -18,8 +18,8 @@ class DevicesModel : public QAbstractTableModel using base = QAbstractTableModel; public: - explicit DevicesModel(FlottenUpdaterSettings &settings, const QSslKey &key, - const QSslCertificate &cert, QObject *parent = nullptr); + explicit DevicesModel(FlottenUpdaterSettings &settings, const QByteArray &username, + const QByteArray &password, QObject *parent = nullptr); ~DevicesModel() override; int rowCount(const QModelIndex &parent) const override; @@ -30,8 +30,8 @@ public: bool addClient(const QString &serial); - std::shared_ptr getDevice(QModelIndex index); - std::shared_ptr getDevice(QModelIndex index) const; + std::shared_ptr getDevice(QModelIndex index); + std::shared_ptr getDevice(QModelIndex index) const; void addCustomColumn(const QString &apiKey); bool customColumnRemovable(int section); @@ -64,11 +64,11 @@ public slots: private: FlottenUpdaterSettings &m_settings; - const QSslKey &m_key; - const QSslCertificate &m_cert; + const QByteArray m_username; + const QByteArray m_password; void columnChanged(int column, const QList &roles = QList()); - std::vector> m_devices; + std::vector> m_devices; QStringList m_customColumns; }; diff --git a/flotten-updater/flottenupdatersettings.cpp b/flotten-updater/flottenupdatersettings.cpp index d575099..2f5bd0a 100644 --- a/flotten-updater/flottenupdatersettings.cpp +++ b/flotten-updater/flottenupdatersettings.cpp @@ -1,23 +1,23 @@ #include "flottenupdatersettings.h" -QByteArray FlottenUpdaterSettings::privateKey() const +QByteArray FlottenUpdaterSettings::username() const { - return value("privateKey").toByteArray(); + return value("username").toByteArray(); } -void FlottenUpdaterSettings::setPrivateKey(const QByteArray &key) +void FlottenUpdaterSettings::setUsername(const QByteArray &username) { - setValue("privateKey", key); + setValue("username", username); } -QByteArray FlottenUpdaterSettings::privateCert() const +QByteArray FlottenUpdaterSettings::password() const { - return value("privateCert").toByteArray(); + return value("password").toByteArray(); } -void FlottenUpdaterSettings::setPrivateCert(const QByteArray &cert) +void FlottenUpdaterSettings::setPassword(const QByteArray &password) { - setValue("privateCert", cert); + setValue("password", password); } QStringList FlottenUpdaterSettings::customColumns() const diff --git a/flotten-updater/flottenupdatersettings.h b/flotten-updater/flottenupdatersettings.h index 64dc01d..3111076 100644 --- a/flotten-updater/flottenupdatersettings.h +++ b/flotten-updater/flottenupdatersettings.h @@ -9,11 +9,11 @@ class FlottenUpdaterSettings : public QSettings public: using QSettings::QSettings; - QByteArray privateKey() const; - void setPrivateKey(const QByteArray &key); + QByteArray username() const; + void setUsername(const QByteArray &key); - QByteArray privateCert() const; - void setPrivateCert(const QByteArray &cert); + QByteArray password() const; + void setPassword(const QByteArray &cert); QStringList customColumns() const; void setCustomColumns(const QStringList &customColumns); diff --git a/flotten-updater/importcertificatedialog.cpp b/flotten-updater/importcertificatedialog.cpp deleted file mode 100644 index 377e77c..0000000 --- a/flotten-updater/importcertificatedialog.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "importcertificatedialog.h" -#include "ui_importcertificatedialog.h" - -#include -#include -#include -#include -#include - -#ifdef HAS_OPENSSL -#include -#endif - -#ifdef HAS_OPENSSL -namespace { -OSSL_PROVIDER *legacy{}; -} -#endif - -ImportCertificateDialog::ImportCertificateDialog(QWidget *parent) : - QDialog{parent}, - m_ui{std::make_unique()} -{ - m_ui->setupUi(this); - - connect(m_ui->pushButtonImport, &QPushButton::clicked, this, &ImportCertificateDialog::loadP12File); - connect(m_ui->plainTextEditKey, &QPlainTextEdit::textChanged, this, &ImportCertificateDialog::keyChanged); - connect(m_ui->plainTextEditCert, &QPlainTextEdit::textChanged, this, &ImportCertificateDialog::certChanged); - - m_ui->labelSupportsSslValue->setText(QSslSocket::supportsSsl() ? tr("Yes") : tr("No")); - m_ui->labelSslLibraryVersionValue->setText(QSslSocket::sslLibraryVersionString()); - m_ui->labelSslLibraryBuildVersionValue->setText(QSslSocket::sslLibraryBuildVersionString()); - const auto &availableBackends = QSslSocket::availableBackends(); - for (const auto &backend : availableBackends) - m_ui->comboBoxSslBackend->addItem(backend); - m_ui->comboBoxSslBackend->setCurrentText(QSslSocket::activeBackend()); - connect(m_ui->comboBoxSslBackend, &QComboBox::currentIndexChanged, - this, &ImportCertificateDialog::updateActiveBackend); -} - -ImportCertificateDialog::~ImportCertificateDialog() = default; - -void ImportCertificateDialog::accept() -{ - if (m_key.isNull()) - return; - if (m_cert.isNull()) - return; - - QDialog::accept(); -} - -void ImportCertificateDialog::loadP12File() -{ - auto selected = QFileDialog::getOpenFileName(this, tr("Select certificate..."), {}, "Certificates (*.p12)"); - if (selected.isEmpty()) - return; - - QFile file{selected}; - if (!file.open(QIODevice::ReadOnly)) - { - QMessageBox::warning(this, tr("Could not open file!"), tr("Could not open file!") + "\n\n" + file.errorString()); - return; - } - - bool ok{}; - QString passwordStr = QInputDialog::getText(this, tr("Please enter password"), tr("Certificate password:"), QLineEdit::PasswordEchoOnEdit, {}, &ok); - if (!ok) - return; - - auto password = passwordStr.toUtf8(); - - QSslKey key; - QSslCertificate cert; - QList certChain; - -#ifdef HAS_OPENSSL - if (QSslSocket::activeBackend() == "openssl" && !legacy) - { - legacy = OSSL_PROVIDER_load(NULL, "legacy"); - if (!legacy) - QMessageBox::warning(this, tr("Failed to load openssl legacy provider!"), tr("Failed to load openssl legacy provider!")); - } -#endif - - if (!QSslCertificate::importPkcs12(&file, &key, &cert, &certChain, password)) - { - QMessageBox::warning(this, tr("Failed processing certificate!"), tr("Failed processing certificate!") + "\n\n" + tr("Possible reasons: openssl has a problem, the file is corrupt/invalid or the password is incorrect.")); - return; - } - - if (key.isNull()) - { - QMessageBox::warning(this, tr("Failed processing certificate!"), tr("Failed processing certificate!") + "\n\n" + tr("The key seems to be invalid.")); - return; - } - - if (cert.isNull()) - { - QMessageBox::warning(this, tr("Failed processing certificate!"), tr("Failed processing certificate!") + "\n\n" + tr("The cert seems to be invalid.")); - return; - } - - m_key = std::move(key); - m_cert = std::move(cert); - - { - QSignalBlocker blocker{m_ui->plainTextEditKey}; - m_ui->plainTextEditKey->setPlainText(m_key.toPem()); - } - - { - auto palette = m_ui->plainTextEditKey->palette(); - palette.setBrush(QPalette::Base, QColor{200, 255, 200}); - palette.setBrush(QPalette::Window, QColor{200, 255, 200}); - m_ui->plainTextEditKey->setPalette(palette); - } - - { - QSignalBlocker blocker{m_ui->plainTextEditCert}; - m_ui->plainTextEditCert->setPlainText(m_cert.toPem()); - } - - { - auto palette = m_ui->plainTextEditCert->palette(); - palette.setBrush(QPalette::Base, QColor{200, 255, 200}); - palette.setBrush(QPalette::Window, QColor{200, 255, 200}); - m_ui->plainTextEditCert->setPalette(palette); - } -} - -void ImportCertificateDialog::keyChanged() -{ - m_key = QSslKey{m_ui->plainTextEditKey->toPlainText().toUtf8(), QSsl::KeyAlgorithm::Rsa, QSsl::Pem}; - - auto palette = m_ui->plainTextEditKey->palette(); - palette.setBrush(QPalette::Base, m_key.isNull() ? QColor{255, 200, 200} : QColor{200, 255, 200}); - palette.setBrush(QPalette::Window, m_key.isNull() ? QColor{255, 200, 200} : QColor{200, 255, 200}); - m_ui->plainTextEditKey->setPalette(palette); -} - -void ImportCertificateDialog::certChanged() -{ - m_cert = QSslCertificate{m_ui->plainTextEditCert->toPlainText().toUtf8()}; - - auto palette = m_ui->plainTextEditCert->palette(); - palette.setBrush(QPalette::Base, m_cert.isNull() ? QColor{255, 200, 200} : QColor{200, 255, 200}); - palette.setBrush(QPalette::Window, m_cert.isNull() ? QColor{255, 200, 200} : QColor{200, 255, 200}); - m_ui->plainTextEditCert->setPalette(palette); -} - -void ImportCertificateDialog::updateActiveBackend() -{ - if (!QSslSocket::setActiveBackend(m_ui->comboBoxSslBackend->currentText())) - QMessageBox::warning(this, tr("Could not change active backend"), tr("Could not change active backend")); - m_ui->comboBoxSslBackend->setCurrentText(QSslSocket::activeBackend()); -} diff --git a/flotten-updater/importcertificatedialog.h b/flotten-updater/importcertificatedialog.h deleted file mode 100644 index 78e65da..0000000 --- a/flotten-updater/importcertificatedialog.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace Ui { class ImportCertificateDialog; } - -class ImportCertificateDialog : public QDialog -{ - Q_OBJECT - -public: - explicit ImportCertificateDialog(QWidget *parent = nullptr); - ~ImportCertificateDialog(); - - const QSslKey &privateKey() const { return m_key; } - const QSslCertificate &privateCert() const { return m_cert; } - -public slots: - void accept() override; - -private slots: - void loadP12File(); - void keyChanged(); - void certChanged(); - void updateActiveBackend(); - -private: - const std::unique_ptr m_ui; - - QSslKey m_key; - QSslCertificate m_cert; -}; diff --git a/flotten-updater/importcertificatedialog.ui b/flotten-updater/importcertificatedialog.ui deleted file mode 100644 index f63d515..0000000 --- a/flotten-updater/importcertificatedialog.ui +++ /dev/null @@ -1,184 +0,0 @@ - - - ImportCertificateDialog - - - - 0 - 0 - 459 - 429 - - - - Import Certificate - - - - - - - - Supports Ssl: - - - - - - - TextLabel - - - - - - - Ssl Library Version: - - - - - - - TextLabel - - - - - - - Ssl Library Build Version: - - - - - - - TextLabel - - - - - - - Ssl Backend: - - - comboBoxSslBackend - - - - - - - - - - Automatic Import: - - - pushButtonImport - - - - - - - Load p12 file... - - - - - - - Private Key: - - - plainTextEditKey - - - - - - - true - - - - - - - Private Cert: - - - plainTextEditCert - - - - - - - true - - - - - - - - - Warning: Your private key and cert will be stored on this machine, but can later be erased from the main window. - - - true - - - - - - - Qt::Orientation::Horizontal - - - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Save - - - - - - - - - buttonBox - accepted() - ImportCertificateDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - ImportCertificateDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/flotten-updater/importcredentialsdialog.cpp b/flotten-updater/importcredentialsdialog.cpp new file mode 100644 index 0000000..aa80eed --- /dev/null +++ b/flotten-updater/importcredentialsdialog.cpp @@ -0,0 +1,89 @@ +#include "importcredentialsdialog.h" +#include "ui_importcredentialsdialog.h" + +#include +#include + +#include "deviceconnection.h" + +ImportCredentialsDialog::ImportCredentialsDialog(QWidget *parent) : + QDialog{parent}, + m_ui{std::make_unique()} +{ + m_ui->setupUi(this); +} + +ImportCredentialsDialog::~ImportCredentialsDialog() = default; + +QByteArray ImportCredentialsDialog::username() const +{ + return m_ui->lineEditUsername->text().toUtf8(); +} + +QByteArray ImportCredentialsDialog::password() const +{ + return m_ui->lineEditPassword->text().toUtf8(); +} + +void ImportCredentialsDialog::accept() +{ + if (username().isEmpty() || + password().isEmpty()) + { + QMessageBox::warning(this, tr("Please fill out all fields!"), tr("Please fill out all fields!")); + return; + } + + m_ui->lineEditUsername->setEnabled(false); + m_ui->lineEditPassword->setEnabled(false); + if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Save)) + button->setEnabled(false); + + m_testConnection = std::make_unique(username(), password(), "123456"); + connect(m_testConnection.get(), &DeviceConnection::connectedSignal, + this, &ImportCredentialsDialog::connected); + connect(m_testConnection.get(), &DeviceConnection::disconnectedSignal, + this, &ImportCredentialsDialog::disconnected); + connect(m_testConnection.get(), &DeviceConnection::errorOccurredSignal, + this, &ImportCredentialsDialog::errorOccurred); + m_testConnection->start(); +} + +void ImportCredentialsDialog::connected() +{ + qDebug() << "called"; + + QDialog::accept(); + + finishTestConnection(); +} + +void ImportCredentialsDialog::disconnected() +{ + qDebug() << "called"; + + finishTestConnection(); +} + +void ImportCredentialsDialog::errorOccurred(QAbstractSocket::SocketError error) +{ + Q_ASSERT(m_testConnection); + QMessageBox::warning(this, + tr("Problem verifying credentials!"), + QString("%0\n\n%1") + .arg(QMetaEnum::fromType().valueToKey(error)) + .arg(m_testConnection->errorString()) + ); +} + +void ImportCredentialsDialog::finishTestConnection() +{ + Q_ASSERT(m_testConnection); + + m_ui->lineEditUsername->setEnabled(true); + m_ui->lineEditPassword->setEnabled(true); + if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Save)) + button->setEnabled(true); + + m_testConnection.release()->deleteLater(); +} diff --git a/flotten-updater/importcredentialsdialog.h b/flotten-updater/importcredentialsdialog.h new file mode 100644 index 0000000..568c554 --- /dev/null +++ b/flotten-updater/importcredentialsdialog.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include + +namespace Ui { class ImportCredentialsDialog; } +class DeviceConnection; + +class ImportCredentialsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ImportCredentialsDialog(QWidget *parent = nullptr); + ~ImportCredentialsDialog(); + + QByteArray username() const; + QByteArray password() const; + +public slots: + void accept() override; + +private slots: + void connected(); + void disconnected(); + void errorOccurred(QAbstractSocket::SocketError error); + +private: + void finishTestConnection(); + + const std::unique_ptr m_ui; + std::unique_ptr m_testConnection; +}; diff --git a/flotten-updater/importcredentialsdialog.ui b/flotten-updater/importcredentialsdialog.ui new file mode 100644 index 0000000..37b7297 --- /dev/null +++ b/flotten-updater/importcredentialsdialog.ui @@ -0,0 +1,114 @@ + + + ImportCredentialsDialog + + + + 0 + 0 + 442 + 164 + + + + Import Credentials + + + + + + Please enter your credentials to access solalaweb.com: + + + + + + + Please create an app password in <a href="https://auth.go-e.com/if/user/#/settings;{%22page%22:%22page-tokens%22}">our SSO</a>. + + + true + + + Qt::TextInteractionFlag::TextBrowserInteraction + + + + + + + + + Username: + + + lineEditUsername + + + + + + + App-Password: + + + lineEditPassword + + + + + + + + + + + + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Save + + + + + + + + + buttonBox + accepted() + ImportCredentialsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ImportCredentialsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/flotten-updater/main.cpp b/flotten-updater/main.cpp index ca6b2fc..fa2340b 100644 --- a/flotten-updater/main.cpp +++ b/flotten-updater/main.cpp @@ -1,14 +1,9 @@ #include #include #include -#include -#include -#ifdef Q_OS_WIN -#include -#endif #include "flottenupdatersettings.h" -#include "importcertificatedialog.h" +#include "importcredentialsdialog.h" #include "mainwindow.h" int main(int argc, char *argv[]) @@ -36,50 +31,32 @@ int main(int argc, char *argv[]) #endif FlottenUpdaterSettings settings; - QByteArray keyBuf = settings.privateKey(); - QByteArray certBuf = settings.privateCert(); - QSslKey key{keyBuf, QSsl::KeyAlgorithm::Rsa, QSsl::Pem}; - QSslCertificate cert{certBuf}; + QByteArray username = settings.username(); + QByteArray password = settings.password(); - if (keyBuf.isEmpty()) - goto loadCert; + if (username.isEmpty()) + goto loadCredentials; - if (certBuf.isEmpty()) - goto loadCert; - - if (key.isNull()) - { - QMessageBox::warning(nullptr, - QCoreApplication::translate("main", "Could not parse private key!"), - QCoreApplication::translate("main", "Could not parse private key!")); - goto loadCert; - } - - if (cert.isNull()) - { - QMessageBox::warning(nullptr, - QCoreApplication::translate("main", "Could not parse private cert!"), - QCoreApplication::translate("main", "Could not parse private cert!")); - goto loadCert; - } + if (password.isEmpty()) + goto loadCredentials; goto showMainWindow; { - loadCert: - ImportCertificateDialog dialog; + loadCredentials: + ImportCredentialsDialog dialog; if (dialog.exec() != QDialog::Accepted) return 0; - key = dialog.privateKey(); - cert = dialog.privateCert(); - settings.setPrivateKey(key.toPem()); - settings.setPrivateCert(cert.toPem()); + username = dialog.username(); + password = dialog.password(); + settings.setUsername(username); + settings.setPassword(password); } showMainWindow: - MainWindow mainWindow{settings, key, cert}; + MainWindow mainWindow{settings, username, password}; mainWindow.show(); return app.exec(); diff --git a/flotten-updater/mainwindow.cpp b/flotten-updater/mainwindow.cpp index a4be53c..83d08d6 100644 --- a/flotten-updater/mainwindow.cpp +++ b/flotten-updater/mainwindow.cpp @@ -18,12 +18,12 @@ #include "setarbitraryapikeydialog.h" #include "addserialsrangedialog.h" -MainWindow::MainWindow(FlottenUpdaterSettings &settings, const QSslKey &key, - const QSslCertificate &cert, QWidget *parent) : +MainWindow::MainWindow(FlottenUpdaterSettings &settings, const QByteArray &username, + const QByteArray &password, QWidget *parent) : QMainWindow{parent}, m_ui{std::make_unique()}, m_settings{settings}, - m_model{std::make_unique(settings, key, cert, this)}, + m_model{std::make_unique(settings, username, password, this)}, m_proxyModel{std::make_unique(this)} { m_ui->setupUi(this); @@ -146,7 +146,7 @@ void MainWindow::contextMenuRequested(const QPoint &pos) [&](const QModelIndex &index){ return m_proxyModel->mapToSource(index); }); // get all the devices for selected indices - std::vector> devices; + std::vector> devices; devices.reserve(selectedRows.size()); std::transform(std::begin(selectedRows), std::end(selectedRows), std::back_inserter(devices), [&](const QModelIndex &index){ auto device = m_model->getDevice(index); Q_ASSERT(device); return device; }); diff --git a/flotten-updater/mainwindow.h b/flotten-updater/mainwindow.h index 590666d..610e80d 100644 --- a/flotten-updater/mainwindow.h +++ b/flotten-updater/mainwindow.h @@ -18,8 +18,8 @@ class MainWindow : public QMainWindow Q_OBJECT public: - explicit MainWindow(FlottenUpdaterSettings &settings, const QSslKey &key, - const QSslCertificate &cert, QWidget *parent = nullptr); + explicit MainWindow(FlottenUpdaterSettings &settings, const QByteArray &username, + const QByteArray &password, QWidget *parent = nullptr); ~MainWindow() override; private slots: diff --git a/flotten-updater/requestdialog.cpp b/flotten-updater/requestdialog.cpp index 2de53d0..00cac5a 100644 --- a/flotten-updater/requestdialog.cpp +++ b/flotten-updater/requestdialog.cpp @@ -7,7 +7,7 @@ #include "deviceconnection.h" #include "requestmodel.h" -RequestDialog::RequestDialog(QJsonObject &&msg, std::vector> &&devices, QWidget *parent) : +RequestDialog::RequestDialog(QJsonObject &&msg, std::vector> &&devices, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, m_model{std::make_unique(std::move(msg), std::move(devices), this)} diff --git a/flotten-updater/requestdialog.h b/flotten-updater/requestdialog.h index c9e4367..5e424e5 100644 --- a/flotten-updater/requestdialog.h +++ b/flotten-updater/requestdialog.h @@ -5,7 +5,7 @@ #include class QJsonObject; -class DevicesConnection; +class DeviceConnection; class RequestModel; namespace Ui { class RequestDialog; } @@ -15,7 +15,7 @@ class RequestDialog : public QDialog Q_OBJECT public: - explicit RequestDialog(QJsonObject &&msg, std::vector> &&devices, QWidget *parent = nullptr); + explicit RequestDialog(QJsonObject &&msg, std::vector> &&devices, QWidget *parent = nullptr); ~RequestDialog(); private: diff --git a/flotten-updater/requestmodel.cpp b/flotten-updater/requestmodel.cpp index 1c66110..f1564a4 100644 --- a/flotten-updater/requestmodel.cpp +++ b/flotten-updater/requestmodel.cpp @@ -21,7 +21,7 @@ enum { QString getRandomString(); } -RequestModel::RequestModel(QJsonObject &&msg, std::vector> &&devices, QObject *parent) : +RequestModel::RequestModel(QJsonObject &&msg, std::vector> &&devices, QObject *parent) : QAbstractTableModel{parent} { m_requests.reserve(devices.size()); @@ -33,7 +33,7 @@ RequestModel::RequestModel(QJsonObject &&msg, std::vector class QJsonObject; -class DevicesConnection; +class DeviceConnection; class RequestModel : public QAbstractTableModel { Q_OBJECT public: - explicit RequestModel(QJsonObject &&msg, std::vector> &&devices, QObject *parent = nullptr); + explicit RequestModel(QJsonObject &&msg, std::vector> &&devices, QObject *parent = nullptr); ~RequestModel() override; // QAbstractItemModel interface @@ -27,7 +27,7 @@ private slots: private: struct Request { - std::shared_ptr device; + std::shared_ptr device; QString requestId; enum class Status { Pending, Failed, Succeeded }; Status status{Status::Pending};