From: Felix Ableitner Date: Sat, 16 Oct 2021 11:14:02 +0000 (+0200) Subject: Remove DeletableApubObject trait X-Git-Url: http://these/git/%7B%60%24%7BwebArchiveUrl%7D/%22%7B%7D/%22https:/nerdica.net/%7BimageUploadUrl%7D?a=commitdiff_plain;h=d206aad282ac1bc1266b087a963c7024a4b54e27;p=lemmy.git Remove DeletableApubObject trait --- diff --git a/crates/apub/src/fetcher/deletable_apub_object.rs b/crates/apub/src/fetcher/deletable_apub_object.rs deleted file mode 100644 index 503949e1..00000000 --- a/crates/apub/src/fetcher/deletable_apub_object.rs +++ /dev/null @@ -1,99 +0,0 @@ -use crate::fetcher::post_or_comment::PostOrComment; -use lemmy_api_common::blocking; -use lemmy_db_queries::source::{ - comment::Comment_, - community::Community_, - person::Person_, - post::Post_, -}; -use lemmy_db_schema::source::{ - comment::Comment, - community::Community, - person::Person, - post::Post, - private_message::PrivateMessage, -}; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - -// TODO: merge this trait with ApubObject (means that db_schema needs to depend on apub_lib) -#[async_trait::async_trait(?Send)] -pub trait DeletableApubObject { - // TODO: pass in tombstone with summary field, to decide between remove/delete - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError>; -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for Community { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - let id = self.id; - blocking(context.pool(), move |conn| { - Community::update_deleted(conn, id, true) - }) - .await??; - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for Person { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - let id = self.id; - blocking(context.pool(), move |conn| Person::delete_account(conn, id)).await??; - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for Post { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - let id = self.id; - blocking(context.pool(), move |conn| { - Post::update_deleted(conn, id, true) - }) - .await??; - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for Comment { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - let id = self.id; - blocking(context.pool(), move |conn| { - Comment::update_deleted(conn, id, true) - }) - .await??; - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for PostOrComment { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - match self { - PostOrComment::Comment(c) => { - blocking(context.pool(), move |conn| { - Comment::update_deleted(conn, c.id, true) - }) - .await??; - } - PostOrComment::Post(p) => { - blocking(context.pool(), move |conn| { - Post::update_deleted(conn, p.id, true) - }) - .await??; - } - } - - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for PrivateMessage { - async fn delete(self, _context: &LemmyContext) -> Result<(), LemmyError> { - // do nothing, because pm can't be fetched over http - unimplemented!() - } -} diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index b1b9e9ad..641d59f0 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -1,5 +1,4 @@ pub mod community; -pub mod deletable_apub_object; mod fetch; pub mod object_id; pub mod post_or_comment; diff --git a/crates/apub/src/fetcher/object_id.rs b/crates/apub/src/fetcher/object_id.rs index 69d7c028..14e983bb 100644 --- a/crates/apub/src/fetcher/object_id.rs +++ b/crates/apub/src/fetcher/object_id.rs @@ -1,7 +1,4 @@ -use crate::{ - fetcher::{deletable_apub_object::DeletableApubObject, should_refetch_actor}, - objects::FromApub, -}; +use crate::{fetcher::should_refetch_actor, objects::FromApub}; use anyhow::anyhow; use diesel::{NotFound, PgConnection}; use lemmy_api_common::blocking; @@ -26,12 +23,12 @@ static REQUEST_LIMIT: i32 = 25; #[derive(Clone, PartialEq, Serialize, Deserialize, Debug)] pub struct ObjectId(Url, #[serde(skip)] PhantomData) where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de2> ::ApubType: serde::Deserialize<'de2>; impl ObjectId where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { pub fn new(url: T) -> Self @@ -117,7 +114,7 @@ where if res.status() == StatusCode::GONE { if let Some(db_object) = db_object { - db_object.delete(context).await?; + blocking(context.pool(), move |conn| db_object.delete(conn)).await??; } return Err(anyhow!("Fetched remote object {} which was deleted", self).into()); } @@ -130,7 +127,7 @@ where impl Display for ObjectId where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { @@ -140,7 +137,7 @@ where impl From> for Url where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn from(id: ObjectId) -> Self { @@ -150,7 +147,7 @@ where impl From> for DbUrl where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn from(id: ObjectId) -> Self { diff --git a/crates/apub/src/fetcher/post_or_comment.rs b/crates/apub/src/fetcher/post_or_comment.rs index 23fc709d..9d700c96 100644 --- a/crates/apub/src/fetcher/post_or_comment.rs +++ b/crates/apub/src/fetcher/post_or_comment.rs @@ -48,6 +48,13 @@ impl ApubObject for PostOrComment { None => Comment::read_from_apub_id(conn, object_id)?.map(PostOrComment::Comment), }) } + + fn delete(self, data: &Self::DataType) -> Result<(), LemmyError> { + match self { + PostOrComment::Post(p) => p.delete(data), + PostOrComment::Comment(c) => c.delete(data), + } + } } #[async_trait::async_trait(?Send)] diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs index c8ac0d92..9fcf5a79 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -1,5 +1,5 @@ use crate::{ - fetcher::{deletable_apub_object::DeletableApubObject, object_id::ObjectId}, + fetcher::object_id::ObjectId, objects::{comment::Note, community::Group, person::Person as ApubPerson, post::Page, FromApub}, }; use activitystreams::chrono::NaiveDateTime; @@ -136,6 +136,15 @@ impl ApubObject for SearchableObjects { } Ok(None) } + + fn delete(self, conn: &Self::DataType) -> Result<(), LemmyError> { + match self { + SearchableObjects::Person(p) => p.delete(conn), + SearchableObjects::Community(c) => c.delete(conn), + SearchableObjects::Post(p) => p.delete(conn), + SearchableObjects::Comment(c) => c.delete(conn), + } + } } #[async_trait::async_trait(?Send)] @@ -158,15 +167,3 @@ impl FromApub for SearchableObjects { }) } } - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for SearchableObjects { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - match self { - SearchableObjects::Person(p) => p.delete(context).await, - SearchableObjects::Community(c) => c.delete(context).await, - SearchableObjects::Post(p) => p.delete(context).await, - SearchableObjects::Comment(c) => c.delete(context).await, - } - } -} diff --git a/crates/apub_lib/src/traits.rs b/crates/apub_lib/src/traits.rs index f8cdba0a..16fb3f8e 100644 --- a/crates/apub_lib/src/traits.rs +++ b/crates/apub_lib/src/traits.rs @@ -36,6 +36,8 @@ pub trait ApubObject { fn read_from_apub_id(data: &Self::DataType, object_id: Url) -> Result, LemmyError> where Self: Sized; + /// Marks the object as deleted in local db. Called when a tombstone is received. + fn delete(self, data: &Self::DataType) -> Result<(), LemmyError>; } /// Common methods provided by ActivityPub actors (community and person). Not all methods are diff --git a/crates/db_schema/src/source/comment.rs b/crates/db_schema/src/source/comment.rs index 63062d1d..54e8221f 100644 --- a/crates/db_schema/src/source/comment.rs +++ b/crates/db_schema/src/source/comment.rs @@ -1,4 +1,5 @@ use crate::{ + naive_now, schema::{comment, comment_alias_1, comment_like, comment_saved}, source::post::Post, CommentId, @@ -126,4 +127,14 @@ impl ApubObject for Comment { let object_id: DbUrl = object_id.into(); Ok(comment.filter(ap_id.eq(object_id)).first::(conn).ok()) } + + // TODO: duplicate code from Comment::update_deleted(), we should really move all impls to + // this crate so we can call that function from here + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::comment::dsl::*; + diesel::update(comment.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } } diff --git a/crates/db_schema/src/source/community.rs b/crates/db_schema/src/source/community.rs index f90bab13..365ddba7 100644 --- a/crates/db_schema/src/source/community.rs +++ b/crates/db_schema/src/source/community.rs @@ -1,4 +1,5 @@ use crate::{ + naive_now, schema::{community, community_follower, community_moderator, community_person_ban}, CommunityId, DbUrl, @@ -147,6 +148,14 @@ impl ApubObject for Community { .ok(), ) } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::community::dsl::*; + diesel::update(community.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } } impl ActorType for Community { diff --git a/crates/db_schema/src/source/person.rs b/crates/db_schema/src/source/person.rs index 03fb821f..f71f39dc 100644 --- a/crates/db_schema/src/source/person.rs +++ b/crates/db_schema/src/source/person.rs @@ -1,4 +1,5 @@ use crate::{ + naive_now, schema::{person, person_alias_1, person_alias_2}, DbUrl, PersonId, @@ -194,6 +195,14 @@ impl ApubObject for Person { .ok(), ) } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::person::dsl::*; + diesel::update(person.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } } impl ActorType for Person { diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs index a09e8839..d28599c5 100644 --- a/crates/db_schema/src/source/post.rs +++ b/crates/db_schema/src/source/post.rs @@ -1,4 +1,5 @@ use crate::{ + naive_now, schema::{post, post_like, post_read, post_saved}, CommunityId, DbUrl, @@ -124,4 +125,12 @@ impl ApubObject for Post { let object_id: DbUrl = object_id.into(); Ok(post.filter(ap_id.eq(object_id)).first::(conn).ok()) } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::post::dsl::*; + diesel::update(post.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } } diff --git a/crates/db_schema/src/source/private_message.rs b/crates/db_schema/src/source/private_message.rs index a867ce93..6247cb95 100644 --- a/crates/db_schema/src/source/private_message.rs +++ b/crates/db_schema/src/source/private_message.rs @@ -54,4 +54,9 @@ impl ApubObject for PrivateMessage { .ok(), ) } + + fn delete(self, _conn: &PgConnection) -> Result<(), LemmyError> { + // do nothing, because pm can't be fetched over http + unimplemented!() + } }