diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cc2aed7f53..f97c48fbdf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1352,10 +1352,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle); auto domainAccountManager = DependencyManager::get(); - connect(domainAccountManager.data(), &DomainAccountManager::authRequired, dialogsManager.data(), - &DialogsManager::showDomainLoginDialog); - connect(domainAccountManager.data(), &DomainAccountManager::loginComplete, this, - &Application::updateWindowTitle); + connect(domainAccountManager.data(), &DomainAccountManager::authRequired, + dialogsManager.data(), &DialogsManager::showDomainLoginDialog); + connect(domainAccountManager.data(), &DomainAccountManager::authRequired, this, &Application::updateWindowTitle); + connect(domainAccountManager.data(), &DomainAccountManager::loginComplete, this, &Application::updateWindowTitle); // ####### TODO: Connect any other signals from domainAccountManager. // use our MyAvatar position and quat for address manager path @@ -7084,6 +7084,7 @@ void Application::updateWindowTitle() const { auto domainAccountManager = DependencyManager::get(); auto isInErrorState = nodeList->getDomainHandler().isInErrorState(); bool isMetaverseLoggedIn = accountManager->isLoggedIn(); + bool hasDomainLogIn = domainAccountManager->hasLogIn(); bool isDomainLoggedIn = domainAccountManager->isLoggedIn(); QString authedDomain = domainAccountManager->getAuthedDomain(); @@ -7115,20 +7116,23 @@ void Application::updateWindowTitle() const { QString metaverseDetails; if (isMetaverseLoggedIn) { - metaverseDetails = "Metaverse: Logged in as " + metaverseUsername; + metaverseDetails = " (Metaverse: Logged in as " + metaverseUsername + ")"; } else { - metaverseDetails = "Metaverse: Not Logged In"; + metaverseDetails = " (Metaverse: Not Logged In)"; } QString domainDetails; - if (currentPlaceName == authedDomain && isDomainLoggedIn) { - domainDetails = "Domain: Logged in as " + domainUsername; + if (hasDomainLogIn) { + if (currentPlaceName == authedDomain && isDomainLoggedIn) { + domainDetails = " (Domain: Logged in as " + domainUsername + ")"; + } else { + domainDetails = " (Domain: Not Logged In)"; + } } else { - domainDetails = "Domain: Not Logged In"; + domainDetails = ""; } - QString title = QString() + currentPlaceName + connectionStatus + " (" + metaverseDetails + ") (" + domainDetails + ")" - + buildVersion; + QString title = currentPlaceName + connectionStatus + metaverseDetails + domainDetails + buildVersion; #ifndef WIN32 // crashes with vs2013/win32 diff --git a/libraries/networking/src/DomainAccountManager.cpp b/libraries/networking/src/DomainAccountManager.cpp index 928b581a5b..6475d50cbb 100644 --- a/libraries/networking/src/DomainAccountManager.cpp +++ b/libraries/networking/src/DomainAccountManager.cpp @@ -39,29 +39,54 @@ Setting::Handle domainAccessTokenExpiresIn {"private/domainAccessTokenExpir Setting::Handle domainAccessTokenType {"private/domainAccessTokenType", "" }; */ -DomainAccountManager::DomainAccountManager() : - _authURL(), - _username(), - _access_token(), - _refresh_token(), - _domain_name() -{ +DomainAccountManager::DomainAccountManager() { connect(this, &DomainAccountManager::loginComplete, this, &DomainAccountManager::sendInterfaceAccessTokenToServer); } -void DomainAccountManager::setAuthURL(const QUrl& authURL) { - if (_authURL != authURL) { - _authURL = authURL; +void DomainAccountManager::setDomainURL(const QUrl& domainURL) { - qCDebug(networking) << "AccountManager URL for authenticated requests has been changed to" << qPrintable(_authURL.toString()); - - _access_token = ""; - _refresh_token = ""; - - // ####### TODO: Restore and refresh OAuth2 tokens if have them for this domain. - - // ####### TODO: Handle "keep me logged in". + if (domainURL == _domainURL) { + return; } + + _domainURL = domainURL; + qCDebug(networking) << "DomainAccountManager domain URL has been changed to" << qPrintable(_domainURL.toString()); + + // Restore OAuth2 authorization if have it for this domain. + if (_domainURL == _previousDomainURL) { + _authURL = _previousAuthURL; + _clientID = _previousClientID; + _username = _previousUsername; + _access_token = _previousAccessToken; + _refresh_token = _previousRefreshToken; + _domain_name = _previousDomainName; + // ####### TODO: Refresh OAuth2 access token if necessary. + } else { + _authURL.clear(); + _clientID.clear(); + _username.clear(); + _access_token.clear(); + _refresh_token.clear(); + _domain_name.clear(); + } + +} + +void DomainAccountManager::setAuthURL(const QUrl& authURL) { + if (_authURL == authURL) { + return; + } + + _authURL = authURL; + qCDebug(networking) << "DomainAccountManager URL for authenticated requests has been changed to" + << qPrintable(_authURL.toString()); + + _access_token = ""; + _refresh_token = ""; +} + +bool DomainAccountManager::hasLogIn() { + return !_authURL.isEmpty(); } bool DomainAccountManager::isLoggedIn() { @@ -115,6 +140,18 @@ void DomainAccountManager::requestAccessTokenFinished() { QUrl rootURL = requestReply->url(); rootURL.setPath(""); setTokensFromJSON(rootObject, rootURL); + + // Remember domain login for the current Interface session. + _previousDomainURL = _domainURL; + _previousAuthURL = _authURL; + _previousClientID = _clientID; + _previousUsername = _username; + _previousAccessToken = _access_token; + _previousRefreshToken = _refresh_token; + _previousDomainName = _domain_name; + + // ####### TODO: Handle "keep me logged in". + emit loginComplete(); } else { // Failure. diff --git a/libraries/networking/src/DomainAccountManager.h b/libraries/networking/src/DomainAccountManager.h index 31226d6990..765217549d 100644 --- a/libraries/networking/src/DomainAccountManager.h +++ b/libraries/networking/src/DomainAccountManager.h @@ -23,6 +23,7 @@ class DomainAccountManager : public QObject, public Dependency { public: DomainAccountManager(); + void setDomainURL(const QUrl& domainURL); void setAuthURL(const QUrl& authURL); void setClientID(const QString& clientID) { _clientID = clientID; } @@ -31,6 +32,7 @@ public: QString getRefreshToken() { return _refresh_token; } QString getAuthedDomain() { return _domain_name; } + bool hasLogIn(); bool isLoggedIn(); Q_INVOKABLE bool checkAndSignalForAccessToken(); @@ -55,12 +57,23 @@ private: void setTokensFromJSON(const QJsonObject&, const QUrl& url); void sendInterfaceAccessTokenToServer(); + QUrl _domainURL; QUrl _authURL; QString _clientID; - QString _username; // ####### TODO: Store elsewhere? + + QString _username; QString _access_token; // ####... "" QString _refresh_token; // ####... "" QString _domain_name; // ####... "" + + // ####### TODO: Handle more than one domain. + QUrl _previousDomainURL; + QUrl _previousAuthURL; + QString _previousClientID; + QString _previousUsername; + QString _previousAccessToken; + QString _previousRefreshToken; + QString _previousDomainName; }; #endif // hifi_DomainAccountManager_h diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index c1a24748f4..ea4c0a00cb 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -241,6 +241,8 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) { } } + DependencyManager::get()->setDomainURL(_domainURL); + emit domainURLChanged(_domainURL); if (_sockAddr.getPort() != domainPort) { @@ -584,18 +586,28 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointergenerateNewUserKeypair(); _connectionDenialsSinceKeypairRegen = 0; } + + // Server with domain login will prompt for domain login, not metaverse, so reset domain values if asked for metaverse. + auto domainAccountManager = DependencyManager::get(); + domainAccountManager->setAuthURL(QUrl()); + domainAccountManager->setClientID(QString()); + } else if (reasonSuggestsDomainLogin(reasonCode)) { qCWarning(networking) << "Make sure you are logged in to the domain."; - auto accountManager = DependencyManager::get(); + auto domainAccountManager = DependencyManager::get(); if (!extraInfo.isEmpty()) { auto extraInfoComponents = extraInfo.split("|"); - accountManager->setAuthURL(extraInfoComponents.value(0)); - accountManager->setClientID(extraInfoComponents.value(1)); + domainAccountManager->setAuthURL(extraInfoComponents.value(0)); + domainAccountManager->setClientID(extraInfoComponents.value(1)); + } else { + // Shouldn't occur, but just in case. + domainAccountManager->setAuthURL(QUrl()); + domainAccountManager->setClientID(QString()); } if (!_hasCheckedForDomainAccessToken) { - accountManager->checkAndSignalForAccessToken(); + domainAccountManager->checkAndSignalForAccessToken(); _hasCheckedForDomainAccessToken = true; } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index e02a8dd56e..64663def22 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -476,33 +476,28 @@ void NodeList::sendDomainServerCheckIn() { packetStream << _ownerType.load() << publicSockAddr << localSockAddr << _nodeTypesOfInterest.toList(); packetStream << DependencyManager::get()->getPlaceName(); - // ####### TODO: Also send if need to send new domainLogin data? if (!domainIsConnected) { + + // Metaverse account. DataServerAccountInfo& accountInfo = accountManager->getAccountInfo(); packetStream << accountInfo.getUsername(); - // if this is a connect request, and we can present a username signature, send it along if (requiresUsernameSignature && accountManager->getAccountInfo().hasPrivateKey()) { const QByteArray& usernameSignature = accountManager->getAccountInfo().getUsernameSignature(connectionToken); packetStream << usernameSignature; } else { - // ####### TODO: Only append if are going to send domain username? packetStream << QString(""); // Placeholder in case have domain username. } - } else { - // ####### TODO: Only append if are going to send domainUsername? - packetStream << QString("") << QString(""); // Placeholders in case have domain username. - } - // Send domain domain login data from Interface to domain server. - if (_hasDomainAccountManager) { - auto domainAccountManager = DependencyManager::get(); - if (!domainAccountManager->getUsername().isEmpty()) { - packetStream << domainAccountManager->getUsername(); - if (!domainAccountManager->getAccessToken().isEmpty()) { + // Domain account. + if (_hasDomainAccountManager) { + auto domainAccountManager = DependencyManager::get(); + if (!domainAccountManager->getUsername().isEmpty() && !domainAccountManager->getAccessToken().isEmpty()) { + packetStream << domainAccountManager->getUsername(); packetStream << (domainAccountManager->getAccessToken() + ":" + domainAccountManager->getRefreshToken()); } } + } flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::SendDSCheckIn);