diff --git a/libraries/shared/src/AccountManager.cpp b/libraries/shared/src/AccountManager.cpp index 501c4a6ca5..05d66a61f4 100644 --- a/libraries/shared/src/AccountManager.cpp +++ b/libraries/shared/src/AccountManager.cpp @@ -26,17 +26,21 @@ AccountManager& AccountManager::getInstance() { } Q_DECLARE_METATYPE(OAuthAccessToken) +Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) +Q_DECLARE_METATYPE(JSONCallbackParameters) const QString ACCOUNT_TOKEN_GROUP = "tokens"; AccountManager::AccountManager() : _rootURL(), _username(), - _networkAccessManager(new QNetworkAccessManager), + _networkAccessManager(), _pendingCallbackMap() { qRegisterMetaType("OAuthAccessToken"); qRegisterMetaTypeStreamOperators("OAuthAccessToken"); + qRegisterMetaType("QNetworkAccessManager::Operation"); + qRegisterMetaType("JSONCallbackParameters"); // check if there are existing access tokens to load from settings QSettings settings; @@ -53,9 +57,32 @@ AccountManager::AccountManager() : } } +void AccountManager::setRootURL(const QUrl& rootURL) { + + if (_rootURL != rootURL) { + _rootURL = rootURL; + + // we have an auth URL change, set the username empty + // we will need to ask for profile information again + _username.clear(); + + qDebug() << "URL for node authentication has been changed to" << qPrintable(_rootURL.toString()); + qDebug() << "Re-setting authentication flow."; + } +} + void AccountManager::authenticatedRequest(const QString& path, QNetworkAccessManager::Operation operation, const JSONCallbackParameters& callbackParams, const QByteArray& dataByteArray) { - if (_networkAccessManager && hasValidAccessToken()) { + QMetaObject::invokeMethod(this, "invokedRequest", + Q_ARG(const QString&, path), + Q_ARG(QNetworkAccessManager::Operation, operation), + Q_ARG(const JSONCallbackParameters&, callbackParams), + Q_ARG(const QByteArray&, dataByteArray)); +} + +void AccountManager::invokedRequest(const QString& path, QNetworkAccessManager::Operation operation, + const JSONCallbackParameters& callbackParams, const QByteArray& dataByteArray) { + if (hasValidAccessToken()) { QNetworkRequest authenticatedRequest; QUrl requestURL = _rootURL; @@ -70,11 +97,11 @@ void AccountManager::authenticatedRequest(const QString& path, QNetworkAccessMan switch (operation) { case QNetworkAccessManager::GetOperation: - networkReply = _networkAccessManager->get(authenticatedRequest); + networkReply = _networkAccessManager.get(authenticatedRequest); break; case QNetworkAccessManager::PostOperation: authenticatedRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - networkReply = _networkAccessManager->post(authenticatedRequest, dataByteArray); + networkReply = _networkAccessManager.post(authenticatedRequest, dataByteArray); default: // other methods not yet handled break; @@ -155,24 +182,22 @@ bool AccountManager::checkAndSignalForAccessToken() { } void AccountManager::requestAccessToken(const QString& login, const QString& password) { - if (_networkAccessManager) { - QNetworkRequest request; - - QUrl grantURL = _rootURL; - grantURL.setPath("/oauth/token"); - - QByteArray postData; - postData.append("grant_type=password&"); - postData.append("username=" + login + "&"); - postData.append("password=" + password); - - request.setUrl(grantURL); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - - QNetworkReply* requestReply = _networkAccessManager->post(request, postData); - connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestFinished); - connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError))); - } + QNetworkRequest request; + + QUrl grantURL = _rootURL; + grantURL.setPath("/oauth/token"); + + QByteArray postData; + postData.append("grant_type=password&"); + postData.append("username=" + login + "&"); + postData.append("password=" + password); + + request.setUrl(grantURL); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + + QNetworkReply* requestReply = _networkAccessManager.post(request, postData); + connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestFinished); + connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError))); } diff --git a/libraries/shared/src/AccountManager.h b/libraries/shared/src/AccountManager.h index 5da13b5560..6479711754 100644 --- a/libraries/shared/src/AccountManager.h +++ b/libraries/shared/src/AccountManager.h @@ -42,7 +42,7 @@ public: const JSONCallbackParameters& callbackParams = JSONCallbackParameters(), const QByteArray& dataByteArray = QByteArray()); - void setRootURL(const QUrl& rootURL) { _rootURL = rootURL; } + void setRootURL(const QUrl& rootURL); bool hasValidAccessToken(); bool checkAndSignalForAccessToken(); @@ -66,9 +66,12 @@ private: AccountManager(AccountManager const& other); // not implemented void operator=(AccountManager const& other); // not implemented + Q_INVOKABLE void invokedRequest(const QString& path, QNetworkAccessManager::Operation operation, + const JSONCallbackParameters& callbackParams, const QByteArray& dataByteArray); + QUrl _rootURL; QString _username; - QNetworkAccessManager* _networkAccessManager; + QNetworkAccessManager _networkAccessManager; QMap _pendingCallbackMap; static QMap _accessTokens; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index ea07c3bdc1..a8d39d05f7 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -111,8 +111,13 @@ bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { if (checkType == PacketTypeDomainList) { if (_domainInfo.getRootAuthenticationURL().isEmpty() && _domainInfo.getUUID().isNull()) { + // if this is a domain-server that doesn't require auth, // pull the UUID from this packet and set it as our domain-server UUID _domainInfo.setUUID(uuidFromPacketHeader(packet)); + + // we also know this domain-server requires no authentication + // so set the account manager root URL empty + AccountManager::getInstance().setRootURL(QUrl()); } if (_domainInfo.getUUID() == uuidFromPacketHeader(packet)) {