user update
This commit is contained in:
parent
d7a55f6579
commit
e5fe40e4be
8 changed files with 205 additions and 77 deletions
|
@ -3,9 +3,11 @@ use serde::{Deserialize, Serialize};
|
|||
use serde_json::json;
|
||||
use sqlx::FromRow;
|
||||
|
||||
use super::{Session, gen_token};
|
||||
use super::Sessions;
|
||||
use crate::{get_pg, request::api::ToAPI};
|
||||
|
||||
// TODO : 2FA
|
||||
|
||||
/// User
|
||||
///
|
||||
/// # Example:
|
||||
|
@ -27,7 +29,7 @@ pub struct User {
|
|||
/// The role of the user
|
||||
pub user_role: UserRole,
|
||||
#[sqlx(default)]
|
||||
pub session: String
|
||||
pub session: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::Type)]
|
||||
|
@ -40,18 +42,6 @@ pub enum UserRole {
|
|||
}
|
||||
|
||||
impl User {
|
||||
// Get a user from session ID
|
||||
pub async fn from_session(session: &str) -> Option<Self> {
|
||||
let user: Option<Self> = sqlx::query_as("SELECT * FROM users WHERE username = (SELECT \"user\" FROM user_session WHERE token = $1)").bind(session).fetch_optional(get_pg!()).await.unwrap();
|
||||
|
||||
if let Some(mut user) = user {
|
||||
user.session = session.to_string();
|
||||
return Some(user);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Find a user by their username
|
||||
pub async fn find(username: &str) -> Option<Self> {
|
||||
sqlx::query_as("SELECT * FROM users WHERE username = $1")
|
||||
|
@ -74,6 +64,7 @@ impl User {
|
|||
username: username.to_string(),
|
||||
password: bcrypt::hash(password, bcrypt::DEFAULT_COST).unwrap(),
|
||||
user_role: role,
|
||||
session: String::new(),
|
||||
};
|
||||
|
||||
sqlx::query("INSERT INTO users (username, \"password\", user_role) VALUES ($1, $2, $3)")
|
||||
|
@ -87,17 +78,6 @@ impl User {
|
|||
Some(u)
|
||||
}
|
||||
|
||||
/// Login a user with the given username and password
|
||||
pub async fn login(username: &str, password: &str) -> Option<(Session, UserRole)> {
|
||||
let u = Self::find(username).await?;
|
||||
|
||||
if !u.verify_pw(password) {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((u.session().await, u.user_role))
|
||||
}
|
||||
|
||||
/// Change the password of a User
|
||||
///
|
||||
/// Returns a Result indicating whether the password change was successful or not
|
||||
|
@ -124,20 +104,6 @@ impl User {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
/// Generate a new session token for the user
|
||||
///
|
||||
/// Returns a Session instance containing the generated token and associated user
|
||||
pub async fn session(&self) -> Session {
|
||||
sqlx::query_as(
|
||||
"INSERT INTO user_session (token, \"user\") VALUES ($1, $2) RETURNING id, token, \"user\"",
|
||||
)
|
||||
.bind(gen_token(64))
|
||||
.bind(&self.username)
|
||||
.fetch_one(get_pg!())
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Check if the user is an admin
|
||||
pub const fn is_admin(&self) -> bool {
|
||||
matches!(self.user_role, UserRole::Admin)
|
||||
|
@ -160,6 +126,7 @@ impl ToAPI for User {
|
|||
}
|
||||
}
|
||||
|
||||
/// extracts a user from a request with `session` cookie
|
||||
async fn extract_user<'r>(request: &'r Request<'_>) -> Option<User> {
|
||||
if let Some(session_id) = request.cookies().get("session") {
|
||||
if let Some(user) = User::from_session(session_id.value()).await {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue