fix: critical bugs from deep audit

- Fix copy_files() data loss: implement real copy_file across full stack
  (FileWritePort, FileManagementUseCase, stubs, service, repository with
  atomic CTE + dedup ref_count increment, batch_operations caller)
- Fix plaintext password in replace_default_admin: hash password via
  PasswordHasherPort before User::new()
- Fix CalendarService hardcoded user_id: unify CalendarUseCase trait with
  explicit user_id parameter on all methods, remove zombie _for_user
  duplicates and hardcoded 'current_user_id', update 20 CalDAV handler
  call sites
- Previous session: migrate DedupService to PostgreSQL (storage.blobs),
  atomic CTEs with compensation for file/folder repository operations
This commit is contained in:
Dionisio
2026-02-14 20:22:19 +01:00
parent 3179e1dd91
commit fac0b5e77b
17 changed files with 2163 additions and 2185 deletions
+34 -57
View File
@@ -106,23 +106,33 @@ pub trait CalendarStoragePort: Send + Sync + 'static {
) -> Result<Vec<CalendarEventDto>, DomainError>;
}
/// Port for calendar use cases
/// Port for calendar use cases.
///
/// All methods require an explicit `user_id` parameter for authorization.
/// The CalDAV protocol handler extracts the user identity from JWT claims
/// and passes it through.
#[async_trait]
pub trait CalendarUseCase: Send + Sync + 'static {
// Calendar operations
async fn create_calendar(
&self,
calendar: CreateCalendarDto,
user_id: &str,
) -> Result<CalendarDto, DomainError>;
async fn update_calendar(
&self,
calendar_id: &str,
update: UpdateCalendarDto,
user_id: &str,
) -> Result<CalendarDto, DomainError>;
async fn delete_calendar(&self, calendar_id: &str) -> Result<(), DomainError>;
async fn get_calendar(&self, calendar_id: &str) -> Result<CalendarDto, DomainError>;
async fn list_my_calendars(&self) -> Result<Vec<CalendarDto>, DomainError>;
async fn list_shared_calendars(&self) -> Result<Vec<CalendarDto>, DomainError>;
async fn delete_calendar(&self, calendar_id: &str, user_id: &str) -> Result<(), DomainError>;
async fn get_calendar(
&self,
calendar_id: &str,
user_id: &str,
) -> Result<CalendarDto, DomainError>;
async fn list_my_calendars(&self, user_id: &str) -> Result<Vec<CalendarDto>, DomainError>;
async fn list_shared_calendars(&self, user_id: &str) -> Result<Vec<CalendarDto>, DomainError>;
async fn list_public_calendars(
&self,
limit: Option<i64>,
@@ -133,90 +143,57 @@ pub trait CalendarUseCase: Send + Sync + 'static {
async fn share_calendar(
&self,
calendar_id: &str,
user_id: &str,
target_user_id: &str,
access_level: &str,
caller_user_id: &str,
) -> Result<(), DomainError>;
async fn remove_calendar_sharing(
&self,
calendar_id: &str,
user_id: &str,
target_user_id: &str,
caller_user_id: &str,
) -> Result<(), DomainError>;
async fn get_calendar_shares(
&self,
calendar_id: &str,
user_id: &str,
) -> Result<Vec<(String, String)>, DomainError>;
// Event operations
async fn create_event(&self, event: CreateEventDto) -> Result<CalendarEventDto, DomainError>;
async fn create_event(
&self,
event: CreateEventDto,
user_id: &str,
) -> Result<CalendarEventDto, DomainError>;
async fn create_event_from_ical(
&self,
event: CreateEventICalDto,
user_id: &str,
) -> Result<CalendarEventDto, DomainError>;
async fn update_event(
&self,
event_id: &str,
update: UpdateEventDto,
user_id: &str,
) -> Result<CalendarEventDto, DomainError>;
async fn delete_event(&self, event_id: &str, user_id: &str) -> Result<(), DomainError>;
async fn get_event(
&self,
event_id: &str,
user_id: &str,
) -> Result<CalendarEventDto, DomainError>;
async fn delete_event(&self, event_id: &str) -> Result<(), DomainError>;
async fn get_event(&self, event_id: &str) -> Result<CalendarEventDto, DomainError>;
async fn list_events(
&self,
calendar_id: &str,
limit: Option<i64>,
offset: Option<i64>,
user_id: &str,
) -> Result<Vec<CalendarEventDto>, DomainError>;
async fn get_events_in_range(
&self,
calendar_id: &str,
start: DateTime<Utc>,
end: DateTime<Utc>,
) -> Result<Vec<CalendarEventDto>, DomainError>;
// ─── User-contextualized variants (for CalDAV protocol handler) ──
async fn create_calendar_for_user(
&self,
calendar: CreateCalendarDto,
user_id: &str,
) -> Result<CalendarDto, DomainError>;
async fn update_calendar_for_user(
&self,
calendar_id: &str,
update: UpdateCalendarDto,
user_id: &str,
) -> Result<CalendarDto, DomainError>;
async fn delete_calendar_for_user(
&self,
calendar_id: &str,
user_id: &str,
) -> Result<(), DomainError>;
async fn get_calendar_for_user(
&self,
calendar_id: &str,
user_id: &str,
) -> Result<CalendarDto, DomainError>;
async fn list_my_calendars_for_user(
&self,
user_id: &str,
) -> Result<Vec<CalendarDto>, DomainError>;
async fn list_events_for_user(
&self,
calendar_id: &str,
limit: Option<i64>,
offset: Option<i64>,
user_id: &str,
) -> Result<Vec<CalendarEventDto>, DomainError>;
async fn get_events_in_range_for_user(
&self,
calendar_id: &str,
start: DateTime<Utc>,
end: DateTime<Utc>,
user_id: &str,
) -> Result<Vec<CalendarEventDto>, DomainError>;
async fn create_event_from_ical_for_user(
&self,
event: CreateEventICalDto,
user_id: &str,
) -> Result<CalendarEventDto, DomainError>;
async fn delete_event_for_user(&self, event_id: &str, user_id: &str)
-> Result<(), DomainError>;
}
+7
View File
@@ -138,6 +138,13 @@ pub trait FileManagementUseCase: Send + Sync + 'static {
folder_id: Option<String>,
) -> Result<FileDto, DomainError>;
/// Copies a file to another folder (zero-copy with dedup).
async fn copy_file(
&self,
file_id: &str,
target_folder_id: Option<String>,
) -> Result<FileDto, DomainError>;
/// Renames a file
async fn rename_file(&self, file_id: &str, new_name: &str) -> Result<FileDto, DomainError>;
+10
View File
@@ -115,6 +115,16 @@ pub trait FileWritePort: Send + Sync + 'static {
size: u64,
) -> Result<(File, PathBuf), DomainError>;
/// Copies a file to a (possibly different) folder.
///
/// With blob-dedup, this only creates a new metadata row and increments
/// the blob reference count — zero disk I/O for the content.
async fn copy_file(
&self,
file_id: &str,
target_folder_id: Option<String>,
) -> Result<File, DomainError>;
// ── Trash operations ──
/// Moves a file to the trash
@@ -168,7 +168,7 @@ impl AuthApplicationService {
/// Returns whether OIDC is configured and enabled
pub fn oidc_enabled(&self) -> bool {
let state = self.oidc.read().unwrap();
state.service.is_some() && state.config.as_ref().is_some_and(|c| c.enabled)
state.service.is_some() && state.config.as_ref().map_or(false, |c| c.enabled)
}
/// Returns whether password login is disabled (OIDC-only mode)
@@ -177,7 +177,7 @@ impl AuthApplicationService {
state
.config
.as_ref()
.is_some_and(|c| c.disable_password_login)
.map_or(false, |c| c.disable_password_login)
}
/// Returns a clone of the OIDC config if available
@@ -664,11 +664,23 @@ impl AuthApplicationService {
// Admin quota, capped to available disk space
let admin_quota = self.capped_quota(&admin_role);
// Hash the password (same as register / admin_create_user)
let password_hash = self
.password_hasher
.hash_password(&dto.password)
.map_err(|e| {
DomainError::new(
ErrorKind::InternalError,
"User",
format!("Error hashing password: {}", e),
)
})?;
// Create the new admin user
let user = User::new(
dto.username.clone(),
dto.email.clone(),
dto.password.clone(),
password_hash,
admin_role,
admin_quota,
)
+1 -1
View File
@@ -129,7 +129,7 @@ impl BatchOperationService {
// Acquire semaphore permit
let permit = semaphore.acquire().await.unwrap();
let copy_result = mgmt.move_file(&file_id, target_folder.clone()).await;
let copy_result = mgmt.copy_file(&file_id, target_folder.clone()).await;
// Release the permit explicitly (also released on drop)
drop(permit);
+34 -290
View File
@@ -24,13 +24,8 @@ impl CalendarUseCase for CalendarService {
async fn create_calendar(
&self,
calendar: CreateCalendarDto,
user_id: &str,
) -> Result<CalendarDto, DomainError> {
// This function requires the current user context which will come from middleware
// For now, we'll use a dummy implementation that needs to be completed
// In a real implementation, get user_id from current user context
let user_id = "current_user_id"; // This should come from middleware
self.calendar_storage
.create_calendar(calendar, user_id)
.await
@@ -40,20 +35,12 @@ impl CalendarUseCase for CalendarService {
&self,
calendar_id: &str,
update: UpdateCalendarDto,
user_id: &str,
) -> Result<CalendarDto, DomainError> {
// In a real implementation, we would:
// 1. Get the current user ID from middleware
// 2. Verify that the user has access to this calendar
// 3. Update the calendar if they have permission
let user_id = "current_user_id"; // This should come from middleware
// Check if user has access
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -61,21 +48,16 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to update this calendar",
));
}
self.calendar_storage
.update_calendar(calendar_id, update)
.await
}
async fn delete_calendar(&self, calendar_id: &str) -> Result<(), DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Check if user has access
async fn delete_calendar(&self, calendar_id: &str, user_id: &str) -> Result<(), DomainError> {
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -83,22 +65,19 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to delete this calendar",
));
}
self.calendar_storage.delete_calendar(calendar_id).await
}
async fn get_calendar(&self, calendar_id: &str) -> Result<CalendarDto, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Get the calendar
async fn get_calendar(
&self,
calendar_id: &str,
user_id: &str,
) -> Result<CalendarDto, DomainError> {
let calendar = self.calendar_storage.get_calendar(calendar_id).await?;
// Check if user has access or if calendar is public
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
if !has_access && !calendar.is_public {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -106,19 +85,14 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to view this calendar",
));
}
Ok(calendar)
}
async fn list_my_calendars(&self) -> Result<Vec<CalendarDto>, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
async fn list_my_calendars(&self, user_id: &str) -> Result<Vec<CalendarDto>, DomainError> {
self.calendar_storage.list_calendars_by_owner(user_id).await
}
async fn list_shared_calendars(&self) -> Result<Vec<CalendarDto>, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
async fn list_shared_calendars(&self, user_id: &str) -> Result<Vec<CalendarDto>, DomainError> {
self.calendar_storage
.list_calendars_shared_with_user(user_id)
.await
@@ -131,7 +105,6 @@ impl CalendarUseCase for CalendarService {
) -> Result<Vec<CalendarDto>, DomainError> {
let limit = limit.unwrap_or(100);
let offset = offset.unwrap_or(0);
self.calendar_storage
.list_public_calendars(limit, offset)
.await
@@ -140,24 +113,18 @@ impl CalendarUseCase for CalendarService {
async fn share_calendar(
&self,
calendar_id: &str,
user_id: &str,
target_user_id: &str,
access_level: &str,
caller_user_id: &str,
) -> Result<(), DomainError> {
let current_user_id = "current_user_id"; // This should come from middleware
// Check if current user has access
let calendar = self.calendar_storage.get_calendar(calendar_id).await?;
// Only the owner can share the calendar
if calendar.owner_id != current_user_id {
if calendar.owner_id != caller_user_id {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"Only the calendar owner can change sharing settings",
));
}
// Validate access_level
match access_level {
"read" | "write" | "owner" => {}
_ => {
@@ -171,66 +138,55 @@ impl CalendarUseCase for CalendarService {
));
}
}
self.calendar_storage
.share_calendar(calendar_id, user_id, access_level)
.share_calendar(calendar_id, target_user_id, access_level)
.await
}
async fn remove_calendar_sharing(
&self,
calendar_id: &str,
user_id: &str,
target_user_id: &str,
caller_user_id: &str,
) -> Result<(), DomainError> {
let current_user_id = "current_user_id"; // This should come from middleware
// Check if current user has access
let calendar = self.calendar_storage.get_calendar(calendar_id).await?;
// Only the owner can change sharing settings
if calendar.owner_id != current_user_id {
if calendar.owner_id != caller_user_id {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"Only the calendar owner can change sharing settings",
));
}
self.calendar_storage
.remove_calendar_sharing(calendar_id, user_id)
.remove_calendar_sharing(calendar_id, target_user_id)
.await
}
async fn get_calendar_shares(
&self,
calendar_id: &str,
user_id: &str,
) -> Result<Vec<(String, String)>, DomainError> {
let current_user_id = "current_user_id"; // This should come from middleware
// Check if current user has access
let calendar = self.calendar_storage.get_calendar(calendar_id).await?;
// Only the owner can view sharing settings
if calendar.owner_id != current_user_id {
if calendar.owner_id != user_id {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"Only the calendar owner can view sharing settings",
));
}
self.calendar_storage.get_calendar_shares(calendar_id).await
}
async fn create_event(&self, event: CreateEventDto) -> Result<CalendarEventDto, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Check if user has access to the calendar
async fn create_event(
&self,
event: CreateEventDto,
user_id: &str,
) -> Result<CalendarEventDto, DomainError> {
let has_access = self
.calendar_storage
.check_calendar_access(&event.calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -238,22 +194,18 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to add events to this calendar",
));
}
self.calendar_storage.create_event(event).await
}
async fn create_event_from_ical(
&self,
event: CreateEventICalDto,
user_id: &str,
) -> Result<CalendarEventDto, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Check if user has access to the calendar
let has_access = self
.calendar_storage
.check_calendar_access(&event.calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -261,7 +213,6 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to add events to this calendar",
));
}
self.calendar_storage.create_event_from_ical(event).await
}
@@ -269,18 +220,13 @@ impl CalendarUseCase for CalendarService {
&self,
event_id: &str,
update: UpdateEventDto,
user_id: &str,
) -> Result<CalendarEventDto, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Get the event to find its calendar
let event = self.calendar_storage.get_event(event_id).await?;
// Check if user has access to the calendar
let has_access = self
.calendar_storage
.check_calendar_access(&event.calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -288,22 +234,15 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to update events in this calendar",
));
}
self.calendar_storage.update_event(event_id, update).await
}
async fn delete_event(&self, event_id: &str) -> Result<(), DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Get the event to find its calendar
async fn delete_event(&self, event_id: &str, user_id: &str) -> Result<(), DomainError> {
let event = self.calendar_storage.get_event(event_id).await?;
// Check if user has access to the calendar
let has_access = self
.calendar_storage
.check_calendar_access(&event.calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -311,28 +250,23 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to delete events in this calendar",
));
}
self.calendar_storage.delete_event(event_id).await
}
async fn get_event(&self, event_id: &str) -> Result<CalendarEventDto, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Get the event
async fn get_event(
&self,
event_id: &str,
user_id: &str,
) -> Result<CalendarEventDto, DomainError> {
let event = self.calendar_storage.get_event(event_id).await?;
// Check if user has access to the calendar
let has_access = self
.calendar_storage
.check_calendar_access(&event.calendar_id, user_id)
.await?;
// Check if calendar is public
let calendar = self
.calendar_storage
.get_calendar(&event.calendar_id)
.await?;
if !has_access && !calendar.is_public {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -340,7 +274,6 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to view events in this calendar",
));
}
Ok(event)
}
@@ -349,18 +282,13 @@ impl CalendarUseCase for CalendarService {
calendar_id: &str,
limit: Option<i64>,
offset: Option<i64>,
user_id: &str,
) -> Result<Vec<CalendarEventDto>, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Check if user has access to the calendar
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
// Check if calendar is public
let calendar = self.calendar_storage.get_calendar(calendar_id).await?;
if !has_access && !calendar.is_public {
return Err(DomainError::new(
ErrorKind::AccessDenied,
@@ -368,12 +296,9 @@ impl CalendarUseCase for CalendarService {
"You don't have permission to view events in this calendar",
));
}
// Use pagination if provided
if limit.is_some() || offset.is_some() {
let limit = limit.unwrap_or(100);
let offset = offset.unwrap_or(0);
self.calendar_storage
.list_events_by_calendar_paginated(calendar_id, limit, offset)
.await
@@ -389,148 +314,6 @@ impl CalendarUseCase for CalendarService {
calendar_id: &str,
start: DateTime<Utc>,
end: DateTime<Utc>,
) -> Result<Vec<CalendarEventDto>, DomainError> {
let user_id = "current_user_id"; // This should come from middleware
// Check if user has access to the calendar
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
// Check if calendar is public
let calendar = self.calendar_storage.get_calendar(calendar_id).await?;
if !has_access && !calendar.is_public {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"You don't have permission to view events in this calendar",
));
}
self.calendar_storage
.get_events_in_time_range(calendar_id, &start, &end)
.await
}
// ─── User-contextualized variants (for CalDAV protocol handler) ──
async fn create_calendar_for_user(
&self,
calendar: CreateCalendarDto,
user_id: &str,
) -> Result<CalendarDto, DomainError> {
self.calendar_storage
.create_calendar(calendar, user_id)
.await
}
async fn update_calendar_for_user(
&self,
calendar_id: &str,
update: UpdateCalendarDto,
user_id: &str,
) -> Result<CalendarDto, DomainError> {
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"You don't have permission to update this calendar",
));
}
self.calendar_storage
.update_calendar(calendar_id, update)
.await
}
async fn delete_calendar_for_user(
&self,
calendar_id: &str,
user_id: &str,
) -> Result<(), DomainError> {
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"You don't have permission to delete this calendar",
));
}
self.calendar_storage.delete_calendar(calendar_id).await
}
async fn get_calendar_for_user(
&self,
calendar_id: &str,
user_id: &str,
) -> Result<CalendarDto, DomainError> {
let calendar = self.calendar_storage.get_calendar(calendar_id).await?;
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
if !has_access && !calendar.is_public {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"You don't have permission to view this calendar",
));
}
Ok(calendar)
}
async fn list_my_calendars_for_user(
&self,
user_id: &str,
) -> Result<Vec<CalendarDto>, DomainError> {
self.calendar_storage.list_calendars_by_owner(user_id).await
}
async fn list_events_for_user(
&self,
calendar_id: &str,
limit: Option<i64>,
offset: Option<i64>,
user_id: &str,
) -> Result<Vec<CalendarEventDto>, DomainError> {
let has_access = self
.calendar_storage
.check_calendar_access(calendar_id, user_id)
.await?;
let calendar = self.calendar_storage.get_calendar(calendar_id).await?;
if !has_access && !calendar.is_public {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"You don't have permission to view events in this calendar",
));
}
if limit.is_some() || offset.is_some() {
let limit = limit.unwrap_or(100);
let offset = offset.unwrap_or(0);
self.calendar_storage
.list_events_by_calendar_paginated(calendar_id, limit, offset)
.await
} else {
self.calendar_storage
.list_events_by_calendar(calendar_id)
.await
}
}
async fn get_events_in_range_for_user(
&self,
calendar_id: &str,
start: DateTime<Utc>,
end: DateTime<Utc>,
user_id: &str,
) -> Result<Vec<CalendarEventDto>, DomainError> {
let has_access = self
@@ -549,43 +332,4 @@ impl CalendarUseCase for CalendarService {
.get_events_in_time_range(calendar_id, &start, &end)
.await
}
async fn create_event_from_ical_for_user(
&self,
event: CreateEventICalDto,
user_id: &str,
) -> Result<CalendarEventDto, DomainError> {
let has_access = self
.calendar_storage
.check_calendar_access(&event.calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"You don't have permission to add events to this calendar",
));
}
self.calendar_storage.create_event_from_ical(event).await
}
async fn delete_event_for_user(
&self,
event_id: &str,
user_id: &str,
) -> Result<(), DomainError> {
let event = self.calendar_storage.get_event(event_id).await?;
let has_access = self
.calendar_storage
.check_calendar_access(&event.calendar_id, user_id)
.await?;
if !has_access {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"Calendar",
"You don't have permission to delete events in this calendar",
));
}
self.calendar_storage.delete_event(event_id).await
}
}
@@ -121,6 +121,35 @@ impl FileManagementUseCase for FileManagementService {
Ok(FileDto::from(moved_file))
}
async fn copy_file(
&self,
file_id: &str,
target_folder_id: Option<String>,
) -> Result<FileDto, DomainError> {
info!(
"Copying file with ID: {} to folder: {:?}",
file_id, target_folder_id
);
let copied_file = self
.file_repository
.copy_file(file_id, target_folder_id)
.await
.map_err(|e| {
error!("Error copying file (ID: {}): {}", file_id, e);
e
})?;
info!(
"File copied successfully: {} (ID: {}) to folder: {:?}",
copied_file.name(),
copied_file.id(),
copied_file.folder_id()
);
Ok(FileDto::from(copied_file))
}
async fn rename_file(&self, file_id: &str, new_name: &str) -> Result<FileDto, DomainError> {
info!("Renaming file with ID: {} to \"{}\"", file_id, new_name);