use mongodb::bson::DateTime; use mongodb::bson::{doc, oid::ObjectId}; use mongodb::Collection; use serde::{Deserialize, Serialize}; use super::permission::Permission; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Share { #[serde(rename = "_id", skip_serializing_if = "Option::is_none")] pub id: Option, pub owner_id: ObjectId, pub target_user_id: ObjectId, pub resource_type: String, #[serde(skip_serializing_if = "Option::is_none")] pub resource_id: Option, pub permissions: Vec, #[serde(skip_serializing_if = "Option::is_none")] pub expires_at: Option, pub created_at: DateTime, pub active: bool, } impl Share { pub fn new( owner_id: ObjectId, target_user_id: ObjectId, resource_type: String, resource_id: Option, permissions: Vec, expires_at: Option, ) -> Self { Self { id: None, owner_id, target_user_id, resource_type, resource_id, permissions, expires_at, created_at: DateTime::now(), active: true, } } pub fn is_expired(&self) -> bool { if let Some(expires) = self.expires_at { DateTime::now() > expires } else { false } } pub fn has_permission(&self, permission: &Permission) -> bool { self.permissions.contains(permission) || self.permissions.contains(&Permission::Admin) } pub fn revoke(&mut self) { self.active = false; } } #[derive(Clone)] pub struct ShareRepository { collection: Collection, } impl ShareRepository { pub fn new(collection: Collection) -> Self { Self { collection } } pub async fn create(&self, share: &Share) -> mongodb::error::Result> { let result = self.collection.insert_one(share, None).await?; Ok(Some(result.inserted_id.as_object_id().unwrap())) } pub async fn find_by_id(&self, id: &ObjectId) -> mongodb::error::Result> { self.collection.find_one(doc! { "_id": id }, None).await } pub async fn find_by_owner(&self, owner_id: &ObjectId) -> mongodb::error::Result> { use futures::stream::TryStreamExt; self.collection .find(doc! { "owner_id": owner_id }, None) .await? .try_collect() .await } pub async fn find_by_target( &self, target_user_id: &ObjectId, ) -> mongodb::error::Result> { use futures::stream::TryStreamExt; self.collection .find( doc! { "target_user_id": target_user_id, "active": true }, None, ) .await? .try_collect() .await } pub async fn update(&self, share: &Share) -> mongodb::error::Result<()> { if let Some(id) = &share.id { self.collection .replace_one(doc! { "_id": id }, share, None) .await?; } Ok(()) } pub async fn delete(&self, share_id: &ObjectId) -> mongodb::error::Result<()> { self.collection .delete_one(doc! { "_id": share_id }, None) .await?; Ok(()) } }