]> Untitled Git - lemmy.git/commitdiff
Merge logic for post create and update
authorFelix Ableitner <me@nutomic.com>
Sat, 31 Jul 2021 17:26:17 +0000 (19:26 +0200)
committerFelix Ableitner <me@nutomic.com>
Sat, 31 Jul 2021 17:26:17 +0000 (19:26 +0200)
12 files changed:
crates/api/src/post.rs
crates/api_crud/src/comment/create.rs
crates/api_crud/src/comment/update.rs
crates/api_crud/src/post/create.rs
crates/api_crud/src/post/update.rs
crates/apub/src/activities/comment/create_or_update.rs
crates/apub/src/activities/community/announce.rs
crates/apub/src/activities/mod.rs
crates/apub/src/activities/post/create_or_update.rs [moved from crates/apub/src/activities/post/create.rs with 51% similarity]
crates/apub/src/activities/post/mod.rs
crates/apub/src/activities/post/update.rs [deleted file]
crates/apub/src/http/inbox_enums.rs

index 84e0c849e0dde837f92e2af6af732a6167a61081..a3392f550ab1c6c4295cd543b41ff8743463d41e 100644 (file)
@@ -9,7 +9,10 @@ use lemmy_api_common::{
   mark_post_as_read,
   post::*,
 };
-use lemmy_apub::{activities::post::update::UpdatePost, ApubLikeableType};
+use lemmy_apub::{
+  activities::{post::create_or_update::CreateOrUpdatePost, CreateOrUpdateType},
+  ApubLikeableType,
+};
 use lemmy_db_queries::{source::post::Post_, Crud, Likeable, Saveable};
 use lemmy_db_schema::source::{moderator::*, post::*};
 use lemmy_db_views::post_view::PostView;
