]> Untitled Git - lemmy.git/blobdiff - crates/apub/src/http/person.rs
Implement instance actor (#1798)
[lemmy.git] / crates / apub / src / http / person.rs
index 89d678cf59b4de8b28e45453ae73a5ba223b6770..9081d5a554dc7d27250442112379c8810acde490 100644 (file)
@@ -1,21 +1,25 @@
 use crate::{
-  extensions::context::lemmy_context,
-  http::{create_apub_response, create_apub_tombstone_response},
-  objects::ToApub,
-  ActorType,
+  activity_lists::PersonInboxActivities,
+  context::WithContext,
+  generate_outbox_url,
+  http::{
+    create_apub_response,
+    create_apub_tombstone_response,
+    payload_to_string,
+    receive_activity,
+    ActivityCommonFields,
+  },
+  objects::person::ApubPerson,
+  protocol::collections::empty_outbox::EmptyOutbox,
 };
-use activitystreams::{
-  base::BaseExt,
-  collection::{CollectionExt, OrderedCollection},
-};
-use actix_web::{body::Body, web, HttpResponse};
-use lemmy_api_structs::blocking;
-use lemmy_db_queries::source::person::Person_;
-use lemmy_db_schema::source::person::Person;
+use actix_web::{web, web::Payload, HttpRequest, HttpResponse};
+use lemmy_api_common::blocking;
+use lemmy_apub_lib::traits::ApubObject;
+use lemmy_db_schema::{source::person::Person, traits::ApubActor};
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
 use serde::Deserialize;
-use url::Url;
+use tracing::info;
 
 #[derive(Deserialize)]
 pub struct PersonQuery {
@@ -23,19 +27,21 @@ pub struct PersonQuery {
 }
 
 /// Return the ActivityPub json representation of a local person over HTTP.
-pub async fn get_apub_person_http(
+#[tracing::instrument(skip_all)]
+pub(crate) async fn get_apub_person_http(
   info: web::Path<PersonQuery>,
   context: web::Data<LemmyContext>,
-) -> Result<HttpResponse<Body>, LemmyError> {
+) -> Result<HttpResponse, LemmyError> {
   let user_name = info.into_inner().user_name;
   // TODO: this needs to be able to read deleted persons, so that it can send tombstones
-  let person = blocking(context.pool(), move |conn| {
-    Person::find_by_name(conn, &user_name)
+  let person: ApubPerson = blocking(context.pool(), move |conn| {
+    Person::read_from_name(conn, &user_name)
   })
-  .await??;
+  .await??
+  .into();
 
   if !person.deleted {
-    let apub = person.to_apub(context.pool()).await?;
+    let apub = person.into_apub(&context).await?;
 
     Ok(create_apub_response(&apub))
   } else {
@@ -43,36 +49,39 @@ pub async fn get_apub_person_http(
   }
 }
 
-pub async fn get_apub_person_outbox(
-  info: web::Path<PersonQuery>,
+#[tracing::instrument(skip_all)]
+pub async fn person_inbox(
+  request: HttpRequest,
+  payload: Payload,
+  _path: web::Path<String>,
   context: web::Data<LemmyContext>,
-) -> Result<HttpResponse<Body>, LemmyError> {
-  let person = blocking(context.pool(), move |conn| {
-    Person::find_by_name(&conn, &info.user_name)
-  })
-  .await??;
-  // TODO: populate the person outbox
-  let mut collection = OrderedCollection::new();
-  collection
-    .set_many_items(Vec::<Url>::new())
-    .set_many_contexts(lemmy_context()?)
-    .set_id(person.get_outbox_url()?)
-    .set_total_items(0_u64);
-  Ok(create_apub_response(&collection))
+) -> Result<HttpResponse, LemmyError> {
+  let unparsed = payload_to_string(payload).await?;
+  info!("Received person inbox activity {}", unparsed);
+  let activity_data: ActivityCommonFields = serde_json::from_str(&unparsed)?;
+  let activity = serde_json::from_str::<WithContext<PersonInboxActivities>>(&unparsed)?;
+  receive_person_inbox(activity.inner(), activity_data, request, &context).await
 }
 
-pub async fn get_apub_person_inbox(
+pub(in crate::http) async fn receive_person_inbox(
+  activity: PersonInboxActivities,
+  activity_data: ActivityCommonFields,
+  request: HttpRequest,
+  context: &LemmyContext,
+) -> Result<HttpResponse, LemmyError> {
+  receive_activity(request, activity, activity_data, context).await
+}
+
+#[tracing::instrument(skip_all)]
+pub(crate) async fn get_apub_person_outbox(
   info: web::Path<PersonQuery>,
   context: web::Data<LemmyContext>,
-) -> Result<HttpResponse<Body>, LemmyError> {
+) -> Result<HttpResponse, LemmyError> {
   let person = blocking(context.pool(), move |conn| {
-    Person::find_by_name(&conn, &info.user_name)
+    Person::read_from_name(conn, &info.user_name)
   })
   .await??;
-
-  let mut collection = OrderedCollection::new();
-  collection
-    .set_id(format!("{}/inbox", person.actor_id.into_inner()).parse()?)
-    .set_many_contexts(lemmy_context()?);
-  Ok(create_apub_response(&collection))
+  let outbox_id = generate_outbox_url(&person.actor_id)?.into();
+  let outbox = EmptyOutbox::new(outbox_id).await?;
+  Ok(create_apub_response(&outbox))
 }