98 lines
2.5 KiB
Rust
98 lines
2.5 KiB
Rust
use std::sync::Arc;
|
|
|
|
use tokio::sync::Mutex;
|
|
use tokio_postgres::{Client, Row};
|
|
|
|
use crate::sec;
|
|
|
|
use super::db;
|
|
|
|
#[derive(Clone)]
|
|
pub struct Users(Arc<Mutex<Client>>);
|
|
|
|
impl Users {
|
|
pub fn new(client: Arc<Mutex<Client>>) -> Self {
|
|
Self(client)
|
|
}
|
|
|
|
pub async fn create_user(&self, u: User) -> Result<User, db::DBError> {
|
|
let row = self.0.lock().await.query_one(
|
|
"insert into users (id, username, host, display_name, password_hash, email) values ($1, $2, $3, $4, $5, $6) returning id",
|
|
&[&sec::new_id(), &u.username, &u.host, &u.display_name, &u.password_hash, &u.email],
|
|
).await?;
|
|
Ok(User {
|
|
id: row.get("id"),
|
|
username: u.username,
|
|
host: u.host,
|
|
display_name: u.display_name,
|
|
password_hash: u.password_hash,
|
|
email: u.email,
|
|
})
|
|
}
|
|
|
|
pub async fn user(&self, by: UserSelect) -> Result<User, db::DBError> {
|
|
let where_param: String;
|
|
let where_clause = match by {
|
|
UserSelect::ID(id) => {
|
|
where_param = id;
|
|
"id = $1"
|
|
}
|
|
UserSelect::Username(username) => {
|
|
where_param = username;
|
|
"username = $1"
|
|
}
|
|
UserSelect::FullUsername(full) => {
|
|
where_param = full;
|
|
"(username || '@' || host) = $1"
|
|
}
|
|
};
|
|
let rows = self
|
|
.0
|
|
.lock()
|
|
.await
|
|
.query(
|
|
format!(
|
|
"select id, username, host, display_name, password_hash, email from users where {}",
|
|
where_clause
|
|
)
|
|
.as_str(),
|
|
&[&where_param],
|
|
)
|
|
.await?;
|
|
|
|
if let Some(row) = rows.first() && rows.len() == 1 {
|
|
Ok(User::from(row))
|
|
} else {
|
|
Err(db::DBError::NotFound)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct User {
|
|
pub id: String,
|
|
pub username: String,
|
|
pub host: Option<String>,
|
|
pub display_name: Option<String>,
|
|
pub password_hash: String,
|
|
pub email: String,
|
|
}
|
|
|
|
impl From<&Row> for User {
|
|
fn from(row: &Row) -> Self {
|
|
Self {
|
|
id: row.get("id"),
|
|
username: row.get("username"),
|
|
host: row.get("host"),
|
|
display_name: row.get("display_name"),
|
|
password_hash: row.get("password_hash"),
|
|
email: row.get("email"),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum UserSelect {
|
|
ID(String),
|
|
Username(String),
|
|
FullUsername(String),
|
|
}
|