Implement authorization service and refactor services to use it
- Added `AuthorizationService` and its implementation `AuthorizationServiceImpl` to handle permission checks across various services. - Refactored `AlbumServiceImpl`, `MediaServiceImpl`, `PersonServiceImpl`, and `TagServiceImpl` to utilize the new authorization service for permission checks. - Removed direct permission checks from services and replaced them with calls to the `AuthorizationService`. - Updated repository interfaces to include new methods for checking media permissions in shared albums. - Enhanced the `authz` module with new permission types for better granularity in access control. - Adjusted the `AppState` struct to include the new `authorization_service`.
This commit is contained in:
@@ -2,6 +2,34 @@ use uuid::Uuid;
|
||||
|
||||
use crate::models::{Album, AlbumPermission, Media, Person, PersonPermission, Role, User};
|
||||
|
||||
pub enum Permission {
|
||||
// Media
|
||||
ViewMedia(Uuid),
|
||||
EditMedia(Uuid),
|
||||
AddTags(Uuid),
|
||||
RemoveTags(Uuid),
|
||||
EditTags(Uuid),
|
||||
DeleteMedia(Uuid),
|
||||
|
||||
// Albums
|
||||
ViewAlbum(Uuid),
|
||||
AddToAlbum(Uuid),
|
||||
EditAlbum(Uuid),
|
||||
ShareAlbum(Uuid),
|
||||
DeleteAlbum(Uuid),
|
||||
|
||||
// People
|
||||
ViewPerson(Uuid),
|
||||
EditPerson(Uuid),
|
||||
UsePerson(Uuid),
|
||||
SharePerson(Uuid),
|
||||
DeletePerson(Uuid),
|
||||
|
||||
// Faces
|
||||
ViewFaces(Uuid),
|
||||
AssignFace(Uuid),
|
||||
}
|
||||
|
||||
pub trait Ownable {
|
||||
fn owner_id(&self) -> Uuid;
|
||||
}
|
||||
@@ -48,10 +76,18 @@ pub fn can_contribute_to_album(
|
||||
is_owner(user_id, album) || share_permission == Some(AlbumPermission::Contribute)
|
||||
}
|
||||
|
||||
pub fn can_access_person(user_id: Uuid, person: &Person, share_permission: Option<PersonPermission>) -> bool {
|
||||
pub fn can_access_person(
|
||||
user_id: Uuid,
|
||||
person: &Person,
|
||||
share_permission: Option<PersonPermission>,
|
||||
) -> bool {
|
||||
is_owner(user_id, person) || share_permission.is_some()
|
||||
}
|
||||
|
||||
pub fn can_edit_person(user_id: Uuid, person: &Person, share_permission: Option<PersonPermission>) -> bool {
|
||||
pub fn can_use_person(
|
||||
user_id: Uuid,
|
||||
person: &Person,
|
||||
share_permission: Option<PersonPermission>,
|
||||
) -> bool {
|
||||
is_owner(user_id, person) || share_permission == Some(PersonPermission::CanUse)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
error::CoreResult,
|
||||
models::{Album, AlbumPermission, FaceRegion, Media, MediaMetadata, Person, PersonPermission, Tag, User}, schema::ListMediaOptions,
|
||||
models::{
|
||||
Album, AlbumPermission, FaceRegion, Media, MediaMetadata, Person, PersonPermission, Tag,
|
||||
User,
|
||||
},
|
||||
schema::ListMediaOptions,
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@@ -11,7 +15,11 @@ pub trait MediaRepository: Send + Sync {
|
||||
async fn find_by_hash(&self, hash: &str) -> CoreResult<Option<Media>>;
|
||||
async fn create(&self, media: &Media) -> CoreResult<()>;
|
||||
async fn find_by_id(&self, id: Uuid) -> CoreResult<Option<Media>>;
|
||||
async fn list_by_user(&self, user_id: Uuid, options: &ListMediaOptions) -> CoreResult<Vec<Media>>;
|
||||
async fn list_by_user(
|
||||
&self,
|
||||
user_id: Uuid,
|
||||
options: &ListMediaOptions,
|
||||
) -> CoreResult<Vec<Media>>;
|
||||
async fn update_thumbnail_path(&self, id: Uuid, thumbnail_path: String) -> CoreResult<()>;
|
||||
async fn delete(&self, id: Uuid) -> CoreResult<()>;
|
||||
}
|
||||
@@ -51,6 +59,11 @@ pub trait AlbumShareRepository: Send + Sync {
|
||||
) -> CoreResult<Option<AlbumPermission>>;
|
||||
|
||||
async fn is_media_in_shared_album(&self, media_id: Uuid, user_id: Uuid) -> CoreResult<bool>;
|
||||
async fn is_media_in_contributable_album(
|
||||
&self,
|
||||
media_id: Uuid,
|
||||
user_id: Uuid,
|
||||
) -> CoreResult<bool>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -65,7 +78,7 @@ pub trait TagRepository: Send + Sync {
|
||||
async fn add_tags_to_media(&self, media_id: Uuid, tag_ids: &[Uuid]) -> CoreResult<()>;
|
||||
async fn remove_tags_from_media(&self, media_id: Uuid, tag_ids: &[Uuid]) -> CoreResult<()>;
|
||||
async fn list_tags_for_media(&self, media_id: Uuid) -> CoreResult<Vec<Tag>>;
|
||||
async fn find_tag_by_name(&self, name: &str) -> CoreResult<Option<Tag>>;
|
||||
async fn find_tag_by_name(&self, name: &str) -> CoreResult<Option<Tag>>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -107,4 +120,4 @@ pub trait PersonShareRepository: Send + Sync {
|
||||
&self,
|
||||
user_id: Uuid,
|
||||
) -> CoreResult<Vec<(Person, PersonPermission)>>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,9 @@ use async_trait::async_trait;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
error::CoreResult,
|
||||
models::{Album, FaceRegion, Media, MediaBundle, Person, PersonPermission, Tag, User},
|
||||
schema::{
|
||||
authz::Permission, error::CoreResult, models::{Album, FaceRegion, Media, MediaBundle, Person, PersonPermission, Tag, User}, schema::{
|
||||
AddMediaToAlbumData, CreateAlbumData, CreateUserData, ListMediaOptions, LoginUserData, ShareAlbumData, UpdateAlbumData, UploadMediaData
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@@ -84,4 +82,9 @@ pub trait PersonService: Send + Sync {
|
||||
target_user_id: Uuid,
|
||||
owner_id: Uuid,
|
||||
) -> CoreResult<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait AuthorizationService: Send + Sync {
|
||||
async fn check_permission(&self, user_id: Uuid, permission: Permission) -> CoreResult<()>;
|
||||
}
|
||||
Reference in New Issue
Block a user