Initial database operations

This commit is contained in:
Talha Qamar 2024-11-23 08:11:19 +05:00
parent 241eabd064
commit 3ea28ac7ff
5 changed files with 119 additions and 3 deletions

35
Cargo.lock generated
View file

@ -7,7 +7,10 @@ name = "abuelo"
version = "0.1.0"
dependencies = [
"chrono",
"rand",
"ring",
"rusqlite",
"sha2",
"tokio",
"warp",
]
@ -892,6 +895,21 @@ dependencies = [
"bitflags",
]
[[package]]
name = "ring"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"spin",
"untrusted",
"windows-sys",
]
[[package]]
name = "rusqlite"
version = "0.32.1"
@ -986,6 +1004,17 @@ dependencies = [
"digest",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
@ -1213,6 +1242,12 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.3"

View file

@ -8,3 +8,6 @@ tokio = { version = "1", features = ["full"] }
warp = "0.3"
chrono = "0.4"
rusqlite = { version = "0.32", features = ["chrono", "bundled"] }
sha2 = "0.10.8"
ring = "0.17.8"
rand = "0.8.5"

View file

@ -4,9 +4,8 @@ pub type UserID = u128;
pub enum AccountStatusState {
Offline,
Idle,
// Similar to discords do not disturb.
Silenced,
Away,
DoNotDisturb,
Online,
}

78
src/database.rs Normal file
View file

@ -0,0 +1,78 @@
use std::{rc::Rc, sync::Arc};
use chrono::{DateTime, Utc};
use rusqlite::{Connection, Result};
use sha2::{Digest, Sha256};
pub struct Database {
conn: Connection,
}
impl Database {
pub fn new() -> Self {
let conn = Connection::open("user_db.db3").unwrap();
// If this returns an error; it's prolly cuz the table already exists.
// That's fine and we can just let it error and the other queries will
// use the existing table instead
// NOTE: Look at the other possible errors here
let _ = conn.execute(
"CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
username TINYTEXT NOT NULL,
password_hash TINYTEXT NOT NULL,
creation_time DATETIME NOT NULL
is_premium BOOL NOT NULL,
random_value INTEGER NOT NULL
)",
());
Self { conn }
}
pub fn add_user(&self, username : &str, password : &str) -> Result<()>{
let password_hash = self.hash_password(username, password)?;
self.conn.execute(
"INSERT INTO person (
username,
password_hash,
creation_time,
is_premium,
random_value)
VALUES (?1, ?2, ?3, ?4, ?5)",
(username, password_hash, Utc::now(), false, rand::random::<u64>()),
)?;
Ok(())
}
fn hash_password(&self, username : &str, password : &str) -> Result<String>{
let (creation_time, num) : (DateTime<Utc>, u64) = self.conn.query_row(
"SELECT creation_time, random_value, name FROM person WHERE name=?1",
[username],
|row|{
let creation_time = row.get(0)?;
let num = row.get(1)?;
Ok((creation_time, num))
},
)?;
let mut hasher = Sha256::new();
hasher.update(password);
hasher.update(creation_time.format("%Y-%m-%d-%H-%M").to_string());
hasher.update(num.to_string());
Ok(format!("{:x}", hasher.finalize()))
}
pub fn check_login(&self, username : &str, password : &str) -> bool{
let saved_password_hash : Result<Rc<str>> = self.conn.query_row(
"SELECT password_hash, name FROM person WHERE name=?1",
[username],
|row| row.get::<usize, Rc<str>>(0),
);
if let Err(_) = saved_password_hash {
return false;
}
*saved_password_hash.unwrap() == *password
}
}

View file

@ -1,6 +1,7 @@
use warp::Filter;
mod account;
mod database;
#[tokio::main]
async fn main() {
// GET /hello/warp => 200 OK with body "Hello, warp!"