From 803aad3b3ea31d5985213c5124ee3cbfbe28f331 Mon Sep 17 00:00:00 2001
From: Felix Ableitner <me@nutomic.com>
Date: Thu, 11 Mar 2021 17:50:47 +0100
Subject: [PATCH] Add check so only author or mods can edit posts/comments

---
 crates/apub/src/inbox/community_inbox.rs      |  3 ++-
 .../apub/src/inbox/receive_for_community.rs   | 26 ++++++++++++++++++-
 crates/apub/src/inbox/user_inbox.rs           |  9 ++++++-
 docker/federation/docker-compose.yml          |  2 +-
 4 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/crates/apub/src/inbox/community_inbox.rs b/crates/apub/src/inbox/community_inbox.rs
index d357ee07..de44ef6f 100644
--- a/crates/apub/src/inbox/community_inbox.rs
+++ b/crates/apub/src/inbox/community_inbox.rs
@@ -148,7 +148,8 @@ pub(crate) async fn community_receive_message(
       true
     }
     CommunityValidTypes::Update => {
-      receive_update_for_community(context, any_base.clone(), &actor_url, request_counter).await?;
+      receive_update_for_community(context, any_base.clone(), None, &actor_url, request_counter)
+        .await?;
       true
     }
     CommunityValidTypes::Like => {
diff --git a/crates/apub/src/inbox/receive_for_community.rs b/crates/apub/src/inbox/receive_for_community.rs
index 4a548bc0..58b40045 100644
--- a/crates/apub/src/inbox/receive_for_community.rs
+++ b/crates/apub/src/inbox/receive_for_community.rs
@@ -112,6 +112,7 @@ pub(in crate::inbox) async fn receive_create_for_community(
 pub(in crate::inbox) async fn receive_update_for_community(
   context: &LemmyContext,
   activity: AnyBase,
+  announce: Option<Announce>,
   expected_domain: &Url,
   request_counter: &mut i32,
 ) -> Result<(), LemmyError> {
@@ -119,6 +120,28 @@ pub(in crate::inbox) async fn receive_update_for_community(
   verify_activity_domains_valid(&update, &expected_domain, true)?;
   verify_is_addressed_to_public(&update)?;
 
+  // Check that actor is the creator (or a mod)
+  let actor = update
+    .actor()?
+    .to_owned()
+    .single_xsd_any_uri()
+    .context(location_info!())?;
+  let actor = get_or_fetch_and_upsert_user(&actor, context, request_counter).await?;
+  let object_id = update
+    .object()
+    .as_one()
+    .map(|o| o.id())
+    .flatten()
+    .context(location_info!())?;
+  let original_author = match find_post_or_comment_by_id(context, object_id.to_owned()).await? {
+    PostOrComment::Post(p) => p.creator_id,
+    PostOrComment::Comment(c) => c.creator_id,
+  };
+  if actor.id != original_author {
+    let community = extract_community_from_cc(&update, context).await?;
+    verify_mod_activity(&update, announce, &community, context).await?;
+  }
+
   let kind = update
     .object()
     .as_single_kind_str()
@@ -522,7 +545,7 @@ async fn verify_mod_activity<T, Kind>(
   context: &LemmyContext,
 ) -> Result<(), LemmyError>
 where
-  T: ActorAndObjectRef + OptTargetRef + BaseExt<Kind>,
+  T: ActorAndObjectRef + BaseExt<Kind>,
 {
   // Remove was sent by community to user, we just check that it came from the right domain
   if let Some(announce) = announce {
@@ -535,6 +558,7 @@ where
 
   Ok(())
 }
+
 fn verify_add_remove_moderator_target<T, Kind>(
   activity: &T,
   community: &Community,
diff --git a/crates/apub/src/inbox/user_inbox.rs b/crates/apub/src/inbox/user_inbox.rs
index 28e1365f..571e3329 100644
--- a/crates/apub/src/inbox/user_inbox.rs
+++ b/crates/apub/src/inbox/user_inbox.rs
@@ -289,7 +289,14 @@ pub async fn receive_announce(
       receive_create_for_community(context, inner_activity, &inner_id, request_counter).await
     }
     Some(Update) => {
-      receive_update_for_community(context, inner_activity, &inner_id, request_counter).await
+      receive_update_for_community(
+        context,
+        inner_activity,
+        Some(announce),
+        &inner_id,
+        request_counter,
+      )
+      .await
     }
     Some(Like) => {
       receive_like_for_community(context, inner_activity, &inner_id, request_counter).await
diff --git a/docker/federation/docker-compose.yml b/docker/federation/docker-compose.yml
index a2ee7f26..142c4fa4 100644
--- a/docker/federation/docker-compose.yml
+++ b/docker/federation/docker-compose.yml
@@ -87,7 +87,7 @@ services:
       - ./volumes/postgres_beta:/var/lib/postgresql/data
 
   lemmy-gamma-ui:
-    image: dessalines/lemmy-ui:0.9.9
+    image: lemmy-ui:test
     environment:
       - LEMMY_INTERNAL_HOST=lemmy-gamma:8561
       - LEMMY_EXTERNAL_HOST=localhost:8561
-- 
2.44.1