Merge pull request 'Dont include full objects with remove/delete activities' (#113) from delete-with-id into main

Reviewed-on: https://yerbamate.dev/LemmyNet/lemmy/pulls/113
This commit is contained in:
dessalines 2020-10-13 18:31:11 +00:00
commit d55e38d4a6
11 changed files with 273 additions and 618 deletions

View file

@ -1,27 +1,19 @@
use crate::{ use crate::activities::receive::{
activities::receive::{
announce_if_community_is_local, announce_if_community_is_local,
find_by_id,
get_actor_as_user, get_actor_as_user,
receive_unhandled_activity, FindResults,
},
fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
ActorType,
FromApub,
GroupExt,
PageExt,
}; };
use activitystreams::{activity::Delete, base::AnyBase, object::Note, prelude::*}; use activitystreams::{activity::Delete, base::AnyBase, prelude::*};
use actix_web::HttpResponse; use actix_web::HttpResponse;
use anyhow::Context; use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
comment::{Comment, CommentForm}, comment::Comment,
comment_view::CommentView, comment_view::CommentView,
community::{Community, CommunityForm}, community::Community,
community_view::CommunityView, community_view::CommunityView,
naive_now, post::Post,
post::{Post, PostForm},
post_view::PostView, post_view::PostView,
Crud,
}; };
use lemmy_structs::{ use lemmy_structs::{
blocking, blocking,
@ -41,108 +33,66 @@ pub async fn receive_delete(
context: &LemmyContext, context: &LemmyContext,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let delete = Delete::from_any_base(activity)?.context(location_info!())?; let delete = Delete::from_any_base(activity)?.context(location_info!())?;
match delete.object().as_single_kind_str() {
Some("Page") => receive_delete_post(delete, context).await, let object = delete
Some("Note") => receive_delete_comment(delete, context).await, .object()
Some("Group") => receive_delete_community(delete, context).await, .to_owned()
_ => receive_unhandled_activity(delete), .single_xsd_any_uri()
.context(location_info!())?;
// Ensure that delete activity comes from the same domain as the object
delete.id(object.domain().context(location_info!())?)?;
match find_by_id(context, object).await {
Ok(FindResults::Post(p)) => receive_delete_post(context, delete, p).await,
Ok(FindResults::Comment(c)) => receive_delete_comment(context, delete, c).await,
Ok(FindResults::Community(c)) => receive_delete_community(context, delete, c).await,
// if we dont have the object, no need to do anything
Err(_) => Ok(HttpResponse::Ok().finish()),
} }
} }
async fn receive_delete_post( async fn receive_delete_post(
delete: Delete,
context: &LemmyContext, context: &LemmyContext,
delete: Delete,
post: Post,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let user = get_actor_as_user(&delete, context).await?; let deleted_post = blocking(context.pool(), move |conn| {
let page = PageExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)? Post::update_deleted(conn, post.id, true)
.context(location_info!())?;
let post_ap_id = PostForm::from_apub(&page, context, Some(user.actor_id()?))
.await?
.get_ap_id()?;
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
let post_form = PostForm {
name: post.name.to_owned(),
url: post.url.to_owned(),
body: post.body.to_owned(),
creator_id: post.creator_id.to_owned(),
community_id: post.community_id,
removed: None,
deleted: Some(true),
nsfw: post.nsfw,
locked: None,
stickied: None,
updated: Some(naive_now()),
embed_title: post.embed_title,
embed_description: post.embed_description,
embed_html: post.embed_html,
thumbnail_url: post.thumbnail_url,
ap_id: Some(post.ap_id),
local: post.local,
published: None,
};
let post_id = post.id;
blocking(context.pool(), move |conn| {
Post::update(conn, post_id, &post_form)
}) })
.await??; .await??;
// Refetch the view // Refetch the view
let post_id = post.id; let post_id = deleted_post.id;
let post_view = blocking(context.pool(), move |conn| { let post_view = blocking(context.pool(), move |conn| {
PostView::read(conn, post_id, None) PostView::read(conn, post_id, None)
}) })
.await??; .await??;
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::EditPost, op: UserOperation::EditPost,
post: res, post: res,
websocket_id: None, websocket_id: None,
}); });
let user = get_actor_as_user(&delete, context).await?;
announce_if_community_is_local(delete, &user, context).await?; announce_if_community_is_local(delete, &user, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
async fn receive_delete_comment( async fn receive_delete_comment(
delete: Delete,
context: &LemmyContext, context: &LemmyContext,
delete: Delete,
comment: Comment,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let user = get_actor_as_user(&delete, context).await?; let deleted_comment = blocking(context.pool(), move |conn| {
let note = Note::from_any_base(delete.object().to_owned().one().context(location_info!())?)? Comment::update_deleted(conn, comment.id, true)
.context(location_info!())?;
let comment_ap_id = CommentForm::from_apub(&note, context, Some(user.actor_id()?))
.await?
.get_ap_id()?;
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
let comment_form = CommentForm {
content: comment.content.to_owned(),
parent_id: comment.parent_id,
post_id: comment.post_id,
creator_id: comment.creator_id,
removed: None,
deleted: Some(true),
read: None,
published: None,
updated: Some(naive_now()),
ap_id: Some(comment.ap_id),
local: comment.local,
};
let comment_id = comment.id;
blocking(context.pool(), move |conn| {
Comment::update(conn, comment_id, &comment_form)
}) })
.await??; .await??;
// Refetch the view // Refetch the view
let comment_id = comment.id; let comment_id = deleted_comment.id;
let comment_view = blocking(context.pool(), move |conn| { let comment_view = blocking(context.pool(), move |conn| {
CommentView::read(conn, comment_id, None) CommentView::read(conn, comment_id, None)
}) })
@ -155,62 +105,28 @@ async fn receive_delete_comment(
recipient_ids, recipient_ids,
form_id: None, form_id: None,
}; };
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::EditComment, op: UserOperation::EditComment,
comment: res, comment: res,
websocket_id: None, websocket_id: None,
}); });
let user = get_actor_as_user(&delete, context).await?;
announce_if_community_is_local(delete, &user, context).await?; announce_if_community_is_local(delete, &user, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
async fn receive_delete_community( async fn receive_delete_community(
delete: Delete,
context: &LemmyContext, context: &LemmyContext,
delete: Delete,
community: Community,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let group = GroupExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)? let deleted_community = blocking(context.pool(), move |conn| {
.context(location_info!())?; Community::update_deleted(conn, community.id, true)
let user = get_actor_as_user(&delete, context).await?;
let community_actor_id = CommunityForm::from_apub(&group, context, Some(user.actor_id()?))
.await?
.actor_id
.context(location_info!())?;
let community = blocking(context.pool(), move |conn| {
Community::read_from_actor_id(conn, &community_actor_id)
}) })
.await??; .await??;
let community_form = CommunityForm { let community_id = deleted_community.id;
name: community.name.to_owned(),
title: community.title.to_owned(),
description: community.description.to_owned(),
category_id: community.category_id, // Note: need to keep this due to foreign key constraint
creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint
removed: None,
published: None,
updated: Some(naive_now()),
deleted: Some(true),
nsfw: community.nsfw,
actor_id: Some(community.actor_id),
local: community.local,
private_key: community.private_key,
public_key: community.public_key,
last_refreshed_at: None,
icon: Some(community.icon.to_owned()),
banner: Some(community.banner.to_owned()),
};
let community_id = community.id;
blocking(context.pool(), move |conn| {
Community::update(conn, community_id, &community_form)
})
.await??;
let community_id = community.id;
let res = CommunityResponse { let res = CommunityResponse {
community: blocking(context.pool(), move |conn| { community: blocking(context.pool(), move |conn| {
CommunityView::read(conn, community_id, None) CommunityView::read(conn, community_id, None)
@ -219,7 +135,6 @@ async fn receive_delete_community(
}; };
let community_id = res.community.id; let community_id = res.community.id;
context.chat_server().do_send(SendCommunityRoomMessage { context.chat_server().do_send(SendCommunityRoomMessage {
op: UserOperation::EditCommunity, op: UserOperation::EditCommunity,
response: res, response: res,
@ -227,6 +142,7 @@ async fn receive_delete_community(
websocket_id: None, websocket_id: None,
}); });
let user = get_actor_as_user(&delete, context).await?;
announce_if_community_is_local(delete, &user, context).await?; announce_if_community_is_local(delete, &user, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }

View file

@ -9,7 +9,9 @@ use activitystreams::{
}; };
use actix_web::HttpResponse; use actix_web::HttpResponse;
use anyhow::Context; use anyhow::Context;
use lemmy_db::user::User_; use diesel::result::Error::NotFound;
use lemmy_db::{comment::Comment, community::Community, post::Post, user::User_};
use lemmy_structs::blocking;
use lemmy_utils::{location_info, LemmyError}; use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use log::debug; use log::debug;
@ -68,7 +70,7 @@ where
Ok(()) Ok(())
} }
pub(in crate) async fn get_actor_as_user<T, A>( pub(crate) async fn get_actor_as_user<T, A>(
activity: &T, activity: &T,
context: &LemmyContext, context: &LemmyContext,
) -> Result<User_, LemmyError> ) -> Result<User_, LemmyError>
@ -79,3 +81,43 @@ where
let user_uri = actor.as_single_xsd_any_uri().context(location_info!())?; let user_uri = actor.as_single_xsd_any_uri().context(location_info!())?;
get_or_fetch_and_upsert_user(&user_uri, context).await get_or_fetch_and_upsert_user(&user_uri, context).await
} }
pub(crate) enum FindResults {
Comment(Comment),
Community(Community),
Post(Post),
}
pub(crate) async fn find_by_id(
context: &LemmyContext,
apub_id: Url,
) -> Result<FindResults, LemmyError> {
let ap_id = apub_id.to_string();
let community = blocking(context.pool(), move |conn| {
Community::read_from_actor_id(conn, &ap_id)
})
.await?;
if let Ok(c) = community {
return Ok(FindResults::Community(c));
}
let ap_id = apub_id.to_string();
let post = blocking(context.pool(), move |conn| {
Post::read_from_apub_id(conn, &ap_id)
})
.await?;
if let Ok(p) = post {
return Ok(FindResults::Post(p));
}
let ap_id = apub_id.to_string();
let comment = blocking(context.pool(), move |conn| {
Comment::read_from_apub_id(conn, &ap_id)
})
.await?;
if let Ok(c) = comment {
return Ok(FindResults::Comment(c));
}
return Err(NotFound.into());
}

View file

@ -1,27 +1,17 @@
use crate::{ use crate::{
activities::receive::{ activities::receive::{find_by_id, get_actor_as_user, FindResults},
announce_if_community_is_local,
get_actor_as_user,
receive_unhandled_activity,
},
fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
ActorType, ActorType,
FromApub,
GroupExt,
PageExt,
}; };
use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*}; use activitystreams::{activity::Remove, base::AnyBase, error::DomainError, prelude::*};
use actix_web::HttpResponse; use actix_web::HttpResponse;
use anyhow::{anyhow, Context}; use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
comment::{Comment, CommentForm}, comment::Comment,
comment_view::CommentView, comment_view::CommentView,
community::{Community, CommunityForm}, community::Community,
community_view::CommunityView, community_view::CommunityView,
naive_now, post::Post,
post::{Post, PostForm},
post_view::PostView, post_view::PostView,
Crud,
}; };
use lemmy_structs::{ use lemmy_structs::{
blocking, blocking,
@ -52,112 +42,69 @@ pub async fn receive_remove(
.map(|c| c.as_xsd_any_uri()) .map(|c| c.as_xsd_any_uri())
.flatten() .flatten()
.context(location_info!())?; .context(location_info!())?;
let object = remove
.object()
.to_owned()
.single_xsd_any_uri()
.context(location_info!())?;
// Ensure that remove comes from the same domain as the community
if actor.actor_id()?.domain() != community_id.domain() { if actor.actor_id()?.domain() != community_id.domain() {
return Err(anyhow!("Remove receive are only allowed on local objects").into()); return Err(DomainError.into());
} }
match remove.object().as_single_kind_str() { // Ensure that remove activity comes from the same domain as the community
Some("Page") => receive_remove_post(remove, context).await, remove.id(community_id.domain().context(location_info!())?)?;
Some("Note") => receive_remove_comment(remove, context).await,
Some("Group") => receive_remove_community(remove, context).await, match find_by_id(context, object).await {
_ => receive_unhandled_activity(remove), Ok(FindResults::Post(p)) => receive_remove_post(context, remove, p).await,
Ok(FindResults::Comment(c)) => receive_remove_comment(context, remove, c).await,
Ok(FindResults::Community(c)) => receive_remove_community(context, remove, c).await,
// if we dont have the object, no need to do anything
Err(_) => Ok(HttpResponse::Ok().finish()),
} }
} }
async fn receive_remove_post( async fn receive_remove_post(
remove: Remove,
context: &LemmyContext, context: &LemmyContext,
_remove: Remove,
post: Post,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let mod_ = get_actor_as_user(&remove, context).await?; let removed_post = blocking(context.pool(), move |conn| {
let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)? Post::update_removed(conn, post.id, true)
.context(location_info!())?;
let post_ap_id = PostForm::from_apub(&page, context, None)
.await?
.get_ap_id()?;
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
let post_form = PostForm {
name: post.name.to_owned(),
url: post.url.to_owned(),
body: post.body.to_owned(),
creator_id: post.creator_id.to_owned(),
community_id: post.community_id,
removed: Some(true),
deleted: None,
nsfw: post.nsfw,
locked: None,
stickied: None,
updated: Some(naive_now()),
embed_title: post.embed_title,
embed_description: post.embed_description,
embed_html: post.embed_html,
thumbnail_url: post.thumbnail_url,
ap_id: Some(post.ap_id),
local: post.local,
published: None,
};
let post_id = post.id;
blocking(context.pool(), move |conn| {
Post::update(conn, post_id, &post_form)
}) })
.await??; .await??;
// Refetch the view // Refetch the view
let post_id = post.id; let post_id = removed_post.id;
let post_view = blocking(context.pool(), move |conn| { let post_view = blocking(context.pool(), move |conn| {
PostView::read(conn, post_id, None) PostView::read(conn, post_id, None)
}) })
.await??; .await??;
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::EditPost, op: UserOperation::EditPost,
post: res, post: res,
websocket_id: None, websocket_id: None,
}); });
announce_if_community_is_local(remove, &mod_, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
async fn receive_remove_comment( async fn receive_remove_comment(
remove: Remove,
context: &LemmyContext, context: &LemmyContext,
_remove: Remove,
comment: Comment,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let mod_ = get_actor_as_user(&remove, context).await?; let removed_comment = blocking(context.pool(), move |conn| {
let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)? Comment::update_removed(conn, comment.id, true)
.context(location_info!())?;
let comment_ap_id = CommentForm::from_apub(&note, context, None)
.await?
.get_ap_id()?;
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
let comment_form = CommentForm {
content: comment.content.to_owned(),
parent_id: comment.parent_id,
post_id: comment.post_id,
creator_id: comment.creator_id,
removed: Some(true),
deleted: None,
read: None,
published: None,
updated: Some(naive_now()),
ap_id: Some(comment.ap_id),
local: comment.local,
};
let comment_id = comment.id;
blocking(context.pool(), move |conn| {
Comment::update(conn, comment_id, &comment_form)
}) })
.await??; .await??;
// Refetch the view // Refetch the view
let comment_id = comment.id; let comment_id = removed_comment.id;
let comment_view = blocking(context.pool(), move |conn| { let comment_view = blocking(context.pool(), move |conn| {
CommentView::read(conn, comment_id, None) CommentView::read(conn, comment_id, None)
}) })
@ -170,62 +117,26 @@ async fn receive_remove_comment(
recipient_ids, recipient_ids,
form_id: None, form_id: None,
}; };
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::EditComment, op: UserOperation::EditComment,
comment: res, comment: res,
websocket_id: None, websocket_id: None,
}); });
announce_if_community_is_local(remove, &mod_, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
async fn receive_remove_community( async fn receive_remove_community(
remove: Remove,
context: &LemmyContext, context: &LemmyContext,
_remove: Remove,
community: Community,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let mod_ = get_actor_as_user(&remove, context).await?; let removed_community = blocking(context.pool(), move |conn| {
let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)? Community::update_removed(conn, community.id, true)
.context(location_info!())?;
let community_actor_id = CommunityForm::from_apub(&group, context, Some(mod_.actor_id()?))
.await?
.actor_id
.context(location_info!())?;
let community = blocking(context.pool(), move |conn| {
Community::read_from_actor_id(conn, &community_actor_id)
}) })
.await??; .await??;
let community_form = CommunityForm { let community_id = removed_community.id;
name: community.name.to_owned(),
title: community.title.to_owned(),
description: community.description.to_owned(),
category_id: community.category_id, // Note: need to keep this due to foreign key constraint
creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint
removed: Some(true),
published: None,
updated: Some(naive_now()),
deleted: None,
nsfw: community.nsfw,
actor_id: Some(community.actor_id),
local: community.local,
private_key: community.private_key,
public_key: community.public_key,
last_refreshed_at: None,
icon: Some(community.icon.to_owned()),
banner: Some(community.banner.to_owned()),
};
let community_id = community.id;
blocking(context.pool(), move |conn| {
Community::update(conn, community_id, &community_form)
})
.await??;
let community_id = community.id;
let res = CommunityResponse { let res = CommunityResponse {
community: blocking(context.pool(), move |conn| { community: blocking(context.pool(), move |conn| {
CommunityView::read(conn, community_id, None) CommunityView::read(conn, community_id, None)
@ -234,7 +145,6 @@ async fn receive_remove_community(
}; };
let community_id = res.community.id; let community_id = res.community.id;
context.chat_server().do_send(SendCommunityRoomMessage { context.chat_server().do_send(SendCommunityRoomMessage {
op: UserOperation::EditCommunity, op: UserOperation::EditCommunity,
response: res, response: res,
@ -242,6 +152,5 @@ async fn receive_remove_community(
websocket_id: None, websocket_id: None,
}); });
announce_if_community_is_local(remove, &mod_, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }

View file

@ -1,14 +1,11 @@
use crate::{ use crate::activities::receive::{
activities::receive::{
announce_if_community_is_local, announce_if_community_is_local,
find_by_id,
get_actor_as_user, get_actor_as_user,
receive_unhandled_activity, receive_unhandled_activity,
undo_comment::*, undo_comment::*,
undo_post::*, undo_post::*,
}, FindResults,
ActorType,
FromApub,
GroupExt,
}; };
use activitystreams::{ use activitystreams::{
activity::*, activity::*,
@ -17,12 +14,7 @@ use activitystreams::{
}; };
use actix_web::HttpResponse; use actix_web::HttpResponse;
use anyhow::{anyhow, Context}; use anyhow::{anyhow, Context};
use lemmy_db::{ use lemmy_db::{community::Community, community_view::CommunityView};
community::{Community, CommunityForm},
community_view::CommunityView,
naive_now,
Crud,
};
use lemmy_structs::{blocking, community::CommunityResponse}; use lemmy_structs::{blocking, community::CommunityResponse};
use lemmy_utils::{location_info, LemmyError}; use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation}; use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
@ -69,15 +61,18 @@ async fn receive_undo_delete(
let delete = Delete::from_any_base(undo.object().to_owned().one().context(location_info!())?)? let delete = Delete::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
check_is_undo_valid(&undo, &delete)?; check_is_undo_valid(&undo, &delete)?;
let type_ = delete
let object = delete
.object() .object()
.as_single_kind_str() .to_owned()
.single_xsd_any_uri()
.context(location_info!())?; .context(location_info!())?;
match type_ { match find_by_id(context, object).await {
"Note" => receive_undo_delete_comment(undo, &delete, context).await, Ok(FindResults::Post(p)) => receive_undo_delete_post(context, undo, p).await,
"Page" => receive_undo_delete_post(undo, &delete, context).await, Ok(FindResults::Comment(c)) => receive_undo_delete_comment(context, undo, c).await,
"Group" => receive_undo_delete_community(undo, &delete, context).await, Ok(FindResults::Community(c)) => receive_undo_delete_community(context, undo, c).await,
d => Err(anyhow!("Undo Delete type {} not supported", d).into()), // if we dont have the object, no need to do anything
Err(_) => Ok(HttpResponse::Ok().finish()),
} }
} }
@ -89,15 +84,17 @@ async fn receive_undo_remove(
.context(location_info!())?; .context(location_info!())?;
check_is_undo_valid(&undo, &remove)?; check_is_undo_valid(&undo, &remove)?;
let type_ = remove let object = remove
.object() .object()
.as_single_kind_str() .to_owned()
.single_xsd_any_uri()
.context(location_info!())?; .context(location_info!())?;
match type_ { match find_by_id(context, object).await {
"Note" => receive_undo_remove_comment(undo, &remove, context).await, Ok(FindResults::Post(p)) => receive_undo_remove_post(context, undo, p).await,
"Page" => receive_undo_remove_post(undo, &remove, context).await, Ok(FindResults::Comment(c)) => receive_undo_remove_comment(context, undo, c).await,
"Group" => receive_undo_remove_community(undo, &remove, context).await, Ok(FindResults::Community(c)) => receive_undo_remove_community(context, undo, c).await,
d => Err(anyhow!("Undo Delete type {} not supported", d).into()), // if we dont have the object, no need to do anything
Err(_) => Ok(HttpResponse::Ok().finish()),
} }
} }
@ -137,51 +134,16 @@ async fn receive_undo_dislike(
} }
async fn receive_undo_delete_community( async fn receive_undo_delete_community(
undo: Undo,
delete: &Delete,
context: &LemmyContext, context: &LemmyContext,
undo: Undo,
community: Community,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let user = get_actor_as_user(delete, context).await?; let deleted_community = blocking(context.pool(), move |conn| {
let group = GroupExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)? Community::update_deleted(conn, community.id, false)
.context(location_info!())?;
let community_actor_id = CommunityForm::from_apub(&group, context, Some(user.actor_id()?))
.await?
.actor_id
.context(location_info!())?;
let community = blocking(context.pool(), move |conn| {
Community::read_from_actor_id(conn, &community_actor_id)
}) })
.await??; .await??;
let community_form = CommunityForm { let community_id = deleted_community.id;
name: community.name.to_owned(),
title: community.title.to_owned(),
description: community.description.to_owned(),
category_id: community.category_id, // Note: need to keep this due to foreign key constraint
creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint
removed: None,
published: None,
updated: Some(naive_now()),
deleted: Some(false),
nsfw: community.nsfw,
actor_id: Some(community.actor_id),
local: community.local,
private_key: community.private_key,
public_key: community.public_key,
last_refreshed_at: None,
icon: Some(community.icon.to_owned()),
banner: Some(community.banner.to_owned()),
};
let community_id = community.id;
blocking(context.pool(), move |conn| {
Community::update(conn, community_id, &community_form)
})
.await??;
let community_id = community.id;
let res = CommunityResponse { let res = CommunityResponse {
community: blocking(context.pool(), move |conn| { community: blocking(context.pool(), move |conn| {
CommunityView::read(conn, community_id, None) CommunityView::read(conn, community_id, None)
@ -190,7 +152,6 @@ async fn receive_undo_delete_community(
}; };
let community_id = res.community.id; let community_id = res.community.id;
context.chat_server().do_send(SendCommunityRoomMessage { context.chat_server().do_send(SendCommunityRoomMessage {
op: UserOperation::EditCommunity, op: UserOperation::EditCommunity,
response: res, response: res,
@ -198,56 +159,22 @@ async fn receive_undo_delete_community(
websocket_id: None, websocket_id: None,
}); });
let user = get_actor_as_user(&undo, context).await?;
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
async fn receive_undo_remove_community( async fn receive_undo_remove_community(
undo: Undo,
remove: &Remove,
context: &LemmyContext, context: &LemmyContext,
undo: Undo,
community: Community,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let mod_ = get_actor_as_user(remove, context).await?; let removed_community = blocking(context.pool(), move |conn| {
let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)? Community::update_removed(conn, community.id, false)
.context(location_info!())?;
let community_actor_id = CommunityForm::from_apub(&group, context, Some(mod_.actor_id()?))
.await?
.actor_id
.context(location_info!())?;
let community = blocking(context.pool(), move |conn| {
Community::read_from_actor_id(conn, &community_actor_id)
}) })
.await??; .await??;
let community_form = CommunityForm { let community_id = removed_community.id;
name: community.name.to_owned(),
title: community.title.to_owned(),
description: community.description.to_owned(),
category_id: community.category_id, // Note: need to keep this due to foreign key constraint
creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint
removed: Some(false),
published: None,
updated: Some(naive_now()),
deleted: None,
nsfw: community.nsfw,
actor_id: Some(community.actor_id),
local: community.local,
private_key: community.private_key,
public_key: community.public_key,
last_refreshed_at: None,
icon: Some(community.icon.to_owned()),
banner: Some(community.banner.to_owned()),
};
let community_id = community.id;
blocking(context.pool(), move |conn| {
Community::update(conn, community_id, &community_form)
})
.await??;
let community_id = community.id;
let res = CommunityResponse { let res = CommunityResponse {
community: blocking(context.pool(), move |conn| { community: blocking(context.pool(), move |conn| {
CommunityView::read(conn, community_id, None) CommunityView::read(conn, community_id, None)
@ -264,6 +191,7 @@ async fn receive_undo_remove_community(
websocket_id: None, websocket_id: None,
}); });
let mod_ = get_actor_as_user(&undo, context).await?;
announce_if_community_is_local(undo, &mod_, context).await?; announce_if_community_is_local(undo, &mod_, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }

View file

@ -1,7 +1,6 @@
use crate::{ use crate::{
activities::receive::{announce_if_community_is_local, get_actor_as_user}, activities::receive::{announce_if_community_is_local, get_actor_as_user},
fetcher::get_or_fetch_and_insert_comment, fetcher::get_or_fetch_and_insert_comment,
ActorType,
FromApub, FromApub,
}; };
use activitystreams::{activity::*, object::Note, prelude::*}; use activitystreams::{activity::*, object::Note, prelude::*};
@ -10,8 +9,6 @@ use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
comment::{Comment, CommentForm, CommentLike}, comment::{Comment, CommentForm, CommentLike},
comment_view::CommentView, comment_view::CommentView,
naive_now,
Crud,
Likeable, Likeable,
}; };
use lemmy_structs::{blocking, comment::CommentResponse}; use lemmy_structs::{blocking, comment::CommentResponse};
@ -115,41 +112,17 @@ pub(crate) async fn receive_undo_dislike_comment(
} }
pub(crate) async fn receive_undo_delete_comment( pub(crate) async fn receive_undo_delete_comment(
undo: Undo,
delete: &Delete,
context: &LemmyContext, context: &LemmyContext,
undo: Undo,
comment: Comment,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let user = get_actor_as_user(delete, context).await?; let deleted_comment = blocking(context.pool(), move |conn| {
let note = Note::from_any_base(delete.object().to_owned().one().context(location_info!())?)? Comment::update_deleted(conn, comment.id, false)
.context(location_info!())?;
let comment_ap_id = CommentForm::from_apub(&note, context, Some(user.actor_id()?))
.await?
.get_ap_id()?;
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
let comment_form = CommentForm {
content: comment.content.to_owned(),
parent_id: comment.parent_id,
post_id: comment.post_id,
creator_id: comment.creator_id,
removed: None,
deleted: Some(false),
read: None,
published: None,
updated: Some(naive_now()),
ap_id: Some(comment.ap_id),
local: comment.local,
};
let comment_id = comment.id;
blocking(context.pool(), move |conn| {
Comment::update(conn, comment_id, &comment_form)
}) })
.await??; .await??;
// Refetch the view // Refetch the view
let comment_id = comment.id; let comment_id = deleted_comment.id;
let comment_view = blocking(context.pool(), move |conn| { let comment_view = blocking(context.pool(), move |conn| {
CommentView::read(conn, comment_id, None) CommentView::read(conn, comment_id, None)
}) })
@ -169,46 +142,23 @@ pub(crate) async fn receive_undo_delete_comment(
websocket_id: None, websocket_id: None,
}); });
let user = get_actor_as_user(&undo, context).await?;
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
pub(crate) async fn receive_undo_remove_comment( pub(crate) async fn receive_undo_remove_comment(
undo: Undo,
remove: &Remove,
context: &LemmyContext, context: &LemmyContext,
undo: Undo,
comment: Comment,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let mod_ = get_actor_as_user(remove, context).await?; let removed_comment = blocking(context.pool(), move |conn| {
let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)? Comment::update_removed(conn, comment.id, false)
.context(location_info!())?;
let comment_ap_id = CommentForm::from_apub(&note, context, None)
.await?
.get_ap_id()?;
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
let comment_form = CommentForm {
content: comment.content.to_owned(),
parent_id: comment.parent_id,
post_id: comment.post_id,
creator_id: comment.creator_id,
removed: Some(false),
deleted: None,
read: None,
published: None,
updated: Some(naive_now()),
ap_id: Some(comment.ap_id),
local: comment.local,
};
let comment_id = comment.id;
blocking(context.pool(), move |conn| {
Comment::update(conn, comment_id, &comment_form)
}) })
.await??; .await??;
// Refetch the view // Refetch the view
let comment_id = comment.id; let comment_id = removed_comment.id;
let comment_view = blocking(context.pool(), move |conn| { let comment_view = blocking(context.pool(), move |conn| {
CommentView::read(conn, comment_id, None) CommentView::read(conn, comment_id, None)
}) })
@ -228,6 +178,7 @@ pub(crate) async fn receive_undo_remove_comment(
websocket_id: None, websocket_id: None,
}); });
let mod_ = get_actor_as_user(&undo, context).await?;
announce_if_community_is_local(undo, &mod_, context).await?; announce_if_community_is_local(undo, &mod_, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }

View file

@ -1,7 +1,6 @@
use crate::{ use crate::{
activities::receive::{announce_if_community_is_local, get_actor_as_user}, activities::receive::{announce_if_community_is_local, get_actor_as_user},
fetcher::get_or_fetch_and_insert_post, fetcher::get_or_fetch_and_insert_post,
ActorType,
FromApub, FromApub,
PageExt, PageExt,
}; };
@ -9,10 +8,8 @@ use activitystreams::{activity::*, prelude::*};
use actix_web::HttpResponse; use actix_web::HttpResponse;
use anyhow::Context; use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
naive_now,
post::{Post, PostForm, PostLike}, post::{Post, PostForm, PostLike},
post_view::PostView, post_view::PostView,
Crud,
Likeable, Likeable,
}; };
use lemmy_structs::{blocking, post::PostResponse}; use lemmy_structs::{blocking, post::PostResponse};
@ -104,108 +101,46 @@ pub(crate) async fn receive_undo_dislike_post(
} }
pub(crate) async fn receive_undo_delete_post( pub(crate) async fn receive_undo_delete_post(
undo: Undo,
delete: &Delete,
context: &LemmyContext, context: &LemmyContext,
undo: Undo,
post: Post,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let user = get_actor_as_user(delete, context).await?; let deleted_post = blocking(context.pool(), move |conn| {
let page = PageExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)? Post::update_deleted(conn, post.id, false)
.context(location_info!())?;
let post_ap_id = PostForm::from_apub(&page, context, Some(user.actor_id()?))
.await?
.get_ap_id()?;
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
let post_form = PostForm {
name: post.name.to_owned(),
url: post.url.to_owned(),
body: post.body.to_owned(),
creator_id: post.creator_id.to_owned(),
community_id: post.community_id,
removed: None,
deleted: Some(false),
nsfw: post.nsfw,
locked: None,
stickied: None,
updated: Some(naive_now()),
embed_title: post.embed_title,
embed_description: post.embed_description,
embed_html: post.embed_html,
thumbnail_url: post.thumbnail_url,
ap_id: Some(post.ap_id),
local: post.local,
published: None,
};
let post_id = post.id;
blocking(context.pool(), move |conn| {
Post::update(conn, post_id, &post_form)
}) })
.await??; .await??;
// Refetch the view // Refetch the view
let post_id = post.id; let post_id = deleted_post.id;
let post_view = blocking(context.pool(), move |conn| { let post_view = blocking(context.pool(), move |conn| {
PostView::read(conn, post_id, None) PostView::read(conn, post_id, None)
}) })
.await??; .await??;
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::EditPost, op: UserOperation::EditPost,
post: res, post: res,
websocket_id: None, websocket_id: None,
}); });
let user = get_actor_as_user(&undo, context).await?;
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
pub(crate) async fn receive_undo_remove_post( pub(crate) async fn receive_undo_remove_post(
undo: Undo,
remove: &Remove,
context: &LemmyContext, context: &LemmyContext,
undo: Undo,
post: Post,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let mod_ = get_actor_as_user(remove, context).await?; let removed_post = blocking(context.pool(), move |conn| {
let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)? Post::update_removed(conn, post.id, false)
.context(location_info!())?;
let post_ap_id = PostForm::from_apub(&page, context, None)
.await?
.get_ap_id()?;
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
let post_form = PostForm {
name: post.name.to_owned(),
url: post.url.to_owned(),
body: post.body.to_owned(),
creator_id: post.creator_id.to_owned(),
community_id: post.community_id,
removed: Some(false),
deleted: None,
nsfw: post.nsfw,
locked: None,
stickied: None,
updated: Some(naive_now()),
embed_title: post.embed_title,
embed_description: post.embed_description,
embed_html: post.embed_html,
thumbnail_url: post.thumbnail_url,
ap_id: Some(post.ap_id),
local: post.local,
published: None,
};
let post_id = post.id;
blocking(context.pool(), move |conn| {
Post::update(conn, post_id, &post_form)
}) })
.await??; .await??;
// Refetch the view // Refetch the view
let post_id = post.id; let post_id = removed_post.id;
let post_view = blocking(context.pool(), move |conn| { let post_view = blocking(context.pool(), move |conn| {
PostView::read(conn, post_id, None) PostView::read(conn, post_id, None)
}) })
@ -219,6 +154,7 @@ pub(crate) async fn receive_undo_remove_post(
websocket_id: None, websocket_id: None,
}); });
let mod_ = get_actor_as_user(&undo, context).await?;
announce_if_community_is_local(undo, &mod_, context).await?; announce_if_community_is_local(undo, &mod_, context).await?;
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }

View file

@ -106,8 +106,6 @@ impl ApubObjectType for Comment {
} }
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let note = self.to_apub(context.pool()).await?;
let post_id = self.post_id; let post_id = self.post_id;
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??;
@ -117,7 +115,7 @@ impl ApubObjectType for Comment {
}) })
.await??; .await??;
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?); let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
delete delete
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(DeleteType::Delete)?) .set_id(generate_activity_id(DeleteType::Delete)?)
@ -133,8 +131,6 @@ impl ApubObjectType for Comment {
creator: &User_, creator: &User_,
context: &LemmyContext, context: &LemmyContext,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
let note = self.to_apub(context.pool()).await?;
let post_id = self.post_id; let post_id = self.post_id;
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??;
@ -145,7 +141,7 @@ impl ApubObjectType for Comment {
.await??; .await??;
// Generate a fake delete activity, with the correct object // Generate a fake delete activity, with the correct object
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?); let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
delete delete
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(DeleteType::Delete)?) .set_id(generate_activity_id(DeleteType::Delete)?)
@ -165,8 +161,6 @@ impl ApubObjectType for Comment {
} }
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let note = self.to_apub(context.pool()).await?;
let post_id = self.post_id; let post_id = self.post_id;
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??;
@ -176,7 +170,7 @@ impl ApubObjectType for Comment {
}) })
.await??; .await??;
let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?); let mut remove = Remove::new(mod_.actor_id.to_owned(), Url::parse(&self.ap_id)?);
remove remove
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(RemoveType::Remove)?) .set_id(generate_activity_id(RemoveType::Remove)?)
@ -188,8 +182,6 @@ impl ApubObjectType for Comment {
} }
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let note = self.to_apub(context.pool()).await?;
let post_id = self.post_id; let post_id = self.post_id;
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??;
@ -200,7 +192,7 @@ impl ApubObjectType for Comment {
.await??; .await??;
// Generate a fake delete activity, with the correct object // Generate a fake delete activity, with the correct object
let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?); let mut remove = Remove::new(mod_.actor_id.to_owned(), Url::parse(&self.ap_id)?);
remove remove
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(RemoveType::Remove)?) .set_id(generate_activity_id(RemoveType::Remove)?)

