blob: 9125ad5f50707e5eb51f393a465ac0ac156dc241 [file]
// Copyright 2022 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![allow(clippy::extra_unused_lifetimes)]
use crate::{
constants,
model::{db::Connection, user_token::UserToken},
schema::users::{self, dsl::*},
utils::bcrypt::{compare_password, hash_password},
};
use axum_macros::FromRequest;
use diesel::prelude::*;
use diesel::QueryDsl;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize, Queryable)]
// #[derive(Identifiable, Queryable, PartialEq, Debug)]
#[diesel(table_name = users)]
pub struct User {
pub id: i32,
pub username: String,
pub email: String,
pub password: String,
pub role: String,
pub login_session: String,
}
#[derive(Insertable, Serialize, Deserialize, AsChangeset, Clone, FromRequest)]
#[table_name = "users"]
pub struct AddUser {
pub username: String,
pub email: String,
pub password: String,
#[serde(default = "default_role")]
pub role: String,
pub login_session: String,
}
fn default_role() -> String {
"patient".to_owned()
}
#[derive(Serialize, Deserialize)]
pub struct LoginForm {
pub email: String,
pub password: String,
}
#[derive(Insertable)]
#[table_name = "users"]
pub struct LoginInfo {
// WILL GET UNIQUE USERNAME BY EMAIL
pub username: String,
pub role: String,
pub login_session: String,
}
impl User {
pub fn register(user: AddUser, conn: &Connection) -> Result<String, String> {
if Self::get_user_by_email(&user.email, conn).is_err() {
let hashed_pwd = hash_password(&user.password).unwrap();
let user_upd = AddUser {
password: hashed_pwd,
..user
};
diesel::insert_into(users)
.values(&user_upd)
.execute(conn)
.map_err(|e| e.to_string())?;
Ok(constants::MESSAGE_SIGNUP_SUCCESS.to_string())
} else {
Err(format!("User {} is already registered", &user.username))
}
}
pub fn update_user(i: i32, user_data: AddUser, conn: &Connection) -> Result<String, String> {
if Self::get_user_by_email(&user_data.email, conn).is_err() {
Err("User is not present".to_string())
} else {
let hashed_pwd = hash_password(&user_data.password).unwrap();
let user_update = AddUser {
password: hashed_pwd,
..user_data
};
diesel::update(users.find(i))
.set(&user_update)
.execute(conn)
.map_err(|e| e.to_string())?;
Ok(constants::MESSAGE_UPDATE_USER_SUCCESS.to_string())
}
}
pub fn get_user(i: i32, conn: &Connection) -> QueryResult<User> {
users.find(i).get_result::<User>(conn)
}
pub fn get_all_user(conn: &Connection) -> QueryResult<Vec<User>> {
users.order(id.asc()).load::<User>(conn)
}
pub fn signin(login: LoginForm, conn: &Connection) -> Option<LoginInfo> {
if let Ok(user_to_verify) = users
.filter(email.eq(&login.email))
.get_result::<User>(conn)
{
if !user_to_verify.password.is_empty()
&& compare_password(&login.password, &user_to_verify.password).unwrap()
{
let login_session_str = User::generate_login_session();
if User::update_login_session_to_db(&user_to_verify.email, &login_session_str, conn)
{
return Some(LoginInfo {
username: user_to_verify.username,
role: user_to_verify.role,
login_session: login_session_str,
});
}
}
}
None
}
pub fn delete_user(delete_id: i32, conn: &Connection) -> QueryResult<usize> {
diesel::delete(users.filter(users::id.eq(delete_id))).execute(conn)
}
pub fn update_login_session_to_db(
eml: &str,
login_session_str: &str,
conn: &Connection,
) -> bool {
if let Ok(user) = User::get_user_by_email(eml, conn) {
diesel::update(users.find(user.id))
.set(login_session.eq(login_session_str.to_string()))
.execute(conn)
.is_ok()
} else {
false
}
}
pub fn is_valid_login_session(user_token: &UserToken, conn: &Connection) -> bool {
users
.filter(username.eq(&user_token.user_name))
.filter(login_session.eq(&user_token.login_session))
.get_result::<User>(conn)
.is_ok()
}
pub fn get_user_by_email(eml: &str, conn: &Connection) -> QueryResult<User> {
users.filter(email.eq(eml)).get_result::<User>(conn)
}
pub fn generate_login_session() -> String {
Uuid::new_v4().simple().to_string()
}
}