- better error msgs
- default user
This commit is contained in:
Mohamad.Elsena 2025-01-02 14:33:49 +01:00
parent 25db5f108d
commit a30f14a0d4

View File

@ -1,7 +1,10 @@
use rusqlite::{params, Connection, OptionalExtension, Result}; use anyhow::{Context, Result as AnyhowResult};
use bcrypt::{hash, verify, DEFAULT_COST}; // Add bcrypt dependency for password hashing
use rusqlite::{params, Connection, OptionalExtension};
use uuid::Uuid; // UUID for generating unique IDs // Import anyhow
pub fn init_db() -> Result<Connection> { pub fn init_db() -> AnyhowResult<Connection> {
let conn = Connection::open("form_data.db")?; let conn = Connection::open("form_data.db").context("Failed to open the database")?;
conn.execute( conn.execute(
"CREATE TABLE IF NOT EXISTS forms ( "CREATE TABLE IF NOT EXISTS forms (
@ -35,15 +38,51 @@ pub fn init_db() -> Result<Connection> {
[], [],
)?; )?;
// Setup initial admin after creating the tables
setup_initial_admin(&conn)?;
Ok(conn) Ok(conn)
} }
pub fn setup_initial_admin(conn: &Connection) -> AnyhowResult<()> {
add_admin_user(conn)?;
Ok(())
}
pub fn add_admin_user(conn: &Connection) -> AnyhowResult<()> {
// Check if admin user already exists
let mut stmt = conn
.prepare("SELECT id FROM users WHERE username = ?1")
.context("Failed to prepare query for checking admin user")?;
if stmt.exists(params!["admin"])? {
return Ok(());
}
// Generate a UUID for the admin user
let admin_id = Uuid::new_v4().to_string();
// Hash the password before storing it
let hashed_password = hash("admin", DEFAULT_COST).context("Failed to hash password")?;
// Add admin user with hashed password
conn.execute(
"INSERT INTO users (id, username, password) VALUES (?1, ?2, ?3)",
params![admin_id, "admin", hashed_password],
)
.context("Failed to insert admin user into the database")?;
Ok(())
}
// Add a function to validate a token // Add a function to validate a token
pub fn validate_token(conn: &Connection, token: &str) -> Result<Option<String>> { pub fn validate_token(conn: &Connection, token: &str) -> AnyhowResult<Option<String>> {
let mut stmt = conn.prepare("SELECT id FROM users WHERE token = ?1")?; let mut stmt = conn
.prepare("SELECT id FROM users WHERE token = ?1")
.context("Failed to prepare query for validating token")?;
let user_id: Option<String> = stmt let user_id: Option<String> = stmt
.query_row(params![token], |row| row.get(0)) .query_row(params![token], |row| row.get(0))
.optional()?; .optional()
.context("Failed to retrieve user ID for the given token")?;
Ok(user_id) Ok(user_id)
} }
@ -52,16 +91,20 @@ pub fn authenticate_user(
conn: &Connection, conn: &Connection,
username: &str, username: &str,
password: &str, password: &str,
) -> Result<Option<String>> { ) -> AnyhowResult<Option<String>> {
let mut stmt = conn.prepare("SELECT id, password FROM users WHERE username = ?1")?; let mut stmt = conn
let mut rows = stmt.query(params![username])?; .prepare("SELECT id, password FROM users WHERE username = ?1")
.context("Failed to prepare query for authenticating user")?;
let mut rows = stmt
.query(params![username])
.context("Failed to execute query for authenticating user")?;
if let Some(row) = rows.next()? { if let Some(row) = rows.next()? {
let user_id: String = row.get(0)?; let user_id: String = row.get(0)?;
let stored_password: String = row.get(1)?; let stored_password: String = row.get(1)?;
// Replace this with a secure password hashing and verification mechanism // Use bcrypt to verify the hashed password
if stored_password == password { if verify(password, &stored_password).context("Failed to verify password")? {
return Ok(Some(user_id)); return Ok(Some(user_id));
} }
} }
@ -69,10 +112,11 @@ pub fn authenticate_user(
} }
// Add a function to generate and save a token for a user // Add a function to generate and save a token for a user
pub fn generate_token_for_user(conn: &Connection, user_id: &str, token: &str) -> Result<()> { pub fn generate_token_for_user(conn: &Connection, user_id: &str, token: &str) -> AnyhowResult<()> {
conn.execute( conn.execute(
"UPDATE users SET token = ?1 WHERE id = ?2", "UPDATE users SET token = ?1 WHERE id = ?2",
params![token, user_id], params![token, user_id],
)?; )
.context("Failed to update token for user")?;
Ok(()) Ok(())
} }