Got auto-login to sorta-kinda work.

It's a mess, though... Next step is gonna be some serious re-factoring.
This commit is contained in:
Werner Kroneman 2023-12-10 00:44:04 +01:00
parent 234db497a9
commit 6b6562e210
4 changed files with 136 additions and 144 deletions

165
Cargo.lock generated
View File

@ -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",

View File

@ -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"] }
confy = "0.5.1"
serde = "1.0"
serde_derive = "1.0"

View File

@ -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);

View File

@ -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<BareJid> {
//
// let jid = match pkg.get::<String>("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::<BareJid>);
let connection_status = use_state(cx, || LoginStatus::LoggedOut);
let mut pkv = PkvStore::new("Mizah.xyz", "DergChat");
let stored_jid = match pkv.get::<BareJid>("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<NetworkCommand>|
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| {
{
let x = x.clone();
// Store the JID in the PKV.
pkv.set("jid", x.username.clone()).expect("Failed to store JID in 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 {