3 block::{generate_cc, SiteOrCommunity},
4 community::send_activity_in_community,
9 activity_lists::AnnouncableActivities,
10 insert_received_activity,
11 objects::{instance::remote_instance_inboxes, person::ApubPerson},
12 protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
14 use activitypub_federation::{
16 kinds::{activity::UndoType, public},
17 protocol::verification::verify_domains_match,
18 traits::{ActivityHandler, Actor},
20 use lemmy_api_common::{context::LemmyContext, utils::sanitize_html_opt};
21 use lemmy_db_schema::{
23 community::{CommunityPersonBan, CommunityPersonBanForm},
24 moderator::{ModBan, ModBanForm, ModBanFromCommunity, ModBanFromCommunityForm},
25 person::{Person, PersonUpdateForm},
27 traits::{Bannable, Crud},
29 use lemmy_utils::error::LemmyError;
33 #[tracing::instrument(skip_all)]
35 target: &SiteOrCommunity,
38 reason: Option<String>,
39 context: &Data<LemmyContext>,
40 ) -> Result<(), LemmyError> {
41 let block = BlockUser::new(target, user, mod_, None, reason, None, context).await?;
42 let audience = if let SiteOrCommunity::Community(c) = target {
48 let id = generate_activity_id(
50 &context.settings().get_protocol_and_hostname(),
52 let undo = UndoBlockUser {
53 actor: mod_.id().into(),
56 cc: generate_cc(target, &mut context.pool()).await?,
62 let mut inboxes = vec![user.shared_inbox_or_inbox()];
64 SiteOrCommunity::Site(_) => {
65 inboxes.append(&mut remote_instance_inboxes(&mut context.pool()).await?);
66 send_lemmy_activity(context, undo, mod_, inboxes, false).await
68 SiteOrCommunity::Community(c) => {
69 let activity = AnnouncableActivities::UndoBlockUser(undo);
70 send_activity_in_community(activity, mod_, c, inboxes, true, context).await
76 #[async_trait::async_trait]
77 impl ActivityHandler for UndoBlockUser {
78 type DataType = LemmyContext;
79 type Error = LemmyError;
81 fn id(&self) -> &Url {
85 fn actor(&self) -> &Url {
89 #[tracing::instrument(skip_all)]
90 async fn verify(&self, context: &Data<LemmyContext>) -> Result<(), LemmyError> {
91 insert_received_activity(&self.id, context).await?;
92 verify_is_public(&self.to, &self.cc)?;
93 verify_domains_match(self.actor.inner(), self.object.actor.inner())?;
94 self.object.verify(context).await?;
98 #[tracing::instrument(skip_all)]
99 async fn receive(self, context: &Data<LemmyContext>) -> Result<(), LemmyError> {
100 let expires = self.object.expires.map(|u| u.naive_local());
101 let mod_person = self.actor.dereference(context).await?;
102 let blocked_person = self.object.object.dereference(context).await?;
103 match self.object.target.dereference(context).await? {
104 SiteOrCommunity::Site(_site) => {
105 let blocked_person = Person::update(
110 ban_expires: Some(expires),
117 let form = ModBanForm {
118 mod_person_id: mod_person.id,
119 other_person_id: blocked_person.id,
120 reason: sanitize_html_opt(&self.object.summary),
124 ModBan::create(&mut context.pool(), &form).await?;
126 SiteOrCommunity::Community(community) => {
127 let community_user_ban_form = CommunityPersonBanForm {
128 community_id: community.id,
129 person_id: blocked_person.id,
132 CommunityPersonBan::unban(&mut context.pool(), &community_user_ban_form).await?;
135 let form = ModBanFromCommunityForm {
136 mod_person_id: mod_person.id,
137 other_person_id: blocked_person.id,
138 community_id: community.id,
139 reason: sanitize_html_opt(&self.object.summary),
143 ModBanFromCommunity::create(&mut context.pool(), &form).await?;