Automatically generate token (#22/#28)

Co-authored-by: anon <anon@noreply.localhost>
Co-authored-by: spectranator <spectranator@y2nlvhmmk5jnsvechppxnbyzmmv3vbl7dvzn6ltwcdbpgxixp3clkgqd.onion>
Reviewed-on: http://vub63vv26q6v27xzv2dtcd25xumubshogm67yrpaz2rculqxs7jlfqad.onion/torzu-emu/torzu/pulls/22
Reviewed-on: http://vub63vv26q6v27xzv2dtcd25xumubshogm67yrpaz2rculqxs7jlfqad.onion/torzu-emu/torzu/pulls/28
This commit is contained in:
spectranator 2024-07-26 15:38:31 +00:00 committed by spectranator
parent a1c2940b31
commit c92b9f9024
5 changed files with 39 additions and 107 deletions

View file

@ -177,6 +177,9 @@ void ConfigureProfileManager::UpdateCurrentUser() {
scene->addPixmap(
GetIcon(*current_user).scaled(48, 48, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
ui->current_user_username->setText(username);
// update the token username, process completed by ConfigureWeb::ApplyConfiguration()
Settings::values.yuzu_username = username.toStdString();
}
void ConfigureProfileManager::ApplyConfiguration() {

View file

@ -5,40 +5,15 @@
#include <QMessageBox>
#include <QtConcurrent/QtConcurrentRun>
#include "common/settings.h"
#include "common/uuid.h"
#include "ui_configure_web.h"
#include "yuzu/configuration/configure_web.h"
#include "yuzu/uisettings.h"
static constexpr char token_delimiter{':'};
static std::string GenerateDisplayToken(const std::string& username, const std::string& token) {
if (username.empty() || token.empty()) {
return {};
}
const std::string unencoded_display_token{username + token_delimiter + token};
QByteArray b{unencoded_display_token.c_str()};
QByteArray b64 = b.toBase64();
return b64.toStdString();
}
static std::string UsernameFromDisplayToken(const std::string& display_token) {
const std::string unencoded_display_token{
QByteArray::fromBase64(display_token.c_str()).toStdString()};
return unencoded_display_token.substr(0, unencoded_display_token.find(token_delimiter));
}
static std::string TokenFromDisplayToken(const std::string& display_token) {
const std::string unencoded_display_token{
QByteArray::fromBase64(display_token.c_str()).toStdString()};
return unencoded_display_token.substr(unencoded_display_token.find(token_delimiter) + 1);
}
ConfigureWeb::ConfigureWeb(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureWeb>()) {
ui->setupUi(this);
connect(ui->button_verify_login, &QPushButton::clicked, this, &ConfigureWeb::VerifyLogin);
connect(&verify_watcher, &QFutureWatcher<bool>::finished, this, &ConfigureWeb::OnLoginVerified);
connect(ui->button_reset_token, &QPushButton::clicked, this, &ConfigureWeb::ResetToken);
#ifndef USE_DISCORD_PRESENCE
ui->discord_group->setVisible(false);
@ -60,94 +35,51 @@ void ConfigureWeb::changeEvent(QEvent* event) {
void ConfigureWeb::RetranslateUI() {
ui->retranslateUi(this);
ui->web_signup_link->setText(
tr("<a href='https://profile.yuzu-emu.org/'><span style=\"text-decoration: underline; "
"color:#039be5;\">Sign up</span></a>"));
ui->web_token_info_link->setText(
tr("<a href='https://yuzu-emu.org/wiki/yuzu-web-service/'><span style=\"text-decoration: "
"underline; color:#039be5;\">What is my token?</span></a>"));
}
void ConfigureWeb::SetConfiguration() {
ui->web_credentials_disclaimer->setWordWrap(true);
ui->web_signup_link->setOpenExternalLinks(true);
ui->web_token_info_link->setOpenExternalLinks(true);
if (Settings::values.yuzu_username.GetValue().empty()) {
ui->username->setText(tr("Unspecified"));
} else {
ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
}
ui->edit_token->setText(QString::fromStdString(GenerateDisplayToken(
Settings::values.yuzu_username.GetValue(), Settings::values.yuzu_token.GetValue())));
// Connect after setting the values, to avoid calling OnLoginChanged now
connect(ui->edit_token, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged);
user_verified = true;
ui->edit_token->setText(QString::fromStdString(Settings::values.yuzu_token.GetValue()));
ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence.GetValue());
}
void ConfigureWeb::ApplyConfiguration() {
UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked();
if (user_verified) {
Settings::values.yuzu_username =
UsernameFromDisplayToken(ui->edit_token->text().toStdString());
Settings::values.yuzu_token = TokenFromDisplayToken(ui->edit_token->text().toStdString());
if (Settings::values.yuzu_username.GetValue().empty()) {
// Backup: default name should already be set by ConfigureProfileManager::UpdateCurrentUser()
Settings::values.yuzu_username = "torzu";
} else {
QMessageBox::warning(
this, tr("Token not verified"),
tr("Token was not verified. The change to your token has not been saved."));
}
// If a name already exist, reassign it to itself (needed for change set with a profile switch)
Settings::values.yuzu_username = Settings::values.yuzu_username.GetValue();
}
void ConfigureWeb::OnLoginChanged() {
if (ui->edit_token->text().isEmpty()) {
user_verified = true;
// Empty = no icon
ui->label_token_verified->setPixmap(QPixmap());
ui->label_token_verified->setToolTip(QString());
// If no token specified, automatically generate one
Settings::values.yuzu_token = Common::UUID::MakeRandom().FormattedString();
} else {
user_verified = false;
// Show an info icon if it's been changed, clearer than showing failure
const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("info")).pixmap(16);
ui->label_token_verified->setPixmap(pixmap);
ui->label_token_verified->setToolTip(
tr("Unverified, please click Verify before saving configuration", "Tooltip"));
// Otherwise use user-specified value
Settings::values.yuzu_token = ui->edit_token->text().toStdString();
}
}
void ConfigureWeb::VerifyLogin() {
ui->button_verify_login->setDisabled(true);
ui->button_verify_login->setText(tr("Verifying..."));
ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("sync")).pixmap(16));
ui->label_token_verified->setToolTip(tr("Verifying..."));
}
void ConfigureWeb::OnLoginVerified() {
ui->button_verify_login->setEnabled(true);
ui->button_verify_login->setText(tr("Verify"));
if (verify_watcher.result()) {
user_verified = true;
ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("checked")).pixmap(16));
ui->label_token_verified->setToolTip(tr("Verified", "Tooltip"));
ui->username->setText(
QString::fromStdString(UsernameFromDisplayToken(ui->edit_token->text().toStdString())));
} else {
ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("failed")).pixmap(16));
ui->label_token_verified->setToolTip(tr("Verification failed", "Tooltip"));
ui->username->setText(tr("Unspecified"));
QMessageBox::critical(this, tr("Verification failed"),
tr("Verification failed. Check that you have entered your token "
"correctly, and that your internet connection is working."));
}
void ConfigureWeb::ResetToken() {
// Generate and set token
const auto token = Common::UUID::MakeRandom().FormattedString();
Settings::values.yuzu_token = token;
// Just to display the label_token_icon pic and tooltip for visual confirmation
ui->label_token_icon->setPixmap(QIcon::fromTheme(QStringLiteral("checked")).pixmap(16));
ui->label_token_icon->setToolTip(tr("Token Changed", "Tooltip"));
ui->username->setText(QString::fromStdString(token));
// Apply the changes
SetConfiguration();
}
void ConfigureWeb::SetWebServiceConfigEnabled(bool enabled) {

View file

@ -25,14 +25,9 @@ private:
void changeEvent(QEvent* event) override;
void RetranslateUI();
void OnLoginChanged();
void VerifyLogin();
void OnLoginVerified();
void ResetToken();
void SetConfiguration();
bool user_verified = true;
QFutureWatcher<bool> verify_watcher;
std::unique_ptr<Ui::ConfigureWeb> ui;
};

