From 5e5681709ab878f3aa6cf1344af44e8ae9544987 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Thu, 11 Jul 2019 01:55:31 -0400
Subject: reworked the nexus connection panel moved most of the stuff into a
new NexusSSOLogin class
---
src/settingsdialog.cpp | 321 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 237 insertions(+), 84 deletions(-)
(limited to 'src/settingsdialog.cpp')
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 95e4ceb0..d1ace6a5 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -49,6 +49,8 @@ along with Mod Organizer. If not, see .
using namespace MOBase;
+const QString NexusSSO("wss://sso.nexusmods.com");
+const QString NexusSSOPage("https://www.nexusmods.com/sso?id=%1&application=modorganizer2");
class NexusManualKeyDialog : public QDialog
{
@@ -98,35 +100,177 @@ private:
};
+
+NexusSSOLogin::NexusSSOLogin()
+ : m_keyReceived(false), m_active(false)
+{
+ QObject::connect(
+ &m_socket, &QWebSocket::connected,
+ [&]{ onConnected(); });
+
+ QObject::connect(
+ &m_socket, qOverload(&QWebSocket::error),
+ [&](auto&& e){ onError(e); });
+
+ QObject::connect(
+ &m_socket, &QWebSocket::textMessageReceived,
+ [&](auto&& s){ onMessage(s); });
+
+ QObject::connect(
+ &m_socket, &QWebSocket::disconnected,
+ [&]{ onDisconnected(); });
+
+ QObject::connect(&m_timeout, &QTimer::timeout, [&]{ onTimeout(); });
+}
+
+void NexusSSOLogin::start()
+{
+ m_active = true;
+ setState(ConnectingToSSO);
+ m_timeout.start(NXMAccessManager::ValidationTimeout);
+ m_socket.open(NexusSSO);
+}
+
+void NexusSSOLogin::cancel()
+{
+ abort();
+ setState(Cancelled);
+}
+
+void NexusSSOLogin::close()
+{
+ m_active = false;
+ m_timeout.stop();
+ m_socket.close();
+}
+
+void NexusSSOLogin::abort()
+{
+ m_active = false;
+ m_timeout.stop();
+ m_socket.abort();
+}
+
+bool NexusSSOLogin::isActive() const
+{
+ return m_active;
+}
+
+void NexusSSOLogin::setState(States s, const QString& error)
+{
+ if (stateChanged) {
+ stateChanged(s, error);
+ }
+}
+
+void NexusSSOLogin::onConnected()
+{
+ setState(WaitingForToken);
+
+ m_keyReceived = false;
+
+ //if (m_guid.isEmpty()) {
+ boost::uuids::random_generator generator;
+ boost::uuids::uuid sessionId = generator();
+ m_guid = boost::uuids::to_string(sessionId).c_str();
+ //}
+
+ QJsonObject data;
+ data.insert(QString("id"), QJsonValue(m_guid));
+ //data.insert(QString("token"), QJsonValue(m_token));
+ data.insert(QString("protocol"), 2);
+
+ const QString message = QJsonDocument(data).toJson();
+ m_socket.sendTextMessage(message);
+}
+
+void NexusSSOLogin::onMessage(const QString& s)
+{
+ const QJsonDocument doc = QJsonDocument::fromJson(s.toUtf8());
+ const QVariantMap root = doc.object().toVariantMap();
+
+ if (!root["success"].toBool()) {
+ close();
+
+ setState(Error, QString("There was a problem with SSO initialization: %1")
+ .arg(root["error"].toString()));
+
+ return;
+ }
+
+ const QVariantMap data = root["data"].toMap();
+
+ if (data.contains("connection_token")) {
+ // first answer
+ m_token = data["connection_token"].toString();
+
+ // open browser
+ const auto url = NexusSSOPage.arg(m_guid);
+ shell::OpenLink(url);
+
+ m_timeout.stop();
+ setState(WaitingForBrowser);
+ } else {
+ // second answer
+ const auto key = data["api_key"].toString();
+ close();
+
+ if (keyChanged) {
+ keyChanged(key);
+ }
+
+ setState(Finished);
+ }
+}
+
+void NexusSSOLogin::onDisconnected()
+{
+ if (m_active) {
+ m_active = false;
+
+ if (!m_keyReceived) {
+ setState(ClosedByRemote);
+ }
+ }
+}
+
+void NexusSSOLogin::onError(QAbstractSocket::SocketError e)
+{
+ if (m_active) {
+ setState(Error, m_socket.errorString());
+ }
+}
+
+void NexusSSOLogin::onTimeout()
+{
+ abort();
+ setState(Timeout);
+}
+
+
SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* settings, QWidget *parent)
: TutorableDialog("SettingsDialog", parent)
, ui(new Ui::SettingsDialog)
, m_settings(settings)
, m_PluginContainer(pluginContainer)
- , m_nexusLogin(new QWebSocket)
- , m_KeyReceived(false)
- , m_KeyCleared(false)
+ , m_keyChanged(false)
, m_GeometriesReset(false)
{
+ m_nexusLogin.keyChanged = [&](auto&& s){ onKeyChanged(s); };
+ m_nexusLogin.stateChanged = [&](auto&& s, auto&& e){ onStateChanged(s, e); };
+
ui->setupUi(this);
ui->pluginSettingsList->setStyleSheet("QTreeWidget::item {padding-right: 10px;}");
QShortcut *delShortcut
= new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem()));
- connect(m_nexusLogin, SIGNAL(connected()), this, SLOT(dispatchLogin()));
- connect(m_nexusLogin, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(authError(QAbstractSocket::SocketError)));
- connect(m_nexusLogin, SIGNAL(textMessageReceived(const QString &)), this, SLOT(receiveApiKey(const QString &)));
- connect(m_nexusLogin, SIGNAL(disconnected()), this, SLOT(completeApiConnection()));
- m_loginTimer.callOnTimeout(this, &SettingsDialog::loginPing);
updateNexusButtons();
}
SettingsDialog::~SettingsDialog()
{
- m_loginTimer.stop();
- m_nexusLogin->close();
disconnect(this);
delete ui;
}
@@ -188,7 +332,7 @@ bool SettingsDialog::getResetGeometries()
bool SettingsDialog::getApiKeyChanged()
{
- return m_KeyReceived || m_KeyCleared;
+ return m_keyChanged;
}
void SettingsDialog::on_categoriesBtn_clicked()
@@ -391,7 +535,11 @@ void SettingsDialog::on_resetDialogsButton_clicked()
void SettingsDialog::on_nexusConnect_clicked()
{
- fetchNexusApiKey();
+ if (m_nexusLogin.isActive()) {
+ m_nexusLogin.cancel();
+ } else {
+ fetchNexusApiKey();
+ }
}
void SettingsDialog::on_nexusManualKey_clicked()
@@ -415,92 +563,95 @@ void SettingsDialog::on_nexusManualKey_clicked()
void SettingsDialog::fetchNexusApiKey()
{
- QUrl url = QUrl("wss://sso.nexusmods.com");
- m_nexusLogin->open(url);
+ ui->nexusLog->clear();
+ m_nexusLogin.start();
updateNexusButtons();
}
-void SettingsDialog::dispatchLogin()
+void SettingsDialog::onKeyChanged(const QString& key)
{
- m_KeyReceived = false;
- QJsonObject login;
- if (m_UUID.isEmpty()) {
- boost::uuids::random_generator generator;
- boost::uuids::uuid sessionId = generator();
- m_UUID = boost::uuids::to_string(sessionId).c_str();
+ if (key.isEmpty()) {
+ clearKey();
+ } else {
+ setKey(key);
}
- login.insert(QString("id"), QJsonValue(m_UUID));
- login.insert(QString("token"), QJsonValue(m_AuthToken));
- login.insert(QString("protocol"), 2);
- QJsonDocument loginDoc(login);
- QString finalMessage(loginDoc.toJson());
- m_nexusLogin->sendTextMessage(finalMessage);
- QDesktopServices::openUrl(QUrl(QString("https://www.nexusmods.com/sso?id=%1&application=%2").arg(m_UUID).arg("modorganizer2")));
- m_loginTimer.start(30000);
}
-void SettingsDialog::loginPing()
+void SettingsDialog::onStateChanged(NexusSSOLogin::States s, const QString& e)
{
- if (m_nexusLogin->isValid()) {
- m_nexusLogin->ping();
- m_totalPings++;
- }
- if (m_totalPings >= 60) {
- m_loginTimer.stop();
- m_totalPings = 0;
- m_nexusLogin->close(QWebSocketProtocol::CloseCodeGoingAway, "Timeout: No response received after thirty minutes. Cancelling request.");
- }
-}
+ QString log;
-void SettingsDialog::authError(QAbstractSocket::SocketError error)
-{
- auto errorInfo = m_nexusLogin->errorString();
- qCritical() << "An error occurred: " << errorInfo;
-}
+ switch (s)
+ {
+ case NexusSSOLogin::Idle:
+ {
+ break;
+ }
-void SettingsDialog::receiveApiKey(const QString &response)
-{
- QJsonDocument responseDoc = QJsonDocument::fromJson(response.toUtf8());
- QVariantMap responseData = responseDoc.object().toVariantMap();
- if (responseData["success"].toBool()) {
- QVariantMap data = responseData["data"].toMap();
- if (data.contains("connection_token")) {
- m_AuthToken = data["connection_token"].toString();
- } else {
- const auto key = data["api_key"].toString();
+ case NexusSSOLogin::ConnectingToSSO:
+ {
+ log = tr("Connecting to Nexus...");
+ break;
+ }
+
+ case NexusSSOLogin::WaitingForToken:
+ {
+ log = tr("Waiting for Nexus...");
+ break;
+ }
- m_nexusLogin->close();
- m_loginTimer.stop();
- m_totalPings = 0;
+ case NexusSSOLogin::WaitingForBrowser:
+ {
+ log = tr("Opened browser, waiting for user...");
+ break;
+ }
- if (key.isEmpty()) {
- clearKey();
- } else {
- setKey(key);
- }
+ case NexusSSOLogin::Finished:
+ {
+ log = tr("Connected.");
+ break;
}
- } else {
- QString error("There was a problem with SSO initialization: %1");
- qCritical() << error.arg(responseData["error"].toString());
- m_nexusLogin->close();
- }
-}
-void SettingsDialog::completeApiConnection()
-{
- if (!m_KeyReceived && !m_loginTimer.isActive()) {
- QMessageBox::warning(qApp->activeWindow(), tr("Error"),
- tr("Failed to retrieve a Nexus API key! Please try again. "
- "A browser window should open asking you to authorize."));
+ case NexusSSOLogin::Timeout:
+ {
+ log = QObject::tr(
+ "No answer from Nexus.\n"
+ "A firewall might be blocking Mod Organizer.");
- // try again
- fetchNexusApiKey();
+ break;
+ }
+
+ case NexusSSOLogin::ClosedByRemote:
+ {
+ log = QObject::tr("Nexus closed the connection.");
+ break;
+ }
+
+ case NexusSSOLogin::Cancelled:
+ {
+ log = QObject::tr("Cancelled.");
+ break;
+ }
+
+ case NexusSSOLogin::Error:
+ {
+ log = tr("Error: %1.").arg(e);
+ break;
+ }
}
+
+ if (!log.isEmpty()) {
+ for (auto&& line : log.split("\n")) {
+ ui->nexusLog->addItem(line);
+ }
+ }
+
+ updateNexusButtons();
}
bool SettingsDialog::setKey(const QString& key)
{
- m_KeyReceived = true;
+ m_keyChanged = true;
const bool ret = m_settings->setNexusApiKey(key);
updateNexusButtons();
return ret;
@@ -508,7 +659,7 @@ bool SettingsDialog::setKey(const QString& key)
bool SettingsDialog::clearKey()
{
- m_KeyCleared = true;
+ m_keyChanged = true;
const auto ret = m_settings->clearNexusApiKey();
updateNexusButtons();
@@ -530,22 +681,22 @@ void SettingsDialog::testApiKey()
void SettingsDialog::updateNexusButtons()
{
- if (m_nexusLogin->state() != QAbstractSocket::UnconnectedState) {
+ if (m_nexusLogin.isActive()) {
// api key is in the process of being retrieved
- ui->nexusConnect->setText("Connecting the API. Please login within the browser and accept the request. This will time out after 30 minutes.");
- ui->nexusConnect->setEnabled(false);
+ ui->nexusConnect->setText(tr("Cancel"));
+ ui->nexusConnect->setEnabled(true);
ui->nexusDisconnect->setEnabled(false);
ui->nexusManualKey->setEnabled(false);
}
else if (m_settings->hasNexusApiKey()) {
// api key is present
- ui->nexusConnect->setText("Nexus API Key Stored");
+ ui->nexusConnect->setText(tr("Connect to Nexus"));
ui->nexusConnect->setEnabled(false);
ui->nexusDisconnect->setEnabled(true);
ui->nexusManualKey->setEnabled(false);
} else {
// api key not present
- ui->nexusConnect->setText("Connect to Nexus");
+ ui->nexusConnect->setText(tr("Connect to Nexus"));
ui->nexusConnect->setEnabled(true);
ui->nexusDisconnect->setEnabled(false);
ui->nexusManualKey->setEnabled(true);
@@ -622,6 +773,8 @@ void SettingsDialog::on_clearCacheButton_clicked()
void SettingsDialog::on_nexusDisconnect_clicked()
{
clearKey();
+ ui->nexusLog->clear();
+ ui->nexusLog->addItem(tr("Disconnected."));
}
void SettingsDialog::normalizePath(QLineEdit *lineEdit)
--
cgit v1.3.1
From ad29525e982f83343dbd70e17b914e0a30adb662 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Thu, 11 Jul 2019 02:31:59 -0400
Subject: moved NexusSSOLogin to nxmaccessmanager added logs for manual key
validation, will need to rewrite a few things
---
src/nxmaccessmanager.cpp | 166 +++++++++++++++++++++++++++++++++++++--
src/nxmaccessmanager.h | 64 ++++++++++++++-
src/settingsdialog.cpp | 198 +++++++----------------------------------------
src/settingsdialog.h | 52 +------------
4 files changed, 250 insertions(+), 230 deletions(-)
(limited to 'src/settingsdialog.cpp')
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index 8bbfd536..a274261d 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -44,6 +44,8 @@ using namespace std::chrono_literals;
const QString NexusBaseUrl("https://api.nexusmods.com/v1");
const std::chrono::seconds NXMAccessManager::ValidationTimeout = 10s;
+const QString NexusSSO("wss://sso.nexusmods.com");
+const QString NexusSSOPage("https://www.nexusmods.com/sso?id=%1&application=modorganizer2");
ValidationProgressDialog::ValidationProgressDialog(std::chrono::seconds t)
@@ -94,7 +96,10 @@ void ValidationProgressDialog::start()
void ValidationProgressDialog::stop()
{
- m_timer->stop();
+ if (m_timer) {
+ m_timer->stop();
+ }
+
hide();
}
@@ -119,6 +124,153 @@ void ValidationProgressDialog::onTimer()
}
+NexusSSOLogin::NexusSSOLogin()
+ : m_keyReceived(false), m_active(false)
+{
+ QObject::connect(
+ &m_socket, &QWebSocket::connected,
+ [&]{ onConnected(); });
+
+ QObject::connect(
+ &m_socket, qOverload(&QWebSocket::error),
+ [&](auto&& e){ onError(e); });
+
+ QObject::connect(
+ &m_socket, &QWebSocket::textMessageReceived,
+ [&](auto&& s){ onMessage(s); });
+
+ QObject::connect(
+ &m_socket, &QWebSocket::disconnected,
+ [&]{ onDisconnected(); });
+
+ QObject::connect(&m_timeout, &QTimer::timeout, [&]{ onTimeout(); });
+}
+
+void NexusSSOLogin::start()
+{
+ m_active = true;
+ setState(ConnectingToSSO);
+ m_timeout.start(NXMAccessManager::ValidationTimeout);
+ m_socket.open(NexusSSO);
+}
+
+void NexusSSOLogin::cancel()
+{
+ abort();
+ setState(Cancelled);
+}
+
+void NexusSSOLogin::close()
+{
+ m_active = false;
+ m_timeout.stop();
+ m_socket.close();
+}
+
+void NexusSSOLogin::abort()
+{
+ m_active = false;
+ m_timeout.stop();
+ m_socket.abort();
+}
+
+bool NexusSSOLogin::isActive() const
+{
+ return m_active;
+}
+
+void NexusSSOLogin::setState(States s, const QString& error)
+{
+ if (stateChanged) {
+ stateChanged(s, error);
+ }
+}
+
+void NexusSSOLogin::onConnected()
+{
+ setState(WaitingForToken);
+
+ m_keyReceived = false;
+
+ //if (m_guid.isEmpty()) {
+ boost::uuids::random_generator generator;
+ boost::uuids::uuid sessionId = generator();
+ m_guid = boost::uuids::to_string(sessionId).c_str();
+ //}
+
+ QJsonObject data;
+ data.insert(QString("id"), QJsonValue(m_guid));
+ //data.insert(QString("token"), QJsonValue(m_token));
+ data.insert(QString("protocol"), 2);
+
+ const QString message = QJsonDocument(data).toJson();
+ m_socket.sendTextMessage(message);
+}
+
+void NexusSSOLogin::onMessage(const QString& s)
+{
+ const QJsonDocument doc = QJsonDocument::fromJson(s.toUtf8());
+ const QVariantMap root = doc.object().toVariantMap();
+
+ if (!root["success"].toBool()) {
+ close();
+
+ setState(Error, QString("There was a problem with SSO initialization: %1")
+ .arg(root["error"].toString()));
+
+ return;
+ }
+
+ const QVariantMap data = root["data"].toMap();
+
+ if (data.contains("connection_token")) {
+ // first answer
+ m_token = data["connection_token"].toString();
+
+ // open browser
+ const auto url = NexusSSOPage.arg(m_guid);
+ shell::OpenLink(url);
+
+ m_timeout.stop();
+ setState(WaitingForBrowser);
+ } else {
+ // second answer
+ const auto key = data["api_key"].toString();
+ close();
+
+ if (keyChanged) {
+ keyChanged(key);
+ }
+
+ setState(Finished);
+ }
+}
+
+void NexusSSOLogin::onDisconnected()
+{
+ if (m_active) {
+ m_active = false;
+
+ if (!m_keyReceived) {
+ setState(ClosedByRemote);
+ }
+ }
+}
+
+void NexusSSOLogin::onError(QAbstractSocket::SocketError e)
+{
+ if (m_active) {
+ setState(Error, m_socket.errorString());
+ }
+}
+
+void NexusSSOLogin::onTimeout()
+{
+ abort();
+ setState(Timeout);
+}
+
+
NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion)
: QNetworkAccessManager(parent)
, m_ValidateReply(nullptr)
@@ -192,7 +344,7 @@ void NXMAccessManager::clearCookies()
}
}
-void NXMAccessManager::startValidationCheck()
+void NXMAccessManager::startValidationCheck(bool showProgress)
{
qDebug("Checking Nexus API Key...");
QString requestString = NexusBaseUrl + "/users/validate";
@@ -205,7 +357,9 @@ void NXMAccessManager::startValidationCheck()
request.setRawHeader("Application-Name", "MO2");
request.setRawHeader("Application-Version", m_MOVersion.toUtf8());
- m_ProgressDialog->start();
+ if (showProgress) {
+ m_ProgressDialog->start();
+ }
QCoreApplication::processEvents(); // for some reason the whole app hangs during the login. This way the user has at least a little feedback
@@ -245,13 +399,13 @@ bool NXMAccessManager::validateWaiting() const
}
-void NXMAccessManager::apiCheck(const QString &apiKey, bool force)
+void NXMAccessManager::apiCheck(const QString &apiKey, ApiCheckFlags flags)
{
if (m_ValidateReply != nullptr) {
return;
}
- if (force) {
+ if (flags & Force) {
m_ValidateState = VALIDATE_NOT_CHECKED;
}
@@ -261,7 +415,7 @@ void NXMAccessManager::apiCheck(const QString &apiKey, bool force)
}
m_ApiKey = apiKey;
- startValidationCheck();
+ startValidationCheck((flags & HideProgress) == 0);
}
diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h
index cbec0530..08a799f9 100644
--- a/src/nxmaccessmanager.h
+++ b/src/nxmaccessmanager.h
@@ -27,6 +27,7 @@ along with Mod Organizer. If not, see .
#include
#include
#include
+#include
#include
namespace MOBase { class IPluginGame; }
@@ -60,6 +61,52 @@ private:
};
+class NexusSSOLogin
+{
+public:
+ enum States
+ {
+ ConnectingToSSO,
+ WaitingForToken,
+ WaitingForBrowser,
+ Finished,
+ Timeout,
+ ClosedByRemote,
+ Cancelled,
+ Error
+ };
+
+ std::function keyChanged;
+ std::function stateChanged;
+
+ NexusSSOLogin();
+
+ void start();
+ void cancel();
+
+ bool isActive() const;
+
+private:
+ QWebSocket m_socket;
+ QString m_guid;
+ bool m_keyReceived;
+ QString m_token;
+ bool m_active;
+ QTimer m_timeout;
+
+ void setState(States s, const QString& error={});
+
+ void close();
+ void abort();
+
+ void onConnected();
+ void onMessage(const QString& s);
+ void onDisconnected();
+ void onError(QAbstractSocket::SocketError e);
+ void onTimeout();
+};
+
+
/**
* @brief access manager extended to handle nxm links
**/
@@ -67,6 +114,15 @@ class NXMAccessManager : public QNetworkAccessManager
{
Q_OBJECT
public:
+ enum ApiCheckFlagsEnum
+ {
+ NoFlags = 0,
+ Force,
+ HideProgress
+ };
+
+ Q_DECLARE_FLAGS(ApiCheckFlags, ApiCheckFlagsEnum)
+
static const std::chrono::seconds ValidationTimeout;
explicit NXMAccessManager(QObject *parent, const QString &moVersion);
@@ -80,7 +136,7 @@ public:
bool validateAttempted() const;
bool validateWaiting() const;
- void apiCheck(const QString &apiKey, bool force=false);
+ void apiCheck(const QString &apiKey, ApiCheckFlags flags=NoFlags);
void showCookies() const;
@@ -91,8 +147,6 @@ public:
QString apiKey() const;
void clearApiKey();
- void startValidationCheck();
-
void refuseValidation();
signals:
@@ -145,6 +199,10 @@ private:
VALIDATE_REFUSED,
VALIDATE_VALID
} m_ValidateState = VALIDATE_NOT_CHECKED;
+
+ void startValidationCheck(bool showProgress);
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(NXMAccessManager::ApiCheckFlags);
+
#endif // NXMACCESSMANAGER_H
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index d1ace6a5..0131d20b 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -28,7 +28,6 @@ along with Mod Organizer. If not, see .
#include "settings.h"
#include "instancemanager.h"
#include "nexusinterface.h"
-#include "nxmaccessmanager.h"
#include "plugincontainer.h"
#include
@@ -49,9 +48,6 @@ along with Mod Organizer. If not, see .
using namespace MOBase;
-const QString NexusSSO("wss://sso.nexusmods.com");
-const QString NexusSSOPage("https://www.nexusmods.com/sso?id=%1&application=modorganizer2");
-
class NexusManualKeyDialog : public QDialog
{
public:
@@ -100,154 +96,6 @@ private:
};
-
-NexusSSOLogin::NexusSSOLogin()
- : m_keyReceived(false), m_active(false)
-{
- QObject::connect(
- &m_socket, &QWebSocket::connected,
- [&]{ onConnected(); });
-
- QObject::connect(
- &m_socket, qOverload(&QWebSocket::error),
- [&](auto&& e){ onError(e); });
-
- QObject::connect(
- &m_socket, &QWebSocket::textMessageReceived,
- [&](auto&& s){ onMessage(s); });
-
- QObject::connect(
- &m_socket, &QWebSocket::disconnected,
- [&]{ onDisconnected(); });
-
- QObject::connect(&m_timeout, &QTimer::timeout, [&]{ onTimeout(); });
-}
-
-void NexusSSOLogin::start()
-{
- m_active = true;
- setState(ConnectingToSSO);
- m_timeout.start(NXMAccessManager::ValidationTimeout);
- m_socket.open(NexusSSO);
-}
-
-void NexusSSOLogin::cancel()
-{
- abort();
- setState(Cancelled);
-}
-
-void NexusSSOLogin::close()
-{
- m_active = false;
- m_timeout.stop();
- m_socket.close();
-}
-
-void NexusSSOLogin::abort()
-{
- m_active = false;
- m_timeout.stop();
- m_socket.abort();
-}
-
-bool NexusSSOLogin::isActive() const
-{
- return m_active;
-}
-
-void NexusSSOLogin::setState(States s, const QString& error)
-{
- if (stateChanged) {
- stateChanged(s, error);
- }
-}
-
-void NexusSSOLogin::onConnected()
-{
- setState(WaitingForToken);
-
- m_keyReceived = false;
-
- //if (m_guid.isEmpty()) {
- boost::uuids::random_generator generator;
- boost::uuids::uuid sessionId = generator();
- m_guid = boost::uuids::to_string(sessionId).c_str();
- //}
-
- QJsonObject data;
- data.insert(QString("id"), QJsonValue(m_guid));
- //data.insert(QString("token"), QJsonValue(m_token));
- data.insert(QString("protocol"), 2);
-
- const QString message = QJsonDocument(data).toJson();
- m_socket.sendTextMessage(message);
-}
-
-void NexusSSOLogin::onMessage(const QString& s)
-{
- const QJsonDocument doc = QJsonDocument::fromJson(s.toUtf8());
- const QVariantMap root = doc.object().toVariantMap();
-
- if (!root["success"].toBool()) {
- close();
-
- setState(Error, QString("There was a problem with SSO initialization: %1")
- .arg(root["error"].toString()));
-
- return;
- }
-
- const QVariantMap data = root["data"].toMap();
-
- if (data.contains("connection_token")) {
- // first answer
- m_token = data["connection_token"].toString();
-
- // open browser
- const auto url = NexusSSOPage.arg(m_guid);
- shell::OpenLink(url);
-
- m_timeout.stop();
- setState(WaitingForBrowser);
- } else {
- // second answer
- const auto key = data["api_key"].toString();
- close();
-
- if (keyChanged) {
- keyChanged(key);
- }
-
- setState(Finished);
- }
-}
-
-void NexusSSOLogin::onDisconnected()
-{
- if (m_active) {
- m_active = false;
-
- if (!m_keyReceived) {
- setState(ClosedByRemote);
- }
- }
-}
-
-void NexusSSOLogin::onError(QAbstractSocket::SocketError e)
-{
- if (m_active) {
- setState(Error, m_socket.errorString());
- }
-}
-
-void NexusSSOLogin::onTimeout()
-{
- abort();
- setState(Timeout);
-}
-
-
SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* settings, QWidget *parent)
: TutorableDialog("SettingsDialog", parent)
, ui(new Ui::SettingsDialog)
@@ -259,11 +107,22 @@ SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* setti
m_nexusLogin.keyChanged = [&](auto&& s){ onKeyChanged(s); };
m_nexusLogin.stateChanged = [&](auto&& s, auto&& e){ onStateChanged(s, e); };
+ connect(
+ NexusInterface::instance(m_PluginContainer)->getAccessManager(),
+ &NXMAccessManager::validateSuccessful,
+ [&]{ onManualKeyValidation(true, ""); });
+
+ connect(
+ NexusInterface::instance(m_PluginContainer)->getAccessManager(),
+ &NXMAccessManager::validateFailed,
+ [&](auto&& e){ onManualKeyValidation(false, e); });
+
+
ui->setupUi(this);
ui->pluginSettingsList->setStyleSheet("QTreeWidget::item {padding-right: 10px;}");
- QShortcut *delShortcut
- = new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
+ QShortcut *delShortcut = new QShortcut(
+ QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem()));
updateNexusButtons();
@@ -556,7 +415,11 @@ void SettingsDialog::on_nexusManualKey_clicked()
clearKey();
} else {
if (setKey(key)) {
- testApiKey();
+ ui->nexusLog->clear();
+ ui->nexusLog->addItem(tr("Checking API key..."));
+
+ NexusInterface::instance(m_PluginContainer)->getAccessManager()->apiCheck(
+ key, NXMAccessManager::Force | NXMAccessManager::HideProgress);
}
}
}
@@ -583,11 +446,6 @@ void SettingsDialog::onStateChanged(NexusSSOLogin::States s, const QString& e)
switch (s)
{
- case NexusSSOLogin::Idle:
- {
- break;
- }
-
case NexusSSOLogin::ConnectingToSSO:
{
log = tr("Connecting to Nexus...");
@@ -649,6 +507,15 @@ void SettingsDialog::onStateChanged(NexusSSOLogin::States s, const QString& e)
updateNexusButtons();
}
+void SettingsDialog::onManualKeyValidation(bool success, const QString& e)
+{
+ if (success) {
+ ui->nexusLog->addItem("Connected.");
+ } else {
+ ui->nexusLog->addItem("Error: " + e);
+ }
+}
+
bool SettingsDialog::setKey(const QString& key)
{
m_keyChanged = true;
@@ -668,17 +535,6 @@ bool SettingsDialog::clearKey()
return ret;
}
-void SettingsDialog::testApiKey()
-{
- QString key;
- if (!m_settings->getNexusApiKey(key)) {
- qWarning().nospace() << "can't test API key, nothing stored";
- return;
- }
-
- NexusInterface::instance(m_PluginContainer)->getAccessManager()->apiCheck(key, true);
-}
-
void SettingsDialog::updateNexusButtons()
{
if (m_nexusLogin.isActive()) {
diff --git a/src/settingsdialog.h b/src/settingsdialog.h
index aee447d7..507214dd 100644
--- a/src/settingsdialog.h
+++ b/src/settingsdialog.h
@@ -21,12 +21,9 @@ along with Mod Organizer. If not, see .
#define SETTINGSDIALOG_H
#include "tutorabledialog.h"
+#include "nxmaccessmanager.h"
#include
-#include
-#include
-#include
#include
-#include
class PluginContainer;
class Settings;
@@ -35,51 +32,6 @@ namespace Ui {
class SettingsDialog;
}
-class NexusSSOLogin
-{
-public:
- enum States
- {
- Idle,
- ConnectingToSSO,
- WaitingForToken,
- WaitingForBrowser,
- Finished,
- Timeout,
- ClosedByRemote,
- Cancelled,
- Error
- };
-
- std::function keyChanged;
- std::function stateChanged;
-
- NexusSSOLogin();
-
- void start();
- void cancel();
-
- bool isActive() const;
-
-private:
- QWebSocket m_socket;
- QString m_guid;
- bool m_keyReceived;
- QString m_token;
- bool m_active;
- QTimer m_timeout;
-
- void setState(States s, const QString& error={});
-
- void close();
- void abort();
-
- void onConnected();
- void onMessage(const QString& s);
- void onDisconnected();
- void onError(QAbstractSocket::SocketError e);
- void onTimeout();
-};
/**
* dialog used to change settings for Mod Organizer. On top of the
@@ -197,9 +149,9 @@ private:
void updateNexusButtons();
void fetchNexusApiKey();
- void testApiKey();
void onKeyChanged(const QString& key);
void onStateChanged(NexusSSOLogin::States s, const QString& e);
+ void onManualKeyValidation(bool success, const QString& e);
};
#endif // SETTINGSDIALOG_H
--
cgit v1.3.1
From 226372dba2f8a06ef2349a331da91010d97e72bf Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Thu, 11 Jul 2019 05:33:35 -0400
Subject: api key validator in settings
---
src/nxmaccessmanager.cpp | 4 +-
src/settingsdialog.cpp | 161 +++++++++++++++++++++++++++++++++++------------
src/settingsdialog.h | 12 ++--
3 files changed, 129 insertions(+), 48 deletions(-)
(limited to 'src/settingsdialog.cpp')
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index c0a6c227..40ab19b9 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -313,7 +313,7 @@ void NexusKeyValidator::start(const QString& key)
return;
}
- qDebug("Checking Nexus API Key...");
+ m_active = true;
setState(Connecting);
const QString requestUrl(NexusBaseUrl + "/users/validate");
@@ -328,11 +328,11 @@ void NexusKeyValidator::start(const QString& key)
m_reply = m_manager.get(request);
if (!m_reply) {
+ close();
setState(Error, QObject::tr("Failed to request %1").arg(requestUrl));
return;
}
- m_active = true;
m_timeout.start(NXMAccessManager::ValidationTimeout);
QObject::connect(
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 0131d20b..12dbc482 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -104,20 +104,6 @@ SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* setti
, m_keyChanged(false)
, m_GeometriesReset(false)
{
- m_nexusLogin.keyChanged = [&](auto&& s){ onKeyChanged(s); };
- m_nexusLogin.stateChanged = [&](auto&& s, auto&& e){ onStateChanged(s, e); };
-
- connect(
- NexusInterface::instance(m_PluginContainer)->getAccessManager(),
- &NXMAccessManager::validateSuccessful,
- [&]{ onManualKeyValidation(true, ""); });
-
- connect(
- NexusInterface::instance(m_PluginContainer)->getAccessManager(),
- &NXMAccessManager::validateFailed,
- [&](auto&& e){ onManualKeyValidation(false, e); });
-
-
ui->setupUi(this);
ui->pluginSettingsList->setStyleSheet("QTreeWidget::item {padding-right: 10px;}");
@@ -394,44 +380,66 @@ void SettingsDialog::on_resetDialogsButton_clicked()
void SettingsDialog::on_nexusConnect_clicked()
{
- if (m_nexusLogin.isActive()) {
- m_nexusLogin.cancel();
- } else {
- fetchNexusApiKey();
+ if (m_nexusLogin && m_nexusLogin->isActive()) {
+ m_nexusLogin->cancel();
+ return;
}
+
+ if (!m_nexusLogin) {
+ m_nexusLogin.reset(new NexusSSOLogin);
+
+ m_nexusLogin->keyChanged = [&](auto&& s){
+ onSSOKeyChanged(s);
+ };
+
+ m_nexusLogin->stateChanged = [&](auto&& s, auto&& e){
+ onSSOStateChanged(s, e);
+ };
+ }
+
+ ui->nexusLog->clear();
+ m_nexusLogin->start();
+ updateNexusButtons();
}
void SettingsDialog::on_nexusManualKey_clicked()
{
- NexusManualKeyDialog dialog(this);
+ if (m_nexusValidator && m_nexusValidator->isActive()) {
+ m_nexusValidator->cancel();
+ return;
+ }
+ NexusManualKeyDialog dialog(this);
if (dialog.exec() != QDialog::Accepted) {
return;
}
const auto key = dialog.key();
-
if (key.isEmpty()) {
clearKey();
- } else {
- if (setKey(key)) {
- ui->nexusLog->clear();
- ui->nexusLog->addItem(tr("Checking API key..."));
-
- NexusInterface::instance(m_PluginContainer)->getAccessManager()->apiCheck(
- key, NXMAccessManager::Force | NXMAccessManager::HideProgress);
- }
+ return;
}
-}
-void SettingsDialog::fetchNexusApiKey()
-{
ui->nexusLog->clear();
- m_nexusLogin.start();
- updateNexusButtons();
+ ui->nexusLog->addItem(tr("Checking API key..."));
+
+ if (!m_nexusValidator) {
+ m_nexusValidator.reset(new NexusKeyValidator(
+ *NexusInterface::instance(m_PluginContainer)->getAccessManager()));
+
+ m_nexusValidator->stateChanged = [&](auto&& s, auto&& e){
+ onValidatorStateChanged(s, e);
+ };
+
+ m_nexusValidator->finished = [&](auto&& user) {
+ onValidatorFinished(user);
+ };
+ }
+
+ m_nexusValidator->start(key);
}
-void SettingsDialog::onKeyChanged(const QString& key)
+void SettingsDialog::onSSOKeyChanged(const QString& key)
{
if (key.isEmpty()) {
clearKey();
@@ -440,7 +448,7 @@ void SettingsDialog::onKeyChanged(const QString& key)
}
}
-void SettingsDialog::onStateChanged(NexusSSOLogin::States s, const QString& e)
+void SettingsDialog::onSSOStateChanged(NexusSSOLogin::States s, const QString& e)
{
QString log;
@@ -507,12 +515,72 @@ void SettingsDialog::onStateChanged(NexusSSOLogin::States s, const QString& e)
updateNexusButtons();
}
-void SettingsDialog::onManualKeyValidation(bool success, const QString& e)
+void SettingsDialog::onValidatorStateChanged(
+ NexusKeyValidator::States s, const QString& e)
{
- if (success) {
- ui->nexusLog->addItem("Connected.");
- } else {
- ui->nexusLog->addItem("Error: " + e);
+ QString log;
+
+ switch (s)
+ {
+ case NexusKeyValidator::Connecting:
+ {
+ log = tr("Connecting to Nexus...");
+ break;
+ }
+
+ case NexusKeyValidator::Finished:
+ {
+ log = tr("Connected.");
+ break;
+ }
+
+ case NexusKeyValidator::InvalidJson:
+ {
+ log = tr("Invalid JSON");
+ break;
+ }
+
+ case NexusKeyValidator::BadResponse:
+ {
+ log = tr("Bad response");
+ break;
+ }
+
+ case NexusKeyValidator::Timeout:
+ {
+ log = QObject::tr(
+ "No answer from Nexus.\n"
+ "A firewall might be blocking Mod Organizer.");
+
+ break;
+ }
+
+ case NexusKeyValidator::Cancelled:
+ {
+ log = QObject::tr("Cancelled.");
+ break;
+ }
+
+ case NexusKeyValidator::Error:
+ {
+ log = tr("Error: %1.").arg(e);
+ break;
+ }
+ }
+
+ if (!log.isEmpty()) {
+ for (auto&& line : log.split("\n")) {
+ ui->nexusLog->addItem(line);
+ }
+ }
+
+ updateNexusButtons();
+}
+
+void SettingsDialog::onValidatorFinished(const APIUserAccount& user)
+{
+ if (!user.apiKey().isEmpty()) {
+ setKey(user.apiKey());
}
}
@@ -537,24 +605,35 @@ bool SettingsDialog::clearKey()
void SettingsDialog::updateNexusButtons()
{
- if (m_nexusLogin.isActive()) {
+ if (m_nexusLogin && m_nexusLogin->isActive()) {
// api key is in the process of being retrieved
ui->nexusConnect->setText(tr("Cancel"));
ui->nexusConnect->setEnabled(true);
ui->nexusDisconnect->setEnabled(false);
+ ui->nexusManualKey->setText(tr("Enter API Key Manually"));
ui->nexusManualKey->setEnabled(false);
}
+ else if (m_nexusValidator && m_nexusValidator->isActive()) {
+ // api key is in the process of being tested
+ ui->nexusConnect->setText(tr("Connect to Nexus"));
+ ui->nexusConnect->setEnabled(false);
+ ui->nexusDisconnect->setEnabled(false);
+ ui->nexusManualKey->setText(tr("Cancel"));
+ ui->nexusManualKey->setEnabled(true);
+ }
else if (m_settings->hasNexusApiKey()) {
// api key is present
ui->nexusConnect->setText(tr("Connect to Nexus"));
ui->nexusConnect->setEnabled(false);
ui->nexusDisconnect->setEnabled(true);
+ ui->nexusManualKey->setText(tr("Enter API Key Manually"));
ui->nexusManualKey->setEnabled(false);
} else {
// api key not present
ui->nexusConnect->setText(tr("Connect to Nexus"));
ui->nexusConnect->setEnabled(true);
ui->nexusDisconnect->setEnabled(false);
+ ui->nexusManualKey->setText(tr("Enter API Key Manually"));
ui->nexusManualKey->setEnabled(true);
}
}
diff --git a/src/settingsdialog.h b/src/settingsdialog.h
index 507214dd..1741fc13 100644
--- a/src/settingsdialog.h
+++ b/src/settingsdialog.h
@@ -142,16 +142,18 @@ private:
bool m_keyChanged;
QString m_ExecutableBlacklist;
- NexusSSOLogin m_nexusLogin;
+ std::unique_ptr m_nexusLogin;
+ std::unique_ptr m_nexusValidator;
bool setKey(const QString& key);
bool clearKey();
void updateNexusButtons();
- void fetchNexusApiKey();
- void onKeyChanged(const QString& key);
- void onStateChanged(NexusSSOLogin::States s, const QString& e);
- void onManualKeyValidation(bool success, const QString& e);
+ void onSSOKeyChanged(const QString& key);
+ void onSSOStateChanged(NexusSSOLogin::States s, const QString& e);
+
+ void onValidatorStateChanged(NexusKeyValidator::States s, const QString& e);
+ void onValidatorFinished(const APIUserAccount& user);
};
#endif // SETTINGSDIALOG_H
--
cgit v1.3.1
From be1ee2a97c867a80c07c4b865c306977d96249dc Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Thu, 11 Jul 2019 05:49:12 -0400
Subject: refactored state messages
---
src/nxmaccessmanager.cpp | 125 ++++++++++++++++++++++++++++++-----------------
src/nxmaccessmanager.h | 5 +-
src/settingsdialog.cpp | 118 +++-----------------------------------------
3 files changed, 90 insertions(+), 158 deletions(-)
(limited to 'src/settingsdialog.cpp')
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index 40ab19b9..a331b2e8 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -153,6 +153,45 @@ NexusSSOLogin::NexusSSOLogin()
QObject::connect(&m_timeout, &QTimer::timeout, [&]{ onTimeout(); });
}
+QString NexusSSOLogin::stateToString(States s, const QString& e)
+{
+ switch (s)
+ {
+ case ConnectingToSSO:
+ return QObject::tr("Connecting to Nexus...");
+
+ case WaitingForToken:
+ return QObject::tr("Waiting for Nexus...");
+
+ case WaitingForBrowser:
+ return QObject::tr("Opened browser, waiting for user...");
+
+ case Finished:
+ return QObject::tr("Connected.");
+
+ case Timeout:
+ return QObject::tr(
+ "No answer from Nexus.\n"
+ "A firewall might be blocking Mod Organizer.");
+
+ case ClosedByRemote:
+ return QObject::tr("Nexus closed the connection.");
+
+ case Cancelled:
+ return QObject::tr("Cancelled.");
+
+ case Error: // fall-through
+ default:
+ {
+ if (e.isEmpty()) {
+ return QString("%1").arg(s);
+ } else {
+ return e;
+ }
+ }
+ }
+}
+
void NexusSSOLogin::start()
{
m_active = true;
@@ -306,6 +345,40 @@ NexusKeyValidator::~NexusKeyValidator()
abort();
}
+QString NexusKeyValidator::stateToString(States s, const QString& e)
+{
+ switch (s)
+ {
+ case NexusKeyValidator::Connecting:
+ return QObject::tr("Connecting to Nexus...");
+
+ case NexusKeyValidator::Finished:
+ return QObject::tr("Finished.");
+
+ case NexusKeyValidator::InvalidJson:
+ return QObject::tr("Invalid JSON");
+
+ case NexusKeyValidator::BadResponse:
+ return QObject::tr("Bad response");
+
+ case NexusKeyValidator::Timeout:
+ return QObject::tr("There was a timeout during the request");
+
+ case NexusKeyValidator::Cancelled:
+ return QObject::tr("Cancelled");
+
+ case NexusKeyValidator::Error: // fall-through
+ default:
+ {
+ if (e.isEmpty()) {
+ return QString("%1").arg(s);
+ } else {
+ return e;
+ }
+ }
+ }
+}
+
void NexusKeyValidator::start(const QString& key)
{
if (m_reply) {
@@ -558,45 +631,14 @@ void NXMAccessManager::startValidationCheck(const QString& key, bool showProgres
void NXMAccessManager::onValidatorState(
NexusKeyValidator::States s, const QString& e)
{
- switch (s)
- {
- case NexusKeyValidator::Connecting: // fall-through
- case NexusKeyValidator::Finished:
- {
- // no-op, success is handled in onValidatorFinished()
- break;
- }
-
- case NexusKeyValidator::InvalidJson:
- {
- onValidatorError(tr("Invalid JSON"));
- break;
- }
-
- case NexusKeyValidator::BadResponse:
- {
- onValidatorError(tr("Bad response"));
- break;
- }
-
- case NexusKeyValidator::Timeout:
- {
- onValidatorError(tr("There was a timeout during the request"));
- break;
- }
-
- case NexusKeyValidator::Cancelled:
- {
- onValidatorError(tr("Cancelled"));
- break;
- }
-
- case NexusKeyValidator::Error:
- {
- onValidatorError(e);
- break;
- }
+ if (s == NexusKeyValidator::Connecting || s == NexusKeyValidator::Finished) {
+ // no-op, success is handled in onValidatorFinished()
+ return;
}
+
+ m_ProgressDialog->stop();
+ m_validationState = Invalid;
+ emit validateFailed(NexusKeyValidator::stateToString(s, e));
}
void NXMAccessManager::onValidatorFinished(const APIUserAccount& user)
@@ -608,13 +650,6 @@ void NXMAccessManager::onValidatorFinished(const APIUserAccount& user)
emit validateSuccessful(true);
}
-void NXMAccessManager::onValidatorError(const QString& e)
-{
- m_ProgressDialog->stop();
- m_validationState = Invalid;
- emit validateFailed(e);
-}
-
bool NXMAccessManager::validated() const
{
if (m_validator.isActive()) {
diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h
index 11370d65..c633ae3b 100644
--- a/src/nxmaccessmanager.h
+++ b/src/nxmaccessmanager.h
@@ -80,6 +80,8 @@ public:
std::function keyChanged;
std::function stateChanged;
+ static QString stateToString(States s, const QString& e);
+
NexusSSOLogin();
void start();
@@ -126,6 +128,8 @@ public:
std::function finished;
std::function stateChanged;
+ static QString stateToString(States s, const QString& e);
+
NexusKeyValidator(NXMAccessManager& am);
~NexusKeyValidator();
@@ -236,7 +240,6 @@ private:
void startValidationCheck(const QString& key, bool showProgress);
void onValidatorState(NexusKeyValidator::States s, const QString& e);
void onValidatorFinished(const APIUserAccount& user);
- void onValidatorError(const QString& e);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(NXMAccessManager::ApiCheckFlags);
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 12dbc482..df957f87 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -450,66 +450,10 @@ void SettingsDialog::onSSOKeyChanged(const QString& key)
void SettingsDialog::onSSOStateChanged(NexusSSOLogin::States s, const QString& e)
{
- QString log;
+ const auto log = NexusSSOLogin::stateToString(s, e);
- switch (s)
- {
- case NexusSSOLogin::ConnectingToSSO:
- {
- log = tr("Connecting to Nexus...");
- break;
- }
-
- case NexusSSOLogin::WaitingForToken:
- {
- log = tr("Waiting for Nexus...");
- break;
- }
-
- case NexusSSOLogin::WaitingForBrowser:
- {
- log = tr("Opened browser, waiting for user...");
- break;
- }
-
- case NexusSSOLogin::Finished:
- {
- log = tr("Connected.");
- break;
- }
-
- case NexusSSOLogin::Timeout:
- {
- log = QObject::tr(
- "No answer from Nexus.\n"
- "A firewall might be blocking Mod Organizer.");
-
- break;
- }
-
- case NexusSSOLogin::ClosedByRemote:
- {
- log = QObject::tr("Nexus closed the connection.");
- break;
- }
-
- case NexusSSOLogin::Cancelled:
- {
- log = QObject::tr("Cancelled.");
- break;
- }
-
- case NexusSSOLogin::Error:
- {
- log = tr("Error: %1.").arg(e);
- break;
- }
- }
-
- if (!log.isEmpty()) {
- for (auto&& line : log.split("\n")) {
- ui->nexusLog->addItem(line);
- }
+ for (auto&& line : log.split("\n")) {
+ ui->nexusLog->addItem(line);
}
updateNexusButtons();
@@ -518,60 +462,10 @@ void SettingsDialog::onSSOStateChanged(NexusSSOLogin::States s, const QString& e
void SettingsDialog::onValidatorStateChanged(
NexusKeyValidator::States s, const QString& e)
{
- QString log;
-
- switch (s)
- {
- case NexusKeyValidator::Connecting:
- {
- log = tr("Connecting to Nexus...");
- break;
- }
-
- case NexusKeyValidator::Finished:
- {
- log = tr("Connected.");
- break;
- }
-
- case NexusKeyValidator::InvalidJson:
- {
- log = tr("Invalid JSON");
- break;
- }
-
- case NexusKeyValidator::BadResponse:
- {
- log = tr("Bad response");
- break;
- }
-
- case NexusKeyValidator::Timeout:
- {
- log = QObject::tr(
- "No answer from Nexus.\n"
- "A firewall might be blocking Mod Organizer.");
+ const auto log = NexusKeyValidator::stateToString(s, e);
- break;
- }
-
- case NexusKeyValidator::Cancelled:
- {
- log = QObject::tr("Cancelled.");
- break;
- }
-
- case NexusKeyValidator::Error:
- {
- log = tr("Error: %1.").arg(e);
- break;
- }
- }
-
- if (!log.isEmpty()) {
- for (auto&& line : log.split("\n")) {
- ui->nexusLog->addItem(line);
- }
+ for (auto&& line : log.split("\n")) {
+ ui->nexusLog->addItem(line);
}
updateNexusButtons();
--
cgit v1.3.1
From 45f0a9e78ac876a2a956bc538c6d34358703e338 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 12 Jul 2019 02:46:31 -0400
Subject: nexus info and stats in settings cleaned up double logging for github
reset validation progress dialog parent just before the main window dies
removed unused APIStats from APIUserAccount, added isValid()
---
src/apiuseraccount.cpp | 22 +++++
src/apiuseraccount.h | 8 +-
src/main.cpp | 8 +-
src/nxmaccessmanager.cpp | 2 +-
src/organizercore.cpp | 2 +-
src/selfupdater.cpp | 2 +-
src/settingsdialog.cpp | 98 ++++++++++++++++-----
src/settingsdialog.h | 6 ++
src/settingsdialog.ui | 218 +++++++++++++++++++++++------------------------
9 files changed, 226 insertions(+), 140 deletions(-)
(limited to 'src/settingsdialog.cpp')
diff --git a/src/apiuseraccount.cpp b/src/apiuseraccount.cpp
index 596f8aa7..35a868d5 100644
--- a/src/apiuseraccount.cpp
+++ b/src/apiuseraccount.cpp
@@ -1,10 +1,32 @@
#include "apiuseraccount.h"
+QString localizedUserAccountType(APIUserAccountTypes t)
+{
+ switch (t)
+ {
+ case APIUserAccountTypes::Regular:
+ return QObject::tr("Regular");
+
+ case APIUserAccountTypes::Premium:
+ return QObject::tr("Premium");
+
+ case APIUserAccountTypes::None: // fall-through
+ default:
+ return QObject::tr("None");
+ }
+}
+
+
APIUserAccount::APIUserAccount()
: m_type(APIUserAccountTypes::None)
{
}
+bool APIUserAccount::isValid() const
+{
+ return !m_key.isEmpty();
+}
+
const QString& APIUserAccount::apiKey() const
{
return m_key;
diff --git a/src/apiuseraccount.h b/src/apiuseraccount.h
index 7dd16128..ea4e8685 100644
--- a/src/apiuseraccount.h
+++ b/src/apiuseraccount.h
@@ -18,6 +18,8 @@ enum class APIUserAccountTypes
Premium
};
+QString localizedUserAccountType(APIUserAccountTypes t);
+
/**
* current limits imposed on the user account
@@ -61,6 +63,11 @@ public:
APIUserAccount();
+ /**
+ * whether the user is logged in
+ */
+ bool isValid() const;
+
/**
* api key
*/
@@ -134,7 +141,6 @@ private:
QString m_key, m_id, m_name;
APIUserAccountTypes m_type;
APILimits m_limits;
- APIStats m_stats;
};
#endif // APIUSERACCOUNT_H
diff --git a/src/main.cpp b/src/main.cpp
index 0b078f03..4359c645 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -713,7 +713,13 @@ int runApplication(MOApplication &application, SingleInstance &instance,
mainWindow.activateWindow();
splash.finish(&mainWindow);
- return application.exec();
+
+ const auto ret = application.exec();
+
+ NexusInterface::instance(&pluginContainer)
+ ->getAccessManager()->setTopLevelWidget(nullptr);
+
+ return ret;
}
} catch (const std::exception &e) {
reportError(e.what());
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index a331b2e8..196368fd 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -167,7 +167,7 @@ QString NexusSSOLogin::stateToString(States s, const QString& e)
return QObject::tr("Opened browser, waiting for user...");
case Finished:
- return QObject::tr("Connected.");
+ return QObject::tr("Finished.");
case Timeout:
return QObject::tr(
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 87668f4b..eeb69e61 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -2484,7 +2484,7 @@ void OrganizerCore::loginSuccessfulUpdate(bool necessary)
void OrganizerCore::loginFailed(const QString &message)
{
- qDebug().nospace().noquote()
+ qCritical().nospace().noquote()
<< "Nexus API validation failed: " << message;
if (QMessageBox::question(qApp->activeWindow(), tr("Login failed"),
diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp
index 271c621b..e967b27c 100644
--- a/src/selfupdater.cpp
+++ b/src/selfupdater.cpp
@@ -130,7 +130,7 @@ void SelfUpdater::testForUpdate()
m_GitHub.releases(GitHub::Repository("Modorganizer2", "modorganizer"),
[this](const QJsonArray &releases) {
if (releases.isEmpty()) {
- qDebug("Unable to connect to github.com to check version");
+ // error message already logged
return;
}
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index df957f87..0dae31ac 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -55,6 +55,7 @@ public:
: QDialog(parent), ui(new Ui::NexusManualKeyDialog)
{
ui->setupUi(this);
+ ui->key->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
connect(ui->openBrowser, &QPushButton::clicked, [&]{ openBrowser(); });
connect(ui->paste, &QPushButton::clicked, [&]{ paste(); });
@@ -111,7 +112,7 @@ SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* setti
QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem()));
- updateNexusButtons();
+ updateNexusState();
}
SettingsDialog::~SettingsDialog()
@@ -399,7 +400,7 @@ void SettingsDialog::on_nexusConnect_clicked()
ui->nexusLog->clear();
m_nexusLogin->start();
- updateNexusButtons();
+ updateNexusState();
}
void SettingsDialog::on_nexusManualKey_clicked()
@@ -421,8 +422,18 @@ void SettingsDialog::on_nexusManualKey_clicked()
}
ui->nexusLog->clear();
- ui->nexusLog->addItem(tr("Checking API key..."));
+ validateKey(key);
+}
+
+void SettingsDialog::on_nexusDisconnect_clicked()
+{
+ clearKey();
+ ui->nexusLog->clear();
+ addNexusLog(tr("Disconnected."));
+}
+void SettingsDialog::validateKey(const QString& key)
+{
if (!m_nexusValidator) {
m_nexusValidator.reset(new NexusKeyValidator(
*NexusInterface::instance(m_PluginContainer)->getAccessManager()));
@@ -436,6 +447,7 @@ void SettingsDialog::on_nexusManualKey_clicked()
};
}
+ addNexusLog(tr("Checking API key..."));
m_nexusValidator->start(key);
}
@@ -444,45 +456,62 @@ void SettingsDialog::onSSOKeyChanged(const QString& key)
if (key.isEmpty()) {
clearKey();
} else {
- setKey(key);
+ addNexusLog(tr("Received API key."));
+ validateKey(key);
}
}
void SettingsDialog::onSSOStateChanged(NexusSSOLogin::States s, const QString& e)
{
- const auto log = NexusSSOLogin::stateToString(s, e);
+ if (s != NexusSSOLogin::Finished) {
+ // finished state is handled in onSSOKeyChanged()
+ const auto log = NexusSSOLogin::stateToString(s, e);
- for (auto&& line : log.split("\n")) {
- ui->nexusLog->addItem(line);
+ for (auto&& line : log.split("\n")) {
+ addNexusLog(line);
+ }
}
- updateNexusButtons();
+ updateNexusState();
}
void SettingsDialog::onValidatorStateChanged(
NexusKeyValidator::States s, const QString& e)
{
- const auto log = NexusKeyValidator::stateToString(s, e);
+ if (s != NexusKeyValidator::Finished) {
+ // finished state is handled in onValidatorFinished()
+ const auto log = NexusKeyValidator::stateToString(s, e);
- for (auto&& line : log.split("\n")) {
- ui->nexusLog->addItem(line);
+ for (auto&& line : log.split("\n")) {
+ addNexusLog(line);
+ }
}
- updateNexusButtons();
+ updateNexusState();
}
void SettingsDialog::onValidatorFinished(const APIUserAccount& user)
{
+ NexusInterface::instance(m_PluginContainer)->setUserAccount(user);
+
if (!user.apiKey().isEmpty()) {
- setKey(user.apiKey());
+ if (setKey(user.apiKey())) {
+ addNexusLog(tr("Linked with Nexus successfully."));
+ }
}
}
+void SettingsDialog::addNexusLog(const QString& s)
+{
+ ui->nexusLog->addItem(s);
+ ui->nexusLog->scrollToBottom();
+}
+
bool SettingsDialog::setKey(const QString& key)
{
m_keyChanged = true;
const bool ret = m_settings->setNexusApiKey(key);
- updateNexusButtons();
+ updateNexusState();
return ret;
}
@@ -490,13 +519,19 @@ bool SettingsDialog::clearKey()
{
m_keyChanged = true;
const auto ret = m_settings->clearNexusApiKey();
- updateNexusButtons();
NexusInterface::instance(m_PluginContainer)->getAccessManager()->clearApiKey();
+ updateNexusState();
return ret;
}
+void SettingsDialog::updateNexusState()
+{
+ updateNexusButtons();
+ updateNexusData();
+}
+
void SettingsDialog::updateNexusButtons()
{
if (m_nexusLogin && m_nexusLogin->isActive()) {
@@ -532,6 +567,32 @@ void SettingsDialog::updateNexusButtons()
}
}
+void SettingsDialog::updateNexusData()
+{
+ const auto user = NexusInterface::instance(m_PluginContainer)
+ ->getAPIUserAccount();
+
+ if (user.isValid()) {
+ ui->nexusUserID->setText(user.id());
+ ui->nexusName->setText(user.name());
+ ui->nexusAccount->setText(localizedUserAccountType(user.type()));
+
+ ui->nexusDailyRequests->setText(QString("%1/%2")
+ .arg(user.limits().remainingDailyRequests)
+ .arg(user.limits().maxDailyRequests));
+
+ ui->nexusHourlyRequests->setText(QString("%1/%2")
+ .arg(user.limits().remainingHourlyRequests)
+ .arg(user.limits().maxHourlyRequests));
+ } else {
+ ui->nexusUserID->setText(tr("N/A"));
+ ui->nexusName->setText(tr("N/A"));
+ ui->nexusAccount->setText(tr("N/A"));
+ ui->nexusDailyRequests->setText(tr("N/A"));
+ ui->nexusHourlyRequests->setText(tr("N/A"));
+ }
+}
+
void SettingsDialog::storeSettings(QListWidgetItem *pluginItem)
{
if (pluginItem != nullptr) {
@@ -599,13 +660,6 @@ void SettingsDialog::on_clearCacheButton_clicked()
NexusInterface::instance(m_PluginContainer)->clearCache();
}
-void SettingsDialog::on_nexusDisconnect_clicked()
-{
- clearKey();
- ui->nexusLog->clear();
- ui->nexusLog->addItem(tr("Disconnected."));
-}
-
void SettingsDialog::normalizePath(QLineEdit *lineEdit)
{
QString text = lineEdit->text();
diff --git a/src/settingsdialog.h b/src/settingsdialog.h
index 1741fc13..c5f487fd 100644
--- a/src/settingsdialog.h
+++ b/src/settingsdialog.h
@@ -145,15 +145,21 @@ private:
std::unique_ptr m_nexusLogin;
std::unique_ptr m_nexusValidator;
+ void validateKey(const QString& key);
bool setKey(const QString& key);
bool clearKey();
+
+ void updateNexusState();
void updateNexusButtons();
+ void updateNexusData();
void onSSOKeyChanged(const QString& key);
void onSSOStateChanged(NexusSSOLogin::States s, const QString& e);
void onValidatorStateChanged(NexusKeyValidator::States s, const QString& e);
void onValidatorFinished(const APIUserAccount& user);
+
+ void addNexusLog(const QString& s);
};
#endif // SETTINGSDIALOG_H
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui
index dfbde943..fccc8be0 100644
--- a/src/settingsdialog.ui
+++ b/src/settingsdialog.ui
@@ -451,103 +451,7 @@ If you use pre-releases, never contact me directly by e-mail or via private mess
Nexus
-
- -
-
-
- Nexus Connection
-
-
-
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- Connect to Nexus
-
-
-
- -
-
-
- Manually enter the API key and try to login
-
-
- Enter API Key Manually
-
-
-
- -
-
-
- Clear the stored Nexus API key and force reauthorization.
-
-
- Disconnect from Nexus
-
-
-
- :/MO/gui/edit_clear:/MO/gui/edit_clear
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 0
- 0
-
-
-
-
-
-
-
- -
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- QAbstractScrollArea::AdjustToContents
-
-
-
-
-
-
-
-
-
+
-
@@ -569,10 +473,13 @@ If you use pre-releases, never contact me directly by e-mail or via private mess
Nexus Account
+
+ 10
+
-
- User ID
+ User ID:
Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
@@ -589,21 +496,21 @@ If you use pre-releases, never contact me directly by e-mail or via private mess
-
- Username
+ Name:
-
-
+
- username
+ name
-
- Account
+ Account:
@@ -623,17 +530,27 @@ If you use pre-releases, never contact me directly by e-mail or via private mess
Statistics
+
+ 10
+
-
- Daily requests
+ Daily requests:
+
+
+
+ -
+
+
+ daily requests
-
- Hourly requests
+ Hourly requests:
@@ -644,24 +561,99 @@ If you use pre-releases, never contact me directly by e-mail or via private mess
- -
-
+
+
+
+
+
+
+ -
+
+
+ Nexus Connection
+
+
+
-
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
- Requests queued
+ Connect to Nexus
- -
-
+
-
+
+
+ Manually enter the API key and try to login
+
- queued
+ Enter API Key Manually
- -
-
+
-
+
+
+ Clear the stored Nexus API key and force reauthorization.
+
- daily requests
+ Disconnect from Nexus
+
+
+
+ :/MO/gui/edit_clear:/MO/gui/edit_clear
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QAbstractScrollArea::AdjustToContents
--
cgit v1.3.1