]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/following/accept.rs
Show deleted and removed posts for profile views. Fixes #2624 (#2729)
[lemmy.git] / crates / apub / src / activities / following / accept.rs
1 use crate::{
2   activities::{generate_activity_id, send_lemmy_activity},
3   local_instance,
4   protocol::activities::following::{accept::AcceptFollow, follow::Follow},
5   ActorType,
6 };
7 use activitypub_federation::{
8   core::object_id::ObjectId,
9   data::Data,
10   traits::{ActivityHandler, Actor},
11   utils::verify_urls_match,
12 };
13 use activitystreams_kinds::activity::AcceptType;
14 use lemmy_api_common::{
15   community::CommunityResponse,
16   context::LemmyContext,
17   websocket::UserOperation,
18 };
19 use lemmy_db_schema::{
20   source::{actor_language::CommunityLanguage, community::CommunityFollower},
21   traits::Followable,
22 };
23 use lemmy_db_views::structs::LocalUserView;
24 use lemmy_db_views_actor::structs::CommunityView;
25 use lemmy_utils::error::LemmyError;
26 use url::Url;
27
28 impl AcceptFollow {
29   #[tracing::instrument(skip_all)]
30   pub async fn send(
31     follow: Follow,
32     context: &LemmyContext,
33     request_counter: &mut i32,
34   ) -> Result<(), LemmyError> {
35     let user_or_community = follow.object.dereference_local(context).await?;
36     let person = follow
37       .actor
38       .clone()
39       .dereference(context, local_instance(context).await, request_counter)
40       .await?;
41     let accept = AcceptFollow {
42       actor: ObjectId::new(user_or_community.actor_id()),
43       object: follow,
44       kind: AcceptType::Accept,
45       id: generate_activity_id(
46         AcceptType::Accept,
47         &context.settings().get_protocol_and_hostname(),
48       )?,
49     };
50     let inbox = vec![person.shared_inbox_or_inbox()];
51     send_lemmy_activity(context, accept, &user_or_community, inbox, true).await
52   }
53 }
54
55 /// Handle accepted follows
56 #[async_trait::async_trait(?Send)]
57 impl ActivityHandler for AcceptFollow {
58   type DataType = LemmyContext;
59   type Error = LemmyError;
60
61   fn id(&self) -> &Url {
62     &self.id
63   }
64
65   fn actor(&self) -> &Url {
66     self.actor.inner()
67   }
68
69   #[tracing::instrument(skip_all)]
70   async fn verify(
71     &self,
72     context: &Data<LemmyContext>,
73     request_counter: &mut i32,
74   ) -> Result<(), LemmyError> {
75     verify_urls_match(self.actor.inner(), self.object.object.inner())?;
76     self.object.verify(context, request_counter).await?;
77     Ok(())
78   }
79
80   #[tracing::instrument(skip_all)]
81   async fn receive(
82     self,
83     context: &Data<LemmyContext>,
84     request_counter: &mut i32,
85   ) -> Result<(), LemmyError> {
86     let community = self
87       .actor
88       .dereference(context, local_instance(context).await, request_counter)
89       .await?;
90     let person = self
91       .object
92       .actor
93       .dereference(context, local_instance(context).await, request_counter)
94       .await?;
95     // This will throw an error if no follow was requested
96     let community_id = community.id;
97     let person_id = person.id;
98     CommunityFollower::follow_accepted(context.pool(), community_id, person_id).await?;
99
100     // Send the Subscribed message over websocket
101     // Re-read the community_view to get the new SubscribedType
102     let community_view =
103       CommunityView::read(context.pool(), community_id, Some(person_id), None).await?;
104
105     // Get the local_user_id
106     let local_recipient_id = LocalUserView::read_person(context.pool(), person_id)
107       .await?
108       .local_user
109       .id;
110     let discussion_languages = CommunityLanguage::read(context.pool(), community_id).await?;
111
112     let response = CommunityResponse {
113       community_view,
114       discussion_languages,
115     };
116
117     context
118       .chat_server()
119       .send_user_room_message(
120         &UserOperation::FollowCommunity,
121         &response,
122         local_recipient_id,
123         None,
124       )
125       .await?;
126
127     Ok(())
128   }
129 }