mirror of
https://github.com/overte-org/overte.git
synced 2025-07-10 04:40:26 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into OculusOverlay
This commit is contained in:
commit
7e4317d5d2
6 changed files with 163 additions and 106 deletions
|
@ -132,7 +132,7 @@ Menu::Menu() :
|
||||||
toggleLoginMenuItem();
|
toggleLoginMenuItem();
|
||||||
|
|
||||||
// connect to the appropriate slots of the AccountManager so that we can change the Login/Logout menu item
|
// connect to the appropriate slots of the AccountManager so that we can change the Login/Logout menu item
|
||||||
connect(&accountManager, &AccountManager::accessTokenChanged, this, &Menu::toggleLoginMenuItem);
|
connect(&accountManager, &AccountManager::profileChanged, this, &Menu::toggleLoginMenuItem);
|
||||||
connect(&accountManager, &AccountManager::logoutComplete, this, &Menu::toggleLoginMenuItem);
|
connect(&accountManager, &AccountManager::logoutComplete, this, &Menu::toggleLoginMenuItem);
|
||||||
|
|
||||||
addDisabledActionAndSeparator(fileMenu, "Scripts");
|
addDisabledActionAndSeparator(fileMenu, "Scripts");
|
||||||
|
@ -331,7 +331,7 @@ Menu::Menu() :
|
||||||
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, "None", 0, true));
|
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, "None", 0, true));
|
||||||
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false));
|
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false));
|
||||||
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false));
|
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, true);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, true);
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::BuckyBalls, 0, false);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::BuckyBalls, 0, false);
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Particles, 0, true);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Particles, 0, true);
|
||||||
|
@ -411,7 +411,7 @@ Menu::Menu() :
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::DisableNackPackets, 0, false);
|
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::DisableNackPackets, 0, false);
|
||||||
|
|
||||||
addDisabledActionAndSeparator(developerMenu, "Testing");
|
addDisabledActionAndSeparator(developerMenu, "Testing");
|
||||||
|
|
||||||
QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools");
|
QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools");
|
||||||
QMenu* perfTimerMenu = timingMenu->addMenu("Performance Timer");
|
QMenu* perfTimerMenu = timingMenu->addMenu("Performance Timer");
|
||||||
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::DisplayTimingDetails, 0, true);
|
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::DisplayTimingDetails, 0, true);
|
||||||
|
@ -466,7 +466,7 @@ Menu::Menu() :
|
||||||
false,
|
false,
|
||||||
appInstance->getAudio(),
|
appInstance->getAudio(),
|
||||||
SLOT(toggleToneInjection()));
|
SLOT(toggleToneInjection()));
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioScope,
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioScope,
|
||||||
Qt::CTRL | Qt::Key_P, false,
|
Qt::CTRL | Qt::Key_P, false,
|
||||||
appInstance->getAudio(),
|
appInstance->getAudio(),
|
||||||
SLOT(toggleScope()));
|
SLOT(toggleScope()));
|
||||||
|
@ -1779,4 +1779,3 @@ QString Menu::getSnapshotsLocation() const {
|
||||||
}
|
}
|
||||||
return _snapshotsLocation;
|
return _snapshotsLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ XmppClient::XmppClient() :
|
||||||
_xmppMUCManager()
|
_xmppMUCManager()
|
||||||
{
|
{
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
connect(&accountManager, SIGNAL(accessTokenChanged()), this, SLOT(connectToServer()));
|
connect(&accountManager, SIGNAL(profileChanged()), this, SLOT(connectToServer()));
|
||||||
connect(&accountManager, SIGNAL(logoutComplete()), this, SLOT(disconnectFromServer()));
|
connect(&accountManager, SIGNAL(logoutComplete()), this, SLOT(disconnectFromServer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,13 +55,13 @@ AccountManager::AccountManager() :
|
||||||
{
|
{
|
||||||
qRegisterMetaType<OAuthAccessToken>("OAuthAccessToken");
|
qRegisterMetaType<OAuthAccessToken>("OAuthAccessToken");
|
||||||
qRegisterMetaTypeStreamOperators<OAuthAccessToken>("OAuthAccessToken");
|
qRegisterMetaTypeStreamOperators<OAuthAccessToken>("OAuthAccessToken");
|
||||||
|
|
||||||
qRegisterMetaType<DataServerAccountInfo>("DataServerAccountInfo");
|
qRegisterMetaType<DataServerAccountInfo>("DataServerAccountInfo");
|
||||||
qRegisterMetaTypeStreamOperators<DataServerAccountInfo>("DataServerAccountInfo");
|
qRegisterMetaTypeStreamOperators<DataServerAccountInfo>("DataServerAccountInfo");
|
||||||
|
|
||||||
qRegisterMetaType<QNetworkAccessManager::Operation>("QNetworkAccessManager::Operation");
|
qRegisterMetaType<QNetworkAccessManager::Operation>("QNetworkAccessManager::Operation");
|
||||||
qRegisterMetaType<JSONCallbackParameters>("JSONCallbackParameters");
|
qRegisterMetaType<JSONCallbackParameters>("JSONCallbackParameters");
|
||||||
|
|
||||||
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,18 +70,18 @@ const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash";
|
||||||
void AccountManager::logout() {
|
void AccountManager::logout() {
|
||||||
// a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file
|
// a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file
|
||||||
_accountInfo = DataServerAccountInfo();
|
_accountInfo = DataServerAccountInfo();
|
||||||
|
|
||||||
emit balanceChanged(0);
|
emit balanceChanged(0);
|
||||||
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.beginGroup(ACCOUNTS_GROUP);
|
settings.beginGroup(ACCOUNTS_GROUP);
|
||||||
|
|
||||||
QString keyURLString(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE));
|
QString keyURLString(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE));
|
||||||
settings.remove(keyURLString);
|
settings.remove(keyURLString);
|
||||||
|
|
||||||
qDebug() << "Removed account info for" << _authURL << "from in-memory accounts and .ini file";
|
qDebug() << "Removed account info for" << _authURL << "from in-memory accounts and .ini file";
|
||||||
|
|
||||||
emit logoutComplete();
|
emit logoutComplete();
|
||||||
// the username has changed to blank
|
// the username has changed to blank
|
||||||
emit usernameChanged(QString());
|
emit usernameChanged(QString());
|
||||||
|
@ -93,7 +93,7 @@ void AccountManager::updateBalance() {
|
||||||
JSONCallbackParameters callbackParameters;
|
JSONCallbackParameters callbackParameters;
|
||||||
callbackParameters.jsonCallbackReceiver = &_accountInfo;
|
callbackParameters.jsonCallbackReceiver = &_accountInfo;
|
||||||
callbackParameters.jsonCallbackMethod = "setBalanceFromJSON";
|
callbackParameters.jsonCallbackMethod = "setBalanceFromJSON";
|
||||||
|
|
||||||
authenticatedRequest("/api/v1/wallets/mine", QNetworkAccessManager::GetOperation, callbackParameters);
|
authenticatedRequest("/api/v1/wallets/mine", QNetworkAccessManager::GetOperation, callbackParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,28 +105,33 @@ void AccountManager::accountInfoBalanceChanged(qint64 newBalance) {
|
||||||
void AccountManager::setAuthURL(const QUrl& authURL) {
|
void AccountManager::setAuthURL(const QUrl& authURL) {
|
||||||
if (_authURL != authURL) {
|
if (_authURL != authURL) {
|
||||||
_authURL = authURL;
|
_authURL = authURL;
|
||||||
|
|
||||||
qDebug() << "URL for node authentication has been changed to" << qPrintable(_authURL.toString());
|
qDebug() << "URL for node authentication has been changed to" << qPrintable(_authURL.toString());
|
||||||
qDebug() << "Re-setting authentication flow.";
|
qDebug() << "Re-setting authentication flow.";
|
||||||
|
|
||||||
// check if there are existing access tokens to load from settings
|
// check if there are existing access tokens to load from settings
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.beginGroup(ACCOUNTS_GROUP);
|
settings.beginGroup(ACCOUNTS_GROUP);
|
||||||
|
|
||||||
foreach(const QString& key, settings.allKeys()) {
|
foreach(const QString& key, settings.allKeys()) {
|
||||||
// take a key copy to perform the double slash replacement
|
// take a key copy to perform the double slash replacement
|
||||||
QString keyCopy(key);
|
QString keyCopy(key);
|
||||||
QUrl keyURL(keyCopy.replace("slashslash", "//"));
|
QUrl keyURL(keyCopy.replace("slashslash", "//"));
|
||||||
|
|
||||||
if (keyURL == _authURL) {
|
if (keyURL == _authURL) {
|
||||||
// pull out the stored access token and store it in memory
|
// pull out the stored access token and store it in memory
|
||||||
_accountInfo = settings.value(key).value<DataServerAccountInfo>();
|
_accountInfo = settings.value(key).value<DataServerAccountInfo>();
|
||||||
qDebug() << "Found a data-server access token for" << qPrintable(keyURL.toString());
|
qDebug() << "Found a data-server access token for" << qPrintable(keyURL.toString());
|
||||||
|
|
||||||
emit accessTokenChanged();
|
// profile info isn't guaranteed to be saved too
|
||||||
|
if (_accountInfo.hasProfile()) {
|
||||||
|
emit profileChanged();
|
||||||
|
} else {
|
||||||
|
requestProfile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tell listeners that the auth endpoint has changed
|
// tell listeners that the auth endpoint has changed
|
||||||
emit authEndpointChanged();
|
emit authEndpointChanged();
|
||||||
}
|
}
|
||||||
|
@ -147,36 +152,36 @@ void AccountManager::authenticatedRequest(const QString& path, QNetworkAccessMan
|
||||||
void AccountManager::invokedRequest(const QString& path, QNetworkAccessManager::Operation operation,
|
void AccountManager::invokedRequest(const QString& path, QNetworkAccessManager::Operation operation,
|
||||||
const JSONCallbackParameters& callbackParams,
|
const JSONCallbackParameters& callbackParams,
|
||||||
const QByteArray& dataByteArray, QHttpMultiPart* dataMultiPart) {
|
const QByteArray& dataByteArray, QHttpMultiPart* dataMultiPart) {
|
||||||
|
|
||||||
if (!_networkAccessManager) {
|
if (!_networkAccessManager) {
|
||||||
_networkAccessManager = new QNetworkAccessManager(this);
|
_networkAccessManager = new QNetworkAccessManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasValidAccessToken()) {
|
if (hasValidAccessToken()) {
|
||||||
QNetworkRequest authenticatedRequest;
|
QNetworkRequest authenticatedRequest;
|
||||||
|
|
||||||
QUrl requestURL = _authURL;
|
QUrl requestURL = _authURL;
|
||||||
|
|
||||||
if (path.startsWith("/")) {
|
if (path.startsWith("/")) {
|
||||||
requestURL.setPath(path);
|
requestURL.setPath(path);
|
||||||
} else {
|
} else {
|
||||||
requestURL.setPath("/" + path);
|
requestURL.setPath("/" + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
requestURL.setQuery("access_token=" + _accountInfo.getAccessToken().token);
|
requestURL.setQuery("access_token=" + _accountInfo.getAccessToken().token);
|
||||||
|
|
||||||
authenticatedRequest.setUrl(requestURL);
|
authenticatedRequest.setUrl(requestURL);
|
||||||
|
|
||||||
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
||||||
qDebug() << "Making an authenticated request to" << qPrintable(requestURL.toString());
|
qDebug() << "Making an authenticated request to" << qPrintable(requestURL.toString());
|
||||||
|
|
||||||
if (!dataByteArray.isEmpty()) {
|
if (!dataByteArray.isEmpty()) {
|
||||||
qDebug() << "The POST/PUT body -" << QString(dataByteArray);
|
qDebug() << "The POST/PUT body -" << QString(dataByteArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply* networkReply = NULL;
|
QNetworkReply* networkReply = NULL;
|
||||||
|
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case QNetworkAccessManager::GetOperation:
|
case QNetworkAccessManager::GetOperation:
|
||||||
networkReply = _networkAccessManager->get(authenticatedRequest);
|
networkReply = _networkAccessManager->get(authenticatedRequest);
|
||||||
|
@ -198,24 +203,24 @@ void AccountManager::invokedRequest(const QString& path, QNetworkAccessManager::
|
||||||
networkReply = _networkAccessManager->put(authenticatedRequest, dataByteArray);
|
networkReply = _networkAccessManager->put(authenticatedRequest, dataByteArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// other methods not yet handled
|
// other methods not yet handled
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (networkReply) {
|
if (networkReply) {
|
||||||
if (!callbackParams.isEmpty()) {
|
if (!callbackParams.isEmpty()) {
|
||||||
// if we have information for a callback, insert the callbackParams into our local map
|
// if we have information for a callback, insert the callbackParams into our local map
|
||||||
_pendingCallbackMap.insert(networkReply, callbackParams);
|
_pendingCallbackMap.insert(networkReply, callbackParams);
|
||||||
|
|
||||||
if (callbackParams.updateReciever && !callbackParams.updateSlot.isEmpty()) {
|
if (callbackParams.updateReciever && !callbackParams.updateSlot.isEmpty()) {
|
||||||
callbackParams.updateReciever->connect(networkReply, SIGNAL(uploadProgress(qint64, qint64)),
|
callbackParams.updateReciever->connect(networkReply, SIGNAL(uploadProgress(qint64, qint64)),
|
||||||
callbackParams.updateSlot.toStdString().c_str());
|
callbackParams.updateSlot.toStdString().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we ended up firing of a request, hook up to it now
|
// if we ended up firing of a request, hook up to it now
|
||||||
connect(networkReply, SIGNAL(finished()), SLOT(processReply()));
|
connect(networkReply, SIGNAL(finished()), SLOT(processReply()));
|
||||||
}
|
}
|
||||||
|
@ -224,7 +229,7 @@ void AccountManager::invokedRequest(const QString& path, QNetworkAccessManager::
|
||||||
|
|
||||||
void AccountManager::processReply() {
|
void AccountManager::processReply() {
|
||||||
QNetworkReply* requestReply = reinterpret_cast<QNetworkReply*>(sender());
|
QNetworkReply* requestReply = reinterpret_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
if (requestReply->error() == QNetworkReply::NoError) {
|
if (requestReply->error() == QNetworkReply::NoError) {
|
||||||
passSuccessToCallback(requestReply);
|
passSuccessToCallback(requestReply);
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,17 +240,17 @@ void AccountManager::processReply() {
|
||||||
|
|
||||||
void AccountManager::passSuccessToCallback(QNetworkReply* requestReply) {
|
void AccountManager::passSuccessToCallback(QNetworkReply* requestReply) {
|
||||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll());
|
QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll());
|
||||||
|
|
||||||
JSONCallbackParameters callbackParams = _pendingCallbackMap.value(requestReply);
|
JSONCallbackParameters callbackParams = _pendingCallbackMap.value(requestReply);
|
||||||
|
|
||||||
if (callbackParams.jsonCallbackReceiver) {
|
if (callbackParams.jsonCallbackReceiver) {
|
||||||
// invoke the right method on the callback receiver
|
// invoke the right method on the callback receiver
|
||||||
QMetaObject::invokeMethod(callbackParams.jsonCallbackReceiver, qPrintable(callbackParams.jsonCallbackMethod),
|
QMetaObject::invokeMethod(callbackParams.jsonCallbackReceiver, qPrintable(callbackParams.jsonCallbackMethod),
|
||||||
Q_ARG(const QJsonObject&, jsonResponse.object()));
|
Q_ARG(const QJsonObject&, jsonResponse.object()));
|
||||||
|
|
||||||
// remove the related reply-callback group from the map
|
// remove the related reply-callback group from the map
|
||||||
_pendingCallbackMap.remove(requestReply);
|
_pendingCallbackMap.remove(requestReply);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
||||||
qDebug() << "Received JSON response from data-server that has no matching callback.";
|
qDebug() << "Received JSON response from data-server that has no matching callback.";
|
||||||
|
@ -256,13 +261,13 @@ void AccountManager::passSuccessToCallback(QNetworkReply* requestReply) {
|
||||||
|
|
||||||
void AccountManager::passErrorToCallback(QNetworkReply* requestReply) {
|
void AccountManager::passErrorToCallback(QNetworkReply* requestReply) {
|
||||||
JSONCallbackParameters callbackParams = _pendingCallbackMap.value(requestReply);
|
JSONCallbackParameters callbackParams = _pendingCallbackMap.value(requestReply);
|
||||||
|
|
||||||
if (callbackParams.errorCallbackReceiver) {
|
if (callbackParams.errorCallbackReceiver) {
|
||||||
// invoke the right method on the callback receiver
|
// invoke the right method on the callback receiver
|
||||||
QMetaObject::invokeMethod(callbackParams.errorCallbackReceiver, qPrintable(callbackParams.errorCallbackMethod),
|
QMetaObject::invokeMethod(callbackParams.errorCallbackReceiver, qPrintable(callbackParams.errorCallbackMethod),
|
||||||
Q_ARG(QNetworkReply::NetworkError, requestReply->error()),
|
Q_ARG(QNetworkReply::NetworkError, requestReply->error()),
|
||||||
Q_ARG(const QString&, requestReply->errorString()));
|
Q_ARG(const QString&, requestReply->errorString()));
|
||||||
|
|
||||||
// remove the related reply-callback group from the map
|
// remove the related reply-callback group from the map
|
||||||
_pendingCallbackMap.remove(requestReply);
|
_pendingCallbackMap.remove(requestReply);
|
||||||
} else {
|
} else {
|
||||||
|
@ -274,12 +279,12 @@ void AccountManager::passErrorToCallback(QNetworkReply* requestReply) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AccountManager::hasValidAccessToken() {
|
bool AccountManager::hasValidAccessToken() {
|
||||||
|
|
||||||
if (_accountInfo.getAccessToken().token.isEmpty() || _accountInfo.getAccessToken().isExpired()) {
|
if (_accountInfo.getAccessToken().token.isEmpty() || _accountInfo.getAccessToken().isExpired()) {
|
||||||
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
||||||
qDebug() << "An access token is required for requests to" << qPrintable(_authURL.toString());
|
qDebug() << "An access token is required for requests to" << qPrintable(_authURL.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
@ -288,12 +293,12 @@ bool AccountManager::hasValidAccessToken() {
|
||||||
|
|
||||||
bool AccountManager::checkAndSignalForAccessToken() {
|
bool AccountManager::checkAndSignalForAccessToken() {
|
||||||
bool hasToken = hasValidAccessToken();
|
bool hasToken = hasValidAccessToken();
|
||||||
|
|
||||||
if (!hasToken) {
|
if (!hasToken) {
|
||||||
// emit a signal so somebody can call back to us and request an access token given a username and password
|
// emit a signal so somebody can call back to us and request an access token given a username and password
|
||||||
emit authRequired();
|
emit authRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasToken;
|
return hasToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,36 +309,36 @@ void AccountManager::requestAccessToken(const QString& login, const QString& pas
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
|
|
||||||
QUrl grantURL = _authURL;
|
QUrl grantURL = _authURL;
|
||||||
grantURL.setPath("/oauth/token");
|
grantURL.setPath("/oauth/token");
|
||||||
|
|
||||||
const QString ACCOUNT_MANAGER_REQUESTED_SCOPE = "owner";
|
const QString ACCOUNT_MANAGER_REQUESTED_SCOPE = "owner";
|
||||||
|
|
||||||
QByteArray postData;
|
QByteArray postData;
|
||||||
postData.append("grant_type=password&");
|
postData.append("grant_type=password&");
|
||||||
postData.append("username=" + login + "&");
|
postData.append("username=" + login + "&");
|
||||||
postData.append("password=" + QUrl::toPercentEncoding(password) + "&");
|
postData.append("password=" + QUrl::toPercentEncoding(password) + "&");
|
||||||
postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
|
postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
|
||||||
|
|
||||||
request.setUrl(grantURL);
|
request.setUrl(grantURL);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
QNetworkReply* requestReply = _networkAccessManager->post(request, postData);
|
QNetworkReply* requestReply = _networkAccessManager->post(request, postData);
|
||||||
connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestFinished);
|
connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestAccessTokenFinished);
|
||||||
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError)));
|
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AccountManager::requestFinished() {
|
void AccountManager::requestAccessTokenFinished() {
|
||||||
QNetworkReply* requestReply = reinterpret_cast<QNetworkReply*>(sender());
|
QNetworkReply* requestReply = reinterpret_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll());
|
QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll());
|
||||||
const QJsonObject& rootObject = jsonResponse.object();
|
const QJsonObject& rootObject = jsonResponse.object();
|
||||||
|
|
||||||
if (!rootObject.contains("error")) {
|
if (!rootObject.contains("error")) {
|
||||||
// construct an OAuthAccessToken from the json object
|
// construct an OAuthAccessToken from the json object
|
||||||
|
|
||||||
if (!rootObject.contains("access_token") || !rootObject.contains("expires_in")
|
if (!rootObject.contains("access_token") || !rootObject.contains("expires_in")
|
||||||
|| !rootObject.contains("token_type")) {
|
|| !rootObject.contains("token_type")) {
|
||||||
// TODO: error handling - malformed token response
|
// TODO: error handling - malformed token response
|
||||||
|
@ -342,23 +347,21 @@ void AccountManager::requestFinished() {
|
||||||
// clear the path from the response URL so we have the right root URL for this access token
|
// clear the path from the response URL so we have the right root URL for this access token
|
||||||
QUrl rootURL = requestReply->url();
|
QUrl rootURL = requestReply->url();
|
||||||
rootURL.setPath("");
|
rootURL.setPath("");
|
||||||
|
|
||||||
qDebug() << "Storing an account with access-token for" << qPrintable(rootURL.toString());
|
qDebug() << "Storing an account with access-token for" << qPrintable(rootURL.toString());
|
||||||
|
|
||||||
_accountInfo = DataServerAccountInfo(rootObject);
|
_accountInfo = DataServerAccountInfo();
|
||||||
|
_accountInfo.setAccessTokenFromJSON(rootObject);
|
||||||
|
|
||||||
emit loginComplete(rootURL);
|
emit loginComplete(rootURL);
|
||||||
// the username has changed to whatever came back
|
|
||||||
emit usernameChanged(_accountInfo.getUsername());
|
|
||||||
|
|
||||||
// we have found or requested an access token
|
|
||||||
emit accessTokenChanged();
|
|
||||||
|
|
||||||
// store this access token into the local settings
|
// store this access token into the local settings
|
||||||
QSettings localSettings;
|
QSettings localSettings;
|
||||||
localSettings.beginGroup(ACCOUNTS_GROUP);
|
localSettings.beginGroup(ACCOUNTS_GROUP);
|
||||||
localSettings.setValue(rootURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
|
localSettings.setValue(rootURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
|
||||||
QVariant::fromValue(_accountInfo));
|
QVariant::fromValue(_accountInfo));
|
||||||
|
|
||||||
|
requestProfile();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: error handling
|
// TODO: error handling
|
||||||
|
@ -367,7 +370,53 @@ void AccountManager::requestFinished() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountManager::requestError(QNetworkReply::NetworkError error) {
|
void AccountManager::requestAccessTokenError(QNetworkReply::NetworkError error) {
|
||||||
// TODO: error handling
|
// TODO: error handling
|
||||||
qDebug() << "AccountManager requestError - " << error;
|
qDebug() << "AccountManager requestError - " << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AccountManager::requestProfile() {
|
||||||
|
if (!_networkAccessManager) {
|
||||||
|
_networkAccessManager = new QNetworkAccessManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl profileURL = _authURL;
|
||||||
|
profileURL.setPath("/api/v1/users/profile");
|
||||||
|
profileURL.setQuery("access_token=" + _accountInfo.getAccessToken().token);
|
||||||
|
|
||||||
|
QNetworkReply* profileReply = _networkAccessManager->get(QNetworkRequest(profileURL));
|
||||||
|
connect(profileReply, &QNetworkReply::finished, this, &AccountManager::requestProfileFinished);
|
||||||
|
connect(profileReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestProfileError(QNetworkReply::NetworkError)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManager::requestProfileFinished() {
|
||||||
|
QNetworkReply* profileReply = reinterpret_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
|
QJsonDocument jsonResponse = QJsonDocument::fromJson(profileReply->readAll());
|
||||||
|
const QJsonObject& rootObject = jsonResponse.object();
|
||||||
|
|
||||||
|
if (rootObject.contains("status") && rootObject["status"].toString() == "success") {
|
||||||
|
_accountInfo.setProfileInfoFromJSON(rootObject);
|
||||||
|
|
||||||
|
emit profileChanged();
|
||||||
|
|
||||||
|
// the username has changed to whatever came back
|
||||||
|
emit usernameChanged(_accountInfo.getUsername());
|
||||||
|
|
||||||
|
// store the whole profile into the local settings
|
||||||
|
QUrl rootURL = profileReply->url();
|
||||||
|
rootURL.setPath("");
|
||||||
|
QSettings localSettings;
|
||||||
|
localSettings.beginGroup(ACCOUNTS_GROUP);
|
||||||
|
localSettings.setValue(rootURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
|
||||||
|
QVariant::fromValue(_accountInfo));
|
||||||
|
} else {
|
||||||
|
// TODO: error handling
|
||||||
|
qDebug() << "Error in response for profile";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountManager::requestProfileError(QNetworkReply::NetworkError error) {
|
||||||
|
// TODO: error handling
|
||||||
|
qDebug() << "AccountManager requestProfileError - " << error;
|
||||||
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
class JSONCallbackParameters {
|
class JSONCallbackParameters {
|
||||||
public:
|
public:
|
||||||
JSONCallbackParameters();
|
JSONCallbackParameters();
|
||||||
|
|
||||||
bool isEmpty() const { return !jsonCallbackReceiver && !errorCallbackReceiver; }
|
bool isEmpty() const { return !jsonCallbackReceiver && !errorCallbackReceiver; }
|
||||||
|
|
||||||
QObject* jsonCallbackReceiver;
|
QObject* jsonCallbackReceiver;
|
||||||
QString jsonCallbackMethod;
|
QString jsonCallbackMethod;
|
||||||
QObject* errorCallbackReceiver;
|
QObject* errorCallbackReceiver;
|
||||||
|
@ -38,30 +38,33 @@ class AccountManager : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static AccountManager& getInstance();
|
static AccountManager& getInstance();
|
||||||
|
|
||||||
void authenticatedRequest(const QString& path,
|
void authenticatedRequest(const QString& path,
|
||||||
QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation,
|
QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation,
|
||||||
const JSONCallbackParameters& callbackParams = JSONCallbackParameters(),
|
const JSONCallbackParameters& callbackParams = JSONCallbackParameters(),
|
||||||
const QByteArray& dataByteArray = QByteArray(),
|
const QByteArray& dataByteArray = QByteArray(),
|
||||||
QHttpMultiPart* dataMultiPart = NULL);
|
QHttpMultiPart* dataMultiPart = NULL);
|
||||||
|
|
||||||
const QUrl& getAuthURL() const { return _authURL; }
|
const QUrl& getAuthURL() const { return _authURL; }
|
||||||
void setAuthURL(const QUrl& authURL);
|
void setAuthURL(const QUrl& authURL);
|
||||||
bool hasAuthEndpoint() { return !_authURL.isEmpty(); }
|
bool hasAuthEndpoint() { return !_authURL.isEmpty(); }
|
||||||
|
|
||||||
bool isLoggedIn() { return !_authURL.isEmpty() && hasValidAccessToken(); }
|
bool isLoggedIn() { return !_authURL.isEmpty() && hasValidAccessToken(); }
|
||||||
bool hasValidAccessToken();
|
bool hasValidAccessToken();
|
||||||
Q_INVOKABLE bool checkAndSignalForAccessToken();
|
Q_INVOKABLE bool checkAndSignalForAccessToken();
|
||||||
|
|
||||||
void requestAccessToken(const QString& login, const QString& password);
|
void requestAccessToken(const QString& login, const QString& password);
|
||||||
|
void requestProfile();
|
||||||
|
|
||||||
const DataServerAccountInfo& getAccountInfo() const { return _accountInfo; }
|
const DataServerAccountInfo& getAccountInfo() const { return _accountInfo; }
|
||||||
|
|
||||||
void destroy() { delete _networkAccessManager; }
|
void destroy() { delete _networkAccessManager; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void requestFinished();
|
void requestAccessTokenFinished();
|
||||||
void requestError(QNetworkReply::NetworkError error);
|
void requestProfileFinished();
|
||||||
|
void requestAccessTokenError(QNetworkReply::NetworkError error);
|
||||||
|
void requestProfileError(QNetworkReply::NetworkError error);
|
||||||
void logout();
|
void logout();
|
||||||
void updateBalance();
|
void updateBalance();
|
||||||
void accountInfoBalanceChanged(qint64 newBalance);
|
void accountInfoBalanceChanged(qint64 newBalance);
|
||||||
|
@ -69,7 +72,7 @@ signals:
|
||||||
void authRequired();
|
void authRequired();
|
||||||
void authEndpointChanged();
|
void authEndpointChanged();
|
||||||
void usernameChanged(const QString& username);
|
void usernameChanged(const QString& username);
|
||||||
void accessTokenChanged();
|
void profileChanged();
|
||||||
void loginComplete(const QUrl& authURL);
|
void loginComplete(const QUrl& authURL);
|
||||||
void loginFailed();
|
void loginFailed();
|
||||||
void logoutComplete();
|
void logoutComplete();
|
||||||
|
@ -80,19 +83,19 @@ private:
|
||||||
AccountManager();
|
AccountManager();
|
||||||
AccountManager(AccountManager const& other); // not implemented
|
AccountManager(AccountManager const& other); // not implemented
|
||||||
void operator=(AccountManager const& other); // not implemented
|
void operator=(AccountManager const& other); // not implemented
|
||||||
|
|
||||||
void passSuccessToCallback(QNetworkReply* reply);
|
void passSuccessToCallback(QNetworkReply* reply);
|
||||||
void passErrorToCallback(QNetworkReply* reply);
|
void passErrorToCallback(QNetworkReply* reply);
|
||||||
|
|
||||||
Q_INVOKABLE void invokedRequest(const QString& path, QNetworkAccessManager::Operation operation,
|
Q_INVOKABLE void invokedRequest(const QString& path, QNetworkAccessManager::Operation operation,
|
||||||
const JSONCallbackParameters& callbackParams,
|
const JSONCallbackParameters& callbackParams,
|
||||||
const QByteArray& dataByteArray,
|
const QByteArray& dataByteArray,
|
||||||
QHttpMultiPart* dataMultiPart);
|
QHttpMultiPart* dataMultiPart);
|
||||||
|
|
||||||
QUrl _authURL;
|
QUrl _authURL;
|
||||||
QNetworkAccessManager* _networkAccessManager;
|
QNetworkAccessManager* _networkAccessManager;
|
||||||
QMap<QNetworkReply*, JSONCallbackParameters> _pendingCallbackMap;
|
QMap<QNetworkReply*, JSONCallbackParameters> _pendingCallbackMap;
|
||||||
|
|
||||||
DataServerAccountInfo _accountInfo;
|
DataServerAccountInfo _accountInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,20 +21,7 @@ DataServerAccountInfo::DataServerAccountInfo() :
|
||||||
_balance(0),
|
_balance(0),
|
||||||
_hasBalance(false)
|
_hasBalance(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
DataServerAccountInfo::DataServerAccountInfo(const QJsonObject& jsonObject) :
|
|
||||||
_accessToken(jsonObject),
|
|
||||||
_username(),
|
|
||||||
_xmppPassword(),
|
|
||||||
_balance(0),
|
|
||||||
_hasBalance(false)
|
|
||||||
{
|
|
||||||
QJsonObject userJSONObject = jsonObject["user"].toObject();
|
|
||||||
setUsername(userJSONObject["username"].toString());
|
|
||||||
setXMPPPassword(userJSONObject["xmpp_password"].toString());
|
|
||||||
setDiscourseApiKey(userJSONObject["discourse_api_key"].toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherInfo) {
|
DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherInfo) {
|
||||||
|
@ -54,7 +41,7 @@ DataServerAccountInfo& DataServerAccountInfo::operator=(const DataServerAccountI
|
||||||
|
|
||||||
void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) {
|
void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
|
|
||||||
swap(_accessToken, otherInfo._accessToken);
|
swap(_accessToken, otherInfo._accessToken);
|
||||||
swap(_username, otherInfo._username);
|
swap(_username, otherInfo._username);
|
||||||
swap(_xmppPassword, otherInfo._xmppPassword);
|
swap(_xmppPassword, otherInfo._xmppPassword);
|
||||||
|
@ -63,10 +50,14 @@ void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) {
|
||||||
swap(_hasBalance, otherInfo._hasBalance);
|
swap(_hasBalance, otherInfo._hasBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataServerAccountInfo::setAccessTokenFromJSON(const QJsonObject& jsonObject) {
|
||||||
|
_accessToken = OAuthAccessToken(jsonObject);
|
||||||
|
}
|
||||||
|
|
||||||
void DataServerAccountInfo::setUsername(const QString& username) {
|
void DataServerAccountInfo::setUsername(const QString& username) {
|
||||||
if (_username != username) {
|
if (_username != username) {
|
||||||
_username = username;
|
_username = username;
|
||||||
|
|
||||||
qDebug() << "Username changed to" << username;
|
qDebug() << "Username changed to" << username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +78,7 @@ void DataServerAccountInfo::setBalance(qint64 balance) {
|
||||||
if (!_hasBalance || _balance != balance) {
|
if (!_hasBalance || _balance != balance) {
|
||||||
_balance = balance;
|
_balance = balance;
|
||||||
_hasBalance = true;
|
_hasBalance = true;
|
||||||
|
|
||||||
emit balanceChanged(_balance);
|
emit balanceChanged(_balance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +90,17 @@ void DataServerAccountInfo::setBalanceFromJSON(const QJsonObject& jsonObject) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DataServerAccountInfo::hasProfile() const {
|
||||||
|
return _username.length() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataServerAccountInfo::setProfileInfoFromJSON(const QJsonObject& jsonObject) {
|
||||||
|
QJsonObject user = jsonObject["data"].toObject()["user"].toObject();
|
||||||
|
setUsername(user["username"].toString());
|
||||||
|
setXMPPPassword(user["xmpp_password"].toString());
|
||||||
|
setDiscourseApiKey(user["discourse_api_key"].toString());
|
||||||
|
}
|
||||||
|
|
||||||
QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info) {
|
QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info) {
|
||||||
out << info._accessToken << info._username << info._xmppPassword << info._discourseApiKey;
|
out << info._accessToken << info._username << info._xmppPassword << info._discourseApiKey;
|
||||||
return out;
|
return out;
|
||||||
|
|
|
@ -22,12 +22,12 @@ class DataServerAccountInfo : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DataServerAccountInfo();
|
DataServerAccountInfo();
|
||||||
DataServerAccountInfo(const QJsonObject& jsonObject);
|
|
||||||
DataServerAccountInfo(const DataServerAccountInfo& otherInfo);
|
DataServerAccountInfo(const DataServerAccountInfo& otherInfo);
|
||||||
DataServerAccountInfo& operator=(const DataServerAccountInfo& otherInfo);
|
DataServerAccountInfo& operator=(const DataServerAccountInfo& otherInfo);
|
||||||
|
|
||||||
const OAuthAccessToken& getAccessToken() const { return _accessToken; }
|
const OAuthAccessToken& getAccessToken() const { return _accessToken; }
|
||||||
|
void setAccessTokenFromJSON(const QJsonObject& jsonObject);
|
||||||
|
|
||||||
const QString& getUsername() const { return _username; }
|
const QString& getUsername() const { return _username; }
|
||||||
void setUsername(const QString& username);
|
void setUsername(const QString& username);
|
||||||
|
|
||||||
|
@ -36,20 +36,24 @@ public:
|
||||||
|
|
||||||
const QString& getDiscourseApiKey() const { return _discourseApiKey; }
|
const QString& getDiscourseApiKey() const { return _discourseApiKey; }
|
||||||
void setDiscourseApiKey(const QString& discourseApiKey);
|
void setDiscourseApiKey(const QString& discourseApiKey);
|
||||||
|
|
||||||
qint64 getBalance() const { return _balance; }
|
qint64 getBalance() const { return _balance; }
|
||||||
void setBalance(qint64 balance);
|
void setBalance(qint64 balance);
|
||||||
bool hasBalance() const { return _hasBalance; }
|
bool hasBalance() const { return _hasBalance; }
|
||||||
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
|
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
|
||||||
Q_INVOKABLE void setBalanceFromJSON(const QJsonObject& jsonObject);
|
Q_INVOKABLE void setBalanceFromJSON(const QJsonObject& jsonObject);
|
||||||
|
|
||||||
|
bool hasProfile() const;
|
||||||
|
|
||||||
|
void setProfileInfoFromJSON(const QJsonObject& jsonObject);
|
||||||
|
|
||||||
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
|
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
|
||||||
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
|
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
|
||||||
signals:
|
signals:
|
||||||
qint64 balanceChanged(qint64 newBalance);
|
qint64 balanceChanged(qint64 newBalance);
|
||||||
private:
|
private:
|
||||||
void swap(DataServerAccountInfo& otherInfo);
|
void swap(DataServerAccountInfo& otherInfo);
|
||||||
|
|
||||||
OAuthAccessToken _accessToken;
|
OAuthAccessToken _accessToken;
|
||||||
QString _username;
|
QString _username;
|
||||||
QString _xmppPassword;
|
QString _xmppPassword;
|
||||||
|
|
Loading…
Reference in a new issue