From 78aa717560bd6c1a12fe98bc955d8de968d9247c Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Wed, 7 Jul 2021 16:40:19 +0200 Subject: [PATCH] working activity routing! --- api_tests/package.json | 2 +- api_tests/src/post.spec.ts | 3 +- crates/apub/src/fetcher/mod.rs | 6 -- crates/apub_lib/src/lib.rs | 17 +---- .../src/activities/comment/create.rs | 37 ++++++----- .../src/activities/comment/delete.rs | 28 ++++---- .../src/activities/comment/dislike.rs | 31 +++++---- .../src/activities/comment/like.rs | 31 +++++---- .../src/activities/comment/mod.rs | 7 +- .../src/activities/comment/remove.rs | 28 ++++---- .../src/activities/comment/undo_delete.rs | 39 ++++++----- .../src/activities/comment/undo_dislike.rs | 39 ++++++----- .../src/activities/comment/undo_like.rs | 39 ++++++----- .../src/activities/comment/undo_remove.rs | 35 +++++----- .../src/activities/comment/update.rs | 36 +++++----- .../src/activities/community/add_mod.rs | 43 ++++++------ .../src/activities/community/announce.rs | 65 +++++++------------ .../src/activities/community/block_user.rs | 40 ++++++------ .../src/activities/community/delete.rs | 41 ++++++------ .../src/activities/community/remove.rs | 27 ++++---- .../src/activities/community/remove_mod.rs | 43 ++++++------ .../activities/community/undo_block_user.rs | 45 +++++++------ .../src/activities/community/undo_delete.rs | 57 ++++++++-------- .../src/activities/community/undo_remove.rs | 38 ++++++----- .../src/activities/community/update.rs | 37 +++++------ .../src/activities/following/accept.rs | 21 +++--- .../src/activities/following/follow.rs | 33 +++++----- .../src/activities/following/undo.rs | 46 +++++++------ crates/apub_receive/src/activities/mod.rs | 25 ------- .../src/activities/post/delete.rs | 27 ++++---- .../src/activities/post/dislike.rs | 31 +++++---- .../apub_receive/src/activities/post/like.rs | 13 ++-- .../apub_receive/src/activities/post/mod.rs | 16 +++-- .../src/activities/post/remove.rs | 27 ++++---- .../src/activities/post/undo_delete.rs | 40 ++++++------ .../src/activities/post/undo_dislike.rs | 39 ++++++----- .../src/activities/post/undo_like.rs | 39 ++++++----- .../src/activities/post/undo_remove.rs | 36 +++++----- .../src/activities/post/update.rs | 33 +++++----- .../src/activities/private_message/create.rs | 31 +++++---- .../src/activities/private_message/delete.rs | 27 ++++---- .../activities/private_message/undo_delete.rs | 38 ++++++----- .../src/activities/private_message/update.rs | 31 +++++---- crates/apub_receive/src/http/community.rs | 22 +++---- crates/apub_receive/src/http/inbox_enums.rs | 62 ++---------------- crates/apub_receive/src/http/mod.rs | 26 +++++--- crates/apub_receive/src/http/person.rs | 22 +++---- 47 files changed, 739 insertions(+), 760 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 9b9ee1327..2a88a0983 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -9,7 +9,7 @@ "scripts": { "lint": "tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src", "fix": "prettier --write src && eslint --fix src", - "api-test": "jest src/post.spec.ts -i --verbose" + "api-test": "jest src/ -i --verbose" }, "devDependencies": { "@types/jest": "^26.0.23", diff --git a/api_tests/src/post.spec.ts b/api_tests/src/post.spec.ts index 243595921..36e5ac3fa 100644 --- a/api_tests/src/post.spec.ts +++ b/api_tests/src/post.spec.ts @@ -88,7 +88,7 @@ test('Create a post', async () => { let searchEpsilon = await searchPost(epsilon, postRes.post_view.post); expect(searchEpsilon.posts[0]).toBeUndefined(); }); -/* + test('Create a post in a non-existent community', async () => { let postRes = await createPost(alpha, -2); expect(postRes).toStrictEqual({ error: 'couldnt_create_post' }); @@ -363,4 +363,3 @@ test('Enforce community ban for federated user', async () => { let betaPost = searchBeta.posts[0]; expect(betaPost).toBeDefined(); }); -*/ \ No newline at end of file diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index ec12c22f2..477cecc87 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -37,12 +37,6 @@ where false } -// TODO: remove this -pub enum Actor { - Person, - Community, -} - /// Get a remote actor from its apub ID (either a person or a community). Thin wrapper around /// `get_or_fetch_and_upsert_person()` and `get_or_fetch_and_upsert_community()`. /// diff --git a/crates/apub_lib/src/lib.rs b/crates/apub_lib/src/lib.rs index 9b45add11..e3cfc0e12 100644 --- a/crates/apub_lib/src/lib.rs +++ b/crates/apub_lib/src/lib.rs @@ -65,6 +65,7 @@ pub trait ActivityHandlerNew { request_counter: &mut i32, ) -> Result<(), LemmyError>; + // todo: later handle request_counter completely inside library async fn receive( &self, context: &LemmyContext, @@ -73,22 +74,6 @@ pub trait ActivityHandlerNew { fn common(&self) -> &ActivityCommonFields; } -#[async_trait::async_trait(?Send)] -pub trait ActivityHandler { - type Actor; - - // TODO: also need to check for instance/community blocks in here - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError>; - - // todo: later handle request_counter completely inside library - async fn receive( - &self, - actor: Self::Actor, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError>; -} - pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), LemmyError> { if a.domain() != b.domain() { return Err(DomainError.into()); diff --git a/crates/apub_receive/src/activities/comment/create.rs b/crates/apub_receive/src/activities/comment/create.rs index 8d8008483..4259a956d 100644 --- a/crates/apub_receive/src/activities/comment/create.rs +++ b/crates/apub_receive/src/activities/comment/create.rs @@ -1,11 +1,8 @@ -use crate::activities::{ - comment::{get_notif_recipients, send_websocket_message}, - LemmyActivity, -}; +use crate::activities::comment::{get_notif_recipients, send_websocket_message}; use activitystreams::{activity::kind::CreateType, base::BaseExt}; -use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::{comment::Comment, person::Person}; +use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; +use lemmy_db_schema::source::comment::Comment; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -18,33 +15,33 @@ pub struct CreateComment { cc: Vec, #[serde(rename = "type")] kind: CreateType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - self.inner.object.id(self.actor.as_str())?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for CreateComment { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + self.object.id(self.common.actor.as_str())?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let comment = Comment::from_apub( - &self.inner.object, + &self.object, context, - actor.actor_id(), + self.common.actor.clone(), request_counter, false, ) .await?; - let recipients = get_notif_recipients(&self.actor, &comment, context, request_counter).await?; + let recipients = + get_notif_recipients(&self.common.actor, &comment, context, request_counter).await?; send_websocket_message( comment.id, recipients, @@ -53,4 +50,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/comment/delete.rs b/crates/apub_receive/src/activities/comment/delete.rs index a11ab72f5..73e692760 100644 --- a/crates/apub_receive/src/activities/comment/delete.rs +++ b/crates/apub_receive/src/activities/comment/delete.rs @@ -1,10 +1,10 @@ -use crate::activities::{comment::send_websocket_message, LemmyActivity}; +use crate::activities::comment::send_websocket_message; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::comment::Comment_; -use lemmy_db_schema::source::{comment::Comment, person::Person}; +use lemmy_db_schema::source::comment::Comment; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -17,26 +17,24 @@ pub struct DeleteComment { cc: [Url; 1], #[serde(rename = "type")] kind: DeleteType, + #[serde(flatten)] + pub(in crate::activities::comment) common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object)?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for DeleteComment { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object)?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let comment = - get_or_fetch_and_insert_comment(&self.inner.object, context, request_counter).await?; + let comment = get_or_fetch_and_insert_comment(&self.object, context, request_counter).await?; let deleted_comment = blocking(context.pool(), move |conn| { Comment::update_deleted(conn, comment.id, true) @@ -51,4 +49,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/comment/dislike.rs b/crates/apub_receive/src/activities/comment/dislike.rs index d5aafcd48..d80b19757 100644 --- a/crates/apub_receive/src/activities/comment/dislike.rs +++ b/crates/apub_receive/src/activities/comment/dislike.rs @@ -1,8 +1,7 @@ -use crate::activities::{comment::like_or_dislike_comment, LemmyActivity}; +use crate::activities::comment::like_or_dislike_comment; use activitystreams::activity::kind::DislikeType; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::person::Person; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -15,23 +14,33 @@ pub struct DislikeComment { cc: [Url; 1], #[serde(rename = "type")] kind: DislikeType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for DislikeComment { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - like_or_dislike_comment(-1, &actor, &self.inner.object, context, request_counter).await + like_or_dislike_comment( + -1, + &self.common.actor, + &self.object, + context, + request_counter, + ) + .await + } + + fn common(&self) -> &ActivityCommonFields { + &self.common } } diff --git a/crates/apub_receive/src/activities/comment/like.rs b/crates/apub_receive/src/activities/comment/like.rs index a73067638..ce45f10ff 100644 --- a/crates/apub_receive/src/activities/comment/like.rs +++ b/crates/apub_receive/src/activities/comment/like.rs @@ -1,8 +1,7 @@ -use crate::activities::{comment::like_or_dislike_comment, LemmyActivity}; +use crate::activities::comment::like_or_dislike_comment; use activitystreams::activity::kind::LikeType; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::person::Person; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -15,23 +14,33 @@ pub struct LikeComment { cc: [Url; 1], #[serde(rename = "type")] kind: LikeType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for LikeComment { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - like_or_dislike_comment(-1, &actor, &self.inner.object, context, request_counter).await + like_or_dislike_comment( + -1, + &self.common.actor, + &self.object, + context, + request_counter, + ) + .await + } + + fn common(&self) -> &ActivityCommonFields { + &self.common } } diff --git a/crates/apub_receive/src/activities/comment/mod.rs b/crates/apub_receive/src/activities/comment/mod.rs index 80338b15a..27a11256f 100644 --- a/crates/apub_receive/src/activities/comment/mod.rs +++ b/crates/apub_receive/src/activities/comment/mod.rs @@ -7,7 +7,6 @@ use lemmy_db_queries::{Crud, Likeable}; use lemmy_db_schema::{ source::{ comment::{Comment, CommentLike, CommentLikeForm}, - person::Person, post::Post, }, CommentId, @@ -79,11 +78,12 @@ async fn send_websocket_message Result<(), LemmyError> { + let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?; let comment = get_or_fetch_and_insert_comment(object, context, request_counter).await?; let comment_id = comment.id; @@ -110,11 +110,12 @@ async fn like_or_dislike_comment( } async fn undo_like_or_dislike_comment( - actor: &Person, + actor: &Url, object: &Url, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { + let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?; let comment = get_or_fetch_and_insert_comment(object, context, request_counter).await?; let comment_id = comment.id; diff --git a/crates/apub_receive/src/activities/comment/remove.rs b/crates/apub_receive/src/activities/comment/remove.rs index a12a26c03..b5d995ec6 100644 --- a/crates/apub_receive/src/activities/comment/remove.rs +++ b/crates/apub_receive/src/activities/comment/remove.rs @@ -1,10 +1,10 @@ -use crate::activities::{comment::send_websocket_message, verify_mod_action, LemmyActivity}; +use crate::activities::{comment::send_websocket_message, verify_mod_action}; use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::comment::Comment_; -use lemmy_db_schema::source::{comment::Comment, person::Person}; +use lemmy_db_schema::source::comment::Comment; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -17,26 +17,24 @@ pub struct RemoveComment { cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await +impl ActivityHandlerNew for RemoveComment { + async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let comment = - get_or_fetch_and_insert_comment(&self.inner.object, context, request_counter).await?; + let comment = get_or_fetch_and_insert_comment(&self.object, context, request_counter).await?; let removed_comment = blocking(context.pool(), move |conn| { Comment::update_removed(conn, comment.id, true) @@ -51,4 +49,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/comment/undo_delete.rs b/crates/apub_receive/src/activities/comment/undo_delete.rs index b540b6a47..f84f7ce75 100644 --- a/crates/apub_receive/src/activities/comment/undo_delete.rs +++ b/crates/apub_receive/src/activities/comment/undo_delete.rs @@ -1,13 +1,10 @@ -use crate::activities::{ - comment::{delete::DeleteComment, send_websocket_message}, - LemmyActivity, -}; +use crate::activities::comment::{delete::DeleteComment, send_websocket_message}; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::comment::Comment_; -use lemmy_db_schema::source::{comment::Comment, person::Person}; +use lemmy_db_schema::source::comment::Comment; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -16,32 +13,34 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDeleteComment { to: PublicUrl, - object: LemmyActivity, + object: DeleteComment, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object.actor)?; - check_is_apub_id_valid(&self.actor, false)?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoDeleteComment { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object.common.actor)?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let comment = - get_or_fetch_and_insert_comment(&self.inner.object.inner.object, context, request_counter) - .await?; + get_or_fetch_and_insert_comment(&self.object.object, context, request_counter).await?; let deleted_comment = blocking(context.pool(), move |conn| { Comment::update_deleted(conn, comment.id, false) @@ -56,4 +55,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/comment/undo_dislike.rs b/crates/apub_receive/src/activities/comment/undo_dislike.rs index 72d52c1c3..b15cb445a 100644 --- a/crates/apub_receive/src/activities/comment/undo_dislike.rs +++ b/crates/apub_receive/src/activities/comment/undo_dislike.rs @@ -1,11 +1,7 @@ -use crate::activities::{ - comment::{dislike::DislikeComment, undo_like_or_dislike_comment}, - LemmyActivity, -}; +use crate::activities::comment::{dislike::DislikeComment, undo_like_or_dislike_comment}; use activitystreams::activity::kind::UndoType; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::person::Person; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -14,35 +10,42 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDislikeComment { to: PublicUrl, - object: LemmyActivity, + object: DislikeComment, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.actor, false)?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoDislikeComment { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object.object)?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { undo_like_or_dislike_comment( - &actor, - &self.inner.object.inner.object, + &self.common.actor, + &self.object.object, context, request_counter, ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/comment/undo_like.rs b/crates/apub_receive/src/activities/comment/undo_like.rs index df87e1ad3..3892485e6 100644 --- a/crates/apub_receive/src/activities/comment/undo_like.rs +++ b/crates/apub_receive/src/activities/comment/undo_like.rs @@ -1,11 +1,7 @@ -use crate::activities::{ - comment::{like::LikeComment, undo_like_or_dislike_comment}, - LemmyActivity, -}; +use crate::activities::comment::{like::LikeComment, undo_like_or_dislike_comment}; use activitystreams::activity::kind::UndoType; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::person::Person; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -14,35 +10,42 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoLikeComment { to: PublicUrl, - object: LemmyActivity, + object: LikeComment, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.actor, false)?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoLikeComment { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object.object)?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { undo_like_or_dislike_comment( - &actor, - &self.inner.object.inner.object, + &self.common.actor, + &self.object.object, context, request_counter, ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/comment/undo_remove.rs b/crates/apub_receive/src/activities/comment/undo_remove.rs index 094cb36f0..cd48ec338 100644 --- a/crates/apub_receive/src/activities/comment/undo_remove.rs +++ b/crates/apub_receive/src/activities/comment/undo_remove.rs @@ -1,14 +1,13 @@ use crate::activities::{ comment::{remove::RemoveComment, send_websocket_message}, verify_mod_action, - LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::comment::Comment_; -use lemmy_db_schema::source::{comment::Comment, person::Person}; +use lemmy_db_schema::source::comment::Comment; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -17,32 +16,34 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoRemoveComment { to: PublicUrl, - object: LemmyActivity, + object: RemoveComment, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoRemoveComment { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?; + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let comment = - get_or_fetch_and_insert_comment(&self.inner.object.inner.object, context, request_counter) - .await?; + get_or_fetch_and_insert_comment(&self.object.object, context, request_counter).await?; let removed_comment = blocking(context.pool(), move |conn| { Comment::update_removed(conn, comment.id, false) @@ -57,4 +58,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/comment/update.rs b/crates/apub_receive/src/activities/comment/update.rs index cacaff04a..f13ae9fc7 100644 --- a/crates/apub_receive/src/activities/comment/update.rs +++ b/crates/apub_receive/src/activities/comment/update.rs @@ -1,11 +1,8 @@ -use crate::activities::{ - comment::{get_notif_recipients, send_websocket_message}, - LemmyActivity, -}; +use crate::activities::comment::{get_notif_recipients, send_websocket_message}; use activitystreams::{activity::kind::UpdateType, base::BaseExt}; -use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::{comment::Comment, person::Person}; +use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; +use lemmy_db_schema::source::comment::Comment; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -18,35 +15,34 @@ pub struct UpdateComment { cc: Vec, #[serde(rename = "type")] kind: UpdateType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - self.inner.object.id(self.actor.as_str())?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for UpdateComment { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + self.object.id(self.common.actor.as_str())?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let comment = Comment::from_apub( - &self.inner.object, + &self.object, context, - self.actor.clone(), + self.common.actor.clone(), request_counter, false, ) .await?; let recipients = - get_notif_recipients(&actor.actor_id(), &comment, context, request_counter).await?; + get_notif_recipients(&self.common.actor, &comment, context, request_counter).await?; send_websocket_message( comment.id, recipients, @@ -55,4 +51,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/add_mod.rs b/crates/apub_receive/src/activities/community/add_mod.rs index a6e1b9d9b..368d563ad 100644 --- a/crates/apub_receive/src/activities/community/add_mod.rs +++ b/crates/apub_receive/src/activities/community/add_mod.rs @@ -1,8 +1,4 @@ -use crate::activities::{ - community::verify_add_remove_moderator_target, - verify_mod_action, - LemmyActivity, -}; +use crate::activities::{community::verify_add_remove_moderator_target, verify_mod_action}; use activitystreams::{activity::kind::AddType, base::AnyBase}; use lemmy_api_common::blocking; use lemmy_apub::{ @@ -10,12 +6,9 @@ use lemmy_apub::{ fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, CommunityType, }; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::{source::community::CommunityModerator_, Joinable}; -use lemmy_db_schema::source::{ - community::{CommunityModerator, CommunityModeratorForm}, - person::Person, -}; +use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -29,30 +22,28 @@ pub struct AddMod { cc: [Url; 1], #[serde(rename = "type")] kind: AddType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.target, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.actor, false)?; - verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; - verify_add_remove_moderator_target(&self.inner.target, self.inner.cc[0].clone()) +impl ActivityHandlerNew for AddMod { + async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.target, &self.cc[0])?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?; + verify_add_remove_moderator_target(&self.target, self.cc[0].clone()) } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let community = - get_or_fetch_and_upsert_community(&self.inner.cc[0], context, request_counter).await?; - let new_mod = - get_or_fetch_and_upsert_person(&self.inner.object, context, request_counter).await?; + get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?; + let new_mod = get_or_fetch_and_upsert_person(&self.object, context, request_counter).await?; // If we had to refetch the community while parsing the activity, then the new mod has already // been added. Skip it here as it would result in a duplicate key error. @@ -74,10 +65,14 @@ impl ActivityHandler for LemmyActivity { if community.local { let anybase = AnyBase::from_arbitrary_json(serde_json::to_string(self)?)?; community - .send_announce(anybase, Some(self.inner.object.clone()), context) + .send_announce(anybase, Some(self.object.clone()), context) .await?; } // TODO: send websocket notification about added mod Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/announce.rs b/crates/apub_receive/src/activities/community/announce.rs index a25eaec0f..ca0a8edad 100644 --- a/crates/apub_receive/src/activities/community/announce.rs +++ b/crates/apub_receive/src/activities/community/announce.rs @@ -25,19 +25,18 @@ use crate::{ undo_remove::UndoRemovePost, update::UpdatePost, }, - LemmyActivity, }, http::is_activity_already_known, }; use activitystreams::activity::kind::RemoveType; -use lemmy_apub::{check_is_apub_id_valid, fetcher::person::get_or_fetch_and_upsert_person}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::{community::Community, person::Person}; +use lemmy_apub::check_is_apub_id_valid; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; +use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)] pub enum AnnouncableActivities { CreateComment(CreateComment), UpdateComment(UpdateComment), @@ -63,61 +62,43 @@ pub enum AnnouncableActivities { UndoBlockUserFromCommunity(UndoBlockUserFromCommunity), } -#[async_trait::async_trait(?Send)] -impl ActivityHandler for AnnouncableActivities { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - self.verify(context).await - } - - async fn receive( - &self, - actor: Self::Actor, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError> { - self.receive(actor, context, request_counter).await - } -} - #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct AnnounceActivity { to: PublicUrl, - object: LemmyActivity, + object: AnnouncableActivities, cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Community; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.actor, false)?; - self.inner.object.inner.verify(context).await +impl ActivityHandlerNew for AnnounceActivity { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.cc[0])?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - if is_activity_already_known(context.pool(), self.inner.object.id_unchecked()).await? { + if is_activity_already_known(context.pool(), self.object.common().id_unchecked()).await? { return Ok(()); } - let inner_actor = - get_or_fetch_and_upsert_person(&self.inner.object.actor, context, request_counter).await?; - self - .inner - .object - .inner - .receive(inner_actor, context, request_counter) - .await + self.object.receive(context, request_counter).await + } + + fn common(&self) -> &ActivityCommonFields { + &self.common } } diff --git a/crates/apub_receive/src/activities/community/block_user.rs b/crates/apub_receive/src/activities/community/block_user.rs index 69b2f28d1..0b29fe907 100644 --- a/crates/apub_receive/src/activities/community/block_user.rs +++ b/crates/apub_receive/src/activities/community/block_user.rs @@ -1,20 +1,17 @@ -use crate::activities::{verify_mod_action, LemmyActivity}; +use crate::activities::verify_mod_action; use activitystreams::activity::kind::BlockType; use lemmy_api_common::blocking; use lemmy_apub::{ check_is_apub_id_valid, fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, }; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::{Bannable, Followable}; -use lemmy_db_schema::source::{ - community::{ - CommunityFollower, - CommunityFollowerForm, - CommunityPersonBan, - CommunityPersonBanForm, - }, - person::Person, +use lemmy_db_schema::source::community::{ + CommunityFollower, + CommunityFollowerForm, + CommunityPersonBan, + CommunityPersonBanForm, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -28,28 +25,27 @@ pub struct BlockUserFromCommunity { cc: [Url; 1], #[serde(rename = "type")] kind: BlockType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await +impl ActivityHandlerNew for BlockUserFromCommunity { + async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let community = - get_or_fetch_and_upsert_community(&self.inner.cc[0], context, request_counter).await?; + get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?; let blocked_user = - get_or_fetch_and_upsert_person(&self.inner.object, context, request_counter).await?; + get_or_fetch_and_upsert_person(&self.object, context, request_counter).await?; let community_user_ban_form = CommunityPersonBanForm { community_id: community.id, @@ -75,4 +71,8 @@ impl ActivityHandler for LemmyActivity { Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/delete.rs b/crates/apub_receive/src/activities/community/delete.rs index d00cb90f8..6242f68f2 100644 --- a/crates/apub_receive/src/activities/community/delete.rs +++ b/crates/apub_receive/src/activities/community/delete.rs @@ -1,7 +1,4 @@ -use crate::activities::{ - community::{send_websocket_message, verify_is_community_mod}, - LemmyActivity, -}; +use crate::activities::community::{send_websocket_message, verify_is_community_mod}; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; use lemmy_apub::{ @@ -10,7 +7,7 @@ use lemmy_apub::{ ActorType, CommunityType, }; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::{source::community::Community_, ApubObject}; use lemmy_db_schema::source::community::Community; use lemmy_utils::LemmyError; @@ -28,40 +25,39 @@ pub struct DeleteCommunity { cc: [Url; 1], #[serde(rename = "type")] kind: DeleteType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = lemmy_apub::fetcher::Actor; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - let object = self.inner.object.clone(); +impl ActivityHandlerNew for DeleteCommunity { + async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + let object = self.object.clone(); let community = blocking(context.pool(), move |conn| { Community::read_from_apub_id(conn, &object.into()) }) .await?; // remote mod action on local community if let Ok(c) = community { - verify_domains_match(&self.inner.object, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.actor, false)?; - verify_is_community_mod(self.actor.clone(), c.actor_id(), context).await + verify_domains_match(&self.object, &self.cc[0])?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_is_community_mod(self.common.actor.clone(), c.actor_id(), context).await } // community action sent to followers else { - verify_domains_match(&self.actor, &self.inner.object)?; - verify_domains_match(&self.actor, &self.inner.cc[0]) + verify_domains_match(&self.common.actor, &self.object)?; + verify_domains_match(&self.common.actor, &self.cc[0]) } } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { // TODO: match on actor to decide what to do - let actor = self.inner.object.clone(); + let actor = self.object.clone(); let community = blocking(context.pool(), move |conn| { Community::read_from_apub_id(conn, &actor.into()) }) @@ -69,14 +65,15 @@ impl ActivityHandler for LemmyActivity { let community_id = match community { Ok(c) => { // remote mod sent delete to local community, forward it to followers - let actor = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?; + let actor = + get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?; c.send_delete(actor, context).await?; c.id } Err(_) => { // refetch the remote community let community = - get_or_fetch_and_upsert_community(&self.inner.object, context, request_counter).await?; + get_or_fetch_and_upsert_community(&self.object, context, request_counter).await?; community.id } }; @@ -92,4 +89,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/remove.rs b/crates/apub_receive/src/activities/community/remove.rs index ce3b35dee..41b86ef67 100644 --- a/crates/apub_receive/src/activities/community/remove.rs +++ b/crates/apub_receive/src/activities/community/remove.rs @@ -1,8 +1,8 @@ -use crate::activities::{community::send_websocket_message, LemmyActivity}; +use crate::activities::community::send_websocket_message; use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::{source::community::Community_, ApubObject}; use lemmy_db_schema::source::community::Community; use lemmy_utils::LemmyError; @@ -17,26 +17,25 @@ pub struct RemoveCommunity { cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = lemmy_apub::fetcher::Actor; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_domains_match(&self.actor, &self.inner.object)?; - verify_domains_match(&self.actor, &self.inner.cc[0]) +impl ActivityHandlerNew for RemoveCommunity { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_domains_match(&self.common.actor, &self.object)?; + verify_domains_match(&self.common.actor, &self.cc[0]) } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, _request_counter: &mut i32, ) -> Result<(), LemmyError> { - let object = self.inner.object.clone(); + let object = self.object.clone(); // only search in local database, there is no reason to fetch something thats deleted let community = blocking(context.pool(), move |conn| { Community::read_from_apub_id(conn, &object.into()) @@ -54,4 +53,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/remove_mod.rs b/crates/apub_receive/src/activities/community/remove_mod.rs index 2225a3457..69f874603 100644 --- a/crates/apub_receive/src/activities/community/remove_mod.rs +++ b/crates/apub_receive/src/activities/community/remove_mod.rs @@ -1,8 +1,4 @@ -use crate::activities::{ - community::verify_add_remove_moderator_target, - verify_mod_action, - LemmyActivity, -}; +use crate::activities::{community::verify_add_remove_moderator_target, verify_mod_action}; use activitystreams::{activity::kind::RemoveType, base::AnyBase}; use lemmy_api_common::blocking; use lemmy_apub::{ @@ -10,12 +6,9 @@ use lemmy_apub::{ fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, CommunityType, }; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::Joinable; -use lemmy_db_schema::source::{ - community::{CommunityModerator, CommunityModeratorForm}, - person::Person, -}; +use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -29,30 +22,28 @@ pub struct RemoveMod { cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.target, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.actor, false)?; - verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; - verify_add_remove_moderator_target(&self.inner.target, self.inner.cc[0].clone()) +impl ActivityHandlerNew for RemoveMod { + async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.target, &self.cc[0])?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?; + verify_add_remove_moderator_target(&self.target, self.cc[0].clone()) } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let community = - get_or_fetch_and_upsert_community(&self.inner.cc[0], context, request_counter).await?; - let add_mod = - get_or_fetch_and_upsert_person(&self.inner.object, context, request_counter).await?; + get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?; + let add_mod = get_or_fetch_and_upsert_person(&self.object, context, request_counter).await?; let form = CommunityModeratorForm { community_id: community.id, @@ -64,9 +55,13 @@ impl ActivityHandler for LemmyActivity { .await??; let anybase = AnyBase::from_arbitrary_json(serde_json::to_string(self)?)?; community - .send_announce(anybase, Some(self.inner.object.clone()), context) + .send_announce(anybase, Some(self.object.clone()), context) .await?; // TODO: send websocket notification about removed mod Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/undo_block_user.rs b/crates/apub_receive/src/activities/community/undo_block_user.rs index e00979912..f71765c6f 100644 --- a/crates/apub_receive/src/activities/community/undo_block_user.rs +++ b/crates/apub_receive/src/activities/community/undo_block_user.rs @@ -1,20 +1,13 @@ -use crate::activities::{ - community::block_user::BlockUserFromCommunity, - verify_mod_action, - LemmyActivity, -}; +use crate::activities::{community::block_user::BlockUserFromCommunity, verify_mod_action}; use activitystreams::activity::kind::BlockType; use lemmy_api_common::blocking; use lemmy_apub::{ check_is_apub_id_valid, fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, }; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::Bannable; -use lemmy_db_schema::source::{ - community::{CommunityPersonBan, CommunityPersonBanForm}, - person::Person, -}; +use lemmy_db_schema::source::community::{CommunityPersonBan, CommunityPersonBanForm}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -23,34 +16,36 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoBlockUserFromCommunity { to: PublicUrl, - object: LemmyActivity, + object: BlockUserFromCommunity, cc: [Url; 1], #[serde(rename = "type")] kind: BlockType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoBlockUserFromCommunity { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?; + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let community = - get_or_fetch_and_upsert_community(&self.inner.cc[0], context, request_counter).await?; + get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?; let blocked_user = - get_or_fetch_and_upsert_person(&self.inner.object.inner.object, context, request_counter) - .await?; + get_or_fetch_and_upsert_person(&self.object.object, context, request_counter).await?; let community_user_ban_form = CommunityPersonBanForm { community_id: community.id, @@ -64,4 +59,8 @@ impl ActivityHandler for LemmyActivity { Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/undo_delete.rs b/crates/apub_receive/src/activities/community/undo_delete.rs index 739347960..79c61e962 100644 --- a/crates/apub_receive/src/activities/community/undo_delete.rs +++ b/crates/apub_receive/src/activities/community/undo_delete.rs @@ -1,6 +1,7 @@ -use crate::activities::{ - community::{delete::DeleteCommunity, send_websocket_message, verify_is_community_mod}, - LemmyActivity, +use crate::activities::community::{ + delete::DeleteCommunity, + send_websocket_message, + verify_is_community_mod, }; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; @@ -10,7 +11,7 @@ use lemmy_apub::{ ActorType, CommunityType, }; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::{source::community::Community_, ApubObject}; use lemmy_db_schema::source::community::Community; use lemmy_utils::LemmyError; @@ -24,44 +25,47 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDeleteCommunity { to: PublicUrl, - object: LemmyActivity, + object: DeleteCommunity, cc: [Url; 1], #[serde(rename = "type")] kind: DeleteType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = lemmy_apub::fetcher::Actor; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - let object = self.inner.object.inner.object.clone(); +impl ActivityHandlerNew for UndoDeleteCommunity { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + let object = self.object.object.clone(); let community = blocking(context.pool(), move |conn| { Community::read_from_apub_id(conn, &object.into()) }) .await?; // remote mod action on local community if let Ok(c) = community { - verify_domains_match(&self.inner.object.inner.object, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.actor, false)?; - verify_is_community_mod(self.actor.clone(), c.actor_id(), context).await?; + verify_domains_match(&self.object.object, &self.cc[0])?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_is_community_mod(self.common.actor.clone(), c.actor_id(), context).await?; } // community action sent to followers else { - verify_domains_match(&self.actor, &self.inner.object.inner.object)?; - verify_domains_match(&self.actor, &self.inner.cc[0])?; + verify_domains_match(&self.common.actor, &self.object.object)?; + verify_domains_match(&self.common.actor, &self.cc[0])?; } - self.inner.object.verify(context).await + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let object = self.inner.object.inner.object.clone(); + let object = self.object.object.clone(); let community = blocking(context.pool(), move |conn| { Community::read_from_apub_id(conn, &object.into()) }) @@ -69,18 +73,15 @@ impl ActivityHandler for LemmyActivity { let community_id = match community { Ok(c) => { // remote mod sent undo to local community, forward it to followers - let actor = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?; + let actor = + get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?; c.send_delete(actor, context).await?; c.id } Err(_) => { // refetch the remote community - let community = get_or_fetch_and_upsert_community( - &self.inner.object.inner.object, - context, - request_counter, - ) - .await?; + let community = + get_or_fetch_and_upsert_community(&self.object.object, context, request_counter).await?; community.id } }; @@ -96,4 +97,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/undo_remove.rs b/crates/apub_receive/src/activities/community/undo_remove.rs index 9f1e5a68a..67ed85825 100644 --- a/crates/apub_receive/src/activities/community/undo_remove.rs +++ b/crates/apub_receive/src/activities/community/undo_remove.rs @@ -1,11 +1,8 @@ -use crate::activities::{ - community::{remove::RemoveCommunity, send_websocket_message}, - LemmyActivity, -}; +use crate::activities::community::{remove::RemoveCommunity, send_websocket_message}; use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::community::get_or_fetch_and_upsert_community}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::community::Community_; use lemmy_db_schema::source::community::Community; use lemmy_utils::LemmyError; @@ -16,31 +13,34 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoRemoveCommunity { to: PublicUrl, - object: LemmyActivity, + object: RemoveCommunity, cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = lemmy_apub::fetcher::Actor; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_domains_match(&self.actor, &self.inner.object.inner.object)?; - verify_domains_match(&self.actor, &self.inner.cc[0])?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoRemoveCommunity { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_domains_match(&self.common.actor, &self.object.object)?; + verify_domains_match(&self.common.actor, &self.cc[0])?; + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let community_id = self.inner.object.inner.object.clone(); + let community_id = self.object.object.clone(); let community = get_or_fetch_and_upsert_community(&community_id, context, request_counter).await?; @@ -56,4 +56,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/community/update.rs b/crates/apub_receive/src/activities/community/update.rs index 05ee02096..3cadc8dec 100644 --- a/crates/apub_receive/src/activities/community/update.rs +++ b/crates/apub_receive/src/activities/community/update.rs @@ -1,16 +1,10 @@ -use crate::activities::{ - community::{send_websocket_message, verify_is_community_mod}, - LemmyActivity, -}; +use crate::activities::community::{send_websocket_message, verify_is_community_mod}; use activitystreams::{activity::kind::UpdateType, base::BaseExt}; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, objects::FromApubToForm, GroupExt}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::{ApubObject, Crud}; -use lemmy_db_schema::source::{ - community::{Community, CommunityForm}, - person::Person, -}; +use lemmy_db_schema::source::community::{Community, CommunityForm}; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -25,33 +19,32 @@ pub struct UpdateCommunity { cc: [Url; 1], #[serde(rename = "type")] kind: UpdateType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - self.inner.object.id(self.inner.cc[0].as_str())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_is_community_mod(self.actor.clone(), self.inner.cc[0].clone(), context).await +impl ActivityHandlerNew for UpdateCommunity { + async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + self.object.id(self.cc[0].as_str())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_is_community_mod(self.common.actor.clone(), self.cc[0].clone(), context).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let cc = self.inner.cc[0].clone().into(); + let cc = self.cc[0].clone().into(); let community = blocking(context.pool(), move |conn| { Community::read_from_apub_id(conn, &cc) }) .await??; let updated_community = CommunityForm::from_apub( - &self.inner.object, + &self.object, context, community.actor_id.clone().into(), request_counter, @@ -80,4 +73,8 @@ impl ActivityHandler for LemmyActivity { ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/following/accept.rs b/crates/apub_receive/src/activities/following/accept.rs index 7d7891132..74b81777d 100644 --- a/crates/apub_receive/src/activities/following/accept.rs +++ b/crates/apub_receive/src/activities/following/accept.rs @@ -1,16 +1,11 @@ -use crate::activities::{following::follow::FollowCommunity, LemmyActivity}; +use crate::activities::following::follow::FollowCommunity; use activitystreams::activity::kind::AcceptType; use lemmy_api_common::blocking; use lemmy_apub::{ check_is_apub_id_valid, fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, }; -use lemmy_apub_lib::{ - verify_domains_match, - ActivityCommonFields, - ActivityHandler, - ActivityHandlerNew, -}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew}; use lemmy_db_queries::Followable; use lemmy_db_schema::source::community::CommunityFollower; use lemmy_utils::LemmyError; @@ -21,7 +16,7 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct AcceptFollowCommunity { to: Url, - object: LemmyActivity, + object: FollowCommunity, #[serde(rename = "type")] kind: AcceptType, #[serde(flatten)] @@ -31,10 +26,14 @@ pub struct AcceptFollowCommunity { /// Handle accepted follows #[async_trait::async_trait(?Send)] impl ActivityHandlerNew for AcceptFollowCommunity { - async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { - verify_domains_match(&self.common.actor, &self.common.id_unchecked())?; + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; check_is_apub_id_valid(&self.common.actor, false)?; - self.object.verify(context).await + self.object.verify(context, request_counter).await } async fn receive( diff --git a/crates/apub_receive/src/activities/following/follow.rs b/crates/apub_receive/src/activities/following/follow.rs index 8f38e4552..598d8d20e 100644 --- a/crates/apub_receive/src/activities/following/follow.rs +++ b/crates/apub_receive/src/activities/following/follow.rs @@ -1,4 +1,3 @@ -use crate::activities::LemmyActivity; use activitystreams::{ activity::{kind::FollowType, Follow}, base::{AnyBase, ExtendsExt}, @@ -7,15 +6,12 @@ use anyhow::Context; use lemmy_api_common::blocking; use lemmy_apub::{ check_is_apub_id_valid, - fetcher::community::get_or_fetch_and_upsert_community, + fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, CommunityType, }; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew}; use lemmy_db_queries::Followable; -use lemmy_db_schema::source::{ - community::{CommunityFollower, CommunityFollowerForm}, - person::Person, -}; +use lemmy_db_schema::source::community::{CommunityFollower, CommunityFollowerForm}; use lemmy_utils::{location_info, LemmyError}; use lemmy_websocket::LemmyContext; use url::Url; @@ -27,26 +23,27 @@ pub struct FollowCommunity { pub(in crate::activities::following) object: Url, #[serde(rename = "type")] kind: FollowType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.to, &self.inner.object)?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for FollowCommunity { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.to, &self.object)?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { + let actor = + get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?; let community = - get_or_fetch_and_upsert_community(&self.inner.object, context, request_counter).await?; + get_or_fetch_and_upsert_community(&self.object, context, request_counter).await?; let community_follower_form = CommunityFollowerForm { community_id: community.id, person_id: actor.id, @@ -64,4 +61,8 @@ impl ActivityHandler for LemmyActivity { let anybase = Follow::from_any_base(anybase)?.context(location_info!())?; community.send_accept_follow(anybase, context).await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/following/undo.rs b/crates/apub_receive/src/activities/following/undo.rs index 8ced67aa2..9923fd58f 100644 --- a/crates/apub_receive/src/activities/following/undo.rs +++ b/crates/apub_receive/src/activities/following/undo.rs @@ -1,13 +1,13 @@ -use crate::activities::{following::follow::FollowCommunity, LemmyActivity}; +use crate::activities::following::follow::FollowCommunity; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; -use lemmy_apub::{check_is_apub_id_valid, fetcher::community::get_or_fetch_and_upsert_community}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler}; -use lemmy_db_queries::Followable; -use lemmy_db_schema::source::{ - community::{CommunityFollower, CommunityFollowerForm}, - person::Person, +use lemmy_apub::{ + check_is_apub_id_valid, + fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, }; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew}; +use lemmy_db_queries::Followable; +use lemmy_db_schema::source::community::{CommunityFollower, CommunityFollowerForm}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -16,30 +16,34 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoFollowCommunity { to: Url, - object: LemmyActivity, + object: FollowCommunity, #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.to, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.actor, false)?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoFollowCommunity { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.to, &self.object.object)?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let community = - get_or_fetch_and_upsert_community(&self.inner.to, context, request_counter).await?; + let actor = + get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?; + let community = get_or_fetch_and_upsert_community(&self.to, context, request_counter).await?; let community_follower_form = CommunityFollowerForm { community_id: community.id, @@ -54,4 +58,8 @@ impl ActivityHandler for LemmyActivity { .await?; Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/mod.rs b/crates/apub_receive/src/activities/mod.rs index 873a13ba9..ed137f79f 100644 --- a/crates/apub_receive/src/activities/mod.rs +++ b/crates/apub_receive/src/activities/mod.rs @@ -1,4 +1,3 @@ -use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed}; use anyhow::anyhow; use lemmy_api_common::blocking; use lemmy_db_queries::ApubObject; @@ -14,30 +13,6 @@ pub mod following; pub mod post; pub mod private_message; -// TODO: remove this -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -#[serde(rename_all = "camelCase")] -pub struct LemmyActivity { - #[serde(rename = "@context")] - context: OneOrMany, - id: Url, - pub(crate) actor: Url, - - /// type-specific fields - #[serde(flatten)] - pub inner: Kind, - - // unparsed fields - #[serde(flatten)] - unparsed: Unparsed, -} - -impl LemmyActivity { - pub fn id_unchecked(&self) -> &Url { - &self.id - } -} - async fn verify_mod_action( actor_id: Url, activity_cc: Url, diff --git a/crates/apub_receive/src/activities/post/delete.rs b/crates/apub_receive/src/activities/post/delete.rs index 274c6a341..8efcad819 100644 --- a/crates/apub_receive/src/activities/post/delete.rs +++ b/crates/apub_receive/src/activities/post/delete.rs @@ -1,10 +1,10 @@ -use crate::activities::{post::send_websocket_message, LemmyActivity}; +use crate::activities::post::send_websocket_message; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::post::Post_; -use lemmy_db_schema::source::{person::Person, post::Post}; +use lemmy_db_schema::source::post::Post; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -17,25 +17,24 @@ pub struct DeletePost { cc: [Url; 1], #[serde(rename = "type")] kind: DeleteType, + #[serde(flatten)] + pub(in crate::activities::post) common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object)?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for DeletePost { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object)?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?; + let post = get_or_fetch_and_insert_post(&self.object, context, request_counter).await?; let deleted_post = blocking(context.pool(), move |conn| { Post::update_deleted(conn, post.id, true) @@ -44,4 +43,8 @@ impl ActivityHandler for LemmyActivity { send_websocket_message(deleted_post.id, UserOperationCrud::EditPost, context).await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/post/dislike.rs b/crates/apub_receive/src/activities/post/dislike.rs index 63c34731e..f8b730e28 100644 --- a/crates/apub_receive/src/activities/post/dislike.rs +++ b/crates/apub_receive/src/activities/post/dislike.rs @@ -1,8 +1,7 @@ -use crate::activities::{post::like_or_dislike_post, LemmyActivity}; +use crate::activities::post::like_or_dislike_post; use activitystreams::activity::kind::DislikeType; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::person::Person; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -15,23 +14,33 @@ pub struct DislikePost { cc: [Url; 1], #[serde(rename = "type")] kind: DislikeType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for DislikePost { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - like_or_dislike_post(-1, &actor, &self.inner.object, context, request_counter).await + like_or_dislike_post( + -1, + &self.common.actor, + &self.object, + context, + request_counter, + ) + .await + } + + fn common(&self) -> &ActivityCommonFields { + &self.common } } diff --git a/crates/apub_receive/src/activities/post/like.rs b/crates/apub_receive/src/activities/post/like.rs index c932160d9..8cf22b2ae 100644 --- a/crates/apub_receive/src/activities/post/like.rs +++ b/crates/apub_receive/src/activities/post/like.rs @@ -1,6 +1,6 @@ use crate::activities::post::like_or_dislike_post; use activitystreams::activity::kind::LikeType; -use lemmy_apub::{check_is_apub_id_valid, fetcher::person::get_or_fetch_and_upsert_person}; +use lemmy_apub::check_is_apub_id_valid; use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -30,9 +30,14 @@ impl ActivityHandlerNew for LikePost { context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let actor = - get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?; - like_or_dislike_post(1, &actor, &self.object, context, request_counter).await + like_or_dislike_post( + 1, + &self.common.actor, + &self.object, + context, + request_counter, + ) + .await } fn common(&self) -> &ActivityCommonFields { diff --git a/crates/apub_receive/src/activities/post/mod.rs b/crates/apub_receive/src/activities/post/mod.rs index 3969f30cc..fe6fc51c2 100644 --- a/crates/apub_receive/src/activities/post/mod.rs +++ b/crates/apub_receive/src/activities/post/mod.rs @@ -1,11 +1,11 @@ use lemmy_api_common::{blocking, post::PostResponse}; -use lemmy_apub::fetcher::objects::get_or_fetch_and_insert_post; +use lemmy_apub::fetcher::{ + objects::get_or_fetch_and_insert_post, + person::get_or_fetch_and_upsert_person, +}; use lemmy_db_queries::Likeable; use lemmy_db_schema::{ - source::{ - person::Person, - post::{PostLike, PostLikeForm}, - }, + source::post::{PostLike, PostLikeForm}, PostId, }; use lemmy_db_views::post_view::PostView; @@ -47,11 +47,12 @@ async fn send_websocket_message Result<(), LemmyError> { + let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?; let post = get_or_fetch_and_insert_post(object, context, request_counter).await?; let post_id = post.id; @@ -71,11 +72,12 @@ async fn like_or_dislike_post( } async fn undo_like_or_dislike_post( - actor: &Person, + actor: &Url, object: &Url, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { + let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?; let post = get_or_fetch_and_insert_post(object, context, request_counter).await?; let post_id = post.id; diff --git a/crates/apub_receive/src/activities/post/remove.rs b/crates/apub_receive/src/activities/post/remove.rs index 7f8e62b45..4b7afd30a 100644 --- a/crates/apub_receive/src/activities/post/remove.rs +++ b/crates/apub_receive/src/activities/post/remove.rs @@ -1,10 +1,10 @@ -use crate::activities::{post::send_websocket_message, verify_mod_action, LemmyActivity}; +use crate::activities::{post::send_websocket_message, verify_mod_action}; use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::post::Post_; -use lemmy_db_schema::source::{person::Person, post::Post}; +use lemmy_db_schema::source::post::Post; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -17,26 +17,25 @@ pub struct RemovePost { cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await +impl ActivityHandlerNew for RemovePost { + async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { // TODO: check that actor is instance mod if community is local (same for undo, RemoveComment) - let post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?; + let post = get_or_fetch_and_insert_post(&self.object, context, request_counter).await?; let removed_post = blocking(context.pool(), move |conn| { Post::update_removed(conn, post.id, true) @@ -45,4 +44,8 @@ impl ActivityHandler for LemmyActivity { send_websocket_message(removed_post.id, UserOperationCrud::EditPost, context).await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/post/undo_delete.rs b/crates/apub_receive/src/activities/post/undo_delete.rs index 814c928c6..8e32c5fc7 100644 --- a/crates/apub_receive/src/activities/post/undo_delete.rs +++ b/crates/apub_receive/src/activities/post/undo_delete.rs @@ -1,13 +1,10 @@ -use crate::activities::{ - post::{delete::DeletePost, send_websocket_message}, - LemmyActivity, -}; +use crate::activities::post::{delete::DeletePost, send_websocket_message}; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::post::Post_; -use lemmy_db_schema::source::{person::Person, post::Post}; +use lemmy_db_schema::source::post::Post; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -16,32 +13,33 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDeletePost { to: PublicUrl, - object: LemmyActivity, + object: DeletePost, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object.actor)?; - check_is_apub_id_valid(&self.actor, false)?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoDeletePost { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object.common.actor)?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let post = - get_or_fetch_and_insert_post(&self.inner.object.inner.object, context, request_counter) - .await?; + let post = get_or_fetch_and_insert_post(&self.object.object, context, request_counter).await?; let deleted_post = blocking(context.pool(), move |conn| { Post::update_deleted(conn, post.id, false) @@ -50,4 +48,8 @@ impl ActivityHandler for LemmyActivity { send_websocket_message(deleted_post.id, UserOperationCrud::EditPost, context).await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/post/undo_dislike.rs b/crates/apub_receive/src/activities/post/undo_dislike.rs index d1484be38..d9a0c6de5 100644 --- a/crates/apub_receive/src/activities/post/undo_dislike.rs +++ b/crates/apub_receive/src/activities/post/undo_dislike.rs @@ -1,11 +1,7 @@ -use crate::activities::{ - post::{dislike::DislikePost, undo_like_or_dislike_post}, - LemmyActivity, -}; +use crate::activities::post::{dislike::DislikePost, undo_like_or_dislike_post}; use activitystreams::activity::kind::UndoType; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::person::Person; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -14,35 +10,42 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDislikePost { to: PublicUrl, - object: LemmyActivity, + object: DislikePost, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.actor, false)?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoDislikePost { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object.object)?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { undo_like_or_dislike_post( - &actor, - &self.inner.object.inner.object, + &self.common.actor, + &self.object.object, context, request_counter, ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/post/undo_like.rs b/crates/apub_receive/src/activities/post/undo_like.rs index e1caa7159..f256f4f4a 100644 --- a/crates/apub_receive/src/activities/post/undo_like.rs +++ b/crates/apub_receive/src/activities/post/undo_like.rs @@ -1,11 +1,7 @@ -use crate::activities::{ - post::{like::LikePost, undo_like_or_dislike_post}, - LemmyActivity, -}; +use crate::activities::post::{like::LikePost, undo_like_or_dislike_post}; use activitystreams::activity::kind::UndoType; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; -use lemmy_db_schema::source::person::Person; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -14,34 +10,41 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoLikePost { to: PublicUrl, - object: LemmyActivity, + object: LikePost, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.actor, false) - //self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoLikePost { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object.object)?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { undo_like_or_dislike_post( - &actor, - &self.inner.object.inner.object, + &self.common.actor, + &self.object.object, context, request_counter, ) .await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/post/undo_remove.rs b/crates/apub_receive/src/activities/post/undo_remove.rs index 252ef7e73..a21ca9892 100644 --- a/crates/apub_receive/src/activities/post/undo_remove.rs +++ b/crates/apub_receive/src/activities/post/undo_remove.rs @@ -1,14 +1,13 @@ use crate::activities::{ post::{remove::RemovePost, send_websocket_message}, verify_mod_action, - LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::source::post::Post_; -use lemmy_db_schema::source::{person::Person, post::Post}; +use lemmy_db_schema::source::post::Post; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -17,32 +16,33 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoRemovePost { to: PublicUrl, - object: LemmyActivity, + object: RemovePost, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoRemovePost { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?; + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let post = - get_or_fetch_and_insert_post(&self.inner.object.inner.object, context, request_counter) - .await?; + let post = get_or_fetch_and_insert_post(&self.object.object, context, request_counter).await?; let removed_post = blocking(context.pool(), move |conn| { Post::update_removed(conn, post.id, false) @@ -51,4 +51,8 @@ impl ActivityHandler for LemmyActivity { send_websocket_message(removed_post.id, UserOperationCrud::EditPost, context).await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/post/update.rs b/crates/apub_receive/src/activities/post/update.rs index bd03f45a7..cb1a476a6 100644 --- a/crates/apub_receive/src/activities/post/update.rs +++ b/crates/apub_receive/src/activities/post/update.rs @@ -1,19 +1,17 @@ -use crate::activities::{post::send_websocket_message, LemmyActivity}; +use crate::activities::post::send_websocket_message; use activitystreams::{activity::kind::UpdateType, base::BaseExt}; use anyhow::Context; use lemmy_api_common::blocking; use lemmy_apub::{ check_is_apub_id_valid, objects::{FromApub, FromApubToForm}, - ActorType, PageExt, }; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_db_queries::{ApubObject, Crud}; use lemmy_db_schema::{ source::{ community::Community, - person::Person, post::{Post, PostForm}, }, DbUrl, @@ -30,28 +28,27 @@ pub struct UpdatePost { cc: Vec, #[serde(rename = "type")] kind: UpdateType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - self.inner.object.id(self.actor.as_str())?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for UpdatePost { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + self.object.id(self.common.actor.as_str())?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let temp_post = PostForm::from_apub( - &self.inner.object, + &self.object, context, - actor.actor_id(), + self.common.actor.clone(), request_counter, false, ) @@ -81,9 +78,9 @@ impl ActivityHandler for LemmyActivity { } let post = Post::from_apub( - &self.inner.object, + &self.object, context, - actor.actor_id(), + self.common.actor.clone(), request_counter, mod_action_allowed, ) @@ -91,4 +88,8 @@ impl ActivityHandler for LemmyActivity { send_websocket_message(post.id, UserOperationCrud::EditPost, context).await } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/private_message/create.rs b/crates/apub_receive/src/activities/private_message/create.rs index 27889ddf8..ac298b167 100644 --- a/crates/apub_receive/src/activities/private_message/create.rs +++ b/crates/apub_receive/src/activities/private_message/create.rs @@ -1,8 +1,8 @@ -use crate::activities::{private_message::send_websocket_message, LemmyActivity}; +use crate::activities::private_message::send_websocket_message; use activitystreams::{activity::kind::CreateType, base::BaseExt}; -use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler}; -use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage}; +use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew}; +use lemmy_db_schema::source::private_message::PrivateMessage; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -14,28 +14,27 @@ pub struct CreatePrivateMessage { object: NoteExt, #[serde(rename = "type")] kind: CreateType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(self.id_unchecked(), &self.actor)?; - self.inner.object.id(self.actor.as_str())?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for CreatePrivateMessage { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(self.common.id_unchecked(), &self.common.actor)?; + self.object.id(self.common.actor.as_str())?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let private_message = PrivateMessage::from_apub( - &self.inner.object, + &self.object, context, - actor.actor_id(), + self.common.actor.clone(), request_counter, false, ) @@ -50,4 +49,8 @@ impl ActivityHandler for LemmyActivity { Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/private_message/delete.rs b/crates/apub_receive/src/activities/private_message/delete.rs index 61e52fc8d..cfb45db5b 100644 --- a/crates/apub_receive/src/activities/private_message/delete.rs +++ b/crates/apub_receive/src/activities/private_message/delete.rs @@ -1,10 +1,10 @@ -use crate::activities::{private_message::send_websocket_message, LemmyActivity}; +use crate::activities::private_message::send_websocket_message; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew}; use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject}; -use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage}; +use lemmy_db_schema::source::private_message::PrivateMessage; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -16,25 +16,24 @@ pub struct DeletePrivateMessage { pub(in crate::activities::private_message) object: Url, #[serde(rename = "type")] kind: DeleteType, + #[serde(flatten)] + pub(in crate::activities::private_message) common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, &self.inner.object)?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for DeletePrivateMessage { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, &self.object)?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, _request_counter: &mut i32, ) -> Result<(), LemmyError> { - let ap_id = self.inner.object.clone(); + let ap_id = self.object.clone(); let private_message = blocking(context.pool(), move |conn| { PrivateMessage::read_from_apub_id(conn, &ap_id.into()) }) @@ -53,4 +52,8 @@ impl ActivityHandler for LemmyActivity { Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/private_message/undo_delete.rs b/crates/apub_receive/src/activities/private_message/undo_delete.rs index 8edee65f6..440e79c70 100644 --- a/crates/apub_receive/src/activities/private_message/undo_delete.rs +++ b/crates/apub_receive/src/activities/private_message/undo_delete.rs @@ -1,13 +1,10 @@ -use crate::activities::{ - private_message::{delete::DeletePrivateMessage, send_websocket_message}, - LemmyActivity, -}; +use crate::activities::private_message::{delete::DeletePrivateMessage, send_websocket_message}; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub::check_is_apub_id_valid; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew}; use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject}; -use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage}; +use lemmy_db_schema::source::private_message::PrivateMessage; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -16,29 +13,32 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDeletePrivateMessage { to: Url, - object: LemmyActivity, + object: DeletePrivateMessage, #[serde(rename = "type")] kind: UndoType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.actor, self.id_unchecked())?; - verify_domains_match(&self.actor, self.inner.object.id_unchecked())?; - check_is_apub_id_valid(&self.actor, false)?; - self.inner.object.verify(context).await +impl ActivityHandlerNew for UndoDeletePrivateMessage { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.common.actor, self.common.id_unchecked())?; + verify_domains_match(&self.common.actor, self.object.common.id_unchecked())?; + check_is_apub_id_valid(&self.common.actor, false)?; + self.object.verify(context, request_counter).await } async fn receive( &self, - _actor: Self::Actor, context: &LemmyContext, _request_counter: &mut i32, ) -> Result<(), LemmyError> { - let ap_id = self.inner.object.inner.object.clone(); + let ap_id = self.object.object.clone(); let private_message = blocking(context.pool(), move |conn| { PrivateMessage::read_from_apub_id(conn, &ap_id.into()) }) @@ -58,4 +58,8 @@ impl ActivityHandler for LemmyActivity { Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/activities/private_message/update.rs b/crates/apub_receive/src/activities/private_message/update.rs index d535b9d7a..7c477eac6 100644 --- a/crates/apub_receive/src/activities/private_message/update.rs +++ b/crates/apub_receive/src/activities/private_message/update.rs @@ -1,8 +1,8 @@ -use crate::activities::{private_message::send_websocket_message, LemmyActivity}; +use crate::activities::private_message::send_websocket_message; use activitystreams::{activity::kind::UpdateType, base::BaseExt}; -use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt}; -use lemmy_apub_lib::{verify_domains_match, ActivityHandler}; -use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage}; +use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt}; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew}; +use lemmy_db_schema::source::private_message::PrivateMessage; use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; @@ -14,28 +14,27 @@ pub struct UpdatePrivateMessage { object: NoteExt, #[serde(rename = "type")] kind: UpdateType, + #[serde(flatten)] + common: ActivityCommonFields, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for LemmyActivity { - type Actor = Person; - - async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(self.id_unchecked(), &self.actor)?; - self.inner.object.id(self.actor.as_str())?; - check_is_apub_id_valid(&self.actor, false) +impl ActivityHandlerNew for UpdatePrivateMessage { + async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> { + verify_domains_match(self.common.id_unchecked(), &self.common.actor)?; + self.object.id(self.common.actor.as_str())?; + check_is_apub_id_valid(&self.common.actor, false) } async fn receive( &self, - actor: Self::Actor, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let private_message = PrivateMessage::from_apub( - &self.inner.object, + &self.object, context, - actor.actor_id(), + self.common.actor.clone(), request_counter, false, ) @@ -50,4 +49,8 @@ impl ActivityHandler for LemmyActivity { Ok(()) } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } } diff --git a/crates/apub_receive/src/http/community.rs b/crates/apub_receive/src/http/community.rs index 1b68b59f5..beeb4cf0c 100644 --- a/crates/apub_receive/src/http/community.rs +++ b/crates/apub_receive/src/http/community.rs @@ -1,18 +1,16 @@ -use crate::{ - activities::LemmyActivity, - http::{ - create_apub_response, - create_apub_tombstone_response, - inbox_enums::GroupInboxActivities, - receive_activity, - }, +use crate::http::{ + create_apub_response, + create_apub_tombstone_response, + inbox_enums::GroupInboxActivities, + payload_to_string, + receive_activity, }; use activitystreams::{ base::{AnyBase, BaseExt}, collection::{CollectionExt, OrderedCollection, UnorderedCollection}, url::Url, }; -use actix_web::{body::Body, web, HttpRequest, HttpResponse}; +use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; use lemmy_apub::{ extensions::context::lemmy_context, @@ -57,12 +55,12 @@ pub(crate) async fn get_apub_community_http( /// Handler for all incoming receive to community inboxes. pub async fn community_inbox( request: HttpRequest, - input: web::Json>, + payload: Payload, path: web::Path, context: web::Data, ) -> Result { - //receive_activity(request, input.into_inner(), Some(path.0), context).await - todo!() + let unparsed = payload_to_string(payload).await?; + receive_activity::(request, &unparsed, Some(path.0), context).await } /// Returns an empty followers collection, only populating the size (for privacy). diff --git a/crates/apub_receive/src/http/inbox_enums.rs b/crates/apub_receive/src/http/inbox_enums.rs index 8f0854ddd..68bf16f14 100644 --- a/crates/apub_receive/src/http/inbox_enums.rs +++ b/crates/apub_receive/src/http/inbox_enums.rs @@ -43,12 +43,12 @@ use crate::activities::{ update::UpdatePrivateMessage, }, }; -use lemmy_apub_lib::ActivityHandler; +use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)] #[serde(untagged)] pub enum PersonInboxActivities { AcceptFollowCommunity(AcceptFollowCommunity), @@ -59,7 +59,7 @@ pub enum PersonInboxActivities { AnnounceActivity(Box), } -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)] #[serde(untagged)] pub enum GroupInboxActivities { FollowCommunity(FollowCommunity), @@ -95,7 +95,7 @@ pub enum GroupInboxActivities { RemoveMod(RemoveMod), } -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)] #[serde(untagged)] pub enum SharedInboxActivities { // received by person @@ -138,57 +138,3 @@ pub enum SharedInboxActivities { AddMod(AddMod), RemoveMod(RemoveMod), } - -#[async_trait::async_trait(?Send)] -impl ActivityHandler for SharedInboxActivities { - type Actor = lemmy_apub::fetcher::Actor; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - self.verify(context).await - } - - async fn receive( - &self, - actor: Self::Actor, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError> { - self.receive(actor, context, request_counter).await - } -} - -#[async_trait::async_trait(?Send)] -impl ActivityHandler for PersonInboxActivities { - type Actor = lemmy_apub::fetcher::Actor; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - self.verify(context).await - } - - async fn receive( - &self, - actor: Self::Actor, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError> { - self.receive(actor, context, request_counter).await - } -} - -#[async_trait::async_trait(?Send)] -impl ActivityHandler for GroupInboxActivities { - type Actor = lemmy_apub::fetcher::Actor; - - async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - self.verify(context).await - } - - async fn receive( - &self, - actor: Self::Actor, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError> { - self.receive(actor, context, request_counter).await - } -} diff --git a/crates/apub_receive/src/http/mod.rs b/crates/apub_receive/src/http/mod.rs index edfc03cb0..82700cbed 100644 --- a/crates/apub_receive/src/http/mod.rs +++ b/crates/apub_receive/src/http/mod.rs @@ -2,7 +2,13 @@ use crate::activities::{ following::accept::AcceptFollowCommunity, post::{create::CreatePost, like::LikePost}, }; -use actix_web::{body::Body, web, web::Bytes, HttpRequest, HttpResponse}; +use actix_web::{ + body::Body, + web, + web::{Bytes, BytesMut, Payload}, + HttpRequest, + HttpResponse, +}; use anyhow::{anyhow, Context}; use futures::StreamExt; use http::StatusCode; @@ -40,18 +46,22 @@ enum Ac { pub async fn shared_inbox( request: HttpRequest, - mut body: web::Payload, + payload: Payload, context: web::Data, ) -> Result { - let mut bytes = web::BytesMut::new(); - while let Some(item) = body.next().await { - bytes.extend_from_slice(&item?); - } - let mut unparsed: String = String::new(); - Bytes::from(bytes).as_ref().read_to_string(&mut unparsed)?; + let unparsed = payload_to_string(payload).await?; receive_activity::(request, &unparsed, None, context).await } +async fn payload_to_string(mut payload: Payload) -> Result { + let mut bytes = BytesMut::new(); + while let Some(item) = payload.next().await { + bytes.extend_from_slice(&item?); + } + let mut unparsed = String::new(); + Bytes::from(bytes).as_ref().read_to_string(&mut unparsed)?; + Ok(unparsed) +} async fn receive_activity<'a, T>( request: HttpRequest, activity: &'a str, diff --git a/crates/apub_receive/src/http/person.rs b/crates/apub_receive/src/http/person.rs index 808f093ed..b3a3b7386 100644 --- a/crates/apub_receive/src/http/person.rs +++ b/crates/apub_receive/src/http/person.rs @@ -1,17 +1,15 @@ -use crate::{ - activities::LemmyActivity, - http::{ - create_apub_response, - create_apub_tombstone_response, - inbox_enums::PersonInboxActivities, - receive_activity, - }, +use crate::http::{ + create_apub_response, + create_apub_tombstone_response, + inbox_enums::PersonInboxActivities, + payload_to_string, + receive_activity, }; use activitystreams::{ base::BaseExt, collection::{CollectionExt, OrderedCollection}, }; -use actix_web::{body::Body, web, HttpRequest, HttpResponse}; +use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; use lemmy_apub::{extensions::context::lemmy_context, objects::ToApub, ActorType}; use lemmy_db_queries::source::person::Person_; @@ -49,12 +47,12 @@ pub(crate) async fn get_apub_person_http( pub async fn person_inbox( request: HttpRequest, - input: web::Json>, + payload: Payload, path: web::Path, context: web::Data, ) -> Result { - //receive_activity(request, input.into_inner(), Some(path.0), context).await - todo!() + let unparsed = payload_to_string(payload).await?; + receive_activity::(request, &unparsed, Some(path.0), context).await } pub(crate) async fn get_apub_person_outbox(