improving flow from Oculus API to login dialog wip

This commit is contained in:
Wayne Chen 2019-01-04 16:55:03 -08:00
parent 1af57bdba6
commit 970798705c
8 changed files with 137 additions and 79 deletions

View file

@ -394,10 +394,10 @@ Item {
buttonGlyphSize: 24 buttonGlyphSize: 24
buttonGlyphRightMargin: 10 buttonGlyphRightMargin: 10
onClicked: { onClicked: {
// if (loginDialog.isOculusRunning()) { if (loginDialog.isOculusRunning()) {
// linkAccountBody.withOculus = true; linkAccountBody.withOculus = true;
// loginDialog.loginThroughSteam(); loginDialog.loginThroughOculus();
// } else } else
if (loginDialog.isSteamRunning()) { if (loginDialog.isSteamRunning()) {
linkAccountBody.withSteam = true; linkAccountBody.withSteam = true;
loginDialog.loginThroughSteam(); loginDialog.loginThroughSteam();
@ -527,6 +527,9 @@ Item {
}); });
} }
} }
onLoginFailed: {
console.log("login failed");
}
} }
Component.onCompleted: { Component.onCompleted: {
@ -539,9 +542,6 @@ Item {
Qt.callLater(function() { Qt.callLater(function() {
emailField.forceActiveFocus(); emailField.forceActiveFocus();
}); });
if (loginDialog.isOculusRunning()) {
print(loginDialog.getLoggedInUserID());
}
} }
Keys.onPressed: { Keys.onPressed: {

View file

@ -252,7 +252,11 @@ Item {
console.log("Login Failed") console.log("Login Failed")
loggingInSpinner.visible = false; loggingInSpinner.visible = false;
var errorString = ""; var errorString = "";
if (loggingInBody.linkSteam && loggingInBody.withSteam) { if (loggingInBody.withOculus) {
loggingInGlyph.visible = false;
errorString = "Your Oculus authentication has failed. Please make sure you are logged into Oculus and try again.";
bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": false, "errorString": errorString });
} else if (loggingInBody.linkSteam && loggingInBody.withSteam) {
errorString = "Username or password is incorrect."; errorString = "Username or password is incorrect.";
bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, "linkSteam": loggingInBody.linkSteam, "errorString": errorString }); bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, "linkSteam": loggingInBody.linkSteam, "errorString": errorString });
} else if (loggingInBody.withSteam) { } else if (loggingInBody.withSteam) {

View file

@ -126,11 +126,13 @@ void LoginDialog::login(const QString& username, const QString& password) const
void LoginDialog::loginThroughOculus() { void LoginDialog::loginThroughOculus() {
qDebug() << "Attempting to login through Oculus"; qDebug() << "Attempting to login through Oculus";
if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) {
oculusPlatform->requestTicket([this](Ticket ticket) { oculusPlatform->requestTicket([this](QString nonce, QString userID) {
if (ticket.isNull()) { if (nonce.isEmpty() || userID.isEmpty()) {
emit handleLoginFailed(); emit handleLoginFailed();
return; return;
} }
DependencyManager::get<AccountManager>()->requestAccessTokenWithOculus(nonce, userID);
}); });
} }
} }
@ -138,11 +140,26 @@ void LoginDialog::loginThroughOculus() {
void LoginDialog::linkOculus() { void LoginDialog::linkOculus() {
qDebug() << "Attempting to link Oculus account"; qDebug() << "Attempting to link Oculus account";
if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) {
oculusPlatform->requestTicket([this](Ticket ticket) { oculusPlatform->requestTicket([this](QString nonce, QString userID) {
if (ticket.isNull()) { if (nonce.isEmpty() || userID.isEmpty()) {
emit handleLoginFailed(); emit handleLoginFailed();
return; return;
} }
JSONCallbackParameters callbackParams;
callbackParams.callbackReceiver = this;
callbackParams.jsonCallbackMethod = "linkCompleted";
callbackParams.errorCallbackMethod = "linkFailed";
const QString LINK_OCULUS_PATH = "api/v1/user/oculus/link";
QJsonObject payload;
payload.insert("oculus_nonce", QJsonValue::fromVariant(QVariant(nonce)));
payload.insert("oculus_user_id", QJsonValue::fromVariant(QVariant(userID)));
auto accountManager = DependencyManager::get<AccountManager>();
accountManager->sendRequest(LINK_OCULUS_PATH, AccountManagerAuth::Required,
QNetworkAccessManager::PostOperation, callbackParams,
QJsonDocument(payload).toJson());
}); });
} }
} }
@ -150,11 +167,30 @@ void LoginDialog::linkOculus() {
void LoginDialog::createAccountFromOculus(QString username) { void LoginDialog::createAccountFromOculus(QString username) {
qDebug() << "Attempting to create account from Oculus info"; qDebug() << "Attempting to create account from Oculus info";
if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) {
oculusPlatform->requestTicket([this](Ticket ticket) { oculusPlatform->requestTicket([this, username](QString nonce, QString userID) {
if (ticket.isNull()) { if (nonce.isEmpty() || userID.isEmpty()) {
emit handleLoginFailed(); emit handleLoginFailed();
return; return;
} }
JSONCallbackParameters callbackParams;
callbackParams.callbackReceiver = this;
callbackParams.jsonCallbackMethod = "createCompleted";
callbackParams.errorCallbackMethod = "createFailed";
const QString CREATE_ACCOUNT_FROM_OCULUS_PATH = "api/v1/user/oculus/create";
QJsonObject payload;
payload.insert("oculus_nonce", QJsonValue::fromVariant(QVariant(nonce)));
payload.insert("oculus_user_id", QJsonValue::fromVariant(QVariant(userID)));
if (!username.isEmpty()) {
payload.insert("username", QJsonValue::fromVariant(QVariant(username)));
}
auto accountManager = DependencyManager::get<AccountManager>();
accountManager->sendRequest(CREATE_ACCOUNT_FROM_OCULUS_PATH, AccountManagerAuth::None,
QNetworkAccessManager::PostOperation, callbackParams,
QJsonDocument(payload).toJson());
}); });
} }
} }

