Files
llink/cpp/src/authmanager.cpp
T

229 lines
5.2 KiB
C++

#include "authmanager.h"
#include "networkmanager.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkReply>
#include <QSettings>
namespace
{
constexpr char key[] = "network/session_token";
}
AuthManager::AuthManager(QObject *parent)
: QObject{parent}, m_sessionData(nullptr), m_settings(new QSettings(this)), m_isSignedIn(false), m_lastEmail(""),
m_sessionToken("")
{
connect(&NetworkManager::instance(), &NetworkManager::unauthorizedDetected, this, [this]() {
if (!m_isSignedIn)
{
return;
}
setIsSignedIn(false);
if (m_sessionData)
{
delete m_sessionData;
m_sessionData = nullptr;
}
setSessionToken("");
});
}
void AuthManager::tryRestoreSession()
{
QString storageSessionToken = m_settings->value(key).toString();
if (storageSessionToken.isEmpty())
{
return;
}
qDebug() << "Storage session token is: " << storageSessionToken;
// set it here, and unset if it fails...network manager needs to inject into the request
setSessionToken(storageSessionToken);
QNetworkReply *reply = NetworkManager::instance().get("/auth/me");
connect(reply, &QNetworkReply::finished, this, [=]() {
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError)
{
qDebug() << "Saved session token is invalid";
setSessionToken("");
return;
}
qDebug() << "Saved session token is valid";
QByteArray responseData = reply->readAll();
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
if (jsonDoc.isNull())
{
qWarning() << "Failed to create a JSON doc.";
setSessionToken("");
return;
}
QJsonObject jsonObj = jsonDoc.object();
if (!m_sessionData)
{
m_sessionData = new SessionData{};
}
m_sessionData->id = jsonObj["id"].toString();
m_sessionData->email = jsonObj["email"].toString();
m_sessionData->emailPrefix = jsonObj["email_prefix"].toString();
setSessionToken(storageSessionToken);
setIsSignedIn(true);
});
}
void AuthManager::setIsSignedIn(bool newValue)
{
if (m_isSignedIn == newValue)
{
return;
}
m_isSignedIn = newValue;
emit isSignedInChanged();
if (m_isSignedIn)
{
emit signedIn();
}
else
{
emit signedOut();
}
}
bool AuthManager::isSignedIn() const
{
return m_isSignedIn;
}
SessionData *AuthManager::sessionData() const
{
return m_sessionData;
}
void AuthManager::requestSignInCode(const QString &email)
{
if (isSignedIn())
{
qWarning() << "Must sign out first";
return;
}
QJsonDocument body;
QJsonObject object;
object["email"] = email;
body.setObject(object);
QNetworkReply *reply = NetworkManager::instance().post("/auth/request-code", body);
connect(reply, &QNetworkReply::finished, this, [=]() {
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError)
{
emit errorOccurred("Unable to send code. Please try again.");
qDebug() << "Error in emailing auth code: " << reply->errorString();
return;
}
qDebug() << "Code successfully sent";
m_lastEmail = email;
emit codeSentToEmail(email);
});
}
void AuthManager::signIn(const QString &code)
{
if (isSignedIn())
{
qWarning() << "Must sign out first";
return;
}
assert(!m_lastEmail.isEmpty());
QJsonDocument body;
QJsonObject object;
object["email"] = m_lastEmail;
object["code"] = code;
body.setObject(object);
QNetworkReply *reply = NetworkManager::instance().post("/auth/sign-in", body);
connect(reply, &QNetworkReply::finished, this, [=]() {
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError)
{
emit errorOccurred("Unable to verify code. Please try again.");
qDebug() << "Error in verify code: " << reply->errorString();
return;
}
qDebug() << "Session successfully created";
QByteArray responseData = reply->readAll();
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
if (jsonDoc.isNull())
{
qWarning() << "Failed to create a JSON doc.";
emit errorOccurred("Unable to verify code");
return;
}
QJsonObject jsonObj = jsonDoc.object();
if (!m_sessionData)
{
m_sessionData = new SessionData{};
}
QJsonObject human = jsonObj["human"].toObject();
m_sessionData->id = human["id"].toString();
m_sessionData->email = human["email"].toString();
m_sessionData->emailPrefix = human["email_prefix"].toString();
setSessionToken(jsonObj["token"].toString());
setIsSignedIn(true);
});
}
void AuthManager::signOut()
{
if (!isSignedIn())
{
qWarning() << "Not signed in, skipping sign out";
return;
}
setIsSignedIn(false);
if (m_sessionData)
{
delete m_sessionData;
m_sessionData = nullptr;
}
setSessionToken("");
QNetworkReply *reply = NetworkManager::instance().post("/auth/sign-out", QJsonDocument());
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
}
void AuthManager::setSessionToken(const QString &newValue)
{
if (newValue.isEmpty())
{
m_settings->remove(key);
}
else
{
m_settings->setValue(key, newValue);
}
m_sessionToken = newValue;
NetworkManager::instance().setSessionToken(newValue);
}