2 activities::{following::follow::FollowCommunity, generate_activity_id, verify_activity},
3 context::lemmy_context,
4 fetcher::object_id::ObjectId,
5 objects::{community::ApubCommunity, person::ApubPerson},
9 activity::kind::AcceptType,
11 primitives::OneOrMany,
14 use lemmy_api_common::blocking;
17 traits::{ActivityFields, ActivityHandler, ActorType},
18 verify::verify_urls_match,
20 use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable};
21 use lemmy_utils::LemmyError;
22 use lemmy_websocket::LemmyContext;
23 use serde::{Deserialize, Serialize};
26 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
27 #[serde(rename_all = "camelCase")]
28 pub struct AcceptFollowCommunity {
29 actor: ObjectId<ApubCommunity>,
30 to: [ObjectId<ApubPerson>; 1],
31 object: FollowCommunity,
32 #[serde(rename = "type")]
35 #[serde(rename = "@context")]
36 context: OneOrMany<AnyBase>,
41 impl AcceptFollowCommunity {
43 follow: FollowCommunity,
44 context: &LemmyContext,
45 request_counter: &mut i32,
46 ) -> Result<(), LemmyError> {
47 let community = follow.object.dereference_local(context).await?;
51 .dereference(context, request_counter)
53 let accept = AcceptFollowCommunity {
54 actor: ObjectId::new(community.actor_id()),
55 to: [ObjectId::new(person.actor_id())],
57 kind: AcceptType::Accept,
58 id: generate_activity_id(
60 &context.settings().get_protocol_and_hostname(),
62 context: lemmy_context(),
63 unparsed: Default::default(),
65 let inbox = vec![person.inbox_url()];
66 send_lemmy_activity(context, &accept, &accept.id, &community, inbox, true).await
70 /// Handle accepted follows
71 #[async_trait::async_trait(?Send)]
72 impl ActivityHandler for AcceptFollowCommunity {
73 type DataType = LemmyContext;
76 context: &Data<LemmyContext>,
77 request_counter: &mut i32,
78 ) -> Result<(), LemmyError> {
79 verify_activity(self, &context.settings())?;
80 verify_urls_match(self.to[0].inner(), self.object.actor())?;
81 verify_urls_match(self.actor(), self.object.to[0].inner())?;
82 self.object.verify(context, request_counter).await?;
88 context: &Data<LemmyContext>,
89 request_counter: &mut i32,
90 ) -> Result<(), LemmyError> {
91 let actor = self.actor.dereference(context, request_counter).await?;
92 let to = self.to[0].dereference(context, request_counter).await?;
93 // This will throw an error if no follow was requested
94 blocking(context.pool(), move |conn| {
95 CommunityFollower::follow_accepted(conn, actor.id, to.id)