user permissions

This commit is contained in:
2025-07-19 13:38:58 +02:00
parent ec8e73507c
commit 496d5bdb2b
30 changed files with 1384 additions and 195 deletions

View File

@@ -151,4 +151,67 @@ impl AuthMetrics for MetricsDebugLogger {
async fn record_auth_session_fetch_failure(&self) {
tracing::debug!("[Metrics] Auth session fetch failed");
}
async fn record_auth_fetch_user_warren_list_success(&self) {
tracing::debug!("[Metrics] Auth warren list succeeded");
}
async fn record_auth_fetch_user_warren_list_failure(&self) {
tracing::debug!("[Metrics] Auth warren list failed");
}
async fn record_auth_fetch_user_warrens_success(&self) -> () {
tracing::debug!("[Metrics] Auth user warren id fetch succeeded");
}
async fn record_auth_fetch_user_warrens_failure(&self) -> () {
tracing::debug!("[Metrics] Auth user warren id fetch failed");
}
async fn record_auth_warren_fetch_success(&self) {
tracing::debug!("[Metrics] Auth warren fetch succeeded");
}
async fn record_auth_warren_fetch_failure(&self) {
tracing::debug!("[Metrics] Auth warren fetch failed");
}
async fn record_auth_warren_file_list_success(&self) {
tracing::debug!("[Metrics] Auth warren file list succeeded");
}
async fn record_auth_warren_file_list_failure(&self) {
tracing::debug!("[Metrics] Auth warren file list failed");
}
async fn record_auth_warren_directory_creation_success(&self) {
tracing::debug!("[Metrics] Auth warren directory creation succeeded");
}
async fn record_auth_warren_directory_creation_failure(&self) {
tracing::debug!("[Metrics] Auth warren directory creation failed");
}
async fn record_auth_warren_directory_deletion_success(&self) {
tracing::debug!("[Metrics] Auth warren directory deletion succeeded");
}
async fn record_auth_warren_directory_deletion_failure(&self) {
tracing::debug!("[Metrics] Auth warren directory deletion failed");
}
async fn record_auth_warren_file_deletion_success(&self) {
tracing::debug!("[Metrics] Auth warren file deletion succeeded");
}
async fn record_auth_warren_file_deletion_failure(&self) {
tracing::debug!("[Metrics] Auth warren file deletion failed");
}
async fn record_auth_warren_entry_rename_success(&self) {
tracing::debug!("[Metrics] Auth warren entry rename succeeded");
}
async fn record_auth_warren_entry_rename_failure(&self) {
tracing::debug!("[Metrics] Auth warren entry rename failed");
}
async fn record_auth_warren_files_upload_success(&self) {
tracing::debug!("[Metrics] Auth warren files upload succeeded");
}
async fn record_auth_warren_files_upload_failure(&self) {
tracing::debug!("[Metrics] Auth warren files upload failed");
}
}

View File

