tetratto/crates/tetratto_core/src/model/auth.rs
trisua b6fe2fba37 add: postgres support
chore: restructure
2025-03-22 22:17:47 -04:00

71 lines
1.7 KiB
Rust

use rainbeam_shared::{
hash::{hash_salted, salt},
snow::AlmostSnowflake,
unix_epoch_timestamp,
};
use serde::{Deserialize, Serialize};
/// `(ip, token, creation timestamp)`
pub type Token = (String, String, usize);
#[derive(Debug, Serialize)]
pub struct User {
pub id: usize,
pub created: usize,
pub username: String,
pub password: String,
pub salt: String,
pub settings: UserSettings,
pub tokens: Vec<Token>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct UserSettings;
impl Default for UserSettings {
fn default() -> Self {
Self {}
}
}
impl User {
/// Create a new [`User`].
pub fn new(username: String, password: String) -> Self {
let salt = salt();
let password = hash_salted(password, salt.clone());
Self {
id: AlmostSnowflake::new(1234567890)
.to_string()
.parse::<usize>()
.unwrap(),
created: unix_epoch_timestamp() as usize,
username,
password,
salt,
settings: UserSettings::default(),
tokens: Vec::new(),
}
}
/// Create a new token
///
/// # Returns
/// `(unhashed id, token)`
pub fn create_token(ip: &str) -> (String, Token) {
let unhashed = rainbeam_shared::hash::uuid();
(
unhashed.clone(),
(
ip.to_string(),
rainbeam_shared::hash::hash(unhashed),
unix_epoch_timestamp() as usize,
),
)
}
/// Check if the given password is correct for the user.
pub fn check_password(&self, against: String) -> bool {
self.password == hash_salted(against, self.salt.clone())
}
}