12 #ifndef hifi_AccountManager_h
13 #define hifi_AccountManager_h
15 #include <QtCore/QByteArray>
16 #include <QtCore/QObject>
17 #include <QtCore/QTimer>
18 #include <QtCore/QUrl>
19 #include <QtNetwork/QNetworkReply>
22 #include <DependencyManager.h>
24 #include "AccountSettings.h"
25 #include "DataServerAccountInfo.h"
26 #include "NetworkingConstants.h"
27 #include "MetaverseAPI.h"
28 #include "NetworkAccessManager.h"
29 #include <SharedUtil.h>
31 class JSONCallbackParameters {
33 JSONCallbackParameters(QObject* callbackReceiver =
nullptr,
34 const QString& jsonCallbackMethod = QString(),
35 const QString& errorCallbackMethod = QString(),
36 const QJsonObject& callbackData = QJsonObject());
38 bool isEmpty()
const {
return !callbackReceiver; }
40 QObject* callbackReceiver;
41 QString jsonCallbackMethod;
42 QString errorCallbackMethod;
43 QJsonObject callbackData;
46 namespace AccountManagerAuth {
54 Q_DECLARE_METATYPE(AccountManagerAuth::Type);
56 const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER =
"Authorization";
57 const auto METAVERSE_SESSION_ID_HEADER = QString(
"HFM-SessionID").toLocal8Bit();
59 using UserAgentGetter = std::function<QString()>;
61 const auto DEFAULT_USER_AGENT_GETTER = []() -> QString {
return NetworkingConstants::OVERTE_USER_AGENT; };
63 class AccountManager :
public QObject,
public Dependency {
66 AccountManager(
bool accountSettingsEnabled =
false, UserAgentGetter userAgentGetter = DEFAULT_USER_AGENT_GETTER);
68 QNetworkRequest createRequest(QString path, AccountManagerAuth::Type authType);
69 Q_INVOKABLE
void sendRequest(
const QString& path,
70 AccountManagerAuth::Type authType,
71 QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation,
72 const JSONCallbackParameters& callbackParams = JSONCallbackParameters(),
73 const QByteArray& dataByteArray = QByteArray(),
74 QHttpMultiPart* dataMultiPart = NULL,
75 const QVariantMap& propertyMap = QVariantMap());
77 void setIsAgent(
bool isAgent) { _isAgent = isAgent; }
79 const QUrl& getAuthURL()
const {
return _authURL; }
80 void setAuthURL(
const QUrl& authURL);
81 bool hasAuthEndpoint() {
return !_authURL.isEmpty(); }
82 Q_INVOKABLE
void updateAuthURLFromMetaverseServerURL();
84 bool isLoggedIn() {
return !_authURL.isEmpty() && hasValidAccessToken(); }
85 bool hasValidAccessToken();
86 bool needsToRefreshToken();
87 Q_INVOKABLE
bool checkAndSignalForAccessToken();
88 void setAccessTokenForCurrentAuthURL(
const QString& accessToken);
89 bool hasKeyPair()
const;
91 void requestProfile();
93 DataServerAccountInfo& getAccountInfo() {
return _accountInfo; }
94 void setAccountInfo(
const DataServerAccountInfo& newAccountInfo);
96 static QJsonObject dataObjectFromResponse(QNetworkReply* requestReply);
98 QUuid getSessionID()
const {
return _sessionID; }
99 void setSessionID(
const QUuid& sessionID);
101 void setTemporaryDomain(
const QUuid& domainID,
const QString& key);
102 const QString& getTemporaryDomainKey(
const QUuid& domainID) {
return _accountInfo.getTemporaryDomainKey(domainID); }
104 QUrl getMetaverseServerURL() {
return MetaverseAPI::getCurrentMetaverseServerURL(); }
105 QString getMetaverseServerURLPath(
bool appendForwardSlash =
false) {
106 return MetaverseAPI::getCurrentMetaverseServerURLPath(appendForwardSlash);
109 void removeAccountFromFile();
111 bool getLimitedCommerce() {
return _limitedCommerce; }
112 void setLimitedCommerce(
bool isLimited);
114 void setAccessTokens(
const QString& response);
115 void setConfigFileURL(
const QString& fileURL) { _configFileURL = fileURL; }
116 void saveLoginStatus(
bool isLoggedIn);
118 AccountSettings& getAccountSettings() {
return _settings; }
121 void requestAccessToken(
const QString& login,
const QString& password);
122 void requestAccessTokenWithSteam(QByteArray authSessionTicket);
123 void requestAccessTokenWithOculus(
const QString& nonce,
const QString& oculusID);
124 void requestAccessTokenWithAuthCode(
const QString& authCode,
125 const QString& clientId,
126 const QString& clientSecret,
127 const QString& redirectUri);
128 void refreshAccessToken();
130 void requestAccessTokenFinished();
131 void refreshAccessTokenFinished();
132 void requestProfileFinished();
133 void refreshAccessTokenError(QNetworkReply::NetworkError error);
134 void requestProfileError(QNetworkReply::NetworkError error);
136 void generateNewUserKeypair() { generateNewKeypair(); }
137 void generateNewDomainKeypair(
const QUuid& domainID) { generateNewKeypair(
false, domainID); }
141 void authEndpointChanged();
142 void usernameChanged(
const QString& username);
143 void profileChanged();
144 void loginComplete(
const QUrl& authURL);
146 void logoutComplete();
148 void limitedCommerceChanged();
149 void accountSettingsLoaded();
152 void handleKeypairGenerationError();
153 void processGeneratedKeypair(QByteArray publicKey, QByteArray privateKey);
154 void uploadPublicKey();
155 void publicKeyUploadSucceeded(QNetworkReply* reply);
156 void publicKeyUploadFailed(QNetworkReply* reply);
157 void generateNewKeypair(
bool isUserKeypair =
true,
const QUuid& domainID = QUuid());
159 void requestAccountSettings();
160 void requestAccountSettingsFinished();
161 void requestAccountSettingsError(QNetworkReply::NetworkError error);
162 void postAccountSettings();
163 void postAccountSettingsFinished();
164 void postAccountSettingsError(QNetworkReply::NetworkError error);
167 Q_DISABLE_COPY(AccountManager);
169 void persistAccountToFile();
171 void passSuccessToCallback(QNetworkReply* reply);
172 void passErrorToCallback(QNetworkReply* reply);
174 UserAgentGetter _userAgentGetter;
178 DataServerAccountInfo _accountInfo;
179 bool _isWaitingForTokenRefresh {
false };
180 bool _isAgent {
false };
182 bool _isWaitingForKeypairResponse {
false };
183 QByteArray _pendingPrivateKey;
184 QByteArray _pendingPublicKey;
186 QUuid _sessionID { QUuid::createUuid() };
188 bool _limitedCommerce {
false };
189 QString _configFileURL;
191 bool _accountSettingsEnabled {
false };
192 AccountSettings _settings;
193 quint64 _currentSyncTimestamp { 0 };
194 quint64 _lastSuccessfulSyncTimestamp { 0 };
195 int _numPullRetries { 0 };
196 QTimer* _pullSettingsRetryTimer {
nullptr };
197 QTimer* _postSettingsTimer {
nullptr };