]> Untitled Git - lemmy.git/blob - crates/apub/src/http/community.rs
Make functions work with both connection and pool (#3420)
[lemmy.git] / crates / apub / src / http / community.rs
1 use crate::{
2   activity_lists::GroupInboxActivities,
3   collections::{
4     community_featured::ApubCommunityFeatured,
5     community_moderators::ApubCommunityModerators,
6     community_outbox::ApubCommunityOutbox,
7   },
8   http::{create_apub_response, create_apub_tombstone_response},
9   objects::{community::ApubCommunity, person::ApubPerson},
10   protocol::collections::group_followers::GroupFollowers,
11 };
12 use activitypub_federation::{
13   actix_web::inbox::receive_activity,
14   config::Data,
15   protocol::context::WithContext,
16   traits::{Collection, Object},
17 };
18 use actix_web::{web, web::Bytes, HttpRequest, HttpResponse};
19 use lemmy_api_common::context::LemmyContext;
20 use lemmy_db_schema::{source::community::Community, traits::ApubActor};
21 use lemmy_utils::error::{LemmyError, LemmyErrorType};
22 use serde::Deserialize;
23
24 #[derive(Deserialize)]
25 pub(crate) struct CommunityQuery {
26   community_name: String,
27 }
28
29 /// Return the ActivityPub json representation of a local community over HTTP.
30 #[tracing::instrument(skip_all)]
31 pub(crate) async fn get_apub_community_http(
32   info: web::Path<CommunityQuery>,
33   context: Data<LemmyContext>,
34 ) -> Result<HttpResponse, LemmyError> {
35   let community: ApubCommunity =
36     Community::read_from_name(&mut context.pool(), &info.community_name, true)
37       .await?
38       .into();
39
40   if !community.deleted && !community.removed {
41     let apub = community.into_json(&context).await?;
42
43     create_apub_response(&apub)
44   } else {
45     create_apub_tombstone_response(community.actor_id.clone())
46   }
47 }
48
49 /// Handler for all incoming receive to community inboxes.
50 #[tracing::instrument(skip_all)]
51 pub async fn community_inbox(
52   request: HttpRequest,
53   body: Bytes,
54   data: Data<LemmyContext>,
55 ) -> Result<HttpResponse, LemmyError> {
56   receive_activity::<WithContext<GroupInboxActivities>, ApubPerson, LemmyContext>(
57     request, body, &data,
58   )
59   .await
60 }
61
62 /// Returns an empty followers collection, only populating the size (for privacy).
63 pub(crate) async fn get_apub_community_followers(
64   info: web::Path<CommunityQuery>,
65   context: Data<LemmyContext>,
66 ) -> Result<HttpResponse, LemmyError> {
67   let community =
68     Community::read_from_name(&mut context.pool(), &info.community_name, false).await?;
69   let followers = GroupFollowers::new(community, &context).await?;
70   create_apub_response(&followers)
71 }
72
73 /// Returns the community outbox, which is populated by a maximum of 20 posts (but no other
74 /// activites like votes or comments).
75 pub(crate) async fn get_apub_community_outbox(
76   info: web::Path<CommunityQuery>,
77   context: Data<LemmyContext>,
78 ) -> Result<HttpResponse, LemmyError> {
79   let community: ApubCommunity =
80     Community::read_from_name(&mut context.pool(), &info.community_name, false)
81       .await?
82       .into();
83   if community.deleted || community.removed {
84     return Err(LemmyErrorType::Deleted)?;
85   }
86   let outbox = ApubCommunityOutbox::read_local(&community, &context).await?;
87   create_apub_response(&outbox)
88 }
89
90 #[tracing::instrument(skip_all)]
91 pub(crate) async fn get_apub_community_moderators(
92   info: web::Path<CommunityQuery>,
93   context: Data<LemmyContext>,
94 ) -> Result<HttpResponse, LemmyError> {
95   let community: ApubCommunity =
96     Community::read_from_name(&mut context.pool(), &info.community_name, false)
97       .await?
98       .into();
99   if community.deleted || community.removed {
100     return Err(LemmyErrorType::Deleted)?;
101   }
102   let moderators = ApubCommunityModerators::read_local(&community, &context).await?;
103   create_apub_response(&moderators)
104 }
105
106 /// Returns collection of featured (stickied) posts.
107 pub(crate) async fn get_apub_community_featured(
108   info: web::Path<CommunityQuery>,
109   context: Data<LemmyContext>,
110 ) -> Result<HttpResponse, LemmyError> {
111   let community: ApubCommunity =
112     Community::read_from_name(&mut context.pool(), &info.community_name, false)
113       .await?
114       .into();
115   if community.deleted || community.removed {
116     return Err(LemmyErrorType::Deleted)?;
117   }
118   let featured = ApubCommunityFeatured::read_local(&community, &context).await?;
119   create_apub_response(&featured)
120 }