]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/undo_block_user.rs
Move @context out of object/activity definitions
[lemmy.git] / crates / apub / src / activities / community / undo_block_user.rs
1 use crate::{
2   activities::{
3     community::{
4       announce::{AnnouncableActivities, GetCommunity},
5       block_user::BlockUserFromCommunity,
6       send_to_community,
7     },
8     generate_activity_id,
9     verify_activity,
10     verify_is_public,
11     verify_mod_action,
12     verify_person_in_community,
13   },
14   fetcher::object_id::ObjectId,
15   objects::{community::ApubCommunity, person::ApubPerson},
16 };
17 use activitystreams::{activity::kind::UndoType, public, unparsed::Unparsed};
18 use lemmy_api_common::blocking;
19 use lemmy_apub_lib::{
20   data::Data,
21   traits::{ActivityFields, ActivityHandler, ActorType},
22 };
23 use lemmy_db_schema::{
24   source::community::{CommunityPersonBan, CommunityPersonBanForm},
25   traits::Bannable,
26 };
27 use lemmy_utils::LemmyError;
28 use lemmy_websocket::LemmyContext;
29 use serde::{Deserialize, Serialize};
30 use url::Url;
31
32 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
33 #[serde(rename_all = "camelCase")]
34 pub struct UndoBlockUserFromCommunity {
35   actor: ObjectId<ApubPerson>,
36   to: Vec<Url>,
37   object: BlockUserFromCommunity,
38   cc: Vec<Url>,
39   #[serde(rename = "type")]
40   kind: UndoType,
41   id: Url,
42   #[serde(flatten)]
43   unparsed: Unparsed,
44 }
45
46 impl UndoBlockUserFromCommunity {
47   pub async fn send(
48     community: &ApubCommunity,
49     target: &ApubPerson,
50     actor: &ApubPerson,
51     context: &LemmyContext,
52   ) -> Result<(), LemmyError> {
53     let block = BlockUserFromCommunity::new(community, target, actor, context)?;
54
55     let id = generate_activity_id(
56       UndoType::Undo,
57       &context.settings().get_protocol_and_hostname(),
58     )?;
59     let undo = UndoBlockUserFromCommunity {
60       actor: ObjectId::new(actor.actor_id()),
61       to: vec![public()],
62       object: block,
63       cc: vec![community.actor_id()],
64       kind: UndoType::Undo,
65       id: id.clone(),
66       unparsed: Default::default(),
67     };
68
69     let activity = AnnouncableActivities::UndoBlockUserFromCommunity(undo);
70     let inboxes = vec![target.shared_inbox_or_inbox_url()];
71     send_to_community(activity, &id, actor, community, inboxes, context).await
72   }
73 }
74
75 #[async_trait::async_trait(?Send)]
76 impl ActivityHandler for UndoBlockUserFromCommunity {
77   type DataType = LemmyContext;
78   async fn verify(
79     &self,
80     context: &Data<LemmyContext>,
81     request_counter: &mut i32,
82   ) -> Result<(), LemmyError> {
83     verify_is_public(&self.to)?;
84     verify_activity(self, &context.settings())?;
85     let community = self.get_community(context, request_counter).await?;
86     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
87     verify_mod_action(&self.actor, &community, context, request_counter).await?;
88     self.object.verify(context, request_counter).await?;
89     Ok(())
90   }
91
92   async fn receive(
93     self,
94     context: &Data<LemmyContext>,
95     request_counter: &mut i32,
96   ) -> Result<(), LemmyError> {
97     let community = self.get_community(context, request_counter).await?;
98     let blocked_user = self
99       .object
100       .object
101       .dereference(context, request_counter)
102       .await?;
103
104     let community_user_ban_form = CommunityPersonBanForm {
105       community_id: community.id,
106       person_id: blocked_user.id,
107     };
108
109     blocking(context.pool(), move |conn: &'_ _| {
110       CommunityPersonBan::unban(conn, &community_user_ban_form)
111     })
112     .await??;
113
114     Ok(())
115   }
116 }
117
118 #[async_trait::async_trait(?Send)]
119 impl GetCommunity for UndoBlockUserFromCommunity {
120   async fn get_community(
121     &self,
122     context: &LemmyContext,
123     request_counter: &mut i32,
124   ) -> Result<ApubCommunity, LemmyError> {
125     self.object.get_community(context, request_counter).await
126   }
127 }