From 71067a8cb58a6d1d1b064d3c01852fd53057b609 Mon Sep 17 00:00:00 2001
From: Felix Ableitner <me@nutomic.com>
Date: Tue, 16 Mar 2021 18:26:19 +0100
Subject: [PATCH] For FromApub trait, use `is_mod_action: bool` instead

---
 crates/apub/src/activities/receive/comment.rs |  4 +--
 crates/apub/src/activities/receive/post.rs    | 15 +++++++---
 .../src/activities/receive/private_message.rs |  4 +--
 crates/apub/src/fetcher/community.rs          | 10 +++++--
 crates/apub/src/fetcher/objects.rs            |  6 ++--
 crates/apub/src/fetcher/search.rs             |  4 +--
 crates/apub/src/fetcher/user.rs               |  6 ++--
 crates/apub/src/objects/comment.rs            | 17 +++++++----
 crates/apub/src/objects/community.rs          | 17 +++++++----
 crates/apub/src/objects/mod.rs                | 19 ++++++++++---
 crates/apub/src/objects/post.rs               | 28 ++++++++++++-------
 crates/apub/src/objects/private_message.rs    | 16 ++++++++---
 crates/apub/src/objects/user.rs               | 17 +++++++----
 13 files changed, 114 insertions(+), 49 deletions(-)

diff --git a/crates/apub/src/activities/receive/comment.rs b/crates/apub/src/activities/receive/comment.rs
index 2b11ad18..bc150793 100644
--- a/crates/apub/src/activities/receive/comment.rs
+++ b/crates/apub/src/activities/receive/comment.rs
@@ -23,7 +23,7 @@ pub(crate) async fn receive_create_comment(
   let note = NoteExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
     .context(location_info!())?;
 
-  let comment = Comment::from_apub(&note, context, Some(user.actor_id()), request_counter).await?;
+  let comment = Comment::from_apub(&note, context, user.actor_id(), request_counter, false).await?;
 
   let post_id = comment.post_id;
   let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
@@ -66,7 +66,7 @@ pub(crate) async fn receive_update_comment(
     .context(location_info!())?;
   let user = get_actor_as_user(&update, context, request_counter).await?;
 
-  let comment = Comment::from_apub(&note, context, Some(user.actor_id()), request_counter).await?;
+  let comment = Comment::from_apub(&note, context, user.actor_id(), request_counter, false).await?;
 
   let comment_id = comment.id;
   let post_id = comment.post_id;
diff --git a/crates/apub/src/activities/receive/post.rs b/crates/apub/src/activities/receive/post.rs
index c6370679..33b2ce67 100644
--- a/crates/apub/src/activities/receive/post.rs
+++ b/crates/apub/src/activities/receive/post.rs
@@ -32,7 +32,7 @@ pub(crate) async fn receive_create_post(
   let page = PageExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
     .context(location_info!())?;
 
-  let post = Post::from_apub(&page, context, Some(user.actor_id()), request_counter).await?;
+  let post = Post::from_apub(&page, context, user.actor_id(), request_counter, false).await?;
 
   // Refetch the view
   let post_id = post.id;
@@ -72,20 +72,27 @@ pub(crate) async fn receive_update_post(
   })
   .await??;
 
-  let mut expected_domain = Some(user.actor_id());
   // If sticked or locked state was changed, make sure the actor is a mod
   let stickied = page.ext_one.stickied.context(location_info!())?;
   let locked = !page.ext_one.comments_enabled.context(location_info!())?;
+  let mut is_mod_action = false;
   if stickied != old_post.stickied || locked != old_post.locked {
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, old_post.community_id)
     })
     .await??;
     verify_mod_activity(&update, announce, &community, context).await?;
-    expected_domain = None;
+    is_mod_action = true;
   }
 
-  let post = Post::from_apub(&page, context, expected_domain, request_counter).await?;
+  let post = Post::from_apub(
+    &page,
+    context,
+    user.actor_id(),
+    request_counter,
+    is_mod_action,
+  )
+  .await?;
 
   let post_id = post.id;
   // Refetch the view
