Added logout support, store user data

This commit is contained in:
2024-10-12 12:29:09 -04:00
Unverified
parent 62fff30b8e
commit c333bf1b49
5 changed files with 185 additions and 27 deletions

View File

@@ -70,7 +70,13 @@ impl RealmAuthServer {
match result { match result {
Ok(row) => { Ok(row) => {
let token_long: &str = &row.tokens.unwrap(); let token_long: &str = &row.tokens.unwrap();
let tokens = token_long.split(',').collect::<Vec<&str>>(); let tokens : Vec<&str> = {
if token_long.eq("") {
Vec::new()
} else {
token_long.split(',').collect::<Vec<&str>>()
}
};
for i in 0..tokens.len() { for i in 0..tokens.len() {
if tokens.get(i).unwrap() == &token { if tokens.get(i).unwrap() == &token {
@@ -174,7 +180,13 @@ impl RealmAuth for RealmAuthServer {
match result { match result {
Ok(row) => { Ok(row) => {
let token_long: &str = &row.tokens.unwrap(); let token_long: &str = &row.tokens.unwrap();
let tokens = token_long.split(',').collect::<Vec<&str>>(); let tokens: Vec<&str> = {
if token_long.eq("") {
Vec::new()
} else {
token_long.split(',').collect::<Vec<&str>>()
}
};
for token in tokens { for token in tokens {
let hash = Sha3_256::new().chain(format!("{}{}{}{}", token, server_id, domain, tarpc_port)).finalize(); let hash = Sha3_256::new().chain(format!("{}{}{}{}", token, server_id, domain, tarpc_port)).finalize();
@@ -411,7 +423,13 @@ impl RealmAuth for RealmAuthServer {
match result { match result {
Ok(row) => { Ok(row) => {
let token_long: &str = &row.tokens.unwrap(); let token_long: &str = &row.tokens.unwrap();
let mut tokens = token_long.split(',').collect::<Vec<&str>>(); let mut tokens: Vec<&str> = {
if token_long.eq("") {
Vec::new()
} else {
token_long.split(',').collect::<Vec<&str>>()
}
};
for i in 0..tokens.len() { for i in 0..tokens.len() {
if tokens.get(i).unwrap().eq(&token.as_str()) { 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; let result = query!("SELECT servers FROM user WHERE username = ?", username).fetch_one(&self.db_pool).await;
match result { match result {
Ok(row) => { Ok(row) => {
let mut vec_servers = row.servers.split('|').collect::<Vec<&str>>(); let mut vec_servers: Vec<&str> = {
if row.servers.eq("") {
Vec::new()
} else {
row.servers.split('|').collect::<Vec<&str>>()
}
};
for server in &vec_servers { for server in &vec_servers {
if server.eq(&domain) { if server.eq(&domain) {
return Err(AlreadyJoinedServer); 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; let result = query!("SELECT servers FROM user WHERE username = ?", username).fetch_one(&self.db_pool).await;
match result { match result {
Ok(row) => { Ok(row) => {
let mut vec_servers = row.servers.split('|').collect::<Vec<&str>>(); let mut vec_servers: Vec<&str> = {
if row.servers.eq("") {
Vec::new()
} else {
row.servers.split('|').collect::<Vec<&str>>()
}
};
for i in 0..vec_servers.len() { for i in 0..vec_servers.len() {
if vec_servers.get(i).unwrap().eq(&domain) { if vec_servers.get(i).unwrap().eq(&domain) {
vec_servers.remove(i); 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; let result = query!("SELECT servers FROM user WHERE username = ?", username).fetch_one(&self.db_pool).await;
match result { match result {
Ok(row) => { Ok(row) => {
let vec_servers = row.servers.split('|').collect::<Vec<&str>>(); let vec_servers: Vec<&str> = {
if row.servers.eq("") {
Vec::new()
} else {
row.servers.split('|').collect::<Vec<&str>>()
}
};
let mut servers = Vec::new(); let mut servers = Vec::new();
for server in vec_servers { for server in vec_servers {
servers.push(server.to_string()) servers.push(server.to_string())

View File

@@ -1,6 +1,10 @@
use tarpc::context;
use tarpc::tokio_serde::formats::Json;
use tokio::sync::broadcast; use tokio::sync::broadcast;
use tokio::sync::broadcast::{Receiver, Sender}; 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 realm_shared::types::ErrorCode;
use crate::types::ClientUser; use crate::types::ClientUser;
use crate::ui::panels; use crate::ui::panels;
@@ -40,6 +44,9 @@ pub struct TemplateApp {
pub login_start_channel: (Sender<Result<(), ErrorCode>>, Receiver<Result<(), ErrorCode>>), pub login_start_channel: (Sender<Result<(), ErrorCode>>, Receiver<Result<(), ErrorCode>>),
#[serde(skip)] #[serde(skip)]
pub login_ending_channel: (Sender<Result<String, ErrorCode>>, Receiver<Result<String, ErrorCode>>), pub login_ending_channel: (Sender<Result<String, ErrorCode>>, Receiver<Result<String, ErrorCode>>),
#[serde(skip)]
pub fetching_user_data_channel: (Sender<Result<ClientUser, ErrorCode>>, Receiver<Result<ClientUser, ErrorCode>>),
} }
impl Default for TemplateApp { impl Default for TemplateApp {
@@ -63,6 +70,8 @@ impl Default for TemplateApp {
login_window_email: String::new(), login_window_email: String::new(),
signup_window_open: false, signup_window_open: false,
fetching_user_data_channel: broadcast::channel(10),
} }
} }
} }
@@ -101,12 +110,75 @@ impl eframe::App for TemplateApp {
Ok(token) => { Ok(token) => {
info!("Login successful! Token: {token}"); info!("Login successful! Token: {token}");
self.login_ready_for_code_input = false; 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<String> = {
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), 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 // File -> Quit
panels::top_panel(self, ctx); panels::top_panel(self, ctx);

View File

@@ -1,7 +1,19 @@
use tracing::subscriber;
#[tokio::main] #[tokio::main]
async fn main() -> eframe::Result { async fn main() -> eframe::Result {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). 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 { let native_options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default() viewport: egui::ViewportBuilder::default()
.with_inner_size([720.0, 500.0]) .with_inner_size([720.0, 500.0])

View File

@@ -1,9 +1,19 @@
#[derive(serde::Deserialize, serde::Serialize)] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct ClientUser { pub struct ClientUser {
pub id: i64, pub id: i64,
pub server_address: String,
pub username: String, pub username: String,
pub email: String, pub email: String,
pub avatar: String, //pub avatar: String,
pub servers: Vec<String>, pub servers: Vec<String>,
pub token: String, 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,
}

View File

@@ -4,28 +4,54 @@ use tarpc::tokio_serde::formats::Json;
use realm_auth::types::RealmAuthClient; use realm_auth::types::RealmAuthClient;
use realm_shared::types::ErrorCode::RPCError; use realm_shared::types::ErrorCode::RPCError;
use regex::Regex; use regex::Regex;
use tracing::log::*;
use crate::app::TemplateApp; use crate::app::TemplateApp;
pub fn top_panel(app: &mut TemplateApp, ctx: &Context) { pub fn top_panel(app: &mut TemplateApp, ctx: &Context) {
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
egui::menu::bar(ui, |ui| { egui::menu::bar(ui, |ui| {
ui.menu_button("File", |ui| { if app.current_user.is_none() && ui.button("Sign Up").clicked() {
if ui.button("Sign Up").clicked() { app.signup_window_open = true;
app.signup_window_open = true; }
}
if ui.button("Login").clicked() { if app.current_user.is_none() && ui.button("Login").clicked() {
app.login_window_open = true; app.login_window_open = true;
} }
if ui.button("Logout").clicked() { if app.current_user.is_some() && ui.button("Logout").clicked() {
// TODO: Logout 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); ui.add_space(16.0);
egui::widgets::global_dark_light_mode_buttons(ui); 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.separator();
ui.label(format!("Current user: {:?}", app.current_user));
}); });
} }