From 3b206e11216b383fae0e860e0092f71301fd4425 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 30 Jun 2023 20:43:08 -0400 Subject: remote auth impl. up to QR code display --- src/abaddon.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/abaddon.cpp') diff --git a/src/abaddon.cpp b/src/abaddon.cpp index 92cc494..545a3c2 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -21,6 +21,7 @@ #include "windows/voicewindow.hpp" #include "startup.hpp" #include "notifications/notifications.hpp" +#include "remoteauth/remoteauthdialog.hpp" #ifdef WITH_LIBHANDY #include @@ -267,6 +268,7 @@ int Abaddon::StartGTK() { m_main_window->signal_action_connect().connect(sigc::mem_fun(*this, &Abaddon::ActionConnect)); m_main_window->signal_action_disconnect().connect(sigc::mem_fun(*this, &Abaddon::ActionDisconnect)); m_main_window->signal_action_set_token().connect(sigc::mem_fun(*this, &Abaddon::ActionSetToken)); + m_main_window->signal_action_login_qr().connect(sigc::mem_fun(*this, &Abaddon::ActionLoginQR)); m_main_window->signal_action_reload_css().connect(sigc::mem_fun(*this, &Abaddon::ActionReloadCSS)); m_main_window->signal_action_set_status().connect(sigc::mem_fun(*this, &Abaddon::ActionSetStatus)); m_main_window->signal_action_add_recipient().connect(sigc::mem_fun(*this, &Abaddon::ActionAddRecipient)); @@ -834,6 +836,16 @@ void Abaddon::ActionSetToken() { m_main_window->UpdateMenus(); } +void Abaddon::ActionLoginQR() { + RemoteAuthDialog dlg(*m_main_window); + auto response = dlg.run(); + if (response == Gtk::RESPONSE_OK) { + m_discord_token = dlg.GetToken(); + m_main_window->UpdateComponents(); + } + m_main_window->UpdateMenus(); +} + void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) { if (!id.IsValid()) { m_discord.SetReferringChannel(Snowflake::Invalid); @@ -1142,6 +1154,7 @@ int main(int argc, char **argv) { auto log_audio = spdlog::stdout_color_mt("audio"); auto log_voice = spdlog::stdout_color_mt("voice"); auto log_discord = spdlog::stdout_color_mt("discord"); + auto log_ra = spdlog::stdout_color_mt("remote-auth"); Gtk::Main::init_gtkmm_internals(); // why??? return Abaddon::Get().StartGTK(); -- cgit v1.2.3 From 4ac7ca9245016616bbc77acf8e989e41729e1afd Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 1 Jul 2023 00:56:09 -0400 Subject: finalize login --- src/abaddon.cpp | 3 +++ src/discord/discord.cpp | 14 ++++++++++++++ src/discord/discord.hpp | 2 ++ src/remoteauth/remoteauthclient.cpp | 32 ++++++++++++++++++++++++++++++++ src/remoteauth/remoteauthclient.hpp | 6 ++++++ src/remoteauth/remoteauthdialog.cpp | 7 +++++++ src/remoteauth/remoteauthdialog.hpp | 1 + 7 files changed, 65 insertions(+) (limited to 'src/abaddon.cpp') diff --git a/src/abaddon.cpp b/src/abaddon.cpp index 545a3c2..e0d39b5 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -841,9 +841,12 @@ void Abaddon::ActionLoginQR() { auto response = dlg.run(); if (response == Gtk::RESPONSE_OK) { m_discord_token = dlg.GetToken(); + m_discord.UpdateToken(m_discord_token); m_main_window->UpdateComponents(); + GetSettings().DiscordToken = m_discord_token; } m_main_window->UpdateMenus(); + ActionConnect(); } void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) { diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 817aca8..5dc0464 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -1197,6 +1197,20 @@ void DiscordClient::AcceptVerificationGate(Snowflake guild_id, VerificationGateI }); } +void DiscordClient::RemoteAuthLogin(const std::string &ticket, const sigc::slot, DiscordError code)> &callback) { + http::request req(http::REQUEST_POST, "https://discord.com/api/v9/users/@me/remote-auth/login"); + req.set_header("Content-Type", "application/json"); + req.set_user_agent(Abaddon::Get().GetSettings().UserAgent); + req.set_body("{\"ticket\":\"" + ticket + "\"}"); + m_http.Execute(std::move(req), [this, callback](const http::response_type &r) { + if (CheckCode(r)) { + callback(nlohmann::json::parse(r.text).at("encrypted_token").get(), DiscordError::NONE); + } else { + callback(std::nullopt, GetCodeFromResponse(r)); + } + }); +} + #ifdef WITH_VOICE void DiscordClient::ConnectToVoice(Snowflake channel_id) { auto channel = GetChannel(channel_id); diff --git a/src/discord/discord.hpp b/src/discord/discord.hpp index d2435dd..438e4e6 100644 --- a/src/discord/discord.hpp +++ b/src/discord/discord.hpp @@ -184,6 +184,8 @@ public: void GetVerificationGateInfo(Snowflake guild_id, const sigc::slot)> &callback); void AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, const sigc::slot &callback); + void RemoteAuthLogin(const std::string &ticket, const sigc::slot, DiscordError code)> &callback); + #ifdef WITH_VOICE void ConnectToVoice(Snowflake channel_id); void DisconnectFromVoice(); diff --git a/src/remoteauth/remoteauthclient.cpp b/src/remoteauth/remoteauthclient.cpp index 1ebb7cb..390f42d 100644 --- a/src/remoteauth/remoteauthclient.cpp +++ b/src/remoteauth/remoteauthclient.cpp @@ -1,4 +1,5 @@ #include "remoteauthclient.hpp" +#include "http.hpp" #include #include @@ -65,6 +66,14 @@ struct RemoteAuthPendingTicketMessage { } }; +struct RemoteAuthPendingLoginMessage { + std::string Ticket; + + friend void from_json(const nlohmann::json &j, RemoteAuthPendingLoginMessage &m) { + j.at("ticket").get_to(m.Ticket); + } +}; + RemoteAuthClient::RemoteAuthClient() : m_ws("remote-auth-ws") , m_log(spdlog::get("remote-auth")) { @@ -116,6 +125,8 @@ void RemoteAuthClient::OnGatewayMessage(const std::string &str) { HandleGatewayPendingRemoteInit(j); } else if (msg.Opcode == "pending_ticket") { HandleGatewayPendingTicket(j); + } else if (msg.Opcode == "pending_login") { + HandleGatewayPendingLogin(j); } } @@ -162,6 +173,23 @@ void RemoteAuthClient::HandleGatewayPendingTicket(const nlohmann::json &j) { m_log->trace("User payload: {}", std::string(payload.begin(), payload.end())); } +void RemoteAuthClient::HandleGatewayPendingLogin(const nlohmann::json &j) { + RemoteAuthPendingLoginMessage msg = j; + + Abaddon::Get().GetDiscordClient().RemoteAuthLogin(msg.Ticket, sigc::mem_fun(*this, &RemoteAuthClient::OnRemoteAuthLoginResponse)); +} + +void RemoteAuthClient::OnRemoteAuthLoginResponse(const std::optional &encrypted_token, DiscordError err) { + if (!encrypted_token.has_value()) { + m_log->error("Remote auth login failed: {}", static_cast(err)); + return; + } + + const auto encrypted = Glib::Base64::decode(*encrypted_token); + const auto token = Decrypt(reinterpret_cast(encrypted.data()), encrypted.size()); + m_signal_token.emit(std::string(token.begin(), token.end())); +} + void RemoteAuthClient::Init() { RemoteAuthInitMessage msg; @@ -319,3 +347,7 @@ void RemoteAuthClient::OnDispatch() { RemoteAuthClient::type_signal_fingerprint RemoteAuthClient::signal_fingerprint() { return m_signal_fingerprint; } + +RemoteAuthClient::type_signal_token RemoteAuthClient::signal_token() { + return m_signal_token; +} diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp index 178e10a..8fb8bc3 100644 --- a/src/remoteauth/remoteauthclient.hpp +++ b/src/remoteauth/remoteauthclient.hpp @@ -22,6 +22,9 @@ private: void HandleGatewayNonceProof(const nlohmann::json &j); void HandleGatewayPendingRemoteInit(const nlohmann::json &j); void HandleGatewayPendingTicket(const nlohmann::json &j); + void HandleGatewayPendingLogin(const nlohmann::json &j); + + void OnRemoteAuthLoginResponse(const std::optional &encrypted_token, DiscordError err); void Init(); @@ -57,8 +60,11 @@ private: public: using type_signal_fingerprint = sigc::signal; + using type_signal_token = sigc::signal; type_signal_fingerprint signal_fingerprint(); + type_signal_token signal_token(); private: type_signal_fingerprint m_signal_fingerprint; + type_signal_token m_signal_token; }; diff --git a/src/remoteauth/remoteauthdialog.cpp b/src/remoteauth/remoteauthdialog.cpp index db154c4..ea250d6 100644 --- a/src/remoteauth/remoteauthdialog.cpp +++ b/src/remoteauth/remoteauthdialog.cpp @@ -24,6 +24,7 @@ RemoteAuthDialog::RemoteAuthDialog(Gtk::Window &parent) m_bbox.set_layout(Gtk::BUTTONBOX_END); m_ra.signal_fingerprint().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnFingerprint)); + m_ra.signal_token().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnToken)); m_ra.Start(); @@ -77,3 +78,9 @@ void RemoteAuthDialog::OnFingerprint(const std::string &fingerprint) { std::string RemoteAuthDialog::GetToken() { return m_token; } + +void RemoteAuthDialog::OnToken(const std::string &token) { + m_token = token; + m_ra.Stop(); + response(Gtk::RESPONSE_OK); +} diff --git a/src/remoteauth/remoteauthdialog.hpp b/src/remoteauth/remoteauthdialog.hpp index 24fad56..44af821 100644 --- a/src/remoteauth/remoteauthdialog.hpp +++ b/src/remoteauth/remoteauthdialog.hpp @@ -18,6 +18,7 @@ private: RemoteAuthClient m_ra; void OnFingerprint(const std::string &fingerprint); + void OnToken(const std::string &token); std::string m_token; }; -- cgit v1.2.3 From 044e508df7868856648e14ad7c957be8b9bb46b5 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 1 Jul 2023 01:47:45 -0400 Subject: only connect on RESPONSE_OK --- src/abaddon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/abaddon.cpp') diff --git a/src/abaddon.cpp b/src/abaddon.cpp index e0d39b5..c161595 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -844,9 +844,9 @@ void Abaddon::ActionLoginQR() { m_discord.UpdateToken(m_discord_token); m_main_window->UpdateComponents(); GetSettings().DiscordToken = m_discord_token; + ActionConnect(); } m_main_window->UpdateMenus(); - ActionConnect(); } void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) { -- cgit v1.2.3 From 229555939d697700e988f09f04871bde55adc5a7 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 9 Jul 2023 22:31:21 -0400 Subject: make qrcodegen optional wow!!! --- CMakeLists.txt | 12 ++++++++---- src/abaddon.cpp | 2 ++ src/remoteauth/remoteauthclient.cpp | 8 ++++++++ src/remoteauth/remoteauthclient.hpp | 9 +++++++++ src/remoteauth/remoteauthdialog.cpp | 8 ++++++++ src/remoteauth/remoteauthdialog.hpp | 9 +++++++++ src/windows/mainwindow.cpp | 6 ++++++ 7 files changed, 50 insertions(+), 4 deletions(-) (limited to 'src/abaddon.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index b85e6c1..7a782ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ option(USE_LIBHANDY "Enable features that require libhandy (default)" ON) option(ENABLE_VOICE "Enable voice suppport" ON) option(USE_KEYCHAIN "Store the token in the keychain (default)" ON) option(ENABLE_NOTIFICATION_SOUNDS "Enable notification sounds (default)" ON) +option(ENABLE_QRCODE_LOGIN "Enable QR code login (default)" ON) find_package(nlohmann_json REQUIRED) find_package(CURL) @@ -61,11 +62,14 @@ target_include_directories(abaddon PUBLIC ${ZLIB_INCLUDE_DIRS}) target_include_directories(abaddon PUBLIC ${SQLite3_INCLUDE_DIRS}) target_include_directories(abaddon PUBLIC ${NLOHMANN_JSON_INCLUDE_DIRS}) -add_library(qrcodegen subprojects/qrcodegen/cpp/qrcodegen.hpp subprojects/qrcodegen/cpp/qrcodegen.cpp) -target_include_directories(qrcodegen PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/subprojects/qrcodegen/cpp") -target_link_libraries(abaddon qrcodegen) +if (ENABLE_QRCODE_LOGIN) + add_library(qrcodegen subprojects/qrcodegen/cpp/qrcodegen.hpp subprojects/qrcodegen/cpp/qrcodegen.cpp) + target_include_directories(qrcodegen PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/subprojects/qrcodegen/cpp") + target_link_libraries(abaddon qrcodegen) -target_include_directories(abaddon PUBLIC "subprojects/qrcodegen/cpp") + target_include_directories(abaddon PUBLIC "subprojects/qrcodegen/cpp") + target_compile_definitions(abaddon PRIVATE WITH_QRLOGIN) +endif () target_precompile_headers(abaddon PRIVATE src/abaddon.hpp src/util.hpp) diff --git a/src/abaddon.cpp b/src/abaddon.cpp index c161595..921549b 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -837,6 +837,7 @@ void Abaddon::ActionSetToken() { } void Abaddon::ActionLoginQR() { +#ifdef WITH_QRLOGIN RemoteAuthDialog dlg(*m_main_window); auto response = dlg.run(); if (response == Gtk::RESPONSE_OK) { @@ -847,6 +848,7 @@ void Abaddon::ActionLoginQR() { ActionConnect(); } m_main_window->UpdateMenus(); +#endif } void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) { diff --git a/src/remoteauth/remoteauthclient.cpp b/src/remoteauth/remoteauthclient.cpp index 467ea8b..7653b78 100644 --- a/src/remoteauth/remoteauthclient.cpp +++ b/src/remoteauth/remoteauthclient.cpp @@ -1,8 +1,14 @@ +#ifdef WITH_QRLOGIN + +// clang-format off + #include "remoteauthclient.hpp" #include "http.hpp" #include #include +// clang-format on + RemoteAuthClient::RemoteAuthClient() : m_ws("remote-auth-ws") , m_log(spdlog::get("remote-auth")) { @@ -341,3 +347,5 @@ RemoteAuthClient::type_signal_token RemoteAuthClient::signal_token() { RemoteAuthClient::type_signal_error RemoteAuthClient::signal_error() { return m_signal_error; } + +#endif diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp index c2e00f3..6ab6dbb 100644 --- a/src/remoteauth/remoteauthclient.hpp +++ b/src/remoteauth/remoteauthclient.hpp @@ -1,4 +1,9 @@ #pragma once + +#ifdef WITH_QRLOGIN + +// clang-format off + #include #include #include @@ -6,6 +11,8 @@ #include "discord/waiter.hpp" #include "discord/websocket.hpp" +// clang-format on + class RemoteAuthClient { public: RemoteAuthClient(); @@ -84,3 +91,5 @@ private: type_signal_token m_signal_token; type_signal_error m_signal_error; }; + +#endif diff --git a/src/remoteauth/remoteauthdialog.cpp b/src/remoteauth/remoteauthdialog.cpp index 7ee045f..7975b4e 100644 --- a/src/remoteauth/remoteauthdialog.cpp +++ b/src/remoteauth/remoteauthdialog.cpp @@ -1,6 +1,12 @@ +#ifdef WITH_QRLOGIN + +// clang-format off + #include "remoteauthdialog.hpp" #include +// clang-format on + RemoteAuthDialog::RemoteAuthDialog(Gtk::Window &parent) : Gtk::Dialog("Login with QR Code", parent, true) , m_layout(Gtk::ORIENTATION_VERTICAL) @@ -122,3 +128,5 @@ void RemoteAuthDialog::OnError(const std::string &error) { Abaddon::Get().ShowConfirm(error, dynamic_cast(get_toplevel())); response(Gtk::RESPONSE_CANCEL); } + +#endif diff --git a/src/remoteauth/remoteauthdialog.hpp b/src/remoteauth/remoteauthdialog.hpp index 9a6ca29..465a188 100644 --- a/src/remoteauth/remoteauthdialog.hpp +++ b/src/remoteauth/remoteauthdialog.hpp @@ -1,7 +1,14 @@ #pragma once + +#ifdef WITH_QRLOGIN + +// clang-format off + #include #include "remoteauthclient.hpp" +// clang-format on + class RemoteAuthDialog : public Gtk::Dialog { public: RemoteAuthDialog(Gtk::Window &parent); @@ -27,3 +34,5 @@ private: std::string m_token; }; + +#endif diff --git a/src/windows/mainwindow.cpp b/src/windows/mainwindow.cpp index 56d735e..0b21567 100644 --- a/src/windows/mainwindow.cpp +++ b/src/windows/mainwindow.cpp @@ -206,7 +206,9 @@ void MainWindow::OnDiscordSubmenuPopup() { m_menu_discord_connect.set_sensitive(!token.empty() && !discord_active); m_menu_discord_disconnect.set_sensitive(discord_active); m_menu_discord_set_token.set_sensitive(!discord_active); +#ifdef WITH_QRLOGIN m_menu_discord_login_qr.set_sensitive(!discord_active); +#endif m_menu_discord_set_status.set_sensitive(discord_active); } @@ -249,6 +251,10 @@ void MainWindow::SetupMenu() { m_menu_discord_disconnect.set_sensitive(false); m_menu_discord_set_token.set_label("Set Token"); m_menu_discord_login_qr.set_label("Login with QR Code"); +#ifndef WITH_QRLOGIN + m_menu_discord_login_qr.set_sensitive(false); + m_menu_discord_login_qr.set_tooltip_text("Not compiled with support"); +#endif m_menu_discord_set_status.set_label("Set Status"); m_menu_discord_set_status.set_sensitive(false); m_menu_discord_add_recipient.set_label("Add user to DM"); -- cgit v1.2.3