@@ -5,7 +5,11 @@ use crate::domain::warren::{
auth_session::requests::FetchAuthSessionResponse,
file::{File, FilePath},
user::{LoginUserResponse, User},
warren::Warren,
user_warren::UserWarren,
warren::{
CreateWarrenDirectoryResponse, DeleteWarrenDirectoryResponse, DeleteWarrenFileResponse,
ListWarrenFilesResponse, RenameWarrenEntryResponse, UploadWarrenFilesResponse, Warren,
},
},
ports::{AuthNotifier, FileSystemNotifier, WarrenNotifier},
};
@@ -28,27 +32,27 @@ impl WarrenNotifier for NotifierDebugLogger {
tracing::debug!("[Notifier] Fetched warren {}", warren.name());
}
async fn warren_files_listed(&self, warren: &Warren, files: &Vec<File>) {
async fn warren_files_listed(&self, response: &ListWarrenFilesResponse) {
tracing::debug!(
"[Notifier] Listed {} file(s) in warren {}",
files.len(),
warren.name()
response.files().len(),
response.warren().name()
);
}
async fn warren_directory_created(&self, warren: &Warren, path: &FilePath) {
async fn warren_directory_created(&self, response: &CreateWarrenDirectoryResponse) {
tracing::debug!(
"[Notifier] Created directory {} in warren {}",
path,
warren.name()
response.path(),
response.warren().name()
);
}
async fn warren_directory_deleted(&self, warren: &Warren, path: &FilePath) {
async fn warren_directory_deleted(&self, response: &DeleteWarrenDirectoryResponse) {
tracing::debug!(
"[Notifier] Deleted directory {} in warren {}",
path,
warren.name()
response.path(),
response.warren().name()
);
}
@@ -60,33 +64,28 @@ impl WarrenNotifier for NotifierDebugLogger {
);
}
async fn warren_files_uploaded(&self, warren: &Warren, paths: &[FilePath]) {
async fn warren_files_uploaded(&self, response: &UploadWarrenFilesResponse) {
tracing::debug!(
"[Notifier] Uploaded {} file(s) to warren {}",
paths.len(),
warren.name()
response.paths().len(),
response.warren().name()
);
}
async fn warren_file_deleted(&self, warren: &Warren, path: &FilePath) {
async fn warren_file_deleted(&self, response: &DeleteWarrenFileResponse) {
tracing::debug!(
"[Notifier] Deleted file {} from warren {}",
path,
warren.name(),
response.path(),
response.warren().name(),
);
}
async fn warren_entry_renamed(
&self,
warren: &Warren,
old_path: &crate::domain::warren::models::file::AbsoluteFilePath,
new_path: &FilePath,
) {
async fn warren_entry_renamed(&self, response: &RenameWarrenEntryResponse) {
tracing::debug!(
"[Notifier] Renamed file {} to {} in warren {}",
old_path,
new_path,
warren.name(),
response.old_path(),
response.path(),
response.warren().name(),
);
}
}
@@ -136,4 +135,91 @@ impl AuthNotifier for NotifierDebugLogger {
response.user().id()
);
}
async fn auth_user_warrens_fetched(&self, user_id: &Uuid, warren_ids: &Vec<UserWarren>) {
tracing::debug!(
"[Notifier] Fetched {} user warrens for authenticated user {}",
warren_ids.len(),
user_id
);
}
async fn auth_user_warrens_listed(&self, user: &User, warrens: &Vec<Warren>) {
tracing::debug!(
"[Notifier] Fetched {} warren(s) for authenticated user {}",
warrens.len(),
user.id()
);
}
async fn auth_warren_fetched(&self, user: &User, warren: &Warren) {
tracing::debug!(
"[Notifier] Fetched warren {} for authenticated user {}",
warren.name(),
user.id(),
);
}
async fn auth_warren_files_listed(&self, user: &User, response: &ListWarrenFilesResponse) {
tracing::debug!(
"[Notifier] Listed {} file(s) in warren {} for authenticated user {}",
response.files().len(),
response.warren().name(),
user.id()
);
}
async fn auth_warren_directory_created(
&self,
user: &User,
response: &CreateWarrenDirectoryResponse,
) {
tracing::debug!(
"[Notifier] Created directory {} in warren {} for authenticated user {}",
response.path(),
response.warren().name(),
user.id(),
);
}
async fn auth_warren_directory_deleted(
&self,
user: &User,
response: &DeleteWarrenDirectoryResponse,
) {
tracing::debug!(
"[Notifier] Deleted directory {} in warren {} for authenticated user {}",
response.path(),
response.warren().name(),
user.id(),
);
}
async fn auth_warren_files_uploaded(&self, user: &User, response: &UploadWarrenFilesResponse) {
tracing::debug!(
"[Notifier] Uploaded {} file(s) to warren {} for authenticated user {}",
response.paths().len(),
response.warren().name(),
user.id(),
);
}
async fn auth_warren_file_deleted(&self, user: &User, response: &DeleteWarrenFileResponse) {
tracing::debug!(
"[Notifier] Deleted file {} from warren {} for authenticated user {}",
response.path(),
response.warren().name(),
user.id(),
);
}
async fn auth_warren_entry_renamed(&self, user: &User, response: &RenameWarrenEntryResponse) {
tracing::debug!(
"[Notifier] Renamed file {} to {} in warren {} for authenticated user {}",
response.old_path(),
response.path(),
response.warren().name(),
user.id(),
);
}
}

View File

@@ -28,8 +28,15 @@ use crate::domain::warren::{
RegisterUserError, RegisterUserRequest, User, UserEmail, UserName, UserPassword,
VerifyUserPasswordError, VerifyUserPasswordRequest,
},
user_warren::{
UserWarren,
requests::{
FetchUserWarrenError, FetchUserWarrenRequest, FetchUserWarrensError,
FetchUserWarrensRequest,
},
},
warren::{
FetchWarrenError, FetchWarrenRequest, ListWarrensError, ListWarrensRequest, Warren,
FetchWarrenError, FetchWarrenRequest, FetchWarrensError, FetchWarrensRequest, Warren,
},
},
ports::{AuthRepository, WarrenRepository},
@@ -103,6 +110,7 @@ impl Postgres {
async fn list_warrens(
&self,
connection: &mut PgConnection,
ids: &[Uuid],
) -> Result<Vec<Warren>, sqlx::Error> {
let warrens: Vec<Warren> = sqlx::query_as::<sqlx::Postgres, Warren>(
"
@@ -110,10 +118,11 @@ impl Postgres {
*
FROM
warrens
LIMIT
50
WHERE
id = ANY($1)
",
)
.bind(ids)
.fetch_all(&mut *connection)
.await?;
@@ -292,13 +301,60 @@ impl Postgres {
Ok(session)
}
async fn get_user_warrens(
&self,
connection: &mut PgConnection,
user_id: &Uuid,
) -> Result<Vec<UserWarren>, sqlx::Error> {
let ids: Vec<UserWarren> = sqlx::query_as(
"
SELECT
*
FROM
user_warrens
WHERE
user_id = $1
",
)
.bind(user_id)
.fetch_all(connection)
.await?;
Ok(ids)
}
async fn get_user_warren(
&self,
connection: &mut PgConnection,
user_id: &Uuid,
warren_id: &Uuid,
) -> Result<UserWarren, sqlx::Error> {
let ids: UserWarren = sqlx::query_as(
"
SELECT
*
FROM
user_warrens
WHERE
user_id = $1 AND
warren_id = $2
",
)
.bind(user_id)
.bind(warren_id)
.fetch_one(connection)
.await?;
Ok(ids)
}
}
impl WarrenRepository for Postgres {
async fn list_warrens(
&self,
_request: ListWarrensRequest,
) -> Result<Vec<Warren>, ListWarrensError> {
request: FetchWarrensRequest,
) -> Result<Vec<Warren>, FetchWarrensError> {
let mut connection = self
.pool
.acquire()
@@ -306,7 +362,7 @@ impl WarrenRepository for Postgres {
.context("Failed to get a PostgreSQL connection")?;
let warrens = self
.list_warrens(&mut connection)
.list_warrens(&mut connection, request.ids())
.await
.map_err(|err| anyhow!(err).context("Failed to list warrens"))?;
@@ -424,6 +480,45 @@ impl AuthRepository for Postgres {
Ok(FetchAuthSessionResponse::new(session, user))
}
async fn fetch_user_warrens(
&self,
request: FetchUserWarrensRequest,
) -> Result<Vec<UserWarren>, FetchUserWarrensError> {
let mut connection = self
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
let warren_ids = self
.get_user_warrens(&mut connection, request.user_id())
.await
.context("Failed to get user warrens")?;
Ok(warren_ids)
}
async fn fetch_user_warren(
&self,
request: FetchUserWarrenRequest,
) -> Result<UserWarren, FetchUserWarrenError> {
let mut connection = self
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
self.get_user_warren(&mut connection, request.user_id(), request.warren_id())
.await
.map_err(|e| {
if is_not_found_error(&e) {
FetchUserWarrenError::NotFound
} else {
FetchUserWarrenError::Unknown(anyhow!(e))
}
})
}
}
fn is_not_found_error(err: &sqlx::Error) -> bool {