diff --git a/crates/api/src/comment.rs b/crates/api/src/comment.rs index 62b01b33f..e6eef2cba 100644 --- a/crates/api/src/comment.rs +++ b/crates/api/src/comment.rs @@ -1,5 +1,7 @@ -use crate::Perform; +use std::convert::TryInto; + use actix_web::web::Data; + use lemmy_api_common::{ blocking, check_community_ban, @@ -9,11 +11,11 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, }; use lemmy_apub::{ - activities::voting::{ + fetcher::post_or_comment::PostOrComment, + protocol::activities::voting::{ undo_vote::UndoVote, vote::{Vote, VoteType}, }, - fetcher::post_or_comment::PostOrComment, }; use lemmy_db_schema::{ newtypes::LocalUserId, @@ -23,7 +25,8 @@ use lemmy_db_schema::{ use lemmy_db_views::{comment_view::CommentView, local_user_view::LocalUserView}; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperation}; -use std::convert::TryInto; + +use crate::Perform; #[async_trait::async_trait(?Send)] impl Perform for MarkCommentAsRead { diff --git a/crates/api/src/comment_report.rs b/crates/api/src/comment_report.rs index a7299b7ae..82ecc1f44 100644 --- a/crates/api/src/comment_report.rs +++ b/crates/api/src/comment_report.rs @@ -1,5 +1,5 @@ -use crate::Perform; use actix_web::web::Data; + use lemmy_api_common::{ blocking, check_community_ban, @@ -7,7 +7,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, is_mod_or_admin, }; -use lemmy_apub::{activities::report::Report, fetcher::object_id::ObjectId}; +use lemmy_apub::{fetcher::object_id::ObjectId, protocol::activities::community::report::Report}; use lemmy_db_schema::{source::comment_report::*, traits::Reportable}; use lemmy_db_views::{ comment_report_view::{CommentReportQueryBuilder, CommentReportView}, @@ -16,6 +16,8 @@ use lemmy_db_views::{ use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; +use crate::Perform; + /// Creates a comment report and notifies the moderators of the community #[async_trait::async_trait(?Send)] impl Perform for CreateCommentReport { diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index ac39751c8..b47a4ec60 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -10,16 +10,16 @@ use lemmy_api_common::{ is_mod_or_admin, }; use lemmy_apub::{ - activities::{ + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::{ community::{ add_mod::AddMod, block_user::BlockUserFromCommunity, remove_mod::RemoveMod, undo_block_user::UndoBlockUserFromCommunity, }, - following::{follow::FollowCommunity as FollowCommunityApub, undo::UndoFollowCommunity}, + following::{follow::FollowCommunity as FollowCommunityApub, undo_follow::UndoFollowCommunity}, }, - objects::{community::ApubCommunity, person::ApubPerson}, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/post.rs b/crates/api/src/post.rs index 488c8f590..3564f1352 100644 --- a/crates/api/src/post.rs +++ b/crates/api/src/post.rs @@ -12,16 +12,16 @@ use lemmy_api_common::{ post::*, }; use lemmy_apub::{ - activities::{ - post::create_or_update::CreateOrUpdatePost, + fetcher::post_or_comment::PostOrComment, + objects::post::ApubPost, + protocol::activities::{ + create_or_update::post::CreateOrUpdatePost, voting::{ undo_vote::UndoVote, vote::{Vote, VoteType}, }, CreateOrUpdateType, }, - fetcher::post_or_comment::PostOrComment, - objects::post::ApubPost, }; use lemmy_db_schema::{ source::{moderator::*, post::*}, diff --git a/crates/api/src/post_report.rs b/crates/api/src/post_report.rs index 3e610bff8..98b2f1c11 100644 --- a/crates/api/src/post_report.rs +++ b/crates/api/src/post_report.rs @@ -1,5 +1,5 @@ -use crate::Perform; use actix_web::web::Data; + use lemmy_api_common::{ blocking, check_community_ban, @@ -13,7 +13,7 @@ use lemmy_api_common::{ ResolvePostReport, }, }; -use lemmy_apub::{activities::report::Report, fetcher::object_id::ObjectId}; +use lemmy_apub::{fetcher::object_id::ObjectId, protocol::activities::community::report::Report}; use lemmy_db_schema::{ source::post_report::{PostReport, PostReportForm}, traits::Reportable, @@ -25,6 +25,8 @@ use lemmy_db_views::{ use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; +use crate::Perform; + /// Creates a post report and notifies the moderators of the community #[async_trait::async_trait(?Send)] impl Perform for CreatePostReport { diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index 6c90e94e1..ab093ea19 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -1,5 +1,5 @@ -use crate::PerformCrud; use actix_web::web::Data; + use lemmy_api_common::{ blocking, check_community_ban, @@ -11,13 +11,13 @@ use lemmy_api_common::{ get_post, }; use lemmy_apub::{ - activities::{ - comment::create_or_update::CreateOrUpdateComment, + fetcher::post_or_comment::PostOrComment, + generate_local_apub_endpoint, + protocol::activities::{ + create_or_update::comment::CreateOrUpdateComment, voting::vote::{Vote, VoteType}, CreateOrUpdateType, }, - fetcher::post_or_comment::PostOrComment, - generate_local_apub_endpoint, EndpointType, }; use lemmy_db_schema::{ @@ -40,6 +40,8 @@ use lemmy_websocket::{ UserOperationCrud, }; +use crate::PerformCrud; + #[async_trait::async_trait(?Send)] impl PerformCrud for CreateComment { type Response = CommentResponse; diff --git a/crates/api_crud/src/comment/update.rs b/crates/api_crud/src/comment/update.rs index 9a164fc3f..70f15dfb2 100644 --- a/crates/api_crud/src/comment/update.rs +++ b/crates/api_crud/src/comment/update.rs @@ -1,5 +1,5 @@ -use crate::PerformCrud; use actix_web::web::Data; + use lemmy_api_common::{ blocking, check_community_ban, @@ -8,8 +8,8 @@ use lemmy_api_common::{ comment::*, get_local_user_view_from_jwt, }; -use lemmy_apub::activities::{ - comment::create_or_update::CreateOrUpdateComment, +use lemmy_apub::protocol::activities::{ + create_or_update::comment::CreateOrUpdateComment, CreateOrUpdateType, }; use lemmy_db_schema::source::comment::Comment; @@ -26,6 +26,8 @@ use lemmy_websocket::{ UserOperationCrud, }; +use crate::PerformCrud; + #[async_trait::async_trait(?Send)] impl PerformCrud for EditComment { type Response = CommentResponse; diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index 97722a98b..4764b0254 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -5,7 +5,7 @@ use lemmy_api_common::{ community::{CommunityResponse, EditCommunity}, get_local_user_view_from_jwt, }; -use lemmy_apub::activities::community::update::UpdateCommunity; +use lemmy_apub::protocol::activities::community::update::UpdateCommunity; use lemmy_db_schema::{ diesel_option_overwrite_to_url, naive_now, diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index a66410341..99b67d2ea 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -1,5 +1,7 @@ -use crate::PerformCrud; use actix_web::web::Data; +use log::warn; +use webmention::{Webmention, WebmentionError}; + use lemmy_api_common::{ blocking, check_community_ban, @@ -10,13 +12,13 @@ use lemmy_api_common::{ post::*, }; use lemmy_apub::{ - activities::{ - post::create_or_update::CreateOrUpdatePost, + fetcher::post_or_comment::PostOrComment, + generate_local_apub_endpoint, + protocol::activities::{ + create_or_update::post::CreateOrUpdatePost, voting::vote::{Vote, VoteType}, CreateOrUpdateType, }, - fetcher::post_or_comment::PostOrComment, - generate_local_apub_endpoint, EndpointType, }; use lemmy_db_schema::{ @@ -31,8 +33,8 @@ use lemmy_utils::{ LemmyError, }; use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; -use log::warn; -use webmention::{Webmention, WebmentionError}; + +use crate::PerformCrud; #[async_trait::async_trait(?Send)] impl PerformCrud for CreatePost { diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index 96e4400a5..0a982d688 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -1,5 +1,5 @@ -use crate::PerformCrud; use actix_web::web::Data; + use lemmy_api_common::{ blocking, check_community_ban, @@ -7,7 +7,10 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, post::*, }; -use lemmy_apub::activities::{post::create_or_update::CreateOrUpdatePost, CreateOrUpdateType}; +use lemmy_apub::protocol::activities::{ + create_or_update::post::CreateOrUpdatePost, + CreateOrUpdateType, +}; use lemmy_db_schema::{ naive_now, source::post::{Post, PostForm}, @@ -22,6 +25,8 @@ use lemmy_utils::{ }; use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; +use crate::PerformCrud; + #[async_trait::async_trait(?Send)] impl PerformCrud for EditPost { type Response = PostResponse; diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index c7bca4e02..705d781e2 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -7,11 +7,11 @@ use lemmy_api_common::{ person::{CreatePrivateMessage, PrivateMessageResponse}, }; use lemmy_apub::{ - activities::{ + generate_local_apub_endpoint, + protocol::activities::{ private_message::create_or_update::CreateOrUpdatePrivateMessage, CreateOrUpdateType, }, - generate_local_apub_endpoint, EndpointType, }; use lemmy_db_schema::{ diff --git a/crates/api_crud/src/private_message/delete.rs b/crates/api_crud/src/private_message/delete.rs index f369f82b1..06bc22ede 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -5,7 +5,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, person::{DeletePrivateMessage, PrivateMessageResponse}, }; -use lemmy_apub::activities::private_message::{ +use lemmy_apub::protocol::activities::private_message::{ delete::DeletePrivateMessage as DeletePrivateMessageApub, undo_delete::UndoDeletePrivateMessage, }; diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index d72e3b137..8114556c1 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -5,7 +5,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, person::{EditPrivateMessage, PrivateMessageResponse}, }; -use lemmy_apub::activities::{ +use lemmy_apub::protocol::activities::{ private_message::create_or_update::CreateOrUpdatePrivateMessage, CreateOrUpdateType, }; diff --git a/crates/apub/src/activities/comment/create_or_update.rs b/crates/apub/src/activities/comment/create_or_update.rs index d53801aa2..335e17139 100644 --- a/crates/apub/src/activities/comment/create_or_update.rs +++ b/crates/apub/src/activities/comment/create_or_update.rs @@ -1,11 +1,9 @@ -use activitystreams::{link::Mention, public, unparsed::Unparsed}; -use serde::{Deserialize, Serialize}; -use url::Url; +use activitystreams::public; use lemmy_api_common::{blocking, check_post_deleted_or_removed}; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType, ApubObject}, + traits::{ActivityHandler, ActorType, ApubObject}, verify::verify_domains_match, }; use lemmy_db_schema::{ @@ -19,37 +17,18 @@ use crate::{ activities::{ check_community_deleted_or_removed, comment::{collect_non_local_mentions, get_notif_recipients}, - community::{ - announce::{AnnouncableActivities, GetCommunity}, - send_to_community, - }, + community::{announce::GetCommunity, send_to_community}, generate_activity_id, verify_activity, verify_is_public, verify_person_in_community, - CreateOrUpdateType, }, + activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson}, - protocol::objects::note::Note, + protocol::activities::{create_or_update::comment::CreateOrUpdateComment, CreateOrUpdateType}, }; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct CreateOrUpdateComment { - actor: ObjectId, - to: Vec, - object: Note, - cc: Vec, - #[serde(default)] - tag: Vec, - #[serde(rename = "type")] - kind: CreateOrUpdateType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} - impl CreateOrUpdateComment { pub async fn send( comment: &ApubComment, diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index b65fa48e7..b18e50ada 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -1,10 +1,6 @@ use crate::{ activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - get_community_from_moderators_url, - send_to_community, - }, + community::{announce::GetCommunity, get_community_from_moderators_url, send_to_community}, generate_activity_id, verify_activity, verify_add_remove_moderator_target, @@ -12,15 +8,17 @@ use crate::{ verify_mod_action, verify_person_in_community, }, + activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, generate_moderators_url, objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::community::add_mod::AddMod, }; -use activitystreams::{activity::kind::AddType, public, unparsed::Unparsed}; +use activitystreams::{activity::kind::AddType, public}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, }; use lemmy_db_schema::{ source::community::{CommunityModerator, CommunityModeratorForm}, @@ -28,23 +26,6 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct AddMod { - actor: ObjectId, - to: Vec, - object: ObjectId, - target: Url, - cc: Vec, - #[serde(rename = "type")] - kind: AddType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl AddMod { pub async fn send( diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs index 007fcbb3c..62e7c56fd 100644 --- a/crates/apub/src/activities/community/announce.rs +++ b/crates/apub/src/activities/community/announce.rs @@ -1,55 +1,27 @@ use crate::{ activities::{ - comment::create_or_update::CreateOrUpdateComment, - community::{ - add_mod::AddMod, - block_user::BlockUserFromCommunity, - list_community_follower_inboxes, - remove_mod::RemoveMod, - undo_block_user::UndoBlockUserFromCommunity, - update::UpdateCommunity, - }, - deletion::{delete::Delete, undo_delete::UndoDelete}, + community::list_community_follower_inboxes, generate_activity_id, - post::create_or_update::CreateOrUpdatePost, send_lemmy_activity, verify_activity, verify_is_public, - voting::{undo_vote::UndoVote, vote::Vote}, }, + activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, http::is_activity_already_known, insert_activity, objects::community::ApubCommunity, + protocol::activities::community::announce::AnnounceActivity, }; -use activitystreams::{activity::kind::AnnounceType, public, unparsed::Unparsed}; +use activitystreams::{activity::kind::AnnounceType, public}; use lemmy_apub_lib::{ data::Data, traits::{ActivityFields, ActivityHandler, ActorType}, - verify::verify_urls_match, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] -#[serde(untagged)] -#[activity_handler(LemmyContext)] -pub enum AnnouncableActivities { - CreateOrUpdateComment(CreateOrUpdateComment), - CreateOrUpdatePost(Box), - Vote(Vote), - UndoVote(UndoVote), - Delete(Delete), - UndoDelete(UndoDelete), - UpdateCommunity(Box), - BlockUserFromCommunity(BlockUserFromCommunity), - UndoBlockUserFromCommunity(UndoBlockUserFromCommunity), - AddMod(AddMod), - RemoveMod(RemoveMod), -} - #[async_trait::async_trait(?Send)] pub(crate) trait GetCommunity { async fn get_community( @@ -59,46 +31,6 @@ pub(crate) trait GetCommunity { ) -> Result; } -#[async_trait::async_trait(?Send)] -impl GetCommunity for AnnouncableActivities { - async fn get_community( - &self, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result { - use AnnouncableActivities::*; - let community = match self { - CreateOrUpdateComment(a) => a.get_community(context, request_counter).await?, - CreateOrUpdatePost(a) => a.get_community(context, request_counter).await?, - Vote(a) => a.get_community(context, request_counter).await?, - UndoVote(a) => a.get_community(context, request_counter).await?, - Delete(a) => a.get_community(context, request_counter).await?, - UndoDelete(a) => a.get_community(context, request_counter).await?, - UpdateCommunity(a) => a.get_community(context, request_counter).await?, - BlockUserFromCommunity(a) => a.get_community(context, request_counter).await?, - UndoBlockUserFromCommunity(a) => a.get_community(context, request_counter).await?, - AddMod(a) => a.get_community(context, request_counter).await?, - RemoveMod(a) => a.get_community(context, request_counter).await?, - }; - verify_urls_match(self.actor(), &community.actor_id())?; - Ok(community) - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct AnnounceActivity { - actor: ObjectId, - to: Vec, - object: AnnouncableActivities, - cc: Vec, - #[serde(rename = "type")] - kind: AnnounceType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} - impl AnnounceActivity { pub async fn send( object: AnnouncableActivities, diff --git a/crates/apub/src/activities/community/block_user.rs b/crates/apub/src/activities/community/block_user.rs index 0a716228d..dfe6c4c92 100644 --- a/crates/apub/src/activities/community/block_user.rs +++ b/crates/apub/src/activities/community/block_user.rs @@ -1,23 +1,22 @@ use crate::{ activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - send_to_community, - }, + community::{announce::GetCommunity, send_to_community}, generate_activity_id, verify_activity, verify_is_public, verify_mod_action, verify_person_in_community, }, + activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::community::block_user::BlockUserFromCommunity, }; -use activitystreams::{activity::kind::BlockType, public, unparsed::Unparsed}; +use activitystreams::{activity::kind::BlockType, public}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, }; use lemmy_db_schema::{ source::community::{ @@ -30,23 +29,6 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct BlockUserFromCommunity { - actor: ObjectId, - to: Vec, - pub(in crate::activities::community) object: ObjectId, - cc: Vec, - target: ObjectId, - #[serde(rename = "type")] - kind: BlockType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl BlockUserFromCommunity { pub(in crate::activities::community) fn new( diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 1f51c0335..ebc6e7f92 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -1,23 +1,25 @@ +use itertools::Itertools; +use url::Url; + +use lemmy_apub_lib::traits::ActorType; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; + use crate::{ - activities::{ - community::announce::{AnnouncableActivities, AnnounceActivity}, - send_lemmy_activity, - }, + activities::send_lemmy_activity, + activity_lists::AnnouncableActivities, check_is_apub_id_valid, fetcher::object_id::ObjectId, insert_activity, objects::community::ApubCommunity, + protocol::activities::community::announce::AnnounceActivity, }; -use itertools::Itertools; -use lemmy_apub_lib::traits::ActorType; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; -use url::Url; pub mod add_mod; pub mod announce; pub mod block_user; pub mod remove_mod; +pub mod report; pub mod undo_block_user; pub mod update; diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs index f0c0b90e1..02ff3c064 100644 --- a/crates/apub/src/activities/community/remove_mod.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -1,10 +1,6 @@ use crate::{ activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - get_community_from_moderators_url, - send_to_community, - }, + community::{announce::GetCommunity, get_community_from_moderators_url, send_to_community}, generate_activity_id, verify_activity, verify_add_remove_moderator_target, @@ -12,15 +8,17 @@ use crate::{ verify_mod_action, verify_person_in_community, }, + activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, generate_moderators_url, objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::community::remove_mod::RemoveMod, }; -use activitystreams::{activity::kind::RemoveType, public, unparsed::Unparsed}; +use activitystreams::{activity::kind::RemoveType, public}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, }; use lemmy_db_schema::{ source::community::{CommunityModerator, CommunityModeratorForm}, @@ -28,23 +26,6 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct RemoveMod { - actor: ObjectId, - to: Vec, - pub(in crate::activities) object: ObjectId, - cc: Vec, - #[serde(rename = "type")] - kind: RemoveType, - pub(in crate::activities) target: Url, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl RemoveMod { pub async fn send( diff --git a/crates/apub/src/activities/report.rs b/crates/apub/src/activities/community/report.rs similarity index 88% rename from crates/apub/src/activities/report.rs rename to crates/apub/src/activities/community/report.rs index 9256920a6..1e7cc5fad 100644 --- a/crates/apub/src/activities/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -1,19 +1,9 @@ -use crate::{ - activities::{ - generate_activity_id, - send_lemmy_activity, - verify_activity, - verify_person_in_community, - }, - fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, - PostOrComment, -}; -use activitystreams::{activity::kind::FlagType, unparsed::Unparsed}; +use activitystreams::activity::kind::FlagType; + use lemmy_api_common::{blocking, comment::CommentReportResponse, post::PostReportResponse}; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, }; use lemmy_db_schema::{ source::{ @@ -25,22 +15,19 @@ use lemmy_db_schema::{ use lemmy_db_views::{comment_report_view::CommentReportView, post_report_view::PostReportView}; use lemmy_utils::LemmyError; use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; -use serde::{Deserialize, Serialize}; -use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct Report { - actor: ObjectId, - to: [ObjectId; 1], - object: ObjectId, - summary: String, - #[serde(rename = "type")] - kind: FlagType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} +use crate::{ + activities::{ + generate_activity_id, + send_lemmy_activity, + verify_activity, + verify_person_in_community, + }, + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::community::report::Report, + PostOrComment, +}; impl Report { pub async fn send( diff --git a/crates/apub/src/activities/community/undo_block_user.rs b/crates/apub/src/activities/community/undo_block_user.rs index ad220c968..2bda94441 100644 --- a/crates/apub/src/activities/community/undo_block_user.rs +++ b/crates/apub/src/activities/community/undo_block_user.rs @@ -1,24 +1,25 @@ use crate::{ activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - block_user::BlockUserFromCommunity, - send_to_community, - }, + community::{announce::GetCommunity, send_to_community}, generate_activity_id, verify_activity, verify_is_public, verify_mod_action, verify_person_in_community, }, + activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::community::{ + block_user::BlockUserFromCommunity, + undo_block_user::UndoBlockUserFromCommunity, + }, }; -use activitystreams::{activity::kind::UndoType, public, unparsed::Unparsed}; +use activitystreams::{activity::kind::UndoType, public}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, }; use lemmy_db_schema::{ source::community::{CommunityPersonBan, CommunityPersonBanForm}, @@ -26,22 +27,6 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct UndoBlockUserFromCommunity { - actor: ObjectId, - to: Vec, - object: BlockUserFromCommunity, - cc: Vec, - #[serde(rename = "type")] - kind: UndoType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl UndoBlockUserFromCommunity { pub async fn send( diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index df34ca289..28de0db00 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -1,11 +1,22 @@ -use activitystreams::{activity::kind::UpdateType, public, unparsed::Unparsed}; -use serde::{Deserialize, Serialize}; -use url::Url; - +use crate::{ + activities::{ + community::{announce::GetCommunity, send_to_community}, + generate_activity_id, + verify_activity, + verify_is_public, + verify_mod_action, + verify_person_in_community, + }, + activity_lists::AnnouncableActivities, + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::{activities::community::update::UpdateCommunity, objects::group::Group}, +}; +use activitystreams::{activity::kind::UpdateType, public}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType, ApubObject}, + traits::{ActivityHandler, ActorType, ApubObject}, }; use lemmy_db_schema::{ source::community::{Community, CommunityForm}, @@ -14,40 +25,6 @@ use lemmy_db_schema::{ use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; -use crate::{ - activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - send_to_community, - }, - generate_activity_id, - verify_activity, - verify_is_public, - verify_mod_action, - verify_person_in_community, - }, - fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::objects::group::Group, -}; - -/// This activity is received from a remote community mod, and updates the description or other -/// fields of a local community. -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct UpdateCommunity { - actor: ObjectId, - to: Vec, - // TODO: would be nice to use a separate struct here, which only contains the fields updated here - object: Group, - cc: Vec, - #[serde(rename = "type")] - kind: UpdateType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} - impl UpdateCommunity { pub async fn send( community: &ApubCommunity, diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs index 0db590b9a..672fca52a 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -1,28 +1,11 @@ -use crate::{ - activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - send_to_community, - }, - deletion::{ - receive_delete_action, - verify_delete_activity, - DeletableObjects, - WebsocketMessages, - }, - generate_activity_id, - verify_activity, - verify_is_public, - }, - fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, -}; -use activitystreams::{activity::kind::DeleteType, public, unparsed::Unparsed}; +use activitystreams::{activity::kind::DeleteType, public}; use anyhow::anyhow; +use url::Url; + use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, }; use lemmy_db_schema::{ source::{ @@ -46,35 +29,25 @@ use lemmy_websocket::{ LemmyContext, UserOperationCrud, }; -use serde::{Deserialize, Serialize}; -use serde_with::skip_serializing_none; -use url::Url; -/// This is very confusing, because there are four distinct cases to handle: -/// - user deletes their post -/// - user deletes their comment -/// - remote community mod deletes local community -/// - remote community deletes itself (triggered by a mod) -/// -/// TODO: we should probably change how community deletions work to simplify this. Probably by -/// wrapping it in an announce just like other activities, instead of having the community send it. -#[skip_serializing_none] -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct Delete { - actor: ObjectId, - to: Vec, - pub(in crate::activities::deletion) object: Url, - pub(in crate::activities::deletion) cc: Vec, - #[serde(rename = "type")] - kind: DeleteType, - /// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user - /// deleting their own content. - pub(in crate::activities::deletion) summary: Option, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} +use crate::{ + activities::{ + community::{announce::GetCommunity, send_to_community}, + deletion::{ + receive_delete_action, + verify_delete_activity, + DeletableObjects, + WebsocketMessages, + }, + generate_activity_id, + verify_activity, + verify_is_public, + }, + activity_lists::AnnouncableActivities, + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::deletion::delete::Delete, +}; #[async_trait::async_trait(?Send)] impl ActivityHandler for Delete { diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs index 1af022459..b9c11291f 100644 --- a/crates/apub/src/activities/deletion/mod.rs +++ b/crates/apub/src/activities/deletion/mod.rs @@ -1,12 +1,5 @@ -use crate::{ - activities::{ - deletion::{delete::Delete, undo_delete::UndoDelete}, - verify_mod_action, - verify_person_in_community, - }, - fetcher::object_id::ObjectId, - objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost}, -}; +use url::Url; + use lemmy_api_common::blocking; use lemmy_apub_lib::{ traits::{ActivityFields, ActorType, ApubObject}, @@ -19,7 +12,13 @@ use lemmy_websocket::{ LemmyContext, UserOperationCrud, }; -use url::Url; + +use crate::{ + activities::{verify_mod_action, verify_person_in_community}, + fetcher::object_id::ObjectId, + objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost}, + protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete}, +}; pub mod delete; pub mod undo_delete; diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs index 5cc4dffc2..c16891190 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -1,11 +1,24 @@ +use activitystreams::{activity::kind::UndoType, public}; +use anyhow::anyhow; +use url::Url; + +use lemmy_api_common::blocking; +use lemmy_apub_lib::{ + data::Data, + traits::{ActivityHandler, ActorType}, +}; +use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post}; +use lemmy_utils::LemmyError; +use lemmy_websocket::{ + send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, + LemmyContext, + UserOperationCrud, +}; + use crate::{ activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - send_to_community, - }, + community::{announce::GetCommunity, send_to_community}, deletion::{ - delete::Delete, receive_delete_action, verify_delete_activity, DeletableObjects, @@ -15,39 +28,11 @@ use crate::{ verify_activity, verify_is_public, }, + activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete}, }; -use activitystreams::{activity::kind::UndoType, public, unparsed::Unparsed}; -use anyhow::anyhow; -use lemmy_api_common::blocking; -use lemmy_apub_lib::{ - data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, -}; -use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post}; -use lemmy_utils::LemmyError; -use lemmy_websocket::{ - send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, - LemmyContext, - UserOperationCrud, -}; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct UndoDelete { - actor: ObjectId, - to: Vec, - object: Delete, - cc: Vec, - #[serde(rename = "type")] - kind: UndoType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} #[async_trait::async_trait(?Send)] impl ActivityHandler for UndoDelete { diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index 28f6c1089..984d622a8 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -1,14 +1,9 @@ use crate::{ - activities::{ - following::follow::FollowCommunity, - generate_activity_id, - send_lemmy_activity, - verify_activity, - }, + activities::{generate_activity_id, send_lemmy_activity, verify_activity}, fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity}, }; -use activitystreams::{activity::kind::AcceptType, unparsed::Unparsed}; +use activitystreams::activity::kind::AcceptType; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, @@ -18,21 +13,6 @@ use lemmy_apub_lib::{ use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct AcceptFollowCommunity { - actor: ObjectId, - to: [ObjectId; 1], - object: FollowCommunity, - #[serde(rename = "type")] - kind: AcceptType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl AcceptFollowCommunity { pub async fn send( diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 57a112e0b..e048907fe 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -1,6 +1,5 @@ use crate::{ activities::{ - following::accept::AcceptFollowCommunity, generate_activity_id, send_lemmy_activity, verify_activity, @@ -9,12 +8,13 @@ use crate::{ }, fetcher::object_id::ObjectId, objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity}, }; -use activitystreams::{activity::kind::FollowType, unparsed::Unparsed}; +use activitystreams::activity::kind::FollowType; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, verify::verify_urls_match, }; use lemmy_db_schema::{ @@ -23,21 +23,6 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct FollowCommunity { - pub(in crate::activities::following) actor: ObjectId, - pub(in crate::activities::following) to: [ObjectId; 1], - pub(in crate::activities::following) object: ObjectId, - #[serde(rename = "type")] - kind: FollowType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl FollowCommunity { pub(in crate::activities::following) fn new( diff --git a/crates/apub/src/activities/following/mod.rs b/crates/apub/src/activities/following/mod.rs index 050c36916..60bdd5f78 100644 --- a/crates/apub/src/activities/following/mod.rs +++ b/crates/apub/src/activities/following/mod.rs @@ -1,3 +1,3 @@ pub mod accept; pub mod follow; -pub mod undo; +pub mod undo_follow; diff --git a/crates/apub/src/activities/following/undo.rs b/crates/apub/src/activities/following/undo_follow.rs similarity index 79% rename from crates/apub/src/activities/following/undo.rs rename to crates/apub/src/activities/following/undo_follow.rs index a9326a268..c3fd78b51 100644 --- a/crates/apub/src/activities/following/undo.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -1,15 +1,10 @@ use crate::{ - activities::{ - following::follow::FollowCommunity, - generate_activity_id, - send_lemmy_activity, - verify_activity, - verify_person, - }, + activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person}, fetcher::object_id::ObjectId, objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::following::{follow::FollowCommunity, undo_follow::UndoFollowCommunity}, }; -use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, @@ -22,21 +17,6 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct UndoFollowCommunity { - actor: ObjectId, - to: [ObjectId; 1], - object: FollowCommunity, - #[serde(rename = "type")] - kind: UndoType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl UndoFollowCommunity { pub async fn send( diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 9509babb0..bc6cfb512 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -22,8 +22,7 @@ use lemmy_db_views_actor::{ use lemmy_utils::{settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use log::info; -use serde::{Deserialize, Serialize}; -use strum_macros::ToString; +use serde::Serialize; use url::{ParseError, Url}; use uuid::Uuid; @@ -33,15 +32,8 @@ pub mod deletion; pub mod following; pub mod post; pub mod private_message; -pub mod report; pub mod voting; -#[derive(Clone, Debug, ToString, Deserialize, Serialize)] -pub enum CreateOrUpdateType { - Create, - Update, -} - /// Checks that the specified Url actually identifies a Person (by fetching it), and that the person /// doesn't have a site ban. async fn verify_person( diff --git a/crates/apub/src/activities/post/create_or_update.rs b/crates/apub/src/activities/post/create_or_update.rs index ee1bf19c8..41590493c 100644 --- a/crates/apub/src/activities/post/create_or_update.rs +++ b/crates/apub/src/activities/post/create_or_update.rs @@ -1,7 +1,5 @@ -use activitystreams::{public, unparsed::Unparsed}; +use activitystreams::public; use anyhow::anyhow; -use serde::{Deserialize, Serialize}; -use url::Url; use lemmy_api_common::blocking; use lemmy_apub_lib::{ @@ -16,36 +14,19 @@ use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCru use crate::{ activities::{ check_community_deleted_or_removed, - community::{ - announce::{AnnouncableActivities, GetCommunity}, - send_to_community, - }, + community::{announce::GetCommunity, send_to_community}, generate_activity_id, verify_activity, verify_is_public, verify_mod_action, verify_person_in_community, - CreateOrUpdateType, }, + activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost}, - protocol::objects::page::Page, + protocol::activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType}, }; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct CreateOrUpdatePost { - actor: ObjectId, - to: Vec, - object: Page, - cc: Vec, - #[serde(rename = "type")] - kind: CreateOrUpdateType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} - impl CreateOrUpdatePost { pub(crate) async fn new( post: &ApubPost, diff --git a/crates/apub/src/activities/private_message/create_or_update.rs b/crates/apub/src/activities/private_message/create_or_update.rs index 0067607ec..cfd7c8bcf 100644 --- a/crates/apub/src/activities/private_message/create_or_update.rs +++ b/crates/apub/src/activities/private_message/create_or_update.rs @@ -1,40 +1,21 @@ use crate::{ - activities::{ - generate_activity_id, - send_lemmy_activity, - verify_activity, - verify_person, - CreateOrUpdateType, - }, + activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person}, fetcher::object_id::ObjectId, objects::{person::ApubPerson, private_message::ApubPrivateMessage}, - protocol::objects::chat_message::ChatMessage, + protocol::activities::{ + private_message::create_or_update::CreateOrUpdatePrivateMessage, + CreateOrUpdateType, + }, }; -use activitystreams::unparsed::Unparsed; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType, ApubObject}, + traits::{ActivityHandler, ActorType, ApubObject}, verify::verify_domains_match, }; use lemmy_db_schema::{source::person::Person, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct CreateOrUpdatePrivateMessage { - id: Url, - actor: ObjectId, - to: [ObjectId; 1], - object: ChatMessage, - #[serde(rename = "type")] - kind: CreateOrUpdateType, - #[serde(flatten)] - pub unparsed: Unparsed, -} impl CreateOrUpdatePrivateMessage { pub async fn send( diff --git a/crates/apub/src/activities/private_message/delete.rs b/crates/apub/src/activities/private_message/delete.rs index 0928cba2e..da3b6472d 100644 --- a/crates/apub/src/activities/private_message/delete.rs +++ b/crates/apub/src/activities/private_message/delete.rs @@ -2,12 +2,13 @@ use crate::{ activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person}, fetcher::object_id::ObjectId, objects::{person::ApubPerson, private_message::ApubPrivateMessage}, + protocol::activities::private_message::delete::DeletePrivateMessage, }; -use activitystreams::{activity::kind::DeleteType, unparsed::Unparsed}; +use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, verify::verify_domains_match, }; use lemmy_db_schema::{ @@ -16,21 +17,6 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct DeletePrivateMessage { - actor: ObjectId, - to: [ObjectId; 1], - pub(in crate::activities::private_message) object: ObjectId, - #[serde(rename = "type")] - kind: DeleteType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl DeletePrivateMessage { pub(in crate::activities::private_message) fn new( diff --git a/crates/apub/src/activities/private_message/undo_delete.rs b/crates/apub/src/activities/private_message/undo_delete.rs index 4275ea9cd..bba9e0f22 100644 --- a/crates/apub/src/activities/private_message/undo_delete.rs +++ b/crates/apub/src/activities/private_message/undo_delete.rs @@ -1,15 +1,13 @@ use crate::{ - activities::{ - generate_activity_id, - private_message::delete::DeletePrivateMessage, - send_lemmy_activity, - verify_activity, - verify_person, - }, + activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person}, fetcher::object_id::ObjectId, objects::{person::ApubPerson, private_message::ApubPrivateMessage}, + protocol::activities::private_message::{ + delete::DeletePrivateMessage, + undo_delete::UndoDeletePrivateMessage, + }, }; -use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, @@ -22,21 +20,6 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; -use serde::{Deserialize, Serialize}; -use url::Url; - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct UndoDeletePrivateMessage { - actor: ObjectId, - to: [ObjectId; 1], - object: DeletePrivateMessage, - #[serde(rename = "type")] - kind: UndoType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} impl UndoDeletePrivateMessage { pub async fn send( diff --git a/crates/apub/src/activities/voting/mod.rs b/crates/apub/src/activities/voting/mod.rs index 829553d35..0a2a8fd1f 100644 --- a/crates/apub/src/activities/voting/mod.rs +++ b/crates/apub/src/activities/voting/mod.rs @@ -1,7 +1,3 @@ -use crate::{ - activities::voting::vote::VoteType, - objects::{comment::ApubComment, person::ApubPerson, post::ApubPost}, -}; use lemmy_api_common::blocking; use lemmy_db_schema::{ source::{ @@ -17,6 +13,11 @@ use lemmy_websocket::{ UserOperation, }; +use crate::{ + objects::{comment::ApubComment, person::ApubPerson, post::ApubPost}, + protocol::activities::voting::vote::VoteType, +}; + pub mod undo_vote; pub mod vote; diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index cc6206616..e95d25179 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -1,24 +1,7 @@ -use crate::{ - activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - send_to_community, - }, - generate_activity_id, - verify_activity, - verify_is_public, - verify_person_in_community, - voting::{ - undo_vote_comment, - undo_vote_post, - vote::{Vote, VoteType}, - }, - }, - fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, - PostOrComment, -}; -use activitystreams::{activity::kind::UndoType, public, unparsed::Unparsed}; +use std::ops::Deref; + +use activitystreams::{activity::kind::UndoType, public}; + use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, @@ -28,23 +11,25 @@ use lemmy_apub_lib::{ use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use std::ops::Deref; -use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct UndoVote { - actor: ObjectId, - to: Vec, - object: Vote, - cc: Vec, - #[serde(rename = "type")] - kind: UndoType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} +use crate::{ + activities::{ + community::{announce::GetCommunity, send_to_community}, + generate_activity_id, + verify_activity, + verify_is_public, + verify_person_in_community, + voting::{undo_vote_comment, undo_vote_post}, + }, + activity_lists::AnnouncableActivities, + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::voting::{ + undo_vote::UndoVote, + vote::{Vote, VoteType}, + }, + PostOrComment, +}; impl UndoVote { pub async fn send( diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index 3efef7cf8..01df4b93e 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -1,25 +1,11 @@ -use crate::{ - activities::{ - community::{ - announce::{AnnouncableActivities, GetCommunity}, - send_to_community, - }, - generate_activity_id, - verify_activity, - verify_is_public, - verify_person_in_community, - voting::{vote_comment, vote_post}, - }, - fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, - PostOrComment, -}; -use activitystreams::{public, unparsed::Unparsed}; -use anyhow::anyhow; +use std::ops::Deref; + +use activitystreams::public; + use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, }; use lemmy_db_schema::{ newtypes::CommunityId, @@ -28,51 +14,22 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use std::{convert::TryFrom, ops::Deref}; -use strum_macros::ToString; -use url::Url; -#[derive(Clone, Debug, ToString, Deserialize, Serialize)] -pub enum VoteType { - Like, - Dislike, -} - -impl TryFrom for VoteType { - type Error = LemmyError; - - fn try_from(value: i16) -> Result { - match value { - 1 => Ok(VoteType::Like), - -1 => Ok(VoteType::Dislike), - _ => Err(anyhow!("invalid vote value").into()), - } - } -} - -impl From<&VoteType> for i16 { - fn from(value: &VoteType) -> i16 { - match value { - VoteType::Like => 1, - VoteType::Dislike => -1, - } - } -} - -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] -#[serde(rename_all = "camelCase")] -pub struct Vote { - actor: ObjectId, - to: Vec, - pub(in crate::activities::voting) object: ObjectId, - cc: Vec, - #[serde(rename = "type")] - pub(in crate::activities::voting) kind: VoteType, - id: Url, - #[serde(flatten)] - unparsed: Unparsed, -} +use crate::{ + activities::{ + community::{announce::GetCommunity, send_to_community}, + generate_activity_id, + verify_activity, + verify_is_public, + verify_person_in_community, + voting::{vote_comment, vote_post}, + }, + activity_lists::AnnouncableActivities, + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::voting::vote::{Vote, VoteType}, + PostOrComment, +}; impl Vote { pub(in crate::activities::voting) fn new( diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs new file mode 100644 index 000000000..9fd1a9dc1 --- /dev/null +++ b/crates/apub/src/activity_lists.rs @@ -0,0 +1,113 @@ +use serde::{Deserialize, Serialize}; + +use lemmy_apub_lib::{ + traits::{ActivityFields, ActivityHandler, ActorType}, + verify::verify_urls_match, +}; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; + +use crate::{ + activities::community::announce::GetCommunity, + objects::community::ApubCommunity, + protocol::activities::{ + community::{ + add_mod::AddMod, + announce::AnnounceActivity, + block_user::BlockUserFromCommunity, + remove_mod::RemoveMod, + report::Report, + undo_block_user::UndoBlockUserFromCommunity, + update::UpdateCommunity, + }, + create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost}, + deletion::{delete::Delete, undo_delete::UndoDelete}, + following::{ + accept::AcceptFollowCommunity, + follow::FollowCommunity, + undo_follow::UndoFollowCommunity, + }, + private_message::{ + create_or_update::CreateOrUpdatePrivateMessage, + delete::DeletePrivateMessage, + undo_delete::UndoDeletePrivateMessage, + }, + voting::{undo_vote::UndoVote, vote::Vote}, + }, +}; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] +#[serde(untagged)] +#[activity_handler(LemmyContext)] +pub enum SharedInboxActivities { + GroupInboxActivities(GroupInboxActivities), + // Note, pm activities need to be at the end, otherwise comments will end up here. We can probably + // avoid this problem by replacing createpm.object with our own struct, instead of NoteExt. + PersonInboxActivities(PersonInboxActivities), +} + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] +#[serde(untagged)] +#[activity_handler(LemmyContext)] +pub enum GroupInboxActivities { + FollowCommunity(FollowCommunity), + UndoFollowCommunity(UndoFollowCommunity), + AnnouncableActivities(AnnouncableActivities), + Report(Report), +} + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] +#[serde(untagged)] +#[activity_handler(LemmyContext)] +pub enum PersonInboxActivities { + AcceptFollowCommunity(AcceptFollowCommunity), + /// Some activities can also be sent from user to user, eg a comment with mentions + AnnouncableActivities(AnnouncableActivities), + CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage), + DeletePrivateMessage(DeletePrivateMessage), + UndoDeletePrivateMessage(UndoDeletePrivateMessage), + AnnounceActivity(Box), +} + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] +#[serde(untagged)] +#[activity_handler(LemmyContext)] +pub enum AnnouncableActivities { + CreateOrUpdateComment(CreateOrUpdateComment), + CreateOrUpdatePost(Box), + Vote(Vote), + UndoVote(UndoVote), + Delete(Delete), + UndoDelete(UndoDelete), + UpdateCommunity(Box), + BlockUserFromCommunity(BlockUserFromCommunity), + UndoBlockUserFromCommunity(UndoBlockUserFromCommunity), + AddMod(AddMod), + RemoveMod(RemoveMod), +} + +#[async_trait::async_trait(?Send)] +impl GetCommunity for AnnouncableActivities { + async fn get_community( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result { + use AnnouncableActivities::*; + let community = match self { + CreateOrUpdateComment(a) => a.get_community(context, request_counter).await?, + CreateOrUpdatePost(a) => a.get_community(context, request_counter).await?, + Vote(a) => a.get_community(context, request_counter).await?, + UndoVote(a) => a.get_community(context, request_counter).await?, + Delete(a) => a.get_community(context, request_counter).await?, + UndoDelete(a) => a.get_community(context, request_counter).await?, + UpdateCommunity(a) => a.get_community(context, request_counter).await?, + BlockUserFromCommunity(a) => a.get_community(context, request_counter).await?, + UndoBlockUserFromCommunity(a) => a.get_community(context, request_counter).await?, + AddMod(a) => a.get_community(context, request_counter).await?, + RemoveMod(a) => a.get_community(context, request_counter).await?, + }; + verify_urls_match(self.actor(), &community.actor_id())?; + Ok(community) + } +} diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs index cf5ad8b25..451c3fa94 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -1,12 +1,7 @@ -use crate::{ - activities::{post::create_or_update::CreateOrUpdatePost, CreateOrUpdateType}, - collections::CommunityContext, - generate_outbox_url, - objects::{person::ApubPerson, post::ApubPost}, - protocol::collections::group_outbox::GroupOutbox, -}; use activitystreams::collection::kind::OrderedCollectionType; use chrono::NaiveDateTime; +use url::Url; + use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, @@ -18,7 +13,16 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::LemmyError; -use url::Url; + +use crate::{ + collections::CommunityContext, + generate_outbox_url, + objects::{person::ApubPerson, post::ApubPost}, + protocol::{ + activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType}, + collections::group_outbox::GroupOutbox, + }, +}; #[derive(Clone, Debug)] pub(crate) struct ApubCommunityOutbox(Vec); diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 0a7cb664c..ffc76d3f4 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -1,23 +1,6 @@ -use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; -use log::info; -use serde::{Deserialize, Serialize}; - -use lemmy_api_common::blocking; -use lemmy_apub_lib::{ - traits::{ActivityFields, ActivityHandler, ActorType, ApubObject}, - verify::verify_domains_match, -}; -use lemmy_db_schema::source::community::Community; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - use crate::{ - activities::{ - community::announce::{AnnouncableActivities, AnnounceActivity, GetCommunity}, - following::{follow::FollowCommunity, undo::UndoFollowCommunity}, - report::Report, - verify_person_in_community, - }, + activities::{community::announce::GetCommunity, verify_person_in_community}, + activity_lists::GroupInboxActivities, collections::{ community_moderators::ApubCommunityModerators, community_outbox::ApubCommunityOutbox, @@ -33,8 +16,22 @@ use crate::{ receive_activity, }, objects::community::ApubCommunity, - protocol::collections::group_followers::CommunityFollowers, + protocol::{ + activities::community::announce::AnnounceActivity, + collections::group_followers::CommunityFollowers, + }, }; +use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; +use lemmy_api_common::blocking; +use lemmy_apub_lib::{ + traits::{ActivityFields, ActorType, ApubObject}, + verify::verify_domains_match, +}; +use lemmy_db_schema::source::community::Community; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; +use log::info; +use serde::Deserialize; #[derive(Deserialize)] pub(crate) struct CommunityQuery { @@ -61,16 +58,6 @@ pub(crate) async fn get_apub_community_http( } } -#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] -#[serde(untagged)] -#[activity_handler(LemmyContext)] -pub enum GroupInboxActivities { - FollowCommunity(FollowCommunity), - UndoFollowCommunity(UndoFollowCommunity), - AnnouncableActivities(AnnouncableActivities), - Report(Report), -} - /// Handler for all incoming receive to community inboxes. pub async fn community_inbox( request: HttpRequest, diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index 48956cdf2..9c61c2747 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -1,11 +1,9 @@ use crate::{ + activity_lists::SharedInboxActivities, check_is_apub_id_valid, context::WithContext, fetcher::get_or_fetch_and_upsert_actor, - http::{ - community::{receive_group_inbox, GroupInboxActivities}, - person::{receive_person_inbox, PersonInboxActivities}, - }, + http::{community::receive_group_inbox, person::receive_person_inbox}, insert_activity, }; use actix_web::{ @@ -39,16 +37,6 @@ mod person; mod post; pub mod routes; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] -#[serde(untagged)] -#[activity_handler(LemmyContext)] -pub enum SharedInboxActivities { - GroupInboxActivities(GroupInboxActivities), - // Note, pm activities need to be at the end, otherwise comments will end up here. We can probably - // avoid this problem by replacing createpm.object with our own struct, instead of NoteExt. - PersonInboxActivities(PersonInboxActivities), -} - pub async fn shared_inbox( request: HttpRequest, payload: Payload, diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index 77bfd6940..3f18bcc50 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -1,23 +1,5 @@ -use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; -use log::info; -use serde::{Deserialize, Serialize}; - -use lemmy_api_common::blocking; -use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ApubObject}; -use lemmy_db_schema::source::person::Person; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - use crate::{ - activities::{ - community::announce::{AnnouncableActivities, AnnounceActivity}, - following::accept::AcceptFollowCommunity, - private_message::{ - create_or_update::CreateOrUpdatePrivateMessage, - delete::DeletePrivateMessage, - undo_delete::UndoDeletePrivateMessage, - }, - }, + activity_lists::PersonInboxActivities, context::WithContext, http::{ create_apub_response, @@ -28,6 +10,14 @@ use crate::{ objects::person::ApubPerson, protocol::collections::person_outbox::UserOutbox, }; +use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; +use lemmy_api_common::blocking; +use lemmy_apub_lib::traits::ApubObject; +use lemmy_db_schema::source::person::Person; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; +use log::info; +use serde::Deserialize; #[derive(Deserialize)] pub struct PersonQuery { @@ -56,19 +46,6 @@ pub(crate) async fn get_apub_person_http( } } -#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] -#[serde(untagged)] -#[activity_handler(LemmyContext)] -pub enum PersonInboxActivities { - AcceptFollowCommunity(AcceptFollowCommunity), - /// Some activities can also be sent from user to user, eg a comment with mentions - AnnouncableActivities(AnnouncableActivities), - CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage), - DeletePrivateMessage(DeletePrivateMessage), - UndoDeletePrivateMessage(UndoDeletePrivateMessage), - AnnounceActivity(Box), -} - pub async fn person_inbox( request: HttpRequest, payload: Payload, diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index d188274be..f38a9f86d 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -1,11 +1,12 @@ pub mod activities; +pub(crate) mod activity_lists; pub(crate) mod collections; mod context; pub mod fetcher; pub mod http; pub mod migrations; pub mod objects; -pub(crate) mod protocol; +pub mod protocol; #[macro_use] extern crate lazy_static; diff --git a/crates/apub/src/protocol/activities/community/add_mod.rs b/crates/apub/src/protocol/activities/community/add_mod.rs new file mode 100644 index 000000000..74ec46457 --- /dev/null +++ b/crates/apub/src/protocol/activities/community/add_mod.rs @@ -0,0 +1,20 @@ +use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson}; +use activitystreams::{activity::kind::AddType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct AddMod { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: ObjectId, + pub(crate) target: Url, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: AddType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/community/announce.rs b/crates/apub/src/protocol/activities/community/announce.rs new file mode 100644 index 000000000..2f4e9bd26 --- /dev/null +++ b/crates/apub/src/protocol/activities/community/announce.rs @@ -0,0 +1,23 @@ +use crate::{ + activity_lists::AnnouncableActivities, + fetcher::object_id::ObjectId, + objects::community::ApubCommunity, +}; +use activitystreams::{activity::kind::AnnounceType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct AnnounceActivity { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: AnnouncableActivities, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: AnnounceType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/community/block_user.rs b/crates/apub/src/protocol/activities/community/block_user.rs new file mode 100644 index 000000000..4ede06ae1 --- /dev/null +++ b/crates/apub/src/protocol/activities/community/block_user.rs @@ -0,0 +1,23 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, +}; +use activitystreams::{activity::kind::BlockType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct BlockUserFromCommunity { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: ObjectId, + pub(crate) cc: Vec, + pub(crate) target: ObjectId, + #[serde(rename = "type")] + pub(crate) kind: BlockType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/community/mod.rs b/crates/apub/src/protocol/activities/community/mod.rs new file mode 100644 index 000000000..62f8329b6 --- /dev/null +++ b/crates/apub/src/protocol/activities/community/mod.rs @@ -0,0 +1,7 @@ +pub mod add_mod; +pub mod announce; +pub mod block_user; +pub mod remove_mod; +pub mod report; +pub mod undo_block_user; +pub mod update; diff --git a/crates/apub/src/protocol/activities/community/remove_mod.rs b/crates/apub/src/protocol/activities/community/remove_mod.rs new file mode 100644 index 000000000..db30ddbe4 --- /dev/null +++ b/crates/apub/src/protocol/activities/community/remove_mod.rs @@ -0,0 +1,20 @@ +use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson}; +use activitystreams::{activity::kind::RemoveType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct RemoveMod { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: ObjectId, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: RemoveType, + pub(crate) target: Url, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs new file mode 100644 index 000000000..5efdd792e --- /dev/null +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -0,0 +1,22 @@ +use crate::{ + fetcher::{object_id::ObjectId, post_or_comment::PostOrComment}, + objects::{community::ApubCommunity, person::ApubPerson}, +}; +use activitystreams::{activity::kind::FlagType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct Report { + pub(crate) actor: ObjectId, + pub(crate) to: [ObjectId; 1], + pub(crate) object: ObjectId, + pub(crate) summary: String, + #[serde(rename = "type")] + pub(crate) kind: FlagType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/community/undo_block_user.rs b/crates/apub/src/protocol/activities/community/undo_block_user.rs new file mode 100644 index 000000000..0e89f87ef --- /dev/null +++ b/crates/apub/src/protocol/activities/community/undo_block_user.rs @@ -0,0 +1,23 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + protocol::activities::community::block_user::BlockUserFromCommunity, +}; +use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct UndoBlockUserFromCommunity { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: BlockUserFromCommunity, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: UndoType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/community/update.rs b/crates/apub/src/protocol/activities/community/update.rs new file mode 100644 index 000000000..4ba1ed843 --- /dev/null +++ b/crates/apub/src/protocol/activities/community/update.rs @@ -0,0 +1,26 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + protocol::objects::group::Group, +}; +use activitystreams::{activity::kind::UpdateType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +/// This activity is received from a remote community mod, and updates the description or other +/// fields of a local community. +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct UpdateCommunity { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + // TODO: would be nice to use a separate struct here, which only contains the fields updated here + pub(crate) object: Group, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: UpdateType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/create_or_update/comment.rs b/crates/apub/src/protocol/activities/create_or_update/comment.rs new file mode 100644 index 000000000..ede7417bc --- /dev/null +++ b/crates/apub/src/protocol/activities/create_or_update/comment.rs @@ -0,0 +1,25 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + protocol::{activities::CreateOrUpdateType, objects::note::Note}, +}; +use activitystreams::{link::Mention, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct CreateOrUpdateComment { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: Note, + pub(crate) cc: Vec, + #[serde(default)] + pub(crate) tag: Vec, + #[serde(rename = "type")] + pub(crate) kind: CreateOrUpdateType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/create_or_update/mod.rs b/crates/apub/src/protocol/activities/create_or_update/mod.rs new file mode 100644 index 000000000..38203b5eb --- /dev/null +++ b/crates/apub/src/protocol/activities/create_or_update/mod.rs @@ -0,0 +1,2 @@ +pub mod comment; +pub mod post; diff --git a/crates/apub/src/protocol/activities/create_or_update/post.rs b/crates/apub/src/protocol/activities/create_or_update/post.rs new file mode 100644 index 000000000..03b283e3c --- /dev/null +++ b/crates/apub/src/protocol/activities/create_or_update/post.rs @@ -0,0 +1,23 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + protocol::{activities::CreateOrUpdateType, objects::page::Page}, +}; +use activitystreams::unparsed::Unparsed; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct CreateOrUpdatePost { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: Page, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: CreateOrUpdateType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/deletion/delete.rs b/crates/apub/src/protocol/activities/deletion/delete.rs new file mode 100644 index 000000000..f8e81b47a --- /dev/null +++ b/crates/apub/src/protocol/activities/deletion/delete.rs @@ -0,0 +1,24 @@ +use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson}; +use activitystreams::{activity::kind::DeleteType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use serde_with::skip_serializing_none; +use url::Url; + +#[skip_serializing_none] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct Delete { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: Url, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: DeleteType, + /// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user + /// deleting their own content. + pub(crate) summary: Option, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/deletion/mod.rs b/crates/apub/src/protocol/activities/deletion/mod.rs new file mode 100644 index 000000000..b440edd68 --- /dev/null +++ b/crates/apub/src/protocol/activities/deletion/mod.rs @@ -0,0 +1,2 @@ +pub mod delete; +pub mod undo_delete; diff --git a/crates/apub/src/protocol/activities/deletion/undo_delete.rs b/crates/apub/src/protocol/activities/deletion/undo_delete.rs new file mode 100644 index 000000000..d962820b3 --- /dev/null +++ b/crates/apub/src/protocol/activities/deletion/undo_delete.rs @@ -0,0 +1,25 @@ +use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use serde::{Deserialize, Serialize}; +use url::Url; + +use lemmy_apub_lib::traits::ActivityFields; + +use crate::{ + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + protocol::activities::deletion::delete::Delete, +}; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct UndoDelete { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: Delete, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: UndoType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/following/accept.rs b/crates/apub/src/protocol/activities/following/accept.rs new file mode 100644 index 000000000..502a908c2 --- /dev/null +++ b/crates/apub/src/protocol/activities/following/accept.rs @@ -0,0 +1,22 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::following::follow::FollowCommunity, +}; +use activitystreams::{activity::kind::AcceptType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct AcceptFollowCommunity { + pub(crate) actor: ObjectId, + pub(crate) to: [ObjectId; 1], + pub(crate) object: FollowCommunity, + #[serde(rename = "type")] + pub(crate) kind: AcceptType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/following/follow.rs b/crates/apub/src/protocol/activities/following/follow.rs new file mode 100644 index 000000000..9dfec2163 --- /dev/null +++ b/crates/apub/src/protocol/activities/following/follow.rs @@ -0,0 +1,21 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, +}; +use activitystreams::{activity::kind::FollowType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct FollowCommunity { + pub(crate) actor: ObjectId, + pub(crate) to: [ObjectId; 1], + pub(crate) object: ObjectId, + #[serde(rename = "type")] + pub(crate) kind: FollowType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/following/mod.rs b/crates/apub/src/protocol/activities/following/mod.rs new file mode 100644 index 000000000..5dc6a3f8c --- /dev/null +++ b/crates/apub/src/protocol/activities/following/mod.rs @@ -0,0 +1,3 @@ +pub(crate) mod accept; +pub mod follow; +pub mod undo_follow; diff --git a/crates/apub/src/protocol/activities/following/undo_follow.rs b/crates/apub/src/protocol/activities/following/undo_follow.rs new file mode 100644 index 000000000..be6a7ab89 --- /dev/null +++ b/crates/apub/src/protocol/activities/following/undo_follow.rs @@ -0,0 +1,22 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::following::follow::FollowCommunity, +}; +use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct UndoFollowCommunity { + pub(crate) actor: ObjectId, + pub(crate) to: [ObjectId; 1], + pub(crate) object: FollowCommunity, + #[serde(rename = "type")] + pub(crate) kind: UndoType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/mod.rs b/crates/apub/src/protocol/activities/mod.rs new file mode 100644 index 000000000..23575c279 --- /dev/null +++ b/crates/apub/src/protocol/activities/mod.rs @@ -0,0 +1,15 @@ +use serde::{Deserialize, Serialize}; +use strum_macros::ToString; + +pub mod community; +pub mod create_or_update; +pub mod deletion; +pub mod following; +pub mod private_message; +pub mod voting; + +#[derive(Clone, Debug, ToString, Deserialize, Serialize)] +pub enum CreateOrUpdateType { + Create, + Update, +} diff --git a/crates/apub/src/protocol/activities/private_message/create_or_update.rs b/crates/apub/src/protocol/activities/private_message/create_or_update.rs new file mode 100644 index 000000000..7632ef9fe --- /dev/null +++ b/crates/apub/src/protocol/activities/private_message/create_or_update.rs @@ -0,0 +1,22 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + protocol::{activities::CreateOrUpdateType, objects::chat_message::ChatMessage}, +}; +use activitystreams::unparsed::Unparsed; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct CreateOrUpdatePrivateMessage { + pub(crate) id: Url, + pub(crate) actor: ObjectId, + pub(crate) to: [ObjectId; 1], + pub(crate) object: ChatMessage, + #[serde(rename = "type")] + pub(crate) kind: CreateOrUpdateType, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/private_message/delete.rs b/crates/apub/src/protocol/activities/private_message/delete.rs new file mode 100644 index 000000000..499d7d1d6 --- /dev/null +++ b/crates/apub/src/protocol/activities/private_message/delete.rs @@ -0,0 +1,21 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::{person::ApubPerson, private_message::ApubPrivateMessage}, +}; +use activitystreams::{activity::kind::DeleteType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct DeletePrivateMessage { + pub(crate) actor: ObjectId, + pub(crate) to: [ObjectId; 1], + pub(crate) object: ObjectId, + #[serde(rename = "type")] + pub(crate) kind: DeleteType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/private_message/mod.rs b/crates/apub/src/protocol/activities/private_message/mod.rs new file mode 100644 index 000000000..4bcda7c7b --- /dev/null +++ b/crates/apub/src/protocol/activities/private_message/mod.rs @@ -0,0 +1,3 @@ +pub mod create_or_update; +pub mod delete; +pub mod undo_delete; diff --git a/crates/apub/src/protocol/activities/private_message/undo_delete.rs b/crates/apub/src/protocol/activities/private_message/undo_delete.rs new file mode 100644 index 000000000..699f6eec9 --- /dev/null +++ b/crates/apub/src/protocol/activities/private_message/undo_delete.rs @@ -0,0 +1,22 @@ +use crate::{ + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + protocol::activities::private_message::delete::DeletePrivateMessage, +}; +use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use lemmy_apub_lib::traits::ActivityFields; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct UndoDeletePrivateMessage { + pub(crate) actor: ObjectId, + pub(crate) to: [ObjectId; 1], + pub(crate) object: DeletePrivateMessage, + #[serde(rename = "type")] + pub(crate) kind: UndoType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/voting/mod.rs b/crates/apub/src/protocol/activities/voting/mod.rs new file mode 100644 index 000000000..4583c2317 --- /dev/null +++ b/crates/apub/src/protocol/activities/voting/mod.rs @@ -0,0 +1,2 @@ +pub mod undo_vote; +pub mod vote; diff --git a/crates/apub/src/protocol/activities/voting/undo_vote.rs b/crates/apub/src/protocol/activities/voting/undo_vote.rs new file mode 100644 index 000000000..0d3e66360 --- /dev/null +++ b/crates/apub/src/protocol/activities/voting/undo_vote.rs @@ -0,0 +1,25 @@ +use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use serde::{Deserialize, Serialize}; +use url::Url; + +use lemmy_apub_lib::traits::ActivityFields; + +use crate::{ + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + protocol::activities::voting::vote::Vote, +}; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct UndoVote { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: Vote, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: UndoType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/apub/src/protocol/activities/voting/vote.rs b/crates/apub/src/protocol/activities/voting/vote.rs new file mode 100644 index 000000000..fdc87a3bd --- /dev/null +++ b/crates/apub/src/protocol/activities/voting/vote.rs @@ -0,0 +1,53 @@ +use crate::{ + fetcher::{object_id::ObjectId, post_or_comment::PostOrComment}, + objects::person::ApubPerson, +}; +use activitystreams::unparsed::Unparsed; +use anyhow::anyhow; +use lemmy_apub_lib::traits::ActivityFields; +use lemmy_utils::LemmyError; +use serde::{Deserialize, Serialize}; +use std::convert::TryFrom; +use strum_macros::ToString; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[serde(rename_all = "camelCase")] +pub struct Vote { + pub(crate) actor: ObjectId, + pub(crate) to: Vec, + pub(crate) object: ObjectId, + pub(crate) cc: Vec, + #[serde(rename = "type")] + pub(crate) kind: VoteType, + pub(crate) id: Url, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} + +#[derive(Clone, Debug, ToString, Deserialize, Serialize)] +pub enum VoteType { + Like, + Dislike, +} + +impl TryFrom for VoteType { + type Error = LemmyError; + + fn try_from(value: i16) -> Result { + match value { + 1 => Ok(VoteType::Like), + -1 => Ok(VoteType::Dislike), + _ => Err(anyhow!("invalid vote value").into()), + } + } +} + +impl From<&VoteType> for i16 { + fn from(value: &VoteType) -> i16 { + match value { + VoteType::Like => 1, + VoteType::Dislike => -1, + } + } +} diff --git a/crates/apub/src/protocol/collections/group_outbox.rs b/crates/apub/src/protocol/collections/group_outbox.rs index 26da4b6fd..3b295003a 100644 --- a/crates/apub/src/protocol/collections/group_outbox.rs +++ b/crates/apub/src/protocol/collections/group_outbox.rs @@ -1,4 +1,4 @@ -use crate::activities::post::create_or_update::CreateOrUpdatePost; +use crate::protocol::activities::create_or_update::post::CreateOrUpdatePost; use activitystreams::collection::kind::OrderedCollectionType; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/protocol/mod.rs b/crates/apub/src/protocol/mod.rs index f4ad9e234..f587dba7e 100644 --- a/crates/apub/src/protocol/mod.rs +++ b/crates/apub/src/protocol/mod.rs @@ -4,6 +4,7 @@ use url::Url; use lemmy_apub_lib::values::MediaTypeMarkdown; +pub mod activities; pub(crate) mod collections; pub(crate) mod objects;