Add ban check and reason retrieval for user authentication
- Introduced `check_ban` and `get_ban_reason` functions in `db::users` - Updated client handler to enforce ban checks during login - Added detailed logging for ban status and reasons
This commit is contained in:
parent
b98a890738
commit
d06a15771a
4 changed files with 103 additions and 1 deletions
BIN
db.sqlite
BIN
db.sqlite
Binary file not shown.
Binary file not shown.
|
@ -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);
|
||||
|
|
|
@ -93,6 +93,74 @@ pub(crate) mod users {
|
|||
password_hash.to_string()
|
||||
}
|
||||
|
||||
pub async fn check_ban(username: &str) -> Result<bool, sqlx::Error> {
|
||||
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::<i64, _>(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<Option<String>, 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<String> = 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,
|
||||
|
|
Loading…
Add table
Reference in a new issue