3 community::announce::{AnnouncableActivities, AnnounceActivity},
4 following::accept::AcceptFollowCommunity,
6 create_or_update::CreateOrUpdatePrivateMessage,
7 delete::DeletePrivateMessage,
8 undo_delete::UndoDeletePrivateMessage,
11 context::lemmy_context,
15 create_apub_tombstone_response,
21 use activitystreams::{
23 collection::{CollectionExt, OrderedCollection},
25 use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
26 use lemmy_api_common::blocking;
27 use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler};
28 use lemmy_db_schema::source::person::Person;
29 use lemmy_utils::LemmyError;
30 use lemmy_websocket::LemmyContext;
32 use serde::{Deserialize, Serialize};
35 #[derive(Deserialize)]
36 pub struct PersonQuery {
40 /// Return the ActivityPub json representation of a local person over HTTP.
41 pub(crate) async fn get_apub_person_http(
42 info: web::Path<PersonQuery>,
43 context: web::Data<LemmyContext>,
44 ) -> Result<HttpResponse<Body>, LemmyError> {
45 let user_name = info.into_inner().user_name;
46 // TODO: this needs to be able to read deleted persons, so that it can send tombstones
47 let person = blocking(context.pool(), move |conn| {
48 Person::find_by_name(conn, &user_name)
53 let apub = person.to_apub(context.pool()).await?;
55 Ok(create_apub_response(&apub))
57 Ok(create_apub_tombstone_response(&person.to_tombstone()?))
61 #[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)]
63 #[activity_handler(LemmyContext)]
64 pub enum PersonInboxActivities {
65 AcceptFollowCommunity(AcceptFollowCommunity),
66 /// Some activities can also be sent from user to user, eg a comment with mentions
67 AnnouncableActivities(AnnouncableActivities),
68 CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage),
69 DeletePrivateMessage(DeletePrivateMessage),
70 UndoDeletePrivateMessage(UndoDeletePrivateMessage),
71 AnnounceActivity(Box<AnnounceActivity>),
74 pub async fn person_inbox(
77 _path: web::Path<String>,
78 context: web::Data<LemmyContext>,
79 ) -> Result<HttpResponse, LemmyError> {
80 let unparsed = payload_to_string(payload).await?;
81 trace!("Received person inbox activity {}", unparsed);
82 let activity = serde_json::from_str::<PersonInboxActivities>(&unparsed)?;
83 receive_person_inbox(activity, request, &context).await
86 pub(in crate::http) async fn receive_person_inbox(
87 activity: PersonInboxActivities,
89 context: &LemmyContext,
90 ) -> Result<HttpResponse, LemmyError> {
91 receive_activity(request, activity, context).await
94 pub(crate) async fn get_apub_person_outbox(
95 info: web::Path<PersonQuery>,
96 context: web::Data<LemmyContext>,
97 ) -> Result<HttpResponse<Body>, LemmyError> {
98 let person = blocking(context.pool(), move |conn| {
99 Person::find_by_name(conn, &info.user_name)
102 // TODO: populate the person outbox
103 let mut collection = OrderedCollection::new();
105 .set_many_items(Vec::<Url>::new())
106 .set_many_contexts(lemmy_context())
107 .set_id(generate_outbox_url(&person.actor_id)?.into())
108 .set_total_items(0_u64);
109 Ok(create_apub_response(&collection))
112 pub(crate) async fn get_apub_person_inbox(
113 info: web::Path<PersonQuery>,
114 context: web::Data<LemmyContext>,
115 ) -> Result<HttpResponse<Body>, LemmyError> {
116 let person = blocking(context.pool(), move |conn| {
117 Person::find_by_name(conn, &info.user_name)
121 let mut collection = OrderedCollection::new();
123 .set_id(person.inbox_url.into())
124 .set_many_contexts(lemmy_context());
125 Ok(create_apub_response(&collection))