57 lines
1.6 KiB
Rust
57 lines
1.6 KiB
Rust
use crate::db::{Dao, TenebrousDbConn};
|
|
use crate::schema::users;
|
|
use argon2::{self, Config, Error as ArgonError};
|
|
use rand::Rng;
|
|
use rocket::outcome::IntoOutcome;
|
|
use rocket::request::{self, FromRequest, Request};
|
|
use serde_derive::Serialize;
|
|
|
|
pub(crate) fn hash_password(raw_password: &str) -> Result<String, ArgonError> {
|
|
let salt = rand::thread_rng().gen::<[u8; 16]>();
|
|
let config = Config::default();
|
|
argon2::hash_encoded(raw_password.as_bytes(), &salt, &config)
|
|
}
|
|
|
|
#[derive(Eq, PartialEq, Serialize, Debug, Queryable)]
|
|
pub struct User {
|
|
pub id: i32,
|
|
pub username: String,
|
|
pub password: String,
|
|
}
|
|
|
|
impl User {
|
|
pub fn verify_password(&self, raw_password: &str) -> bool {
|
|
argon2::verify_encoded(&self.password, raw_password.as_bytes()).unwrap_or(false)
|
|
}
|
|
}
|
|
|
|
impl<'a, 'r> FromRequest<'a, 'r> for &'a User {
|
|
type Error = !;
|
|
|
|
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, !> {
|
|
let user: &Option<User> = request.local_cache(|| {
|
|
let attempt_load_user = |id| -> Option<User> {
|
|
TenebrousDbConn::from_request(request)
|
|
.map(|conn| conn.load_user_by_id(id).ok().flatten())
|
|
.succeeded()
|
|
.flatten()
|
|
};
|
|
|
|
request
|
|
.cookies()
|
|
.get_private("user_id")
|
|
.and_then(|cookie| cookie.value().parse().ok())
|
|
.and_then(attempt_load_user)
|
|
});
|
|
|
|
user.as_ref().or_forward(())
|
|
}
|
|
}
|
|
|
|
#[derive(Insertable)]
|
|
#[table_name = "users"]
|
|
pub struct NewUser<'a> {
|
|
pub username: &'a str,
|
|
pub password: &'a str,
|
|
}
|