mabel/src/auth/user.rs

102 lines
2.6 KiB
Rust

use anyhow::Result;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, Pool, Postgres};
use uuid::Uuid;
use super::hash::hash;
#[derive(Deserialize, Serialize, FromRow)]
pub struct User {
/// User internal ID
pub id: Uuid,
/// User name (unique per instance, shows up in URLs)
pub name: String,
/// User email (for validation/login)
pub email: Option<String>,
/// Hashed password
pub password: Option<String>,
/// User's chosen displayed name
pub display_name: Option<String>,
/// Biography / User description
pub bio: Option<String>,
/// User roles (as role IDs)
pub roles: Vec<Uuid>,
/// Times
pub created_at: NaiveDateTime,
pub modified_at: Option<NaiveDateTime>,
pub deleted_at: Option<NaiveDateTime>,
}
impl Default for User {
fn default() -> Self {
Self {
id: Uuid::nil(),
name: Default::default(),
email: Default::default(),
password: Default::default(),
display_name: Default::default(),
bio: Default::default(),
roles: Default::default(),
created_at: Default::default(),
modified_at: Default::default(),
deleted_at: Default::default(),
}
}
}
impl User {
pub async fn create(
pool: &Pool<Postgres>,
username: &str,
password: &str,
roles: &Vec<Uuid>,
) -> Result<Self> {
let result = sqlx::query!(
r#"INSERT INTO users ( name, password, roles ) VALUES ( $1,$2,$3 ) RETURNING id, created_at"#,
username,
hash(&password)?,
roles,
)
.fetch_one(pool)
.await?;
Ok(Self {
id: result.id,
name: username.to_owned(),
roles: roles.to_owned(),
created_at: result.created_at,
..Default::default()
})
}
pub async fn get_id(pool: &Pool<Postgres>, id: Uuid) -> Result<Option<Self>> {
Ok(sqlx::query_as("SELECT * FROM users WHERE id = $1")
.bind(id)
.fetch_optional(pool)
.await?)
}
pub async fn find(pool: &Pool<Postgres>, name: &str) -> Result<Option<Self>> {
Ok(sqlx::query_as("SELECT * FROM users WHERE name = $1")
.bind(name)
.fetch_optional(pool)
.await?)
}
}
#[derive(Deserialize, Serialize, FromRow)]
pub struct Role {
/// Role ID
pub id: Uuid,
/// Role scopes (permissions)
pub scopes: Vec<String>,
}