Files
Oxicloud/src/domain/repositories/user_repository.rs
T

122 lines
3.9 KiB
Rust
Raw Normal View History

2025-03-20 09:22:31 +01:00
use crate::common::errors::DomainError;
2026-02-14 01:29:34 +01:00
use crate::domain::entities::user::{User, UserRole};
use async_trait::async_trait;
2025-03-20 09:22:31 +01:00
#[derive(Debug, thiserror::Error)]
pub enum UserRepositoryError {
#[error("User not found: {0}")]
2025-03-20 09:22:31 +01:00
NotFound(String),
2026-02-14 01:29:34 +01:00
#[error("User already exists: {0}")]
2025-03-20 09:22:31 +01:00
AlreadyExists(String),
2026-02-14 01:29:34 +01:00
#[error("Database error: {0}")]
2025-03-20 09:22:31 +01:00
DatabaseError(String),
2026-02-14 01:29:34 +01:00
#[error("Validation error: {0}")]
2025-03-20 09:22:31 +01:00
ValidationError(String),
2026-02-14 01:29:34 +01:00
#[error("Timeout error: {0}")]
2025-03-20 09:22:31 +01:00
Timeout(String),
2026-02-14 01:29:34 +01:00
#[error("Operation not allowed: {0}")]
2025-03-20 09:22:31 +01:00
OperationNotAllowed(String),
}
pub type UserRepositoryResult<T> = Result<T, UserRepositoryError>;
// Conversion from UserRepositoryError to DomainError
2025-03-20 09:22:31 +01:00
impl From<UserRepositoryError> for DomainError {
fn from(err: UserRepositoryError) -> Self {
match err {
2026-02-14 01:29:34 +01:00
UserRepositoryError::NotFound(msg) => DomainError::not_found("User", msg),
UserRepositoryError::AlreadyExists(msg) => DomainError::already_exists("User", msg),
UserRepositoryError::DatabaseError(msg) => DomainError::internal_error("Database", msg),
UserRepositoryError::ValidationError(msg) => DomainError::validation_error(msg),
UserRepositoryError::Timeout(msg) => DomainError::timeout("Database", msg),
2025-03-20 09:22:31 +01:00
UserRepositoryError::OperationNotAllowed(msg) => {
DomainError::access_denied("User", msg)
2026-02-14 01:29:34 +01:00
}
2025-03-20 09:22:31 +01:00
}
}
}
#[async_trait]
pub trait UserRepository: Send + Sync + 'static {
/// Creates a new user
2025-03-20 09:22:31 +01:00
async fn create_user(&self, user: User) -> UserRepositoryResult<User>;
2026-02-14 01:29:34 +01:00
/// Gets a user by ID
2025-03-20 09:22:31 +01:00
async fn get_user_by_id(&self, id: &str) -> UserRepositoryResult<User>;
2026-02-14 01:29:34 +01:00
/// Gets a user by username
2025-03-20 09:22:31 +01:00
async fn get_user_by_username(&self, username: &str) -> UserRepositoryResult<User>;
2026-02-14 01:29:34 +01:00
/// Gets a user by email
2025-03-20 09:22:31 +01:00
async fn get_user_by_email(&self, email: &str) -> UserRepositoryResult<User>;
2026-02-14 01:29:34 +01:00
/// Updates an existing user
2025-03-20 09:22:31 +01:00
async fn update_user(&self, user: User) -> UserRepositoryResult<User>;
2026-02-14 01:29:34 +01:00
/// Updates only a user's storage usage
2026-02-14 01:29:34 +01:00
async fn update_storage_usage(
&self,
user_id: &str,
usage_bytes: i64,
) -> UserRepositoryResult<()>;
/// Updates the last login date
2025-03-20 09:22:31 +01:00
async fn update_last_login(&self, user_id: &str) -> UserRepositoryResult<()>;
2026-02-14 01:29:34 +01:00
/// Lists users with pagination
2025-03-20 09:22:31 +01:00
async fn list_users(&self, limit: i64, offset: i64) -> UserRepositoryResult<Vec<User>>;
2026-02-14 01:29:34 +01:00
/// Activates or deactivates a user
2026-02-14 01:29:34 +01:00
async fn set_user_active_status(&self, user_id: &str, active: bool)
-> UserRepositoryResult<()>;
/// Changes a user's password
2026-02-14 01:29:34 +01:00
async fn change_password(&self, user_id: &str, password_hash: &str)
-> UserRepositoryResult<()>;
/// Changes a user's role
2025-03-20 09:22:31 +01:00
async fn change_role(&self, user_id: &str, role: UserRole) -> UserRepositoryResult<()>;
2026-02-14 01:29:34 +01:00
/// Lists users by role (admin or user)
2025-04-12 18:58:21 +02:00
async fn list_users_by_role(&self, role: &str) -> UserRepositoryResult<Vec<User>>;
2026-02-14 01:29:34 +01:00
/// Deletes a user
2025-03-20 09:22:31 +01:00
async fn delete_user(&self, user_id: &str) -> UserRepositoryResult<()>;
/// Finds a user by OIDC provider + subject pair
2026-02-14 01:29:34 +01:00
async fn get_user_by_oidc_subject(
&self,
provider: &str,
subject: &str,
) -> UserRepositoryResult<User>;
/// Updates a user's storage quota
2026-02-14 01:29:34 +01:00
async fn update_storage_quota(
&self,
user_id: &str,
quota_bytes: i64,
) -> UserRepositoryResult<()>;
/// Counts the total number of users
async fn count_users(&self) -> UserRepositoryResult<i64>;
/// Gets aggregated storage statistics
async fn get_storage_stats(&self) -> UserRepositoryResult<StorageStats>;
}
/// Aggregated storage statistics
#[derive(Debug, Clone)]
pub struct StorageStats {
pub total_users: i64,
pub active_users: i64,
pub total_quota_bytes: i64,
pub total_used_bytes: i64,
pub users_over_80_percent: i64,
pub users_over_quota: i64,
2026-02-14 01:29:34 +01:00
}