summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-07-11 05:06:42 -0400
committerisanae <14251494+isanae@users.noreply.github.com>2019-07-11 05:06:42 -0400
commitc0a52bc1ca3bcde8107f7cd2b8924c1dda487b1c (patch)
tree534ad4950752e2f932fdfa0cc1b5daa8f33aaf63 /src
parentad29525e982f83343dbd70e17b914e0a30adb662 (diff)
extracted api key validator from NXMAccessManager
api key now part of ApiUserAccount
Diffstat (limited to 'src')
-rw-r--r--src/apiuseraccount.cpp11
-rw-r--r--src/apiuseraccount.h13
-rw-r--r--src/nexusinterface.cpp25
-rw-r--r--src/nexusinterface.h1
-rw-r--r--src/nxmaccessmanager.cpp441
-rw-r--r--src/nxmaccessmanager.h86
-rw-r--r--src/organizercore.cpp3
7 files changed, 403 insertions, 177 deletions
diff --git a/src/apiuseraccount.cpp b/src/apiuseraccount.cpp
index b901e41a..596f8aa7 100644
--- a/src/apiuseraccount.cpp
+++ b/src/apiuseraccount.cpp
@@ -5,6 +5,11 @@ APIUserAccount::APIUserAccount()
{
}
+const QString& APIUserAccount::apiKey() const
+{
+ return m_key;
+}
+
const QString& APIUserAccount::id() const
{
return m_id;
@@ -25,6 +30,12 @@ const APILimits& APIUserAccount::limits() const
return m_limits;
}
+APIUserAccount& APIUserAccount::apiKey(const QString& key)
+{
+ m_key = key;
+ return *this;
+}
+
APIUserAccount& APIUserAccount::id(const QString& id)
{
m_id = id;
diff --git a/src/apiuseraccount.h b/src/apiuseraccount.h
index 8a238d71..7dd16128 100644
--- a/src/apiuseraccount.h
+++ b/src/apiuseraccount.h
@@ -60,6 +60,12 @@ public:
APIUserAccount();
+
+ /**
+ * api key
+ */
+ const QString& apiKey() const;
+
/**
* user id
*/
@@ -82,6 +88,11 @@ public:
/**
+ * sets the api key
+ */
+ APIUserAccount& apiKey(const QString& key);
+
+ /**
* sets the user id
*/
APIUserAccount& id(const QString& id);
@@ -120,7 +131,7 @@ public:
bool exhausted() const;
private:
- QString m_id, m_name;
+ QString m_key, m_id, m_name;
APIUserAccountTypes m_type;
APILimits m_limits;
APIStats m_stats;
diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp
index ee9acf2c..2bcd72f3 100644
--- a/src/nexusinterface.cpp
+++ b/src/nexusinterface.cpp
@@ -208,12 +208,27 @@ APILimits NexusInterface::defaultAPILimits()
APILimits NexusInterface::parseLimits(const QNetworkReply* reply)
{
+ return parseLimits(reply->rawHeaderPairs());
+}
+
+APILimits NexusInterface::parseLimits(
+ const QList<QNetworkReply::RawHeaderPair>& headers)
+{
APILimits limits;
- limits.maxDailyRequests = reply->rawHeader("x-rl-daily-limit").toInt();
- limits.remainingDailyRequests = reply->rawHeader("x-rl-daily-remaining").toInt();
- limits.maxHourlyRequests = reply->rawHeader("x-rl-hourly-limit").toInt();
- limits.remainingHourlyRequests = reply->rawHeader("x-rl-hourly-remaining").toInt();
+ for (const auto& pair : headers) {
+ const auto name = QString(pair.first).toLower();
+
+ if (name == "x-rl-daily-limit") {
+ limits.maxDailyRequests = pair.second.toInt();
+ } else if (name == "x-rl-daily-remaining") {
+ limits.remainingDailyRequests = pair.second.toInt();
+ } else if (name == "x-rl-hourly-limit") {
+ limits.maxHourlyRequests = pair.second.toInt();
+ } else if (name == "x-rl-hourly-remaining") {
+ limits.remainingHourlyRequests = pair.second.toInt();
+ }
+ }
return limits;
}
@@ -765,7 +780,7 @@ void NexusInterface::nextRequest()
QNetworkRequest request(url);
request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
- request.setRawHeader("APIKEY", m_AccessManager->apiKey().toUtf8());
+ request.setRawHeader("APIKEY", m_User.apiKey().toUtf8());
request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, m_AccessManager->userAgent(info.m_SubModule));
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
request.setRawHeader("Protocol-Version", "1.0.0");
diff --git a/src/nexusinterface.h b/src/nexusinterface.h
index 6e768149..0b1763c4 100644
--- a/src/nexusinterface.h
+++ b/src/nexusinterface.h
@@ -151,6 +151,7 @@ public:
public:
static APILimits defaultAPILimits();
static APILimits parseLimits(const QNetworkReply* reply);
+ static APILimits parseLimits(const QList<QNetworkReply::RawHeaderPair>& headers);
~NexusInterface();
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index a274261d..c0a6c227 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -127,6 +127,9 @@ void ValidationProgressDialog::onTimer()
NexusSSOLogin::NexusSSOLogin()
: m_keyReceived(false), m_active(false)
{
+ m_timeout.setInterval(NXMAccessManager::ValidationTimeout);
+ m_timeout.setSingleShot(true);
+
QObject::connect(
&m_socket, &QWebSocket::connected,
[&]{ onConnected(); });
@@ -136,6 +139,10 @@ NexusSSOLogin::NexusSSOLogin()
[&](auto&& e){ onError(e); });
QObject::connect(
+ &m_socket, &QWebSocket::sslErrors,
+ [&](auto&& errors){ onSslErrors(errors); });
+
+ QObject::connect(
&m_socket, &QWebSocket::textMessageReceived,
[&](auto&& s){ onMessage(s); });
@@ -150,21 +157,25 @@ void NexusSSOLogin::start()
{
m_active = true;
setState(ConnectingToSSO);
- m_timeout.start(NXMAccessManager::ValidationTimeout);
+ m_timeout.start();
m_socket.open(NexusSSO);
}
void NexusSSOLogin::cancel()
{
- abort();
- setState(Cancelled);
+ if (m_active) {
+ abort();
+ setState(Cancelled);
+ }
}
void NexusSSOLogin::close()
{
- m_active = false;
- m_timeout.stop();
- m_socket.close();
+ if (m_active) {
+ m_active = false;
+ m_timeout.stop();
+ m_socket.close();
+ }
}
void NexusSSOLogin::abort()
@@ -261,6 +272,16 @@ void NexusSSOLogin::onError(QAbstractSocket::SocketError e)
{
if (m_active) {
setState(Error, m_socket.errorString());
+ close();
+ }
+}
+
+void NexusSSOLogin::onSslErrors(const QList<QSslError>& errors)
+{
+ if (m_active) {
+ for (const auto& e : errors) {
+ setState(Error, e.errorString());
+ }
}
}
@@ -271,18 +292,207 @@ void NexusSSOLogin::onTimeout()
}
+NexusKeyValidator::NexusKeyValidator(NXMAccessManager& am)
+ : m_manager(am), m_reply(nullptr), m_active(false)
+{
+ m_timeout.setInterval(NXMAccessManager::ValidationTimeout);
+ m_timeout.setSingleShot(true);
+
+ QObject::connect(&m_timeout, &QTimer::timeout, [&]{ onTimeout(); });
+}
+
+NexusKeyValidator::~NexusKeyValidator()
+{
+ abort();
+}
+
+void NexusKeyValidator::start(const QString& key)
+{
+ if (m_reply) {
+ abort();
+ return;
+ }
+
+ qDebug("Checking Nexus API Key...");
+ setState(Connecting);
+
+ const QString requestUrl(NexusBaseUrl + "/users/validate");
+ QNetworkRequest request(requestUrl);
+
+ request.setRawHeader("APIKEY", key.toUtf8());
+ request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, m_manager.userAgent().toUtf8());
+ request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
+ request.setRawHeader("Protocol-Version", "1.0.0");
+ request.setRawHeader("Application-Name", "MO2");
+ request.setRawHeader("Application-Version", m_manager.MOVersion().toUtf8());
+
+ m_reply = m_manager.get(request);
+ if (!m_reply) {
+ setState(Error, QObject::tr("Failed to request %1").arg(requestUrl));
+ return;
+ }
+
+ m_active = true;
+ m_timeout.start(NXMAccessManager::ValidationTimeout);
+
+ QObject::connect(
+ m_reply, &QNetworkReply::finished,
+ [&]{ onFinished(); });
+
+ QObject::connect(
+ m_reply, &QNetworkReply::sslErrors,
+ [&](auto&& errors){ onSslErrors(errors); });
+}
+
+void NexusKeyValidator::cancel()
+{
+ if (m_active) {
+ abort();
+ setState(Cancelled);
+ }
+}
+
+bool NexusKeyValidator::isActive() const
+{
+ return m_active;
+}
+
+void NexusKeyValidator::close()
+{
+ m_active = false;
+ m_timeout.stop();
+
+ if (m_reply) {
+ m_reply->disconnect();
+ m_reply->deleteLater();
+ m_reply = nullptr;
+ }
+}
+
+void NexusKeyValidator::abort()
+{
+ m_active = false;
+ m_timeout.stop();
+
+ if (m_reply) {
+ m_reply->disconnect();
+ m_reply->abort();
+ m_reply->deleteLater();
+ m_reply = nullptr;
+ }
+}
+
+void NexusKeyValidator::setState(States s, const QString& error)
+{
+ if (stateChanged) {
+ stateChanged(s, error);
+ }
+}
+
+void NexusKeyValidator::onFinished()
+{
+ if (!m_reply) {
+ // shouldn't happen
+ return;
+ }
+
+ m_timeout.stop();
+
+ const auto code = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ const auto doc = QJsonDocument::fromJson(m_reply->readAll());
+ const auto headers = m_reply->rawHeaderPairs();
+ const auto error = m_reply->errorString();
+
+ close();
+
+ const QJsonObject data = doc.object();
+
+ if (code != 200) {
+ handleError(code, data.value("message").toString(), error);
+ return;
+ }
+
+ if (doc.isNull()) {
+ setState(InvalidJson);
+ return;
+ }
+
+ if (!data.contains("user_id")) {
+ setState(BadResponse);
+ return;
+ }
+
+ const int id = data.value("user_id").toInt();
+ const QString key = data.value("key").toString();
+ const QString name = data.value("name").toString();
+ const bool premium = data.value("is_premium").toBool();
+
+ const auto user = APIUserAccount()
+ .apiKey(key)
+ .id(QString("%1").arg(id))
+ .name(name)
+ .type(premium ? APIUserAccountTypes::Premium : APIUserAccountTypes::Regular)
+ .limits(NexusInterface::parseLimits(headers));
+
+ if (finished) {
+ setState(Finished);
+ finished(user);
+ }
+}
+
+void NexusKeyValidator::onSslErrors(const QList<QSslError>& errors)
+{
+ if (m_active) {
+ for (const auto& e : errors) {
+ setState(Error, e.errorString());
+ }
+ }
+}
+
+void NexusKeyValidator::onTimeout()
+{
+ abort();
+ setState(Timeout);
+}
+
+void NexusKeyValidator::handleError(
+ int code, const QString& nexusMessage, const QString& httpError)
+{
+ QString s = httpError;
+
+ if (!nexusMessage.isEmpty()) {
+ if (!s.isEmpty()) {
+ s += ", ";
+ }
+
+ s += nexusMessage;
+ }
+
+ if (code != 0) {
+ if (s.isEmpty()) {
+ s = QString("HTTP code %1").arg(code);
+ } else {
+ s += QString(" (%1)").arg(code);
+ }
+ }
+
+ setState(Error, s);
+}
+
+
+
NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion)
: QNetworkAccessManager(parent)
- , m_ValidateReply(nullptr)
, m_ProgressDialog(new ValidationProgressDialog(ValidationTimeout))
, m_MOVersion(moVersion)
+ , m_validator(*this)
+ , m_validationState(NotChecked)
{
- m_ValidateTimeout.setSingleShot(true);
- m_ValidateTimeout.setInterval(ValidationTimeout);
+ m_validator.stateChanged = [&](auto&& s, auto&& e){ onValidatorState(s, e); };
+ m_validator.finished = [&](auto&& user){ onValidatorFinished(user); };
- connect(&m_ValidateTimeout, SIGNAL(timeout()), this, SLOT(validateTimeout()));
- setCookieJar(new PersistentCookieJar(
- QDir::fromNativeSeparators(Settings::instance().getCacheDirectory() + "/nexus_cookies.dat")));
+ setCookieJar(new PersistentCookieJar(QDir::fromNativeSeparators(
+ Settings::instance().getCacheDirectory() + "/nexus_cookies.dat")));
if (networkAccessible() == QNetworkAccessManager::UnknownAccessibility) {
// why is this necessary all of a sudden?
@@ -290,14 +500,6 @@ NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion)
}
}
-NXMAccessManager::~NXMAccessManager()
-{
- if (m_ValidateReply != nullptr) {
- m_ValidateReply->deleteLater();
- m_ValidateReply = nullptr;
- }
-}
-
void NXMAccessManager::setTopLevelWidget(QWidget* w)
{
m_ProgressDialog->setParentWidget(w);
@@ -323,7 +525,6 @@ QNetworkReply *NXMAccessManager::createRequest(
}
}
-
void NXMAccessManager::showCookies() const
{
QUrl url(NexusBaseUrl + "/");
@@ -344,80 +545,122 @@ void NXMAccessManager::clearCookies()
}
}
-void NXMAccessManager::startValidationCheck(bool showProgress)
+void NXMAccessManager::startValidationCheck(const QString& key, bool showProgress)
{
- qDebug("Checking Nexus API Key...");
- QString requestString = NexusBaseUrl + "/users/validate";
-
- QNetworkRequest request(requestString);
- request.setRawHeader("APIKEY", m_ApiKey.toUtf8());
- request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, userAgent().toUtf8());
- request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
- request.setRawHeader("Protocol-Version", "1.0.0");
- request.setRawHeader("Application-Name", "MO2");
- request.setRawHeader("Application-Version", m_MOVersion.toUtf8());
+ m_validationState = NotChecked;
+ m_validator.start(key);
if (showProgress) {
m_ProgressDialog->start();
}
+}
+
+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;
+ }
+ }
+}
- QCoreApplication::processEvents(); // for some reason the whole app hangs during the login. This way the user has at least a little feedback
+void NXMAccessManager::onValidatorFinished(const APIUserAccount& user)
+{
+ m_ProgressDialog->stop();
- m_ValidateReply = get(request);
- m_ValidateTimeout.start();
- m_ValidateState = VALIDATE_CHECKING;
- connect(m_ValidateReply, SIGNAL(finished()), this, SLOT(validateFinished()));
- connect(m_ValidateReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(validateError(QNetworkReply::NetworkError)));
+ m_validationState = Valid;
+ emit credentialsReceived(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_ValidateState == VALIDATE_CHECKING) {
+ if (m_validator.isActive()) {
m_ProgressDialog->show();
}
- return m_ValidateState == VALIDATE_VALID;
+ return (m_validationState == Valid);
}
-
void NXMAccessManager::refuseValidation()
{
- m_ValidateState = VALIDATE_REFUSED;
+ m_validationState = Invalid;
}
-
bool NXMAccessManager::validateAttempted() const
{
- return m_ValidateState != VALIDATE_NOT_CHECKED;
+ return (m_validationState != NotChecked);
}
-
bool NXMAccessManager::validateWaiting() const
{
- return m_ValidateReply != nullptr;
+ return m_validator.isActive();
}
-
void NXMAccessManager::apiCheck(const QString &apiKey, ApiCheckFlags flags)
{
- if (m_ValidateReply != nullptr) {
+ if (m_validator.isActive()) {
return;
}
if (flags & Force) {
- m_ValidateState = VALIDATE_NOT_CHECKED;
+ m_validationState = NotChecked;
}
- if (m_ValidateState == VALIDATE_VALID) {
+ if (m_validationState == Valid) {
emit validateSuccessful(false);
return;
}
- m_ApiKey = apiKey;
- startValidationCheck((flags & HideProgress) == 0);
+ startValidationCheck(apiKey, (flags & HideProgress) == 0);
}
+const QString& NXMAccessManager::MOVersion() const
+{
+ return m_MOVersion;
+}
QString NXMAccessManager::userAgent(const QString &subModule) const
{
@@ -436,100 +679,8 @@ QString NXMAccessManager::userAgent(const QString &subModule) const
return QString("Mod Organizer/%1 (%2) Qt/%3").arg(m_MOVersion, comments.join("; "), qVersion());
}
-
-QString NXMAccessManager::apiKey() const
-{
- return m_ApiKey;
-}
-
void NXMAccessManager::clearApiKey()
{
- m_ApiKey = "";
- m_ValidateState = VALIDATE_NOT_VALID;
-
+ m_validator.cancel();
emit credentialsReceived(APIUserAccount());
}
-
-void NXMAccessManager::validateTimeout()
-{
- m_ValidateTimeout.stop();
- m_ProgressDialog->stop();
-
- m_ApiKey.clear();
- m_ValidateState = VALIDATE_NOT_VALID;
-
- if (m_ValidateReply != nullptr) {
- m_ValidateReply->deleteLater();
- m_ValidateReply = nullptr;
- }
-
- emit validateFailed(tr("There was a timeout during the request"));
-}
-
-
-void NXMAccessManager::validateError(QNetworkReply::NetworkError)
-{
- m_ValidateTimeout.stop();
- m_ProgressDialog->stop();
-
- m_ApiKey.clear();
- m_ValidateState = VALIDATE_NOT_VALID;
-
- if (m_ValidateReply != nullptr) {
- m_ValidateReply->disconnect();
- QString error = m_ValidateReply->errorString();
- m_ValidateReply->deleteLater();
- m_ValidateReply = nullptr;
- emit validateFailed(error);
- } else {
- emit validateFailed(tr("Unknown error"));
- }
-}
-
-
-void NXMAccessManager::validateFinished()
-{
- m_ValidateTimeout.stop();
- m_ProgressDialog->stop();
-
- if (m_ValidateReply != nullptr) {
- QJsonDocument jdoc = QJsonDocument::fromJson(m_ValidateReply->readAll());
- if (!jdoc.isNull()) {
- QJsonObject credentialsData = jdoc.object();
- if (credentialsData.contains("user_id")) {
- int id = credentialsData.value("user_id").toInt();
- QString name = credentialsData.value("name").toString();
- bool premium = credentialsData.value("is_premium").toBool();
-
- const auto user = APIUserAccount()
- .id(QString("%1").arg(id))
- .name(name)
- .type(premium ? APIUserAccountTypes::Premium : APIUserAccountTypes::Regular)
- .limits(NexusInterface::parseLimits(m_ValidateReply));
-
-
- emit credentialsReceived(user);
-
- m_ValidateReply->deleteLater();
- m_ValidateReply = nullptr;
-
- m_ValidateState = VALIDATE_VALID;
- emit validateSuccessful(true);
-
- } else {
- m_ApiKey.clear();
- m_ValidateState = VALIDATE_NOT_VALID;
- emit validateFailed(tr("Validation failed, please reauthenticate in the Settings -> Nexus tab: %1").arg(credentialsData.value("message").toString()));
- }
- } else {
- m_ApiKey.clear();
- m_ValidateState = VALIDATE_NOT_CHECKED;
- emit validateFailed(tr("Could not parse response. Invalid JSON."));
- }
- }
- else {
- m_ApiKey.clear();
- m_ValidateState = VALIDATE_NOT_CHECKED;
- emit validateFailed(tr("Unknown error."));
- }
-}
diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h
index 08a799f9..11370d65 100644
--- a/src/nxmaccessmanager.h
+++ b/src/nxmaccessmanager.h
@@ -31,6 +31,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <set>
namespace MOBase { class IPluginGame; }
+class NXMAccessManager;
class ValidationProgressDialog : private QDialog
{
@@ -103,10 +104,56 @@ private:
void onMessage(const QString& s);
void onDisconnected();
void onError(QAbstractSocket::SocketError e);
+ void onSslErrors(const QList<QSslError>& errors);
void onTimeout();
};
+class NexusKeyValidator
+{
+public:
+ enum States
+ {
+ Connecting,
+ Finished,
+ InvalidJson,
+ BadResponse,
+ Timeout,
+ Cancelled,
+ Error
+ };
+
+ std::function<void (APIUserAccount)> finished;
+ std::function<void (States, QString)> stateChanged;
+
+ NexusKeyValidator(NXMAccessManager& am);
+ ~NexusKeyValidator();
+
+ void start(const QString& key);
+ void cancel();
+
+ bool isActive() const;
+
+private:
+ NXMAccessManager& m_manager;
+ QNetworkReply* m_reply;
+ QTimer m_timeout;
+ bool m_active;
+
+ void setState(States s, const QString& error={});
+
+ void close();
+ void abort();
+
+ void onFinished();
+ void onSslErrors(const QList<QSslError>& errors);
+ void onTimeout();
+
+ void handleError(
+ int code, const QString& nexusMessage, const QString& httpError);
+};
+
+
/**
* @brief access manager extended to handle nxm links
**/
@@ -127,7 +174,6 @@ public:
explicit NXMAccessManager(QObject *parent, const QString &moVersion);
- ~NXMAccessManager();
void setTopLevelWidget(QWidget* w);
@@ -143,8 +189,8 @@ public:
void clearCookies();
QString userAgent(const QString &subModule = QString()) const;
+ const QString& MOVersion() const;
- QString apiKey() const;
void clearApiKey();
void refuseValidation();
@@ -164,17 +210,9 @@ signals:
* @param necessary true if a login was necessary and succeeded, false if the user is still logged in
**/
void validateSuccessful(bool necessary);
-
void validateFailed(const QString &message);
-
void credentialsReceived(const APIUserAccount& user);
-private slots:
-
- void validateFinished();
- void validateError(QNetworkReply::NetworkError errorCode);
- void validateTimeout();
-
protected:
virtual QNetworkReply *createRequest(
@@ -182,25 +220,23 @@ protected:
QIODevice *device);
private:
+ enum States
+ {
+ NotChecked,
+ Valid,
+ Invalid
+ };
+
QWidget* m_TopLevel;
- QTimer m_ValidateTimeout;
- QNetworkReply *m_ValidateReply;
mutable ValidationProgressDialog* m_ProgressDialog;
-
QString m_MOVersion;
+ NexusKeyValidator m_validator;
+ States m_validationState;
- QString m_ApiKey;
-
- enum {
- VALIDATE_NOT_CHECKED,
- VALIDATE_CHECKING,
- VALIDATE_NOT_VALID,
- VALIDATE_ATTEMPT_FAILED,
- VALIDATE_REFUSED,
- VALIDATE_VALID
- } m_ValidateState = VALIDATE_NOT_CHECKED;
-
- void startValidationCheck(bool showProgress);
+ 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/organizercore.cpp b/src/organizercore.cpp
index 65c8eb81..87668f4b 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -2484,7 +2484,8 @@ void OrganizerCore::loginSuccessfulUpdate(bool necessary)
void OrganizerCore::loginFailed(const QString &message)
{
- qDebug("Nexus API validation failed: %s", qUtf8Printable(message));
+ qDebug().nospace().noquote()
+ << "Nexus API validation failed: " << message;
if (QMessageBox::question(qApp->activeWindow(), tr("Login failed"),
tr("Login failed, try again?"))