chore: normalize code #2
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
use crate::{AppState, MetaRequestDto, v1::users_service::UsersService};
|
||||
use crate::{
|
||||
MessageResponseDto, PermissionsEnum, ResponseListSuccessDto, ResponseSuccessDto,
|
||||
UsersCreateRequestDto, UsersDetailItemDto, permissions_guard,
|
||||
};
|
||||
use axum::extract::{Path, Query};
|
||||
use axum::http::HeaderMap;
|
||||
use axum::response::IntoResponse;
|
||||
use axum::{Extension, Json};
|
||||
|
||||
use crate::{
|
||||
permissions_guard, MessageResponseDto, PermissionsEnum, ResponseListSuccessDto,
|
||||
ResponseSuccessDto, UsersActiveInactiveRequestDto, UsersCreateRequestDto,
|
||||
UsersDetailItemDto,
|
||||
use super::{
|
||||
UsersActiveInactiveRequestDto, UsersListItemDto, UsersUpdateRequestDto,
|
||||
};
|
||||
use crate::{v1::users_service::UsersService, AppState, MetaRequestDto};
|
||||
|
||||
use super::{UsersListItemDto, UsersUpdateRequestDto};
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
@@ -204,7 +204,7 @@ pub async fn patch_user_active_status(
|
||||
match permissions_guard(
|
||||
&headers,
|
||||
state.clone(),
|
||||
vec![PermissionsEnum::UpdateUsers],
|
||||
vec![PermissionsEnum::ActivateUsers],
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{RolesDetailQueryDto, RolesItemDto};
|
||||
use crate::{RolesDetailItemDto, RolesDetailQueryDto};
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -10,6 +10,17 @@ lazy_static! {
|
||||
static ref PASSWORD_REGEX: Regex = Regex::new(r"^[A-Za-z\d@$!%*?&]{8,}$").unwrap();
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct UsersActiveInactiveRequestDto {
|
||||
pub is_active: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct UsersSetNewPasswordRequestDto {
|
||||
pub password: String,
|
||||
pub old_password: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct UsersCreateRequestDto {
|
||||
#[validate(
|
||||
@@ -71,7 +82,7 @@ pub struct UsersUpdateRequestDto {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct UsersDetailItemDto {
|
||||
pub id: String,
|
||||
pub role: RolesItemDto,
|
||||
pub role: RolesDetailItemDto,
|
||||
pub fullname: String,
|
||||
pub email: String,
|
||||
pub avatar: Option<String>,
|
||||
@@ -83,6 +94,24 @@ pub struct UsersDetailItemDto {
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
impl UsersDetailItemDto {
|
||||
pub fn from(dto: UsersDetailQueryDto) -> Self {
|
||||
Self {
|
||||
id: dto.id.id.to_raw(),
|
||||
role: RolesDetailItemDto::from(&dto.role),
|
||||
fullname: dto.fullname,
|
||||
email: dto.email,
|
||||
avatar: dto.avatar,
|
||||
phone_number: dto.phone_number,
|
||||
is_active: dto.is_active,
|
||||
gender: dto.gender,
|
||||
birthdate: dto.birthdate,
|
||||
created_at: dto.created_at,
|
||||
updated_at: dto.updated_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct UsersListItemDto {
|
||||
pub id: String,
|
||||
@@ -110,7 +139,7 @@ pub struct UsersListQueryDto {
|
||||
}
|
||||
|
||||
impl UsersListQueryDto {
|
||||
pub fn list_from(&self, role: String) -> UsersListItemDto {
|
||||
pub fn from(&self, role: String) -> UsersListItemDto {
|
||||
UsersListItemDto {
|
||||
id: self.id.id.to_raw(),
|
||||
role,
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
use super::{UsersDetailQueryDto, UsersListItemDto, UsersListQueryDto, UsersSchema};
|
||||
use crate::{
|
||||
AppState, MetaRequestDto, PermissionsItemDto, PermissionsItemDtoRaw, ResourceEnum,
|
||||
ResponseListSuccessDto, RolesDetailQueryDto, extract_id, get_id, make_thing,
|
||||
AppState, MetaRequestDto, PermissionsQueryDto, ResourceEnum,
|
||||
ResponseListSuccessDto, RolesDetailQueryDto, get_id, make_thing,
|
||||
query_list_with_meta,
|
||||
};
|
||||
use anyhow::{Result, bail};
|
||||
use imphnen_utils::DetailQueryBuilder;
|
||||
use surrealdb::{Surreal, engine::remote::ws::Client};
|
||||
|
||||
pub struct UsersRepository<'a> {
|
||||
state: &'a AppState,
|
||||
}
|
||||
|
||||
pub fn build_user_by_field_query(field: &str) -> String {
|
||||
format!(
|
||||
r#"
|
||||
SELECT *, role AS role
|
||||
FROM {}
|
||||
WHERE {} = $value AND is_deleted = false
|
||||
LIMIT 1
|
||||
FETCH role, role.permissions
|
||||
"#,
|
||||
ResourceEnum::Users.to_string(),
|
||||
field
|
||||
)
|
||||
pub async fn update_partial_schema(
|
||||
db: &Surreal<Client>,
|
||||
table: &str,
|
||||
id: &str,
|
||||
patch: UsersSchema,
|
||||
) -> Result<String> {
|
||||
let thing = make_thing(table, id);
|
||||
let record_key = get_id(&thing)?;
|
||||
let result: Option<UsersSchema> = db.update(record_key).merge(patch).await?;
|
||||
match result {
|
||||
Some(_) => Ok("Success update".into()),
|
||||
None => bail!("Failed to update"),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> UsersRepository<'a> {
|
||||
@@ -59,7 +62,7 @@ impl<'a> UsersRepository<'a> {
|
||||
.into_iter()
|
||||
.map(|schema| {
|
||||
let role = schema.clone().role.name;
|
||||
schema.list_from(role)
|
||||
schema.from(role)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -75,13 +78,31 @@ impl<'a> UsersRepository<'a> {
|
||||
) -> Result<UsersDetailQueryDto> {
|
||||
let db = &self.state.surrealdb_ws;
|
||||
|
||||
let sql = build_user_by_field_query("email");
|
||||
let builder = DetailQueryBuilder::new(ResourceEnum::Users.to_string())
|
||||
.with_where("email")
|
||||
.where_value(email.clone())
|
||||
.with_select_fields(vec![
|
||||
"id",
|
||||
"fullname",
|
||||
"email",
|
||||
"avatar",
|
||||
"phone_number",
|
||||
"is_active",
|
||||
"is_deleted",
|
||||
"gender",
|
||||
"birthdate",
|
||||
"password",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"role",
|
||||
])
|
||||
.with_fetch("role")
|
||||
.with_fetch("role.permissions");
|
||||
|
||||
let user_opt: Option<UsersDetailQueryDto> = db
|
||||
.query(sql)
|
||||
.bind(("email", email.clone()))
|
||||
.await?
|
||||
.take(0)?;
|
||||
let sql = builder.build();
|
||||
|
||||
let user_opt: Option<UsersDetailQueryDto> =
|
||||
builder.apply_bindings(db.query(sql)).await?.take(0)?;
|
||||
|
||||
let Some(user) = user_opt else {
|
||||
bail!("User not found");
|
||||
@@ -95,7 +116,7 @@ impl<'a> UsersRepository<'a> {
|
||||
.role
|
||||
.permissions
|
||||
.into_iter()
|
||||
.map(|perm| PermissionsItemDtoRaw {
|
||||
.map(|perm| PermissionsQueryDto {
|
||||
id: perm.id,
|
||||
name: perm.name,
|
||||
created_at: perm.created_at,
|
||||
@@ -130,15 +151,32 @@ impl<'a> UsersRepository<'a> {
|
||||
pub async fn query_user_by_id(&self, id: String) -> Result<UsersDetailQueryDto> {
|
||||
let db = &self.state.surrealdb_ws;
|
||||
|
||||
let sql = build_user_by_field_query(&make_thing("app_users", &id).to_raw());
|
||||
let builder = DetailQueryBuilder::new(ResourceEnum::Users.to_string())
|
||||
.with_id(&id)
|
||||
.with_select_fields(vec![
|
||||
"id",
|
||||
"fullname",
|
||||
"email",
|
||||
"avatar",
|
||||
"phone_number",
|
||||
"is_active",
|
||||
"is_deleted",
|
||||
"gender",
|
||||
"birthdate",
|
||||
"password",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"role",
|
||||
])
|
||||
.with_fetch("role")
|
||||
.with_fetch("role.permissions");
|
||||
|
||||
let user_opt: Option<UsersDetailQueryDto> = db
|
||||
.query(sql)
|
||||
.bind(("email", make_thing("app_users", &id).to_raw()))
|
||||
.await?
|
||||
.take(0)?;
|
||||
let sql = builder.build();
|
||||
|
||||
let Some(user) = user_opt else {
|
||||
let result: Option<UsersDetailQueryDto> =
|
||||
builder.apply_bindings(db.query(sql)).await?.take(0)?;
|
||||
|
||||
let Some(user) = result else {
|
||||
bail!("User not found");
|
||||
};
|
||||
|
||||
@@ -150,7 +188,7 @@ impl<'a> UsersRepository<'a> {
|
||||
.role
|
||||
.permissions
|
||||
.into_iter()
|
||||
.map(|perm| PermissionsItemDtoRaw {
|
||||
.map(|perm| PermissionsQueryDto {
|
||||
id: perm.id,
|
||||
name: perm.name,
|
||||
created_at: perm.created_at,
|
||||
@@ -201,10 +239,15 @@ impl<'a> UsersRepository<'a> {
|
||||
if existing.is_deleted {
|
||||
bail!("User already deleted");
|
||||
}
|
||||
let role_thing = if data.role == existing.role.id {
|
||||
existing.role.id
|
||||
} else {
|
||||
data.clone().role
|
||||
};
|
||||
let merged = UsersSchema {
|
||||
password: existing.password,
|
||||
created_at: existing.created_at,
|
||||
role: make_thing("app_roles", &existing.role.id),
|
||||
role: role_thing,
|
||||
..data.clone()
|
||||
};
|
||||
let record: Option<UsersSchema> = db.update(record_key).merge(merged).await?;
|
||||
@@ -214,76 +257,13 @@ impl<'a> UsersRepository<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn query_active_inactive_user(
|
||||
&self,
|
||||
email: String,
|
||||
data: UsersActiveInactiveSchema,
|
||||
) -> Result<String> {
|
||||
pub async fn query_delete_user(&self, id: String) -> Result<String> {
|
||||
let db = &self.state.surrealdb_ws;
|
||||
let user = self.query_user_by_email(email.clone()).await?;
|
||||
let user = self.query_user_by_id(id).await?;
|
||||
if user.is_deleted {
|
||||
bail!("User already deleted");
|
||||
}
|
||||
let record_key = get_id(&user.id)?;
|
||||
let record: Option<UsersSchema> = db
|
||||
.update(record_key)
|
||||
.merge(UsersActiveInactiveSchema {
|
||||
is_active: data.is_active,
|
||||
})
|
||||
.await?;
|
||||
match record {
|
||||
Some(_) => Ok("Success update user".into()),
|
||||
None => bail!("Failed to update user"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn query_active_inactive_user_by_id(
|
||||
&self,
|
||||
id: String,
|
||||
data: UsersActiveInactiveSchema,
|
||||
) -> Result<String> {
|
||||
let db = &self.state.surrealdb_ws;
|
||||
let record: Option<UsersSchema> = db
|
||||
.update((ResourceEnum::Users.to_string(), id))
|
||||
.merge(UsersActiveInactiveSchema {
|
||||
is_active: data.is_active,
|
||||
})
|
||||
.await?;
|
||||
match record {
|
||||
Some(_) => Ok("Success update user".into()),
|
||||
None => bail!("Failed to update user"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn query_update_password_user(
|
||||
&self,
|
||||
email: String,
|
||||
data: UsersSetNewPasswordSchema,
|
||||
) -> Result<String> {
|
||||
let db = &self.state.surrealdb_ws;
|
||||
let user = self.query_user_by_email(email).await?;
|
||||
let record: Option<UsersSetNewPasswordSchema> = db
|
||||
.update((ResourceEnum::Users.to_string(), user.id.id.to_raw()))
|
||||
.merge(UsersSetNewPasswordSchema {
|
||||
password: data.password.clone(),
|
||||
})
|
||||
.await?;
|
||||
dbg!(record.clone());
|
||||
match record {
|
||||
Some(_) => Ok("Success update password user".into()),
|
||||
None => bail!("Failed to update password user"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn query_delete_user(&self, id: String) -> Result<String> {
|
||||
let db = &self.state.surrealdb_ws;
|
||||
let user_id = make_thing(&ResourceEnum::Users.to_string(), &id);
|
||||
let user = self.query_user_by_id(user_id.id.to_raw()).await?;
|
||||
if user.is_deleted {
|
||||
bail!("User already deleted");
|
||||
}
|
||||
let id = make_thing(&ResourceEnum::Users.to_string(), &user.id);
|
||||
let record_key = get_id(&id)?;
|
||||
let record: Option<UsersSchema> = db
|
||||
.update(record_key)
|
||||
.merge(serde_json::json!({ "is_deleted": true }))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::{UsersDetailItemDto, UsersListItemDto};
|
||||
use crate::RolesItemDto;
|
||||
use imphnen_utils::Crud;
|
||||
use super::{UsersCreateRequestDto, UsersDetailQueryDto, UsersUpdateRequestDto};
|
||||
use imphnen_libs::{ResourceEnum, hash_password};
|
||||
use imphnen_utils::{get_iso_date, make_thing};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use surrealdb::sql::Thing;
|
||||
use surrealdb::{Uuid, sql::Thing};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct UsersSchema {
|
||||
@@ -21,46 +21,89 @@ pub struct UsersSchema {
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
impl Crud<UsersListItemDto, String> for UsersSchema {
|
||||
fn list(&self, role: String) -> UsersListItemDto {
|
||||
UsersListItemDto {
|
||||
id: self.id.id.to_raw(),
|
||||
role,
|
||||
fullname: self.fullname.clone(),
|
||||
email: self.email.clone(),
|
||||
avatar: self.avatar.clone(),
|
||||
phone_number: self.phone_number.clone(),
|
||||
is_active: self.is_active,
|
||||
created_at: self.created_at.clone(),
|
||||
updated_at: self.updated_at.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Crud<UsersDetailItemDto, RolesItemDto> for UsersSchema {
|
||||
fn detail(&self, role: RolesItemDto) -> UsersDetailItemDto {
|
||||
UsersDetailItemDto {
|
||||
id: self.id.id.to_raw(),
|
||||
role,
|
||||
fullname: self.fullname.clone(),
|
||||
email: self.email.clone(),
|
||||
avatar: self.avatar.clone(),
|
||||
phone_number: self.phone_number.clone(),
|
||||
is_active: self.is_active,
|
||||
gender: self.gender.clone(),
|
||||
birthdate: self.birthdate.clone(),
|
||||
created_at: self.created_at.clone(),
|
||||
updated_at: self.updated_at.clone(),
|
||||
impl Default for UsersSchema {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
id: Thing::from(("app_users", "dummy")),
|
||||
fullname: "".into(),
|
||||
email: "".into(),
|
||||
password: "".into(),
|
||||
avatar: None,
|
||||
phone_number: "".into(),
|
||||
is_active: false,
|
||||
is_deleted: false,
|
||||
gender: None,
|
||||
birthdate: None,
|
||||
role: Thing::from(("app_roles", "dummy")),
|
||||
created_at: "".into(),
|
||||
updated_at: "".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UsersSchema {
|
||||
pub fn list_from(&self, role: String) -> UsersListItemDto {
|
||||
self.list(role)
|
||||
pub fn from(dto: UsersDetailQueryDto) -> Self {
|
||||
Self {
|
||||
id: dto.id,
|
||||
fullname: dto.fullname,
|
||||
email: dto.email,
|
||||
avatar: dto.avatar,
|
||||
phone_number: dto.phone_number,
|
||||
is_active: dto.is_active,
|
||||
is_deleted: dto.is_deleted,
|
||||
gender: dto.gender,
|
||||
birthdate: dto.birthdate,
|
||||
password: dto.password,
|
||||
created_at: dto.created_at,
|
||||
updated_at: dto.updated_at,
|
||||
role: make_thing(&ResourceEnum::Roles.to_string(), &dto.role.id.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn detail_from(&self, role: RolesItemDto) -> UsersDetailItemDto {
|
||||
self.detail(role)
|
||||
pub fn update(user: UsersUpdateRequestDto, id: String) -> Self {
|
||||
Self {
|
||||
id: make_thing(&ResourceEnum::Users.to_string(), &id),
|
||||
fullname: user.fullname,
|
||||
email: user.email,
|
||||
phone_number: user.phone_number,
|
||||
is_active: user.is_active,
|
||||
gender: user.gender,
|
||||
birthdate: user.birthdate,
|
||||
avatar: user.avatar,
|
||||
is_deleted: false,
|
||||
role: make_thing(&ResourceEnum::Roles.to_string(), &user.role_id),
|
||||
updated_at: get_iso_date(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(user: UsersCreateRequestDto) -> Self {
|
||||
let password = hash_password(&user.password).unwrap();
|
||||
Self {
|
||||
id: make_thing(
|
||||
&ResourceEnum::Users.to_string(),
|
||||
&Uuid::new_v4().to_string(),
|
||||
),
|
||||
fullname: user.fullname,
|
||||
email: user.email,
|
||||
password,
|
||||
phone_number: user.phone_number,
|
||||
is_active: false,
|
||||
gender: None,
|
||||
birthdate: None,
|
||||
avatar: None,
|
||||
is_deleted: false,
|
||||
role: make_thing(&ResourceEnum::Roles.to_string(), &user.role_id),
|
||||
created_at: get_iso_date(),
|
||||
updated_at: get_iso_date(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn patch_password(dto: UsersDetailQueryDto, password: String) -> Self {
|
||||
Self {
|
||||
password,
|
||||
id: dto.id.clone(),
|
||||
..Self::from(dto)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
use crate::{
|
||||
common_response, extract_email, get_iso_date, hash_password, make_thing,
|
||||
success_list_response, success_response, validate_request, ResourceEnum,
|
||||
ResponseSuccessDto,
|
||||
use super::{
|
||||
UsersActiveInactiveRequestDto, UsersCreateRequestDto, UsersDetailItemDto,
|
||||
UsersSetNewPasswordRequestDto, UsersUpdateRequestDto,
|
||||
};
|
||||
use crate::{
|
||||
AppState, MetaRequestDto, ResponseListSuccessDto, UsersActiveInactiveSchema,
|
||||
UsersRepository, UsersSchema, UsersSetNewPasswordSchema,
|
||||
AppState, MetaRequestDto, ResponseListSuccessDto, UsersRepository, UsersSchema,
|
||||
};
|
||||
use crate::{
|
||||
ResourceEnum, ResponseSuccessDto, common_response, extract_email, make_thing,
|
||||
success_list_response, success_response, validate_request,
|
||||
};
|
||||
use axum::http::HeaderMap;
|
||||
use axum::{http::StatusCode, response::Response};
|
||||
|
||||
use super::{
|
||||
UsersActiveInactiveRequestDto, UsersCreateRequestDto, UsersDetailItemDto,
|
||||
UsersUpdateRequestDto,
|
||||
};
|
||||
use imphnen_libs::{hash_password, verify_password};
|
||||
|
||||
pub struct UsersService;
|
||||
|
||||
@@ -36,17 +34,7 @@ impl UsersService {
|
||||
let repo = UsersRepository::new(state);
|
||||
match repo.query_user_by_id(id).await {
|
||||
Ok(user) if !user.is_deleted => success_response(ResponseSuccessDto {
|
||||
data: UsersDetailItemDto {
|
||||
id: user.id,
|
||||
role: user.role,
|
||||
fullname: user.fullname,
|
||||
email: user.email,
|
||||
avatar: user.avatar,
|
||||
phone_number: user.phone_number,
|
||||
is_active: user.is_active,
|
||||
gender: user.gender,
|
||||
birthdate: user.birthdate,
|
||||
},
|
||||
data: UsersDetailItemDto::from(user),
|
||||
}),
|
||||
Ok(_) => common_response(StatusCode::NOT_FOUND, "User not found"),
|
||||
Err(e) => common_response(StatusCode::NOT_FOUND, &e.to_string()),
|
||||
@@ -55,22 +43,15 @@ impl UsersService {
|
||||
|
||||
pub async fn get_user_me(headers: HeaderMap, state: &AppState) -> Response {
|
||||
let repo = UsersRepository::new(state);
|
||||
let email = extract_email(&headers).unwrap();
|
||||
let user = repo.query_user_by_email(email).await.unwrap();
|
||||
match repo.query_user_by_id(user.id.id.to_raw()).await {
|
||||
Ok(user) => success_response(ResponseSuccessDto {
|
||||
data: UsersDetailItemDto {
|
||||
id: user.id,
|
||||
role: user.role,
|
||||
fullname: user.fullname,
|
||||
email: user.email,
|
||||
avatar: user.avatar,
|
||||
phone_number: user.phone_number,
|
||||
is_active: user.is_active,
|
||||
gender: user.gender,
|
||||
birthdate: user.birthdate,
|
||||
},
|
||||
let email = match extract_email(&headers) {
|
||||
Some(email) => email,
|
||||
None => return common_response(StatusCode::UNAUTHORIZED, "Invalid token"),
|
||||
};
|
||||
match repo.query_user_by_email(email).await {
|
||||
Ok(user) if !user.is_deleted => success_response(ResponseSuccessDto {
|
||||
data: UsersDetailItemDto::from(user),
|
||||
}),
|
||||
Ok(_) => common_response(StatusCode::NOT_FOUND, "User not found"),
|
||||
Err(e) => common_response(StatusCode::NOT_FOUND, &e.to_string()),
|
||||
}
|
||||
}
|
||||
@@ -90,19 +71,7 @@ impl UsersService {
|
||||
{
|
||||
return common_response(StatusCode::BAD_REQUEST, "User already exists");
|
||||
}
|
||||
let role_thing = make_thing(&ResourceEnum::Roles.to_string(), &new_user.role_id);
|
||||
match repo
|
||||
.query_create_user(UsersSchema {
|
||||
email: new_user.email.clone(),
|
||||
fullname: new_user.fullname.clone(),
|
||||
password: hash_password(&new_user.password).unwrap(),
|
||||
phone_number: new_user.phone_number.clone(),
|
||||
is_active: new_user.is_active.clone(),
|
||||
role: role_thing,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
{
|
||||
match repo.query_create_user(UsersSchema::create(new_user)).await {
|
||||
Ok(msg) => common_response(StatusCode::CREATED, &msg),
|
||||
Err(err) => {
|
||||
common_response(StatusCode::INTERNAL_SERVER_ERROR, &err.to_string())
|
||||
@@ -116,28 +85,10 @@ impl UsersService {
|
||||
user: UsersUpdateRequestDto,
|
||||
) -> Response {
|
||||
let repo = UsersRepository::new(state);
|
||||
|
||||
if let Err((status, message)) = validate_request(&user) {
|
||||
return common_response(status, &message);
|
||||
}
|
||||
|
||||
let user_id = make_thing(&ResourceEnum::Users.to_string(), &id);
|
||||
let role_id = make_thing(&ResourceEnum::Roles.to_string(), "");
|
||||
|
||||
let updated_user = UsersSchema {
|
||||
id: user_id,
|
||||
fullname: user.fullname,
|
||||
email: user.email,
|
||||
phone_number: user.phone_number,
|
||||
is_active: user.is_active,
|
||||
gender: user.gender,
|
||||
birthdate: user.birthdate,
|
||||
avatar: user.avatar,
|
||||
role: role_id,
|
||||
updated_at: get_iso_date(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let updated_user = UsersSchema::update(user, id);
|
||||
match repo.query_update_user(updated_user).await {
|
||||
Ok(msg) => common_response(StatusCode::OK, &msg),
|
||||
Err(e) => common_response(StatusCode::BAD_REQUEST, &e.to_string()),
|
||||
@@ -150,30 +101,18 @@ impl UsersService {
|
||||
user: UsersUpdateRequestDto,
|
||||
) -> Response {
|
||||
let repo = UsersRepository::new(state);
|
||||
let email = extract_email(&headers).unwrap();
|
||||
let user_data = repo.query_user_by_email(email).await.unwrap();
|
||||
let email = match extract_email(&headers) {
|
||||
Some(email) => email,
|
||||
None => return common_response(StatusCode::UNAUTHORIZED, "Unauthorized"),
|
||||
};
|
||||
let user_data = match repo.query_user_by_email(email.clone()).await {
|
||||
Ok(user) => user,
|
||||
Err(_) => return common_response(StatusCode::NOT_FOUND, "User not found"),
|
||||
};
|
||||
if let Err((status, message)) = validate_request(&user) {
|
||||
return common_response(status, &message);
|
||||
}
|
||||
let user_id =
|
||||
make_thing(&ResourceEnum::Users.to_string(), &user_data.id.id.to_raw());
|
||||
let role_id = make_thing(&ResourceEnum::Roles.to_string(), "");
|
||||
let updated_user = UsersSchema {
|
||||
id: user_id,
|
||||
fullname: user.fullname,
|
||||
email: user.email,
|
||||
phone_number: user.phone_number,
|
||||
|
||||
is_active: user.is_active,
|
||||
|
||||
gender: user.gender,
|
||||
birthdate: user.birthdate,
|
||||
avatar: user.avatar,
|
||||
|
||||
role: role_id,
|
||||
updated_at: get_iso_date(),
|
||||
..Default::default()
|
||||
};
|
||||
let updated_user = UsersSchema::update(user, user_data.id.id.to_raw());
|
||||
match repo.query_update_user(updated_user).await {
|
||||
Ok(msg) => common_response(StatusCode::OK, &msg),
|
||||
Err(e) => common_response(StatusCode::BAD_REQUEST, &e.to_string()),
|
||||
@@ -183,23 +122,23 @@ impl UsersService {
|
||||
pub async fn set_user_active_status(
|
||||
state: &AppState,
|
||||
id: String,
|
||||
status: UsersActiveInactiveRequestDto,
|
||||
payload: UsersActiveInactiveRequestDto,
|
||||
) -> Response {
|
||||
let repo = UsersRepository::new(state);
|
||||
let thing_id = make_thing(&ResourceEnum::Users.to_string(), &id);
|
||||
match repo.query_user_by_id(thing_id.id.to_raw()).await {
|
||||
Ok(_) => match repo
|
||||
.query_active_inactive_user_by_id(
|
||||
id,
|
||||
UsersActiveInactiveSchema {
|
||||
is_active: status.is_active,
|
||||
},
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(msg) => common_response(StatusCode::OK, &msg),
|
||||
Err(e) => common_response(StatusCode::BAD_REQUEST, &e.to_string()),
|
||||
},
|
||||
Ok(user) if !user.is_deleted => {
|
||||
let patch = UsersSchema {
|
||||
id: user.id.clone(),
|
||||
is_active: payload.is_active,
|
||||
..UsersSchema::from(user)
|
||||
};
|
||||
match repo.query_update_user(patch).await {
|
||||
Ok(msg) => common_response(StatusCode::OK, &msg),
|
||||
Err(e) => common_response(StatusCode::BAD_REQUEST, &e.to_string()),
|
||||
}
|
||||
}
|
||||
Ok(_) => common_response(StatusCode::NOT_FOUND, "User not found"),
|
||||
Err(err) => common_response(StatusCode::BAD_REQUEST, &err.to_string()),
|
||||
}
|
||||
}
|
||||
@@ -207,10 +146,41 @@ impl UsersService {
|
||||
pub async fn update_user_password(
|
||||
state: &AppState,
|
||||
email: String,
|
||||
new_password: UsersSetNewPasswordSchema,
|
||||
payload: UsersSetNewPasswordRequestDto,
|
||||
) -> Response {
|
||||
let repo = UsersRepository::new(state);
|
||||
match repo.query_update_password_user(email, new_password).await {
|
||||
let user = match repo.query_user_by_email(email.clone()).await {
|
||||
Ok(user) if !user.is_deleted => user,
|
||||
_ => return common_response(StatusCode::NOT_FOUND, "User not found"),
|
||||
};
|
||||
let verify_result = match verify_password(&payload.old_password, &user.password)
|
||||
{
|
||||
Ok(result) => result,
|
||||
Err(_) => {
|
||||
return common_response(
|
||||
StatusCode::BAD_REQUEST,
|
||||
"Old password is incorrect",
|
||||
);
|
||||
}
|
||||
};
|
||||
if !verify_result {
|
||||
return common_response(StatusCode::BAD_REQUEST, "Old password is incorrect");
|
||||
}
|
||||
let new_password = match hash_password(&payload.password) {
|
||||
Ok(pw) => pw,
|
||||
Err(_) => {
|
||||
return common_response(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to hash password",
|
||||
);
|
||||
}
|
||||
};
|
||||
let patch = UsersSchema {
|
||||
id: user.id.clone(),
|
||||
password: new_password,
|
||||
..Default::default()
|
||||
};
|
||||
match repo.query_update_user(patch).await {
|
||||
Ok(msg) => common_response(StatusCode::OK, &msg),
|
||||
Err(e) => common_response(StatusCode::BAD_REQUEST, &e.to_string()),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user