Compare commits
3 commits
00979cacff
...
65947193b9
Author | SHA1 | Date | |
---|---|---|---|
|
65947193b9 | ||
|
cdf0b7bd29 | ||
|
8bb227f48e |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/target
|
||||
user_db.db3
|
||||
|
|
|
@ -9,6 +9,7 @@ pub struct Account {
|
|||
creation_time: DateTime<Utc>,
|
||||
// Donator role
|
||||
premium: bool,
|
||||
random: i64,
|
||||
}
|
||||
|
||||
impl Account {
|
||||
|
@ -17,12 +18,14 @@ impl Account {
|
|||
user_id: UserID,
|
||||
creation_time: DateTime<Utc>,
|
||||
premium: bool,
|
||||
random: i64,
|
||||
) -> Self {
|
||||
Self {
|
||||
username,
|
||||
user_id,
|
||||
creation_time,
|
||||
premium,
|
||||
random,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,4 +36,8 @@ impl Account {
|
|||
pub fn creation_time(&self) -> DateTime<Utc> {
|
||||
self.creation_time
|
||||
}
|
||||
|
||||
pub fn id(&self) -> UserID {
|
||||
self.user_id
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,23 @@ pub enum UserCreationError {
|
|||
DBError(rusqlite::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum HandleDBError {
|
||||
HandleAlreadyExists,
|
||||
DBError(rusqlite::Error),
|
||||
}
|
||||
|
||||
impl From<rusqlite::Error> for UserCreationError {
|
||||
fn from(value: rusqlite::Error) -> Self {
|
||||
Self::DBError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<rusqlite::Error> for HandleDBError {
|
||||
fn from(value: rusqlite::Error) -> Self {
|
||||
Self::DBError(value)
|
||||
}
|
||||
}
|
||||
impl std::error::Error for UserCreationError {}
|
||||
impl Display for UserCreationError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
|
@ -35,6 +47,20 @@ impl Display for UserCreationError {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for HandleDBError {}
|
||||
impl Display for HandleDBError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
HandleDBError::HandleAlreadyExists => {
|
||||
write!(f, "Handle already exists.")
|
||||
}
|
||||
HandleDBError::DBError(e) => {
|
||||
write!(f, "DBError: {}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub fn new() -> Self {
|
||||
let conn = Connection::open("user_db.db3").unwrap();
|
||||
|
@ -44,7 +70,7 @@ impl Database {
|
|||
// use the existing table instead
|
||||
// NOTE: Look at the other possible errors here
|
||||
let _val = conn.execute(
|
||||
"CREATE TABLE users (
|
||||
"CREATE TABLE user (
|
||||
user_id INTEGER PRIMARY KEY,
|
||||
username TINYTEXT NOT NULL,
|
||||
password_hash TINYTEXT NOT NULL,
|
||||
|
@ -55,19 +81,30 @@ impl Database {
|
|||
(),
|
||||
);
|
||||
|
||||
let _val = conn.execute(
|
||||
"CREATE TABLE handle (
|
||||
handle_id INTEGER PRIMARY KEY,
|
||||
handle_val BIGINT UNSIGNED NOT NULL
|
||||
CONSTRAINT fk_usr_handle FOREIGN KEY (user)
|
||||
REFERENCES person (id)
|
||||
)",
|
||||
(),
|
||||
);
|
||||
|
||||
Self { conn }
|
||||
}
|
||||
|
||||
pub fn get_user(&self, username: &str) -> Result<Account> {
|
||||
let (user_id, creation_time, premium): (UserID, DateTime<Utc>, bool) =
|
||||
let (user_id, creation_time, premium, random): (UserID, DateTime<Utc>, bool, i64) =
|
||||
self.conn.query_row(
|
||||
"SELECT username, user_id, creation_time, is_premium FROM users WHERE username=?1",
|
||||
"SELECT username, user_id, creation_time, is_premium, random_value FROM user WHERE username=?1",
|
||||
[username],
|
||||
|row| {
|
||||
let user_id = row.get(1)?;
|
||||
let creation_time = row.get(2)?;
|
||||
let premium = row.get(3)?;
|
||||
Ok((user_id, creation_time, premium))
|
||||
let random = row.get(4)?;
|
||||
Ok((user_id, creation_time, premium, random))
|
||||
},
|
||||
)?;
|
||||
Ok(Account::new(
|
||||
|
@ -75,6 +112,7 @@ impl Database {
|
|||
user_id,
|
||||
creation_time,
|
||||
premium,
|
||||
random,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -86,7 +124,7 @@ impl Database {
|
|||
let num = rand::random::<u64>();
|
||||
let password_hash = self.hash_password(password, creation_time, num);
|
||||
self.conn.execute(
|
||||
"INSERT INTO users (
|
||||
"INSERT INTO user (
|
||||
username,
|
||||
password_hash,
|
||||
creation_time,
|
||||
|
@ -108,7 +146,7 @@ impl Database {
|
|||
|
||||
pub fn check_login(&self, username: &str, password: &str) -> bool {
|
||||
let result = self.conn.query_row(
|
||||
"SELECT creation_time, random_value, username FROM users WHERE username=?1",
|
||||
"SELECT creation_time, random_value, username FROM user WHERE username=?1",
|
||||
[username],
|
||||
|row| {
|
||||
let creation_time = row.get(0)?;
|
||||
|
@ -121,7 +159,7 @@ impl Database {
|
|||
}
|
||||
let (creation_time, num) = result.unwrap();
|
||||
let saved_password_hash: Result<Rc<str>> = self.conn.query_row(
|
||||
"SELECT password_hash, username FROM users WHERE username=?1",
|
||||
"SELECT password_hash, username FROM user WHERE username=?1",
|
||||
[username],
|
||||
|row| row.get::<usize, Rc<str>>(0),
|
||||
);
|
||||
|
@ -131,4 +169,28 @@ impl Database {
|
|||
|
||||
*saved_password_hash.unwrap() == self.hash_password(password, creation_time, num)
|
||||
}
|
||||
|
||||
// HANDLE FUNCTIONS --------------------------------------------------
|
||||
pub fn add_handle_to_db(&self, user: &Account, handle: u64) -> Result<(), HandleDBError> {
|
||||
let saved_handle = self
|
||||
.conn
|
||||
.query_row(
|
||||
"SELECT handle_val FROM handle WHERE handle_val=?1",
|
||||
[handle],
|
||||
|row| row.get::<usize, u64>(0),
|
||||
)
|
||||
.is_ok();
|
||||
if saved_handle {
|
||||
return Err(HandleDBError::HandleAlreadyExists);
|
||||
}
|
||||
self.conn.execute(
|
||||
"INSERT INTO handle (
|
||||
handle_val
|
||||
fk_usr_handle
|
||||
)
|
||||
VALUES (?1, ?2)",
|
||||
(handle, user.id()),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
26
src/handle.rs
Normal file
26
src/handle.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use crate::{
|
||||
account::Account,
|
||||
database::{Database, HandleDBError},
|
||||
};
|
||||
|
||||
pub struct Handle(u64);
|
||||
|
||||
impl Handle {
|
||||
pub fn new(user: &Account, db: Database) -> Result<Handle, HandleDBError> {
|
||||
loop {
|
||||
let num = rand::random::<u64>();
|
||||
let res = db.add_handle_to_db(user, num);
|
||||
match res {
|
||||
Ok(_) => return Ok(Handle(num)),
|
||||
Err(x) => match x {
|
||||
HandleDBError::HandleAlreadyExists => continue,
|
||||
HandleDBError::DBError(e) => return Err(HandleDBError::DBError(e)),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -2,7 +2,7 @@ use routes::get_routes;
|
|||
|
||||
mod account;
|
||||
mod database;
|
||||
mod handlers;
|
||||
mod handle;
|
||||
mod routes;
|
||||
|
||||
#[tokio::main]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use warp::Filter;
|
||||
|
||||
use crate::database::Database;
|
||||
use crate::{database::Database, handle::Handle};
|
||||
|
||||
pub fn get_routes() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
|
||||
create_user().or(auth_user()).or(get_user())
|
||||
|
@ -80,6 +80,7 @@ struct UserAuthRequest {
|
|||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
struct UserAuthResponse {
|
||||
success: bool,
|
||||
handle: Option<u64>,
|
||||
message: String,
|
||||
}
|
||||
fn auth_user() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
|
||||
|
@ -89,14 +90,17 @@ fn auth_user() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejectio
|
|||
.map(|body: UserAuthRequest| {
|
||||
let db = Database::new();
|
||||
let reply = if db.check_login(&body.username, &body.password) {
|
||||
let handle = Handle::new(&(db.get_user(&body.username).unwrap()), db).unwrap();
|
||||
UserAuthResponse {
|
||||
success: true,
|
||||
message: "".to_string(),
|
||||
handle: Some(handle.get()),
|
||||
}
|
||||
} else {
|
||||
UserAuthResponse {
|
||||
success: false,
|
||||
message: "Username or Password is invalid".to_string(),
|
||||
handle: None,
|
||||
}
|
||||
};
|
||||
warp::reply::json(&reply)
|
||||
|
|
BIN
user_db.db3
BIN
user_db.db3
Binary file not shown.
Loading…
Reference in a new issue