convert undo like/dislike receivers

This commit is contained in:
Felix Ableitner 2021-06-29 00:10:06 +02:00
parent 5460c658a7
commit 004a07c41b
15 changed files with 264 additions and 263 deletions

View File

@ -1,4 +1,3 @@
use crate::activities::receive::get_actor_as_person;
use activitystreams::activity::{Dislike, Like};
use lemmy_api_common::{blocking, comment::CommentResponse};
use lemmy_db_queries::{source::comment::Comment_, Likeable};
@ -7,82 +6,6 @@ use lemmy_db_views::comment_view::CommentView;
use lemmy_utils::LemmyError;
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation, UserOperationCrud};
pub(crate) async fn receive_undo_like_comment(
like: &Like,
comment: Comment,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_actor_as_person(like, context, request_counter).await?;
let comment_id = comment.id;
let person_id = person.id;
blocking(context.pool(), move |conn| {
CommentLike::remove(conn, person_id, comment_id)
})
.await??;
// Refetch the view
let comment_view = blocking(context.pool(), move |conn| {
CommentView::read(conn, comment_id, None)
})
.await??;
// TODO get those recipient actor ids from somewhere
let recipient_ids = vec![];
let res = CommentResponse {
comment_view,
recipient_ids,
form_id: None,
};
context.chat_server().do_send(SendComment {
op: UserOperation::CreateCommentLike,
comment: res,
websocket_id: None,
});
Ok(())
}
pub(crate) async fn receive_undo_dislike_comment(
dislike: &Dislike,
comment: Comment,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_actor_as_person(dislike, context, request_counter).await?;
let comment_id = comment.id;
let person_id = person.id;
blocking(context.pool(), move |conn| {
CommentLike::remove(conn, person_id, comment_id)
})
.await??;
// Refetch the view
let comment_view = blocking(context.pool(), move |conn| {
CommentView::read(conn, comment_id, None)
})
.await??;
// TODO get those recipient actor ids from somewhere
let recipient_ids = vec![];
let res = CommentResponse {
comment_view,
recipient_ids,
form_id: None,
};
context.chat_server().do_send(SendComment {
op: UserOperation::CreateCommentLike,
comment: res,
websocket_id: None,
});
Ok(())
}
pub(crate) async fn receive_undo_delete_comment(
context: &LemmyContext,
comment: Comment,

View File

@ -24,20 +24,6 @@ where
Err(anyhow!("Activity not supported").into())
}
/// Reads the actor field of an activity and returns the corresponding `Person`.
pub(crate) async fn get_actor_as_person<T, A>(
activity: &T,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<Person, LemmyError>
where
T: AsBase<A> + ActorAndObjectRef,
{
let actor = activity.actor()?;
let person_uri = actor.as_single_xsd_any_uri().context(location_info!())?;
get_or_fetch_and_upsert_person(&person_uri, context, request_counter).await
}
/// Ensure that the ID of an incoming activity comes from the same domain as the actor. Optionally
/// also checks the ID of the inner object.
///

View File

@ -1,4 +1,3 @@
use crate::activities::receive::get_actor_as_person;
use activitystreams::activity::{Dislike, Like};
use lemmy_api_common::{blocking, post::PostResponse};
use lemmy_db_queries::{source::post::Post_, Likeable};
@ -7,70 +6,6 @@ use lemmy_db_views::post_view::PostView;
use lemmy_utils::LemmyError;
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation, UserOperationCrud};
pub(crate) async fn receive_undo_like_post(
like: &Like,
post: Post,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_actor_as_person(like, context, request_counter).await?;
let post_id = post.id;
let person_id = person.id;
blocking(context.pool(), move |conn| {
PostLike::remove(conn, person_id, post_id)
})
.await??;
// Refetch the view
let post_view = blocking(context.pool(), move |conn| {
PostView::read(conn, post_id, None)
})
.await??;
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
op: UserOperation::CreatePostLike,
post: res,
websocket_id: None,
});
Ok(())
}
pub(crate) async fn receive_undo_dislike_post(
dislike: &Dislike,
post: Post,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_actor_as_person(dislike, context, request_counter).await?;
let post_id = post.id;
let person_id = person.id;
blocking(context.pool(), move |conn| {
PostLike::remove(conn, person_id, post_id)
})
.await??;
// Refetch the view
let post_view = blocking(context.pool(), move |conn| {
PostView::read(conn, post_id, None)
})
.await??;
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
op: UserOperation::CreatePostLike,
post: res,
websocket_id: None,
});
Ok(())
}
pub(crate) async fn receive_undo_delete_post(
context: &LemmyContext,
post: Post,

View File

@ -11,7 +11,7 @@ use url::Url;
pub struct DislikeComment {
actor: Url,
to: PublicUrl,
object: Url,
pub(in crate::activities_new::comment) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: DislikeType,

View File

@ -11,7 +11,7 @@ use url::Url;
pub struct LikeComment {
actor: Url,
to: PublicUrl,
object: Url,
pub(in crate::activities_new::comment) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: LikeType,

View File

@ -22,6 +22,8 @@ pub mod delete;
pub mod dislike;
pub mod like;
pub mod remove;
pub mod undo_dislike;
pub mod undo_like;
pub mod update;
async fn get_notif_recipients(
@ -103,3 +105,29 @@ async fn like_or_dislike_comment(
)
.await
}
async fn undo_like_or_dislike_comment(
actor: &Url,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = 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 = person.id;
blocking(context.pool(), move |conn| {
CommentLike::remove(conn, person_id, comment_id)
})
.await??;
// TODO get those recipient actor ids from somewhere
send_websocket_message(
comment.id,
vec![],
UserOperation::CreateCommentLike,
context,
)
.await
}

View File

@ -0,0 +1,51 @@
use crate::{
activities_new::{
comment::{dislike::DislikeComment, undo_like_or_dislike_comment},
post::like::LikePost,
},
inbox::new_inbox_routing::Activity,
};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
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 {
actor: Url,
to: PublicUrl,
object: Activity<DislikeComment>,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoDislikeComment> {
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.inner.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoDislikeComment> {
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_comment(
&self.inner.actor,
&self.inner.object.inner.object,
context,
request_counter,
)
.await
}
}

View File

@ -0,0 +1,51 @@
use crate::{
activities_new::{
comment::{like::LikeComment, undo_like_or_dislike_comment},
post::like::LikePost,
},
inbox::new_inbox_routing::Activity,
};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UndoLikeComment {
actor: Url,
to: PublicUrl,
object: Activity<LikeComment>,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoLikeComment> {
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.inner.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoLikeComment> {
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_comment(
&self.inner.actor,
&self.inner.object.inner.object,
context,
request_counter,
)
.await
}
}

View File

@ -11,7 +11,7 @@ use url::Url;
pub struct DislikePost {
actor: Url,
to: PublicUrl,
object: Url,
pub(in crate::activities_new::post) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: DislikeType,

View File

@ -11,7 +11,7 @@ use url::Url;
pub struct LikePost {
actor: Url,
to: PublicUrl,
object: Url,
pub(in crate::activities_new::post) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: LikeType,

View File

@ -18,6 +18,8 @@ pub mod delete;
pub mod dislike;
pub mod like;
pub mod remove;
pub mod undo_dislike;
pub mod undo_like;
pub mod update;
async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::OperationType + 'static>(
@ -66,3 +68,21 @@ async fn like_or_dislike_post(
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 person = 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 = person.id;
blocking(context.pool(), move |conn| {
PostLike::remove(conn, person_id, post_id)
})
.await??;
send_websocket_message(post.id, UserOperation::CreatePostLike, context).await
}

View File

@ -0,0 +1,48 @@
use crate::{
activities_new::post::{dislike::DislikePost, undo_like_or_dislike_post},
inbox::new_inbox_routing::Activity,
};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UndoDislikePost {
actor: Url,
to: PublicUrl,
object: Activity<DislikePost>,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoDislikePost> {
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.inner.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoDislikePost> {
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_post(
&self.inner.actor,
&self.inner.object.inner.object,
context,
request_counter,
)
.await
}
}

View File

@ -0,0 +1,48 @@
use crate::{
activities_new::post::{like::LikePost, undo_like_or_dislike_post},
inbox::new_inbox_routing::Activity,
};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
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 {
actor: Url,
to: PublicUrl,
object: Activity<LikePost>,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoLikePost> {
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.inner.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoLikePost> {
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_post(
&self.inner.actor,
&self.inner.object.inner.object,
context,
request_counter,
)
.await
}
}

View File

@ -5,6 +5,8 @@ use crate::activities_new::{
dislike::DislikeComment,
like::LikeComment,
remove::RemoveComment,
undo_dislike::UndoDislikeComment,
undo_like::UndoLikeComment,
update::UpdateComment,
},
community::{
@ -21,6 +23,8 @@ use crate::activities_new::{
dislike::DislikePost,
like::LikePost,
remove::RemovePost,
undo_dislike::UndoDislikePost,
undo_like::UndoLikePost,
update::UpdatePost,
},
private_message::{
@ -74,6 +78,8 @@ pub enum PersonAcceptedActivitiesNew {
UpdateComment(UpdateComment),
LikeComment(LikeComment),
DislikeComment(DislikeComment),
UndoLikeComment(UndoLikeComment),
UndoDislikeComment(UndoDislikeComment),
DeleteComment(DeleteComment),
RemoveComment(RemoveComment),
CreatePost(CreatePost),
@ -82,6 +88,8 @@ pub enum PersonAcceptedActivitiesNew {
DislikePost(DislikePost),
DeletePost(DeletePost),
RemovePost(RemovePost),
UndoLikePost(UndoLikePost),
UndoDislikePost(UndoDislikePost),
UpdateCommunity(UpdateCommunity),
DeleteCommunity(DeleteCommunity),
RemoveCommunity(RemoveCommunity),

View File

@ -1,47 +1,22 @@
use crate::{
activities::receive::{
comment_undo::{
receive_undo_delete_comment,
receive_undo_dislike_comment,
receive_undo_like_comment,
receive_undo_remove_comment,
},
post_undo::{
receive_undo_delete_post,
receive_undo_dislike_post,
receive_undo_like_post,
receive_undo_remove_post,
},
comment_undo::{receive_undo_delete_comment, receive_undo_remove_comment},
post_undo::{receive_undo_delete_post, receive_undo_remove_post},
receive_unhandled_activity,
verify_activity_domains_valid,
},
inbox::verify_is_addressed_to_public,
};
use activitystreams::{
activity::{
ActorAndObjectRef,
Add,
Announce,
Block,
Delete,
Dislike,
Like,
OptTargetRef,
Remove,
Undo,
},
activity::{ActorAndObjectRef, Add, Announce, Block, Delete, OptTargetRef, Remove, Undo},
base::AnyBase,
object::AsObject,
prelude::*,
};
use anyhow::{anyhow, Context};
use diesel::result::Error::NotFound;
use lemmy_api_common::blocking;
use lemmy_apub::{
fetcher::{
objects::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
person::get_or_fetch_and_upsert_person,
},
fetcher::person::get_or_fetch_and_upsert_person,
find_object_by_id,
find_post_or_comment_by_id,
generate_moderators_url,
@ -166,12 +141,8 @@ pub(in crate::inbox) async fn receive_undo_for_community(
Some(Remove) => {
receive_undo_remove_for_community(context, undo, announce, expected_domain).await
}
Some(Like) => {
receive_undo_like_for_community(context, undo, expected_domain, request_counter).await
}
Some(Dislike) => {
receive_undo_dislike_for_community(context, undo, expected_domain, request_counter).await
}
Some(Like) => todo!(),
Some(Dislike) => todo!(),
Some(Block) => {
receive_undo_block_user_for_community(
context,
@ -243,32 +214,6 @@ pub(in crate::inbox) async fn receive_undo_remove_for_community(
}
}
/// A post or comment upvote being reverted
pub(in crate::inbox) async fn receive_undo_like_for_community(
context: &LemmyContext,
undo: Undo,
expected_domain: &Url,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let like = Like::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?;
verify_activity_domains_valid(&like, &expected_domain, false)?;
verify_is_addressed_to_public(&like)?;
let object_id = like
.object()
.as_single_xsd_any_uri()
.context(location_info!())?;
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
PostOrComment::Post(post) => {
receive_undo_like_post(&like, *post, context, request_counter).await
}
PostOrComment::Comment(comment) => {
receive_undo_like_comment(&like, *comment, context, request_counter).await
}
}
}
/// Add a new mod to the community (can only be done by an existing mod).
pub(in crate::inbox) async fn receive_add_for_community(
context: &LemmyContext,
@ -319,32 +264,6 @@ pub(in crate::inbox) async fn receive_add_for_community(
Ok(())
}
/// A post or comment downvote being reverted
pub(in crate::inbox) async fn receive_undo_dislike_for_community(
context: &LemmyContext,
undo: Undo,
expected_domain: &Url,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let dislike = Dislike::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?;
verify_activity_domains_valid(&dislike, &expected_domain, false)?;
verify_is_addressed_to_public(&dislike)?;
let object_id = dislike
.object()
.as_single_xsd_any_uri()
.context(location_info!())?;
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
PostOrComment::Post(post) => {
receive_undo_dislike_post(&dislike, *post, context, request_counter).await
}
PostOrComment::Comment(comment) => {
receive_undo_dislike_comment(&dislike, *comment, context, request_counter).await
}
}
}
pub(crate) async fn receive_block_user_for_community(
context: &LemmyContext,
block_any_base: AnyBase,
@ -424,22 +343,6 @@ pub(crate) async fn receive_undo_block_user_for_community(
Ok(())
}
async fn fetch_post_or_comment_by_id(
apub_id: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<PostOrComment, LemmyError> {
if let Ok(post) = get_or_fetch_and_insert_post(apub_id, context, request_counter).await {
return Ok(PostOrComment::Post(Box::new(post)));
}
if let Ok(comment) = get_or_fetch_and_insert_comment(apub_id, context, request_counter).await {
return Ok(PostOrComment::Comment(Box::new(comment)));
}
Err(NotFound.into())
}
/// Searches the activity's cc field for a Community ID, and returns the community.
async fn extract_community_from_cc<T, Kind>(
activity: &T,