diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a6f7e63247..9aa2bdbcdb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1187,6 +1187,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } auto accountManager = DependencyManager::get(); + // set the account manager's root URL and trigger a login request if we don't have the access token + accountManager->setIsAgent(true); + accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL()); + if (!accountManager->hasKeyPair()) { + accountManager->generateNewUserKeypair(); + } + #ifndef Q_OS_ANDROID _logger->setSessionID(accountManager->getSessionID()); #endif @@ -1334,10 +1341,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo #endif connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle); - // set the account manager's root URL and trigger a login request if we don't have the access token - accountManager->setIsAgent(true); - accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL()); - // use our MyAvatar position and quat for address manager path addressManager->setPositionGetter([] { auto avatarManager = DependencyManager::get(); diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 96cfa66013..6cb1582dca 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -86,6 +86,7 @@ AccountManager::AccountManager(UserAgentGetter userAgentGetter) : qRegisterMetaType("QHttpMultiPart*"); qRegisterMetaType(); + connect(this, &AccountManager::loginComplete, this, &AccountManager::uploadPublicKey); } const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash"; @@ -838,18 +839,30 @@ void AccountManager::generateNewKeypair(bool isUserKeypair, const QUuid& domainI connect(keypairGenerator, &RSAKeypairGenerator::errorGeneratingKeypair, this, &AccountManager::handleKeypairGenerationError); - qCDebug(networking) << "Starting worker thread to generate 2048-bit RSA keypair."; + static constexpr int RSA_THREAD_PRIORITY = 1; + qCDebug(networking) << "Starting worker thread to generate 2048-bit RSA keypair, priority" + << RSA_THREAD_PRIORITY << "- QThreadPool::maxThreadCount =" << QThreadPool::globalInstance()->maxThreadCount(); // Start on Qt's global thread pool. - QThreadPool::globalInstance()->start(keypairGenerator); + QThreadPool::globalInstance()->start(keypairGenerator, RSA_THREAD_PRIORITY); } } void AccountManager::processGeneratedKeypair(QByteArray publicKey, QByteArray privateKey) { - qCDebug(networking) << "Generated 2048-bit RSA keypair. Uploading public key now."; + qCDebug(networking) << "Generated 2048-bit RSA keypair."; // hold the private key to later set our metaverse API account info if upload succeeds + _pendingPublicKey = publicKey; _pendingPrivateKey = privateKey; + uploadPublicKey(); +} + +void AccountManager::uploadPublicKey() { + if (_pendingPrivateKey.isEmpty()) { + return; + } + + qCDebug(networking) << "Attempting upload of public key"; // upload the public key so data-web has an up-to-date key const QString USER_PUBLIC_KEY_UPDATE_PATH = "api/v1/user/public_key"; @@ -871,7 +884,7 @@ void AccountManager::processGeneratedKeypair(QByteArray publicKey, QByteArray pr publicKeyPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"public_key\"; filename=\"public_key\"")); - publicKeyPart.setBody(publicKey); + publicKeyPart.setBody(_pendingPublicKey); requestMultiPart->append(publicKeyPart); // Currently broken? We don't have the temporary domain key. @@ -900,6 +913,7 @@ void AccountManager::publicKeyUploadSucceeded(QNetworkReply* reply) { // public key upload complete - store the matching private key and persist the account to settings _accountInfo.setPrivateKey(_pendingPrivateKey); + _pendingPublicKey.clear(); _pendingPrivateKey.clear(); persistAccountToFile(); @@ -915,9 +929,6 @@ void AccountManager::publicKeyUploadFailed(QNetworkReply* reply) { // we aren't waiting for a response any longer _isWaitingForKeypairResponse = false; - - // clear our pending private key - _pendingPrivateKey.clear(); } void AccountManager::handleKeypairGenerationError() { @@ -961,3 +972,7 @@ void AccountManager::saveLoginStatus(bool isLoggedIn) { } } } + +bool AccountManager::hasKeyPair() const { + return _accountInfo.hasPrivateKey(); +} diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index c2187f79cb..a88a5cc4e7 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -81,6 +81,7 @@ public: bool needsToRefreshToken(); Q_INVOKABLE bool checkAndSignalForAccessToken(); void setAccessTokenForCurrentAuthURL(const QString& accessToken); + bool hasKeyPair() const; void requestProfile(); @@ -139,6 +140,7 @@ signals: private slots: void handleKeypairGenerationError(); void processGeneratedKeypair(QByteArray publicKey, QByteArray privateKey); + void uploadPublicKey(); void publicKeyUploadSucceeded(QNetworkReply* reply); void publicKeyUploadFailed(QNetworkReply* reply); void generateNewKeypair(bool isUserKeypair = true, const QUuid& domainID = QUuid()); @@ -162,6 +164,7 @@ private: bool _isWaitingForKeypairResponse { false }; QByteArray _pendingPrivateKey; + QByteArray _pendingPublicKey; QUuid _sessionID { QUuid::createUuid() };