mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-26 06:11:26 +00:00
fix post/comment create/update, rework voting
This commit is contained in:
parent
ddf480d6e2
commit
99f55a4627
31 changed files with 462 additions and 523 deletions
|
@ -1,4 +1,10 @@
|
||||||
use crate::{fetcher::fetch::fetch_remote_object, objects::FromApub, NoteExt, PageExt};
|
use crate::{
|
||||||
|
fetcher::fetch::fetch_remote_object,
|
||||||
|
objects::FromApub,
|
||||||
|
NoteExt,
|
||||||
|
PageExt,
|
||||||
|
PostOrComment,
|
||||||
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
|
@ -89,3 +95,19 @@ pub async fn get_or_fetch_and_insert_comment(
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_or_fetch_and_insert_post_or_comment(
|
||||||
|
ap_id: &Url,
|
||||||
|
context: &LemmyContext,
|
||||||
|
recursion_counter: &mut i32,
|
||||||
|
) -> Result<PostOrComment, LemmyError> {
|
||||||
|
Ok(
|
||||||
|
match get_or_fetch_and_insert_post(ap_id, context, recursion_counter).await {
|
||||||
|
Ok(p) => PostOrComment::Post(Box::new(p)),
|
||||||
|
Err(_) => {
|
||||||
|
let c = get_or_fetch_and_insert_comment(ap_id, context, recursion_counter).await?;
|
||||||
|
PostOrComment::Comment(Box::new(c))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -123,17 +123,7 @@ impl FromApub for Comment {
|
||||||
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
check_object_for_community_or_site_ban(note, post.community_id, context, request_counter)
|
check_object_for_community_or_site_ban(note, post.community_id, context, request_counter)
|
||||||
.await?;
|
.await?;
|
||||||
if post.locked {
|
Ok(comment)
|
||||||
// This is not very efficient because a comment gets inserted just to be deleted right
|
|
||||||
// afterwards, but it seems to be the easiest way to implement it.
|
|
||||||
blocking(context.pool(), move |conn| {
|
|
||||||
Comment::delete(conn, comment.id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
Err(anyhow!("Post is locked").into())
|
|
||||||
} else {
|
|
||||||
Ok(comment)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +164,9 @@ impl FromApubToForm<NoteExt> for CommentForm {
|
||||||
request_counter,
|
request_counter,
|
||||||
))
|
))
|
||||||
.await?;
|
.await?;
|
||||||
|
if post.locked {
|
||||||
|
return Err(anyhow!("Post is locked").into());
|
||||||
|
}
|
||||||
|
|
||||||
// The 2nd item, if it exists, is the parent comment apub_id
|
// The 2nd item, if it exists, is the parent comment apub_id
|
||||||
// For deeply nested comments, FromApub automatically gets called recursively
|
// For deeply nested comments, FromApub automatically gets called recursively
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
use crate::activities::comment::{get_notif_recipients, send_websocket_message};
|
use crate::activities::{
|
||||||
|
comment::{get_notif_recipients, send_websocket_message},
|
||||||
|
verify_activity,
|
||||||
|
verify_person_in_community,
|
||||||
|
};
|
||||||
use activitystreams::{activity::kind::CreateType, base::BaseExt};
|
use activitystreams::{activity::kind::CreateType, base::BaseExt};
|
||||||
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
|
use lemmy_apub::{objects::FromApub, NoteExt};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
use lemmy_apub_lib::{
|
||||||
|
verify_domains_match_opt,
|
||||||
|
ActivityCommonFields,
|
||||||
|
ActivityHandlerNew,
|
||||||
|
PublicUrl,
|
||||||
|
};
|
||||||
use lemmy_db_schema::source::comment::Comment;
|
use lemmy_db_schema::source::comment::Comment;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
||||||
|
@ -21,10 +30,21 @@ pub struct CreateComment {
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandlerNew for CreateComment {
|
impl ActivityHandlerNew for CreateComment {
|
||||||
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
&self,
|
||||||
self.object.id(self.common.actor.as_str())?;
|
context: &LemmyContext,
|
||||||
check_is_apub_id_valid(&self.common.actor, false)
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
dbg!("1");
|
||||||
|
verify_activity(self.common())?;
|
||||||
|
dbg!("2");
|
||||||
|
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
|
||||||
|
dbg!("3");
|
||||||
|
verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?;
|
||||||
|
dbg!("4");
|
||||||
|
// TODO: should add a check that the correct community is in cc (probably needs changes to
|
||||||
|
// comment deserialization)
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
@ -32,6 +52,7 @@ impl ActivityHandlerNew for CreateComment {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
|
dbg!("5");
|
||||||
let comment = Comment::from_apub(
|
let comment = Comment::from_apub(
|
||||||
&self.object,
|
&self.object,
|
||||||
context,
|
context,
|
||||||
|
@ -40,6 +61,7 @@ impl ActivityHandlerNew for CreateComment {
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
dbg!("6");
|
||||||
let recipients =
|
let recipients =
|
||||||
get_notif_recipients(&self.common.actor, &comment, context, request_counter).await?;
|
get_notif_recipients(&self.common.actor, &comment, context, request_counter).await?;
|
||||||
send_websocket_message(
|
send_websocket_message(
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
use crate::activities::comment::like_or_dislike_comment;
|
|
||||||
use activitystreams::activity::kind::LikeType;
|
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
|
||||||
use lemmy_websocket::LemmyContext;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct LikeComment {
|
|
||||||
to: PublicUrl,
|
|
||||||
pub(in crate::activities::comment) object: Url,
|
|
||||||
cc: [Url; 1],
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
kind: LikeType,
|
|
||||||
#[serde(flatten)]
|
|
||||||
common: ActivityCommonFields,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
|
||||||
impl ActivityHandlerNew for LikeComment {
|
|
||||||
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
|
||||||
check_is_apub_id_valid(&self.common.actor, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn receive(
|
|
||||||
&self,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
like_or_dislike_comment(
|
|
||||||
1,
|
|
||||||
&self.common.actor,
|
|
||||||
&self.object,
|
|
||||||
context,
|
|
||||||
request_counter,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
fn common(&self) -> &ActivityCommonFields {
|
|
||||||
&self.common
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +1,20 @@
|
||||||
use lemmy_api_common::{blocking, comment::CommentResponse, send_local_notifs};
|
use lemmy_api_common::{blocking, comment::CommentResponse, send_local_notifs};
|
||||||
use lemmy_apub::fetcher::{
|
use lemmy_apub::fetcher::person::get_or_fetch_and_upsert_person;
|
||||||
objects::get_or_fetch_and_insert_comment,
|
use lemmy_db_queries::Crud;
|
||||||
person::get_or_fetch_and_upsert_person,
|
|
||||||
};
|
|
||||||
use lemmy_db_queries::{Crud, Likeable};
|
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{comment::Comment, post::Post},
|
||||||
comment::{Comment, CommentLike, CommentLikeForm},
|
|
||||||
post::Post,
|
|
||||||
},
|
|
||||||
CommentId,
|
CommentId,
|
||||||
LocalUserId,
|
LocalUserId,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::comment_view::CommentView;
|
use lemmy_db_views::comment_view::CommentView;
|
||||||
use lemmy_utils::{utils::scrape_text_for_mentions, LemmyError};
|
use lemmy_utils::{utils::scrape_text_for_mentions, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendComment, LemmyContext};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub mod create;
|
pub mod create;
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
pub mod dislike;
|
|
||||||
pub mod like;
|
|
||||||
pub mod remove;
|
pub mod remove;
|
||||||
pub mod undo_delete;
|
pub mod undo_delete;
|
||||||
pub mod undo_dislike;
|
|
||||||
pub mod undo_like;
|
|
||||||
pub mod undo_remove;
|
pub mod undo_remove;
|
||||||
pub mod update;
|
pub mod update;
|
||||||
|
|
||||||
|
@ -49,7 +39,9 @@ async fn get_notif_recipients(
|
||||||
|
|
||||||
// TODO: in many call sites we are setting an empty vec for recipient_ids, we should get the actual
|
// TODO: in many call sites we are setting an empty vec for recipient_ids, we should get the actual
|
||||||
// recipient actors from somewhere
|
// recipient actors from somewhere
|
||||||
async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::OperationType + 'static>(
|
pub(crate) async fn send_websocket_message<
|
||||||
|
OP: ToString + Send + lemmy_websocket::OperationType + 'static,
|
||||||
|
>(
|
||||||
comment_id: CommentId,
|
comment_id: CommentId,
|
||||||
recipient_ids: Vec<LocalUserId>,
|
recipient_ids: Vec<LocalUserId>,
|
||||||
op: OP,
|
op: OP,
|
||||||
|
@ -75,61 +67,3 @@ async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::Operation
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn like_or_dislike_comment(
|
|
||||||
score: i16,
|
|
||||||
actor: &Url,
|
|
||||||
object: &Url,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
|
||||||
let comment = get_or_fetch_and_insert_comment(object, context, request_counter).await?;
|
|
||||||
|
|
||||||
let comment_id = comment.id;
|
|
||||||
let like_form = CommentLikeForm {
|
|
||||||
comment_id,
|
|
||||||
post_id: comment.post_id,
|
|
||||||
person_id: actor.id,
|
|
||||||
score,
|
|
||||||
};
|
|
||||||
let person_id = actor.id;
|
|
||||||
blocking(context.pool(), move |conn| {
|
|
||||||
CommentLike::remove(conn, person_id, comment_id)?;
|
|
||||||
CommentLike::like(conn, &like_form)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
|
|
||||||
send_websocket_message(
|
|
||||||
comment_id,
|
|
||||||
vec![],
|
|
||||||
UserOperation::CreateCommentLike,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn undo_like_or_dislike_comment(
|
|
||||||
actor: &Url,
|
|
||||||
object: &Url,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
|
||||||
let comment = get_or_fetch_and_insert_comment(object, context, request_counter).await?;
|
|
||||||
|
|
||||||
let comment_id = comment.id;
|
|
||||||
let person_id = actor.id;
|
|
||||||
blocking(context.pool(), move |conn| {
|
|
||||||
CommentLike::remove(conn, person_id, comment_id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
|
|
||||||
send_websocket_message(
|
|
||||||
comment.id,
|
|
||||||
vec![],
|
|
||||||
UserOperation::CreateCommentLike,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl ActivityHandlerNew for RemoveComment {
|
||||||
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
check_is_apub_id_valid(&self.common.actor, false)?;
|
||||||
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await
|
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
use crate::activities::comment::{dislike::DislikeComment, undo_like_or_dislike_comment};
|
|
||||||
use activitystreams::activity::kind::UndoType;
|
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
|
||||||
use lemmy_websocket::LemmyContext;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UndoDislikeComment {
|
|
||||||
to: PublicUrl,
|
|
||||||
object: DislikeComment,
|
|
||||||
cc: [Url; 1],
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
kind: UndoType,
|
|
||||||
#[serde(flatten)]
|
|
||||||
common: ActivityCommonFields,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
|
||||||
impl ActivityHandlerNew for UndoDislikeComment {
|
|
||||||
async fn verify(
|
|
||||||
&self,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
|
||||||
verify_domains_match(&self.common.actor, &self.object.object)?;
|
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
|
||||||
self.object.verify(context, request_counter).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn receive(
|
|
||||||
&self,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
undo_like_or_dislike_comment(
|
|
||||||
&self.common.actor,
|
|
||||||
&self.object.object,
|
|
||||||
context,
|
|
||||||
request_counter,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
fn common(&self) -> &ActivityCommonFields {
|
|
||||||
&self.common
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -33,7 +33,7 @@ impl ActivityHandlerNew for UndoRemoveComment {
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
check_is_apub_id_valid(&self.common.actor, false)?;
|
||||||
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
|
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
|
||||||
self.object.verify(context, request_counter).await
|
self.object.verify(context, request_counter).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
use crate::activities::comment::{get_notif_recipients, send_websocket_message};
|
use crate::activities::{
|
||||||
|
comment::{get_notif_recipients, send_websocket_message},
|
||||||
|
verify_activity,
|
||||||
|
verify_person_in_community,
|
||||||
|
};
|
||||||
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
|
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
|
||||||
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
|
use lemmy_apub::{objects::FromApub, NoteExt};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
use lemmy_apub_lib::{
|
||||||
|
verify_domains_match_opt,
|
||||||
|
ActivityCommonFields,
|
||||||
|
ActivityHandlerNew,
|
||||||
|
PublicUrl,
|
||||||
|
};
|
||||||
use lemmy_db_schema::source::comment::Comment;
|
use lemmy_db_schema::source::comment::Comment;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
||||||
|
@ -21,10 +30,15 @@ pub struct UpdateComment {
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandlerNew for UpdateComment {
|
impl ActivityHandlerNew for UpdateComment {
|
||||||
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
&self,
|
||||||
self.object.id(self.common.actor.as_str())?;
|
context: &LemmyContext,
|
||||||
check_is_apub_id_valid(&self.common.actor, false)
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
verify_activity(self.common())?;
|
||||||
|
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
|
||||||
|
verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
|
|
@ -32,7 +32,7 @@ impl ActivityHandlerNew for AddMod {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
||||||
verify_domains_match(&self.target, &self.cc[0])?;
|
verify_domains_match(&self.target, &self.cc[0])?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
check_is_apub_id_valid(&self.common.actor, false)?;
|
||||||
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
|
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
|
||||||
verify_add_remove_moderator_target(&self.target, self.cc[0].clone())
|
verify_add_remove_moderator_target(&self.target, self.cc[0].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
|
use activitystreams::activity::kind::AnnounceType;
|
||||||
|
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
||||||
|
use lemmy_utils::LemmyError;
|
||||||
|
use lemmy_websocket::LemmyContext;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
activities::{
|
activities::{
|
||||||
comment::{
|
comment::{
|
||||||
create::CreateComment,
|
create::CreateComment,
|
||||||
delete::DeleteComment,
|
delete::DeleteComment,
|
||||||
dislike::DislikeComment,
|
|
||||||
like::LikeComment,
|
|
||||||
remove::RemoveComment,
|
remove::RemoveComment,
|
||||||
undo_delete::UndoDeleteComment,
|
undo_delete::UndoDeleteComment,
|
||||||
undo_dislike::UndoDislikeComment,
|
|
||||||
undo_like::UndoLikeComment,
|
|
||||||
undo_remove::UndoRemoveComment,
|
undo_remove::UndoRemoveComment,
|
||||||
update::UpdateComment,
|
update::UpdateComment,
|
||||||
},
|
},
|
||||||
|
@ -16,48 +19,42 @@ use crate::{
|
||||||
post::{
|
post::{
|
||||||
create::CreatePost,
|
create::CreatePost,
|
||||||
delete::DeletePost,
|
delete::DeletePost,
|
||||||
dislike::DislikePost,
|
|
||||||
like::LikePost,
|
|
||||||
remove::RemovePost,
|
remove::RemovePost,
|
||||||
undo_delete::UndoDeletePost,
|
undo_delete::UndoDeletePost,
|
||||||
undo_dislike::UndoDislikePost,
|
|
||||||
undo_like::UndoLikePost,
|
|
||||||
undo_remove::UndoRemovePost,
|
undo_remove::UndoRemovePost,
|
||||||
update::UpdatePost,
|
update::UpdatePost,
|
||||||
},
|
},
|
||||||
|
post_or_comment::{
|
||||||
|
dislike::DislikePostOrComment,
|
||||||
|
like::LikePostOrComment,
|
||||||
|
undo_dislike::UndoDislikePostOrComment,
|
||||||
|
undo_like::UndoLikePostOrComment,
|
||||||
|
},
|
||||||
|
verify_activity,
|
||||||
|
verify_community,
|
||||||
},
|
},
|
||||||
http::is_activity_already_known,
|
http::is_activity_already_known,
|
||||||
};
|
};
|
||||||
use activitystreams::activity::kind::RemoveType;
|
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
|
||||||
use lemmy_websocket::LemmyContext;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
|
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
|
||||||
|
#[serde(untagged)]
|
||||||
pub enum AnnouncableActivities {
|
pub enum AnnouncableActivities {
|
||||||
CreateComment(CreateComment),
|
CreateComment(CreateComment),
|
||||||
UpdateComment(UpdateComment),
|
UpdateComment(UpdateComment),
|
||||||
LikeComment(LikeComment),
|
|
||||||
DislikeComment(DislikeComment),
|
|
||||||
UndoLikeComment(UndoLikeComment),
|
|
||||||
UndoDislikeComment(UndoDislikeComment),
|
|
||||||
DeleteComment(DeleteComment),
|
DeleteComment(DeleteComment),
|
||||||
UndoDeleteComment(UndoDeleteComment),
|
UndoDeleteComment(UndoDeleteComment),
|
||||||
RemoveComment(RemoveComment),
|
RemoveComment(RemoveComment),
|
||||||
UndoRemoveComment(UndoRemoveComment),
|
UndoRemoveComment(UndoRemoveComment),
|
||||||
CreatePost(CreatePost),
|
CreatePost(CreatePost),
|
||||||
UpdatePost(UpdatePost),
|
UpdatePost(UpdatePost),
|
||||||
LikePost(LikePost),
|
|
||||||
DislikePost(DislikePost),
|
|
||||||
DeletePost(DeletePost),
|
DeletePost(DeletePost),
|
||||||
UndoDeletePost(UndoDeletePost),
|
UndoDeletePost(UndoDeletePost),
|
||||||
RemovePost(RemovePost),
|
RemovePost(RemovePost),
|
||||||
UndoRemovePost(UndoRemovePost),
|
UndoRemovePost(UndoRemovePost),
|
||||||
UndoLikePost(UndoLikePost),
|
LikePostOrComment(LikePostOrComment),
|
||||||
UndoDislikePost(UndoDislikePost),
|
DislikePostOrComment(DislikePostOrComment),
|
||||||
|
UndoLikePostOrComment(UndoLikePostOrComment),
|
||||||
|
UndoDislikePostOrComment(UndoDislikePostOrComment),
|
||||||
BlockUserFromCommunity(BlockUserFromCommunity),
|
BlockUserFromCommunity(BlockUserFromCommunity),
|
||||||
UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
|
UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
|
||||||
}
|
}
|
||||||
|
@ -69,7 +66,7 @@ pub struct AnnounceActivity {
|
||||||
object: AnnouncableActivities,
|
object: AnnouncableActivities,
|
||||||
cc: [Url; 1],
|
cc: [Url; 1],
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
kind: RemoveType,
|
kind: AnnounceType,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
common: ActivityCommonFields,
|
common: ActivityCommonFields,
|
||||||
}
|
}
|
||||||
|
@ -81,10 +78,9 @@ impl ActivityHandlerNew for AnnounceActivity {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_activity(self.common())?;
|
||||||
verify_domains_match(&self.common.actor, &self.cc[0])?;
|
verify_community(&self.common.actor, context, request_counter).await?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
Ok(())
|
||||||
self.object.verify(context, request_counter).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
|
|
@ -34,7 +34,7 @@ impl ActivityHandlerNew for BlockUserFromCommunity {
|
||||||
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
check_is_apub_id_valid(&self.common.actor, false)?;
|
||||||
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await
|
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
|
|
@ -32,7 +32,7 @@ impl ActivityHandlerNew for RemoveMod {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
||||||
verify_domains_match(&self.target, &self.cc[0])?;
|
verify_domains_match(&self.target, &self.cc[0])?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
check_is_apub_id_valid(&self.common.actor, false)?;
|
||||||
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
|
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
|
||||||
verify_add_remove_moderator_target(&self.target, self.cc[0].clone())
|
verify_add_remove_moderator_target(&self.target, self.cc[0].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl ActivityHandlerNew for UndoBlockUserFromCommunity {
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
check_is_apub_id_valid(&self.common.actor, false)?;
|
||||||
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
|
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
|
||||||
self.object.verify(context, request_counter).await
|
self.object.verify(context, request_counter).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub::{
|
use lemmy_apub::{
|
||||||
|
check_community_or_site_ban,
|
||||||
check_is_apub_id_valid,
|
check_is_apub_id_valid,
|
||||||
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
|
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
|
||||||
};
|
};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields};
|
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields};
|
||||||
use lemmy_db_queries::ApubObject;
|
use lemmy_db_queries::ApubObject;
|
||||||
use lemmy_db_schema::source::{community::Community, person::Person};
|
use lemmy_db_schema::{
|
||||||
|
source::{community::Community, person::Person},
|
||||||
|
DbUrl,
|
||||||
|
};
|
||||||
use lemmy_db_views_actor::community_view::CommunityView;
|
use lemmy_db_views_actor::community_view::CommunityView;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
@ -16,6 +20,7 @@ pub mod comment;
|
||||||
pub mod community;
|
pub mod community;
|
||||||
pub mod following;
|
pub mod following;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
|
pub mod post_or_comment;
|
||||||
pub mod private_message;
|
pub mod private_message;
|
||||||
|
|
||||||
/// Checks that the specified Url actually identifies a Person (by fetching it), and that the person
|
/// Checks that the specified Url actually identifies a Person (by fetching it), and that the person
|
||||||
|
@ -32,6 +37,29 @@ async fn verify_person(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetches the person and community to verify their type, then checks if person is banned from site
|
||||||
|
/// or community.
|
||||||
|
async fn verify_person_in_community(
|
||||||
|
person_id: &Url,
|
||||||
|
cc: &[Url],
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<Community, LemmyError> {
|
||||||
|
let person = get_or_fetch_and_upsert_person(person_id, context, request_counter).await?;
|
||||||
|
let mut cc_iter = cc.iter();
|
||||||
|
let community: Community = loop {
|
||||||
|
if let Some(cid) = cc_iter.next() {
|
||||||
|
if let Ok(c) = get_or_fetch_and_upsert_community(cid, context, request_counter).await {
|
||||||
|
break c;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("No community found in cc").into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
check_community_or_site_ban(&person, community.id, context.pool()).await?;
|
||||||
|
Ok(community)
|
||||||
|
}
|
||||||
|
|
||||||
/// Simply check that the url actually refers to a valid group.
|
/// Simply check that the url actually refers to a valid group.
|
||||||
async fn verify_community(
|
async fn verify_community(
|
||||||
community_id: &Url,
|
community_id: &Url,
|
||||||
|
@ -49,7 +77,7 @@ fn verify_activity(common: &ActivityCommonFields) -> Result<(), LemmyError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn verify_mod_action(
|
async fn verify_mod_action(
|
||||||
actor_id: Url,
|
actor_id: &Url,
|
||||||
activity_cc: Url,
|
activity_cc: Url,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
|
@ -59,8 +87,9 @@ async fn verify_mod_action(
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
if community.local {
|
if community.local {
|
||||||
|
let actor_id: DbUrl = actor_id.clone().into();
|
||||||
let actor = blocking(context.pool(), move |conn| {
|
let actor = blocking(context.pool(), move |conn| {
|
||||||
Person::read_from_apub_id(conn, &actor_id.into())
|
Person::read_from_apub_id(conn, &actor_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,21 @@
|
||||||
use crate::activities::post::send_websocket_message;
|
use crate::activities::{
|
||||||
|
post::send_websocket_message,
|
||||||
|
verify_activity,
|
||||||
|
verify_person_in_community,
|
||||||
|
};
|
||||||
use activitystreams::{activity::kind::CreateType, base::BaseExt};
|
use activitystreams::{activity::kind::CreateType, base::BaseExt};
|
||||||
use lemmy_apub::{
|
use lemmy_apub::{
|
||||||
check_is_apub_id_valid,
|
|
||||||
fetcher::person::get_or_fetch_and_upsert_person,
|
fetcher::person::get_or_fetch_and_upsert_person,
|
||||||
objects::FromApub,
|
objects::FromApub,
|
||||||
ActorType,
|
ActorType,
|
||||||
PageExt,
|
PageExt,
|
||||||
};
|
};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
use lemmy_apub_lib::{
|
||||||
|
verify_domains_match_opt,
|
||||||
|
ActivityCommonFields,
|
||||||
|
ActivityHandlerNew,
|
||||||
|
PublicUrl,
|
||||||
|
};
|
||||||
use lemmy_db_schema::source::post::Post;
|
use lemmy_db_schema::source::post::Post;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
||||||
|
@ -27,10 +35,15 @@ pub struct CreatePost {
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandlerNew for CreatePost {
|
impl ActivityHandlerNew for CreatePost {
|
||||||
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(
|
||||||
verify_domains_match(self.common.id_unchecked(), &self.common.actor)?;
|
&self,
|
||||||
self.object.id(self.common.actor.as_str())?;
|
context: &LemmyContext,
|
||||||
check_is_apub_id_valid(&self.common.actor, false)
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
verify_activity(self.common())?;
|
||||||
|
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
|
||||||
|
verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
use crate::activities::post::like_or_dislike_post;
|
|
||||||
use activitystreams::activity::kind::DislikeType;
|
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
|
||||||
use lemmy_websocket::LemmyContext;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct DislikePost {
|
|
||||||
to: PublicUrl,
|
|
||||||
pub(in crate::activities::post) object: Url,
|
|
||||||
cc: [Url; 1],
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
kind: DislikeType,
|
|
||||||
#[serde(flatten)]
|
|
||||||
common: ActivityCommonFields,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
|
||||||
impl ActivityHandlerNew for DislikePost {
|
|
||||||
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
|
||||||
check_is_apub_id_valid(&self.common.actor, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn receive(
|
|
||||||
&self,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
like_or_dislike_post(
|
|
||||||
-1,
|
|
||||||
&self.common.actor,
|
|
||||||
&self.object,
|
|
||||||
context,
|
|
||||||
request_counter,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
fn common(&self) -> &ActivityCommonFields {
|
|
||||||
&self.common
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +1,19 @@
|
||||||
use lemmy_api_common::{blocking, post::PostResponse};
|
use lemmy_api_common::{blocking, post::PostResponse};
|
||||||
use lemmy_apub::fetcher::{
|
use lemmy_db_schema::PostId;
|
||||||
objects::get_or_fetch_and_insert_post,
|
|
||||||
person::get_or_fetch_and_upsert_person,
|
|
||||||
};
|
|
||||||
use lemmy_db_queries::Likeable;
|
|
||||||
use lemmy_db_schema::{
|
|
||||||
source::post::{PostLike, PostLikeForm},
|
|
||||||
PostId,
|
|
||||||
};
|
|
||||||
use lemmy_db_views::post_view::PostView;
|
use lemmy_db_views::post_view::PostView;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendPost, LemmyContext};
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
pub mod create;
|
pub mod create;
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
pub mod dislike;
|
|
||||||
pub mod like;
|
|
||||||
pub mod remove;
|
pub mod remove;
|
||||||
pub mod undo_delete;
|
pub mod undo_delete;
|
||||||
pub mod undo_dislike;
|
|
||||||
pub mod undo_like;
|
|
||||||
pub mod undo_remove;
|
pub mod undo_remove;
|
||||||
pub mod update;
|
pub mod update;
|
||||||
|
|
||||||
async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::OperationType + 'static>(
|
pub(crate) async fn send_websocket_message<
|
||||||
|
OP: ToString + Send + lemmy_websocket::OperationType + 'static,
|
||||||
|
>(
|
||||||
post_id: PostId,
|
post_id: PostId,
|
||||||
op: OP,
|
op: OP,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
|
@ -44,47 +33,3 @@ async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::Operation
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn like_or_dislike_post(
|
|
||||||
score: i16,
|
|
||||||
actor: &Url,
|
|
||||||
object: &Url,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
|
||||||
let post = get_or_fetch_and_insert_post(object, context, request_counter).await?;
|
|
||||||
|
|
||||||
let post_id = post.id;
|
|
||||||
let like_form = PostLikeForm {
|
|
||||||
post_id: post.id,
|
|
||||||
person_id: actor.id,
|
|
||||||
score,
|
|
||||||
};
|
|
||||||
let person_id = actor.id;
|
|
||||||
blocking(context.pool(), move |conn| {
|
|
||||||
PostLike::remove(conn, person_id, post_id)?;
|
|
||||||
PostLike::like(conn, &like_form)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
|
|
||||||
send_websocket_message(post.id, UserOperation::CreatePostLike, context).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn undo_like_or_dislike_post(
|
|
||||||
actor: &Url,
|
|
||||||
object: &Url,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
|
||||||
let post = get_or_fetch_and_insert_post(object, context, request_counter).await?;
|
|
||||||
|
|
||||||
let post_id = post.id;
|
|
||||||
let person_id = actor.id;
|
|
||||||
blocking(context.pool(), move |conn| {
|
|
||||||
PostLike::remove(conn, person_id, post_id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
send_websocket_message(post.id, UserOperation::CreatePostLike, context).await
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl ActivityHandlerNew for RemovePost {
|
||||||
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
check_is_apub_id_valid(&self.common.actor, false)?;
|
||||||
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await
|
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
use crate::activities::post::{like::LikePost, undo_like_or_dislike_post};
|
|
||||||
use activitystreams::activity::kind::UndoType;
|
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
|
||||||
use lemmy_websocket::LemmyContext;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UndoLikePost {
|
|
||||||
to: PublicUrl,
|
|
||||||
object: LikePost,
|
|
||||||
cc: [Url; 1],
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
kind: UndoType,
|
|
||||||
#[serde(flatten)]
|
|
||||||
common: ActivityCommonFields,
|
|
||||||
}
|
|
||||||
#[async_trait::async_trait(?Send)]
|
|
||||||
impl ActivityHandlerNew for UndoLikePost {
|
|
||||||
async fn verify(
|
|
||||||
&self,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
|
||||||
verify_domains_match(&self.common.actor, &self.object.object)?;
|
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
|
||||||
self.object.verify(context, request_counter).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn receive(
|
|
||||||
&self,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
undo_like_or_dislike_post(
|
|
||||||
&self.common.actor,
|
|
||||||
&self.object.object,
|
|
||||||
context,
|
|
||||||
request_counter,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
fn common(&self) -> &ActivityCommonFields {
|
|
||||||
&self.common
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -33,7 +33,7 @@ impl ActivityHandlerNew for UndoRemovePost {
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
check_is_apub_id_valid(&self.common.actor, false)?;
|
||||||
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
|
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
|
||||||
self.object.verify(context, request_counter).await
|
self.object.verify(context, request_counter).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,26 @@
|
||||||
use crate::activities::post::send_websocket_message;
|
use crate::activities::{
|
||||||
|
post::send_websocket_message,
|
||||||
|
verify_activity,
|
||||||
|
verify_mod_action,
|
||||||
|
verify_person_in_community,
|
||||||
|
};
|
||||||
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
|
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub::{
|
use lemmy_apub::{
|
||||||
check_is_apub_id_valid,
|
|
||||||
objects::{FromApub, FromApubToForm},
|
objects::{FromApub, FromApubToForm},
|
||||||
|
ActorType,
|
||||||
PageExt,
|
PageExt,
|
||||||
};
|
};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
use lemmy_apub_lib::{
|
||||||
use lemmy_db_queries::{ApubObject, Crud};
|
verify_domains_match_opt,
|
||||||
|
ActivityCommonFields,
|
||||||
|
ActivityHandlerNew,
|
||||||
|
PublicUrl,
|
||||||
|
};
|
||||||
|
use lemmy_db_queries::ApubObject;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::post::{Post, PostForm},
|
||||||
community::Community,
|
|
||||||
post::{Post, PostForm},
|
|
||||||
},
|
|
||||||
DbUrl,
|
DbUrl,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
|
@ -34,17 +41,16 @@ pub struct UpdatePost {
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandlerNew for UpdatePost {
|
impl ActivityHandlerNew for UpdatePost {
|
||||||
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
|
||||||
self.object.id(self.common.actor.as_str())?;
|
|
||||||
check_is_apub_id_valid(&self.common.actor, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn receive(
|
|
||||||
&self,
|
&self,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
|
verify_activity(self.common())?;
|
||||||
|
let community =
|
||||||
|
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
|
||||||
|
verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?;
|
||||||
|
|
||||||
let temp_post = PostForm::from_apub(
|
let temp_post = PostForm::from_apub(
|
||||||
&self.object,
|
&self.object,
|
||||||
context,
|
context,
|
||||||
|
@ -53,36 +59,32 @@ impl ActivityHandlerNew for UpdatePost {
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let post_id: DbUrl = temp_post.ap_id.context(location_info!())?;
|
let post_id: DbUrl = temp_post.ap_id.context(location_info!())?;
|
||||||
let old_post = blocking(context.pool(), move |conn| {
|
let old_post = blocking(context.pool(), move |conn| {
|
||||||
Post::read_from_apub_id(conn, &post_id)
|
Post::read_from_apub_id(conn, &post_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// If sticked or locked state was changed, make sure the actor is a mod
|
|
||||||
let stickied = temp_post.stickied.context(location_info!())?;
|
let stickied = temp_post.stickied.context(location_info!())?;
|
||||||
let locked = temp_post.locked.context(location_info!())?;
|
let locked = temp_post.locked.context(location_info!())?;
|
||||||
let mut mod_action_allowed = false;
|
|
||||||
if (stickied != old_post.stickied) || (locked != old_post.locked) {
|
if (stickied != old_post.stickied) || (locked != old_post.locked) {
|
||||||
let community = blocking(context.pool(), move |conn| {
|
verify_mod_action(&self.common.actor, community.actor_id(), context).await?;
|
||||||
Community::read(conn, old_post.community_id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
// Only check mod status if the community is local, otherwise we trust that it was sent correctly.
|
|
||||||
if community.local {
|
|
||||||
// TODO
|
|
||||||
//verify_mod_activity(&update, announce, &community, context).await?;
|
|
||||||
}
|
|
||||||
mod_action_allowed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn receive(
|
||||||
|
&self,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
let post = Post::from_apub(
|
let post = Post::from_apub(
|
||||||
&self.object,
|
&self.object,
|
||||||
context,
|
context,
|
||||||
self.common.actor.clone(),
|
self.common.actor.clone(),
|
||||||
request_counter,
|
request_counter,
|
||||||
mod_action_allowed,
|
// TODO: we already check here if the mod action is valid, can remove that check param
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
use crate::activities::comment::like_or_dislike_comment;
|
use crate::activities::{
|
||||||
|
post_or_comment::voting::receive_like_or_dislike,
|
||||||
|
verify_activity,
|
||||||
|
verify_person_in_community,
|
||||||
|
};
|
||||||
use activitystreams::activity::kind::DislikeType;
|
use activitystreams::activity::kind::DislikeType;
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct DislikeComment {
|
pub struct DislikePostOrComment {
|
||||||
to: PublicUrl,
|
to: PublicUrl,
|
||||||
pub(in crate::activities::comment) object: Url,
|
pub(in crate::activities) object: Url,
|
||||||
cc: [Url; 1],
|
cc: [Url; 1],
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
kind: DislikeType,
|
kind: DislikeType,
|
||||||
|
@ -19,10 +22,15 @@ pub struct DislikeComment {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandlerNew for DislikeComment {
|
impl ActivityHandlerNew for DislikePostOrComment {
|
||||||
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
&self,
|
||||||
check_is_apub_id_valid(&self.common.actor, false)
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
verify_activity(self.common())?;
|
||||||
|
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
@ -30,7 +38,7 @@ impl ActivityHandlerNew for DislikeComment {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
like_or_dislike_comment(
|
receive_like_or_dislike(
|
||||||
-1,
|
-1,
|
||||||
&self.common.actor,
|
&self.common.actor,
|
||||||
&self.object,
|
&self.object,
|
|
@ -1,16 +1,19 @@
|
||||||
use crate::activities::post::like_or_dislike_post;
|
use crate::activities::{
|
||||||
|
post_or_comment::voting::receive_like_or_dislike,
|
||||||
|
verify_activity,
|
||||||
|
verify_person_in_community,
|
||||||
|
};
|
||||||
use activitystreams::activity::kind::LikeType;
|
use activitystreams::activity::kind::LikeType;
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct LikePost {
|
pub struct LikePostOrComment {
|
||||||
to: PublicUrl,
|
to: PublicUrl,
|
||||||
pub(in crate::activities::post) object: Url,
|
pub(in crate::activities::post_or_comment) object: Url,
|
||||||
cc: [Url; 1],
|
cc: [Url; 1],
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
kind: LikeType,
|
kind: LikeType,
|
||||||
|
@ -19,10 +22,15 @@ pub struct LikePost {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandlerNew for LikePost {
|
impl ActivityHandlerNew for LikePostOrComment {
|
||||||
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
|
async fn verify(
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
&self,
|
||||||
check_is_apub_id_valid(&self.common.actor, false)
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
verify_activity(self.common())?;
|
||||||
|
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
@ -30,7 +38,7 @@ impl ActivityHandlerNew for LikePost {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
like_or_dislike_post(
|
receive_like_or_dislike(
|
||||||
1,
|
1,
|
||||||
&self.common.actor,
|
&self.common.actor,
|
||||||
&self.object,
|
&self.object,
|
|
@ -0,0 +1,5 @@
|
||||||
|
pub mod dislike;
|
||||||
|
pub mod like;
|
||||||
|
pub mod undo_dislike;
|
||||||
|
pub mod undo_like;
|
||||||
|
mod voting;
|
|
@ -1,16 +1,19 @@
|
||||||
use crate::activities::post::{dislike::DislikePost, undo_like_or_dislike_post};
|
use crate::activities::{
|
||||||
|
post_or_comment::{dislike::DislikePostOrComment, voting::receive_undo_like_or_dislike},
|
||||||
|
verify_activity,
|
||||||
|
verify_person_in_community,
|
||||||
|
};
|
||||||
use activitystreams::activity::kind::UndoType;
|
use activitystreams::activity::kind::UndoType;
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UndoDislikePost {
|
pub struct UndoDislikePostOrComment {
|
||||||
to: PublicUrl,
|
to: PublicUrl,
|
||||||
object: DislikePost,
|
object: DislikePostOrComment,
|
||||||
cc: [Url; 1],
|
cc: [Url; 1],
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
kind: UndoType,
|
kind: UndoType,
|
||||||
|
@ -19,16 +22,17 @@ pub struct UndoDislikePost {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandlerNew for UndoDislikePost {
|
impl ActivityHandlerNew for UndoDislikePostOrComment {
|
||||||
async fn verify(
|
async fn verify(
|
||||||
&self,
|
&self,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_activity(self.common())?;
|
||||||
verify_domains_match(&self.common.actor, &self.object.object)?;
|
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
verify_urls_match(&self.common.actor, &self.object.common().actor)?;
|
||||||
self.object.verify(context, request_counter).await
|
self.object.verify(context, request_counter).await?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
@ -36,7 +40,7 @@ impl ActivityHandlerNew for UndoDislikePost {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
undo_like_or_dislike_post(
|
receive_undo_like_or_dislike(
|
||||||
&self.common.actor,
|
&self.common.actor,
|
||||||
&self.object.object,
|
&self.object.object,
|
||||||
context,
|
context,
|
|
@ -1,16 +1,19 @@
|
||||||
use crate::activities::comment::{like::LikeComment, undo_like_or_dislike_comment};
|
use crate::activities::{
|
||||||
|
post_or_comment::{like::LikePostOrComment, voting::receive_undo_like_or_dislike},
|
||||||
|
verify_activity,
|
||||||
|
verify_person_in_community,
|
||||||
|
};
|
||||||
use activitystreams::activity::kind::UndoType;
|
use activitystreams::activity::kind::UndoType;
|
||||||
use lemmy_apub::check_is_apub_id_valid;
|
use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
||||||
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UndoLikeComment {
|
pub struct UndoLikePostOrComment {
|
||||||
to: PublicUrl,
|
to: PublicUrl,
|
||||||
object: LikeComment,
|
object: LikePostOrComment,
|
||||||
cc: [Url; 1],
|
cc: [Url; 1],
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
kind: UndoType,
|
kind: UndoType,
|
||||||
|
@ -19,16 +22,17 @@ pub struct UndoLikeComment {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandlerNew for UndoLikeComment {
|
impl ActivityHandlerNew for UndoLikePostOrComment {
|
||||||
async fn verify(
|
async fn verify(
|
||||||
&self,
|
&self,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
|
verify_activity(self.common())?;
|
||||||
verify_domains_match(&self.common.actor, &self.object.object)?;
|
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
|
||||||
check_is_apub_id_valid(&self.common.actor, false)?;
|
verify_urls_match(&self.common.actor, &self.object.common().actor)?;
|
||||||
self.object.verify(context, request_counter).await
|
self.object.verify(context, request_counter).await?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive(
|
async fn receive(
|
||||||
|
@ -36,7 +40,7 @@ impl ActivityHandlerNew for UndoLikeComment {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
undo_like_or_dislike_comment(
|
receive_undo_like_or_dislike(
|
||||||
&self.common.actor,
|
&self.common.actor,
|
||||||
&self.object.object,
|
&self.object.object,
|
||||||
context,
|
context,
|
152
crates/apub_receive/src/activities/post_or_comment/voting.rs
Normal file
152
crates/apub_receive/src/activities/post_or_comment/voting.rs
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
use crate::activities::{
|
||||||
|
comment::send_websocket_message as send_comment_websocket_message,
|
||||||
|
post::send_websocket_message as send_post_websocket_message,
|
||||||
|
};
|
||||||
|
use lemmy_api_common::blocking;
|
||||||
|
use lemmy_apub::{
|
||||||
|
fetcher::{
|
||||||
|
objects::get_or_fetch_and_insert_post_or_comment,
|
||||||
|
person::get_or_fetch_and_upsert_person,
|
||||||
|
},
|
||||||
|
PostOrComment,
|
||||||
|
};
|
||||||
|
use lemmy_db_queries::Likeable;
|
||||||
|
use lemmy_db_schema::source::{
|
||||||
|
comment::{Comment, CommentLike, CommentLikeForm},
|
||||||
|
post::{Post, PostLike, PostLikeForm},
|
||||||
|
};
|
||||||
|
use lemmy_utils::LemmyError;
|
||||||
|
use lemmy_websocket::{LemmyContext, UserOperation};
|
||||||
|
use std::ops::Deref;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub(in crate::activities::post_or_comment) async fn receive_like_or_dislike(
|
||||||
|
score: i16,
|
||||||
|
actor: &Url,
|
||||||
|
object: &Url,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
match get_or_fetch_and_insert_post_or_comment(object, context, request_counter).await? {
|
||||||
|
PostOrComment::Post(p) => {
|
||||||
|
like_or_dislike_post(score, actor, p.deref(), context, request_counter).await
|
||||||
|
}
|
||||||
|
PostOrComment::Comment(c) => {
|
||||||
|
like_or_dislike_comment(score, actor, c.deref(), context, request_counter).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn like_or_dislike_comment(
|
||||||
|
score: i16,
|
||||||
|
actor: &Url,
|
||||||
|
comment: &Comment,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
||||||
|
|
||||||
|
let comment_id = comment.id;
|
||||||
|
let like_form = CommentLikeForm {
|
||||||
|
comment_id,
|
||||||
|
post_id: comment.post_id,
|
||||||
|
person_id: actor.id,
|
||||||
|
score,
|
||||||
|
};
|
||||||
|
let person_id = actor.id;
|
||||||
|
blocking(context.pool(), move |conn| {
|
||||||
|
CommentLike::remove(conn, person_id, comment_id)?;
|
||||||
|
CommentLike::like(conn, &like_form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
send_comment_websocket_message(
|
||||||
|
comment_id,
|
||||||
|
vec![],
|
||||||
|
UserOperation::CreateCommentLike,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn like_or_dislike_post(
|
||||||
|
score: i16,
|
||||||
|
actor: &Url,
|
||||||
|
post: &Post,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
||||||
|
|
||||||
|
let post_id = post.id;
|
||||||
|
let like_form = PostLikeForm {
|
||||||
|
post_id: post.id,
|
||||||
|
person_id: actor.id,
|
||||||
|
score,
|
||||||
|
};
|
||||||
|
let person_id = actor.id;
|
||||||
|
blocking(context.pool(), move |conn| {
|
||||||
|
PostLike::remove(conn, person_id, post_id)?;
|
||||||
|
PostLike::like(conn, &like_form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
send_post_websocket_message(post.id, UserOperation::CreatePostLike, context).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in crate::activities::post_or_comment) async fn receive_undo_like_or_dislike(
|
||||||
|
actor: &Url,
|
||||||
|
object: &Url,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
match get_or_fetch_and_insert_post_or_comment(object, context, request_counter).await? {
|
||||||
|
PostOrComment::Post(p) => {
|
||||||
|
undo_like_or_dislike_post(actor, p.deref(), context, request_counter).await
|
||||||
|
}
|
||||||
|
PostOrComment::Comment(c) => {
|
||||||
|
undo_like_or_dislike_comment(actor, c.deref(), context, request_counter).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn undo_like_or_dislike_comment(
|
||||||
|
actor: &Url,
|
||||||
|
comment: &Comment,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
||||||
|
|
||||||
|
let comment_id = comment.id;
|
||||||
|
let person_id = actor.id;
|
||||||
|
blocking(context.pool(), move |conn| {
|
||||||
|
CommentLike::remove(conn, person_id, comment_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
send_comment_websocket_message(
|
||||||
|
comment.id,
|
||||||
|
vec![],
|
||||||
|
UserOperation::CreateCommentLike,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn undo_like_or_dislike_post(
|
||||||
|
actor: &Url,
|
||||||
|
post: &Post,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
||||||
|
|
||||||
|
let post_id = post.id;
|
||||||
|
let person_id = actor.id;
|
||||||
|
blocking(context.pool(), move |conn| {
|
||||||
|
PostLike::remove(conn, person_id, post_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
send_post_websocket_message(post.id, UserOperation::CreatePostLike, context).await
|
||||||
|
}
|
|
@ -2,12 +2,8 @@ use crate::activities::{
|
||||||
comment::{
|
comment::{
|
||||||
create::CreateComment,
|
create::CreateComment,
|
||||||
delete::DeleteComment,
|
delete::DeleteComment,
|
||||||
dislike::DislikeComment,
|
|
||||||
like::LikeComment,
|
|
||||||
remove::RemoveComment,
|
remove::RemoveComment,
|
||||||
undo_delete::UndoDeleteComment,
|
undo_delete::UndoDeleteComment,
|
||||||
undo_dislike::UndoDislikeComment,
|
|
||||||
undo_like::UndoLikeComment,
|
|
||||||
undo_remove::UndoRemoveComment,
|
undo_remove::UndoRemoveComment,
|
||||||
update::UpdateComment,
|
update::UpdateComment,
|
||||||
},
|
},
|
||||||
|
@ -27,15 +23,17 @@ use crate::activities::{
|
||||||
post::{
|
post::{
|
||||||
create::CreatePost,
|
create::CreatePost,
|
||||||
delete::DeletePost,
|
delete::DeletePost,
|
||||||
dislike::DislikePost,
|
|
||||||
like::LikePost,
|
|
||||||
remove::RemovePost,
|
remove::RemovePost,
|
||||||
undo_delete::UndoDeletePost,
|
undo_delete::UndoDeletePost,
|
||||||
undo_dislike::UndoDislikePost,
|
|
||||||
undo_like::UndoLikePost,
|
|
||||||
undo_remove::UndoRemovePost,
|
undo_remove::UndoRemovePost,
|
||||||
update::UpdatePost,
|
update::UpdatePost,
|
||||||
},
|
},
|
||||||
|
post_or_comment::{
|
||||||
|
dislike::DislikePostOrComment,
|
||||||
|
like::LikePostOrComment,
|
||||||
|
undo_dislike::UndoDislikePostOrComment,
|
||||||
|
undo_like::UndoLikePostOrComment,
|
||||||
|
},
|
||||||
private_message::{
|
private_message::{
|
||||||
create::CreatePrivateMessage,
|
create::CreatePrivateMessage,
|
||||||
delete::DeletePrivateMessage,
|
delete::DeletePrivateMessage,
|
||||||
|
@ -66,24 +64,20 @@ pub enum GroupInboxActivities {
|
||||||
UndoFollowCommunity(UndoFollowCommunity),
|
UndoFollowCommunity(UndoFollowCommunity),
|
||||||
CreateComment(CreateComment),
|
CreateComment(CreateComment),
|
||||||
UpdateComment(UpdateComment),
|
UpdateComment(UpdateComment),
|
||||||
LikeComment(LikeComment),
|
|
||||||
DislikeComment(DislikeComment),
|
|
||||||
UndoLikeComment(UndoLikeComment),
|
|
||||||
UndoDislikeComment(UndoDislikeComment),
|
|
||||||
DeleteComment(DeleteComment),
|
DeleteComment(DeleteComment),
|
||||||
UndoDeleteComment(UndoDeleteComment),
|
UndoDeleteComment(UndoDeleteComment),
|
||||||
RemoveComment(RemoveComment),
|
RemoveComment(RemoveComment),
|
||||||
UndoRemoveComment(UndoRemoveComment),
|
UndoRemoveComment(UndoRemoveComment),
|
||||||
CreatePost(CreatePost),
|
CreatePost(CreatePost),
|
||||||
UpdatePost(UpdatePost),
|
UpdatePost(UpdatePost),
|
||||||
LikePost(LikePost),
|
|
||||||
DislikePost(DislikePost),
|
|
||||||
DeletePost(DeletePost),
|
DeletePost(DeletePost),
|
||||||
UndoDeletePost(UndoDeletePost),
|
UndoDeletePost(UndoDeletePost),
|
||||||
RemovePost(RemovePost),
|
RemovePost(RemovePost),
|
||||||
UndoRemovePost(UndoRemovePost),
|
UndoRemovePost(UndoRemovePost),
|
||||||
UndoLikePost(UndoLikePost),
|
LikePostOrComment(LikePostOrComment),
|
||||||
UndoDislikePost(UndoDislikePost),
|
DislikePostOrComment(DislikePostOrComment),
|
||||||
|
UndoLikePostOrComment(UndoLikePostOrComment),
|
||||||
|
UndoDislikePostOrComment(UndoDislikePostOrComment),
|
||||||
UpdateCommunity(Box<UpdateCommunity>),
|
UpdateCommunity(Box<UpdateCommunity>),
|
||||||
DeleteCommunity(DeleteCommunity),
|
DeleteCommunity(DeleteCommunity),
|
||||||
RemoveCommunity(RemoveCommunity),
|
RemoveCommunity(RemoveCommunity),
|
||||||
|
@ -98,36 +92,25 @@ pub enum GroupInboxActivities {
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
|
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum SharedInboxActivities {
|
pub enum SharedInboxActivities {
|
||||||
// received by person
|
|
||||||
AcceptFollowCommunity(AcceptFollowCommunity),
|
|
||||||
CreatePrivateMessage(CreatePrivateMessage),
|
|
||||||
UpdatePrivateMessage(UpdatePrivateMessage),
|
|
||||||
DeletePrivateMessage(DeletePrivateMessage),
|
|
||||||
UndoDeletePrivateMessage(UndoDeletePrivateMessage),
|
|
||||||
AnnounceActivity(Box<AnnounceActivity>),
|
|
||||||
// received by group
|
// received by group
|
||||||
FollowCommunity(FollowCommunity),
|
FollowCommunity(FollowCommunity),
|
||||||
UndoFollowCommunity(UndoFollowCommunity),
|
UndoFollowCommunity(UndoFollowCommunity),
|
||||||
CreateComment(CreateComment),
|
CreateComment(CreateComment),
|
||||||
UpdateComment(UpdateComment),
|
UpdateComment(UpdateComment),
|
||||||
LikeComment(LikeComment),
|
|
||||||
DislikeComment(DislikeComment),
|
|
||||||
UndoLikeComment(UndoLikeComment),
|
|
||||||
UndoDislikeComment(UndoDislikeComment),
|
|
||||||
DeleteComment(DeleteComment),
|
DeleteComment(DeleteComment),
|
||||||
UndoDeleteComment(UndoDeleteComment),
|
UndoDeleteComment(UndoDeleteComment),
|
||||||
RemoveComment(RemoveComment),
|
RemoveComment(RemoveComment),
|
||||||
UndoRemoveComment(UndoRemoveComment),
|
UndoRemoveComment(UndoRemoveComment),
|
||||||
CreatePost(CreatePost),
|
CreatePost(CreatePost),
|
||||||
UpdatePost(UpdatePost),
|
UpdatePost(UpdatePost),
|
||||||
LikePost(LikePost),
|
|
||||||
DislikePost(DislikePost),
|
|
||||||
DeletePost(DeletePost),
|
DeletePost(DeletePost),
|
||||||
UndoDeletePost(UndoDeletePost),
|
UndoDeletePost(UndoDeletePost),
|
||||||
RemovePost(RemovePost),
|
RemovePost(RemovePost),
|
||||||
UndoRemovePost(UndoRemovePost),
|
UndoRemovePost(UndoRemovePost),
|
||||||
UndoLikePost(UndoLikePost),
|
LikePostOrComment(LikePostOrComment),
|
||||||
UndoDislikePost(UndoDislikePost),
|
DislikePostOrComment(DislikePostOrComment),
|
||||||
|
UndoDislikePostOrComment(UndoDislikePostOrComment),
|
||||||
|
UndoLikePostOrComment(UndoLikePostOrComment),
|
||||||
UpdateCommunity(Box<UpdateCommunity>),
|
UpdateCommunity(Box<UpdateCommunity>),
|
||||||
DeleteCommunity(DeleteCommunity),
|
DeleteCommunity(DeleteCommunity),
|
||||||
RemoveCommunity(RemoveCommunity),
|
RemoveCommunity(RemoveCommunity),
|
||||||
|
@ -137,4 +120,13 @@ pub enum SharedInboxActivities {
|
||||||
UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
|
UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
|
||||||
AddMod(AddMod),
|
AddMod(AddMod),
|
||||||
RemoveMod(RemoveMod),
|
RemoveMod(RemoveMod),
|
||||||
|
// received by person
|
||||||
|
AcceptFollowCommunity(AcceptFollowCommunity),
|
||||||
|
// Note, pm activities need to be at the end, otherwise comments will end up here. We can probably
|
||||||
|
// avoid this problem by replacing createpm.object with our own struct, instead of NoteExt.
|
||||||
|
CreatePrivateMessage(CreatePrivateMessage),
|
||||||
|
UpdatePrivateMessage(UpdatePrivateMessage),
|
||||||
|
DeletePrivateMessage(DeletePrivateMessage),
|
||||||
|
UndoDeletePrivateMessage(UndoDeletePrivateMessage),
|
||||||
|
AnnounceActivity(Box<AnnounceActivity>),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::activities::{
|
use crate::http::inbox_enums::SharedInboxActivities;
|
||||||
following::accept::AcceptFollowCommunity,
|
|
||||||
post::{create::CreatePost, like::LikePost},
|
|
||||||
};
|
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
body::Body,
|
body::Body,
|
||||||
web,
|
web,
|
||||||
|
@ -20,12 +17,11 @@ use lemmy_apub::{
|
||||||
insert_activity,
|
insert_activity,
|
||||||
APUB_JSON_CONTENT_TYPE,
|
APUB_JSON_CONTENT_TYPE,
|
||||||
};
|
};
|
||||||
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew};
|
use lemmy_apub_lib::ActivityHandlerNew;
|
||||||
use lemmy_db_queries::{source::activity::Activity_, DbPool};
|
use lemmy_db_queries::{source::activity::Activity_, DbPool};
|
||||||
use lemmy_db_schema::source::activity::Activity;
|
use lemmy_db_schema::source::activity::Activity;
|
||||||
use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
|
use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use log::debug;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fmt::Debug, io::Read};
|
use std::{fmt::Debug, io::Read};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -36,21 +32,13 @@ pub mod inbox_enums;
|
||||||
pub mod person;
|
pub mod person;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ActivityHandlerNew)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
enum Ac {
|
|
||||||
CreatePost(CreatePost),
|
|
||||||
LikePost(LikePost),
|
|
||||||
AcceptFollowCommunity(AcceptFollowCommunity),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn shared_inbox(
|
pub async fn shared_inbox(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
context: web::Data<LemmyContext>,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let unparsed = payload_to_string(payload).await?;
|
let unparsed = payload_to_string(payload).await?;
|
||||||
receive_activity::<Ac>(request, &unparsed, context).await
|
receive_activity::<SharedInboxActivities>(request, &unparsed, context).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn payload_to_string(mut payload: Payload) -> Result<String, LemmyError> {
|
async fn payload_to_string(mut payload: Payload) -> Result<String, LemmyError> {
|
||||||
|
@ -70,22 +58,23 @@ async fn receive_activity<'a, T>(
|
||||||
where
|
where
|
||||||
T: ActivityHandlerNew + Clone + Deserialize<'a> + Serialize + std::fmt::Debug + Send + 'static,
|
T: ActivityHandlerNew + Clone + Deserialize<'a> + Serialize + std::fmt::Debug + Send + 'static,
|
||||||
{
|
{
|
||||||
debug!("Received activity {}", activity);
|
let activity = serde_json::from_str::<T>(activity);
|
||||||
let activity = serde_json::from_str::<T>(activity)?;
|
dbg!(&activity);
|
||||||
|
let activity = activity?;
|
||||||
let activity_data = activity.common();
|
let activity_data = activity.common();
|
||||||
// TODO: which order to check things?
|
// TODO: which order to check things?
|
||||||
// Do nothing if we received the same activity before
|
// Do nothing if we received the same activity before
|
||||||
if is_activity_already_known(context.pool(), activity_data.id_unchecked()).await? {
|
if is_activity_already_known(context.pool(), activity_data.id_unchecked()).await? {
|
||||||
return Ok(HttpResponse::Ok().finish());
|
return Ok(HttpResponse::Ok().finish());
|
||||||
}
|
}
|
||||||
assert_activity_not_local(&activity)?;
|
|
||||||
check_is_apub_id_valid(&activity_data.actor, false)?;
|
|
||||||
|
|
||||||
let request_counter = &mut 0;
|
let request_counter = &mut 0;
|
||||||
let actor =
|
let actor =
|
||||||
get_or_fetch_and_upsert_actor(&activity_data.actor, &context, request_counter).await?;
|
get_or_fetch_and_upsert_actor(&activity_data.actor, &context, request_counter).await?;
|
||||||
verify_signature(&request, &actor.public_key().context(location_info!())?)?;
|
verify_signature(&request, &actor.public_key().context(location_info!())?)?;
|
||||||
activity.verify(&context, request_counter).await?;
|
activity.verify(&context, request_counter).await?;
|
||||||
|
assert_activity_not_local(&activity)?;
|
||||||
|
check_is_apub_id_valid(&activity_data.actor, false)?;
|
||||||
|
|
||||||
// Log the activity, so we avoid receiving and parsing it twice. Note that this could still happen
|
// Log the activity, so we avoid receiving and parsing it twice. Note that this could still happen
|
||||||
// if we receive the same activity twice in very quick succession.
|
// if we receive the same activity twice in very quick succession.
|
||||||
|
|
|
@ -8,8 +8,8 @@ for ((i=0; i < times; i++)) ; do
|
||||||
echo "cargo clean"
|
echo "cargo clean"
|
||||||
# to benchmark incremental compilation time, do a full build with the same compiler version first,
|
# to benchmark incremental compilation time, do a full build with the same compiler version first,
|
||||||
# and use the following clean command:
|
# and use the following clean command:
|
||||||
#cargo clean -p lemmy_utils
|
cargo clean -p lemmy_utils
|
||||||
cargo clean
|
#cargo clean
|
||||||
echo "cargo build"
|
echo "cargo build"
|
||||||
start=$(date +%s.%N)
|
start=$(date +%s.%N)
|
||||||
RUSTC_WRAPPER='' cargo build -q
|
RUSTC_WRAPPER='' cargo build -q
|
||||||
|
|
Loading…
Reference in a new issue