diff --git a/crates/apub/src/activities/receive/private_message.rs b/crates/apub/src/activities/receive/private_message.rs
index 54379f2a..b20494cf 100644
--- a/crates/apub/src/activities/receive/private_message.rs
+++ b/crates/apub/src/activities/receive/private_message.rs
@@ -39,7 +39,7 @@ pub(crate) async fn receive_create_private_message(
   .context(location_info!())?;
 
   let private_message =
-    PrivateMessage::from_apub(&note, context, Some(expected_domain), request_counter).await?;
+    PrivateMessage::from_apub(&note, context, expected_domain, request_counter, false).await?;
 
   let message = blocking(&context.pool(), move |conn| {
     PrivateMessageView::read(conn, private_message.id)
@@ -78,7 +78,7 @@ pub(crate) async fn receive_update_private_message(
   let note = NoteExt::from_any_base(object)?.context(location_info!())?;
 
   let private_message =
-    PrivateMessage::from_apub(&note, context, Some(expected_domain), request_counter).await?;
+    PrivateMessage::from_apub(&note, context, expected_domain, request_counter, false).await?;
 
   let private_message_id = private_message.id;
   let message = blocking(&context.pool(), move |conn| {
diff --git a/crates/apub/src/fetcher/community.rs b/crates/apub/src/fetcher/community.rs
index 01b30f93..4ae98be6 100644
--- a/crates/apub/src/fetcher/community.rs
+++ b/crates/apub/src/fetcher/community.rs
@@ -71,8 +71,14 @@ async fn fetch_remote_community(
   }
 
   let group = group?;
-  let community =
-    Community::from_apub(&group, context, Some(apub_id.to_owned()), recursion_counter).await?;
+  let community = Community::from_apub(
+    &group,
+    context,
+    apub_id.to_owned(),
+    recursion_counter,
+    false,
+  )
+  .await?;
 
   // only fetch outbox for new communities, otherwise this can create an infinite loop
   if old_community.is_none() {
diff --git a/crates/apub/src/fetcher/objects.rs b/crates/apub/src/fetcher/objects.rs
index f2030a06..4ba2a56f 100644
--- a/crates/apub/src/fetcher/objects.rs
+++ b/crates/apub/src/fetcher/objects.rs
@@ -33,8 +33,9 @@ pub(crate) async fn get_or_fetch_and_insert_post(
       let post = Post::from_apub(
         &page,
         context,
-        Some(post_ap_id.to_owned()),
+        post_ap_id.to_owned(),
         recursion_counter,
+        false,
       )
       .await?;
 
@@ -71,8 +72,9 @@ pub(crate) async fn get_or_fetch_and_insert_comment(
       let comment = Comment::from_apub(
         &comment,
         context,
-        Some(comment_ap_id.to_owned()),
+        comment_ap_id.to_owned(),
         recursion_counter,
+        false,
       )
       .await?;
 
diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs
index f5ae9dfd..10f4ac5d 100644
--- a/crates/apub/src/fetcher/search.rs
+++ b/crates/apub/src/fetcher/search.rs
@@ -147,13 +147,13 @@ async fn build_response(
       ];
     }
     SearchAcceptedObjects::Page(p) => {
-      let p = Post::from_apub(&p, context, Some(query_url), recursion_counter).await?;
+      let p = Post::from_apub(&p, context, query_url, recursion_counter, false).await?;
 
       response.posts =
         vec![blocking(context.pool(), move |conn| PostView::read(conn, p.id, None)).await??];
     }
     SearchAcceptedObjects::Comment(c) => {
-      let c = Comment::from_apub(&c, context, Some(query_url), recursion_counter).await?;
+      let c = Comment::from_apub(&c, context, query_url, recursion_counter, false).await?;
 
       response.comments = vec![
         blocking(context.pool(), move |conn| {
diff --git a/crates/apub/src/fetcher/user.rs b/crates/apub/src/fetcher/user.rs
index e3ea70ea..7f998ac7 100644
--- a/crates/apub/src/fetcher/user.rs
+++ b/crates/apub/src/fetcher/user.rs
@@ -49,8 +49,9 @@ pub(crate) async fn get_or_fetch_and_upsert_user(
       let user = User_::from_apub(
         &person?,
         context,
-        Some(apub_id.to_owned()),
+        apub_id.to_owned(),
         recursion_counter,
+        false,
       )
       .await?;
 
@@ -71,8 +72,9 @@ pub(crate) async fn get_or_fetch_and_upsert_user(
       let user = User_::from_apub(
         &person,
         context,
-        Some(apub_id.to_owned()),
+        apub_id.to_owned(),
         recursion_counter,
+        false,
       )
       .await?;
 
diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs
index 3fe90738..43bd8659 100644
--- a/crates/apub/src/objects/comment.rs
+++ b/crates/apub/src/objects/comment.rs
@@ -97,11 +97,18 @@ impl FromApub for Comment {
   async fn from_apub(
     note: &NoteExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    is_mod_action: bool,
   ) -> Result<Comment, LemmyError> {
-    let comment: Comment =
-      get_object_from_apub(note, context, expected_domain, request_counter).await?;
+    let comment: Comment = get_object_from_apub(
+      note,
+      context,
+      expected_domain,
+      request_counter,
+      is_mod_action,
+    )
+    .await?;
 
     let post_id = comment.post_id;
     let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
@@ -126,10 +133,10 @@ impl FromApubToForm<NoteExt> for CommentForm {
   async fn from_apub(
     note: &NoteExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    _is_mod_action: bool,
   ) -> Result<CommentForm, LemmyError> {
-    let expected_domain = expected_domain.expect("expected_domain must be set for comment");
     let creator_actor_id = &note
       .attributed_to()
       .context(location_info!())?
diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs
index efeb7eea..9ae801b7 100644
--- a/crates/apub/src/objects/community.rs
+++ b/crates/apub/src/objects/community.rs
@@ -105,11 +105,18 @@ impl FromApub for Community {
   async fn from_apub(
     group: &GroupExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    is_mod_action: bool,
   ) -> Result<Community, LemmyError> {
-    let community: Community =
-      get_object_from_apub(group, context, expected_domain, request_counter).await?;
+    let community: Community = get_object_from_apub(
+      group,
+      context,
+      expected_domain,
+      request_counter,
+      is_mod_action,
+    )
+    .await?;
 
     let new_moderators = fetch_community_mods(context, group, request_counter).await?;
     let community_id = community.id;
@@ -160,10 +167,10 @@ impl FromApubToForm<GroupExt> for CommunityForm {
   async fn from_apub(
     group: &GroupExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    _is_mod_action: bool,
   ) -> Result<Self, LemmyError> {
-    let expected_domain = expected_domain.expect("expected_domain must be set for community");
     let moderator_uris = fetch_community_mods(context, group, request_counter).await?;
     let creator_uri = moderator_uris.first().context(location_info!())?;
 
diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs
index 1dff8102..9f500720 100644
--- a/crates/apub/src/objects/mod.rs
+++ b/crates/apub/src/objects/mod.rs
@@ -46,11 +46,13 @@ pub(crate) trait FromApub {
   /// * `apub` The object to read from
   /// * `context` LemmyContext which holds DB pool, HTTP client etc
   /// * `expected_domain` Domain where the object was received from. None in case of mod action.
+  /// * `is_mod_action` True if the object was sent in a mod activity, ignore `expected_domain` in this case
   async fn from_apub(
     apub: &Self::ApubType,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    is_mod_action: bool,
   ) -> Result<Self, LemmyError>
   where
     Self: Sized;
@@ -61,8 +63,9 @@ pub(in crate::objects) trait FromApubToForm<ApubType> {
   async fn from_apub(
     apub: &ApubType,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    is_mod_action: bool,
   ) -> Result<Self, LemmyError>
   where
     Self: Sized;
@@ -173,8 +176,9 @@ pub(in crate::objects) fn check_is_markdown(mime: Option<&Mime>) -> Result<(), L
 pub(in crate::objects) async fn get_object_from_apub<From, Kind, To, ToForm>(
   from: &From,
   context: &LemmyContext,
-  expected_domain: Option<Url>,
+  expected_domain: Url,
   request_counter: &mut i32,
+  is_mod_action: bool,
 ) -> Result<To, LemmyError>
 where
   From: BaseExt<Kind>,
@@ -194,7 +198,14 @@ where
   }
   // otherwise parse and insert, assuring that it comes from the right domain
   else {
-    let to_form = ToForm::from_apub(&from, context, expected_domain, request_counter).await?;
+    let to_form = ToForm::from_apub(
+      &from,
+      context,
+      expected_domain,
+      request_counter,
+      is_mod_action,
+    )
+    .await?;
 
     let to = blocking(context.pool(), move |conn| To::upsert(conn, &to_form)).await??;
     Ok(to)
diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs
index d15f82b7..92d54264 100644
--- a/crates/apub/src/objects/post.rs
+++ b/crates/apub/src/objects/post.rs
@@ -116,10 +116,18 @@ impl FromApub for Post {
   async fn from_apub(
     page: &PageExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    is_mod_action: bool,
   ) -> Result<Post, LemmyError> {
-    let post: Post = get_object_from_apub(page, context, expected_domain, request_counter).await?;
+    let post: Post = get_object_from_apub(
+      page,
+      context,
+      expected_domain,
+      request_counter,
+      is_mod_action,
+    )
+    .await?;
     check_object_for_community_or_site_ban(page, post.community_id, context, request_counter)
       .await?;
     Ok(post)
@@ -131,16 +139,16 @@ impl FromApubToForm<PageExt> for PostForm {
   async fn from_apub(
     page: &PageExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    is_mod_action: bool,
   ) -> Result<PostForm, LemmyError> {
-    let ap_id = match expected_domain {
-      Some(e) => check_object_domain(page, e)?,
-      None => {
-        let id = page.id_unchecked().context(location_info!())?;
-        check_is_apub_id_valid(id)?;
-        id.to_owned().into()
-      }
+    let ap_id = if is_mod_action {
+      let id = page.id_unchecked().context(location_info!())?;
+      check_is_apub_id_valid(id)?;
+      id.to_owned().into()
+    } else {
+      check_object_domain(page, expected_domain)?
     };
     let ext = &page.ext_one;
     let creator_actor_id = page
diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs
index 0dfa102f..93d13503 100644
--- a/crates/apub/src/objects/private_message.rs
+++ b/crates/apub/src/objects/private_message.rs
@@ -75,10 +75,18 @@ impl FromApub for PrivateMessage {
   async fn from_apub(
     note: &NoteExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    is_mod_action: bool,
   ) -> Result<PrivateMessage, LemmyError> {
-    get_object_from_apub(note, context, expected_domain, request_counter).await
+    get_object_from_apub(
+      note,
+      context,
+      expected_domain,
+      request_counter,
+      is_mod_action,
+    )
+    .await
   }
 }
 
@@ -87,10 +95,10 @@ impl FromApubToForm<NoteExt> for PrivateMessageForm {
   async fn from_apub(
     note: &NoteExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    _is_mod_action: bool,
   ) -> Result<PrivateMessageForm, LemmyError> {
-    let expected_domain = expected_domain.expect("expected_domain must be set for private message");
     let creator_actor_id = note
       .attributed_to()
       .context(location_info!())?
diff --git a/crates/apub/src/objects/user.rs b/crates/apub/src/objects/user.rs
index e822fcd9..5b33331b 100644
--- a/crates/apub/src/objects/user.rs
+++ b/crates/apub/src/objects/user.rs
@@ -91,8 +91,9 @@ impl FromApub for User_ {
   async fn from_apub(
     person: &PersonExt,
     context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     request_counter: &mut i32,
+    is_mod_action: bool,
   ) -> Result<User_, LemmyError> {
     let user_id = person.id_unchecked().context(location_info!())?.to_owned();
     let domain = user_id.domain().context(location_info!())?;
@@ -103,8 +104,14 @@ impl FromApub for User_ {
       .await??;
       Ok(user)
     } else {
-      let user_form =
-        UserForm::from_apub(person, context, expected_domain, request_counter).await?;
+      let user_form = UserForm::from_apub(
+        person,
+        context,
+        expected_domain,
+        request_counter,
+        is_mod_action,
+      )
+      .await?;
       let user = blocking(context.pool(), move |conn| User_::upsert(conn, &user_form)).await??;
       Ok(user)
     }
@@ -116,10 +123,10 @@ impl FromApubToForm<PersonExt> for UserForm {
   async fn from_apub(
     person: &PersonExt,
     _context: &LemmyContext,
-    expected_domain: Option<Url>,
+    expected_domain: Url,
     _request_counter: &mut i32,
+    _is_mod_action: bool,
   ) -> Result<Self, LemmyError> {
-    let expected_domain = expected_domain.expect("expected_domain must be set for user");
     let avatar = match person.icon() {
       Some(any_image) => Some(
         Image::from_any_base(any_image.as_one().context(location_info!())?.clone())?
-- 
2.44.1