View file

@ -124,9 +124,7 @@ impl ActorType for Community {
} }
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let group = self.to_apub(context.pool()).await?; let mut remove = Remove::new(mod_.actor_id.to_owned(), self.actor_id()?);
let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
remove remove
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(RemoveType::Remove)?) .set_id(generate_activity_id(RemoveType::Remove)?)
@ -138,9 +136,7 @@ impl ActorType for Community {
} }
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let group = self.to_apub(context.pool()).await?; let mut remove = Remove::new(mod_.actor_id.to_owned(), self.actor_id()?);
let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
remove remove
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(RemoveType::Remove)?) .set_id(generate_activity_id(RemoveType::Remove)?)

View file

@ -24,6 +24,7 @@ use lemmy_db::{community::Community, post::Post, user::User_, Crud};
use lemmy_structs::blocking; use lemmy_structs::blocking;
use lemmy_utils::LemmyError; use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use url::Url;
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl ApubObjectType for Post { impl ApubObjectType for Post {
@ -70,15 +71,13 @@ impl ApubObjectType for Post {
} }
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let page = self.to_apub(context.pool()).await?;
let community_id = self.community_id; let community_id = self.community_id;
let community = blocking(context.pool(), move |conn| { let community = blocking(context.pool(), move |conn| {
Community::read(conn, community_id) Community::read(conn, community_id)
}) })
.await??; .await??;
let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?); let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
delete delete
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(DeleteType::Delete)?) .set_id(generate_activity_id(DeleteType::Delete)?)
@ -94,15 +93,13 @@ impl ApubObjectType for Post {
creator: &User_, creator: &User_,
context: &LemmyContext, context: &LemmyContext,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
let page = self.to_apub(context.pool()).await?;
let community_id = self.community_id; let community_id = self.community_id;
let community = blocking(context.pool(), move |conn| { let community = blocking(context.pool(), move |conn| {
Community::read(conn, community_id) Community::read(conn, community_id)
}) })
.await??; .await??;
let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?); let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
delete delete
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(DeleteType::Delete)?) .set_id(generate_activity_id(DeleteType::Delete)?)
@ -122,15 +119,13 @@ impl ApubObjectType for Post {
} }
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let page = self.to_apub(context.pool()).await?;
let community_id = self.community_id; let community_id = self.community_id;
let community = blocking(context.pool(), move |conn| { let community = blocking(context.pool(), move |conn| {
Community::read(conn, community_id) Community::read(conn, community_id)
}) })
.await??; .await??;
let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?); let mut remove = Remove::new(mod_.actor_id.to_owned(), Url::parse(&self.ap_id)?);
remove remove
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(RemoveType::Remove)?) .set_id(generate_activity_id(RemoveType::Remove)?)
@ -142,15 +137,13 @@ impl ApubObjectType for Post {
} }
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let page = self.to_apub(context.pool()).await?;
let community_id = self.community_id; let community_id = self.community_id;
let community = blocking(context.pool(), move |conn| { let community = blocking(context.pool(), move |conn| {
Community::read(conn, community_id) Community::read(conn, community_id)
}) })
.await??; .await??;
let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?); let mut remove = Remove::new(mod_.actor_id.to_owned(), Url::parse(&self.ap_id)?);
remove remove
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(RemoveType::Remove)?) .set_id(generate_activity_id(RemoveType::Remove)?)