View file

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>926</width>
<width>2280</width>
<height>561</height>
</rect>
</property>
@ -28,14 +28,14 @@
<item>
<widget class="QLabel" name="web_credentials_disclaimer">
<property name="text">
<string>By providing your username and token, you agree to allow yuzu to collect additional usage data, which may include user identifying information.</string>
<string>This token is for hosting public rooms in a lobby and are automatically generated the first time you save settings. To change your username, rename or switch the profile. If you are currently connected to multiplayer, exit and restart the emulator for changes to apply.</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayoutYuzuUsername">
<item row="2" column="3">
<widget class="QPushButton" name="button_verify_login">
<widget class="QPushButton" name="button_reset_token">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -46,12 +46,15 @@
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Verify</string>
<string>Reset Token</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="web_signup_link">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Sign up</string>
</property>
@ -68,7 +71,7 @@
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="label_token_verified"/>
<widget class="QLabel" name="label_token_icon"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_username">
@ -82,13 +85,13 @@
<property name="maxLength">
<number>80</number>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="web_token_info_link">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>What is my token?</string>
</property>

View file

@ -183,10 +183,9 @@ void HostRoomWindow::Host() {
if (result.result_code != WebService::WebResult::Code::Success) {
QMessageBox::warning(
this, tr("Error"),
tr("Failed to announce the room to the public lobby. In order to host a "
"room publicly, you must have a valid yuzu account configured in "
tr("To host a room publicly, you must have a generated token configured in "
"Emulation -> Configure -> Web. If you do not want to publish a room in "
"the public lobby, then select Unlisted instead.\nDebug Message: ") +
"a public lobby, then select Unlisted instead.\n\nDebug Message: ") +
QString::fromStdString(result.result_string),
QMessageBox::Ok);
ui->host->setEnabled(true);