feat: add user and session models
This commit is contained in:
parent
eb0b16ea39
commit
67ad8c2b64
8 changed files with 328 additions and 1 deletions
|
|
@ -0,0 +1,2 @@
|
|||
pub mod session;
|
||||
pub mod user;
|
||||
34
src/db/models/session.rs
Normal file
34
src/db/models/session.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use diesel::prelude::*;
|
||||
use rand::Rng;
|
||||
|
||||
use super::user::User;
|
||||
use crate::db::{schema::*, DbPool, DbResult};
|
||||
|
||||
#[derive(Clone, Queryable, Selectable, Insertable, Associations)]
|
||||
#[diesel(belongs_to(super::user::User))]
|
||||
#[diesel(table_name = sessions)]
|
||||
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
||||
pub struct Session {
|
||||
pub id: i64,
|
||||
pub user_id: i64,
|
||||
}
|
||||
|
||||
impl Session {
|
||||
pub fn new_for_user(pool: &DbPool, user_id: i64) -> DbResult<Self> {
|
||||
let id: i64 = rand::thread_rng().gen();
|
||||
|
||||
Ok(Self { id, user_id }
|
||||
.insert_into(sessions::table)
|
||||
.returning(Self::as_returning())
|
||||
.get_result(&mut pool.get()?)?)
|
||||
}
|
||||
|
||||
pub fn user_from_id(pool: &DbPool, id: i64) -> DbResult<Option<super::user::User>> {
|
||||
Ok(sessions::dsl::sessions
|
||||
.inner_join(users::table)
|
||||
.filter(sessions::id.eq(id))
|
||||
.select(User::as_select())
|
||||
.get_result(&mut pool.get()?)
|
||||
.optional()?)
|
||||
}
|
||||
}
|
||||
67
src/db/models/user.rs
Normal file
67
src/db/models/user.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
use argon2::{password_hash::SaltString, Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
|
||||
use diesel::prelude::*;
|
||||
use rand::rngs::OsRng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::db::{schema::*, DbPool, DbResult};
|
||||
|
||||
#[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,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Insertable)]
|
||||
#[diesel(table_name = users)]
|
||||
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
||||
pub struct NewUser {
|
||||
pub username: String,
|
||||
pub password_hash: String,
|
||||
}
|
||||
|
||||
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) -> Self {
|
||||
Self {
|
||||
username,
|
||||
password_hash: hash_password(&password),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(self, pool: &DbPool) -> DbResult<User> {
|
||||
Ok(diesel::insert_into(users::table)
|
||||
.values(self)
|
||||
.returning(User::as_returning())
|
||||
.get_result(&mut pool.get()?)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub fn by_username(pool: &DbPool, username: impl AsRef<str>) -> DbResult<Option<Self>> {
|
||||
Ok(users::dsl::users
|
||||
.select(User::as_select())
|
||||
.filter(users::username.eq(username.as_ref()))
|
||||
.first(&mut pool.get()?)
|
||||
.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()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +1,23 @@
|
|||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
sessions (id) {
|
||||
id -> BigInt,
|
||||
user_id -> BigInt,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
users (id) {
|
||||
id -> BigInt,
|
||||
username -> Text,
|
||||
password_hash -> Text,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::joinable!(sessions -> users (user_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
sessions,
|
||||
users,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue