diff --git a/db.sqlite b/db.sqlite index ce0640b..5fd4abf 100644 Binary files a/db.sqlite and b/db.sqlite differ diff --git a/db.sqlite-journal b/db.sqlite-journal deleted file mode 100644 index 55c0fd2..0000000 Binary files a/db.sqlite-journal and /dev/null differ diff --git a/src/client/mod.rs b/src/client/mod.rs index a6fe033..dd6c3de 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -4,7 +4,9 @@ pub(crate) mod handlers { Aes256Gcm, Key, Nonce, }; - use crate::db::users::{check_for_account, create_user, hash_password, verify_password}; + use crate::db::users::{ + check_ban, check_for_account, create_user, get_ban_reason, hash_password, verify_password, + }; use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _}; use log::{debug, error, info}; use serde::Deserialize; @@ -89,6 +91,38 @@ pub(crate) mod handlers { // Check if the user already exists in the database if check_for_account(&username).await? { + // Check if the user is banned + if check_ban(&username).await? == true { + let ban_reason_result = get_ban_reason(&username).await; + + let message: String = match ban_reason_result { + Ok(Some(reason)) => { + info!("User {} is banned, Reason: {}", username, reason); + format!("User {} is banned, Reason: {}", username, reason).to_string() + } + Ok(None) => { + info!("User {} is banned, but no reason provided", username); + format!("User {} is banned, but no reason provided", username).to_string() + } + Err(e) => { + error!("Error fetching ban reason: {}", e); + format!("You are banned").to_string(); + return Ok(()); + } + }; + + let encrypted = match cipher_writer.encrypt(&nonce_writer, message.as_bytes()) { + Ok(encrypted) => encrypted, + Err(e) => { + error!("Encryption error: {}", e); + return Ok(()); + } + }; + let message = format!("{}\n", BASE64.encode(&encrypted)); + writer.write_all(message.as_bytes()).await?; + return Ok(()); + } + info!("User {} already exists", username); // Send a message to the client let message = format!("User {} is registered, input your password", username); diff --git a/src/db/mod.rs b/src/db/mod.rs index 5b17473..bb6b225 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -93,6 +93,74 @@ pub(crate) mod users { password_hash.to_string() } + pub async fn check_ban(username: &str) -> Result { + let pool = create_db_pool().await?; + + let is_banned = sqlx::query( + r#" + SELECT EXISTS( + SELECT 1 + FROM users + WHERE username = ? + ) + "#, + ) + .bind(username) + .fetch_one(&pool) + .await? + .get::(0); + + // Check if the user is banned + if is_banned == 1 { + info!("User {} is banned", username); + } else { + info!("User {} is not banned", username); + } + + Ok(is_banned == 1) + } + + pub async fn get_ban_reason(username: &str) -> Result, sqlx::Error> { + let pool = create_db_pool().await?; + info!("Attempting to fetch ban reason for user: {}", username); + + let row_option = sqlx::query( + r#" + SELECT ban_reason + FROM users + WHERE username = ? + "#, + ) + .bind(username) + .fetch_optional(&pool) + .await?; + + // Process the result + match row_option { + Some(row) => { + // Row found, now get the ban_reason (which might be NULL) + let reason: Option = row.get(0); // Type annotation clarifies intent + if let Some(ref r) = reason { + info!("User {} found. Ban reason: {}", username, r); + } else { + // User exists, but ban_reason is NULL in the database + info!( + "User {} found, but ban_reason is NULL (not banned)", + username + ); + } + Ok(reason) + } + None => { + // No row found for the username + info!("User {} not found in the database", username); + // Return Ok(None) as per the function signature, indicating no ban reason found + // because the user doesn't exist. + Ok(None) + } + } + } + pub async fn verify_password( // Use clearer argument names username: &str,