Skip to content

Commit

Permalink
Implement environment variables in requests
Browse files Browse the repository at this point in the history
  • Loading branch information
vicr123 committed Sep 10, 2023
1 parent 4c4ff9c commit ce3663a
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 12 deletions.
4 changes: 2 additions & 2 deletions libthezzz/providers/endpointprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ void EndpointProvider::setEndpoint(QString endpoint) {
emit this->workspace()->dataChanged();
}

QUrl EndpointProvider::calculateUrl() {
return d->endpoint;
QUrl EndpointProvider::calculateUrl(QList<ZzzVariable>* missingEnvironmentVariables) {
return this->workspace()->substituteEnvironment(d->endpoint, missingEnvironmentVariables);
}

QString EndpointProvider::jsonKey() {
Expand Down
3 changes: 2 additions & 1 deletion libthezzz/providers/endpointprovider.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef ENDPOINTPROVIDER_H
#define ENDPOINTPROVIDER_H

#include "environmentprovider.h"
#include "zzzprovider.h"
#include <QString>

Expand All @@ -17,7 +18,7 @@ class EndpointProvider : public ZzzProvider<EndpointProvider> {
QString endpoint();
void setEndpoint(QString endpoint);

QUrl calculateUrl();
QUrl calculateUrl(QList<ZzzVariable>* missingEnvironmentVariables = nullptr);

private:
EndpointProviderPrivate* d;
Expand Down
41 changes: 41 additions & 0 deletions libthezzz/providers/environmentprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ void EnvironmentProvider::removeEnvironment(QUuid uuid) {
d->environments.removeIf([uuid](ZzzEnvironment env) {
return env.first == uuid;
});
d->envVars.removeIf([uuid](ZzzEnvironmentVariable envVar) {
return std::get<0>(envVar) == uuid;
});
emit this->workspace()->dataChanged();
}

Expand All @@ -58,9 +61,20 @@ QList<ZzzVariable> EnvironmentProvider::variables() {

void EnvironmentProvider::setVariables(QList<ZzzVariable> variables) {
d->variables = variables;
d->envVars.removeIf([variables](ZzzEnvironmentVariable envVar) {
return !tRange(variables).some([envVar](ZzzVariable var) {
return std::get<0>(var) == std::get<1>(envVar);
});
});
emit this->workspace()->dataChanged();
}

QString EnvironmentProvider::variableName(QUuid variable) {
return std::get<1>(tRange(d->variables).first([variable](ZzzVariable var) {
return std::get<0>(var) == variable;
}));
}

QList<ZzzEnvironmentVariable> EnvironmentProvider::environmentVariables() {
return d->envVars;
}
Expand All @@ -74,6 +88,33 @@ QUuid EnvironmentProvider::currentEnvironment() {
return d->currentEnvironment;
}

QString EnvironmentProvider::substituteEnvironment(QString string, QList<ZzzVariable>* missingEnvironmentVariables) {
for (const auto& envVar : d->envVars) {
auto [envUuid, varUuid, value] = envVar;
try {
auto variable = tRange(d->variables).first([envVar](ZzzVariable var) {
auto [envUuid, varUuid, value] = envVar;
return std::get<0>(var) == varUuid;
});
auto [varUuid2, varName, varIsSecret] = variable;

auto searchTerm = QStringLiteral("{{%1}}").arg(varName);
if (string.contains(searchTerm)) {
if (value.isEmpty()) {
if (missingEnvironmentVariables) missingEnvironmentVariables->append(variable);
string = string.replace(searchTerm, "");
} else {
string = string.replace(searchTerm, value);
}
}
} catch (tRangeException& ex) {
// ignore
}
}

return string;
}

QString EnvironmentProvider::jsonKey() {
return QStringLiteral("env");
}
Expand Down
3 changes: 3 additions & 0 deletions libthezzz/providers/environmentprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "zzzprovider.h"
#include <QCoreApplication>
#include <texception.h>

typedef std::pair<QUuid, QString> ZzzEnvironment;
typedef std::tuple<QUuid, QString, bool> ZzzVariable;
Expand All @@ -23,11 +24,13 @@ class EnvironmentProvider : public ZzzProvider<EnvironmentProvider> {

QList<ZzzVariable> variables();
void setVariables(QList<ZzzVariable> variables);
QString variableName(QUuid variable);

QList<ZzzEnvironmentVariable> environmentVariables();
void setEnvironmentVariables(QList<ZzzEnvironmentVariable> environmentVariables);

QUuid currentEnvironment();
QString substituteEnvironment(QString string, QList<ZzzVariable>* missingEnvironmentVariables = nullptr);

private:
EnvironmentProviderPrivate* d;
Expand Down
23 changes: 20 additions & 3 deletions libthezzz/translations/en_US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
<name>EnvironmentProvider</name>
<message>
<location filename="../providers/environmentprovider.cpp" line="20"/>
<location filename="../providers/environmentprovider.cpp" line="123"/>
<location filename="../providers/environmentprovider.cpp" line="164"/>
<source>Production</source>
<translation type="unfinished"></translation>
</message>
Expand Down Expand Up @@ -401,8 +401,8 @@
<context>
<name>ZzzRequest</name>
<message>
<location filename="../zzzrequest.cpp" line="16"/>
<location filename="../zzzrequest.cpp" line="20"/>
<location filename="../zzzrequest.cpp" line="17"/>
<location filename="../zzzrequest.cpp" line="21"/>
<source>Untitled Request</source>
<translation type="unfinished"></translation>
</message>
Expand All @@ -414,6 +414,23 @@
<source>Form</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../widgets/zzzrequesteditor.cpp" line="75"/>
<source>Environment Incomplete</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../widgets/zzzrequesteditor.cpp" line="76"/>
<source>The request cannot be sent because some environment variables used by this request are not set.</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<location filename="../widgets/zzzrequesteditor.cpp" line="77"/>
<source>The environment variable(s) %1 need to be set before the request can be sent.</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
</context>
<context>
<name>ZzzRequestFolder</name>
Expand Down
21 changes: 19 additions & 2 deletions libthezzz/widgets/zzzrequesteditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "providers/endpointprovider.h"
#include "zzzrequest.h"
#include <QToolButton>
#include <ranges/trange.h>
#include <tmessagebox.h>

struct ZzzRequestEditorPrivate {
ZzzRequestTreeItemPtr request;
Expand Down Expand Up @@ -60,6 +62,21 @@ void ZzzRequestEditor::executeRequest() {
auto request = d->request.dynamicCast<ZzzRequest>();
if (!request) return;

auto reply = request->execute();
emit addReply(reply);
try {
auto reply = request->execute();
emit addReply(reply);
} catch (EnvironmentIncompleteException& ex) {
([this, &ex]() -> QCoro::Task<> {
auto missingVariables = tRange(ex.missingVariables()).map<QString>([](ZzzVariable variable) {
return QLocale().quoteString(std::get<1>(variable));
})
.toList();
tMessageBox box(this->window());
box.setTitleBarText(tr("Environment Incomplete"));
box.setMessageText(tr("The request cannot be sent because some environment variables used by this request are not set."));
box.setInformativeText(tr("The environment variable(s) %1 need to be set before the request can be sent.", nullptr, missingVariables.length()).arg(QLocale().createSeparatedList(missingVariables)));
box.setIcon(QMessageBox::Information);
co_await box.presentAsync();
})();
}
}
28 changes: 24 additions & 4 deletions libthezzz/zzzrequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "workspacefile.h"
#include "zzzreply.h"
#include <QNetworkAccessManager>
#include <ranges/trange.h>

struct ZzzRequestPrivate {
WorkspaceFilePtr workspace;
Expand All @@ -28,23 +29,24 @@ ZzzRequest::~ZzzRequest() {
}

ZzzReplyPtr ZzzRequest::execute() {
QList<ZzzVariable> missingEnvironmentVariables;
auto mgr = d->workspace->networkAccessManager();

QNetworkRequest request;
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
request.setUrl(this->endpoint());
request.setUrl(this->calculateUrl(&missingEnvironmentVariables));

for (const auto& header : this->implicitHeadersWithAncestors()) {
request.setRawHeader(header.first, header.second);
request.setRawHeader(header.first, d->workspace->substituteEnvironment(header.second, &missingEnvironmentVariables).toUtf8());
}

for (const auto& header : this->ancestorHeaders()) {
request.setRawHeader(header.first, header.second);
request.setRawHeader(header.first, d->workspace->substituteEnvironment(header.second, &missingEnvironmentVariables).toUtf8());
}

// TODO: Concatenate multiple headers correctly
for (const auto& header : this->headers()) {
request.setRawHeader(header.first, header.second);
request.setRawHeader(header.first, d->workspace->substituteEnvironment(header.second, &missingEnvironmentVariables).toUtf8());
}

QNetworkReply* networkReply;
Expand All @@ -60,6 +62,14 @@ ZzzReplyPtr ZzzRequest::execute() {
networkReply = mgr->sendCustomRequest(request, this->verb().toUtf8(), this->body());
}

missingEnvironmentVariables = tRange(missingEnvironmentVariables).unique<QUuid>([](ZzzVariable variable) {
return std::get<0>(variable);
})
.toList();
if (!missingEnvironmentVariables.isEmpty()) {
throw EnvironmentIncompleteException(missingEnvironmentVariables);
}

auto reply = new ZzzReply(this->verb(), request, networkReply);
return reply->sharedFromThis();
}
Expand All @@ -73,3 +83,13 @@ QJsonValue ZzzRequest::toJson() {
json.insert("type", "request");
return json;
}

EnvironmentIncompleteException::EnvironmentIncompleteException(QList<ZzzVariable> missingVariables) {
_missingVariables = missingVariables;
}

QList<ZzzVariable> EnvironmentIncompleteException::missingVariables() {
return _missingVariables;
}

T_EXCEPTION_IMPL(EnvironmentIncompleteException)
11 changes: 11 additions & 0 deletions libthezzz/zzzrequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,15 @@ class LIBTHEZZZ_EXPORT ZzzRequest : public QObject,

typedef QSharedPointer<ZzzRequest> ZzzRequestPtr;

class LIBCONTEMPORARY_EXPORT EnvironmentIncompleteException : public tException {
T_EXCEPTION(EnvironmentIncompleteException)
public:
EnvironmentIncompleteException(QList<ZzzVariable> missingVariables);

QList<ZzzVariable> missingVariables();

private:
QList<ZzzVariable> _missingVariables;
};

#endif // ZZZREQUEST_H

0 comments on commit ce3663a

Please sign in to comment.