]> Untitled Git - lemmy.git/blobdiff - crates/apub/src/protocol/objects/page.rs
Cache & Optimize Woodpecker CI (#3450)
[lemmy.git] / crates / apub / src / protocol / objects / page.rs
index 9055b1fcc3201c570ec2ae99f44f5270cbcc7cbe..f3308b0753078a03bec43d314e37887e2d507d1e 100644 (file)
@@ -1,28 +1,27 @@
 use crate::{
   activities::verify_community_matches,
   fetcher::user_or_community::{PersonOrGroupType, UserOrCommunity},
-  local_instance,
   objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
   protocol::{objects::LanguageTag, ImageObject, InCommunity, Source},
 };
 use activitypub_federation::{
-  core::object_id::ObjectId,
-  data::Data,
-  deser::{
+  config::Data,
+  fetch::object_id::ObjectId,
+  kinds::{
+    link::LinkType,
+    object::{DocumentType, ImageType},
+  },
+  protocol::{
     helpers::{deserialize_one_or_many, deserialize_skip_error},
     values::MediaTypeMarkdownOrHtml,
   },
-  traits::{ActivityHandler, ApubObject},
-};
-use activitystreams_kinds::{
-  link::LinkType,
-  object::{DocumentType, ImageType},
+  traits::{ActivityHandler, Object},
 };
 use chrono::{DateTime, FixedOffset};
 use itertools::Itertools;
 use lemmy_api_common::context::LemmyContext;
 use lemmy_db_schema::newtypes::DbUrl;
-use lemmy_utils::error::LemmyError;
+use lemmy_utils::error::{LemmyError, LemmyErrorType};
 use serde::{de::Error, Deserialize, Deserializer, Serialize};
 use serde_with::skip_serializing_none;
 use url::Url;
@@ -64,7 +63,6 @@ pub struct Page {
   pub(crate) image: Option<ImageObject>,
   pub(crate) comments_enabled: Option<bool>,
   pub(crate) sensitive: Option<bool>,
-  pub(crate) stickied: Option<bool>,
   pub(crate) published: Option<DateTime<FixedOffset>>,
   pub(crate) updated: Option<DateTime<FixedOffset>>,
   pub(crate) language: Option<LanguageTag>,
@@ -131,31 +129,16 @@ pub(crate) struct AttributedToPeertube {
 }
 
 impl Page {
-  /// 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.
+  /// Only mods can change the post's locked status. So if it is changed from the default value,
+  /// it is a mod action and needs to be verified as such.
   ///
-  /// Both stickied and locked need to be false on a newly created post (verified in [[CreatePost]].
-  pub(crate) async fn is_mod_action(&self, context: &LemmyContext) -> Result<bool, LemmyError> {
-    let old_post = ObjectId::<ApubPost>::new(self.id.clone())
-      .dereference_local(context)
-      .await;
-
-    let featured_changed = Page::is_featured_changed(&old_post, &self.stickied);
-    let locked_changed = Page::is_locked_changed(&old_post, &self.comments_enabled);
-    Ok(featured_changed || locked_changed)
-  }
-
-  pub(crate) fn is_featured_changed<E>(
-    old_post: &Result<ApubPost, E>,
-    new_featured_community: &Option<bool>,
-  ) -> bool {
-    if let Some(new_featured_community) = new_featured_community {
-      if let Ok(old_post) = old_post {
-        return new_featured_community != &old_post.featured_community;
-      }
-    }
-
-    false
+  /// Locked needs to be false on a newly created post (verified in [[CreatePost]].
+  pub(crate) async fn is_mod_action(
+    &self,
+    context: &Data<LemmyContext>,
+  ) -> Result<bool, LemmyError> {
+    let old_post = self.id.clone().dereference_local(context).await;
+    Ok(Page::is_locked_changed(&old_post, &self.comments_enabled))
   }
 
   pub(crate) fn is_locked_changed<E>(
@@ -177,8 +160,8 @@ impl Page {
       AttributedTo::Peertube(p) => p
         .iter()
         .find(|a| a.kind == PersonOrGroupType::Person)
-        .map(|a| ObjectId::<ApubPerson>::new(a.id.clone().into_inner()))
-        .ok_or_else(|| LemmyError::from_message("page does not specify creator person")),
+        .map(|a| ObjectId::<ApubPerson>::from(a.id.clone().into_inner()))
+        .ok_or_else(|| LemmyErrorType::PageDoesNotSpecifyCreator.into()),
     }
   }
 }
@@ -193,7 +176,7 @@ impl Attachment {
 }
 
 // Used for community outbox, so that it can be compatible with Pleroma/Mastodon.
-#[async_trait::async_trait(?Send)]
+#[async_trait::async_trait]
 impl ActivityHandler for Page {
   type DataType = LemmyContext;
   type Error = LemmyError;
@@ -203,63 +186,45 @@ impl ActivityHandler for Page {
   fn actor(&self) -> &Url {
     unimplemented!()
   }
-  async fn verify(
-    &self,
-    data: &Data<Self::DataType>,
-    request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    ApubPost::verify(self, self.id.inner(), data, request_counter).await
+  async fn verify(&self, data: &Data<Self::DataType>) -> Result<(), LemmyError> {
+    ApubPost::verify(self, self.id.inner(), data).await
   }
-  async fn receive(
-    self,
-    data: &Data<Self::DataType>,
-    request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    ApubPost::from_apub(self, data, request_counter).await?;
+  async fn receive(self, data: &Data<Self::DataType>) -> Result<(), LemmyError> {
+    ApubPost::from_json(self, data).await?;
     Ok(())
   }
 }
 
-#[async_trait::async_trait(?Send)]
+#[async_trait::async_trait]
 impl InCommunity for Page {
-  async fn community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    let instance = local_instance(context).await;
+  async fn community(&self, context: &Data<LemmyContext>) -> Result<ApubCommunity, LemmyError> {
     let community = match &self.attributed_to {
       AttributedTo::Lemmy(_) => {
         let mut iter = self.to.iter().merge(self.cc.iter());
         loop {
           if let Some(cid) = iter.next() {
-            let cid = ObjectId::new(cid.clone());
-            if let Ok(c) = cid.dereference(context, instance, request_counter).await {
+            let cid = ObjectId::from(cid.clone());
+            if let Ok(c) = cid.dereference(context).await {
               break c;
             }
           } else {
-            return Err(LemmyError::from_message("No community found in cc"));
+            return Err(LemmyErrorType::NoCommunityFoundInCc)?;
           }
         }
       }
       AttributedTo::Peertube(p) => {
         p.iter()
           .find(|a| a.kind == PersonOrGroupType::Group)
-          .map(|a| ObjectId::<ApubCommunity>::new(a.id.clone().into_inner()))
-          .ok_or_else(|| LemmyError::from_message("page does not specify group"))?
-          .dereference(context, instance, request_counter)
+          .map(|a| ObjectId::<ApubCommunity>::from(a.id.clone().into_inner()))
+          .ok_or(LemmyErrorType::PageDoesNotSpecifyGroup)?
+          .dereference(context)
           .await?
       }
     };
     if let Some(audience) = &self.audience {
-      let audience = audience
-        .dereference(context, instance, request_counter)
-        .await?;
-      verify_community_matches(&audience, community.id)?;
-      Ok(audience)
-    } else {
-      Ok(community)
+      verify_community_matches(audience, community.actor_id.clone())?;
     }
+    Ok(community)
   }
 }
 
@@ -277,6 +242,9 @@ where
 
 #[cfg(test)]
 mod tests {
+  #![allow(clippy::unwrap_used)]
+  #![allow(clippy::indexing_slicing)]
+
   use crate::protocol::{objects::page::Page, tests::test_parse_lemmy_item};
 
   #[test]