Permission guard simplification

This commit is contained in:
StNicolay 2024-08-05 23:45:00 +03:00
parent 9f76228ebe
commit eba30d1e9d
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
14 changed files with 42 additions and 24 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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, &params.folder_name, &pool) let exists = db::folder::name_exists(params.parent_folder_id, &params.folder_name, &pool)

View File

@ -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;

View File

@ -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)

View File

@ -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!(

View File

@ -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()?;
} }

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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,
}; };