View file

@ -586,7 +586,7 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) {
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError))); connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError)));
} }
void AccountManager::requestAccessTokenWithOculus(QByteArray authSessionTicket) { void AccountManager::requestAccessTokenWithOculus(const QString& nonce, const QString& userID) {
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
QNetworkRequest request; QNetworkRequest request;
@ -597,8 +597,8 @@ void AccountManager::requestAccessTokenWithOculus(QByteArray authSessionTicket)
QByteArray postData; QByteArray postData;
postData.append("grant_type=password&"); postData.append("grant_type=password&");
postData.append("oculus_nonce=" + QUrl::toPercentEncoding(authSessionTicket) + "&"); postData.append("oculus_nonce=" + nonce + "&");
postData.append("oculus_user_id=" + QUrl::toPercentEncoding(authSessionTicket) + "&"); postData.append("oculus_user_id=" + userID + "&");
postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE); postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
request.setUrl(grantURL); request.setUrl(grantURL);

View file

@ -104,7 +104,7 @@ public:
public slots: public slots:
void requestAccessToken(const QString& login, const QString& password); void requestAccessToken(const QString& login, const QString& password);
void requestAccessTokenWithSteam(QByteArray authSessionTicket); void requestAccessTokenWithSteam(QByteArray authSessionTicket);
void requestAccessTokenWithOculus(QByteArray authSessionTicket); void requestAccessTokenWithOculus(const QString& nonce, const QString& userID);
void requestAccessTokenWithAuthCode(const QString& authCode, const QString& clientId, const QString& clientSecret, const QString& redirectUri); void requestAccessTokenWithAuthCode(const QString& authCode, const QString& clientId, const QString& clientSecret, const QString& redirectUri);
void refreshAccessToken(); void refreshAccessToken();

View file

@ -12,8 +12,7 @@
#include <functional> #include <functional>
using Ticket = QByteArray; using OculusTicketRequestCallback = std::function<void(QString, QString)>;
using TicketRequestCallback = std::function<void(Ticket)>;
class OculusPlatformPlugin { class OculusPlatformPlugin {
@ -27,7 +26,7 @@ public:
virtual void runCallbacks() = 0; virtual void runCallbacks() = 0;
virtual void requestTicket(TicketRequestCallback callback) = 0; virtual void requestTicket(OculusTicketRequestCallback callback) = 0;
virtual QString getUserProof() = 0; virtual QString getUserProof() = 0;

View file

@ -20,17 +20,9 @@
#include <shared/GlobalAppProperties.h> #include <shared/GlobalAppProperties.h>
#include "OculusHelpers.h" #include "OculusHelpers.h"
static const Ticket INVALID_TICKET = Ticket();
static std::atomic_bool initialized { false }; static std::atomic_bool initialized { false };
static ovrSession session { nullptr }; static ovrSession session { nullptr };
class OculusCallbackManager {
public:
OculusCallbackManager();
};
static OculusCallbackManager oculusCallbackManager;
bool OculusAPIPlugin::init() { bool OculusAPIPlugin::init() {
if (session) { if (session) {
return initialized; return initialized;
@ -52,17 +44,30 @@ bool OculusAPIPlugin::init() {
} else { } else {
qCDebug(oculusLog) << "Performing Oculus Platform entitlement check"; qCDebug(oculusLog) << "Performing Oculus Platform entitlement check";
ovr_Entitlement_GetIsViewerEntitled(); ovr_Entitlement_GetIsViewerEntitled();
QTimer timer;
timer.start(1000);
using namespace std::chrono_literals; using namespace std::chrono_literals;
std::this_thread::sleep_for(100ms); std::this_thread::sleep_for(50ms);
auto message = ovr_PopMessage(); while (auto message = ovr_PopMessage()) {
if (ovr_Message_GetType(message) == ovrMessage_Entitlement_GetIsViewerEntitled && ovr_Message_IsError(message)) { if (timer.remainingTime() == 0) {
qCDebug(oculusLog) << "login user id timeout after 1 second";
break;
}
switch (ovr_Message_GetType(message)) {
case ovrMessage_Entitlement_GetIsViewerEntitled:
if (ovr_Message_IsError(message)) {
qDebug() << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); qDebug() << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
} }
initialized = true;
default:
ovr_FreeMessage(message);
break;
}
}
} }
} }
#endif #endif
initialized = true;
return initialized; return initialized;
} }
@ -72,14 +77,14 @@ void OculusAPIPlugin::shutdown() {
void OculusAPIPlugin::runCallbacks() { void OculusAPIPlugin::runCallbacks() {
} }
void OculusAPIPlugin::requestTicket(TicketRequestCallback callback) { void OculusAPIPlugin::requestTicket(OculusTicketRequestCallback callback) {
if (!initialized) { if (!initialized) {
if (!ovr_IsPlatformInitialized()) { if (!ovr_IsPlatformInitialized()) {
init(); init();
} }
else { else {
qWarning() << "Oculus is not running"; qWarning() << "Oculus is not running";
callback(INVALID_TICKET); callback("", "");
return; return;
} }
} }
@ -89,73 +94,87 @@ void OculusAPIPlugin::requestTicket(TicketRequestCallback callback) {
return; return;
} }
auto userProof = requestUserProof(); auto userProof = getUserProof();
if (userProof == "") { auto userID = getLoggedInUserID();
qWarning() << "User proof unavailable."; callback(userProof, userID);
callback(INVALID_TICKET);
return; return;
} else {
oculusCallbackManager;
}
} }
bool OculusAPIPlugin::isRunning() { bool OculusAPIPlugin::isRunning() {
return initialized; return initialized;
} }
QString OculusAPIPlugin::requestUserProof() { QString OculusAPIPlugin::getUserProof() {
if (initialized) { if (initialized) {
QTimer timer; QTimer timer;
timer.start(1000); timer.start(5000);
auto request = ovr_User_GetUserProof(); auto request = ovr_User_GetUserProof();
ovrMessageHandle message { nullptr }; ovrMessageHandle message { nullptr };
while (message = ovr_PopMessage()) { bool messageNotReceived = true;
if (message == nullptr) { while (timer.isActive() && messageNotReceived) {
break; message = ovr_PopMessage();
} else if (!timer.isActive()) { if (timer.remainingTime() == 0) {
qCDebug(oculusLog) << "login user id timeout after 1 second"; qCDebug(oculusLog) << "user proof timeout after 5 seconds";
return ""; return "";
} else if (ovr_Message_GetType(message) == ovrMessage_User_GetUserProof) { }
if (message != nullptr) {
switch (ovr_Message_GetType(message)) {
case ovrMessage_User_GetUserProof:
messageNotReceived = false;
if (!ovr_Message_IsError(message)) { if (!ovr_Message_IsError(message)) {
ovrUserProofHandle userProof = ovr_Message_GetUserProof(message); ovrUserProofHandle userProof = ovr_Message_GetUserProof(message);
QString nonce = ovr_UserProof_GetNonce(userProof); QString nonce = ovr_UserProof_GetNonce(userProof);
qCDebug(oculusLog) << "User nonce: " << nonce; ovr_FreeMessage(message);
return nonce; return nonce;
} else { } else {
qDebug() << "Error getting user proof: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); qDebug() << "Error getting user proof: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
ovr_FreeMessage(message);
return ""; return "";
} }
break;
default:
ovr_FreeMessage(message);
break;
}
}
} }
} }
return ""; return "";
}
} }
QString OculusAPIPlugin::getLoggedInUserID() { QString OculusAPIPlugin::getLoggedInUserID() {
if (initialized) { if (initialized) {
QTimer timer; QTimer timer;
timer.start(1000); timer.start(5000);
auto request = ovr_User_GetLoggedInUser(); auto request = ovr_User_GetLoggedInUser();
ovrMessageHandle message { nullptr }; ovrMessageHandle message { nullptr };
while (message = ovr_PopMessage()) { bool messageNotReceived = true;
if (message == nullptr) { while (messageNotReceived) {
break; if (timer.remainingTime() == 0) {
} else if (!timer.isActive()) { qCDebug(oculusLog) << "login user id timeout after 5 seconds";
qCDebug(oculusLog) << "login user id timeout after 1 second";
return ""; return "";
} else if (ovr_Message_GetType(message) == ovrMessage_User_GetLoggedInUser) { }
switch (ovr_Message_GetType(message)) {
case ovrMessage_User_GetLoggedInUser:
messageNotReceived = false;
if (!ovr_Message_IsError(message)) { if (!ovr_Message_IsError(message)) {
ovrUserHandle user = ovr_Message_GetUser(message); ovrUserHandle user = ovr_Message_GetUser(message);
qCDebug(oculusLog) << "UserID: " << ovr_User_GetID(user) << ", Oculus ID: " << ovr_User_GetOculusID(user); ovr_FreeMessage(message);
return ovr_User_GetOculusID(user); qCDebug(oculusLog) << "UserID: " << ovr_User_GetID(user) << ", Oculus ID: " << QString(ovr_User_GetOculusID(user));
return QString(ovr_User_GetOculusID(user));
} else { } else {
qDebug() << "Error getting user id: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); qDebug() << "Error getting user id: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
ovr_FreeMessage(message);
return ""; return "";
} }
break;
default:
ovr_FreeMessage(message);
break;
}
} }
} }
return ""; return "";
}
} }
QString OculusAPIPlugin::getOculusVRBuildID() { QString OculusAPIPlugin::getOculusVRBuildID() {

View file

@ -18,9 +18,9 @@ public:
void runCallbacks() override; void runCallbacks() override;
void requestTicket(TicketRequestCallback callback) override; void requestTicket(OculusTicketRequestCallback callback) override;
QString requestUserProof() override; QString getUserProof() override;
QString getLoggedInUserID() override; QString getLoggedInUserID() override;
QString getOculusVRBuildID() override; QString getOculusVRBuildID() override;