@@ -140,7 +143,13 @@ impl Perform for LockPost {
     blocking(context.pool(), move |conn| ModLockPost::create(conn, &form)).await??;
 
     // apub updates
-    UpdatePost::send(&updated_post, &local_user_view.person, context).await?;
+    CreateOrUpdatePost::send(
+      &updated_post,
+      &local_user_view.person,
+      CreateOrUpdateType::Update,
+      context,
+    )
+    .await?;
 
     // Refetch the post
     let post_id = data.post_id;
@@ -212,7 +221,13 @@ impl Perform for StickyPost {
 
     // Apub updates
     // TODO stickied should pry work like locked for ease of use
-    UpdatePost::send(&updated_post, &local_user_view.person, context).await?;
+    CreateOrUpdatePost::send(
+      &updated_post,
+      &local_user_view.person,
+      CreateOrUpdateType::Update,
+      context,
+    )
+    .await?;
 
     // Refetch the post
     let post_id = data.post_id;
index 899555fc884030a366e673ab9785a286fe6ccdc1..1b772cd84c51a19be17dbeb6633786d320b837f2 100644 (file)
@@ -9,7 +9,7 @@ use lemmy_api_common::{
   send_local_notifs,
 };
 use lemmy_apub::{
-  activities::comment::create_or_update::{CreateOrUpdateComment, CreateOrUpdateType},
+  activities::{comment::create_or_update::CreateOrUpdateComment, CreateOrUpdateType},
   generate_apub_endpoint,
   ApubLikeableType,
   EndpointType,
index f3911faecdf4ecb48bb8cee90d4e417c2031d752..d0a0e397143c06e70f9d86f051a3f650987e9a97 100644 (file)
@@ -7,8 +7,8 @@ use lemmy_api_common::{
   get_local_user_view_from_jwt,
   send_local_notifs,
 };
-use lemmy_apub::activities::comment::create_or_update::{
-  CreateOrUpdateComment,
+use lemmy_apub::activities::{
+  comment::create_or_update::CreateOrUpdateComment,
   CreateOrUpdateType,
 };
 use lemmy_db_queries::{source::comment::Comment_, DeleteableOrRemoveable};
@@ -61,6 +61,7 @@ impl PerformCrud for EditComment {
     .await?
     .map_err(|_| ApiError::err("couldnt_update_comment"))?;
 
+    // Send the apub update
     CreateOrUpdateComment::send(
       &updated_comment,
       &local_user_view.person,
index b2034a36741aa3c40fe3ffad0192567316e62b16..813c62ce06d582dc1846f78cc86bdfcb65d32766 100644 (file)
@@ -8,7 +8,7 @@ use lemmy_api_common::{
   post::*,
 };
 use lemmy_apub::{
-  activities::post::create::CreatePost as CreateApubPost,
+  activities::{post::create_or_update::CreateOrUpdatePost, CreateOrUpdateType},
   generate_apub_endpoint,
   ApubLikeableType,
   EndpointType,
@@ -87,7 +87,13 @@ impl PerformCrud for CreatePost {
     .await?
     .map_err(|_| ApiError::err("couldnt_create_post"))?;
 
-    CreateApubPost::send(&updated_post, &local_user_view.person, context).await?;
+    CreateOrUpdatePost::send(
+      &updated_post,
+      &local_user_view.person,
+      CreateOrUpdateType::Create,
+      context,
+    )
+    .await?;
 
     // They like their own post by default
     let person_id = local_user_view.person.id;
index 6b2780376e3e81d3080aa2fef8f6b406931a599e..dade6f42bef0ac2977d5678f7b5619e934d80e15 100644 (file)
@@ -1,7 +1,7 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{blocking, check_community_ban, get_local_user_view_from_jwt, post::*};
-use lemmy_apub::activities::post::update::UpdatePost;
+use lemmy_apub::activities::{post::create_or_update::CreateOrUpdatePost, CreateOrUpdateType};
 use lemmy_db_queries::{source::post::Post_, Crud, DeleteableOrRemoveable};
 use lemmy_db_schema::{naive_now, source::post::*};
 use lemmy_db_views::post_view::PostView;
@@ -89,7 +89,13 @@ impl PerformCrud for EditPost {
     };
 
     // Send apub update
-    UpdatePost::send(&updated_post, &local_user_view.person, context).await?;
+    CreateOrUpdatePost::send(
+      &updated_post,
+      &local_user_view.person,
+      CreateOrUpdateType::Update,
+      context,
+    )
+    .await?;
 
     let post_id = data.post_id;
     let mut post_view = blocking(context.pool(), move |conn| {
index f67040987fe625a363f3e9d9b351fbf9c5a7675a..4cafafbaaf3296a7c821a50489024cd87b2faf82 100644 (file)
@@ -6,13 +6,14 @@ use crate::{
     generate_activity_id,
     verify_activity,
     verify_person_in_community,
+    CreateOrUpdateType,
   },
   activity_queue::send_to_community_new,
   extensions::context::lemmy_context,
   objects::{comment::Note, FromApub, ToApub},
   ActorType,
 };
-use activitystreams::{activity::kind::CreateType, link::Mention};
+use activitystreams::link::Mention;
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   values::PublicUrl,
@@ -27,12 +28,6 @@ use lemmy_websocket::{LemmyContext, UserOperationCrud};
 use serde::{Deserialize, Serialize};
 use url::Url;
 
-#[derive(Clone, Debug, Deserialize, Serialize)]
-pub enum CreateOrUpdateType {
-  Create,
-  Update,
-}
-
 #[derive(Clone, Debug, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct CreateOrUpdateComment {
@@ -62,10 +57,7 @@ impl CreateOrUpdateComment {
     })
     .await??;
 
-    let id = match kind {
-      CreateOrUpdateType::Create => generate_activity_id(CreateType::Create),
-      CreateOrUpdateType::Update => generate_activity_id(CreateType::Create),
-    }?;
+    let id = generate_activity_id(kind.clone())?;
     let maa = collect_non_local_mentions(comment, &community, context).await?;
 
     let create_or_update = CreateOrUpdateComment {
index 4beee5d293caaa3d6b24874fde050e2bb7cc04f9..b72cd1a5cbf1f69955547e2fe1bd1482a5b1b826 100644 (file)
@@ -12,7 +12,7 @@ use crate::{
       undo_delete::UndoDeletePostCommentOrCommunity,
     },
     generate_activity_id,
-    post::{create::CreatePost, update::UpdatePost},
+    post::create_or_update::CreateOrUpdatePost,
     removal::{
       remove::RemovePostCommentCommunityOrMod,
       undo_remove::UndoRemovePostCommentOrCommunity,
@@ -45,8 +45,7 @@ use url::Url;
 #[serde(untagged)]
 pub enum AnnouncableActivities {
   CreateOrUpdateComment(CreateOrUpdateComment),
-  CreatePost(CreatePost),
-  UpdatePost(UpdatePost),
+  CreateOrUpdatePost(Box<CreateOrUpdatePost>),
   LikePostOrComment(LikePostOrComment),
   DislikePostOrComment(DislikePostOrComment),
   UndoLikePostOrComment(UndoLikePostOrComment),
@@ -86,7 +85,7 @@ impl AnnounceActivity {
       kind: AnnounceType::Announce,
       common: ActivityCommonFields {
         context: lemmy_context(),
-        id: generate_activity_id(AnnounceType::Announce)?,
+        id: generate_activity_id(&AnnounceType::Announce)?,
         actor: community.actor_id(),
         unparsed: Default::default(),
       },
index d8eaa0e777f3ed0f721a3b2eb26583a7698858ae..f4c535ee69f9bcb359712ad8710e405856955650 100644 (file)
@@ -15,6 +15,8 @@ use lemmy_db_schema::{
 use lemmy_db_views_actor::community_view::CommunityView;
 use lemmy_utils::{settings::structs::Settings, LemmyError};
 use lemmy_websocket::LemmyContext;
+use serde::{Deserialize, Serialize};
+use strum_macros::ToString;
 use url::{ParseError, Url};
 use uuid::Uuid;
 
@@ -28,6 +30,13 @@ pub mod removal;
 pub mod send;
 pub mod voting;
 
+#[derive(Clone, Debug, ToString, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub enum CreateOrUpdateType {
+  Create,
+  Update,
+}
+
 /// Checks that the specified Url actually identifies a Person (by fetching it), and that the person
 /// doesn't have a site ban.
 async fn verify_person(
similarity index 51%
rename from crates/apub/src/activities/post/create.rs
rename to crates/apub/src/activities/post/create_or_update.rs
index 3dd8ce5540134cd8305dfed05f55fd5a8a02c813..4af720753707fe378a8b1e9ddfb4118c35ebcc36 100644 (file)
@@ -5,7 +5,9 @@ use crate::{
     generate_activity_id,
     post::send_websocket_message,
     verify_activity,
+    verify_mod_action,
     verify_person_in_community,
+    CreateOrUpdateType,
   },
   activity_queue::send_to_community_new,
   extensions::context::lemmy_context,
@@ -13,7 +15,6 @@ use crate::{
   objects::{post::Page, FromApub, ToApub},
   ActorType,
 };
-use activitystreams::activity::kind::CreateType;
 use anyhow::anyhow;
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
@@ -31,29 +32,35 @@ use url::Url;
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
 #[serde(rename_all = "camelCase")]
-pub struct CreatePost {
+pub struct CreateOrUpdatePost {
   to: PublicUrl,
   object: Page,
   cc: [Url; 1],
-  r#type: CreateType,
+  #[serde(rename = "type")]
+  kind: CreateOrUpdateType,
   #[serde(flatten)]
   common: ActivityCommonFields,
 }
 
-impl CreatePost {
-  pub async fn send(post: &Post, actor: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
+impl CreateOrUpdatePost {
+  pub async fn send(
+    post: &Post,
+    actor: &Person,
+    kind: CreateOrUpdateType,
+    context: &LemmyContext,
+  ) -> Result<(), LemmyError> {
     let community_id = post.community_id;
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, community_id)
     })
     .await??;
 
-    let id = generate_activity_id(CreateType::Create)?;
-    let create = CreatePost {
+    let id = generate_activity_id(kind.clone())?;
+    let create_or_update = CreateOrUpdatePost {
       to: PublicUrl::Public,
       object: post.to_apub(context.pool()).await?,
       cc: [community.actor_id()],
-      r#type: Default::default(),
+      kind,
       common: ActivityCommonFields {
         context: lemmy_context(),
         id: id.clone(),
@@ -62,33 +69,45 @@ impl CreatePost {
       },
     };
 
-    let activity = AnnouncableActivities::CreatePost(create);
+    let activity = AnnouncableActivities::CreateOrUpdatePost(Box::new(create_or_update));
     send_to_community_new(activity, &id, actor, &community, vec![], context).await
   }
 }
 
 #[async_trait::async_trait(?Send)]
-impl ActivityHandler for CreatePost {
+impl ActivityHandler for CreateOrUpdatePost {
   async fn verify(
     &self,
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = extract_community(&self.cc, context, request_counter).await?;
-    let community_id = &community.actor_id();
-
     verify_activity(self.common())?;
-    verify_person_in_community(&self.common.actor, community_id, context, request_counter).await?;
-    verify_domains_match(&self.common.actor, &self.object.id)?;
-    verify_urls_match(&self.common.actor, &self.object.attributed_to)?;
-    // Check that the post isnt locked or stickied, as that isnt possible for newly created posts.
-    // However, when fetching a remote post we generate a new create activity with the current
-    // locked/stickied value, so this check may fail. So only check if its a local community,
-    // because then we will definitely receive all create and update activities separately.
-    let is_stickied_or_locked =
-      self.object.stickied == Some(true) || self.object.comments_enabled == Some(false);
-    if community.local && is_stickied_or_locked {
-      return Err(anyhow!("New post cannot be stickied or locked").into());
+    let community = extract_community(&self.cc, context, request_counter).await?;
+    let community_id = community.actor_id();
+    verify_person_in_community(&self.common.actor, &community_id, context, request_counter).await?;
+    match self.kind {
+      CreateOrUpdateType::Create => {
+        verify_domains_match(&self.common.actor, &self.object.id)?;
+        verify_urls_match(&self.common.actor, &self.object.attributed_to)?;
+        // Check that the post isnt locked or stickied, as that isnt possible for newly created posts.
+        // However, when fetching a remote post we generate a new create activity with the current
+        // locked/stickied value, so this check may fail. So only check if its a local community,
+        // because then we will definitely receive all create and update activities separately.
+        let is_stickied_or_locked =
+          self.object.stickied == Some(true) || self.object.comments_enabled == Some(false);
+        if community.local && is_stickied_or_locked {
+          return Err(anyhow!("New post cannot be stickied or locked").into());
+        }
+      }
+      CreateOrUpdateType::Update => {
+        let is_mod_action = self.object.is_mod_action(context.pool()).await?;
+        if is_mod_action {
+          verify_mod_action(&self.common.actor, community_id, context).await?;
+        } else {
+          verify_domains_match(&self.common.actor, &self.object.id)?;
+          verify_urls_match(&self.common.actor, &self.object.attributed_to)?;
+        }
+      }
     }
     self.object.verify(context, request_counter).await?;
     Ok(())
@@ -110,7 +129,11 @@ impl ActivityHandler for CreatePost {
     )
     .await?;
 
-    send_websocket_message(post.id, UserOperationCrud::CreatePost, context).await
+    let notif_type = match self.kind {
+      CreateOrUpdateType::Create => UserOperationCrud::CreatePost,
+      CreateOrUpdateType::Update => UserOperationCrud::EditPost,
+    };
+    send_websocket_message(post.id, notif_type, context).await
   }
 
   fn common(&self) -> &ActivityCommonFields {
index a46620402cf992836443f308aaef8feff750b094..b60348ed0c3bc6879679bf55ee4ef1a5be097b32 100644 (file)
@@ -4,8 +4,7 @@ use lemmy_db_views::post_view::PostView;
 use lemmy_utils::LemmyError;
 use lemmy_websocket::{messages::SendPost, LemmyContext};
 
-pub mod create;
-pub mod update;
+pub mod create_or_update;
 
 pub(crate) async fn send_websocket_message<
   OP: ToString + Send + lemmy_websocket::OperationType + 'static,
diff --git a/crates/apub/src/activities/post/update.rs b/crates/apub/src/activities/post/update.rs
deleted file mode 100644 (file)
index f5cd07b..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-use crate::{
-  activities::{
-    community::announce::AnnouncableActivities,
-    generate_activity_id,
-    post::send_websocket_message,
-    verify_activity,
-    verify_mod_action,
-    verify_person_in_community,
-  },
-  activity_queue::send_to_community_new,
-  extensions::context::lemmy_context,
-  fetcher::community::get_or_fetch_and_upsert_community,
-  objects::{post::Page, FromApub, ToApub},
-  ActorType,
-};
-use activitystreams::activity::kind::UpdateType;
-use lemmy_api_common::blocking;
-use lemmy_apub_lib::{values::PublicUrl, verify_urls_match, ActivityCommonFields, ActivityHandler};
-use lemmy_db_queries::Crud;
-use lemmy_db_schema::source::{community::Community, person::Person, post::Post};
-use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
-use url::Url;
-
-#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct UpdatePost {
-  to: PublicUrl,
-  object: Page,
-  cc: [Url; 1],
-  r#type: UpdateType,
-  #[serde(flatten)]
-  common: ActivityCommonFields,
-}
-
-impl UpdatePost {
-  pub async fn send(post: &Post, actor: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
-    let community_id = post.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    let id = generate_activity_id(UpdateType::Update)?;
-    let update = UpdatePost {
-      to: PublicUrl::Public,
-      object: post.to_apub(context.pool()).await?,
-      cc: [community.actor_id()],
-      r#type: Default::default(),
-      common: ActivityCommonFields {
-        context: lemmy_context(),
-        id: id.clone(),
-        actor: actor.actor_id(),
-        unparsed: Default::default(),
-      },
-    };
-    let activity = AnnouncableActivities::UpdatePost(update);
-    send_to_community_new(activity, &id, actor, &community, vec![], context).await
-  }
-}
-
-#[async_trait::async_trait(?Send)]
-impl ActivityHandler for UpdatePost {
-  async fn verify(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    let community_id = get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter)
-      .await?
-      .actor_id();
-    let is_mod_action = self.object.is_mod_action(context.pool()).await?;
-
-    verify_activity(self.common())?;
-    verify_person_in_community(&self.common.actor, &community_id, context, request_counter).await?;
-    if is_mod_action {
-      verify_mod_action(&self.common.actor, community_id, context).await?;
-    } else {
-      verify_urls_match(&self.common.actor, &self.object.attributed_to)?;
-    }
-    self.object.verify(context, request_counter).await?;
-    Ok(())
-  }
-
-  async fn receive(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    let post = Post::from_apub(
-      &self.object,
-      context,
-      self.common.actor.clone(),
-      request_counter,
-      // TODO: we already check here if the mod action is valid, can remove that check param
-      true,
-    )
-    .await?;
-
-    send_websocket_message(post.id, UserOperationCrud::EditPost, context).await
-  }
-
-  fn common(&self) -> &ActivityCommonFields {
-    &self.common
-  }
-}
index 20b311505d44b4a9947361ec61c4a75351d2ab4e..2950799aea5ba05a87bbdde0a956ddb39848db39 100644 (file)
@@ -9,7 +9,7 @@ use crate::activities::{
   },
   deletion::{delete::DeletePostCommentOrCommunity, undo_delete::UndoDeletePostCommentOrCommunity},
   following::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity},
-  post::{create::CreatePost, update::UpdatePost},
+  post::create_or_update::CreateOrUpdatePost,
   private_message::{
     create::CreatePrivateMessage,
     delete::DeletePrivateMessage,
@@ -49,8 +49,7 @@ pub enum GroupInboxActivities {
   FollowCommunity(FollowCommunity),
   UndoFollowCommunity(UndoFollowCommunity),
   CreateOrUpdateComment(CreateOrUpdateComment),
-  CreatePost(CreatePost),
-  UpdatePost(UpdatePost),
+  CreateOrUpdatePost(Box<CreateOrUpdatePost>),
   LikePostOrComment(LikePostOrComment),
   DislikePostOrComment(DislikePostOrComment),
   UndoLikePostOrComment(UndoLikePostOrComment),
@@ -72,8 +71,7 @@ pub enum SharedInboxActivities {
   FollowCommunity(FollowCommunity),
   UndoFollowCommunity(UndoFollowCommunity),
   CreateOrUpdateComment(CreateOrUpdateComment),
-  CreatePost(CreatePost),
-  UpdatePost(UpdatePost),
+  CreateOrUpdatePost(CreateOrUpdatePost),
   LikePostOrComment(LikePostOrComment),
   DislikePostOrComment(DislikePostOrComment),
   UndoDislikePostOrComment(UndoDislikePostOrComment),