mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Add account settings to the AccountManager
This commit is contained in:
parent
610e0c3d82
commit
86196cfd62
4 changed files with 261 additions and 31 deletions
|
@ -87,6 +87,14 @@ AccountManager::AccountManager(UserAgentGetter userAgentGetter) :
|
|||
|
||||
qRegisterMetaType<AccountManagerAuth::Type>();
|
||||
connect(this, &AccountManager::loginComplete, this, &AccountManager::uploadPublicKey);
|
||||
connect(this, &AccountManager::loginComplete, this, &AccountManager::requestAccountSettings);
|
||||
|
||||
static int POST_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND;
|
||||
_postSettingsTimer = new QTimer(this);
|
||||
_postSettingsTimer->setInterval(POST_SETTINGS_INTERVAL);
|
||||
connect(this, SIGNAL(loginComplete(QUrl)), _postSettingsTimer, SLOT(start()));
|
||||
connect(this, &AccountManager::logoutComplete, _postSettingsTimer, &QTimer::stop);
|
||||
connect(_postSettingsTimer, &QTimer::timeout, this, &AccountManager::postAccountSettings);
|
||||
}
|
||||
|
||||
const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash";
|
||||
|
@ -160,33 +168,7 @@ void AccountManager::setAuthURL(const QUrl& authURL) {
|
|||
|
||||
qCDebug(networking) << "Found metaverse API account information for" << qPrintable(_authURL.toString());
|
||||
} else {
|
||||
// we didn't have a file - see if we can migrate old settings and store them in the new file
|
||||
|
||||
// check if there are existing access tokens to load from settings
|
||||
Settings settings;
|
||||
settings.beginGroup(ACCOUNTS_GROUP);
|
||||
|
||||
foreach(const QString& key, settings.allKeys()) {
|
||||
// take a key copy to perform the double slash replacement
|
||||
QString keyCopy(key);
|
||||
QUrl keyURL(keyCopy.replace(DOUBLE_SLASH_SUBSTITUTE, "//"));
|
||||
|
||||
if (keyURL == _authURL) {
|
||||
// pull out the stored access token and store it in memory
|
||||
_accountInfo = settings.value(key).value<DataServerAccountInfo>();
|
||||
|
||||
qCDebug(networking) << "Migrated an access token for" << qPrintable(keyURL.toString())
|
||||
<< "from previous settings file";
|
||||
}
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
if (_accountInfo.getAccessToken().token.isEmpty()) {
|
||||
qCWarning(networking) << "Unable to load account file. No existing account settings will be loaded.";
|
||||
} else {
|
||||
// persist the migrated settings to file
|
||||
persistAccountToFile();
|
||||
}
|
||||
qCWarning(networking) << "Unable to load account file. No existing account settings will be loaded.";
|
||||
}
|
||||
|
||||
if (_isAgent && !_accountInfo.getAccessToken().token.isEmpty() && !_accountInfo.hasProfile()) {
|
||||
|
@ -199,6 +181,10 @@ void AccountManager::setAuthURL(const QUrl& authURL) {
|
|||
refreshAccessToken();
|
||||
}
|
||||
|
||||
if (isLoggedIn()) {
|
||||
emit loginComplete(_authURL);
|
||||
}
|
||||
|
||||
// tell listeners that the auth endpoint has changed
|
||||
emit authEndpointChanged();
|
||||
}
|
||||
|
@ -804,6 +790,94 @@ void AccountManager::requestProfileError(QNetworkReply::NetworkError error) {
|
|||
qCDebug(networking) << "AccountManager requestProfileError - " << error;
|
||||
}
|
||||
|
||||
void AccountManager::requestAccountSettings() {
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
|
||||
QUrl lockerURL = _authURL;
|
||||
lockerURL.setPath("/api/v1/user/locker");
|
||||
|
||||
QNetworkRequest lockerRequest(lockerURL);
|
||||
lockerRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
lockerRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
|
||||
lockerRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, _accountInfo.getAccessToken().authorizationHeaderValue());
|
||||
|
||||
QNetworkReply* lockerReply = networkAccessManager.get(lockerRequest);
|
||||
connect(lockerReply, &QNetworkReply::finished, this, &AccountManager::requestAccountSettingsFinished);
|
||||
connect(lockerReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccountSettingsError(QNetworkReply::NetworkError)));
|
||||
}
|
||||
|
||||
void AccountManager::requestAccountSettingsFinished() {
|
||||
QNetworkReply* lockerReply = reinterpret_cast<QNetworkReply*>(sender());
|
||||
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(lockerReply->readAll());
|
||||
const QJsonObject& rootObject = jsonResponse.object();
|
||||
|
||||
if (rootObject.contains("status") && rootObject["status"].toString() == "success") {
|
||||
if (rootObject.contains("data") && rootObject["data"].isObject()) {
|
||||
_settings.unpack(rootObject["data"].toObject());
|
||||
|
||||
emit accountSettingsLoaded();
|
||||
} else {
|
||||
qCDebug(networking) << "Error in response for account settings: no data object";
|
||||
}
|
||||
} else {
|
||||
// TODO: error handling
|
||||
qCDebug(networking) << "Error in response for account settings" << lockerReply->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void AccountManager::requestAccountSettingsError(QNetworkReply::NetworkError error) {
|
||||
// TODO: error handling
|
||||
qCWarning(networking) << "Account settings request encountered an error" << error;
|
||||
}
|
||||
|
||||
void AccountManager::postAccountSettings() {
|
||||
if (!_settings.somethingChanged()) {
|
||||
// Nothing changed, skipping settings post
|
||||
return;
|
||||
}
|
||||
if (!isLoggedIn()) {
|
||||
qCWarning(networking) << "Can't post account settings: Not logged in";
|
||||
}
|
||||
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
|
||||
QUrl lockerURL = _authURL;
|
||||
lockerURL.setPath("/api/v1/user/locker");
|
||||
|
||||
QNetworkRequest lockerRequest(lockerURL);
|
||||
lockerRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
lockerRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
|
||||
lockerRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
lockerRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, _accountInfo.getAccessToken().authorizationHeaderValue());
|
||||
|
||||
QJsonObject dataObj;
|
||||
dataObj.insert("locker", _settings.pack());
|
||||
|
||||
auto postData = QJsonDocument(dataObj).toJson(QJsonDocument::Compact);
|
||||
|
||||
QNetworkReply* lockerReply = networkAccessManager.put(lockerRequest, postData);
|
||||
connect(lockerReply, &QNetworkReply::finished, this, &AccountManager::postAccountSettingsFinished);
|
||||
connect(lockerReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(postAccountSettingsError(QNetworkReply::NetworkError)));
|
||||
}
|
||||
|
||||
void AccountManager::postAccountSettingsFinished() {
|
||||
QNetworkReply* lockerReply = reinterpret_cast<QNetworkReply*>(sender());
|
||||
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(lockerReply->readAll());
|
||||
const QJsonObject& rootObject = jsonResponse.object();
|
||||
|
||||
if (!rootObject.contains("status") || rootObject["status"].toString() != "success") {
|
||||
// TODO: error handling
|
||||
qCDebug(networking) << "Error in response for account settings post" << lockerReply->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void AccountManager::postAccountSettingsError(QNetworkReply::NetworkError error) {
|
||||
// TODO: error handling
|
||||
qCWarning(networking) << "Post encountered an error" << error;
|
||||
}
|
||||
|
||||
void AccountManager::generateNewKeypair(bool isUserKeypair, const QUuid& domainID) {
|
||||
|
||||
if (thread() != QThread::currentThread()) {
|
||||
|
|
|
@ -14,18 +14,19 @@
|
|||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QUrlQuery>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include "AccountSettings.h"
|
||||
#include "DataServerAccountInfo.h"
|
||||
#include "NetworkingConstants.h"
|
||||
#include "NetworkAccessManager.h"
|
||||
|
||||
#include "DataServerAccountInfo.h"
|
||||
#include "SharedUtil.h"
|
||||
|
||||
#include <DependencyManager.h>
|
||||
|
||||
class JSONCallbackParameters {
|
||||
public:
|
||||
JSONCallbackParameters(QObject* callbackReceiver = nullptr,
|
||||
|
@ -107,6 +108,8 @@ public:
|
|||
void setConfigFileURL(const QString& fileURL) { _configFileURL = fileURL; }
|
||||
void saveLoginStatus(bool isLoggedIn);
|
||||
|
||||
AccountSettings& getAccountSettings() { return _settings; }
|
||||
|
||||
public slots:
|
||||
void requestAccessToken(const QString& login, const QString& password);
|
||||
void requestAccessTokenWithSteam(QByteArray authSessionTicket);
|
||||
|
@ -136,6 +139,7 @@ signals:
|
|||
void logoutComplete();
|
||||
void newKeypair();
|
||||
void limitedCommerceChanged();
|
||||
void accountSettingsLoaded();
|
||||
|
||||
private slots:
|
||||
void handleKeypairGenerationError();
|
||||
|
@ -145,6 +149,13 @@ private slots:
|
|||
void publicKeyUploadFailed(QNetworkReply* reply);
|
||||
void generateNewKeypair(bool isUserKeypair = true, const QUuid& domainID = QUuid());
|
||||
|
||||
void requestAccountSettings();
|
||||
void requestAccountSettingsFinished();
|
||||
void requestAccountSettingsError(QNetworkReply::NetworkError error);
|
||||
void postAccountSettings();
|
||||
void postAccountSettingsFinished();
|
||||
void postAccountSettingsError(QNetworkReply::NetworkError error);
|
||||
|
||||
private:
|
||||
AccountManager(AccountManager const& other) = delete;
|
||||
void operator=(AccountManager const& other) = delete;
|
||||
|
@ -170,6 +181,9 @@ private:
|
|||
|
||||
bool _limitedCommerce { false };
|
||||
QString _configFileURL;
|
||||
|
||||
AccountSettings _settings;
|
||||
QTimer* _postSettingsTimer;
|
||||
};
|
||||
|
||||
#endif // hifi_AccountManager_h
|
||||
|
|
83
libraries/networking/src/AccountSettings.cpp
Normal file
83
libraries/networking/src/AccountSettings.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
//
|
||||
// AccountSettings.cpp
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Clement Brisset on 9/12/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "AccountSettings.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "NetworkLogging.h"
|
||||
|
||||
// Examples:
|
||||
//static QString SOME_STRING_KEY { "some_string" };
|
||||
//static QString SOME_INT_KEY { "some_int" };
|
||||
//static QString SOME_BOOL_KEY { "some_bool" };
|
||||
|
||||
// Examples:
|
||||
//QString AccountSettings::DEFAULT_SOME_STRING { "" };
|
||||
//int AccountSettings::DEFAULT_SOME_INT { 17 };
|
||||
//bool AccountSettings::DEFAULT_SOME_BOOL { true };
|
||||
|
||||
QJsonObject AccountSettings::pack() {
|
||||
QJsonObject data;
|
||||
|
||||
QReadLocker lock(&_settingsLock);
|
||||
// Examples:
|
||||
// data.insert(SOME_STRING_KEY, _someString);
|
||||
// data.insert(SOME_INT_KEY, _someInt);
|
||||
// data.insert(SOME_BOOL_KEY, _someBool);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void AccountSettings::unpack(QJsonObject data) {
|
||||
QWriteLocker lock(&_settingsLock);
|
||||
|
||||
// Examples:
|
||||
// auto it = data.find(SOME_STRING_KEY);
|
||||
// _hasSomeString = it != data.end() && it->isString();
|
||||
// _someString = _hasSomeString ? it->toString() : DEFAULT_SOME_STRING;
|
||||
//
|
||||
// it = data.find(SOME_INT_KEY);
|
||||
// _hasSomeInt = it != data.end() && it->isDouble();
|
||||
// _someInt = _hasSomeInt ? it->toInt() : DEFAULT_SOME_INT;
|
||||
//
|
||||
// it = data.find(SOME_BOOL_KEY);
|
||||
// _hasSomeBool = it != data.end() && it->isBool();
|
||||
// _someBool = _hasSomeBool ? it->toBool() : DEFAULT_SOME_BOOL;
|
||||
|
||||
_somethingChanged = false;
|
||||
}
|
||||
|
||||
// Examples:
|
||||
//void AccountSettings::setSomeString(QString someString) {
|
||||
// QWriteLocker lock(&_settingsLock);
|
||||
// if (someString != _someString) {
|
||||
// _somethingChanged = true;
|
||||
// }
|
||||
// _someString = someString;
|
||||
//}
|
||||
//
|
||||
//void AccountSettings::setSomeInt(int someInt) {
|
||||
// QWriteLocker lock(&_settingsLock);
|
||||
// if (someInt != _someInt) {
|
||||
// _somethingChanged = true;
|
||||
// }
|
||||
// _someInt = someInt;
|
||||
//}
|
||||
//
|
||||
//void AccountSettings::setSomeBool(bool someBool) {
|
||||
// QWriteLocker lock(&_settingsLock);
|
||||
// if (someBool != _someBool) {
|
||||
// _somethingChanged = true;
|
||||
// }
|
||||
// _someBool = someBool;
|
||||
//}
|
59
libraries/networking/src/AccountSettings.h
Normal file
59
libraries/networking/src/AccountSettings.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// AccountSettings.h
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Clement Brisset on 9/12/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_AccountSettings_h
|
||||
#define hifi_AccountSettings_h
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QReadWriteLock>
|
||||
#include <QString>
|
||||
|
||||
class AccountSettings {
|
||||
public:
|
||||
// Examples:
|
||||
// static QString DEFAULT_SOME_STRING;
|
||||
// static int DEFAULT_SOME_INT;
|
||||
// static bool DEFAULT_SOME_BOOL;
|
||||
|
||||
bool somethingChanged() const { return _somethingChanged; }
|
||||
|
||||
QJsonObject pack();
|
||||
void unpack(QJsonObject data);
|
||||
|
||||
// Examples:
|
||||
// bool hasSomeString() const { QReadLocker lock(&_settingsLock); return _hasSomeString; }
|
||||
// QString getSomeString() const { QReadLocker lock(&_settingsLock); return _someString; }
|
||||
// void setSomeString(QString someString);
|
||||
//
|
||||
// bool hasSomeInt() const { QReadLocker lock(&_settingsLock); return _hasSomeInt; }
|
||||
// int getSomeInt() const { QReadLocker lock(&_settingsLock); return _someInt; }
|
||||
// void setSomeInt(int someInt);
|
||||
//
|
||||
// bool hasSomeBool() const { QReadLocker lock(&_settingsLock); return _hasSomeBool; }
|
||||
// bool getSomeBool() const { QReadLocker lock(&_settingsLock); return _someBool; }
|
||||
// void setSomeBool(bool someBool);
|
||||
|
||||
private:
|
||||
mutable QReadWriteLock _settingsLock;
|
||||
bool _somethingChanged { false };
|
||||
|
||||
// Examples:
|
||||
// bool _hasSomeString { false };
|
||||
// bool _hasSomeInt { false };
|
||||
// bool _hasSomeBool { false };
|
||||
|
||||
// Examples:
|
||||
// QString _someString { DEFAULT_SOME_STRING };
|
||||
// int _someInt { DEFAULT_SOME_INT };
|
||||
// bool _someBool { DEFAULT_SOME_BOOL };
|
||||
};
|
||||
|
||||
#endif /* hifi_AccountSettings_h */
|
Loading…
Reference in a new issue