diff --git a/src/plugins/axivion/dashboard/dashboardclient.cpp b/src/plugins/axivion/dashboard/dashboardclient.cpp index 3d20440b60a..54b826c7591 100644 --- a/src/plugins/axivion/dashboard/dashboardclient.cpp +++ b/src/plugins/axivion/dashboard/dashboardclient.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -21,8 +22,29 @@ namespace Axivion::Internal { +Credential::Credential(const QString &apiToken) + : m_authorizationValue(QByteArrayLiteral(u8"AxToken ") + apiToken.toUtf8()) +{ +} + +const QByteArray &Credential::authorizationValue() const +{ + return m_authorizationValue; +} + +QFuture CredentialProvider::getCredential() +{ + return QtFuture::makeReadyFuture(Credential(settings().server.token)); +} + +ClientData::ClientData(Utils::NetworkAccessManager &networkAccessManager) + : networkAccessManager(networkAccessManager), + credentialProvider(std::make_unique()) +{ +} + DashboardClient::DashboardClient(Utils::NetworkAccessManager &networkAccessManager) - : m_networkAccessManager(networkAccessManager) + : m_clientData(std::make_shared(networkAccessManager)) { } @@ -31,7 +53,7 @@ using ResponseData = Utils::expected, Error>; static constexpr int httpStatusCodeOk = 200; static const QLatin1String jsonContentType{ "application/json" }; -ResponseData readResponse(QNetworkReply& reply, QAnyStringView expectedContentType) +static ResponseData readResponse(QNetworkReply &reply, QAnyStringView expectedContentType) { QNetworkReply::NetworkError error = reply.error(); int statusCode = reply.attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); @@ -83,26 +105,22 @@ static Utils::expected, Error> parseResponse(ResponseData rawB } } -QFuture fetch(Utils::NetworkAccessManager &networkAccessManager, - const std::optional &base, - const QUrl &target) +static void fetch(QPromise promise, + std::shared_ptr clientData, + const QUrl &url, + const Credential &credential) { - QPromise promise; - promise.start(); - const AxivionServer &server = settings().server; - QUrl url = base ? base->resolved(target) : target; QNetworkRequest request{ url }; request.setRawHeader(QByteArrayLiteral(u8"Accept"), QByteArray(jsonContentType.data(), jsonContentType.size())); request.setRawHeader(QByteArrayLiteral(u8"Authorization"), - QByteArrayLiteral(u8"AxToken ") + server.token.toUtf8()); + credential.authorizationValue()); QByteArray ua = QByteArrayLiteral(u8"Axivion") + QCoreApplication::applicationName().toUtf8() + QByteArrayLiteral(u8"Plugin/") + QCoreApplication::applicationVersion().toUtf8(); request.setRawHeader(QByteArrayLiteral(u8"X-Axivion-User-Agent"), ua); - QFuture future = promise.future(); - QNetworkReply* reply = networkAccessManager.get(request); + QNetworkReply *reply = clientData->networkAccessManager.get(request); QObject::connect(reply, &QNetworkReply::finished, reply, @@ -111,6 +129,28 @@ QFuture fetch(Utils::NetworkAccessManager &networkAccessManager, promise.finish(); reply->deleteLater(); }); +} + +static QFuture fetch(std::shared_ptr clientData, + const std::optional &base, + const QUrl &target) +{ + QPromise promise; + promise.start(); + QFuture future = promise.future(); + QUrl url = base ? base->resolved(target) : target; + QFutureWatcher *watcher = new QFutureWatcher(&clientData->networkAccessManager); + QObject::connect(watcher, + &QFutureWatcher::finished, + &clientData->networkAccessManager, + [promise = std::move(promise), clientData, url = std::move(url), watcher]() mutable { + fetch(std::move(promise), + std::move(clientData), + url, + watcher->result()); + watcher->deleteLater();; + }); + watcher->setFuture(clientData->credentialProvider->getCredential()); return future; } @@ -123,7 +163,7 @@ QFuture DashboardClient::fetchProjectInfo(const QUrl url = QUrl(dashboard) .resolved(QUrl(QStringLiteral(u"api/projects/"))) .resolved(QUrl(projectName)); - return fetch(this->m_networkAccessManager, std::nullopt, url) + return fetch(this->m_clientData, std::nullopt, url) .then(QtFuture::Launch::Async, &parseResponse); } diff --git a/src/plugins/axivion/dashboard/dashboardclient.h b/src/plugins/axivion/dashboard/dashboardclient.h index eb9d58c799f..29fdf315c14 100644 --- a/src/plugins/axivion/dashboard/dashboardclient.h +++ b/src/plugins/axivion/dashboard/dashboardclient.h @@ -29,6 +29,32 @@ public: DataWithOrigin(QUrl origin, T data) : origin(std::move(origin)), data(std::move(data)) { } }; +class Credential +{ +public: + Credential(const QString &apiToken); + + const QByteArray &authorizationValue() const; + +private: + QByteArray m_authorizationValue; +}; + +class CredentialProvider +{ +public: + QFuture getCredential(); +}; + +class ClientData +{ +public: + Utils::NetworkAccessManager &networkAccessManager; + std::unique_ptr credentialProvider; + + ClientData(Utils::NetworkAccessManager &networkAccessManager); +}; + class DashboardClient { public: @@ -40,7 +66,7 @@ public: QFuture fetchProjectInfo(const QString &projectName); private: - Utils::NetworkAccessManager &m_networkAccessManager; + std::shared_ptr m_clientData; }; } // namespace Axivion::Internal