From eba30d1e9d07670f522ce2d825e93a418e437b54 Mon Sep 17 00:00:00 2001 From: StNicolay Date: Mon, 5 Aug 2024 23:45:00 +0300 Subject: [PATCH] Permission guard simplification --- src/db/permissions.rs | 43 ++++++++++++++++++++++++--- src/endpoints/file/delete.rs | 1 - src/endpoints/file/download.rs | 1 - src/endpoints/file/modify.rs | 1 - src/endpoints/file/upload.rs | 1 - src/endpoints/folder/create.rs | 1 - src/endpoints/folder/delete.rs | 1 - src/endpoints/folder/get_structure.rs | 2 +- src/endpoints/folder/list.rs | 2 +- src/endpoints/permissions/delete.rs | 1 - src/endpoints/permissions/get.rs | 1 - src/endpoints/permissions/set.rs | 1 - src/errors.rs | 8 ----- src/prelude.rs | 2 +- 14 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/db/permissions.rs b/src/db/permissions.rs index dcb8f5e..12630bd 100644 --- a/src/db/permissions.rs +++ b/src/db/permissions.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{borrow::Cow, collections::HashMap}; use crate::prelude::*; @@ -37,7 +37,7 @@ impl PermissionType { self >= PermissionType::Read } - pub fn can_read_guard(self) -> GeneralResult<()> { + fn can_read_guard(self) -> GeneralResult<()> { if !self.can_read() { return Err(GeneralError::message( StatusCode::NOT_FOUND, @@ -47,7 +47,7 @@ impl PermissionType { Ok(()) } - pub fn can_write_guard(self) -> GeneralResult<()> { + fn can_write_guard(self) -> GeneralResult<()> { self.can_read_guard()?; if self < PermissionType::Write { return Err(GeneralError::message( @@ -58,7 +58,7 @@ impl PermissionType { Ok(()) } - pub fn can_manage_guard(self) -> GeneralResult<()> { + fn can_manage_guard(self) -> GeneralResult<()> { self.can_read_guard()?; if self < PermissionType::Manage { return Err(GeneralError::message( @@ -70,6 +70,41 @@ impl PermissionType { } } +pub trait PermissionExt { + fn can_read_guard(self) -> GeneralResult<()>; + fn can_write_guard(self) -> GeneralResult<()>; + fn can_manage_guard(self) -> GeneralResult<()>; +} + +fn permissions_error(error: sqlx::Error) -> GeneralError { + GeneralError { + status_code: StatusCode::INTERNAL_SERVER_ERROR, + message: Cow::Borrowed("Error getting permissions"), + error: Some(error.into()), + } +} + +fn apply_guard( + result: sqlx::Result, + func: impl FnOnce(PermissionType) -> GeneralResult<()>, +) -> GeneralResult<()> { + result.map_err(permissions_error).and_then(func) +} + +impl PermissionExt for sqlx::Result { + fn can_read_guard(self) -> GeneralResult<()> { + apply_guard(self, PermissionType::can_read_guard) + } + + fn can_write_guard(self) -> GeneralResult<()> { + apply_guard(self, PermissionType::can_write_guard) + } + + fn can_manage_guard(self) -> GeneralResult<()> { + apply_guard(self, PermissionType::can_manage_guard) + } +} + pub async fn insert( user_id: i32, folder_id: Uuid, diff --git a/src/endpoints/file/delete.rs b/src/endpoints/file/delete.rs index c3039d5..434857e 100644 --- a/src/endpoints/file/delete.rs +++ b/src/endpoints/file/delete.rs @@ -12,7 +12,6 @@ pub async fn delete( ) -> GeneralResult { db::file::get_permissions(params.file_id, claims.user_id, &state.pool) .await - .map_err(GeneralError::permissions)? .can_write_guard()?; let deleted = db::file::delete(params.file_id, &state.pool) diff --git a/src/endpoints/file/download.rs b/src/endpoints/file/download.rs index 2e4fff0..405fea6 100644 --- a/src/endpoints/file/download.rs +++ b/src/endpoints/file/download.rs @@ -15,7 +15,6 @@ pub async fn download( ) -> GeneralResult { db::file::get_permissions(params.file_id, claims.user_id, &state.pool) .await - .map_err(GeneralError::permissions)? .can_read_guard()?; let mut name = db::file::get_name(params.file_id, &state.pool) diff --git a/src/endpoints/file/modify.rs b/src/endpoints/file/modify.rs index ed95fe7..dc9f754 100644 --- a/src/endpoints/file/modify.rs +++ b/src/endpoints/file/modify.rs @@ -15,7 +15,6 @@ pub async fn modify( ) -> GeneralResult { db::file::get_permissions(params.file_id, claims.user_id, &state.pool) .await - .map_err(GeneralError::permissions)? .can_write_guard()?; // Very weird work around to get the first file in multipart diff --git a/src/endpoints/file/upload.rs b/src/endpoints/file/upload.rs index 8314078..76d7e0a 100644 --- a/src/endpoints/file/upload.rs +++ b/src/endpoints/file/upload.rs @@ -39,7 +39,6 @@ pub async fn upload( ) -> GeneralResult>> { db::folder::get_permissions(params.parent_folder, claims.user_id, &state.pool) .await - .map_err(GeneralError::permissions)? .can_write_guard()?; let existing_names: HashSet = db::folder::get_names(params.parent_folder, &state.pool) diff --git a/src/endpoints/folder/create.rs b/src/endpoints/folder/create.rs index 7110c66..5b70271 100644 --- a/src/endpoints/folder/create.rs +++ b/src/endpoints/folder/create.rs @@ -13,7 +13,6 @@ pub async fn create( ) -> GeneralResult> { db::folder::get_permissions(params.parent_folder_id, claims.user_id, &pool) .await - .map_err(GeneralError::permissions)? .can_write_guard()?; let exists = db::folder::name_exists(params.parent_folder_id, ¶ms.folder_name, &pool) diff --git a/src/endpoints/folder/delete.rs b/src/endpoints/folder/delete.rs index a482a68..30e9c4d 100644 --- a/src/endpoints/folder/delete.rs +++ b/src/endpoints/folder/delete.rs @@ -22,7 +22,6 @@ pub async fn delete( db::folder::get_permissions(params.folder_id, claims.user_id, &state.pool) .await - .map_err(GeneralError::permissions)? .can_write_guard()?; let storage = &state.storage; diff --git a/src/endpoints/folder/get_structure.rs b/src/endpoints/folder/get_structure.rs index 3be156e..dca16dc 100644 --- a/src/endpoints/folder/get_structure.rs +++ b/src/endpoints/folder/get_structure.rs @@ -28,7 +28,7 @@ pub async fn structure( ) -> GeneralResult> { let folder_id = db::folder::process_id(params.folder_id, claims.user_id, &pool) .await - .map_err(GeneralError::permissions)? + .handle_internal("Error processing id")? .ok_or_else(GeneralError::item_not_found)?; let folder = db::folder::get_by_id(folder_id, &pool) diff --git a/src/endpoints/folder/list.rs b/src/endpoints/folder/list.rs index a35500f..53e089d 100644 --- a/src/endpoints/folder/list.rs +++ b/src/endpoints/folder/list.rs @@ -21,7 +21,7 @@ pub async fn list( ) -> GeneralResult> { let folder_id = db::folder::process_id(params.folder_id, claims.user_id, &pool) .await - .map_err(GeneralError::permissions)? + .handle_internal("Error processing id")? .handle(StatusCode::NOT_FOUND, "Item not found")?; let (files, folders) = try_join!( diff --git a/src/endpoints/permissions/delete.rs b/src/endpoints/permissions/delete.rs index 0c1d7df..177f6ad 100644 --- a/src/endpoints/permissions/delete.rs +++ b/src/endpoints/permissions/delete.rs @@ -14,7 +14,6 @@ pub async fn delete( if params.user_id != claims.user_id { db::folder::get_permissions(params.folder_id, claims.user_id, &pool) .await - .map_err(GeneralError::permissions)? .can_manage_guard()?; } diff --git a/src/endpoints/permissions/get.rs b/src/endpoints/permissions/get.rs index 79e561f..98983b2 100644 --- a/src/endpoints/permissions/get.rs +++ b/src/endpoints/permissions/get.rs @@ -16,7 +16,6 @@ pub async fn get( ) -> GeneralResult>> { db::folder::get_permissions(params.folder_id, claims.user_id, &pool) .await - .map_err(GeneralError::permissions)? .can_manage_guard()?; let permissions = db::permissions::get_all_for_folder(params.folder_id, &pool) diff --git a/src/endpoints/permissions/set.rs b/src/endpoints/permissions/set.rs index f1e4558..55da2cb 100644 --- a/src/endpoints/permissions/set.rs +++ b/src/endpoints/permissions/set.rs @@ -24,7 +24,6 @@ pub async fn set( db::folder::get_permissions(params.folder_id, claims.user_id, &pool) .await - .map_err(GeneralError::permissions)? .can_manage_guard()?; let folder_info = db::folder::get_by_id(params.folder_id, &pool) diff --git a/src/errors.rs b/src/errors.rs index dc48e0d..5803512 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -26,14 +26,6 @@ impl GeneralError { Self::message(StatusCode::BAD_REQUEST, error.to_string()) } - pub fn permissions(error: sqlx::Error) -> Self { - GeneralError { - status_code: StatusCode::INTERNAL_SERVER_ERROR, - message: Cow::Borrowed("Error getting permissions"), - error: Some(error.into()), - } - } - pub const fn item_not_found() -> Self { GeneralError { status_code: StatusCode::NOT_FOUND, diff --git a/src/prelude.rs b/src/prelude.rs index 5be2406..c2ee2e4 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,6 +1,6 @@ pub(crate) use crate::{ auth::Claims, - db, + db::{self, permissions::PermissionExt as _}, errors::{ErrorHandlingExt as _, GeneralError, GeneralResult}, AppState, Pool, };