]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/following/accept.rs
Merge pull request #1978 from LemmyNet/asonix/reqwest-middleware
[lemmy.git] / crates / apub / src / activities / following / accept.rs
1 use crate::{
2   activities::{generate_activity_id, send_lemmy_activity, verify_activity},
3   protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity},
4 };
5 use activitystreams_kinds::activity::AcceptType;
6 use lemmy_api_common::blocking;
7 use lemmy_apub_lib::{
8   data::Data,
9   object_id::ObjectId,
10   traits::{ActivityHandler, ActorType},
11   verify::verify_urls_match,
12 };
13 use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable};
14 use lemmy_utils::LemmyError;
15 use lemmy_websocket::LemmyContext;
16
17 impl AcceptFollowCommunity {
18   #[tracing::instrument(skip_all)]
19   pub async fn send(
20     follow: FollowCommunity,
21     context: &LemmyContext,
22     request_counter: &mut i32,
23   ) -> Result<(), LemmyError> {
24     let community = follow.object.dereference_local(context).await?;
25     let person = follow
26       .actor
27       .clone()
28       .dereference(context, context.client(), request_counter)
29       .await?;
30     let accept = AcceptFollowCommunity {
31       actor: ObjectId::new(community.actor_id()),
32       object: follow,
33       kind: AcceptType::Accept,
34       id: generate_activity_id(
35         AcceptType::Accept,
36         &context.settings().get_protocol_and_hostname(),
37       )?,
38       unparsed: Default::default(),
39     };
40     let inbox = vec![person.inbox_url()];
41     send_lemmy_activity(context, &accept, &accept.id, &community, inbox, true).await
42   }
43 }
44
45 /// Handle accepted follows
46 #[async_trait::async_trait(?Send)]
47 impl ActivityHandler for AcceptFollowCommunity {
48   type DataType = LemmyContext;
49
50   #[tracing::instrument(skip_all)]
51   async fn verify(
52     &self,
53     context: &Data<LemmyContext>,
54     request_counter: &mut i32,
55   ) -> Result<(), LemmyError> {
56     verify_activity(&self.id, self.actor.inner(), &context.settings())?;
57     verify_urls_match(self.actor.inner(), self.object.object.inner())?;
58     self.object.verify(context, request_counter).await?;
59     Ok(())
60   }
61
62   #[tracing::instrument(skip_all)]
63   async fn receive(
64     self,
65     context: &Data<LemmyContext>,
66     request_counter: &mut i32,
67   ) -> Result<(), LemmyError> {
68     let person = self
69       .actor
70       .dereference(context, context.client(), request_counter)
71       .await?;
72     let community = self
73       .object
74       .actor
75       .dereference(context, context.client(), request_counter)
76       .await?;
77     // This will throw an error if no follow was requested
78     blocking(context.pool(), move |conn| {
79       CommunityFollower::follow_accepted(conn, person.id, community.id)
80     })
81     .await??;
82
83     Ok(())
84   }
85 }