9 #include <QScopedPointer>
13 #include "qjsonwebtoken/qjsonwebtoken.h"
21 using namespace swift::misc::network;
22 using namespace swift::config;
24 namespace swift::core::afv::connection
32 CApiServerConnection::CApiServerConnection(
const QString &address,
QObject *parent)
33 :
QObject(parent), m_addressUrl(address)
41 if (isShuttingDown()) {
return; }
43 m_username = username;
44 m_password = password;
46 m_networkVersion = networkVersion;
47 m_isAuthenticated =
false;
49 QUrl url(m_addressUrl);
53 {
"password", password },
54 {
"networkversion", networkVersion.
toString() },
55 {
"client", client } };
66 if (!myself || isShuttingDown())
71 this->logRequestDuration(reply.
data(),
"authentication");
74 this->logReplyErrorMessage(reply.
data(),
"authentication error");
80 m_serverToUserOffsetMs = 0;
83 m_jwt = reply->readAll().trimmed();
84 qint64 lifeTimeSecs = -1;
85 qint64 serverToUserOffsetSecs = -1;
88 const QJsonWebToken token = QJsonWebToken::fromTokenAndSecret(jwtToken,
"");
96 if (validFromSecs < 0) {
break; }
98 serverToUserOffsetSecs = validFromSecs - localSecsSinceEpoch;
100 const qint64 expiryLocalUtc = serverExpirySecs - serverToUserOffsetSecs;
101 lifeTimeSecs = expiryLocalUtc - localSecsSinceEpoch;
105 if (lifeTimeSecs > 0)
107 m_serverToUserOffsetMs = serverToUserOffsetSecs * 1000;
109 m_isAuthenticated =
true;
113 callback(m_isAuthenticated);
119 return this->postNoRequest<PostCallsignResponseDto>(
"/api/v1/users/" + m_username +
"/callsigns/" + callsign);
124 this->deleteResource(
"/api/v1/users/" + m_username +
"/callsigns/" + callsign);
129 if (!this->sendToNetworkIfAuthenticated()) {
return; }
132 this->postNoResponse(
"/api/v1/users/" + m_username +
"/callsigns/" + callsign +
"/transceivers",
138 m_isAuthenticated =
false;
144 const QVector<StationDto> stations = this->getAsVector<StationDto>(
"/api/v1/stations/aliased");
157 if (isShuttingDown()) {
return {}; }
168 if (loop && !isShuttingDown())
170 this->logRequestDuration(reply.data());
172 else { this->logReplyErrorMessage(reply.data()); }
174 if (loop) { loop->exit(); }
177 if (loop) { loop->exec(); }
183 if (isShuttingDown()) {
return {}; }
194 if (loop && !isShuttingDown())
196 this->logRequestDuration(reply.data());
198 else { this->logReplyErrorMessage(reply.data()); }
200 if (loop) { loop->exit(); }
203 if (loop) { loop->exec(); }
209 if (isShuttingDown()) {
return; }
212 QUrl url(m_addressUrl);
213 url.setPath(resource);
215 request.
setRawHeader(
"Authorization",
"Bearer " + m_jwt);
220 { this, [=](QNetworkReply *nwReply) {
222 const QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> reply(nwReply);
223 if (isShuttingDown()) { return; }
224 this->logRequestDuration(reply.data());
225 if (reply->error() != QNetworkReply::NoError)
227 this->logReplyErrorMessage(reply.data());
232 void CApiServerConnection::deleteResource(
const QString &resource)
234 if (isShuttingDown()) {
return; }
236 QUrl url(m_addressUrl);
237 url.setPath(resource);
240 request.
setRawHeader(
"Authorization",
"Bearer " + m_jwt);
248 if (isShuttingDown()) {
return; }
249 this->logRequestDuration(reply.data());
252 this->logReplyErrorMessage(reply.data());
257 void CApiServerConnection::checkExpiry()
262 this->connectTo(m_username, m_password, m_client, m_networkVersion,
263 {
this, [=](
bool authenticated) {
264 if (!myself) {
return; }
271 void CApiServerConnection::logReplyErrorMessage(
const QNetworkReply *reply,
const QString &addMsg)
273 if (!reply) {
return; }
283 << addMsg << reply->
url().
toString() << CNetworkUtils::networkOperationToString(reply->
operation())
288 void CApiServerConnection::logRequestDuration(
const QNetworkReply *reply,
const QString &addMsg)
290 if (!CBuildConfig::isLocalDeveloperDebugBuild()) {
return; }
291 if (!reply) {
return; }
293 const qint64 d = CNetworkUtils::requestDuration(reply);
294 if (d < 0) {
return; }
306 QEventLoop *CApiServerConnection::newEventLoop()
316 bool CApiServerConnection::sendToNetworkIfAuthenticated()
const {
return m_isAuthenticated && !isShuttingDown(); }
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
void aboutToShutdown()
About to shutdown.
QNetworkReply * getFromNetwork(const swift::misc::network::CUrl &url, const CallbackSlot &callback, int maxRedirects=DefaultMaxRedirects)
Request to get network reply.
static constexpr int NoLogRequestId
network request without logging
QNetworkReply * postToNetwork(const QNetworkRequest &request, int logId, const QByteArray &data, const CallbackSlot &callback)
Post to network.
bool isShuttingDown() const
Is application shutting down?
QNetworkReply * deleteResourceFromNetwork(const QNetworkRequest &request, int logId, const CallbackSlot &callback, int maxRedirects=DefaultMaxRedirects)
Request to delete a network resource from network, supporting swift::misc::network::CUrlLog.
void removeCallsign(const QString &callsign)
Remove callsign from network.
PostCallsignResponseDto addCallsign(const QString &callsign)
Add callsign to network.
void forceDisconnect()
Force disconnect from network.
QVector< StationDto > getAllAliasedStations()
All aliased stations.
void connectTo(const QString &username, const QString &password, const QString &client, const QUuid &networkVersion, ConnectionCallback callback)
Connect to network.
void updateTransceivers(const QString &callsign, const QVector< TransceiverDto > &transceivers)
Update transceivers.
bool setUrl(const QString &url)
Set the URL.
static const QString & vatsimSpecific()
VATSIM specific.
static const QString & audio()
Audio related.
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & debug()
Set the severity to debug.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
Callable wrapper for a member function with function signature F.
Free functions in swift::misc.
SWIFT_MISC_EXPORT bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs)
String compare.
QDateTime addSecs(qint64 s) const const
QDateTime currentDateTimeUtc()
qint64 currentSecsSinceEpoch()
QString errorString() const const
void append(const QJsonValue &value)
bool isEmpty() const const
bool isObject() const const
QJsonObject object() const const
QByteArray toJson(QJsonDocument::JsonFormat format) const const
QJsonValue value(QLatin1StringView key) const const
int toInt(int defaultValue) const const
QNetworkAccessManager::Operation operation() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool isEmpty() const const
const std::string & boolToYesNo(bool t)
Yes/no from bool.
void setPath(const QString &path, QUrl::ParsingMode mode)
QString toString(QUrl::FormattingOptions options) const const
QString toString(QUuid::StringFormat mode) const const