From 56ba137ee3b4b4b81500ce41d89b6d5c07c7b908 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Jul 2020 20:48:27 +1200 Subject: [PATCH] Get OAuth2 URL from server settings --- domain-server/resources/describe-settings.json | 2 +- domain-server/src/DomainGatekeeper.cpp | 18 ++++++++++-------- .../qml/LoginDialog/LinkAccountBody.qml | 3 +-- interface/src/ui/DialogsManager.cpp | 10 ---------- interface/src/ui/DialogsManager.h | 2 -- interface/src/ui/LoginDialog.cpp | 13 +++---------- interface/src/ui/LoginDialog.h | 3 +-- .../networking/src/DomainAccountManager.cpp | 14 ++++++++++++-- .../networking/src/DomainAccountManager.h | 7 ++++++- libraries/networking/src/DomainHandler.cpp | 5 ++++- 10 files changed, 38 insertions(+), 39 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 281a0be9cc..14c15e1e3d 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -85,7 +85,7 @@ "backup": false }, { - "name": "authentication_oauth2_url_base", + "name": "oauth2_url_base", "label": "Authentication URL Base", "help": "The URL base that the Interface and domain-server will use to make API requests.", "advanced": true diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 32b02382da..f41c20e245 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -444,6 +444,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo return newNode; } +const QString AUTHENTICATION_OAUTH2_URL_BASE = "authentication.oauth2_url_base"; const QString MAXIMUM_USER_CAPACITY = "security.maximum_user_capacity"; const QString MAXIMUM_USER_CAPACITY_REDIRECT_LOCATION = "security.maximum_user_capacity_redirect_location"; @@ -533,8 +534,14 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect if (!userPerms.can(NodePermissions::Permission::canConnectToDomain)) { if (domainHasLogin()) { + QString domainAuthURL; + auto domainAuthURLVariant = _server->_settingsManager.valueForKeyPath(AUTHENTICATION_OAUTH2_URL_BASE); + if (domainAuthURLVariant.canConvert()) { + domainAuthURL = domainAuthURLVariant.toString(); + qDebug() << "Domain authorization URL:" << domainAuthURL; + } sendConnectionDeniedPacket("You lack the required permissions to connect to this domain.", - nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::NotAuthorizedDomain); + nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::NotAuthorizedDomain, domainAuthURL); } else { sendConnectionDeniedPacket("You lack the required permissions to connect to this domain.", nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::NotAuthorizedMetaverse); @@ -1164,13 +1171,8 @@ void DomainGatekeeper::refreshGroupsCache() { } bool DomainGatekeeper::domainHasLogin() { - // The domain may have its own users and groups. This is enabled in the server settings by ... - // ####### TODO: Use a particular string in the server name or set a particular tag in the server's settings? - // Or add a new server setting? - - // ####### TODO: Also configure URL for getting user's group memberships, in the server's settings? - - // ####### TODO + // The domain may have its own users and groups. This is enabled in the server settings by ... ####### + // ####### TODO: Base on server settings. return true; } diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 6f437bb991..3d715d1a39 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -46,7 +46,6 @@ Item { readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() readonly property bool isLoggingInToDomain: loginDialog.getDomainLoginRequested() - readonly property string domainAuthProvider: loginDialog.getDomainLoginAuthProvider() QtObject { id: d @@ -76,7 +75,7 @@ Item { if (!isLoggingInToDomain) { loginDialog.login(emailField.text, passwordField.text); } else { - loginDialog.loginDomain(emailField.text, passwordField.text, domainAuthProvider); + loginDialog.loginDomain(emailField.text, passwordField.text); } if (linkAccountBody.loginDialogPoppedUp) { diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 9cad1b8a9e..848663967f 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -29,7 +29,6 @@ #include "OctreeStatsDialog.h" #include "PreferencesDialog.h" #include "UpdateDialog.h" -#include "DomainHandler.h" #include "scripting/HMDScriptingInterface.h" @@ -131,15 +130,6 @@ void DialogsManager::hideLoginDialog() { void DialogsManager::showDomainLoginDialog() { - const QJsonObject& settingsObject = DependencyManager::get()->getDomainHandler().getSettingsObject(); - static const QString WP_OAUTH2_SERVER_URL = "authentication_oauth2_url_base"; - - if (!settingsObject.contains(WP_OAUTH2_SERVER_URL)) { - qDebug() << "Cannot log in to domain because an OAuth2 authorization was required but no authorization server was specified."; - return; - } - - _domainLoginAuthProvider = settingsObject[WP_OAUTH2_SERVER_URL].toString(); _isDomainLogin = true; LoginDialog::showWithSelection(); } diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index b76ff69386..30127ced68 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -42,7 +42,6 @@ public: void emitAddressBarShown(bool visible) { emit addressBarShown(visible); } void setAddressBarVisible(bool addressBarVisible); bool getIsDomainLogin() { return _isDomainLogin; } - QString getDomainLoginAuthProvider() { return _domainLoginAuthProvider; } public slots: void showAddressBar(); @@ -88,7 +87,6 @@ private: bool _addressBarVisible { false }; bool _isDomainLogin { false }; - QString _domainLoginAuthProvider { "" }; }; #endif // hifi_DialogsManager_h diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index cd686719ea..3cc37bcadb 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -143,12 +143,9 @@ void LoginDialog::login(const QString& username, const QString& password) const DependencyManager::get()->requestAccessToken(username, password); } -void LoginDialog::loginDomain(const QString& username, const QString& password, const QString& domainAuthProvider) const { - qDebug() << "Attempting to login" << username << "into a domain through" << domainAuthProvider; - DependencyManager::get()->requestAccessToken(username, password, domainAuthProvider); - - // ####### TODO: It may not be necessary to pass domainAuthProvider to the login dialog and through to here because it was - // originally provided to the QML from C++. +void LoginDialog::loginDomain(const QString& username, const QString& password) const { + qDebug() << "Attempting to login" << username << "into a domain"; + DependencyManager::get()->requestAccessToken(username, password); } void LoginDialog::loginThroughOculus() { @@ -430,7 +427,3 @@ void LoginDialog::signupFailed(QNetworkReply* reply) { bool LoginDialog::getDomainLoginRequested() const { return DependencyManager::get()->getIsDomainLogin(); } - -QString LoginDialog::getDomainLoginAuthProvider() const { - return DependencyManager::get()->getDomainLoginAuthProvider(); -} diff --git a/interface/src/ui/LoginDialog.h b/interface/src/ui/LoginDialog.h index 49d5dc8fac..310a5db255 100644 --- a/interface/src/ui/LoginDialog.h +++ b/interface/src/ui/LoginDialog.h @@ -72,7 +72,7 @@ protected slots: Q_INVOKABLE QString oculusUserID() const; Q_INVOKABLE void login(const QString& username, const QString& password) const; - Q_INVOKABLE void loginDomain(const QString& username, const QString& password, const QString& domainAuthProvider) const; + Q_INVOKABLE void loginDomain(const QString& username, const QString& password) const; Q_INVOKABLE void loginThroughSteam(); Q_INVOKABLE void linkSteam(); Q_INVOKABLE void createAccountFromSteam(QString username = QString()); @@ -85,7 +85,6 @@ protected slots: Q_INVOKABLE bool getLoginDialogPoppedUp() const; Q_INVOKABLE bool getDomainLoginRequested() const; - Q_INVOKABLE QString getDomainLoginAuthProvider() const; }; diff --git a/libraries/networking/src/DomainAccountManager.cpp b/libraries/networking/src/DomainAccountManager.cpp index 524a7c4b0a..78ae779fca 100644 --- a/libraries/networking/src/DomainAccountManager.cpp +++ b/libraries/networking/src/DomainAccountManager.cpp @@ -45,7 +45,17 @@ DomainAccountManager::DomainAccountManager() { connect(this, &DomainAccountManager::loginComplete, this, &DomainAccountManager::sendInterfaceAccessTokenToServer); } -void DomainAccountManager::requestAccessToken(const QString& login, const QString& password, const QString& domainAuthProvider) { +void DomainAccountManager::setAuthURL(const QUrl& authURL) { + if (_authURL != authURL) { + _authURL = authURL; + + qCDebug(networking) << "AccountManager URL for authenticated requests has been changed to" << qPrintable(_authURL.toString()); + + // ####### TODO: See AccountManager::setAuthURL(). + } +} + +void DomainAccountManager::requestAccessToken(const QString& login, const QString& password) { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); @@ -53,7 +63,7 @@ void DomainAccountManager::requestAccessToken(const QString& login, const QStrin request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); request.setHeader(QNetworkRequest::UserAgentHeader, NetworkingConstants::VIRCADIA_USER_AGENT); - _domainAuthProviderURL = domainAuthProvider; + _domainAuthProviderURL = _authURL; _domainAuthProviderURL.setPath("/oauth/token"); QByteArray postData; diff --git a/libraries/networking/src/DomainAccountManager.h b/libraries/networking/src/DomainAccountManager.h index 4bb197175e..eb0f2659dd 100644 --- a/libraries/networking/src/DomainAccountManager.h +++ b/libraries/networking/src/DomainAccountManager.h @@ -13,6 +13,7 @@ #define hifi_DomainAccountManager_h #include +#include #include @@ -22,10 +23,12 @@ class DomainAccountManager : public QObject, public Dependency { public: DomainAccountManager(); + void setAuthURL(const QUrl& authURL); + Q_INVOKABLE bool checkAndSignalForAccessToken(); public slots: - void requestAccessToken(const QString& login, const QString& password, const QString& domainAuthProvider); + void requestAccessToken(const QString& login, const QString& password); void requestAccessTokenFinished(); signals: @@ -41,6 +44,8 @@ private: bool accessTokenIsExpired(); void setAccessTokenFromJSON(const QJsonObject&); void sendInterfaceAccessTokenToServer(); + + QUrl _authURL; }; #endif // hifi_DomainAccountManager_h diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 66d4c58a34..0a61036b96 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -584,8 +584,11 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer(); + if (!extraInfo.isEmpty()) { + accountManager->setAuthURL(extraInfo); + } if (!_hasCheckedForDomainAccessToken) { accountManager->checkAndSignalForAccessToken();