Add SQLite database support and user management functionality

This commit is contained in:
Andrea Moro 2025-01-31 13:43:35 +01:00
parent 6ebdef9a64
commit 8df02b7a5a
8 changed files with 1362 additions and 9 deletions

View file

@ -7,11 +7,13 @@ pub(crate) mod handlers {
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
use log::{debug, error, info};
use serde::Deserialize;
use std::sync::Arc;
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader};
use tokio::net::TcpStream;
use tokio::sync::broadcast;
use x25519_dalek::{EphemeralSecret, PublicKey};
use crate::db::users::create_user;
/*
Specifications of the packet
32 bytes - Command name
@ -81,9 +83,11 @@ pub(crate) mod handlers {
let decrypted = cipher_reader
.decrypt(&nonce_reader, decoded.as_ref())
.unwrap();
let username = String::from_utf8(decrypted)?;
let username_read = username.clone(); // Clone for read task
let mut username_write = username.clone(); // Clone for write task
let username = Arc::new(String::from_utf8(decrypted)?);
let username_read = Arc::clone(&username); // Clone the Arc for read task
let username_write = Arc::clone(&username); // Clone the Arc for write task
create_user(&username, "1234").await?;
// Read task for receiving messages from the client
let read_task = tokio::spawn(async move {
@ -160,12 +164,20 @@ pub(crate) mod handlers {
}
let new_nickname = &parsed_message.argument[0];
info!("Changing nickname to: {}", new_nickname);
username_write = new_nickname.clone();
// Here implement your nickname change logic
}
_ => {
error!("Unknown command: {}", parsed_message.command[0]);
match tx.send("Error! Unknown command".to_string()) {
Ok(_) => {
info!("Error message sent to client {}", username_write)
}
Err(e) => {
error!("Failed to send error message: {:?}", e);
break;
}
}
}
}
} else {

30
src/db/mod.rs Normal file
View file

@ -0,0 +1,30 @@
pub(crate) mod users {
use sqlx::sqlite::SqlitePool;
pub async fn connect_to_db() -> Result<SqlitePool, sqlx::Error> {
let pool = SqlitePool::connect("sqlite:./db.sqlite").await?;
Ok(pool)
}
pub async fn create_db_pool() -> Result<SqlitePool, sqlx::Error> {
let pool = connect_to_db().await?;
sqlx::migrate!("./migrations").run(&pool).await?;
Ok(pool)
}
pub async fn create_user(username: &str, password_hash: &str) -> Result<(), sqlx::Error> {
let pool = create_db_pool().await?;
sqlx::query(
r#"
INSERT INTO users (username, password_hash)
VALUES (?, ?)
"#,
)
.bind(username)
.bind(password_hash)
.execute(&pool)
.await?;
Ok(())
}
}

View file

@ -1,11 +1,13 @@
mod client;
mod tui; // Add this new module
mod db;
use client::handlers::handle_client;
use db::users::create_db_pool;
use log::{error, info, Level, Log, Metadata, Record};
use serde::Deserialize;
use std::sync::mpsc;
use std::thread;
use std::{process::exit, sync::mpsc};
use tokio::net::TcpListener;
use tokio::sync::broadcast;
use tui::{run_app, LogEntry};
@ -43,6 +45,8 @@ impl Log for CustomLogger {
#[tokio::main]
async fn main() {
create_db_pool().await.unwrap();
// Create a channel for logging
let (tx, rx) = mpsc::channel();
@ -56,6 +60,9 @@ async fn main() {
if let Err(e) = run_app(rx) {
eprintln!("Error running TUI: {:?}", e);
}
// Exit the process when the TUI closes
exit(0);
});
// Load the configuration from config file