GeneIT/geneit_backend/src/models.rs

300 lines
6.8 KiB
Rust
Raw Normal View History

2023-08-07 12:53:44 +00:00
use crate::app_config::AppConfig;
2023-08-07 09:07:24 +00:00
use crate::schema::{families, members, memberships, photos, users};
2023-08-07 12:53:44 +00:00
use crate::utils::crypt_utils::sha256;
2023-05-24 14:19:46 +00:00
use diesel::prelude::*;
/// User ID holder
2023-06-22 14:03:11 +00:00
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
2023-05-30 13:12:58 +00:00
pub struct UserID(pub i32);
2023-05-24 14:19:46 +00:00
2023-05-31 13:52:49 +00:00
#[derive(Queryable, Debug, serde::Serialize)]
2023-05-24 14:19:46 +00:00
pub struct User {
2023-06-21 15:01:52 +00:00
id: i32,
2023-05-30 13:12:58 +00:00
pub name: String,
pub email: String,
2023-05-31 13:52:49 +00:00
#[serde(skip_serializing)]
2023-05-30 13:12:58 +00:00
pub password: Option<String>,
2023-06-06 07:47:52 +00:00
pub time_create: i64,
2023-05-31 13:52:49 +00:00
#[serde(skip_serializing)]
2023-05-30 13:12:58 +00:00
pub reset_password_token: Option<String>,
2023-05-31 13:52:49 +00:00
#[serde(skip_serializing)]
2023-05-30 13:12:58 +00:00
pub time_gen_reset_token: i64,
2023-06-06 07:47:52 +00:00
#[serde(skip_serializing)]
pub delete_account_token: Option<String>,
#[serde(skip_serializing)]
pub time_gen_delete_account_token: i64,
2023-05-30 13:12:58 +00:00
pub time_activate: i64,
pub active: bool,
pub admin: bool,
2023-05-24 14:19:46 +00:00
}
impl User {
pub fn id(&self) -> UserID {
UserID(self.id)
}
2023-05-31 13:17:00 +00:00
pub fn check_password(&self, password: &str) -> bool {
self.password
.as_deref()
.map(|hash| {
bcrypt::verify(password, hash).unwrap_or_else(|e| {
log::error!("Failed to validate password! {}", e);
false
})
})
.unwrap_or(false)
}
2023-05-24 14:19:46 +00:00
}
#[derive(Insertable)]
#[diesel(table_name = users)]
pub struct NewUser<'a> {
pub name: &'a str,
pub email: &'a str,
pub time_create: i64,
}
2023-06-16 15:51:51 +00:00
/// Family ID holder
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
2023-06-16 15:51:51 +00:00
pub struct FamilyID(pub i32);
#[derive(Queryable, Debug, serde::Serialize)]
pub struct Family {
2023-06-21 15:01:52 +00:00
id: i32,
2023-06-16 15:51:51 +00:00
pub time_create: i64,
pub name: String,
pub invitation_code: String,
}
impl Family {
pub fn id(&self) -> FamilyID {
FamilyID(self.id)
}
}
#[derive(Insertable)]
#[diesel(table_name = families)]
pub struct NewFamily<'a> {
pub name: &'a str,
pub invitation_code: String,
pub time_create: i64,
}
#[derive(Queryable, Debug, serde::Serialize)]
pub struct Membership {
2023-06-21 15:01:52 +00:00
user_id: i32,
family_id: i32,
2023-06-21 14:36:46 +00:00
pub time_create: i64,
pub is_admin: bool,
}
impl Membership {
pub fn user_id(&self) -> UserID {
UserID(self.user_id)
}
pub fn family_id(&self) -> FamilyID {
FamilyID(self.family_id)
}
2023-06-16 15:51:51 +00:00
}
#[derive(Insertable)]
#[diesel(table_name = memberships)]
pub struct NewMembership {
pub user_id: i32,
pub family_id: i32,
pub time_create: i64,
pub is_admin: bool,
}
2023-06-20 16:55:14 +00:00
#[derive(Queryable, Debug, serde::Serialize)]
pub struct FamilyMembership {
user_id: i32,
family_id: i32,
name: String,
time_create: i64,
2023-06-21 15:35:07 +00:00
pub is_admin: bool,
2023-06-20 16:55:14 +00:00
invitation_code: String,
2023-06-21 15:35:07 +00:00
pub count_members: i64,
pub count_admins: i64,
2023-06-20 16:55:14 +00:00
}
2023-08-04 17:03:46 +00:00
2023-08-05 17:15:52 +00:00
/// Photo ID holder
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash)]
pub struct PhotoID(pub i32);
2023-08-07 12:53:44 +00:00
impl PhotoID {
pub fn to_signed_hash(&self) -> String {
let secret = AppConfig::get().secret();
format!(
"{}-{}",
self.0,
sha256(format!("{secret}{}{secret}", self.0).as_bytes())
)
}
pub fn from_signed_hash(hash: &str) -> Option<Self> {
let (id, _) = hash.split_once('-')?;
let id = Self(id.parse().ok()?);
if id.to_signed_hash() != hash {
return None;
}
Some(id)
}
}
2023-08-07 09:07:24 +00:00
#[derive(Queryable, Debug, serde::Serialize)]
pub struct Photo {
id: i32,
pub file_id: String,
pub time_create: i64,
pub mime_type: String,
pub sha512: String,
pub file_size: i32,
pub thumb_sha512: String,
}
impl Photo {
pub fn id(&self) -> PhotoID {
PhotoID(self.id)
}
pub fn photo_path(&self) -> String {
format!("photo/{}", self.file_id)
}
pub fn thumbnail_path(&self) -> String {
format!("thumbnail/{}", self.file_id)
}
}
#[derive(Insertable)]
#[diesel(table_name = photos)]
pub struct NewPhoto {
pub file_id: String,
pub time_create: i64,
pub mime_type: String,
pub sha512: String,
pub file_size: i32,
pub thumb_sha512: String,
}
impl NewPhoto {
pub fn photo_path(&self) -> String {
format!("photo/{}", self.file_id)
}
pub fn thumbnail_path(&self) -> String {
format!("thumbnail/{}", self.file_id)
}
}
2023-08-04 17:03:46 +00:00
/// Member ID holder
2023-08-05 10:10:23 +00:00
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash)]
2023-08-04 17:03:46 +00:00
pub struct MemberID(pub i32);
#[derive(serde::Serialize, serde::Deserialize)]
pub enum Sex {
#[serde(rename = "M")]
Male,
#[serde(rename = "F")]
Female,
}
impl Sex {
pub fn parse_str(s: &str) -> Option<Self> {
2023-08-04 17:03:46 +00:00
match s {
"M" => Some(Sex::Male),
"F" => Some(Sex::Female),
_ => None,
}
}
pub fn to_str(&self) -> &'static str {
match self {
Sex::Male => "M",
Sex::Female => "F",
}
}
}
#[derive(Queryable, Debug, serde::Serialize)]
pub struct Member {
id: i32,
family_id: i32,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub birth_last_name: Option<String>,
2023-08-05 17:15:52 +00:00
photo_id: Option<i32>,
2023-08-04 17:03:46 +00:00
pub email: Option<String>,
pub phone: Option<String>,
pub address: Option<String>,
pub city: Option<String>,
pub postal_code: Option<String>,
pub country: Option<String>,
sex: Option<String>,
time_create: i64,
pub time_update: i64,
mother: Option<i32>,
father: Option<i32>,
pub birth_year: Option<i16>,
pub birth_month: Option<i16>,
pub birth_day: Option<i16>,
pub death_year: Option<i16>,
pub death_month: Option<i16>,
pub death_day: Option<i16>,
pub note: Option<String>,
}
impl Member {
pub fn id(&self) -> MemberID {
MemberID(self.id)
}
pub fn family_id(&self) -> FamilyID {
FamilyID(self.family_id)
}
2023-08-07 09:07:24 +00:00
pub fn set_photo_id(&mut self, p: Option<PhotoID>) {
self.photo_id = p.map(|p| p.0)
}
2023-08-05 17:15:52 +00:00
pub fn photo_id(&self) -> Option<PhotoID> {
self.photo_id.map(PhotoID)
}
2023-08-04 17:03:46 +00:00
pub fn sex(&self) -> Option<Sex> {
self.sex.as_deref().map(Sex::parse_str).unwrap_or_default()
2023-08-04 17:03:46 +00:00
}
pub fn set_sex(&mut self, s: Option<Sex>) {
self.sex = s.map(|s| s.to_str().to_string())
}
pub fn mother(&self) -> Option<MemberID> {
self.mother.map(MemberID)
}
pub fn set_mother(&mut self, p: Option<MemberID>) {
self.mother = p.map(|p| p.0);
}
pub fn father(&self) -> Option<MemberID> {
self.father.map(MemberID)
}
pub fn set_father(&mut self, p: Option<MemberID>) {
self.father = p.map(|p| p.0);
}
}
#[derive(Insertable)]
#[diesel(table_name = members)]
pub struct NewMember {
pub family_id: i32,
pub time_create: i64,
pub time_update: i64,
}