Permission guard simplification
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
				
			|||||||
use std::collections::HashMap;
 | 
					use std::{borrow::Cow, collections::HashMap};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::prelude::*;
 | 
					use crate::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,7 +37,7 @@ impl PermissionType {
 | 
				
			|||||||
        self >= PermissionType::Read
 | 
					        self >= PermissionType::Read
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn can_read_guard(self) -> GeneralResult<()> {
 | 
					    fn can_read_guard(self) -> GeneralResult<()> {
 | 
				
			||||||
        if !self.can_read() {
 | 
					        if !self.can_read() {
 | 
				
			||||||
            return Err(GeneralError::message(
 | 
					            return Err(GeneralError::message(
 | 
				
			||||||
                StatusCode::NOT_FOUND,
 | 
					                StatusCode::NOT_FOUND,
 | 
				
			||||||
@@ -47,7 +47,7 @@ impl PermissionType {
 | 
				
			|||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn can_write_guard(self) -> GeneralResult<()> {
 | 
					    fn can_write_guard(self) -> GeneralResult<()> {
 | 
				
			||||||
        self.can_read_guard()?;
 | 
					        self.can_read_guard()?;
 | 
				
			||||||
        if self < PermissionType::Write {
 | 
					        if self < PermissionType::Write {
 | 
				
			||||||
            return Err(GeneralError::message(
 | 
					            return Err(GeneralError::message(
 | 
				
			||||||
@@ -58,7 +58,7 @@ impl PermissionType {
 | 
				
			|||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn can_manage_guard(self) -> GeneralResult<()> {
 | 
					    fn can_manage_guard(self) -> GeneralResult<()> {
 | 
				
			||||||
        self.can_read_guard()?;
 | 
					        self.can_read_guard()?;
 | 
				
			||||||
        if self < PermissionType::Manage {
 | 
					        if self < PermissionType::Manage {
 | 
				
			||||||
            return Err(GeneralError::message(
 | 
					            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<PermissionType>,
 | 
				
			||||||
 | 
					    func: impl FnOnce(PermissionType) -> GeneralResult<()>,
 | 
				
			||||||
 | 
					) -> GeneralResult<()> {
 | 
				
			||||||
 | 
					    result.map_err(permissions_error).and_then(func)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PermissionExt for sqlx::Result<PermissionType> {
 | 
				
			||||||
 | 
					    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(
 | 
					pub async fn insert(
 | 
				
			||||||
    user_id: i32,
 | 
					    user_id: i32,
 | 
				
			||||||
    folder_id: Uuid,
 | 
					    folder_id: Uuid,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,6 @@ pub async fn delete(
 | 
				
			|||||||
) -> GeneralResult<StatusCode> {
 | 
					) -> GeneralResult<StatusCode> {
 | 
				
			||||||
    db::file::get_permissions(params.file_id, claims.user_id, &state.pool)
 | 
					    db::file::get_permissions(params.file_id, claims.user_id, &state.pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
        .can_write_guard()?;
 | 
					        .can_write_guard()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let deleted = db::file::delete(params.file_id, &state.pool)
 | 
					    let deleted = db::file::delete(params.file_id, &state.pool)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ pub async fn download(
 | 
				
			|||||||
) -> GeneralResult<impl IntoResponse> {
 | 
					) -> GeneralResult<impl IntoResponse> {
 | 
				
			||||||
    db::file::get_permissions(params.file_id, claims.user_id, &state.pool)
 | 
					    db::file::get_permissions(params.file_id, claims.user_id, &state.pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
        .can_read_guard()?;
 | 
					        .can_read_guard()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut name = db::file::get_name(params.file_id, &state.pool)
 | 
					    let mut name = db::file::get_name(params.file_id, &state.pool)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ pub async fn modify(
 | 
				
			|||||||
) -> GeneralResult<StatusCode> {
 | 
					) -> GeneralResult<StatusCode> {
 | 
				
			||||||
    db::file::get_permissions(params.file_id, claims.user_id, &state.pool)
 | 
					    db::file::get_permissions(params.file_id, claims.user_id, &state.pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
        .can_write_guard()?;
 | 
					        .can_write_guard()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Very weird work around to get the first file in multipart
 | 
					    // Very weird work around to get the first file in multipart
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,6 @@ pub async fn upload(
 | 
				
			|||||||
) -> GeneralResult<Json<HashMap<String, Uuid>>> {
 | 
					) -> GeneralResult<Json<HashMap<String, Uuid>>> {
 | 
				
			||||||
    db::folder::get_permissions(params.parent_folder, claims.user_id, &state.pool)
 | 
					    db::folder::get_permissions(params.parent_folder, claims.user_id, &state.pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
        .can_write_guard()?;
 | 
					        .can_write_guard()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let existing_names: HashSet<String> = db::folder::get_names(params.parent_folder, &state.pool)
 | 
					    let existing_names: HashSet<String> = db::folder::get_names(params.parent_folder, &state.pool)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,6 @@ pub async fn create(
 | 
				
			|||||||
) -> GeneralResult<Json<Uuid>> {
 | 
					) -> GeneralResult<Json<Uuid>> {
 | 
				
			||||||
    db::folder::get_permissions(params.parent_folder_id, claims.user_id, &pool)
 | 
					    db::folder::get_permissions(params.parent_folder_id, claims.user_id, &pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
        .can_write_guard()?;
 | 
					        .can_write_guard()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let exists = db::folder::name_exists(params.parent_folder_id, ¶ms.folder_name, &pool)
 | 
					    let exists = db::folder::name_exists(params.parent_folder_id, ¶ms.folder_name, &pool)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,6 @@ pub async fn delete(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    db::folder::get_permissions(params.folder_id, claims.user_id, &state.pool)
 | 
					    db::folder::get_permissions(params.folder_id, claims.user_id, &state.pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
        .can_write_guard()?;
 | 
					        .can_write_guard()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let storage = &state.storage;
 | 
					    let storage = &state.storage;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,7 @@ pub async fn structure(
 | 
				
			|||||||
) -> GeneralResult<Json<FolderStructure>> {
 | 
					) -> GeneralResult<Json<FolderStructure>> {
 | 
				
			||||||
    let folder_id = db::folder::process_id(params.folder_id, claims.user_id, &pool)
 | 
					    let folder_id = db::folder::process_id(params.folder_id, claims.user_id, &pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					        .handle_internal("Error processing id")?
 | 
				
			||||||
        .ok_or_else(GeneralError::item_not_found)?;
 | 
					        .ok_or_else(GeneralError::item_not_found)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let folder = db::folder::get_by_id(folder_id, &pool)
 | 
					    let folder = db::folder::get_by_id(folder_id, &pool)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,7 @@ pub async fn list(
 | 
				
			|||||||
) -> GeneralResult<Json<Response>> {
 | 
					) -> GeneralResult<Json<Response>> {
 | 
				
			||||||
    let folder_id = db::folder::process_id(params.folder_id, claims.user_id, &pool)
 | 
					    let folder_id = db::folder::process_id(params.folder_id, claims.user_id, &pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					        .handle_internal("Error processing id")?
 | 
				
			||||||
        .handle(StatusCode::NOT_FOUND, "Item not found")?;
 | 
					        .handle(StatusCode::NOT_FOUND, "Item not found")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let (files, folders) = try_join!(
 | 
					    let (files, folders) = try_join!(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,6 @@ pub async fn delete(
 | 
				
			|||||||
    if params.user_id != claims.user_id {
 | 
					    if params.user_id != claims.user_id {
 | 
				
			||||||
        db::folder::get_permissions(params.folder_id, claims.user_id, &pool)
 | 
					        db::folder::get_permissions(params.folder_id, claims.user_id, &pool)
 | 
				
			||||||
            .await
 | 
					            .await
 | 
				
			||||||
            .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
            .can_manage_guard()?;
 | 
					            .can_manage_guard()?;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,6 @@ pub async fn get(
 | 
				
			|||||||
) -> GeneralResult<Json<HashMap<String, PermissionRaw>>> {
 | 
					) -> GeneralResult<Json<HashMap<String, PermissionRaw>>> {
 | 
				
			||||||
    db::folder::get_permissions(params.folder_id, claims.user_id, &pool)
 | 
					    db::folder::get_permissions(params.folder_id, claims.user_id, &pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
        .can_manage_guard()?;
 | 
					        .can_manage_guard()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let permissions = db::permissions::get_all_for_folder(params.folder_id, &pool)
 | 
					    let permissions = db::permissions::get_all_for_folder(params.folder_id, &pool)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,6 @@ pub async fn set(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    db::folder::get_permissions(params.folder_id, claims.user_id, &pool)
 | 
					    db::folder::get_permissions(params.folder_id, claims.user_id, &pool)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(GeneralError::permissions)?
 | 
					 | 
				
			||||||
        .can_manage_guard()?;
 | 
					        .can_manage_guard()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let folder_info = db::folder::get_by_id(params.folder_id, &pool)
 | 
					    let folder_info = db::folder::get_by_id(params.folder_id, &pool)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,14 +26,6 @@ impl GeneralError {
 | 
				
			|||||||
        Self::message(StatusCode::BAD_REQUEST, error.to_string())
 | 
					        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 {
 | 
					    pub const fn item_not_found() -> Self {
 | 
				
			||||||
        GeneralError {
 | 
					        GeneralError {
 | 
				
			||||||
            status_code: StatusCode::NOT_FOUND,
 | 
					            status_code: StatusCode::NOT_FOUND,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
pub(crate) use crate::{
 | 
					pub(crate) use crate::{
 | 
				
			||||||
    auth::Claims,
 | 
					    auth::Claims,
 | 
				
			||||||
    db,
 | 
					    db::{self, permissions::PermissionExt as _},
 | 
				
			||||||
    errors::{ErrorHandlingExt as _, GeneralError, GeneralResult},
 | 
					    errors::{ErrorHandlingExt as _, GeneralError, GeneralResult},
 | 
				
			||||||
    AppState, Pool,
 | 
					    AppState, Pool,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user