1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-21 04:07:46 +00:00

Add LauncherCore::autoLogin function, remove separate impls

Previously there was two separate auto-login functions, one in the cli
interface and one for the desktop interface. If I didn't stop myself,
there would probably be one in the tablet interface too!
This commit is contained in:
Joshua Goins 2022-09-05 16:14:07 -04:00
parent ce7854626f
commit f28f8c392d
6 changed files with 82 additions and 102 deletions

View file

@ -21,45 +21,7 @@ bool CMDInterface::parse(QCommandLineParser& parser, LauncherCore& core) {
if (parser.isSet(autologinOption)) { if (parser.isSet(autologinOption)) {
auto& profile = core.getProfile(core.defaultProfileIndex); auto& profile = core.getProfile(core.defaultProfileIndex);
if (!profile.rememberUsername || !profile.rememberPassword) { return core.autoLogin(profile);
qInfo() << "Profile does not have a username and/or password saved, autologin disabled.";
return false;
}
auto loop = new QEventLoop();
QString username, password;
auto usernameJob = new QKeychain::ReadPasswordJob("LauncherWindow");
usernameJob->setKey(profile.name + "-username");
usernameJob->start();
core.connect(
usernameJob, &QKeychain::ReadPasswordJob::finished, [loop, usernameJob, &username](QKeychain::Job* j) {
username = usernameJob->textData();
loop->quit();
});
loop->exec();
auto passwordJob = new QKeychain::ReadPasswordJob("LauncherWindow");
passwordJob->setKey(profile.name + "-password");
passwordJob->start();
core.connect(
passwordJob, &QKeychain::ReadPasswordJob::finished, [loop, passwordJob, &password](QKeychain::Job* j) {
password = passwordJob->textData();
loop->quit();
});
loop->exec();
auto info = new LoginInformation();
info->settings = &profile;
info->username = username;
info->password = password;
core.login(*info);
} }
return true; return true;

View file

@ -53,7 +53,9 @@ target_link_libraries(astra_core PUBLIC
Qt5::Widgets # widgets is required by watchdog, to be fixed/removed later Qt5::Widgets # widgets is required by watchdog, to be fixed/removed later
Qt5::Quick # required for some type registrations Qt5::Quick # required for some type registrations
PRIVATE PRIVATE
astra_desktop) # desktop is currently required by the core, to be fixed/removed later astra_desktop
cotp
crypto) # desktop is currently required by the core, to be fixed/removed later
if (ENABLE_WATCHDOG) if (ENABLE_WATCHDOG)
target_include_directories(astra_core PUBLIC ${TESSERACT_INCLUDE_DIRS} ${LEPTONICA_INCLUDE_DIRS}) target_include_directories(astra_core PUBLIC ${TESSERACT_INCLUDE_DIRS} ${LEPTONICA_INCLUDE_DIRS})

View file

@ -161,6 +161,15 @@ public:
*/ */
void login(LoginInformation& loginInformation); void login(LoginInformation& loginInformation);
/*
* Attempts to log into a profile without LoginInformation, which may or may not work depending on a combination of
* the password failing, OTP not being available to auto-generate, among other things.
*
* The launcher will still warn the user about any possible errors, however the call site will need to check the
* result to see whether they need to "reset" or show a failed state or not.
*/
bool autoLogin(ProfileSettings& settings);
/* /*
* Launches the game using the provided authentication. * Launches the game using the provided authentication.
*/ */

View file

