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::*;
 | 
			
		||||
 | 
			
		||||
@@ -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<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(
 | 
			
		||||
    user_id: i32,
 | 
			
		||||
    folder_id: Uuid,
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,6 @@ pub async fn delete(
 | 
			
		||||
) -> GeneralResult<StatusCode> {
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ pub async fn download(
 | 
			
		||||
) -> GeneralResult<impl IntoResponse> {
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ pub async fn modify(
 | 
			
		||||
) -> GeneralResult<StatusCode> {
 | 
			
		||||
    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
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,6 @@ pub async fn upload(
 | 
			
		||||
) -> GeneralResult<Json<HashMap<String, Uuid>>> {
 | 
			
		||||
    db::folder::get_permissions(params.parent_folder, claims.user_id, &state.pool)
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(GeneralError::permissions)?
 | 
			
		||||
        .can_write_guard()?;
 | 
			
		||||
 | 
			
		||||
    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>> {
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ pub async fn structure(
 | 
			
		||||
) -> GeneralResult<Json<FolderStructure>> {
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ pub async fn list(
 | 
			
		||||
) -> GeneralResult<Json<Response>> {
 | 
			
		||||
    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!(
 | 
			
		||||
 
 | 
			
		||||
@@ -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()?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,6 @@ pub async fn get(
 | 
			
		||||
) -> GeneralResult<Json<HashMap<String, PermissionRaw>>> {
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
pub(crate) use crate::{
 | 
			
		||||
    auth::Claims,
 | 
			
		||||
    db,
 | 
			
		||||
    db::{self, permissions::PermissionExt as _},
 | 
			
		||||
    errors::{ErrorHandlingExt as _, GeneralError, GeneralResult},
 | 
			
		||||
    AppState, Pool,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user