From d7c0493b7a4380882e5b74a2a132ceef930ba14f Mon Sep 17 00:00:00 2001 From: Kasen IO Date: Thu, 23 Jul 2020 22:14:21 -0400 Subject: [PATCH 1/8] Updated login QML to handle domain logins. --- .../qml/LoginDialog/LinkAccountBody.qml | 19 +++++++++++++++---- .../qml/LoginDialog/LoggingInBody.qml | 4 ++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 571b7e074c..cd19662931 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -45,6 +45,11 @@ Item { property bool lostFocus: false readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() + // TODO: + // readonly property bool isLoggingInToDomain: loginDialog.getDomainLoginRequested() + // readonly property bool domainAuthProvider: loginDialog.getDomainLoginAuthProvider() + readonly property bool isLoggingInToDomain: true + readonly property string domainAuthProvider: "https://example.com/oauth2" QtObject { id: d @@ -71,7 +76,12 @@ Item { } function login() { - loginDialog.login(emailField.text, passwordField.text); + if (!isLoggingInToDomain) { + loginDialog.login(emailField.text, passwordField.text); + } else { + loginDialog.loginDomain(emailField.text, passwordField.text, domainAuthProvider); + } + if (linkAccountBody.loginDialogPoppedUp) { var data; if (linkAccountBody.linkSteam) { @@ -87,7 +97,7 @@ Item { } bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam, "linkOculus": linkAccountBody.linkOculus, - "displayName":displayNameField.text }); + "displayName":displayNameField.text, "isLoggingInToDomain": linkAccountBody.isLoggingInToDomain }); } function init() { @@ -99,6 +109,7 @@ Item { errorContainer.height = (loginErrorMessageTextMetrics.width / displayNameField.width) * loginErrorMessageTextMetrics.height; } loginButton.text = (!linkAccountBody.linkSteam && !linkAccountBody.linkOculus) ? "Log In" : "Link Account"; + loginButton.text = (!isLoggingInToDomain) ? "Log In" : "Log In to Domain"; loginButton.color = hifi.buttons.blue; displayNameField.placeholderText = "Display Name (optional)"; var savedDisplayName = Settings.getValue("Avatar/displayName", ""); @@ -393,7 +404,7 @@ Item { HifiStylesUit.ShortcutText { id: cantAccessText z: 10 - visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus + visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus && !linkAccountBody.isLoggingInToDomain anchors { top: loginButton.bottom topMargin: hifi.dimensions.contentSpacing.y @@ -492,7 +503,7 @@ Item { id: signUpContainer width: loginContainer.width height: signUpTextMetrics.height - visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus + visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus && !linkAccountBody.isLoggingInToDomain anchors { left: loginContainer.left top: loginContainer.bottom diff --git a/interface/resources/qml/LoginDialog/LoggingInBody.qml b/interface/resources/qml/LoginDialog/LoggingInBody.qml index a0029dc40b..8824be8625 100644 --- a/interface/resources/qml/LoginDialog/LoggingInBody.qml +++ b/interface/resources/qml/LoginDialog/LoggingInBody.qml @@ -31,6 +31,7 @@ Item { property bool linkSteam: linkSteam property bool linkOculus: linkOculus property bool createOculus: createOculus + property bool isLoggingInToDomain: isLoggingInToDomain property string displayName: "" readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() @@ -106,6 +107,9 @@ Item { loggingInGlyph.visible = true; loggingInText.text = "Logging in to Oculus"; loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2; + } else if (loggingInBody.isLoggingInToDomain) { + loggingInText.text = "Logging in to Domain"; + loggingInText.anchors.centerIn = loggingInHeader; } else { loggingInText.text = "Logging in"; loggingInText.anchors.centerIn = loggingInHeader; From cd9f47004be388a3b7c2c68426a65879b23074c5 Mon Sep 17 00:00:00 2001 From: Kasen IO Date: Thu, 23 Jul 2020 22:14:35 -0400 Subject: [PATCH 2/8] Added loginDomain stub. --- interface/src/ui/LoginDialog.cpp | 6 ++++++ interface/src/ui/LoginDialog.h | 1 + 2 files changed, 7 insertions(+) diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index c0e96fe8bb..ca9ae4282d 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -135,6 +135,12 @@ 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 QUrl domainAuthProvider) const { + qDebug() << "Attempting to login " << username << "into a domain through" << domainAuthProvider; + // TODO: + // DependencyManager::get()->requestAccessToken(username, password, domainAuthProvider); +} + void LoginDialog::loginThroughOculus() { qDebug() << "Attempting to login through Oculus"; if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { diff --git a/interface/src/ui/LoginDialog.h b/interface/src/ui/LoginDialog.h index 7c659a9320..6ccef3fa39 100644 --- a/interface/src/ui/LoginDialog.h +++ b/interface/src/ui/LoginDialog.h @@ -71,6 +71,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 QUrl domainAuthProvider) const; Q_INVOKABLE void loginThroughSteam(); Q_INVOKABLE void linkSteam(); Q_INVOKABLE void createAccountFromSteam(QString username = QString()); From 9bb913983d935a249625c6029667e274ab85aaf4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jul 2020 15:31:17 +1200 Subject: [PATCH 3/8] Stub out basics for displaying the domain login dialog --- interface/src/Application.cpp | 14 +++++++ interface/src/ui/DialogsManager.cpp | 13 +++++++ interface/src/ui/DialogsManager.h | 1 + .../networking/src/DomainAccountManager.cpp | 35 +++++++++++++++++ .../networking/src/DomainAccountManager.h | 39 +++++++++++++++++++ libraries/networking/src/DomainHandler.cpp | 16 +++++++- libraries/networking/src/DomainHandler.h | 1 + 7 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 libraries/networking/src/DomainAccountManager.cpp create mode 100644 libraries/networking/src/DomainAccountManager.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b7b2fea67d..df72f0cc4e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -852,6 +853,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { #else DependencyManager::set(true, std::bind(&Application::getUserAgent, qApp)); #endif + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(ScriptEngine::CLIENT_SCRIPT, defaultScriptsOverrideOption); DependencyManager::set(); @@ -1348,6 +1350,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo #endif connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle); + + auto domainAccountManager = DependencyManager::get(); + connect(domainAccountManager.data(), &DomainAccountManager::authRequired, dialogsManager.data(), + &DialogsManager::showDomainLoginDialog); + + // ####### TODO + + // use our MyAvatar position and quat for address manager path addressManager->setPositionGetter([] { auto avatarManager = DependencyManager::get(); @@ -2801,6 +2811,7 @@ void Application::cleanupBeforeQuit() { if (!keepMeLoggedIn) { DependencyManager::get()->removeAccountFromFile(); } + // ####### TODO _displayPlugin.reset(); PluginManager::getInstance()->shutdown(); @@ -3150,6 +3161,7 @@ extern void setupPreferences(); static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, int index, bool active = false); #endif +// ####### TODO void Application::showLoginScreen() { #if !defined(DISABLE_QML) auto accountManager = DependencyManager::get(); @@ -7072,6 +7084,7 @@ void Application::updateWindowTitle() const { + (BuildInfo::BUILD_TYPE == BuildInfo::BuildType::Stable ? QString("Version") : QString("Build")) + " " + applicationVersion(); + // ####### TODO QString loginStatus = accountManager->isLoggedIn() ? "" : " (NOT LOGGED IN)"; QString connectionStatus = isInErrorState ? " (ERROR CONNECTING)" : @@ -9430,6 +9443,7 @@ void Application::forceDisplayName(const QString& displayName) { getMyAvatar()->setDisplayName(displayName); } void Application::forceLoginWithTokens(const QString& tokens) { + // ####### TODO DependencyManager::get()->setAccessTokens(tokens); Setting::Handle(KEEP_ME_LOGGED_IN_SETTING_NAME, true).set(true); } diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 0a655de5e5..7cba608feb 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -121,10 +121,23 @@ void DialogsManager::hideLoginDialog() { LoginDialog::hide(); } + +void DialogsManager::showDomainLoginDialog() { + + // #######: TODO + + qDebug() << "#######: showDomainLoginDialog()"; + +} + +// #######: TODO + + void DialogsManager::showUpdateDialog() { UpdateDialog::show(); } + void DialogsManager::octreeStatsDetails() { if (!_octreeStatsDialog) { _octreeStatsDialog = new OctreeStatsDialog(qApp->getWindow(), qApp->getOcteeSceneStats()); diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index 949c86c240..10bdb4bb20 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -49,6 +49,7 @@ public slots: void toggleLoginDialog(); void showLoginDialog(); void hideLoginDialog(); + void showDomainLoginDialog(); void octreeStatsDetails(); void lodTools(); void hmdTools(bool showTools); diff --git a/libraries/networking/src/DomainAccountManager.cpp b/libraries/networking/src/DomainAccountManager.cpp new file mode 100644 index 0000000000..0d7f38d3f6 --- /dev/null +++ b/libraries/networking/src/DomainAccountManager.cpp @@ -0,0 +1,35 @@ +// +// DomainAccountManager.cpp +// libraries/networking/src +// +// Created by David Rowe on 23 Jul 2020. +// Copyright 2020 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "DomainAccountManager.h" + + +DomainAccountManager::DomainAccountManager() { + +} + +bool DomainAccountManager::hasValidAccessToken() { + + // #######: TODO + + return false; +} + +bool DomainAccountManager::checkAndSignalForAccessToken() { + bool hasToken = hasValidAccessToken(); + + if (!hasToken) { + // Emit a signal so somebody can call back to us and request an access token given a user name and password. + emit authRequired(); + } + + return hasToken; +} diff --git a/libraries/networking/src/DomainAccountManager.h b/libraries/networking/src/DomainAccountManager.h new file mode 100644 index 0000000000..696df71ab1 --- /dev/null +++ b/libraries/networking/src/DomainAccountManager.h @@ -0,0 +1,39 @@ +// +// DomainAccountManager.h +// libraries/networking/src +// +// Created by David Rowe on 23 Jul 2020. +// Copyright 2020 Vircadia contributors. +// +// 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_DomainAccountManager_h +#define hifi_DomainAccountManager_h + +#include + +#include + + +class DomainAccountManager : public QObject, public Dependency { + Q_OBJECT +public: + DomainAccountManager(); + + Q_INVOKABLE bool checkAndSignalForAccessToken(); + +public slots: + +signals: + void authRequired(); + +private slots: + +private: + bool hasValidAccessToken(); + +}; + +#endif // hifi_DomainAccountManager_h diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 1ad371721f..ceb2928c93 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -24,6 +24,7 @@ #include "AddressManager.h" #include "Assignment.h" +#include "DomainAccountManager.h" #include "HifiSockAddr.h" #include "NodeList.h" #include "udt/Packet.h" @@ -500,6 +501,7 @@ bool DomainHandler::reasonSuggestsMetaverseLogin(ConnectionRefusedReason reasonC case ConnectionRefusedReason::Unknown: case ConnectionRefusedReason::ProtocolMismatch: case ConnectionRefusedReason::TooManyUsers: + case ConnectionRefusedReason::NotAuthorizedDomain: return false; } return false; @@ -515,6 +517,7 @@ bool DomainHandler::reasonSuggestsDomainLogin(ConnectionRefusedReason reasonCode case ConnectionRefusedReason::Unknown: case ConnectionRefusedReason::ProtocolMismatch: case ConnectionRefusedReason::TooManyUsers: + case ConnectionRefusedReason::NotAuthorizedMetaverse: return false; } return false; @@ -557,12 +560,13 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer(); // Some connection refusal reasons imply that a login is required. If so, suggest a new login. if (reasonSuggestsMetaverseLogin(reasonCode)) { qCWarning(networking) << "Make sure you are logged in to the metaverse."; + auto accountManager = DependencyManager::get(); + if (!_hasCheckedForAccessToken) { accountManager->checkAndSignalForAccessToken(); _hasCheckedForAccessToken = true; @@ -578,7 +582,15 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer(); + + if (!_hasCheckedForDomainAccessToken) { + accountManager->checkAndSignalForAccessToken(); + _hasCheckedForDomainAccessToken = true; + } + + // ####### TODO: regenerate key-pair after several failed connection attempts, similar to metaverse login code? + } } diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 5bbaac18c5..b9e6aa65b6 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -291,6 +291,7 @@ private: QSet _domainConnectionRefusals; bool _hasCheckedForAccessToken { false }; + bool _hasCheckedForDomainAccessToken { false }; int _connectionDenialsSinceKeypairRegen { 0 }; int _checkInPacketsSinceLastReply { 0 }; From 82252cdc08f6b7e33b8fb0f85f5167808de8dab3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jul 2020 16:22:52 +1200 Subject: [PATCH 4/8] Get basics working --- domain-server/src/DomainGatekeeper.cpp | 2 +- libraries/networking/src/DomainHandler.cpp | 2 ++ libraries/networking/src/NodeList.cpp | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index ea7f0d2d91..350eda7bf0 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -514,7 +514,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect nodeConnection.machineFingerprint); if (!userPerms.can(NodePermissions::Permission::canConnectToDomain)) { - if (domainHasLogin() && !domainUsername.isEmpty()) { + if (domainHasLogin()) { sendConnectionDeniedPacket("You lack the required permissions to connect to this domain.", nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::NotAuthorizedDomain); } else { diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index ceb2928c93..8a8ffe9f8a 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -221,6 +221,8 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) { QString previousHost = _domainURL.host(); _domainURL = domainURL; + _hasCheckedForDomainAccessToken = false; + if (previousHost != domainURL.host()) { qCDebug(networking) << "Updated domain hostname to" << domainURL.host(); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 63c2e9c902..79b939d409 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -486,10 +486,10 @@ void NodeList::sendDomainServerCheckIn() { // ####### If get into difficulties, could perhaps send domain's username and signature instead of metaverse. bool domainLoginIsConnected = false; if (!domainLoginIsConnected) { - if (true) { + if (false) { // ####### For testing, false causes user to be considered "not logged in". packetStream << QString("a@b.c"); - if (true) { - packetStream << QString("signature"); + if (true) { // ####### For testing, false is unhandled at this stage. + packetStream << QString("signature"); // #######: Consider "logged in" if this is sent during testing. } } } From 34eb74ac00fb20a1a879d66dbd7179bdf47f98d5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jul 2020 16:26:57 +1200 Subject: [PATCH 5/8] Update copyrights --- domain-server/src/DomainGatekeeper.cpp | 1 + domain-server/src/DomainGatekeeper.h | 1 + interface/src/Application.cpp | 1 + interface/src/ui/DialogsManager.cpp | 1 + interface/src/ui/DialogsManager.h | 1 + libraries/networking/src/DomainHandler.cpp | 1 + libraries/networking/src/DomainHandler.h | 1 + libraries/networking/src/NodeList.cpp | 1 + libraries/networking/src/NodePermissions.h | 1 + 9 files changed, 9 insertions(+) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 350eda7bf0..75cb11dab7 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -4,6 +4,7 @@ // // Created by Stephen Birarda on 2015-08-24. // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/domain-server/src/DomainGatekeeper.h b/domain-server/src/DomainGatekeeper.h index fcf8e5aede..172c63028c 100644 --- a/domain-server/src/DomainGatekeeper.h +++ b/domain-server/src/DomainGatekeeper.h @@ -4,6 +4,7 @@ // // Created by Stephen Birarda on 2015-08-24. // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index df72f0cc4e..c401733b09 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4,6 +4,7 @@ // // Created by Andrzej Kapolka on 5/10/13. // Copyright 2013 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 7cba608feb..c74342cb45 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -4,6 +4,7 @@ // // Created by Clement on 1/18/15. // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index 10bdb4bb20..6e701df9ef 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -4,6 +4,7 @@ // // Created by Clement on 1/18/15. // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 8a8ffe9f8a..66d4c58a34 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -4,6 +4,7 @@ // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index b9e6aa65b6..ff252426a9 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -4,6 +4,7 @@ // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 79b939d409..262ad0d2a4 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -4,6 +4,7 @@ // // Created by Stephen Birarda on 2/15/13. // Copyright 2013 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/networking/src/NodePermissions.h b/libraries/networking/src/NodePermissions.h index 2b681eb7ee..6658b7ea12 100644 --- a/libraries/networking/src/NodePermissions.h +++ b/libraries/networking/src/NodePermissions.h @@ -4,6 +4,7 @@ // // Created by Seth Alves on 2016-6-1. // Copyright 2016 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html From 0618427d0f0d1912bb7d4fa7a6b13802d7c134a8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jul 2020 20:40:52 +1200 Subject: [PATCH 6/8] Wire up domain login dialog --- .../qml/LoginDialog/LinkAccountBody.qml | 7 ++----- .../qml/LoginDialog/LoggingInBody.qml | 1 + interface/src/Application.cpp | 2 +- interface/src/ui/DialogsManager.cpp | 16 +++++++++++--- interface/src/ui/DialogsManager.h | 3 +++ interface/src/ui/LoginDialog.cpp | 21 +++++++++++++++++-- interface/src/ui/LoginDialog.h | 7 ++++++- 7 files changed, 45 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index cd19662931..5c02de08d5 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -45,11 +45,8 @@ Item { property bool lostFocus: false readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() - // TODO: - // readonly property bool isLoggingInToDomain: loginDialog.getDomainLoginRequested() - // readonly property bool domainAuthProvider: loginDialog.getDomainLoginAuthProvider() - readonly property bool isLoggingInToDomain: true - readonly property string domainAuthProvider: "https://example.com/oauth2" + readonly property bool isLoggingInToDomain: loginDialog.getDomainLoginRequested() + readonly property string domainAuthProvider: loginDialog.getDomainLoginAuthProvider() QtObject { id: d diff --git a/interface/resources/qml/LoginDialog/LoggingInBody.qml b/interface/resources/qml/LoginDialog/LoggingInBody.qml index 8824be8625..796798a2de 100644 --- a/interface/resources/qml/LoginDialog/LoggingInBody.qml +++ b/interface/resources/qml/LoginDialog/LoggingInBody.qml @@ -3,6 +3,7 @@ // // Created by Wayne Chen on 10/18/18 // Copyright 2018 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c401733b09..72e6af74ec 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1356,7 +1356,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(domainAccountManager.data(), &DomainAccountManager::authRequired, dialogsManager.data(), &DialogsManager::showDomainLoginDialog); - // ####### TODO + // ####### TODO: Connect any other signals from domainAccountManager. // use our MyAvatar position and quat for address manager path diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index c74342cb45..272c495789 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -111,10 +111,18 @@ void DialogsManager::setDomainConnectionFailureVisibility(bool visible) { } void DialogsManager::toggleLoginDialog() { + _isDomainLogin = false; LoginDialog::toggleAction(); } void DialogsManager::showLoginDialog() { + + qDebug() << "#######: showLoginDialog()"; + + // ####### TODO: May be called from script via DialogsManagerScriptingInterface. Need to handle the case that it's already + // displayed and may be the domain login version. + + _isDomainLogin = false; LoginDialog::showWithSelection(); } @@ -125,13 +133,15 @@ void DialogsManager::hideLoginDialog() { void DialogsManager::showDomainLoginDialog() { - // #######: TODO - qDebug() << "#######: showDomainLoginDialog()"; + _isDomainLogin = true; + LoginDialog::showWithSelection(); } -// #######: TODO +// #######: TODO: Domain version of toggleLoginDialog()? + +// #######: TODO: Domain version of hiadLoginDialog()? void DialogsManager::showUpdateDialog() { diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index 6e701df9ef..30127ced68 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -41,6 +41,7 @@ public: QPointer getTestingDialog() const { return _testingDialog; } void emitAddressBarShown(bool visible) { emit addressBarShown(visible); } void setAddressBarVisible(bool addressBarVisible); + bool getIsDomainLogin() { return _isDomainLogin; } public slots: void showAddressBar(); @@ -84,6 +85,8 @@ private: QPointer _domainConnectionDialog; bool _dialogCreatedWhileShown { false }; bool _addressBarVisible { false }; + + bool _isDomainLogin { false }; }; #endif // hifi_DialogsManager_h diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index ca9ae4282d..f185b0ab2b 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -4,6 +4,7 @@ // // Created by Bradley Austin Davis on 2015/04/14 // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -25,6 +26,7 @@ #include "AccountManager.h" #include "DependencyManager.h" +#include "DialogsManager.h" #include "Menu.h" #include "Application.h" @@ -135,10 +137,15 @@ 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 QUrl domainAuthProvider) const { +void LoginDialog::loginDomain(const QString& username, const QString& password, const QString& domainAuthProvider) const { + qDebug() << "####### LoginDialog::loginDomain()"; + qDebug() << "Attempting to login " << username << "into a domain through" << domainAuthProvider; - // TODO: + // ####### TODO // 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::loginThroughOculus() { @@ -416,3 +423,13 @@ void LoginDialog::signupFailed(QNetworkReply* reply) { emit handleSignupFailed(DEFAULT_SIGN_UP_FAILURE_MESSAGE); } } + +bool LoginDialog::getDomainLoginRequested() const { + return DependencyManager::get()->getIsDomainLogin(); +} + +// ####### TODO: This method may not be necessary. +QString LoginDialog::getDomainLoginAuthProvider() const { + // ####### TODO + return QString("https://example.com/oauth2"); +} diff --git a/interface/src/ui/LoginDialog.h b/interface/src/ui/LoginDialog.h index 6ccef3fa39..49d5dc8fac 100644 --- a/interface/src/ui/LoginDialog.h +++ b/interface/src/ui/LoginDialog.h @@ -4,6 +4,7 @@ // // Created by Bradley Austin Davis on 2015/04/14 // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -71,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 QUrl domainAuthProvider) const; + Q_INVOKABLE void loginDomain(const QString& username, const QString& password, const QString& domainAuthProvider) const; Q_INVOKABLE void loginThroughSteam(); Q_INVOKABLE void linkSteam(); Q_INVOKABLE void createAccountFromSteam(QString username = QString()); @@ -82,6 +83,10 @@ protected slots: Q_INVOKABLE void signup(const QString& email, const QString& username, const QString& password); Q_INVOKABLE bool getLoginDialogPoppedUp() const; + + Q_INVOKABLE bool getDomainLoginRequested() const; + Q_INVOKABLE QString getDomainLoginAuthProvider() const; + }; #endif // hifi_LoginDialog_h From 361ab97d83c003349ab23a6c91d73593201dc676 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jul 2020 20:53:23 +1200 Subject: [PATCH 7/8] Fix saving metaverse login --- .../qml/LoginDialog/LinkAccountBody.qml | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 5c02de08d5..6f437bb991 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -112,8 +112,13 @@ Item { var savedDisplayName = Settings.getValue("Avatar/displayName", ""); displayNameField.text = savedDisplayName; emailField.placeholderText = "Username or Email"; - var savedUsername = Settings.getValue("keepMeLoggedIn/savedUsername", ""); - emailField.text = keepMeLoggedInCheckbox.checked ? savedUsername === "Unknown user" ? "" : savedUsername : ""; + if (!isLoggingInToDomain) { + var savedUsername = Settings.getValue("keepMeLoggedIn/savedUsername", ""); + emailField.text = keepMeLoggedInCheckbox.checked ? savedUsername === "Unknown user" ? "" : savedUsername : ""; + } else { + // ####### TODO + } + if (linkAccountBody.linkSteam || linkAccountBody.linkOculus) { loginButton.width = (passwordField.width - hifi.dimensions.contentSpacing.x) / 2; loginButton.anchors.right = displayNameField.right; @@ -201,7 +206,11 @@ Item { case Qt.Key_Return: event.accepted = true; if (keepMeLoggedInCheckbox.checked) { - Settings.setValue("keepMeLoggedIn/savedUsername", emailField.text); + if (!isLoggingInToDomain) { + Settings.setValue("keepMeLoggedIn/savedUsername", emailField.text); + } else { + // ####### TODO + } } linkAccountBody.login(); break; @@ -240,7 +249,11 @@ Item { case Qt.Key_Return: event.accepted = true; if (keepMeLoggedInCheckbox.checked) { - Settings.setValue("keepMeLoggedIn/savedUsername", emailField.text); + if (!isLoggingInToDomain) { + Settings.setValue("keepMeLoggedIn/savedUsername", emailField.text); + } else { + // ####### TODO + } } linkAccountBody.login(); break; @@ -320,7 +333,11 @@ Item { case Qt.Key_Return: event.accepted = true; if (keepMeLoggedInCheckbox.checked) { - Settings.setValue("keepMeLoggedIn/savedUsername", emailField.text); + if (!isLoggingInToDomain) { + Settings.setValue("keepMeLoggedIn/savedUsername", emailField.text); + } else { + // ####### TODO + } } linkAccountBody.login(); break; @@ -329,7 +346,7 @@ Item { } HifiControlsUit.CheckBox { id: keepMeLoggedInCheckbox - checked: Settings.getValue("keepMeLoggedIn", false); + checked: !isLoggingInToDomain ? Settings.getValue("keepMeLoggedIn", false) : false; // ####### TODO text: qsTr("Keep Me Logged In"); boxSize: 18; labelFontFamily: linkAccountBody.fontFamily @@ -342,14 +359,22 @@ Item { } onCheckedChanged: { Settings.setValue("keepMeLoggedIn", checked); - if (keepMeLoggedInCheckbox.checked) { - Settings.setValue("keepMeLoggedIn/savedUsername", emailField.text); + if (!isLoggingInToDomain) { + if (keepMeLoggedInCheckbox.checked) { + Settings.setValue("keepMeLoggedIn/savedUsername", emailField.text); + } else { + Settings.setValue("keepMeLoggedIn/savedUsername", ""); + } } else { - Settings.setValue("keepMeLoggedIn/savedUsername", ""); + // ####### TODO } } Component.onCompleted: { - keepMeLoggedInCheckbox.checked = !Account.loggedIn; + if (!isLoggingInToDomain) { + keepMeLoggedInCheckbox.checked = !Account.loggedIn; + } else { + // ####### TODO + } } } HifiControlsUit.Button { From ed444383872c365190a37bbe44795684d91f1be0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jul 2020 21:46:18 +1200 Subject: [PATCH 8/8] Fix domain login dialog disappearing when teleport to domain --- interface/src/ui/DialogsManager.cpp | 5 ----- interface/src/ui/LoginDialog.cpp | 6 ++---- libraries/networking/src/DomainAccountManager.cpp | 6 +++++- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 272c495789..848663967f 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -117,8 +117,6 @@ void DialogsManager::toggleLoginDialog() { void DialogsManager::showLoginDialog() { - qDebug() << "#######: showLoginDialog()"; - // ####### TODO: May be called from script via DialogsManagerScriptingInterface. Need to handle the case that it's already // displayed and may be the domain login version. @@ -132,9 +130,6 @@ void DialogsManager::hideLoginDialog() { void DialogsManager::showDomainLoginDialog() { - - qDebug() << "#######: showDomainLoginDialog()"; - _isDomainLogin = true; LoginDialog::showWithSelection(); } diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index f185b0ab2b..94800529b9 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -133,14 +133,12 @@ void LoginDialog::dismissLoginDialog() { } void LoginDialog::login(const QString& username, const QString& password) const { - qDebug() << "Attempting to login " << username; + qDebug() << "Attempting to login" << username; DependencyManager::get()->requestAccessToken(username, password); } void LoginDialog::loginDomain(const QString& username, const QString& password, const QString& domainAuthProvider) const { - qDebug() << "####### LoginDialog::loginDomain()"; - - qDebug() << "Attempting to login " << username << "into a domain through" << domainAuthProvider; + qDebug() << "Attempting to login" << username << "into a domain through" << domainAuthProvider; // ####### TODO // DependencyManager::get()->requestAccessToken(username, password, domainAuthProvider); diff --git a/libraries/networking/src/DomainAccountManager.cpp b/libraries/networking/src/DomainAccountManager.cpp index 0d7f38d3f6..d1da09817c 100644 --- a/libraries/networking/src/DomainAccountManager.cpp +++ b/libraries/networking/src/DomainAccountManager.cpp @@ -11,6 +11,8 @@ #include "DomainAccountManager.h" +#include + DomainAccountManager::DomainAccountManager() { @@ -28,7 +30,9 @@ bool DomainAccountManager::checkAndSignalForAccessToken() { if (!hasToken) { // Emit a signal so somebody can call back to us and request an access token given a user name and password. - emit authRequired(); + + // Dialog can be hidden immediately after showing if we've just teleported to the domain, unless the signal is delayed. + QTimer::singleShot(500, this, [this] { emit this->authRequired(); }); } return hasToken;