State implementation and initial db work
State system is fully implemented and passing tests. I added in a handful of unit tests to test most of the available operations. Other work has involved getting the interface between client and server right and starting on the actual message handler. This involves starting work on the db as well
This commit is contained in:
@@ -1,2 +1,68 @@
|
||||
use diesel::prelude::*;
|
||||
pub mod models;
|
||||
pub mod schema;
|
||||
|
||||
|
||||
use bcrypt::{DEFAULT_COST, hash, verify};
|
||||
use diesel_async::AsyncPgConnection;
|
||||
use diesel_async::RunQueryDsl;//, AsyncConnection};
|
||||
use diesel_async::pooled_connection::deadpool::Object;
|
||||
use fedichat::client::{ServerMessage,ServerError};
|
||||
use tracing::{instrument,warn};
|
||||
|
||||
#[instrument(skip_all)]
|
||||
pub async fn maybe_create_user(mut connection: Object<AsyncPgConnection>, username: &str, password: &str) -> Result<ServerMessage,ServerError> {
|
||||
let password = match hash(password,DEFAULT_COST) {
|
||||
Ok(val) => val,
|
||||
Err(e) => {
|
||||
warn!("Error encountered while generating password hash");
|
||||
warn!("{e}");
|
||||
return Err(ServerError::Generic)
|
||||
}
|
||||
};
|
||||
let username = username.to_string();
|
||||
let user = models::NewUser{ username, password};
|
||||
let result = diesel::insert_into(schema::users::table)
|
||||
.values(&user)
|
||||
.execute(&mut *connection)
|
||||
.await;
|
||||
|
||||
match result {
|
||||
// TODO: might need to check this? I don't know what it means
|
||||
Ok(_) => Ok(ServerMessage::Ok),
|
||||
// TODO: Probably actually check the error
|
||||
Err(_e) => Err(ServerError::UserAlreadyExists)
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to authenticate a user against information in the database
|
||||
#[instrument(skip_all)]
|
||||
pub async fn verify_user(mut connection: Object<AsyncPgConnection>, user: &str, pass: &str) -> Result<bool,ServerError> {
|
||||
use schema::users::dsl::*;
|
||||
|
||||
let result = users
|
||||
.filter(username.eq(user))
|
||||
.select(models::User::as_select())
|
||||
.first(&mut *connection)
|
||||
.await;
|
||||
|
||||
|
||||
|
||||
match result {
|
||||
// If we have more than 0 rows then authentication is successful
|
||||
Ok(user) => match verify(pass,&user.password) {
|
||||
Ok(val) => Ok(val),
|
||||
Err(e) => {
|
||||
warn!("Error encountered while generating password hash");
|
||||
warn!("{e}");
|
||||
return Err(ServerError::Generic)
|
||||
}
|
||||
|
||||
},
|
||||
// TODO: Probably actually check the error
|
||||
_ => Err(ServerError::AuthenticationFailed)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -55,6 +55,13 @@ pub struct User {
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable)]
|
||||
#[diesel(table_name = crate::db::schema::users)]
|
||||
pub struct NewUser {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Selectable)]
|
||||
#[diesel(table_name = crate::db::schema::messages)]
|
||||
pub struct Messages {
|
||||
|
||||
Reference in New Issue
Block a user