6 verify_person_in_community,
8 fetcher::user_or_community::UserOrCommunity,
10 objects::{community::ApubCommunity, person::ApubPerson},
11 protocol::activities::following::{
14 undo_follow::UndoFollow,
19 use activitypub_federation::{
20 core::object_id::ObjectId,
22 traits::{ActivityHandler, Actor},
24 use activitystreams_kinds::activity::FollowType;
25 use lemmy_api_common::{
26 community::{BlockCommunity, BlockCommunityResponse},
27 context::LemmyContext,
28 utils::get_local_user_view_from_jwt,
30 use lemmy_db_schema::{
32 community::{Community, CommunityFollower, CommunityFollowerForm},
33 person::{PersonFollower, PersonFollowerForm},
35 traits::{Crud, Followable},
37 use lemmy_utils::error::LemmyError;
41 pub(in crate::activities::following) fn new(
43 community: &ApubCommunity,
44 context: &LemmyContext,
45 ) -> Result<Follow, LemmyError> {
47 actor: ObjectId::new(actor.actor_id()),
48 object: ObjectId::new(community.actor_id()),
49 kind: FollowType::Follow,
50 id: generate_activity_id(
52 &context.settings().get_protocol_and_hostname(),
57 #[tracing::instrument(skip_all)]
60 community: &ApubCommunity,
61 context: &LemmyContext,
62 ) -> Result<(), LemmyError> {
63 let community_follower_form = CommunityFollowerForm {
64 community_id: community.id,
68 CommunityFollower::follow(context.pool(), &community_follower_form)
72 let follow = Follow::new(actor, community, context)?;
73 let inbox = vec![community.shared_inbox_or_inbox()];
74 send_lemmy_activity(context, follow, actor, inbox, true).await
78 #[async_trait::async_trait(?Send)]
79 impl ActivityHandler for Follow {
80 type DataType = LemmyContext;
81 type Error = LemmyError;
83 fn id(&self) -> &Url {
87 fn actor(&self) -> &Url {
91 #[tracing::instrument(skip_all)]
94 context: &Data<LemmyContext>,
95 request_counter: &mut i32,
96 ) -> Result<(), LemmyError> {
97 verify_person(&self.actor, context, request_counter).await?;
100 .dereference(context, local_instance(context).await, request_counter)
102 if let UserOrCommunity::Community(c) = object {
103 verify_person_in_community(&self.actor, &c, context, request_counter).await?;
108 #[tracing::instrument(skip_all)]
111 context: &Data<LemmyContext>,
112 request_counter: &mut i32,
113 ) -> Result<(), LemmyError> {
116 .dereference(context, local_instance(context).await, request_counter)
120 .dereference(context, local_instance(context).await, request_counter)
123 UserOrCommunity::User(u) => {
124 let form = PersonFollowerForm {
126 follower_id: actor.id,
129 PersonFollower::follow(context.pool(), &form).await?;
131 UserOrCommunity::Community(c) => {
132 let form = CommunityFollowerForm {
137 CommunityFollower::follow(context.pool(), &form).await?;
141 AcceptFollow::send(self, context, request_counter).await
145 #[async_trait::async_trait(?Send)]
146 impl SendActivity for BlockCommunity {
147 type Response = BlockCommunityResponse;
149 async fn send_activity(
151 _response: &Self::Response,
152 context: &LemmyContext,
153 ) -> Result<(), LemmyError> {
154 let local_user_view =
155 get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?;
156 let community = Community::read(context.pool(), request.community_id).await?;
157 UndoFollow::send(&local_user_view.person.into(), &community.into(), context).await