Refactor permissions and user DTOs to use imphnen_entities module
- Updated permissions_repository.rs to import PermissionsItemDto from imphnen_entities. - Modified permissions_schema.rs to import PermissionsItemDto and PermissionsQueryDto from imphnen_entities. - Changed roles_dto.rs to import PermissionsItemDto and PermissionsQueryDto from imphnen_entities. - Updated users_dto.rs to import ExperienceDto, EducationDto, UsersDetailQueryDto, RolesDetailQueryDto, and RolesDetailItemDto from imphnen_entities, and removed redundant struct definitions. - Refactored users_repository.rs to import UsersDetailQueryDto from imphnen_entities. - Updated users_schema.rs to import UsersDetailQueryDto, ExperienceDto, and EducationDto from imphnen_entities. - Modified users_service.rs to use UsersDetailQueryDto from imphnen_entities and added UserLookupService implementation. - Updated Cargo.toml in imphnen-libs to include async-trait as a workspace dependency. - Refactored axum module to remove redundant imports and streamline code. - Updated lib.rs to include AppState struct with user_lookup_service and auth_repository fields. - Refactored surrealdb module to define SurrealWsClient and SurrealMemClient types. - Removed imphnen-iam dependency from middleware's Cargo.toml. - Updated auth_middleware to use UsersDetailQueryDto from imphnen_entities and refactored user retrieval logic. - Refactored permissions_middleware to use PermissionsEnum from imphnen_entities and updated user retrieval logic. - Updated mock_test.rs to create AppState with user_lookup_service and auth_repository. - Added permissions.rs and users.rs to imphnen_entities with necessary DTOs and enums. - Created services.rs in imphnen-libs to define UserLookupService and AuthRepositoryTrait traits.
This commit is contained in:
@@ -1,22 +1,24 @@
|
||||
use super::AuthOtpSchema;
|
||||
use super::UserCacheSchema;
|
||||
use crate::{
|
||||
AppState, PermissionsQueryDto, ResourceEnum, RolesDetailQueryDto,
|
||||
UsersDetailQueryDto,
|
||||
};
|
||||
use imphnen_entities::{PermissionsQueryDto, RolesDetailQueryDto, UsersDetailQueryDto};
|
||||
use crate::ResourceEnum;
|
||||
use anyhow::{Result, anyhow, bail};
|
||||
use chrono::{Duration, Utc};
|
||||
use surrealdb::sql::Thing;
|
||||
use tracing::instrument;
|
||||
use tracing::info;
|
||||
use async_trait::async_trait;
|
||||
use imphnen_libs::AuthRepositoryTrait;
|
||||
use imphnen_libs::SurrealMemClient;
|
||||
|
||||
pub struct AuthRepository<'a> {
|
||||
pub state: &'a AppState,
|
||||
|
||||
pub struct AuthRepository {
|
||||
pub db: SurrealMemClient,
|
||||
}
|
||||
|
||||
impl<'a> AuthRepository<'a> {
|
||||
pub fn new(state: &'a AppState) -> Self {
|
||||
Self { state }
|
||||
impl AuthRepository {
|
||||
pub fn new(db: SurrealMemClient) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
|
||||
#[instrument(skip(self, user), err)]
|
||||
@@ -35,15 +37,13 @@ impl<'a> AuthRepository<'a> {
|
||||
|
||||
info!(query = %format!("DELETE FROM {} WHERE id = '{}'", table, user_id), "Executing SurrealDB query");
|
||||
let _record: Option<UserCacheSchema> = self
|
||||
.state
|
||||
.surrealdb_mem
|
||||
.db
|
||||
.delete::<Option<UserCacheSchema>>((table.clone(), user_id.clone()))
|
||||
.await?;
|
||||
|
||||
info!(query = %format!("CREATE {}:{}", table, user_id), "Executing SurrealDB query");
|
||||
let record: Option<UserCacheSchema> = self
|
||||
.state
|
||||
.surrealdb_mem
|
||||
.db
|
||||
.create((table, user_id))
|
||||
.content(user_cache)
|
||||
.await?;
|
||||
@@ -61,8 +61,7 @@ impl<'a> AuthRepository<'a> {
|
||||
) -> Result<UsersDetailQueryDto> {
|
||||
info!(query = %format!("SELECT FROM {} WHERE id = '{}'", ResourceEnum::UsersCache.to_string(), email), "Executing SurrealDB query");
|
||||
let user_cache: Option<UserCacheSchema> = self
|
||||
.state
|
||||
.surrealdb_mem
|
||||
.db
|
||||
.select((ResourceEnum::UsersCache.to_string(), email.clone()))
|
||||
.await?;
|
||||
|
||||
@@ -132,8 +131,7 @@ impl<'a> AuthRepository<'a> {
|
||||
pub async fn query_delete_stored_user(&self, email: String) -> Result<String> {
|
||||
info!(query = %format!("DELETE FROM {} WHERE id = '{}'", ResourceEnum::UsersCache.to_string(), email), "Executing SurrealDB query");
|
||||
let record: Option<UsersDetailQueryDto> = self
|
||||
.state
|
||||
.surrealdb_mem
|
||||
.db
|
||||
.delete((ResourceEnum::UsersCache.to_string(), email))
|
||||
.await?;
|
||||
match record {
|
||||
@@ -147,14 +145,13 @@ impl<'a> AuthRepository<'a> {
|
||||
let table = ResourceEnum::OtpCache.to_string();
|
||||
let key = (table.as_str(), email.as_str());
|
||||
info!(query = %format!("SELECT FROM {} WHERE id = '{}'", table, email), "Executing SurrealDB query");
|
||||
let result: Option<AuthOtpSchema> = self.state.surrealdb_mem.select(key).await?;
|
||||
let result: Option<AuthOtpSchema> = self.db.select(key).await?;
|
||||
match result {
|
||||
Some(data) => match Utc::now() > data.expires_at {
|
||||
true => {
|
||||
info!(query = %format!("DELETE FROM {} WHERE id = '{}'", table, email), "Executing SurrealDB query");
|
||||
let _ = self
|
||||
.state
|
||||
.surrealdb_mem
|
||||
.db
|
||||
.delete::<Option<AuthOtpSchema>>(key)
|
||||
.await?;
|
||||
Err(anyhow!("OTP expired"))
|
||||
@@ -171,8 +168,7 @@ impl<'a> AuthRepository<'a> {
|
||||
let table: String = ResourceEnum::OtpCache.to_string();
|
||||
info!(query = %format!("CREATE {}:{}", table, email), "Executing SurrealDB query");
|
||||
let record: Option<AuthOtpSchema> = self
|
||||
.state
|
||||
.surrealdb_mem
|
||||
.db
|
||||
.create((table.as_str(), email.as_str()))
|
||||
.content(AuthOtpSchema { otp, expires_at })
|
||||
.await?;
|
||||
@@ -186,8 +182,7 @@ impl<'a> AuthRepository<'a> {
|
||||
pub async fn query_delete_stored_otp(&self, email: String) -> Result<String> {
|
||||
info!(query = %format!("DELETE FROM {} WHERE id = '{}'", ResourceEnum::OtpCache.to_string(), email), "Executing SurrealDB query");
|
||||
let record: Option<AuthOtpSchema> = self
|
||||
.state
|
||||
.surrealdb_mem
|
||||
.db
|
||||
.delete((ResourceEnum::OtpCache.to_string(), email))
|
||||
.await?;
|
||||
match record {
|
||||
@@ -196,3 +191,19 @@ impl<'a> AuthRepository<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AuthRepoImpl {
|
||||
pub db: SurrealMemClient,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AuthRepositoryTrait for AuthRepoImpl {
|
||||
async fn query_get_stored_user(
|
||||
&self,
|
||||
email: String,
|
||||
) -> Result<UsersDetailQueryDto, anyhow::Error> {
|
||||
let repo = AuthRepository { db: self.db.clone() };
|
||||
repo.query_get_stored_user(email).await.map_err(|e| anyhow::anyhow!(e))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ impl AuthServiceTrait for AuthService {
|
||||
}
|
||||
|
||||
let user_repo = UsersRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(state.surrealdb_mem.clone());
|
||||
|
||||
let email = &payload.email;
|
||||
let password = &payload.password;
|
||||
@@ -169,7 +169,7 @@ impl AuthServiceTrait for AuthService {
|
||||
}
|
||||
|
||||
let user_repo = UsersRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(state.surrealdb_mem.clone());
|
||||
|
||||
match user_repo.query_user_by_email(payload.email.clone()).await {
|
||||
Ok(user) => {
|
||||
@@ -269,7 +269,7 @@ impl AuthServiceTrait for AuthService {
|
||||
return common_response(status, &message);
|
||||
}
|
||||
let user_repo = UsersRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(state.surrealdb_mem.clone());
|
||||
let role_repo = RolesRepository::new(&state);
|
||||
let role = match role_repo
|
||||
.query_role_by_name(RolesEnum::User.to_string())
|
||||
@@ -378,7 +378,7 @@ impl AuthServiceTrait for AuthService {
|
||||
{
|
||||
return common_response(StatusCode::BAD_REQUEST, "User not found");
|
||||
}
|
||||
let auth_repo = AuthRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(state.surrealdb_mem.clone());
|
||||
let _ = auth_repo.query_get_stored_otp(payload.email.clone()).await;
|
||||
let otp = generate_otp::OtpManager::generate_otp();
|
||||
let message = format!("Your OTP code is {otp}");
|
||||
@@ -501,7 +501,7 @@ impl AuthServiceTrait for AuthService {
|
||||
return common_response(status, &message);
|
||||
}
|
||||
let user_repo = UsersRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(&state);
|
||||
let auth_repo = AuthRepository::new(state.surrealdb_mem.clone());
|
||||
let email = payload.email.clone();
|
||||
let user = match user_repo.query_user_by_email(email.clone()).await {
|
||||
Ok(user) => user,
|
||||
|
||||
@@ -356,8 +356,8 @@ let refresh_token = encode_refresh_token(user.email.clone(), user.id.clone())
|
||||
};
|
||||
|
||||
// Cache the user in auth repository for subsequent requests
|
||||
let auth_repo = crate::v1::auth::AuthRepository::new(&app_state);
|
||||
let user_query_dto: crate::v1::users::users_dto::UsersDetailQueryDto = (&user).into();
|
||||
let auth_repo = crate::v1::auth::AuthRepository::new(app_state.surrealdb_mem.clone());
|
||||
let user_query_dto: imphnen_entities::UsersDetailQueryDto = (&user).into();
|
||||
if let Err(err_store) = auth_repo.query_store_user(user_query_dto).await {
|
||||
error!(
|
||||
"Failed to store user cache for {}: {}",
|
||||
|
||||
Reference in New Issue
Block a user