feat: rewrite user model using diesel

This commit is contained in:
Jef Roosens 2025-01-13 13:43:09 +01:00
parent 18a321853a
commit 77995ebec9
Signed by: Jef Roosens
GPG key ID: 21FD3D77D56BAF49
10 changed files with 97 additions and 17 deletions

View file

@ -1,5 +1,6 @@
mod comment;
mod event;
mod models;
mod plant;
mod schema;
mod session;

1
src/db/models/mod.rs Normal file
View file

@ -0,0 +1 @@
mod user;

75
src/db/models/user.rs Normal file
View file

@ -0,0 +1,75 @@
use argon2::{
password_hash::{rand_core::OsRng, SaltString},
Argon2, PasswordHash, PasswordHasher, PasswordVerifier,
};
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
use crate::db::schema::*;
#[derive(Serialize, Deserialize, Clone, Queryable, Selectable)]
#[diesel(table_name = users)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct User {
pub id: i64,
pub username: String,
pub password_hash: String,
pub admin: bool,
}
#[derive(Deserialize, Insertable)]
#[diesel(table_name = users)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct NewUser {
pub username: String,
pub password_hash: String,
pub admin: bool,
}
fn hash_password(password: impl AsRef<str>) -> String {
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
argon2
.hash_password(password.as_ref().as_bytes(), &salt)
.unwrap()
.to_string()
}
impl NewUser {
pub fn new(username: String, password: String, admin: bool) -> Self {
Self {
username,
password_hash: hash_password(&password),
admin,
}
}
pub fn insert(self, conn: &mut SqliteConnection) -> QueryResult<User> {
diesel::insert_into(users::table)
.values(self)
.returning(User::as_returning())
.get_result(conn)
}
}
impl User {
pub fn by_username(
conn: &mut SqliteConnection,
username: impl AsRef<str>,
) -> QueryResult<Option<Self>> {
users::dsl::users
.select(User::as_select())
.filter(users::username.eq(username.as_ref()))
.first(conn)
.optional()
}
pub fn verify_password(&self, password: impl AsRef<str>) -> bool {
let password_hash = PasswordHash::new(&self.password_hash).unwrap();
Argon2::default()
.verify_password(password.as_ref().as_bytes(), &password_hash)
.is_ok()
}
}

View file

@ -2,16 +2,16 @@
diesel::table! {
comments (id) {
id -> Integer,
plant_id -> Nullable<Integer>,
id -> BigInt,
plant_id -> BigInt,
comment -> Text,
}
}
diesel::table! {
events (id) {
id -> Integer,
plant_id -> Integer,
id -> BigInt,
plant_id -> BigInt,
event_type -> Text,
date -> Text,
description -> Text,
@ -20,7 +20,7 @@ diesel::table! {
diesel::table! {
plants (id) {
id -> Integer,
id -> BigInt,
name -> Text,
species -> Text,
description -> Text,
@ -29,14 +29,14 @@ diesel::table! {
diesel::table! {
sessions (id) {
id -> Integer,
user_id -> Integer,
id -> BigInt,
user_id -> BigInt,
}
}
diesel::table! {
users (id) {
id -> Integer,
id -> BigInt,
username -> Text,
password_hash -> Text,
admin -> Bool,