View file

@ -19,6 +19,7 @@ use lemmy_db::{private_message::PrivateMessage, user::User_, Crud};
use lemmy_structs::blocking; use lemmy_structs::blocking;
use lemmy_utils::LemmyError; use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use url::Url;
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl ApubObjectType for PrivateMessage { impl ApubObjectType for PrivateMessage {
@ -58,12 +59,10 @@ impl ApubObjectType for PrivateMessage {
} }
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> { async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
let note = self.to_apub(context.pool()).await?;
let recipient_id = self.recipient_id; let recipient_id = self.recipient_id;
let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??; let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?); let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
delete delete
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(DeleteType::Delete)?) .set_id(generate_activity_id(DeleteType::Delete)?)
@ -78,12 +77,10 @@ impl ApubObjectType for PrivateMessage {
creator: &User_, creator: &User_,
context: &LemmyContext, context: &LemmyContext,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
let note = self.to_apub(context.pool()).await?;
let recipient_id = self.recipient_id; let recipient_id = self.recipient_id;
let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??; let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?); let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
delete delete
.set_context(activitystreams::context()) .set_context(activitystreams::context())
.set_id(generate_activity_id(DeleteType::Delete)?) .set_id(generate_activity_id(DeleteType::Delete)?)

View file

@ -8,6 +8,7 @@ use crate::{
use activitystreams::{ use activitystreams::{
activity::{Accept, ActorAndObject, Create, Delete, Undo, Update}, activity::{Accept, ActorAndObject, Create, Delete, Undo, Update},
base::AnyBase, base::AnyBase,
error::DomainError,
object::Note, object::Note,
prelude::*, prelude::*,
}; };
@ -15,7 +16,6 @@ use actix_web::{web, HttpRequest, HttpResponse};
use anyhow::Context; use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
community::{CommunityFollower, CommunityFollowerForm}, community::{CommunityFollower, CommunityFollowerForm},
naive_now,
private_message::{PrivateMessage, PrivateMessageForm}, private_message::{PrivateMessage, PrivateMessageForm},
private_message_view::PrivateMessageView, private_message_view::PrivateMessageView,
user::User_, user::User_,
@ -131,7 +131,17 @@ async fn receive_create_private_message(
)? )?
.context(location_info!())?; .context(location_info!())?;
let domain = Some(create.id_unchecked().context(location_info!())?.to_owned()); let actor = create
.actor()?
.to_owned()
.single_xsd_any_uri()
.context(location_info!())?;
let domain = Some(
create
.id(actor.domain().context(location_info!())?)?
.context(location_info!())?
.to_owned(),
);
let private_message = PrivateMessageForm::from_apub(&note, context, domain).await?; let private_message = PrivateMessageForm::from_apub(&note, context, domain).await?;
let inserted_private_message = blocking(&context.pool(), move |conn| { let inserted_private_message = blocking(&context.pool(), move |conn| {
@ -172,7 +182,17 @@ async fn receive_update_private_message(
)? )?
.context(location_info!())?; .context(location_info!())?;
let domain = Some(update.id_unchecked().context(location_info!())?.to_owned()); let actor = update
.actor()?
.to_owned()
.single_xsd_any_uri()
.context(location_info!())?;
let domain = Some(
update
.id(actor.domain().context(location_info!())?)?
.context(location_info!())?
.to_owned(),
);
let private_message_form = PrivateMessageForm::from_apub(&note, context, domain).await?; let private_message_form = PrivateMessageForm::from_apub(&note, context, domain).await?;
let private_message_ap_id = private_message_form let private_message_ap_id = private_message_form
@ -216,52 +236,39 @@ async fn receive_delete_private_message(
context: &LemmyContext, context: &LemmyContext,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let delete = Delete::from_any_base(activity)?.context(location_info!())?; let delete = Delete::from_any_base(activity)?.context(location_info!())?;
let note = Note::from_any_base( let private_message_id = delete
delete
.object() .object()
.as_one() .to_owned()
.context(location_info!())? .single_xsd_any_uri()
.to_owned(),
)?
.context(location_info!())?; .context(location_info!())?;
let actor = delete
let domain = Some(delete.id_unchecked().context(location_info!())?.to_owned()); .actor()?
let private_message_form = PrivateMessageForm::from_apub(&note, context, domain).await?; .to_owned()
.single_xsd_any_uri()
let private_message_ap_id = private_message_form.ap_id.context(location_info!())?; .context(location_info!())?;
let private_message = blocking(&context.pool(), move |conn| { let delete_id = delete
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id) .id(actor.domain().context(location_info!())?)?
.map(|i| i.domain())
.flatten();
if private_message_id.domain() != delete_id {
return Err(DomainError.into());
}
let private_message = blocking(context.pool(), move |conn| {
PrivateMessage::read_from_apub_id(conn, private_message_id.as_str())
})
.await??;
let deleted_private_message = blocking(context.pool(), move |conn| {
PrivateMessage::update_deleted(conn, private_message.id, true)
}) })
.await??; .await??;
let private_message_form = PrivateMessageForm {
content: private_message_form.content,
recipient_id: private_message.recipient_id,
creator_id: private_message.creator_id,
deleted: Some(true),
read: None,
ap_id: Some(private_message.ap_id),
local: private_message.local,
published: None,
updated: Some(naive_now()),
};
let private_message_id = private_message.id;
blocking(&context.pool(), move |conn| {
PrivateMessage::update(conn, private_message_id, &private_message_form)
})
.await??;
let private_message_id = private_message.id;
let message = blocking(&context.pool(), move |conn| { let message = blocking(&context.pool(), move |conn| {
PrivateMessageView::read(&conn, private_message_id) PrivateMessageView::read(&conn, deleted_private_message.id)
}) })
.await??; .await??;
let res = PrivateMessageResponse { message }; let res = PrivateMessageResponse { message };
let recipient_id = res.message.recipient_id; let recipient_id = res.message.recipient_id;
context.chat_server().do_send(SendUserRoomMessage { context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::EditPrivateMessage, op: UserOperation::EditPrivateMessage,
response: res, response: res,
@ -279,47 +286,35 @@ async fn receive_undo_delete_private_message(
let undo = Undo::from_any_base(activity)?.context(location_info!())?; let undo = Undo::from_any_base(activity)?.context(location_info!())?;
let delete = Delete::from_any_base(undo.object().as_one().context(location_info!())?.to_owned())? let delete = Delete::from_any_base(undo.object().as_one().context(location_info!())?.to_owned())?
.context(location_info!())?; .context(location_info!())?;
let note = Note::from_any_base( let private_message_id = delete
delete
.object() .object()
.as_one() .to_owned()
.context(location_info!())? .single_xsd_any_uri()
.to_owned(),
)?
.context(location_info!())?; .context(location_info!())?;
let actor = undo
.actor()?
.to_owned()
.single_xsd_any_uri()
.context(location_info!())?;
let undo_id = undo
.id(actor.domain().context(location_info!())?)?
.map(|i| i.domain())
.flatten();
if private_message_id.domain() != undo_id {
return Err(DomainError.into());
}
let domain = Some(undo.id_unchecked().context(location_info!())?.to_owned()); let private_message = blocking(context.pool(), move |conn| {
let private_message = PrivateMessageForm::from_apub(&note, context, domain).await?; PrivateMessage::read_from_apub_id(conn, private_message_id.as_str())
let private_message_ap_id = private_message
.ap_id
.as_ref()
.context(location_info!())?
.clone();
let private_message_id = blocking(&context.pool(), move |conn| {
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id).map(|pm| pm.id)
}) })
.await??; .await??;
let deleted_private_message = blocking(context.pool(), move |conn| {
let private_message_form = PrivateMessageForm { PrivateMessage::update_deleted(conn, private_message.id, false)
content: private_message.content,
recipient_id: private_message.recipient_id,
creator_id: private_message.creator_id,
deleted: Some(false),
read: None,
ap_id: private_message.ap_id,
local: private_message.local,
published: None,
updated: Some(naive_now()),
};
blocking(&context.pool(), move |conn| {
PrivateMessage::update(conn, private_message_id, &private_message_form)
}) })
.await??; .await??;
let message = blocking(&context.pool(), move |conn| { let message = blocking(&context.pool(), move |conn| {
PrivateMessageView::read(&conn, private_message_id) PrivateMessageView::read(&conn, deleted_private_message.id)
}) })
.await??; .await??;