]> Untitled Git - lemmy.git/blob - crates/apub/src/http/community.rs
Merge pull request #2593 from LemmyNet/refactor-notifications
[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   http::{create_apub_response, create_apub_tombstone_response, receive_lemmy_activity},
9   local_instance,
10   objects::{community::ApubCommunity, person::ApubPerson},
11   protocol::collections::group_followers::GroupFollowers,
12 };
13 use activitypub_federation::{
14   core::object_id::ObjectId,
15   deser::context::WithContext,
16   traits::ApubObject,
17 };
18 use actix_web::{web, HttpRequest, HttpResponse};
19 use lemmy_api_common::{context::LemmyContext, utils::generate_outbox_url};
20 use lemmy_db_schema::{source::community::Community, traits::ApubActor};
21 use lemmy_utils::error::LemmyError;
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: web::Data<LemmyContext>,
34 ) -> Result<HttpResponse, LemmyError> {
35   let community: ApubCommunity =
36     Community::read_from_name(context.pool(), &info.community_name, true)
37       .await?
38       .into();
39
40   if !community.deleted && !community.removed {
41     let apub = community.into_apub(&context).await?;
42
43     Ok(create_apub_response(&apub))
44   } else {
45     Ok(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   payload: String,
54   context: web::Data<LemmyContext>,
55 ) -> Result<HttpResponse, LemmyError> {
56   receive_lemmy_activity::<WithContext<GroupInboxActivities>, ApubPerson>(request, payload, context)
57     .await
58 }
59
60 /// Returns an empty followers collection, only populating the size (for privacy).
61 pub(crate) async fn get_apub_community_followers(
62   info: web::Path<CommunityQuery>,
63   context: web::Data<LemmyContext>,
64 ) -> Result<HttpResponse, LemmyError> {
65   let community = Community::read_from_name(context.pool(), &info.community_name, false).await?;
66   let followers = GroupFollowers::new(community, &context).await?;
67   Ok(create_apub_response(&followers))
68 }
69
70 /// Returns the community outbox, which is populated by a maximum of 20 posts (but no other
71 /// activites like votes or comments).
72 pub(crate) async fn get_apub_community_outbox(
73   info: web::Path<CommunityQuery>,
74   context: web::Data<LemmyContext>,
75 ) -> Result<HttpResponse, LemmyError> {
76   let community = Community::read_from_name(context.pool(), &info.community_name, false).await?;
77   if community.deleted || community.removed {
78     return Err(LemmyError::from_message("deleted"));
79   }
80   let id = ObjectId::new(generate_outbox_url(&community.actor_id)?);
81   let outbox_data = CommunityContext(community.into(), context.get_ref().clone());
82   let outbox: ApubCommunityOutbox = id
83     .dereference(&outbox_data, local_instance(&context).await, &mut 0)
84     .await?;
85   Ok(create_apub_response(&outbox.into_apub(&outbox_data).await?))
86 }
87
88 #[tracing::instrument(skip_all)]
89 pub(crate) async fn get_apub_community_moderators(
90   info: web::Path<CommunityQuery>,
91   context: web::Data<LemmyContext>,
92 ) -> Result<HttpResponse, LemmyError> {
93   let community: ApubCommunity =
94     Community::read_from_name(context.pool(), &info.community_name, false)
95       .await?
96       .into();
97   if community.deleted || community.removed {
98     return Err(LemmyError::from_message("deleted"));
99   }
100   let id = ObjectId::new(generate_outbox_url(&community.actor_id)?);
101   let outbox_data = CommunityContext(community, context.get_ref().clone());
102   let moderators: ApubCommunityModerators = id
103     .dereference(&outbox_data, local_instance(&context).await, &mut 0)
104     .await?;
105   Ok(create_apub_response(
106     &moderators.into_apub(&outbox_data).await?,
107   ))
108 }