From 6b6562e210885e49956cfeddaf62e76b17e085a9 Mon Sep 17 00:00:00 2001 From: Werner Kroneman Date: Sun, 10 Dec 2023 00:44:04 +0100 Subject: [PATCH] Got auto-login to sorta-kinda work. It's a mess, though... Next step is gonna be some serious re-factoring. --- Cargo.lock | 165 ++++++++---------------------------- Cargo.toml | 4 +- src/widgets/login_screen.rs | 9 +- src/widgets/mod.rs | 102 +++++++++++++++++++--- 4 files changed, 136 insertions(+), 144 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c52e8c5..860d8ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,23 +315,6 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" -[[package]] -name = "bevy_pkv" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3244c1ecb6931888e9ebb8d4424ec0b12aa9fa405f82f6a58b6b7695f2a7847c" -dependencies = [ - "cfg_aliases", - "directories", - "rmp-serde", - "serde", - "serde_json", - "sled", - "thiserror", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -545,17 +528,11 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "chatclient" version = "0.1.0" dependencies = [ - "bevy_pkv", + "confy", "dioxus", "dioxus-desktop", "dioxus-hot-reload", @@ -564,6 +541,8 @@ dependencies = [ "jid", "keyring", "log", + "serde", + "serde_derive", "tokio", "xmpp", ] @@ -644,6 +623,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "confy" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37668cb35145dcfaa1931a5f37fde375eeae8068b4c0d2f289da28a270b2d2c" +dependencies = [ + "directories", + "serde", + "thiserror", + "toml 0.5.11", +] + [[package]] name = "constcat" version = "0.3.1" @@ -1027,23 +1018,22 @@ dependencies = [ [[package]] name = "directories" -version = "5.0.1" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", - "option-ext", "redox_users", - "windows-sys 0.48.0", + "winapi", ] [[package]] @@ -1348,16 +1338,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "fsevent-sys" version = "4.1.0" @@ -2120,7 +2100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e976188335292f66a1533fd41d5c2ce24b32dc2c000569b8dccf4e57f489806" dependencies = [ "hashbrown 0.12.3", - "parking_lot 0.12.1", + "parking_lot", ] [[package]] @@ -2841,12 +2821,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - [[package]] name = "ordered-float" version = "2.10.1" @@ -2898,17 +2872,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -2916,21 +2879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2946,12 +2895,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - [[package]] name = "pbkdf2" version = "0.12.2" @@ -3295,15 +3238,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -3437,28 +3371,6 @@ dependencies = [ "windows", ] -[[package]] -name = "rmp" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - [[package]] name = "rustc-demangle" version = "0.1.23" @@ -3797,22 +3709,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "sled" -version = "0.34.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" -dependencies = [ - "crc32fast", - "crossbeam-epoch", - "crossbeam-utils", - "fs2", - "fxhash", - "libc", - "log", - "parking_lot 0.11.2", -] - [[package]] name = "smallbox" version = "0.8.2" @@ -3913,7 +3809,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -4000,7 +3896,7 @@ dependencies = [ "cfg-expr 0.15.5", "heck", "pkg-config", - "toml", + "toml 0.8.8", "version-compare", ] @@ -4038,7 +3934,7 @@ dependencies = [ "ndk-sys", "objc", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "png", "raw-window-handle", "scopeguard", @@ -4236,6 +4132,15 @@ dependencies = [ "xmpp-parsers", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.8" @@ -4354,7 +4259,7 @@ dependencies = [ "ipconfig", "lazy_static", "lru-cache", - "parking_lot 0.12.1", + "parking_lot", "resolv-conf", "smallvec", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 3f65ea4..5f2cd27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,4 +32,6 @@ futures-util = "0.3.29" xmpp = { git = "https://gitlab.com/werner.kroneman/xmpp-rs.git", rev="ecd0be4aad985e9812626d6c4499c2586c158aba"} keyring = "2.1.0" jid = "0.10.0" -bevy_pkv = { version = "0.9.0", default-features = false, features = ["sled"] } \ No newline at end of file +confy = "0.5.1" +serde = "1.0" +serde_derive = "1.0" \ No newline at end of file diff --git a/src/widgets/login_screen.rs b/src/widgets/login_screen.rs index 5ddc03e..40d022c 100644 --- a/src/widgets/login_screen.rs +++ b/src/widgets/login_screen.rs @@ -32,6 +32,7 @@ pub enum LoginStatus { Error(String), } +#[derive(Clone)] pub struct LoginAttempt { pub username: String, pub default_nick: String, @@ -50,14 +51,16 @@ impl Debug for LoginAttempt { #[derive(Props)] pub struct LoginScreenProps<'a> { + cached_username: String, + cached_nick: String, login_state: LoginStatus, on_login_attempt: EventHandler<'a, LoginAttempt>, } pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> { - let username = use_state(cx, || "".to_string()); - let default_nick = use_state(cx, || "".to_string()); + let username = use_state(cx, || cx.props.cached_username.clone()); + let default_nick = use_state(cx, || cx.props.cached_nick.clone()); let password = use_state(cx, || "".to_string()); let default_nick_was_changed = use_state(cx, || false); @@ -69,6 +72,7 @@ pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> { input { "type": "text", placeholder: "Username", + value: "{username}", oninput: move |x| { username.set(x.value.clone()); @@ -83,6 +87,7 @@ pub fn LoginScreen<'a>(cx: Scope<'a, LoginScreenProps>) -> Element<'a> { input { placeholder: "Default nick", "type": "text", + value: "{default_nick}", oninput: move |x| { default_nick.set(x.value.clone()); default_nick_was_changed.set(true); diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index 78c70c7..e2b7c0e 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -30,9 +30,13 @@ use jid::BareJid; use log::{error, info}; use std::collections::HashMap; use std::fmt::format; +use std::rc::Rc; use std::str::FromStr; -use bevy_pkv::{GetError, PkvStore}; use xmpp::{Agent, ClientBuilder, ClientType}; +use std::string::String; +use std::sync::Mutex; +use keyring::Entry; +use serde_derive::{Serialize, Deserialize}; mod login_screen; mod room_join_widget; @@ -96,23 +100,83 @@ pub async fn run_xmpp_toplevel( } } +// fn retrieve_stored_jid(pkg : &PkvStore) -> Option { +// +// let jid = match pkg.get::("jid") { +// Ok(x) => x, +// Err(e) => { +// error!("Failed to get JID from PKV: {}", e); +// return None; +// } +// }; +// +// let jid = match BareJid::from_str(&jid) { +// Ok(x) => x, +// Err(e) => { +// error!("Failed to parse JID from PKV: {}", e); +// return None; +// } +// }; +// +// Some(jid) +// +// } + +#[derive(Serialize, Deserialize, Default)] +struct Configuration { + stored_username: String, + stored_default_nick: String, +} + pub fn App(cx: Scope) -> Element { let messages = use_ref(cx, || HashMap::new()); let current_room = use_state(cx, || None::); let connection_status = use_state(cx, || LoginStatus::LoggedOut); - let mut pkv = PkvStore::new("Mizah.xyz", "DergChat"); - - let stored_jid = match pkv.get::("jid") { - Ok(jid) => Some(jid), - Err(GetError::NotFound) => None, - Err(e) => panic!("Failed to get JID from PKV: {}", e), - }; - let coroutine = use_coroutine(cx, |rx: UnboundedReceiver| run_xmpp_toplevel(connection_status.to_owned(), messages.to_owned(), rx)); + let config = use_ref(cx, || match confy::load("dergchat", None) { + Ok(x) => x, + Err(e) => { + error!("Failed to load config file: {}", e); + Configuration::default() + } + }); + + { + let config = config.to_owned(); + let connection_status = connection_status.to_owned(); + let coroutine = coroutine.to_owned(); + + use_on_create(cx, move || { + async move { + let entry = Entry::new("dergchat", &config.read().stored_username).expect("Failed to create keyring entry."); + + let password = match entry.get_password() { + Ok(x) => { + info!("Password retrieved from keyring; will try to log in."); + + let (username, default_nick) = config.with(|c| (c.stored_username.clone(), c.stored_default_nick.clone())); + + // If we have a username, nickname and password, immediately try to log in. + if username.len() > 0 && default_nick.len() > 0 { + let credentials = LoginCredentials { + username: BareJid::from_str(&username).expect("Invalid JID"), + default_nick: default_nick, + password: entry.get_password().expect("Failed to get password from keyring"), + }; + + coroutine.send(NetworkCommand::TryLogin { credentials }); + } + } + Err(e) => println!("Failed to get password from keyring: {}", e), + }; + } + }); + } + render! { // If not logged in, show a login screen. @@ -120,11 +184,27 @@ pub fn App(cx: Scope) -> Element { rsx! { LoginScreen { + cached_username: config.read().stored_username.clone(), + cached_nick: config.read().stored_default_nick.clone(), login_state: connection_status.current().as_ref().clone(), on_login_attempt: move |x: LoginAttempt| { - // Store the JID in the PKV. - pkv.set("jid", x.username.clone()).expect("Failed to store JID in PKV"); + { + let x = x.clone(); + // Store the JID in the PKV. + config.with_mut(move |c| { + c.stored_username = x.username.clone(); + c.stored_default_nick = x.default_nick.clone(); + + // Store the password in the keyring. + let entry = Entry::new("dergchat", &x.username).expect("Failed to create keyring entry."); + entry.set_password(&x.password).expect("Failed to set password in keyring."); + + if let Err(e) = confy::store("dergchat", None, &*config.read()) { + error!("Failed to store JID in config file: {}", e); + } + }); + } coroutine.send(NetworkCommand::TryLogin { credentials: LoginCredentials {