]> Untitled Git - lemmy.git/blobdiff - crates/apub/src/objects/post.rs
Rewrite activitypub following, person, community, pm (#1692)
[lemmy.git] / crates / apub / src / objects / post.rs
index 2fdf8d67b5ce99f696438f17e281873816da70ee..43a019d16c70a046c658fcb8de10caa3fa39a1f7 100644 (file)
@@ -2,7 +2,7 @@ use crate::{
   activities::{extract_community, verify_person_in_community},
   extensions::context::lemmy_context,
   fetcher::person::get_or_fetch_and_upsert_person,
-  objects::{create_tombstone, FromApub, Source, ToApub},
+  objects::{create_tombstone, FromApub, ImageObject, Source, ToApub},
   ActorType,
 };
 use activitystreams::{
@@ -37,15 +37,17 @@ use lemmy_utils::{
 };
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
+use serde_with::skip_serializing_none;
 use url::Url;
 
+#[skip_serializing_none]
 #[derive(Clone, Debug, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct Page {
   #[serde(rename = "@context")]
   context: OneOrMany<AnyBase>,
   r#type: PageType,
-  pub(crate) id: Url,
+  id: Url,
   pub(crate) attributed_to: Url,
   to: [Url; 2],
   name: String,
@@ -63,14 +65,15 @@ pub struct Page {
   unparsed: Unparsed,
 }
 
-#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ImageObject {
-  content: ImageType,
-  url: Url,
-}
-
 impl Page {
+  pub(crate) fn id_unchecked(&self) -> &Url {
+    &self.id
+  }
+  pub(crate) fn id(&self, expected_domain: &Url) -> Result<&Url, LemmyError> {
+    verify_domains_match(&self.id, expected_domain)?;
+    Ok(&self.id)
+  }
+
   /// Only mods can change the post's stickied/locked status. So if either of these is changed from
   /// the current value, it is a mod action and needs to be verified as such.
   ///
@@ -126,7 +129,7 @@ impl ToApub for Post {
       media_type: MediaTypeMarkdown::Markdown,
     });
     let image = self.thumbnail_url.clone().map(|thumb| ImageObject {
-      content: ImageType::Image,
+      kind: ImageType::Image,
       url: thumb.into(),
     });
 
@@ -169,10 +172,17 @@ impl FromApub for Post {
   async fn from_apub(
     page: &Page,
     context: &LemmyContext,
-    _expected_domain: Url,
+    expected_domain: &Url,
     request_counter: &mut i32,
-    _mod_action_allowed: bool,
   ) -> Result<Post, LemmyError> {
+    // We can't verify the domain in case of mod action, because the mod may be on a different
+    // instance from the post author.
+    let ap_id = if page.is_mod_action(context.pool()).await? {
+      page.id_unchecked()
+    } else {
+      page.id(expected_domain)?
+    };
+    let ap_id = Some(ap_id.clone().into());
     let creator =
       get_or_fetch_and_upsert_person(&page.attributed_to, context, request_counter).await?;
     let community = extract_community(&page.to, context, request_counter).await?;
@@ -205,7 +215,7 @@ impl FromApub for Post {
       embed_description,
       embed_html,
       thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
-      ap_id: Some(page.id.clone().into()),
+      ap_id,
       local: Some(false),
     };
     Ok(blocking(context.pool(), move |conn| Post::upsert(conn, &form)).await??)