summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nexusmanualkey.ui156
-rw-r--r--src/settings.cpp78
-rw-r--r--src/settings.h30
-rw-r--r--src/settingsdialog.cpp129
-rw-r--r--src/settingsdialog.h93
-rw-r--r--src/settingsdialog.ui4
6 files changed, 337 insertions, 153 deletions
diff --git a/src/nexusmanualkey.ui b/src/nexusmanualkey.ui
index 191ca218..1a842dc3 100644
--- a/src/nexusmanualkey.ui
+++ b/src/nexusmanualkey.ui
@@ -7,16 +7,16 @@
<x>0</x>
<y>0</y>
<width>452</width>
- <height>302</height>
+ <height>236</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
+ <layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0">
<item>
<widget class="QWidget" name="widget" native="true">
- <layout class="QVBoxLayout" name="verticalLayout">
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
<property name="leftMargin">
<number>0</number>
</property>
@@ -30,10 +30,152 @@
<number>0</number>
</property>
<item>
- <widget class="QPlainTextEdit" name="key">
- <property name="placeholderText">
- <string>Enter API key here</string>
- </property>
+ <widget class="QWidget" name="widget_2" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>1. Get your personal API key</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="openBrowser">
+ <property name="text">
+ <string>Open Browser</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_3" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,1">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QWidget" name="widget_4" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>2. Enter your personal API key</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>115</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="paste">
+ <property name="text">
+ <string>Paste</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clear">
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="key">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Ignored" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ <property name="placeholderText">
+ <string>Enter API key here</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_5" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>&lt;b&gt;Sharing this key with anyone could get your Nexus account banned. You can always revoke this key from your account on the Nexus website.&lt;/b&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
</layout>
diff --git a/src/settings.cpp b/src/settings.cpp
index a844fdc9..53dd32dc 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -363,6 +363,32 @@ bool Settings::getNexusApiKey(QString &apiKey) const
return true;
}
+bool Settings::setNexusApiKey(const QString& apiKey)
+{
+ if (!obfuscate("APIKEY", apiKey)) {
+ wchar_t buffer[256];
+
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buffer, (sizeof(buffer) / sizeof(wchar_t)), NULL);
+
+ qCritical() << "Storing API key failed:" << buffer;
+ return false;
+ }
+
+ return true;
+}
+
+bool Settings::clearNexusApiKey()
+{
+ return setNexusApiKey("");
+}
+
+bool Settings::hasNexusApiKey() const
+{
+ return !deObfuscate("APIKEY").isEmpty();
+}
+
bool Settings::getSteamLogin(QString &username, QString &password) const
{
if (m_Settings.contains("Settings/steam_username")) {
@@ -452,17 +478,6 @@ QString Settings::executablesBlacklist() const
).toString();
}
-void Settings::setNexusApiKey(QString apiKey)
-{
- if (!obfuscate("APIKEY", apiKey)) {
- wchar_t buffer[256];
- FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buffer, (sizeof(buffer) / sizeof(wchar_t)), NULL);
- qCritical() << "Storing API key failed:" << buffer;
- }
-}
-
void Settings::setSteamLogin(QString username, QString password)
{
if (username == "") {
@@ -706,43 +721,10 @@ void Settings::resetDialogs()
QuestionBoxMemory::resetDialogs();
}
-void Settings::processApiKey(const QString &apiKey)
-{
- if (!obfuscate("APIKEY", apiKey)) {
- wchar_t buffer[256];
- FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buffer, (sizeof(buffer) / sizeof(wchar_t)), NULL);
- qCritical() << "Storing or deleting API key failed:" << buffer;
- }
-}
-
-void Settings::clearApiKey(QPushButton *nexusButton)
-{
- obfuscate("APIKEY", "");
- nexusButton->setEnabled(true);
- nexusButton->setText("Connect to Nexus");
-}
-
-void Settings::checkApiKey(QPushButton *nexusButton)
-{
- if (deObfuscate("APIKEY").isEmpty()) {
- nexusButton->setEnabled(true);
- nexusButton->setText("Connect to Nexus");
- 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."));
- }
-}
-
void Settings::query(PluginContainer *pluginContainer, QWidget *parent)
{
- SettingsDialog dialog(pluginContainer, parent);
-
+ SettingsDialog dialog(pluginContainer, this, parent);
connect(&dialog, SIGNAL(resetDialogs()), this, SLOT(resetDialogs()));
- connect(&dialog, SIGNAL(processApiKey(const QString &)), this, SLOT(processApiKey(const QString &)));
- connect(&dialog, SIGNAL(closeApiConnection(QPushButton *)), this, SLOT(checkApiKey(QPushButton *)));
- connect(&dialog, SIGNAL(revokeApiKey(QPushButton *)), this, SLOT(clearApiKey(QPushButton *)));
std::vector<std::unique_ptr<SettingsTab>> tabs;
@@ -1043,7 +1025,6 @@ void Settings::DiagnosticsTab::update()
Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog)
: Settings::SettingsTab(parent, dialog)
- , m_nexusConnect(dialog.findChild<QPushButton *>("nexusConnect"))
, m_offlineBox(dialog.findChild<QCheckBox *>("offlineBox"))
, m_proxyBox(dialog.findChild<QCheckBox *>("proxyBox"))
, m_knownServersList(dialog.findChild<QListWidget *>("knownServersList"))
@@ -1052,11 +1033,6 @@ Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog)
, m_endorsementBox(dialog.findChild<QCheckBox *>("endorsementBox"))
, m_hideAPICounterBox(dialog.findChild<QCheckBox *>("hideAPICounterBox"))
{
- if (!deObfuscate("APIKEY").isEmpty()) {
- m_nexusConnect->setText("Nexus API Key Stored");
- m_nexusConnect->setDisabled(true);
- }
-
m_offlineBox->setChecked(parent->offlineMode());
m_proxyBox->setChecked(parent->useProxy());
m_endorsementBox->setChecked(parent->endorsementIntegration());
diff --git a/src/settings.h b/src/settings.h
index 04a0646e..bccd1e81 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -188,6 +188,24 @@ public:
bool getNexusApiKey(QString &apiKey) const;
/**
+ * @brief set the nexus login information
+ *
+ * @param username username
+ * @param password password
+ */
+ bool setNexusApiKey(const QString& apiKey);
+
+ /**
+ * @brief clears the nexus login information
+ */
+ bool clearNexusApiKey();
+
+ /**
+ * @brief returns whether an API key is currently stored
+ */
+ bool hasNexusApiKey() const;
+
+ /**
* @brief retrieve the login information for steam
*
* @param username (out) receives the user name for nexus
@@ -241,14 +259,6 @@ public:
QString executablesBlacklist() const;
/**
- * @brief set the nexus login information
- *
- * @param username username
- * @param password password
- */
- void setNexusApiKey(QString apiKey);
-
- /**
* @brief set the steam login information
*
* @param username username
@@ -481,7 +491,6 @@ private:
void update();
private:
- QPushButton *m_nexusConnect;
QCheckBox *m_offlineBox;
QCheckBox *m_proxyBox;
QListWidget *m_knownServersList;
@@ -538,9 +547,6 @@ private:
private slots:
void resetDialogs();
- void processApiKey(const QString &);
- void clearApiKey(QPushButton *nexusButton);
- void checkApiKey(QPushButton *nexusButton);
signals:
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 44d7fde5..0373cef6 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -57,6 +57,10 @@ public:
: QDialog(parent), ui(new Ui::NexusManualKeyDialog)
{
ui->setupUi(this);
+
+ connect(ui->openBrowser, &QPushButton::clicked, [&]{ openBrowser(); });
+ connect(ui->paste, &QPushButton::clicked, [&]{ paste(); });
+ connect(ui->clear, &QPushButton::clicked, [&]{ clear(); });
}
void accept() override
@@ -70,15 +74,34 @@ public:
return m_key;
}
+ void openBrowser()
+ {
+ shell::OpenLink(QUrl("https://www.nexusmods.com/users/myaccount?tab=api"));
+ }
+
+ void paste()
+ {
+ const auto text = QApplication::clipboard()->text();
+ if (!text.isEmpty()) {
+ ui->key->setPlainText(text);
+ }
+ }
+
+ void clear()
+ {
+ ui->key->clear();
+ }
+
private:
std::unique_ptr<Ui::NexusManualKeyDialog> ui;
QString m_key;
};
-SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, QWidget *parent)
+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)
@@ -95,8 +118,9 @@ SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, QWidget *parent
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()));
- connect(this, SIGNAL(retryApiConnection()), this, SLOT(on_nexusConnect_clicked()));
m_loginTimer.callOnTimeout(this, &SettingsDialog::loginPing);
+
+ updateNexusButtons();
}
SettingsDialog::~SettingsDialog()
@@ -367,10 +391,7 @@ void SettingsDialog::on_resetDialogsButton_clicked()
void SettingsDialog::on_nexusConnect_clicked()
{
- ui->nexusConnect->setText("Connecting the API. Please login within the browser and accept the request. This will time out after 30 minutes.");
- ui->nexusConnect->setDisabled(true);
- QUrl url = QUrl("wss://sso.nexusmods.com");
- m_nexusLogin->open(url);
+ fetchNexusApiKey();
}
void SettingsDialog::on_nexusManualKey_clicked()
@@ -382,9 +403,21 @@ void SettingsDialog::on_nexusManualKey_clicked()
}
const auto key = dialog.key();
- emit processApiKey(key);
- ui->nexusConnect->setText("Nexus API Key Stored");
- NexusInterface::instance(m_PluginContainer)->getAccessManager()->apiCheck(key, true);
+
+ if (key.isEmpty()) {
+ clearKey();
+ } else {
+ if (setKey(key)) {
+ testApiKey();
+ }
+ }
+}
+
+void SettingsDialog::fetchNexusApiKey()
+{
+ QUrl url = QUrl("wss://sso.nexusmods.com");
+ m_nexusLogin->open(url);
+ updateNexusButtons();
}
void SettingsDialog::dispatchLogin()
@@ -434,12 +467,17 @@ void SettingsDialog::receiveApiKey(const QString &response)
if (data.contains("connection_token")) {
m_AuthToken = data["connection_token"].toString();
} else {
- m_KeyReceived = true;
- emit processApiKey(data["api_key"].toString());
+ const auto key = data["api_key"].toString();
+
m_nexusLogin->close();
- ui->nexusConnect->setText("Nexus API Key Stored");
m_loginTimer.stop();
m_totalPings = 0;
+
+ if (key.isEmpty()) {
+ clearKey();
+ } else {
+ setKey(key);
+ }
}
} else {
QString error("There was a problem with SSO initialization: %1");
@@ -450,10 +488,64 @@ void SettingsDialog::receiveApiKey(const QString &response)
void SettingsDialog::completeApiConnection()
{
- if (m_KeyReceived == true || !m_loginTimer.isActive())
- emit closeApiConnection(ui->nexusConnect);
- else
- emit retryApiConnection();
+ 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."));
+
+ // try again
+ fetchNexusApiKey();
+ }
+}
+
+bool SettingsDialog::setKey(const QString& key)
+{
+ m_KeyReceived = true;
+ const bool ret = m_settings->setNexusApiKey(key);
+ updateNexusButtons();
+ return ret;
+}
+
+bool SettingsDialog::clearKey()
+{
+ m_KeyCleared = true;
+ const auto ret = m_settings->clearNexusApiKey();
+ updateNexusButtons();
+ return ret;
+}
+
+void SettingsDialog::testApiKey()
+{
+ QString key;
+ if (!m_settings->getNexusApiKey(key)) {
+ qWarning().nospace() << "can't test API key, nothing stored";
+ return;
+ }
+
+ auto* am = NexusInterface::instance(m_PluginContainer)->getAccessManager();
+ am->apiCheck(key, true);
+}
+
+void SettingsDialog::updateNexusButtons()
+{
+ if (m_nexusLogin->state() != QAbstractSocket::UnconnectedState) {
+ // 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);
+ }
+ else if (m_settings->hasNexusApiKey()) {
+ // api key is present
+ ui->nexusConnect->setText("Nexus API Key Stored");
+ 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->setEnabled(true);
+ ui->nexusDisconnect->setEnabled(false);
+ ui->nexusManualKey->setEnabled(true);
+ }
}
void SettingsDialog::storeSettings(QListWidgetItem *pluginItem)
@@ -523,10 +615,9 @@ void SettingsDialog::on_clearCacheButton_clicked()
NexusInterface::instance(m_PluginContainer)->clearCache();
}
-void SettingsDialog::on_revokeNexusAuthButton_clicked()
+void SettingsDialog::on_nexusDisconnect_clicked()
{
- emit revokeApiKey(ui->nexusConnect);
- m_KeyCleared = true;
+ clearKey();
}
void SettingsDialog::normalizePath(QLineEdit *lineEdit)
diff --git a/src/settingsdialog.h b/src/settingsdialog.h
index a844b391..858a36d4 100644
--- a/src/settingsdialog.h
+++ b/src/settingsdialog.h
@@ -29,6 +29,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QTimer>
class PluginContainer;
+class Settings;
namespace Ui {
class SettingsDialog;
@@ -44,7 +45,9 @@ class SettingsDialog : public MOBase::TutorableDialog
Q_OBJECT
public:
- explicit SettingsDialog(PluginContainer *pluginContainer, QWidget *parent = 0);
+ explicit SettingsDialog(
+ PluginContainer *pluginContainer, Settings* settings, QWidget *parent = 0);
+
~SettingsDialog();
/**
@@ -62,9 +65,6 @@ public slots:
signals:
void resetDialogs();
- void processApiKey(const QString &);
- void closeApiConnection(QPushButton *);
- void revokeApiKey(QPushButton *);
void retryApiConnection();
private:
@@ -94,105 +94,74 @@ public:
private slots:
- //void on_loginCheckBox_toggled(bool checked);
-
void on_categoriesBtn_clicked();
-
void on_execBlacklistBtn_clicked();
-
void on_bsaDateBtn_clicked();
-
void on_browseDownloadDirBtn_clicked();
-
void on_browseModDirBtn_clicked();
-
void on_browseCacheDirBtn_clicked();
-
void on_resetDialogsButton_clicked();
-
void on_pluginsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
-
- void deleteBlacklistItem();
-
void on_associateButton_clicked();
-
void on_clearCacheButton_clicked();
-
- void on_revokeNexusAuthButton_clicked();
-
+ void on_nexusDisconnect_clicked();
void on_browseBaseDirBtn_clicked();
-
void on_browseOverwriteDirBtn_clicked();
-
void on_browseProfilesDirBtn_clicked();
-
void on_browseGameDirBtn_clicked();
-
void on_overwritingBtn_clicked();
-
void on_overwrittenBtn_clicked();
-
void on_overwritingArchiveBtn_clicked();
-
void on_overwrittenArchiveBtn_clicked();
-
void on_containsBtn_clicked();
-
void on_containedBtn_clicked();
-
void on_resetColorsBtn_clicked();
-
void on_baseDirEdit_editingFinished();
-
void on_downloadDirEdit_editingFinished();
-
void on_modDirEdit_editingFinished();
-
void on_cacheDirEdit_editingFinished();
-
void on_profilesDirEdit_editingFinished();
-
void on_overwriteDirEdit_editingFinished();
-
void on_nexusConnect_clicked();
-
void on_nexusManualKey_clicked();
+ void on_resetGeometryBtn_clicked();
+ void deleteBlacklistItem();
void dispatchLogin();
-
void loginPing();
-
void authError(QAbstractSocket::SocketError error);
-
void receiveApiKey(const QString &apiKey);
-
void completeApiConnection();
- void on_resetGeometryBtn_clicked();
-
private:
- Ui::SettingsDialog *ui;
- PluginContainer *m_PluginContainer;
+ Ui::SettingsDialog *ui;
+ Settings* m_settings;
+ PluginContainer *m_PluginContainer;
- QColor m_OverwritingColor;
- QColor m_OverwrittenColor;
- QColor m_OverwritingArchiveColor;
- QColor m_OverwrittenArchiveColor;
- QColor m_ContainsColor;
- QColor m_ContainedColor;
+ QColor m_OverwritingColor;
+ QColor m_OverwrittenColor;
+ QColor m_OverwritingArchiveColor;
+ QColor m_OverwrittenArchiveColor;
+ QColor m_ContainsColor;
+ QColor m_ContainedColor;
- bool m_KeyReceived;
- bool m_KeyCleared;
- bool m_GeometriesReset;
- QString m_UUID;
- QString m_AuthToken;
+ bool m_KeyReceived;
+ bool m_KeyCleared;
+ bool m_GeometriesReset;
+ QString m_UUID;
+ QString m_AuthToken;
- QString m_ExecutableBlacklist;
- QWebSocket *m_nexusLogin;
- QTimer m_loginTimer;
- int m_totalPings = 0;
-};
+ QString m_ExecutableBlacklist;
+ QWebSocket *m_nexusLogin;
+ QTimer m_loginTimer;
+ int m_totalPings = 0;
+ bool setKey(const QString& key);
+ bool clearKey();
+ void updateNexusButtons();
+ void fetchNexusApiKey();
+ void testApiKey();
+};
#endif // SETTINGSDIALOG_H
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui
index 088b7a0d..08c8d9f2 100644
--- a/src/settingsdialog.ui
+++ b/src/settingsdialog.ui
@@ -511,12 +511,12 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item>
- <widget class="QPushButton" name="revokeNexusAuthButton">
+ <widget class="QPushButton" name="nexusDisconnect">
<property name="toolTip">
<string>Clear the stored Nexus API key and force reauthorization.</string>
</property>
<property name="text">
- <string>Revoke Nexus Authorization</string>
+ <string>Disconnect from Nexus</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">