diff --git a/auth/src/server.rs b/auth/src/server.rs index 4ffc212..a1e187a 100644 --- a/auth/src/server.rs +++ b/auth/src/server.rs @@ -70,7 +70,13 @@ impl RealmAuthServer { match result { Ok(row) => { let token_long: &str = &row.tokens.unwrap(); - let tokens = token_long.split(',').collect::>(); + let tokens : Vec<&str> = { + if token_long.eq("") { + Vec::new() + } else { + token_long.split(',').collect::>() + } + }; for i in 0..tokens.len() { if tokens.get(i).unwrap() == &token { @@ -174,7 +180,13 @@ impl RealmAuth for RealmAuthServer { match result { Ok(row) => { let token_long: &str = &row.tokens.unwrap(); - let tokens = token_long.split(',').collect::>(); + let tokens: Vec<&str> = { + if token_long.eq("") { + Vec::new() + } else { + token_long.split(',').collect::>() + } + }; for token in tokens { let hash = Sha3_256::new().chain(format!("{}{}{}{}", token, server_id, domain, tarpc_port)).finalize(); @@ -288,7 +300,7 @@ impl RealmAuth for RealmAuthServer { let mut tokens: Vec<&str> = { if token_long.eq("") { Vec::new() - } else { + } else { token_long.split(',').collect::>() } }; @@ -411,7 +423,13 @@ impl RealmAuth for RealmAuthServer { match result { Ok(row) => { let token_long: &str = &row.tokens.unwrap(); - let mut tokens = token_long.split(',').collect::>(); + let mut tokens: Vec<&str> = { + if token_long.eq("") { + Vec::new() + } else { + token_long.split(',').collect::>() + } + }; for i in 0..tokens.len() { if tokens.get(i).unwrap().eq(&token.as_str()) { @@ -497,7 +515,13 @@ impl RealmAuth for RealmAuthServer { let result = query!("SELECT servers FROM user WHERE username = ?", username).fetch_one(&self.db_pool).await; match result { Ok(row) => { - let mut vec_servers = row.servers.split('|').collect::>(); + let mut vec_servers: Vec<&str> = { + if row.servers.eq("") { + Vec::new() + } else { + row.servers.split('|').collect::>() + } + }; for server in &vec_servers { if server.eq(&domain) { return Err(AlreadyJoinedServer); @@ -525,7 +549,13 @@ impl RealmAuth for RealmAuthServer { let result = query!("SELECT servers FROM user WHERE username = ?", username).fetch_one(&self.db_pool).await; match result { Ok(row) => { - let mut vec_servers = row.servers.split('|').collect::>(); + let mut vec_servers: Vec<&str> = { + if row.servers.eq("") { + Vec::new() + } else { + row.servers.split('|').collect::>() + } + }; for i in 0..vec_servers.len() { if vec_servers.get(i).unwrap().eq(&domain) { vec_servers.remove(i); @@ -553,7 +583,13 @@ impl RealmAuth for RealmAuthServer { let result = query!("SELECT servers FROM user WHERE username = ?", username).fetch_one(&self.db_pool).await; match result { Ok(row) => { - let vec_servers = row.servers.split('|').collect::>(); + let vec_servers: Vec<&str> = { + if row.servers.eq("") { + Vec::new() + } else { + row.servers.split('|').collect::>() + } + }; let mut servers = Vec::new(); for server in vec_servers { servers.push(server.to_string()) diff --git a/client/src/app.rs b/client/src/app.rs index 79281d9..160cf31 100644 --- a/client/src/app.rs +++ b/client/src/app.rs @@ -1,6 +1,10 @@ +use tarpc::context; +use tarpc::tokio_serde::formats::Json; use tokio::sync::broadcast; use tokio::sync::broadcast::{Receiver, Sender}; -use tracing::log::info; +use tracing::log::*; +use realm_auth::types::RealmAuthClient; +use realm_shared::types::ErrorCode::*; use realm_shared::types::ErrorCode; use crate::types::ClientUser; use crate::ui::panels; @@ -40,6 +44,9 @@ pub struct TemplateApp { pub login_start_channel: (Sender>, Receiver>), #[serde(skip)] pub login_ending_channel: (Sender>, Receiver>), + + #[serde(skip)] + pub fetching_user_data_channel: (Sender>, Receiver>), } impl Default for TemplateApp { @@ -63,6 +70,8 @@ impl Default for TemplateApp { login_window_email: String::new(), signup_window_open: false, + + fetching_user_data_channel: broadcast::channel(10), } } } @@ -101,12 +110,75 @@ impl eframe::App for TemplateApp { Ok(token) => { info!("Login successful! Token: {token}"); self.login_ready_for_code_input = false; + self.login_window_open = false; + self.signup_window_open = false; + self.login_window_code.clear(); + + info!("Fetching user data..."); + let send_channel = self.fetching_user_data_channel.0.clone(); + let server_address = self.login_window_server_address.clone(); + let username = self.login_window_username.clone(); + let _handle = tokio::spawn(async move { + let mut transport = tarpc::serde_transport::tcp::connect(&server_address, Json::default); + transport.config_mut().max_frame_length(usize::MAX); + + let result = transport.await; + let connection = match result { + Ok(connection) => connection, + Err(e) => { + tracing::error!("Failed to connect to server: {}", e); + return; + } + }; + + let client = RealmAuthClient::new(tarpc::client::Config::default(), connection).spawn(); + let result = client.get_all_data(context::current(), username, token.clone()).await; + + match result { + Ok(r) => { + if let Err(code) = r { + send_channel.send(Err(code)).unwrap(); + } else { + let auth_user = r.unwrap(); + let servers: Vec = { + if auth_user.servers.eq("") { + Vec::new() + } else { + auth_user.servers.split('|').map(|s| s.to_string()).collect() + } + }; + send_channel.send(Ok(ClientUser { + id: auth_user.id, + server_address, + username: auth_user.username, + email: auth_user.email, + //avatar: auth_user.avatar, + servers, + token, + })).unwrap(); + } + }, + Err(_) => { + send_channel.send(Err(RPCError)).unwrap(); + }, + }; + }); }, Err(e) => tracing::error!("Error in login flow: {:?}", e), } } + while let Ok(result) = self.fetching_user_data_channel.1.try_recv() { + match result { + Ok(client_user) => { + info!("Got data! User: {:?}", client_user); + self.current_user = Some(client_user); + }, + Err(e) => error!("Error in login flow: {:?}", e), + } + } + // File -> Quit panels::top_panel(self, ctx); diff --git a/client/src/main.rs b/client/src/main.rs index 28c3757..1a696cc 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -1,7 +1,19 @@ +use tracing::subscriber; + #[tokio::main] async fn main() -> eframe::Result { env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). + let subscriber = tracing_subscriber::fmt() + .compact() + .with_file(true) + .with_line_number(true) + .with_thread_ids(true) + .with_target(false) + .finish(); + + subscriber::set_global_default(subscriber).unwrap(); + let native_options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default() .with_inner_size([720.0, 500.0]) diff --git a/client/src/types.rs b/client/src/types.rs index f71a9c1..aee2703 100644 --- a/client/src/types.rs +++ b/client/src/types.rs @@ -1,9 +1,19 @@ -#[derive(serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] pub struct ClientUser { pub id: i64, + pub server_address: String, pub username: String, pub email: String, - pub avatar: String, + //pub avatar: String, pub servers: Vec, pub token: String, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +pub struct ClientServer { + pub server_id: String, + pub domain: String, + pub port: u16, + pub is_admin: bool, + pub is_owner: bool, } \ No newline at end of file diff --git a/client/src/ui/panels.rs b/client/src/ui/panels.rs index af9d346..07f4bdc 100644 --- a/client/src/ui/panels.rs +++ b/client/src/ui/panels.rs @@ -4,28 +4,54 @@ use tarpc::tokio_serde::formats::Json; use realm_auth::types::RealmAuthClient; use realm_shared::types::ErrorCode::RPCError; use regex::Regex; +use tracing::log::*; use crate::app::TemplateApp; pub fn top_panel(app: &mut TemplateApp, ctx: &Context) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::menu::bar(ui, |ui| { - ui.menu_button("File", |ui| { - if ui.button("Sign Up").clicked() { - app.signup_window_open = true; - } + if app.current_user.is_none() && ui.button("Sign Up").clicked() { + app.signup_window_open = true; + } - if ui.button("Login").clicked() { - app.login_window_open = true; - } + if app.current_user.is_none() && ui.button("Login").clicked() { + app.login_window_open = true; + } - if ui.button("Logout").clicked() { - // TODO: Logout - } + if app.current_user.is_some() && ui.button("Logout").clicked() { + let address = app.current_user.clone().unwrap().server_address; + let username = app.current_user.clone().unwrap().username; + let token = app.current_user.clone().unwrap().token; + + let _handle = tokio::spawn(async move { + let mut transport = tarpc::serde_transport::tcp::connect(&address, Json::default); + transport.config_mut().max_frame_length(usize::MAX); + + let result = transport.await; + let connection = match result { + Ok(connection) => connection, + Err(e) => { + tracing::error!("Failed to connect to server: {}", e); + return; + } + }; + + let client = RealmAuthClient::new(tarpc::client::Config::default(), connection).spawn(); + let result = client.sign_out(context::current(), username, token).await; + + match result { + Ok(_) => info!("Signed out!"), // TODO: properly handle this + Err(e) => error!("Error signing out: {:?}", e), + } + }); + + app.current_user = None; + } - if ui.button("Quit").clicked() { - ctx.send_viewport_cmd(egui::ViewportCommand::Close); - } - }); + if ui.button("Quit").clicked() { + ctx.send_viewport_cmd(egui::ViewportCommand::Close); + } + ui.add_space(16.0); egui::widgets::global_dark_light_mode_buttons(ui); @@ -79,7 +105,7 @@ pub fn top_panel(app: &mut TemplateApp, ctx: &Context) { }; }); - ui.close_menu() + //ui.close_menu() } }); @@ -124,7 +150,7 @@ pub fn top_panel(app: &mut TemplateApp, ctx: &Context) { }; }); - ui.close_menu() + //ui.close_menu() } }); @@ -172,7 +198,7 @@ pub fn top_panel(app: &mut TemplateApp, ctx: &Context) { } }); - ui.close_menu() + //ui.close_menu() } }); } @@ -215,5 +241,7 @@ pub fn messages(app: &mut TemplateApp, ctx: &Context) { } ui.separator(); + + ui.label(format!("Current user: {:?}", app.current_user)); }); } \ No newline at end of file