3 following::follow::FollowCommunity,
8 activity_queue::send_activity_new,
9 extensions::context::lemmy_context,
10 fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
13 use activitystreams::activity::kind::{FollowType, UndoType};
14 use lemmy_api_common::blocking;
15 use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandler};
16 use lemmy_db_queries::Followable;
17 use lemmy_db_schema::source::{
18 community::{Community, CommunityFollower, CommunityFollowerForm},
21 use lemmy_utils::LemmyError;
22 use lemmy_websocket::LemmyContext;
25 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
26 #[serde(rename_all = "camelCase")]
27 pub struct UndoFollowCommunity {
29 object: FollowCommunity,
30 #[serde(rename = "type")]
33 common: ActivityCommonFields,
36 impl UndoFollowCommunity {
39 community: &Community,
40 context: &LemmyContext,
41 ) -> Result<(), LemmyError> {
42 let id = generate_activity_id(UndoType::Undo)?;
43 let undo = UndoFollowCommunity {
44 to: community.actor_id(),
45 object: FollowCommunity {
46 to: community.actor_id(),
47 object: community.actor_id(),
48 kind: FollowType::Follow,
49 common: ActivityCommonFields {
50 context: lemmy_context(),
51 id: generate_activity_id(FollowType::Follow)?,
52 actor: actor.actor_id(),
53 unparsed: Default::default(),
57 common: ActivityCommonFields {
58 context: lemmy_context(),
60 actor: actor.actor_id(),
61 unparsed: Default::default(),
64 let inbox = vec![community.get_shared_inbox_or_inbox_url()];
65 send_activity_new(context, &undo, &id, actor, inbox, true).await
69 #[async_trait::async_trait(?Send)]
70 impl ActivityHandler for UndoFollowCommunity {
73 context: &LemmyContext,
74 request_counter: &mut i32,
75 ) -> Result<(), LemmyError> {
76 verify_activity(self.common())?;
77 verify_urls_match(&self.to, &self.object.object)?;
78 verify_urls_match(&self.common.actor, &self.object.common.actor)?;
79 verify_person(&self.common.actor, context, request_counter).await?;
80 self.object.verify(context, request_counter).await?;
86 context: &LemmyContext,
87 request_counter: &mut i32,
88 ) -> Result<(), LemmyError> {
90 get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
91 let community = get_or_fetch_and_upsert_community(&self.to, context, request_counter).await?;
93 let community_follower_form = CommunityFollowerForm {
94 community_id: community.id,
99 // This will fail if they aren't a follower, but ignore the error.
100 blocking(context.pool(), move |conn| {
101 CommunityFollower::unfollow(conn, &community_follower_form).ok()
107 fn common(&self) -> &ActivityCommonFields {