4 announce::{AnnouncableActivities, GetCommunity},
11 verify_person_in_community,
13 context::lemmy_context,
14 fetcher::object_id::ObjectId,
15 objects::{community::ApubCommunity, person::ApubPerson},
17 use activitystreams::{
18 activity::kind::BlockType,
20 primitives::OneOrMany,
24 use lemmy_api_common::blocking;
27 traits::{ActivityFields, ActivityHandler, ActorType},
29 use lemmy_db_schema::{
32 CommunityFollowerForm,
34 CommunityPersonBanForm,
36 traits::{Bannable, Followable},
38 use lemmy_utils::LemmyError;
39 use lemmy_websocket::LemmyContext;
40 use serde::{Deserialize, Serialize};
43 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
44 #[serde(rename_all = "camelCase")]
45 pub struct BlockUserFromCommunity {
46 actor: ObjectId<ApubPerson>,
48 pub(in crate::activities::community) object: ObjectId<ApubPerson>,
49 cc: [ObjectId<ApubCommunity>; 1],
50 target: ObjectId<ApubCommunity>,
51 #[serde(rename = "type")]
54 #[serde(rename = "@context")]
55 context: OneOrMany<AnyBase>,
60 impl BlockUserFromCommunity {
61 pub(in crate::activities::community) fn new(
62 community: &ApubCommunity,
65 context: &LemmyContext,
66 ) -> Result<BlockUserFromCommunity, LemmyError> {
67 Ok(BlockUserFromCommunity {
68 actor: ObjectId::new(actor.actor_id()),
70 object: ObjectId::new(target.actor_id()),
71 cc: [ObjectId::new(community.actor_id())],
72 target: ObjectId::new(community.actor_id()),
73 kind: BlockType::Block,
74 id: generate_activity_id(
76 &context.settings().get_protocol_and_hostname(),
78 context: lemmy_context(),
79 unparsed: Default::default(),
84 community: &ApubCommunity,
87 context: &LemmyContext,
88 ) -> Result<(), LemmyError> {
89 let block = BlockUserFromCommunity::new(community, target, actor, context)?;
90 let block_id = block.id.clone();
92 let activity = AnnouncableActivities::BlockUserFromCommunity(block);
93 let inboxes = vec![target.shared_inbox_or_inbox_url()];
94 send_to_community(activity, &block_id, actor, community, inboxes, context).await
98 #[async_trait::async_trait(?Send)]
99 impl ActivityHandler for BlockUserFromCommunity {
100 type DataType = LemmyContext;
103 context: &Data<LemmyContext>,
104 request_counter: &mut i32,
105 ) -> Result<(), LemmyError> {
106 verify_is_public(&self.to)?;
107 verify_activity(self, &context.settings())?;
108 let community = self.get_community(context, request_counter).await?;
109 verify_person_in_community(&self.actor, &community, context, request_counter).await?;
110 verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
116 context: &Data<LemmyContext>,
117 request_counter: &mut i32,
118 ) -> Result<(), LemmyError> {
119 let community = self.get_community(context, request_counter).await?;
120 let blocked_user = self.object.dereference(context, request_counter).await?;
122 let community_user_ban_form = CommunityPersonBanForm {
123 community_id: community.id,
124 person_id: blocked_user.id,
127 blocking(context.pool(), move |conn: &'_ _| {
128 CommunityPersonBan::ban(conn, &community_user_ban_form)
132 // Also unsubscribe them from the community, if they are subscribed
133 let community_follower_form = CommunityFollowerForm {
134 community_id: community.id,
135 person_id: blocked_user.id,
138 blocking(context.pool(), move |conn: &'_ _| {
139 CommunityFollower::unfollow(conn, &community_follower_form)
148 #[async_trait::async_trait(?Send)]
149 impl GetCommunity for BlockUserFromCommunity {
150 async fn get_community(
152 context: &LemmyContext,
153 request_counter: &mut i32,
154 ) -> Result<ApubCommunity, LemmyError> {
155 self.target.dereference(context, request_counter).await