@ -19,6 +19,7 @@
#include <QUrlQuery> #include <QUrlQuery>
#include <algorithm> #include <algorithm>
#include <keychain.h> #include <keychain.h>
#include <cotp.h>
#include "assetupdater.h" #include "assetupdater.h"
#include "encryptedarg.h" #include "encryptedarg.h"
@ -731,3 +732,69 @@ void LauncherCore::login(LoginInformation& loginInformation) {
squareBoot->checkGateStatus(&loginInformation); squareBoot->checkGateStatus(&loginInformation);
} }
} }
bool LauncherCore::autoLogin(ProfileSettings& profile) {
auto loop = new QEventLoop();
QString username, password;
QString otpSecret;
auto usernameJob = new QKeychain::ReadPasswordJob("LauncherWindow");
usernameJob->setKey(profile.name + "-username");
usernameJob->start();
QObject::connect(
usernameJob, &QKeychain::ReadPasswordJob::finished, [loop, usernameJob, &username](QKeychain::Job* j) {
username = usernameJob->textData();
loop->quit();
});
loop->exec();
auto passwordJob = new QKeychain::ReadPasswordJob("LauncherWindow");
passwordJob->setKey(profile.name + "-password");
passwordJob->start();
QObject::connect(
passwordJob, &QKeychain::ReadPasswordJob::finished, [loop, passwordJob, &password](QKeychain::Job* j) {
password = passwordJob->textData();
loop->quit();
});
loop->exec();
// TODO: handle cases where the user doesn't want to store their OTP secret, so we have to manually prompt them
if(profile.useOneTimePassword && profile.rememberOTPSecret) {
auto otpJob = new QKeychain::ReadPasswordJob("LauncherWindow");
otpJob->setKey(profile.name + "-otpsecret");
otpJob->start();
QObject::connect(
otpJob, &QKeychain::ReadPasswordJob::finished, [loop, otpJob, &otpSecret](QKeychain::Job* j) {
otpSecret = otpJob->textData();
loop->quit();
});
loop->exec();
}
auto info = new LoginInformation();
info->settings = &profile;
info->username = username;
info->password = password;
if(profile.useOneTimePassword && !profile.rememberOTPSecret)
return false;
if(profile.useOneTimePassword && profile.rememberOTPSecret) {
// generate otp
char* totp = get_totp (otpSecret.toStdString().c_str(), 6, 30, SHA1, nullptr);
info->oneTimePassword = totp;
free (totp);
}
// TODO: when login fails, we need some way to propagate this back? or not?
login(*info);
return true;
}

View file

@ -24,6 +24,4 @@ target_link_libraries(astra_desktop PUBLIC
astra_core astra_core
Qt5::Core Qt5::Core
Qt5::Widgets Qt5::Widgets
Qt5::Network Qt5::Network)
cotp
crypto)

View file

@ -13,7 +13,6 @@
#include <QSpinBox> #include <QSpinBox>
#include <QToolTip> #include <QToolTip>
#include <keychain.h> #include <keychain.h>
#include <cotp.h>
#include "launchercore.h" #include "launchercore.h"
#include "launcherwindow.h" #include "launcherwindow.h"
@ -36,64 +35,7 @@ AutoLoginWindow::AutoLoginWindow(ProfileSettings& profile, LauncherCore& core, Q
auto autologinTimer = new QTimer(); auto autologinTimer = new QTimer();
connect(autologinTimer, &QTimer::timeout, [&, this, autologinTimer] { connect(autologinTimer, &QTimer::timeout, [&, this, autologinTimer] {
// TODO: this is the second place where I have implemented this. this is a good idea to abstract, maybe? :-) core.autoLogin(profile);
auto loop = new QEventLoop();
QString username, password;
QString otpSecret;
auto usernameJob = new QKeychain::ReadPasswordJob("LauncherWindow");
usernameJob->setKey(profile.name + "-username");
usernameJob->start();
QObject::connect(
usernameJob, &QKeychain::ReadPasswordJob::finished, [loop, usernameJob, &username](QKeychain::Job* j) {
username = usernameJob->textData();
loop->quit();
});
loop->exec();
auto passwordJob = new QKeychain::ReadPasswordJob("LauncherWindow");
passwordJob->setKey(profile.name + "-password");
passwordJob->start();
QObject::connect(
passwordJob, &QKeychain::ReadPasswordJob::finished, [loop, passwordJob, &password](QKeychain::Job* j) {
password = passwordJob->textData();
loop->quit();
});
loop->exec();
// TODO: handle cases where the user doesn't want to store their OTP secret, so we have to manually prompt them
if(profile.useOneTimePassword && profile.rememberOTPSecret) {
auto otpJob = new QKeychain::ReadPasswordJob("LauncherWindow");
otpJob->setKey(profile.name + "-otpsecret");
otpJob->start();
QObject::connect(
otpJob, &QKeychain::ReadPasswordJob::finished, [loop, otpJob, &otpSecret](QKeychain::Job* j) {
otpSecret = otpJob->textData();
loop->quit();
});
loop->exec();
}
auto info = new LoginInformation();
info->settings = &profile;
info->username = username;
info->password = password;
if(profile.useOneTimePassword && profile.rememberOTPSecret) {
// generate otp
char *totp = get_totp (otpSecret.toStdString().c_str(), 6, 30, SHA1, nullptr);
info->oneTimePassword = totp;
free (totp);
}
core.login(*info);
close(); close();
autologinTimer->stop(); autologinTimer->stop();