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