aboutsummaryrefslogtreecommitdiff
path: root/launcher/minecraft/auth/AuthRequest.cpp
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2021-12-04 01:18:05 +0100
committerPetr Mrázek <peterix@gmail.com>2021-12-04 01:18:05 +0100
commit3c46d8a412956a759f61ae802c540ef72d00b35d (patch)
treef16564ba6be96b68ba5257a982c144320fff7911 /launcher/minecraft/auth/AuthRequest.cpp
parentffcef673de9fe848a92d23e02a2abed8df16eb9f (diff)
downloadPrismLauncher-3c46d8a412956a759f61ae802c540ef72d00b35d.tar.gz
PrismLauncher-3c46d8a412956a759f61ae802c540ef72d00b35d.tar.bz2
PrismLauncher-3c46d8a412956a759f61ae802c540ef72d00b35d.zip
GH-4071 Heavily refactor and rearchitect account system
This makes the account system much more modular and makes it treat errors as something recoverable, unless they come directly from the MSA refresh token becoming invalid.
Diffstat (limited to 'launcher/minecraft/auth/AuthRequest.cpp')
-rw-r--r--launcher/minecraft/auth/AuthRequest.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/launcher/minecraft/auth/AuthRequest.cpp b/launcher/minecraft/auth/AuthRequest.cpp
new file mode 100644
index 00000000..459d2354
--- /dev/null
+++ b/launcher/minecraft/auth/AuthRequest.cpp
@@ -0,0 +1,125 @@
+#include <cassert>
+
+#include <QDebug>
+#include <QTimer>
+#include <QBuffer>
+#include <QUrlQuery>
+
+#include "Application.h"
+#include "AuthRequest.h"
+#include "katabasis/Globals.h"
+
+AuthRequest::AuthRequest(QObject *parent): QObject(parent) {
+}
+
+AuthRequest::~AuthRequest() {
+}
+
+void AuthRequest::get(const QNetworkRequest &req, int timeout/* = 60*1000*/) {
+ setup(req, QNetworkAccessManager::GetOperation);
+ reply_ = APPLICATION->network()->get(request_);
+ status_ = Requesting;
+ timedReplies_.add(new Katabasis::Reply(reply_, timeout));
+ connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError)));
+ connect(reply_, SIGNAL(finished()), this, SLOT(onRequestFinished()));
+ connect(reply_, &QNetworkReply::sslErrors, this, &AuthRequest::onSslErrors);
+}
+
+void AuthRequest::post(const QNetworkRequest &req, const QByteArray &data, int timeout/* = 60*1000*/) {
+ setup(req, QNetworkAccessManager::PostOperation);
+ data_ = data;
+ status_ = Requesting;
+ reply_ = APPLICATION->network()->post(request_, data_);
+ timedReplies_.add(new Katabasis::Reply(reply_, timeout));
+ connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError)));
+ connect(reply_, SIGNAL(finished()), this, SLOT(onRequestFinished()));
+ connect(reply_, &QNetworkReply::sslErrors, this, &AuthRequest::onSslErrors);
+ connect(reply_, SIGNAL(uploadProgress(qint64,qint64)), this, SLOT(onUploadProgress(qint64,qint64)));
+}
+
+void AuthRequest::onRequestFinished() {
+ if (status_ == Idle) {
+ return;
+ }
+ if (reply_ != qobject_cast<QNetworkReply *>(sender())) {
+ return;
+ }
+ httpStatus_ = 200;
+ finish();
+}
+
+void AuthRequest::onRequestError(QNetworkReply::NetworkError error) {
+ qWarning() << "AuthRequest::onRequestError: Error" << (int)error;
+ if (status_ == Idle) {
+ return;
+ }
+ if (reply_ != qobject_cast<QNetworkReply *>(sender())) {
+ return;
+ }
+ errorString_ = reply_->errorString();
+ httpStatus_ = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ error_ = error;
+ qWarning() << "AuthRequest::onRequestError: Error string: " << errorString_;
+ qWarning() << "AuthRequest::onRequestError: HTTP status" << httpStatus_ << reply_->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
+
+ // QTimer::singleShot(10, this, SLOT(finish()));
+}
+
+void AuthRequest::onSslErrors(QList<QSslError> errors) {
+ int i = 1;
+ for (auto error : errors) {
+ qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString();
+ auto cert = error.certificate();
+ qCritical() << "Certificate in question:\n" << cert.toText();
+ i++;
+ }
+}
+
+void AuthRequest::onUploadProgress(qint64 uploaded, qint64 total) {
+ if (status_ == Idle) {
+ qWarning() << "AuthRequest::onUploadProgress: No pending request";
+ return;
+ }
+ if (reply_ != qobject_cast<QNetworkReply *>(sender())) {
+ return;
+ }
+ // Restart timeout because request in progress
+ Katabasis::Reply *o2Reply = timedReplies_.find(reply_);
+ if(o2Reply) {
+ o2Reply->start();
+ }
+ emit uploadProgress(uploaded, total);
+}
+
+void AuthRequest::setup(const QNetworkRequest &req, QNetworkAccessManager::Operation operation, const QByteArray &verb) {
+ request_ = req;
+ operation_ = operation;
+ url_ = req.url();
+
+ QUrl url = url_;
+ request_.setUrl(url);
+
+ if (!verb.isEmpty()) {
+ request_.setRawHeader(Katabasis::HTTP_HTTP_HEADER, verb);
+ }
+
+ status_ = Requesting;
+ error_ = QNetworkReply::NoError;
+ errorString_.clear();
+ httpStatus_ = 0;
+}
+
+void AuthRequest::finish() {
+ QByteArray data;
+ if (status_ == Idle) {
+ qWarning() << "AuthRequest::finish: No pending request";
+ return;
+ }
+ data = reply_->readAll();
+ status_ = Idle;
+ timedReplies_.remove(reply_);
+ reply_->disconnect(this);
+ reply_->deleteLater();
+ QList<QNetworkReply::RawHeaderPair> headers = reply_->rawHeaderPairs();
+ emit finished(error_, data, headers);
+}