6 verify_person_in_community,
11 objects::{community::ApubCommunity, person::ApubPerson},
12 protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity},
15 use activitypub_federation::{
16 core::object_id::ObjectId,
18 traits::{ActivityHandler, Actor},
20 use activitystreams_kinds::activity::FollowType;
21 use lemmy_api_common::utils::blocking;
22 use lemmy_db_schema::{
23 source::community::{CommunityFollower, CommunityFollowerForm},
26 use lemmy_utils::error::LemmyError;
27 use lemmy_websocket::LemmyContext;
30 impl FollowCommunity {
31 pub(in crate::activities::following) fn new(
33 community: &ApubCommunity,
34 context: &LemmyContext,
35 ) -> Result<FollowCommunity, LemmyError> {
37 actor: ObjectId::new(actor.actor_id()),
38 object: ObjectId::new(community.actor_id()),
39 kind: FollowType::Follow,
40 id: generate_activity_id(
42 &context.settings().get_protocol_and_hostname(),
44 unparsed: Default::default(),
48 #[tracing::instrument(skip_all)]
51 community: &ApubCommunity,
52 context: &LemmyContext,
53 ) -> Result<(), LemmyError> {
54 let community_follower_form = CommunityFollowerForm {
55 community_id: community.id,
59 blocking(context.pool(), move |conn| {
60 CommunityFollower::follow(conn, &community_follower_form).ok()
64 let follow = FollowCommunity::new(actor, community, context)?;
65 let inbox = vec![community.shared_inbox_or_inbox()];
66 send_lemmy_activity(context, follow, actor, inbox, true).await
70 #[async_trait::async_trait(?Send)]
71 impl ActivityHandler for FollowCommunity {
72 type DataType = LemmyContext;
73 type Error = LemmyError;
75 fn id(&self) -> &Url {
79 fn actor(&self) -> &Url {
83 #[tracing::instrument(skip_all)]
86 context: &Data<LemmyContext>,
87 request_counter: &mut i32,
88 ) -> Result<(), LemmyError> {
89 let local_site_data = blocking(context.pool(), fetch_local_site_data).await??;
90 check_apub_id_valid(self.id(), &local_site_data, context.settings())
91 .map_err(LemmyError::from_message)?;
92 verify_person(&self.actor, context, request_counter).await?;
95 .dereference(context, local_instance(context), request_counter)
97 verify_person_in_community(&self.actor, &community, context, request_counter).await?;
101 #[tracing::instrument(skip_all)]
104 context: &Data<LemmyContext>,
105 request_counter: &mut i32,
106 ) -> Result<(), LemmyError> {
109 .dereference(context, local_instance(context), request_counter)
113 .dereference(context, local_instance(context), request_counter)
115 let community_follower_form = CommunityFollowerForm {
116 community_id: community.id,
117 person_id: person.id,
121 // This will fail if they're already a follower, but ignore the error.
122 blocking(context.pool(), move |conn| {
123 CommunityFollower::follow(conn, &community_follower_form).ok()
127 AcceptFollowCommunity::send(self, context, request_counter).await