This commit is contained in:
parent
dd865c5af5
commit
788924d7ff
38 changed files with 452 additions and 568 deletions
|
@ -7,7 +7,7 @@ use lemmy_api_common::{
|
||||||
get_local_user_view_from_jwt,
|
get_local_user_view_from_jwt,
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
};
|
};
|
||||||
use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove, DeletableObjects};
|
use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
comment::Comment,
|
comment::Comment,
|
||||||
|
@ -83,21 +83,7 @@ impl PerformCrud for DeleteComment {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Send the apub message
|
let res = send_comment_ws_message(
|
||||||
let community = blocking(context.pool(), move |conn| {
|
|
||||||
Community::read(conn, orig_comment.post.community_id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
send_apub_delete(
|
|
||||||
&local_user_view.person.clone().into(),
|
|
||||||
&community.clone().into(),
|
|
||||||
DeletableObjects::Comment(Box::new(updated_comment.into())),
|
|
||||||
deleted,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
send_comment_ws_message(
|
|
||||||
data.comment_id,
|
data.comment_id,
|
||||||
UserOperationCrud::DeleteComment,
|
UserOperationCrud::DeleteComment,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
|
@ -106,7 +92,25 @@ impl PerformCrud for DeleteComment {
|
||||||
recipient_ids,
|
recipient_ids,
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
|
|
||||||
|
// Send the apub message
|
||||||
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, orig_comment.post.community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into()));
|
||||||
|
send_apub_delete_in_community(
|
||||||
|
local_user_view.person,
|
||||||
|
community,
|
||||||
|
deletable,
|
||||||
|
None,
|
||||||
|
deleted,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,22 +182,7 @@ impl PerformCrud for RemoveComment {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Send the apub message
|
let res = send_comment_ws_message(
|
||||||
let community = blocking(context.pool(), move |conn| {
|
|
||||||
Community::read(conn, orig_comment.post.community_id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
send_apub_remove(
|
|
||||||
&local_user_view.person.clone().into(),
|
|
||||||
&community.into(),
|
|
||||||
DeletableObjects::Comment(Box::new(updated_comment.into())),
|
|
||||||
data.reason.clone().unwrap_or_else(|| "".to_string()),
|
|
||||||
removed,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
send_comment_ws_message(
|
|
||||||
data.comment_id,
|
data.comment_id,
|
||||||
UserOperationCrud::RemoveComment,
|
UserOperationCrud::RemoveComment,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
|
@ -202,6 +191,24 @@ impl PerformCrud for RemoveComment {
|
||||||
recipient_ids,
|
recipient_ids,
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
|
|
||||||
|
// Send the apub message
|
||||||
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, orig_comment.post.community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into()));
|
||||||
|
send_apub_delete_in_community(
|
||||||
|
local_user_view.person,
|
||||||
|
community,
|
||||||
|
deletable,
|
||||||
|
data.reason.clone().or_else(|| Some("".to_string())),
|
||||||
|
removed,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::PerformCrud;
|
use crate::PerformCrud;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt, is_admin};
|
use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt, is_admin};
|
||||||
use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove, DeletableObjects};
|
use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
community::Community,
|
community::Community,
|
||||||
|
@ -49,24 +49,28 @@ impl PerformCrud for DeleteCommunity {
|
||||||
.map_err(LemmyError::from)
|
.map_err(LemmyError::from)
|
||||||
.map_err(|e| e.with_message("couldnt_update_community"))?;
|
.map_err(|e| e.with_message("couldnt_update_community"))?;
|
||||||
|
|
||||||
// Send apub messages
|
let res = send_community_ws_message(
|
||||||
send_apub_delete(
|
|
||||||
&local_user_view.person.clone().into(),
|
|
||||||
&updated_community.clone().into(),
|
|
||||||
DeletableObjects::Community(Box::new(updated_community.into())),
|
|
||||||
deleted,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
send_community_ws_message(
|
|
||||||
data.community_id,
|
data.community_id,
|
||||||
UserOperationCrud::DeleteCommunity,
|
UserOperationCrud::DeleteCommunity,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
Some(local_user_view.person.id),
|
Some(local_user_view.person.id),
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
|
|
||||||
|
// Send apub messages
|
||||||
|
let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into()));
|
||||||
|
send_apub_delete_in_community(
|
||||||
|
local_user_view.person,
|
||||||
|
updated_community,
|
||||||
|
deletable,
|
||||||
|
None,
|
||||||
|
deleted,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,24 +115,26 @@ impl PerformCrud for RemoveCommunity {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Apub messages
|
let res = send_community_ws_message(
|
||||||
send_apub_remove(
|
|
||||||
&local_user_view.person.clone().into(),
|
|
||||||
&updated_community.clone().into(),
|
|
||||||
DeletableObjects::Community(Box::new(updated_community.into())),
|
|
||||||
data.reason.clone().unwrap_or_else(|| "".to_string()),
|
|
||||||
removed,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
send_community_ws_message(
|
|
||||||
data.community_id,
|
data.community_id,
|
||||||
UserOperationCrud::RemoveCommunity,
|
UserOperationCrud::RemoveCommunity,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
Some(local_user_view.person.id),
|
Some(local_user_view.person.id),
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
|
|
||||||
|
// Apub messages
|
||||||
|
let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into()));
|
||||||
|
send_apub_delete_in_community(
|
||||||
|
local_user_view.person,
|
||||||
|
updated_community,
|
||||||
|
deletable,
|
||||||
|
data.reason.clone().or_else(|| Some("".to_string())),
|
||||||
|
removed,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use lemmy_api_common::{
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
post::*,
|
post::*,
|
||||||
};
|
};
|
||||||
use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove, DeletableObjects};
|
use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
community::Community,
|
community::Community,
|
||||||
|
@ -63,28 +63,31 @@ impl PerformCrud for DeletePost {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// apub updates
|
let res = send_post_ws_message(
|
||||||
let community = blocking(context.pool(), move |conn| {
|
|
||||||
Community::read(conn, orig_post.community_id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
send_apub_delete(
|
|
||||||
&local_user_view.person.clone().into(),
|
|
||||||
&community.into(),
|
|
||||||
DeletableObjects::Post(Box::new(updated_post.into())),
|
|
||||||
deleted,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
send_post_ws_message(
|
|
||||||
data.post_id,
|
data.post_id,
|
||||||
UserOperationCrud::DeletePost,
|
UserOperationCrud::DeletePost,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
Some(local_user_view.person.id),
|
Some(local_user_view.person.id),
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
|
|
||||||
|
// apub updates
|
||||||
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, orig_post.community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
let deletable = DeletableObjects::Post(Box::new(updated_post.into()));
|
||||||
|
send_apub_delete_in_community(
|
||||||
|
local_user_view.person,
|
||||||
|
community,
|
||||||
|
deletable,
|
||||||
|
None,
|
||||||
|
deleted,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,28 +143,30 @@ impl PerformCrud for RemovePost {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// apub updates
|
let res = send_post_ws_message(
|
||||||
let community = blocking(context.pool(), move |conn| {
|
|
||||||
Community::read(conn, orig_post.community_id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
send_apub_remove(
|
|
||||||
&local_user_view.person.clone().into(),
|
|
||||||
&community.into(),
|
|
||||||
DeletableObjects::Post(Box::new(updated_post.into())),
|
|
||||||
data.reason.clone().unwrap_or_else(|| "".to_string()),
|
|
||||||
removed,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
send_post_ws_message(
|
|
||||||
data.post_id,
|
data.post_id,
|
||||||
UserOperationCrud::RemovePost,
|
UserOperationCrud::RemovePost,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
Some(local_user_view.person.id),
|
Some(local_user_view.person.id),
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
|
|
||||||
|
// apub updates
|
||||||
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, orig_post.community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
let deletable = DeletableObjects::Post(Box::new(updated_post.into()));
|
||||||
|
send_apub_delete_in_community(
|
||||||
|
local_user_view.person,
|
||||||
|
community,
|
||||||
|
deletable,
|
||||||
|
data.reason.clone().or_else(|| Some("".to_string())),
|
||||||
|
removed,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use lemmy_api_common::{
|
||||||
use lemmy_apub::{
|
use lemmy_apub::{
|
||||||
generate_local_apub_endpoint,
|
generate_local_apub_endpoint,
|
||||||
protocol::activities::{
|
protocol::activities::{
|
||||||
private_message::create_or_update::CreateOrUpdatePrivateMessage,
|
create_or_update::private_message::CreateOrUpdatePrivateMessage,
|
||||||
CreateOrUpdateType,
|
CreateOrUpdateType,
|
||||||
},
|
},
|
||||||
EndpointType,
|
EndpointType,
|
||||||
|
|
|
@ -5,14 +5,8 @@ use lemmy_api_common::{
|
||||||
get_local_user_view_from_jwt,
|
get_local_user_view_from_jwt,
|
||||||
person::{DeletePrivateMessage, PrivateMessageResponse},
|
person::{DeletePrivateMessage, PrivateMessageResponse},
|
||||||
};
|
};
|
||||||
use lemmy_apub::protocol::activities::private_message::{
|
use lemmy_apub::activities::deletion::send_apub_delete_private_message;
|
||||||
delete::DeletePrivateMessage as DeletePrivateMessageApub,
|
use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
|
||||||
undo_delete::UndoDeletePrivateMessage,
|
|
||||||
};
|
|
||||||
use lemmy_db_schema::{
|
|
||||||
source::private_message::PrivateMessage,
|
|
||||||
traits::{Crud, DeleteableOrRemoveable},
|
|
||||||
};
|
|
||||||
use lemmy_utils::{ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
|
||||||
|
|
||||||
|
@ -51,23 +45,13 @@ impl PerformCrud for DeletePrivateMessage {
|
||||||
.map_err(|e| e.with_message("couldnt_update_private_message"))?;
|
.map_err(|e| e.with_message("couldnt_update_private_message"))?;
|
||||||
|
|
||||||
// Send the apub update
|
// Send the apub update
|
||||||
if data.deleted {
|
send_apub_delete_private_message(
|
||||||
DeletePrivateMessageApub::send(
|
|
||||||
&local_user_view.person.into(),
|
&local_user_view.person.into(),
|
||||||
&updated_private_message
|
updated_private_message,
|
||||||
.blank_out_deleted_or_removed_info()
|
data.deleted,
|
||||||
.into(),
|
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
} else {
|
|
||||||
UndoDeletePrivateMessage::send(
|
|
||||||
&local_user_view.person.into(),
|
|
||||||
&updated_private_message.into(),
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let op = UserOperationCrud::DeletePrivateMessage;
|
let op = UserOperationCrud::DeletePrivateMessage;
|
||||||
send_pm_ws_message(data.private_message_id, op, websocket_id, context).await
|
send_pm_ws_message(data.private_message_id, op, websocket_id, context).await
|
||||||
|
|
|
@ -6,7 +6,7 @@ use lemmy_api_common::{
|
||||||
person::{EditPrivateMessage, PrivateMessageResponse},
|
person::{EditPrivateMessage, PrivateMessageResponse},
|
||||||
};
|
};
|
||||||
use lemmy_apub::protocol::activities::{
|
use lemmy_apub::protocol::activities::{
|
||||||
private_message::create_or_update::CreateOrUpdatePrivateMessage,
|
create_or_update::private_message::CreateOrUpdatePrivateMessage,
|
||||||
CreateOrUpdateType,
|
CreateOrUpdateType,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
|
use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
|
||||||
|
|
|
@ -3,10 +3,7 @@
|
||||||
"to": [
|
"to": [
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
],
|
],
|
||||||
"object": {
|
"object": "http://ds9.lemmy.ml/post/1",
|
||||||
"id": "http://ds9.lemmy.ml/post/1",
|
|
||||||
"type": "Tombstone"
|
|
||||||
},
|
|
||||||
"cc": [
|
"cc": [
|
||||||
"http://enterprise.lemmy.ml/c/main"
|
"http://enterprise.lemmy.ml/c/main"
|
||||||
],
|
],
|
||||||
|
|
|
@ -3,10 +3,7 @@
|
||||||
"to": [
|
"to": [
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
],
|
],
|
||||||
"object": {
|
"object": "http://ds9.lemmy.ml/comment/1",
|
||||||
"id": "http://ds9.lemmy.ml/comment/1",
|
|
||||||
"type": "Tombstone"
|
|
||||||
},
|
|
||||||
"cc": [
|
"cc": [
|
||||||
"http://enterprise.lemmy.ml/c/main"
|
"http://enterprise.lemmy.ml/c/main"
|
||||||
],
|
],
|
||||||
|
|
|
@ -8,10 +8,7 @@
|
||||||
"to": [
|
"to": [
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
],
|
],
|
||||||
"object": {
|
"object": "http://ds9.lemmy.ml/post/1",
|
||||||
"id": "http://ds9.lemmy.ml/post/1",
|
|
||||||
"type": "Tombstone"
|
|
||||||
},
|
|
||||||
"cc": [
|
"cc": [
|
||||||
"http://enterprise.lemmy.ml/c/main"
|
"http://enterprise.lemmy.ml/c/main"
|
||||||
],
|
],
|
||||||
|
|
|
@ -8,10 +8,7 @@
|
||||||
"to": [
|
"to": [
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
],
|
],
|
||||||
"object": {
|
"object": "http://ds9.lemmy.ml/comment/1",
|
||||||
"id": "http://ds9.lemmy.ml/comment/1",
|
|
||||||
"type": "Tombstone"
|
|
||||||
},
|
|
||||||
"cc": [
|
"cc": [
|
||||||
"http://enterprise.lemmy.ml/c/main"
|
"http://enterprise.lemmy.ml/c/main"
|
||||||
],
|
],
|
||||||
|
|
26
crates/apub/assets/mastodon/activities/delete.json
Normal file
26
crates/apub/assets/mastodon/activities/delete.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
{
|
||||||
|
"ostatus": "http://ostatus.org#",
|
||||||
|
"atomUri": "ostatus:atomUri"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "https://mastodon.madrid/users/felix/statuses/107773559874184870#delete",
|
||||||
|
"type": "Delete",
|
||||||
|
"actor": "https://mastodon.madrid/users/felix",
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"object": {
|
||||||
|
"id": "https://mastodon.madrid/users/felix/statuses/107773559874184870",
|
||||||
|
"type": "Tombstone",
|
||||||
|
"atomUri": "https://mastodon.madrid/users/felix/statuses/107773559874184870"
|
||||||
|
},
|
||||||
|
"signature": {
|
||||||
|
"type": "RsaSignature2017",
|
||||||
|
"creator": "https://mastodon.madrid/users/felix#main-key",
|
||||||
|
"created": "2022-02-10T11:54:18Z",
|
||||||
|
"signatureValue": "NjGnbkvouSP/cSusR7+sz39iEYxWXCu6nFmBXU3t8ETPkmbpMF5ASeJixXvpTOqbOfkMoWfXncw+jDsbqZ3ELaHGG1gZ5wHWym7mk7YCjQokpF3oPhTWmlEJCVKgewXMrfI4Ok8GGsUMGzuki9EyBDGc/UNBMEAhcxV5Huu7QSQDowcbIwxS3ImxFmtKFceh6mv/kMiXUerCgkYSm6rYZeXZGMTUpvcn9gP6X6Ed6UsrLjCSb3Fj0Naz7LHtzZXRSZDZF/SX2Vw/xKJIgEGzSCv+LKZGvEEkK8PPfMJJhi8cBJebkqOnBGtE6gYK2z2cm/oGorZtXU2L05pXmLAlYQ=="
|
||||||
|
}
|
||||||
|
}
|
35
crates/apub/assets/pleroma/activities/delete.json
Normal file
35
crates/apub/assets/pleroma/activities/delete.json
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://greenish.red/schemas/litepub-0.1.jsonld",
|
||||||
|
{
|
||||||
|
"@language": "und"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actor": "https://greenish.red/users/vpzom",
|
||||||
|
"attachment": [],
|
||||||
|
"attributedTo": "https://greenish.red/users/vpzom",
|
||||||
|
"cc": [],
|
||||||
|
"conversation": null,
|
||||||
|
"id": "https://greenish.red/activities/52f0b259-596e-429f-8a1b-c0b455f8932b",
|
||||||
|
"object": "https://greenish.red/objects/38e2b983-ebf5-4387-9bc2-3b80305469c9",
|
||||||
|
"tag": [
|
||||||
|
{
|
||||||
|
"href": "https://voyager.lemmy.ml/c/main",
|
||||||
|
"name": "@main@voyager.lemmy.ml",
|
||||||
|
"type": "Mention"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "https://voyager.lemmy.ml/u/dess_voy_41u2",
|
||||||
|
"name": "@dess_voy_41u2@voyager.lemmy.ml",
|
||||||
|
"type": "Mention"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"to": [
|
||||||
|
"https://greenish.red/users/vpzom/followers",
|
||||||
|
"https://voyager.lemmy.ml/c/main",
|
||||||
|
"https://voyager.lemmy.ml/u/dess_voy_41u2",
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"type": "Delete"
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
activities::{
|
activities::{
|
||||||
check_community_deleted_or_removed,
|
check_community_deleted_or_removed,
|
||||||
comment::get_notif_recipients,
|
|
||||||
community::{announce::GetCommunity, send_activity_in_community},
|
community::{announce::GetCommunity, send_activity_in_community},
|
||||||
|
create_or_update::get_comment_notif_recipients,
|
||||||
generate_activity_id,
|
generate_activity_id,
|
||||||
verify_activity,
|
verify_activity,
|
||||||
verify_is_public,
|
verify_is_public,
|
||||||
|
@ -114,7 +114,7 @@ impl ActivityHandler for CreateOrUpdateComment {
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let comment = ApubComment::from_apub(self.object, context, request_counter).await?;
|
let comment = ApubComment::from_apub(self.object, context, request_counter).await?;
|
||||||
let do_send_email = self.kind == CreateOrUpdateType::Create;
|
let do_send_email = self.kind == CreateOrUpdateType::Create;
|
||||||
let recipients = get_notif_recipients(
|
let recipients = get_comment_notif_recipients(
|
||||||
&self.actor,
|
&self.actor,
|
||||||
&comment,
|
&comment,
|
||||||
do_send_email,
|
do_send_email,
|
|
@ -9,10 +9,12 @@ use lemmy_db_schema::{
|
||||||
use lemmy_utils::{utils::scrape_text_for_mentions, LemmyError};
|
use lemmy_utils::{utils::scrape_text_for_mentions, LemmyError};
|
||||||
use lemmy_websocket::{send::send_local_notifs, LemmyContext};
|
use lemmy_websocket::{send::send_local_notifs, LemmyContext};
|
||||||
|
|
||||||
pub mod create_or_update;
|
pub mod comment;
|
||||||
|
pub mod post;
|
||||||
|
pub mod private_message;
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
async fn get_notif_recipients(
|
async fn get_comment_notif_recipients(
|
||||||
actor: &ObjectId<ApubPerson>,
|
actor: &ObjectId<ApubPerson>,
|
||||||
comment: &Comment,
|
comment: &Comment,
|
||||||
do_send_email: bool,
|
do_send_email: bool,
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
|
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
|
||||||
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
|
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
|
||||||
protocol::activities::{
|
protocol::activities::{
|
||||||
private_message::create_or_update::CreateOrUpdatePrivateMessage,
|
create_or_update::private_message::CreateOrUpdatePrivateMessage,
|
||||||
CreateOrUpdateType,
|
CreateOrUpdateType,
|
||||||
},
|
},
|
||||||
};
|
};
|
|
@ -1,22 +1,17 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
activities::{
|
activities::{
|
||||||
community::{announce::GetCommunity, send_activity_in_community},
|
community::announce::GetCommunity,
|
||||||
deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
|
deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
|
||||||
generate_activity_id,
|
generate_activity_id,
|
||||||
verify_activity,
|
verify_activity,
|
||||||
verify_is_public,
|
|
||||||
},
|
},
|
||||||
activity_lists::AnnouncableActivities,
|
|
||||||
objects::{community::ApubCommunity, person::ApubPerson},
|
objects::{community::ApubCommunity, person::ApubPerson},
|
||||||
protocol::activities::deletion::delete::Delete,
|
protocol::activities::deletion::delete::{Delete, IdOrNestedObject},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::{activity::DeleteType, public};
|
use activitystreams_kinds::activity::DeleteType;
|
||||||
|
use anyhow::anyhow;
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub_lib::{
|
use lemmy_apub_lib::{data::Data, object_id::ObjectId, traits::ActivityHandler};
|
||||||
data::Data,
|
|
||||||
object_id::ObjectId,
|
|
||||||
traits::{ActivityHandler, ActorType},
|
|
||||||
};
|
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
comment::Comment,
|
comment::Comment,
|
||||||
|
@ -29,6 +24,7 @@ use lemmy_db_schema::{
|
||||||
ModRemovePost,
|
ModRemovePost,
|
||||||
ModRemovePostForm,
|
ModRemovePostForm,
|
||||||
},
|
},
|
||||||
|
person::Person,
|
||||||
post::Post,
|
post::Post,
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
|
@ -51,18 +47,8 @@ impl ActivityHandler for Delete {
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
verify_is_public(&self.to, &[])?;
|
|
||||||
verify_activity(&self.id, self.actor.inner(), &context.settings())?;
|
verify_activity(&self.id, self.actor.inner(), &context.settings())?;
|
||||||
let community = self.get_community(context, request_counter).await?;
|
verify_delete_activity(self, self.summary.is_some(), context, request_counter).await?;
|
||||||
verify_delete_activity(
|
|
||||||
&self.object.id,
|
|
||||||
&self.actor,
|
|
||||||
&community,
|
|
||||||
self.summary.is_some(),
|
|
||||||
context,
|
|
||||||
request_counter,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,53 +68,50 @@ impl ActivityHandler for Delete {
|
||||||
};
|
};
|
||||||
receive_remove_action(
|
receive_remove_action(
|
||||||
&self.actor,
|
&self.actor,
|
||||||
&self.object.id,
|
self.object.id(),
|
||||||
reason,
|
reason,
|
||||||
context,
|
context,
|
||||||
request_counter,
|
request_counter,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
receive_delete_action(&self.object.id, &self.actor, true, context, request_counter).await
|
receive_delete_action(
|
||||||
|
self.object.id(),
|
||||||
|
&self.actor,
|
||||||
|
true,
|
||||||
|
context,
|
||||||
|
request_counter,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Delete {
|
impl Delete {
|
||||||
pub(in crate::activities::deletion) fn new(
|
pub(in crate::activities::deletion) fn new(
|
||||||
actor: &ApubPerson,
|
actor: &Person,
|
||||||
object: DeletableObjects,
|
object: DeletableObjects,
|
||||||
|
to: Url,
|
||||||
|
community: Option<&Community>,
|
||||||
summary: Option<String>,
|
summary: Option<String>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<Delete, LemmyError> {
|
) -> Result<Delete, LemmyError> {
|
||||||
Ok(Delete {
|
let id = generate_activity_id(
|
||||||
actor: ObjectId::new(actor.actor_id()),
|
|
||||||
to: vec![public()],
|
|
||||||
object: object.to_tombstone()?,
|
|
||||||
kind: DeleteType::Delete,
|
|
||||||
summary,
|
|
||||||
id: generate_activity_id(
|
|
||||||
DeleteType::Delete,
|
DeleteType::Delete,
|
||||||
&context.settings().get_protocol_and_hostname(),
|
&context.settings().get_protocol_and_hostname(),
|
||||||
)?,
|
)?;
|
||||||
|
let cc: Option<Url> = community.map(|c| c.actor_id.clone().into());
|
||||||
|
Ok(Delete {
|
||||||
|
actor: ObjectId::new(actor.actor_id.clone()),
|
||||||
|
to: vec![to],
|
||||||
|
object: IdOrNestedObject::Id(object.id()),
|
||||||
|
cc: cc.into_iter().collect(),
|
||||||
|
kind: DeleteType::Delete,
|
||||||
|
summary,
|
||||||
|
id,
|
||||||
unparsed: Default::default(),
|
unparsed: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
pub(in crate::activities::deletion) async fn send(
|
|
||||||
actor: &ApubPerson,
|
|
||||||
community: &ApubCommunity,
|
|
||||||
object: DeletableObjects,
|
|
||||||
summary: Option<String>,
|
|
||||||
context: &LemmyContext,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let delete = Delete::new(actor, object, summary, context)?;
|
|
||||||
let delete_id = delete.id.clone();
|
|
||||||
|
|
||||||
let activity = AnnouncableActivities::Delete(delete);
|
|
||||||
send_activity_in_community(activity, &delete_id, actor, community, vec![], context).await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
|
@ -204,6 +187,7 @@ pub(in crate::activities) async fn receive_remove_action(
|
||||||
|
|
||||||
send_comment_ws_message_simple(removed_comment.id, RemoveComment, context).await?;
|
send_comment_ws_message_simple(removed_comment.id, RemoveComment, context).await?;
|
||||||
}
|
}
|
||||||
|
DeletableObjects::PrivateMessage(_) => unimplemented!(),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -216,13 +200,16 @@ impl GetCommunity for Delete {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
_request_counter: &mut i32,
|
_request_counter: &mut i32,
|
||||||
) -> Result<ApubCommunity, LemmyError> {
|
) -> Result<ApubCommunity, LemmyError> {
|
||||||
let community_id = match DeletableObjects::read_from_db(&self.object.id, context).await? {
|
let community_id = match DeletableObjects::read_from_db(self.object.id(), context).await? {
|
||||||
DeletableObjects::Community(c) => c.id,
|
DeletableObjects::Community(c) => c.id,
|
||||||
DeletableObjects::Comment(c) => {
|
DeletableObjects::Comment(c) => {
|
||||||
let post = blocking(context.pool(), move |conn| Post::read(conn, c.post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, c.post_id)).await??;
|
||||||
post.community_id
|
post.community_id
|
||||||
}
|
}
|
||||||
DeletableObjects::Post(p) => p.community_id,
|
DeletableObjects::Post(p) => p.community_id,
|
||||||
|
DeletableObjects::PrivateMessage(_) => {
|
||||||
|
return Err(anyhow!("Private message is not part of community").into())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let community = blocking(context.pool(), move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read(conn, community_id)
|
Community::read(conn, community_id)
|
||||||
|
|
|
@ -1,62 +1,117 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
activities::{verify_mod_action, verify_person_in_community},
|
activities::{
|
||||||
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
community::{announce::GetCommunity, send_activity_in_community},
|
||||||
protocol::{
|
send_lemmy_activity,
|
||||||
activities::deletion::{delete::Delete, undo_delete::UndoDelete},
|
verify_is_public,
|
||||||
objects::tombstone::Tombstone,
|
verify_mod_action,
|
||||||
|
verify_person,
|
||||||
|
verify_person_in_community,
|
||||||
},
|
},
|
||||||
|
activity_lists::AnnouncableActivities,
|
||||||
|
objects::{
|
||||||
|
comment::ApubComment,
|
||||||
|
community::ApubCommunity,
|
||||||
|
person::ApubPerson,
|
||||||
|
post::ApubPost,
|
||||||
|
private_message::ApubPrivateMessage,
|
||||||
|
},
|
||||||
|
protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
|
||||||
};
|
};
|
||||||
|
use activitystreams_kinds::public;
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject, verify::verify_domains_match};
|
use lemmy_apub_lib::{
|
||||||
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
|
object_id::ObjectId,
|
||||||
|
traits::{ActorType, ApubObject},
|
||||||
|
verify::verify_domains_match,
|
||||||
|
};
|
||||||
|
use lemmy_db_schema::{
|
||||||
|
source::{
|
||||||
|
comment::Comment,
|
||||||
|
community::Community,
|
||||||
|
person::Person,
|
||||||
|
post::Post,
|
||||||
|
private_message::PrivateMessage,
|
||||||
|
},
|
||||||
|
traits::Crud,
|
||||||
|
};
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
|
send::{
|
||||||
|
send_comment_ws_message_simple,
|
||||||
|
send_community_ws_message,
|
||||||
|
send_pm_ws_message,
|
||||||
|
send_post_ws_message,
|
||||||
|
},
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
UserOperationCrud,
|
UserOperationCrud,
|
||||||
};
|
};
|
||||||
|
use std::ops::Deref;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
pub mod undo_delete;
|
pub mod undo_delete;
|
||||||
|
|
||||||
|
/// Parameter `reason` being set indicates that this is a removal by a mod. If its unset, this
|
||||||
|
/// action was done by a normal user.
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn send_apub_delete(
|
pub async fn send_apub_delete_in_community(
|
||||||
actor: &ApubPerson,
|
actor: Person,
|
||||||
community: &ApubCommunity,
|
community: Community,
|
||||||
object: DeletableObjects,
|
object: DeletableObjects,
|
||||||
|
reason: Option<String>,
|
||||||
deleted: bool,
|
deleted: bool,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
if deleted {
|
let (id, activity) = if deleted {
|
||||||
Delete::send(actor, community, object, None, context).await
|
let delete = Delete::new(&actor, object, public(), Some(&community), reason, context)?;
|
||||||
|
(delete.id.clone(), AnnouncableActivities::Delete(delete))
|
||||||
} else {
|
} else {
|
||||||
UndoDelete::send(actor, community, object, None, context).await
|
let undo = UndoDelete::new(&actor, object, public(), Some(&community), reason, context)?;
|
||||||
}
|
(undo.id.clone(), AnnouncableActivities::UndoDelete(undo))
|
||||||
|
};
|
||||||
|
send_activity_in_community(
|
||||||
|
activity,
|
||||||
|
&id,
|
||||||
|
&ApubPerson::from(actor),
|
||||||
|
&community.into(),
|
||||||
|
vec![],
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove reason is actually optional in lemmy. we set an empty string in that case, but its
|
|
||||||
// ugly
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn send_apub_remove(
|
pub async fn send_apub_delete_private_message(
|
||||||
actor: &ApubPerson,
|
actor: &ApubPerson,
|
||||||
community: &ApubCommunity,
|
pm: PrivateMessage,
|
||||||
object: DeletableObjects,
|
deleted: bool,
|
||||||
reason: String,
|
|
||||||
removed: bool,
|
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
if removed {
|
let recipient_id = pm.recipient_id;
|
||||||
Delete::send(actor, community, object, Some(reason), context).await
|
let recipient: ApubPerson =
|
||||||
|
blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
|
||||||
|
.await??
|
||||||
|
.into();
|
||||||
|
|
||||||
|
let deletable = DeletableObjects::PrivateMessage(Box::new(pm.into()));
|
||||||
|
let inbox = vec![recipient.shared_inbox_or_inbox_url()];
|
||||||
|
if deleted {
|
||||||
|
let delete = Delete::new(actor, deletable, recipient.actor_id(), None, None, context)?;
|
||||||
|
let id = delete.id.clone();
|
||||||
|
send_lemmy_activity(context, &delete, &id, actor, inbox, true).await?;
|
||||||
} else {
|
} else {
|
||||||
UndoDelete::send(actor, community, object, Some(reason), context).await
|
let undo = UndoDelete::new(actor, deletable, recipient.actor_id(), None, None, context)?;
|
||||||
}
|
let id = undo.id.clone();
|
||||||
|
send_lemmy_activity(context, &undo, &id, actor, inbox, true).await?;
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum DeletableObjects {
|
pub enum DeletableObjects {
|
||||||
Community(Box<ApubCommunity>),
|
Community(Box<ApubCommunity>),
|
||||||
Comment(Box<ApubComment>),
|
Comment(Box<ApubComment>),
|
||||||
Post(Box<ApubPost>),
|
Post(Box<ApubPost>),
|
||||||
|
PrivateMessage(Box<ApubPrivateMessage>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeletableObjects {
|
impl DeletableObjects {
|
||||||
|
@ -74,43 +129,47 @@ impl DeletableObjects {
|
||||||
if let Some(c) = ApubComment::read_from_apub_id(ap_id.clone(), context).await? {
|
if let Some(c) = ApubComment::read_from_apub_id(ap_id.clone(), context).await? {
|
||||||
return Ok(DeletableObjects::Comment(Box::new(c)));
|
return Ok(DeletableObjects::Comment(Box::new(c)));
|
||||||
}
|
}
|
||||||
|
if let Some(p) = ApubPrivateMessage::read_from_apub_id(ap_id.clone(), context).await? {
|
||||||
|
return Ok(DeletableObjects::PrivateMessage(Box::new(p)));
|
||||||
|
}
|
||||||
Err(diesel::NotFound.into())
|
Err(diesel::NotFound.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn to_tombstone(&self) -> Result<Tombstone, LemmyError> {
|
pub(crate) fn id(&self) -> Url {
|
||||||
match self {
|
match self {
|
||||||
DeletableObjects::Community(c) => c.to_tombstone(),
|
DeletableObjects::Community(c) => c.actor_id(),
|
||||||
DeletableObjects::Comment(c) => c.to_tombstone(),
|
DeletableObjects::Comment(c) => c.ap_id.clone().into(),
|
||||||
DeletableObjects::Post(p) => p.to_tombstone(),
|
DeletableObjects::Post(p) => p.ap_id.clone().into(),
|
||||||
|
DeletableObjects::PrivateMessage(p) => p.ap_id.clone().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub(in crate::activities) async fn verify_delete_activity(
|
pub(in crate::activities) async fn verify_delete_activity(
|
||||||
object: &Url,
|
activity: &Delete,
|
||||||
actor: &ObjectId<ApubPerson>,
|
|
||||||
community: &ApubCommunity,
|
|
||||||
is_mod_action: bool,
|
is_mod_action: bool,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let object = DeletableObjects::read_from_db(object, context).await?;
|
let object = DeletableObjects::read_from_db(activity.object.id(), context).await?;
|
||||||
match object {
|
match object {
|
||||||
DeletableObjects::Community(community) => {
|
DeletableObjects::Community(community) => {
|
||||||
|
verify_is_public(&activity.to, &[])?;
|
||||||
if community.local {
|
if community.local {
|
||||||
// can only do this check for local community, in remote case it would try to fetch the
|
// can only do this check for local community, in remote case it would try to fetch the
|
||||||
// deleted community (which fails)
|
// deleted community (which fails)
|
||||||
verify_person_in_community(actor, &community, context, request_counter).await?;
|
verify_person_in_community(&activity.actor, &community, context, request_counter).await?;
|
||||||
}
|
}
|
||||||
// community deletion is always a mod (or admin) action
|
// community deletion is always a mod (or admin) action
|
||||||
verify_mod_action(actor, &community, context, request_counter).await?;
|
verify_mod_action(&activity.actor, &community, context, request_counter).await?;
|
||||||
}
|
}
|
||||||
DeletableObjects::Post(p) => {
|
DeletableObjects::Post(p) => {
|
||||||
verify_delete_activity_post_or_comment(
|
verify_is_public(&activity.to, &[])?;
|
||||||
actor,
|
verify_delete_post_or_comment(
|
||||||
|
&activity.actor,
|
||||||
&p.ap_id.clone().into(),
|
&p.ap_id.clone().into(),
|
||||||
community,
|
&activity.get_community(context, request_counter).await?,
|
||||||
is_mod_action,
|
is_mod_action,
|
||||||
context,
|
context,
|
||||||
request_counter,
|
request_counter,
|
||||||
|
@ -118,22 +177,27 @@ pub(in crate::activities) async fn verify_delete_activity(
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
DeletableObjects::Comment(c) => {
|
DeletableObjects::Comment(c) => {
|
||||||
verify_delete_activity_post_or_comment(
|
verify_is_public(&activity.to, &[])?;
|
||||||
actor,
|
verify_delete_post_or_comment(
|
||||||
|
&activity.actor,
|
||||||
&c.ap_id.clone().into(),
|
&c.ap_id.clone().into(),
|
||||||
community,
|
&activity.get_community(context, request_counter).await?,
|
||||||
is_mod_action,
|
is_mod_action,
|
||||||
context,
|
context,
|
||||||
request_counter,
|
request_counter,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
DeletableObjects::PrivateMessage(_) => {
|
||||||
|
verify_person(&activity.actor, context, request_counter).await?;
|
||||||
|
verify_domains_match(activity.actor.inner(), activity.object.id())?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
async fn verify_delete_activity_post_or_comment(
|
async fn verify_delete_post_or_comment(
|
||||||
actor: &ObjectId<ApubPerson>,
|
actor: &ObjectId<ApubPerson>,
|
||||||
object_id: &Url,
|
object_id: &Url,
|
||||||
community: &ApubCommunity,
|
community: &ApubCommunity,
|
||||||
|
@ -152,8 +216,6 @@ async fn verify_delete_activity_post_or_comment(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write deletion or restoring of an object to the database, and send websocket message.
|
/// Write deletion or restoring of an object to the database, and send websocket message.
|
||||||
/// TODO: we should do something similar for receive_remove_action(), but its much more complicated
|
|
||||||
/// because of the mod log
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
async fn receive_delete_action(
|
async fn receive_delete_action(
|
||||||
object: &Url,
|
object: &Url,
|
||||||
|
@ -165,11 +227,14 @@ async fn receive_delete_action(
|
||||||
match DeletableObjects::read_from_db(object, context).await? {
|
match DeletableObjects::read_from_db(object, context).await? {
|
||||||
DeletableObjects::Community(community) => {
|
DeletableObjects::Community(community) => {
|
||||||
if community.local {
|
if community.local {
|
||||||
let mod_ = actor
|
let mod_: Person = actor
|
||||||
.dereference(context, context.client(), request_counter)
|
.dereference(context, context.client(), request_counter)
|
||||||
.await?;
|
.await?
|
||||||
|
.deref()
|
||||||
|
.clone();
|
||||||
let object = DeletableObjects::Community(community.clone());
|
let object = DeletableObjects::Community(community.clone());
|
||||||
send_apub_delete(&mod_, &community.clone(), object, true, context).await?;
|
let c: Community = community.deref().deref().clone();
|
||||||
|
send_apub_delete_in_community(mod_, c, object, None, true, context).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let community = blocking(context.pool(), move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
@ -215,6 +280,20 @@ async fn receive_delete_action(
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DeletableObjects::PrivateMessage(pm) => {
|
||||||
|
let deleted_private_message = blocking(context.pool(), move |conn| {
|
||||||
|
PrivateMessage::update_deleted(conn, pm.id, deleted)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
send_pm_ws_message(
|
||||||
|
deleted_private_message.id,
|
||||||
|
UserOperationCrud::DeletePrivateMessage,
|
||||||
|
None,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,17 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
activities::{
|
activities::{
|
||||||
community::{announce::GetCommunity, send_activity_in_community},
|
community::announce::GetCommunity,
|
||||||
deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
|
deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
|
||||||
generate_activity_id,
|
generate_activity_id,
|
||||||
verify_activity,
|
verify_activity,
|
||||||
verify_is_public,
|
|
||||||
},
|
},
|
||||||
activity_lists::AnnouncableActivities,
|
objects::community::ApubCommunity,
|
||||||
objects::{community::ApubCommunity, person::ApubPerson},
|
|
||||||
protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
|
protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::{activity::UndoType, public};
|
use activitystreams_kinds::activity::UndoType;
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub_lib::{
|
use lemmy_apub_lib::{data::Data, object_id::ObjectId, traits::ActivityHandler};
|
||||||
data::Data,
|
use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post};
|
||||||
object_id::ObjectId,
|
|
||||||
traits::{ActivityHandler, ActorType},
|
|
||||||
};
|
|
||||||
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
|
send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
|
||||||
|
@ -36,14 +30,10 @@ impl ActivityHandler for UndoDelete {
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
verify_is_public(&self.to, &self.cc)?;
|
|
||||||
verify_activity(&self.id, self.actor.inner(), &context.settings())?;
|
verify_activity(&self.id, self.actor.inner(), &context.settings())?;
|
||||||
self.object.verify(context, request_counter).await?;
|
self.object.verify(context, request_counter).await?;
|
||||||
let community = self.get_community(context, request_counter).await?;
|
|
||||||
verify_delete_activity(
|
verify_delete_activity(
|
||||||
&self.object.object.id,
|
&self.object,
|
||||||
&self.actor,
|
|
||||||
&community,
|
|
||||||
self.object.summary.is_some(),
|
self.object.summary.is_some(),
|
||||||
context,
|
context,
|
||||||
request_counter,
|
request_counter,
|
||||||
|
@ -59,10 +49,10 @@ impl ActivityHandler for UndoDelete {
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
if self.object.summary.is_some() {
|
if self.object.summary.is_some() {
|
||||||
UndoDelete::receive_undo_remove_action(&self.object.object.id, context).await
|
UndoDelete::receive_undo_remove_action(self.object.object.id(), context).await
|
||||||
} else {
|
} else {
|
||||||
receive_delete_action(
|
receive_delete_action(
|
||||||
&self.object.object.id,
|
self.object.object.id(),
|
||||||
&self.actor,
|
&self.actor,
|
||||||
false,
|
false,
|
||||||
context,
|
context,
|
||||||
|
@ -75,31 +65,30 @@ impl ActivityHandler for UndoDelete {
|
||||||
|
|
||||||
impl UndoDelete {
|
impl UndoDelete {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub(in crate::activities::deletion) async fn send(
|
pub(in crate::activities::deletion) fn new(
|
||||||
actor: &ApubPerson,
|
actor: &Person,
|
||||||
community: &ApubCommunity,
|
|
||||||
object: DeletableObjects,
|
object: DeletableObjects,
|
||||||
|
to: Url,
|
||||||
|
community: Option<&Community>,
|
||||||
summary: Option<String>,
|
summary: Option<String>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<UndoDelete, LemmyError> {
|
||||||
let object = Delete::new(actor, object, summary, context)?;
|
let object = Delete::new(actor, object, to.clone(), community, summary, context)?;
|
||||||
|
|
||||||
let id = generate_activity_id(
|
let id = generate_activity_id(
|
||||||
UndoType::Undo,
|
UndoType::Undo,
|
||||||
&context.settings().get_protocol_and_hostname(),
|
&context.settings().get_protocol_and_hostname(),
|
||||||
)?;
|
)?;
|
||||||
let undo = UndoDelete {
|
let cc: Option<Url> = community.map(|c| c.actor_id.clone().into());
|
||||||
actor: ObjectId::new(actor.actor_id()),
|
Ok(UndoDelete {
|
||||||
to: vec![public()],
|
actor: ObjectId::new(actor.actor_id.clone()),
|
||||||
|
to: vec![to],
|
||||||
object,
|
object,
|
||||||
cc: vec![community.actor_id()],
|
cc: cc.into_iter().collect(),
|
||||||
kind: UndoType::Undo,
|
kind: UndoType::Undo,
|
||||||
id: id.clone(),
|
id,
|
||||||
unparsed: Default::default(),
|
unparsed: Default::default(),
|
||||||
};
|
})
|
||||||
|
|
||||||
let activity = AnnouncableActivities::UndoDelete(undo);
|
|
||||||
send_activity_in_community(activity, &id, actor, community, vec![], context).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
|
@ -135,6 +124,7 @@ impl UndoDelete {
|
||||||
.await??;
|
.await??;
|
||||||
send_comment_ws_message_simple(removed_comment.id, EditComment, context).await?;
|
send_comment_ws_message_simple(removed_comment.id, EditComment, context).await?;
|
||||||
}
|
}
|
||||||
|
DeletableObjects::PrivateMessage(_) => unimplemented!(),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,10 @@ use url::{ParseError, Url};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod comment;
|
|
||||||
pub mod community;
|
pub mod community;
|
||||||
|
pub mod create_or_update;
|
||||||
pub mod deletion;
|
pub mod deletion;
|
||||||
pub mod following;
|
pub mod following;
|
||||||
pub mod post;
|
|
||||||
pub mod private_message;
|
|
||||||
pub mod voting;
|
pub mod voting;
|
||||||
|
|
||||||
/// 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
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
pub mod create_or_update;
|
|
|
@ -1,97 +0,0 @@
|
||||||
use crate::{
|
|
||||||
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
|
|
||||||
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
|
|
||||||
protocol::activities::private_message::delete::DeletePrivateMessage,
|
|
||||||
};
|
|
||||||
use activitystreams_kinds::activity::DeleteType;
|
|
||||||
use lemmy_api_common::blocking;
|
|
||||||
use lemmy_apub_lib::{
|
|
||||||
data::Data,
|
|
||||||
object_id::ObjectId,
|
|
||||||
traits::{ActivityHandler, ActorType},
|
|
||||||
verify::verify_domains_match,
|
|
||||||
};
|
|
||||||
use lemmy_db_schema::{
|
|
||||||
source::{person::Person, private_message::PrivateMessage},
|
|
||||||
traits::Crud,
|
|
||||||
};
|
|
||||||
use lemmy_utils::LemmyError;
|
|
||||||
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
|
|
||||||
|
|
||||||
impl DeletePrivateMessage {
|
|
||||||
pub(in crate::activities::private_message) fn new(
|
|
||||||
actor: &ApubPerson,
|
|
||||||
pm: &PrivateMessage,
|
|
||||||
context: &LemmyContext,
|
|
||||||
) -> Result<DeletePrivateMessage, LemmyError> {
|
|
||||||
Ok(DeletePrivateMessage {
|
|
||||||
actor: ObjectId::new(actor.actor_id()),
|
|
||||||
to: [ObjectId::new(actor.actor_id())],
|
|
||||||
object: ObjectId::new(pm.ap_id.clone()),
|
|
||||||
kind: DeleteType::Delete,
|
|
||||||
id: generate_activity_id(
|
|
||||||
DeleteType::Delete,
|
|
||||||
&context.settings().get_protocol_and_hostname(),
|
|
||||||
)?,
|
|
||||||
unparsed: Default::default(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
pub async fn send(
|
|
||||||
actor: &ApubPerson,
|
|
||||||
pm: &ApubPrivateMessage,
|
|
||||||
context: &LemmyContext,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let delete = DeletePrivateMessage::new(actor, pm, context)?;
|
|
||||||
let delete_id = delete.id.clone();
|
|
||||||
|
|
||||||
let recipient_id = pm.recipient_id;
|
|
||||||
let recipient: ApubPerson =
|
|
||||||
blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
|
|
||||||
.await??
|
|
||||||
.into();
|
|
||||||
let inbox = vec![recipient.shared_inbox_or_inbox_url()];
|
|
||||||
send_lemmy_activity(context, &delete, &delete_id, actor, inbox, true).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
|
||||||
impl ActivityHandler for DeletePrivateMessage {
|
|
||||||
type DataType = LemmyContext;
|
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
async fn verify(
|
|
||||||
&self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
verify_activity(&self.id, self.actor.inner(), &context.settings())?;
|
|
||||||
verify_person(&self.actor, context, request_counter).await?;
|
|
||||||
verify_domains_match(self.actor.inner(), self.object.inner())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
async fn receive(
|
|
||||||
self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
_request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let private_message = self.object.dereference_local(context).await?;
|
|
||||||
let deleted_private_message = blocking(context.pool(), move |conn| {
|
|
||||||
PrivateMessage::update_deleted(conn, private_message.id, true)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
|
|
||||||
send_pm_ws_message(
|
|
||||||
deleted_private_message.id,
|
|
||||||
UserOperationCrud::DeletePrivateMessage,
|
|
||||||
None,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
pub mod create_or_update;
|
|
||||||
pub mod delete;
|
|
||||||
pub mod undo_delete;
|
|
|
@ -1,97 +0,0 @@
|
||||||
use crate::{
|
|
||||||
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
|
|
||||||
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
|
|
||||||
protocol::activities::private_message::{
|
|
||||||
delete::DeletePrivateMessage,
|
|
||||||
undo_delete::UndoDeletePrivateMessage,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use activitystreams_kinds::activity::UndoType;
|
|
||||||
use lemmy_api_common::blocking;
|
|
||||||
use lemmy_apub_lib::{
|
|
||||||
data::Data,
|
|
||||||
object_id::ObjectId,
|
|
||||||
traits::{ActivityHandler, ActorType},
|
|
||||||
verify::{verify_domains_match, verify_urls_match},
|
|
||||||
};
|
|
||||||
use lemmy_db_schema::{
|
|
||||||
source::{person::Person, private_message::PrivateMessage},
|
|
||||||
traits::Crud,
|
|
||||||
};
|
|
||||||
use lemmy_utils::LemmyError;
|
|
||||||
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
|
|
||||||
|
|
||||||
impl UndoDeletePrivateMessage {
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
pub async fn send(
|
|
||||||
actor: &ApubPerson,
|
|
||||||
pm: &ApubPrivateMessage,
|
|
||||||
context: &LemmyContext,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let recipient_id = pm.recipient_id;
|
|
||||||
let recipient: ApubPerson =
|
|
||||||
blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
|
|
||||||
.await??
|
|
||||||
.into();
|
|
||||||
|
|
||||||
let object = DeletePrivateMessage::new(actor, pm, context)?;
|
|
||||||
let id = generate_activity_id(
|
|
||||||
UndoType::Undo,
|
|
||||||
&context.settings().get_protocol_and_hostname(),
|
|
||||||
)?;
|
|
||||||
let undo = UndoDeletePrivateMessage {
|
|
||||||
actor: ObjectId::new(actor.actor_id()),
|
|
||||||
to: [ObjectId::new(recipient.actor_id())],
|
|
||||||
object,
|
|
||||||
kind: UndoType::Undo,
|
|
||||||
id: id.clone(),
|
|
||||||
unparsed: Default::default(),
|
|
||||||
};
|
|
||||||
let inbox = vec![recipient.shared_inbox_or_inbox_url()];
|
|
||||||
send_lemmy_activity(context, &undo, &id, actor, inbox, true).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
|
||||||
impl ActivityHandler for UndoDeletePrivateMessage {
|
|
||||||
type DataType = LemmyContext;
|
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
async fn verify(
|
|
||||||
&self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
verify_activity(&self.id, self.actor.inner(), &context.settings())?;
|
|
||||||
verify_person(&self.actor, context, request_counter).await?;
|
|
||||||
verify_urls_match(self.actor.inner(), self.object.actor.inner())?;
|
|
||||||
verify_domains_match(self.actor.inner(), self.object.object.inner())?;
|
|
||||||
self.object.verify(context, request_counter).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
async fn receive(
|
|
||||||
self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
_request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let ap_id = self.object.object.clone();
|
|
||||||
let private_message = ap_id.dereference_local(context).await?;
|
|
||||||
|
|
||||||
let deleted_private_message = blocking(context.pool(), move |conn| {
|
|
||||||
PrivateMessage::update_deleted(conn, private_message.id, false)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
|
|
||||||
send_pm_ws_message(
|
|
||||||
deleted_private_message.id,
|
|
||||||
UserOperationCrud::EditPrivateMessage,
|
|
||||||
None,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,18 +11,17 @@ use crate::{
|
||||||
report::Report,
|
report::Report,
|
||||||
update::UpdateCommunity,
|
update::UpdateCommunity,
|
||||||
},
|
},
|
||||||
create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost},
|
create_or_update::{
|
||||||
|
comment::CreateOrUpdateComment,
|
||||||
|
post::CreateOrUpdatePost,
|
||||||
|
private_message::CreateOrUpdatePrivateMessage,
|
||||||
|
},
|
||||||
deletion::{delete::Delete, undo_delete::UndoDelete},
|
deletion::{delete::Delete, undo_delete::UndoDelete},
|
||||||
following::{
|
following::{
|
||||||
accept::AcceptFollowCommunity,
|
accept::AcceptFollowCommunity,
|
||||||
follow::FollowCommunity,
|
follow::FollowCommunity,
|
||||||
undo_follow::UndoFollowCommunity,
|
undo_follow::UndoFollowCommunity,
|
||||||
},
|
},
|
||||||
private_message::{
|
|
||||||
create_or_update::CreateOrUpdatePrivateMessage,
|
|
||||||
delete::DeletePrivateMessage,
|
|
||||||
undo_delete::UndoDeletePrivateMessage,
|
|
||||||
},
|
|
||||||
voting::{undo_vote::UndoVote, vote::Vote},
|
voting::{undo_vote::UndoVote, vote::Vote},
|
||||||
},
|
},
|
||||||
objects::page::Page,
|
objects::page::Page,
|
||||||
|
@ -61,8 +60,8 @@ pub enum PersonInboxActivities {
|
||||||
/// Some activities can also be sent from user to user, eg a comment with mentions
|
/// Some activities can also be sent from user to user, eg a comment with mentions
|
||||||
AnnouncableActivities(AnnouncableActivities),
|
AnnouncableActivities(AnnouncableActivities),
|
||||||
CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage),
|
CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage),
|
||||||
DeletePrivateMessage(DeletePrivateMessage),
|
Delete(Delete),
|
||||||
UndoDeletePrivateMessage(UndoDeletePrivateMessage),
|
UndoDelete(UndoDelete),
|
||||||
AnnounceActivity(AnnounceActivity),
|
AnnounceActivity(AnnounceActivity),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,12 +84,16 @@ pub(in crate::http) async fn receive_group_inbox(
|
||||||
let res = receive_activity(request, activity.clone(), activity_data, context).await?;
|
let res = receive_activity(request, activity.clone(), activity_data, context).await?;
|
||||||
|
|
||||||
if let GroupInboxActivities::AnnouncableActivities(announcable) = activity {
|
if let GroupInboxActivities::AnnouncableActivities(announcable) = activity {
|
||||||
let community = announcable.get_community(context, &mut 0).await?;
|
// Ignore failures in get_community(). those happen because Delete/PrivateMessage is not in a
|
||||||
verify_person_in_community(&actor_id, &community, context, &mut 0).await?;
|
// community, but looks identical to Delete/Post or Delete/Comment which are in a community.
|
||||||
|
let community = announcable.get_community(context, &mut 0).await;
|
||||||
|
if let Ok(community) = community {
|
||||||
if community.local {
|
if community.local {
|
||||||
|
verify_person_in_community(&actor_id, &community, context, &mut 0).await?;
|
||||||
AnnounceActivity::send(*announcable, &community, context).await?;
|
AnnounceActivity::send(*announcable, &community, context).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod comment;
|
pub mod comment;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
|
pub mod private_message;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -7,7 +8,11 @@ mod tests {
|
||||||
context::WithContext,
|
context::WithContext,
|
||||||
objects::tests::file_to_json_object,
|
objects::tests::file_to_json_object,
|
||||||
protocol::{
|
protocol::{
|
||||||
activities::create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost},
|
activities::create_or_update::{
|
||||||
|
comment::CreateOrUpdateComment,
|
||||||
|
post::CreateOrUpdatePost,
|
||||||
|
private_message::CreateOrUpdatePrivateMessage,
|
||||||
|
},
|
||||||
tests::test_parse_lemmy_item,
|
tests::test_parse_lemmy_item,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -26,6 +31,10 @@ mod tests {
|
||||||
"assets/lemmy/activities/create_or_update/create_note.json",
|
"assets/lemmy/activities/create_or_update/create_note.json",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
test_parse_lemmy_item::<CreateOrUpdatePrivateMessage>(
|
||||||
|
"assets/lemmy/activities/create_or_update/create_private_message.json",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
file_to_json_object::<WithContext<CreateOrUpdateComment>>(
|
file_to_json_object::<WithContext<CreateOrUpdateComment>>(
|
||||||
"assets/pleroma/activities/create_note.json",
|
"assets/pleroma/activities/create_note.json",
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::{
|
use crate::{objects::person::ApubPerson, protocol::Unparsed};
|
||||||
objects::person::ApubPerson,
|
|
||||||
protocol::{objects::tombstone::Tombstone, Unparsed},
|
|
||||||
};
|
|
||||||
use activitystreams_kinds::activity::DeleteType;
|
use activitystreams_kinds::activity::DeleteType;
|
||||||
use lemmy_apub_lib::object_id::ObjectId;
|
use lemmy_apub_lib::object_id::ObjectId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -15,7 +12,11 @@ pub struct Delete {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: Tombstone,
|
pub(crate) object: IdOrNestedObject,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: DeleteType,
|
pub(crate) kind: DeleteType,
|
||||||
/// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user
|
/// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user
|
||||||
|
@ -25,3 +26,26 @@ pub struct Delete {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub(crate) unparsed: Unparsed,
|
pub(crate) unparsed: Unparsed,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Instead of a simple ID string as object, Mastodon sends a nested tombstone for some reason,
|
||||||
|
/// so we need to handle that as well.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub(crate) enum IdOrNestedObject {
|
||||||
|
Id(Url),
|
||||||
|
NestedObject(NestedObject),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub(crate) struct NestedObject {
|
||||||
|
id: Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IdOrNestedObject {
|
||||||
|
pub(crate) fn id(&self) -> &Url {
|
||||||
|
match self {
|
||||||
|
IdOrNestedObject::Id(i) => i,
|
||||||
|
IdOrNestedObject::NestedObject(n) => &n.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,13 +3,17 @@ pub mod undo_delete;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::protocol::{
|
use crate::{
|
||||||
|
context::WithContext,
|
||||||
|
objects::tests::file_to_json_object,
|
||||||
|
protocol::{
|
||||||
activities::deletion::{delete::Delete, undo_delete::UndoDelete},
|
activities::deletion::{delete::Delete, undo_delete::UndoDelete},
|
||||||
tests::test_parse_lemmy_item,
|
tests::test_parse_lemmy_item,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_parse_lemmy_deletion() {
|
async fn test_parse_deletion() {
|
||||||
test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/remove_note.json").unwrap();
|
test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/remove_note.json").unwrap();
|
||||||
test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/delete_page.json").unwrap();
|
test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/delete_page.json").unwrap();
|
||||||
|
|
||||||
|
@ -17,5 +21,14 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
test_parse_lemmy_item::<UndoDelete>("assets/lemmy/activities/deletion/undo_delete_page.json")
|
test_parse_lemmy_item::<UndoDelete>("assets/lemmy/activities/deletion/undo_delete_page.json")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/delete_private_message.json")
|
||||||
|
.unwrap();
|
||||||
|
test_parse_lemmy_item::<UndoDelete>(
|
||||||
|
"assets/lemmy/activities/deletion/undo_delete_private_message.json",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
file_to_json_object::<WithContext<Delete>>("assets/pleroma/activities/delete.json").unwrap();
|
||||||
|
file_to_json_object::<WithContext<Delete>>("assets/mastodon/activities/delete.json").unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ pub struct UndoDelete {
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: Delete,
|
pub(crate) object: Delete,
|
||||||
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: UndoType,
|
pub(crate) kind: UndoType,
|
||||||
|
|
|
@ -6,7 +6,6 @@ pub mod community;
|
||||||
pub mod create_or_update;
|
pub mod create_or_update;
|
||||||
pub mod deletion;
|
pub mod deletion;
|
||||||
pub mod following;
|
pub mod following;
|
||||||
pub mod private_message;
|
|
||||||
pub mod voting;
|
pub mod voting;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Display, Deserialize, Serialize, PartialEq)]
|
#[derive(Clone, Debug, Display, Deserialize, Serialize, PartialEq)]
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
use crate::{
|
|
||||||
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
|
|
||||||
protocol::Unparsed,
|
|
||||||
};
|
|
||||||
use activitystreams_kinds::activity::DeleteType;
|
|
||||||
use lemmy_apub_lib::object_id::ObjectId;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct DeletePrivateMessage {
|
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
|
||||||
#[serde(deserialize_with = "crate::deserialize_one")]
|
|
||||||
pub(crate) to: [ObjectId<ApubPerson>; 1],
|
|
||||||
pub(crate) object: ObjectId<ApubPrivateMessage>,
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub(crate) kind: DeleteType,
|
|
||||||
pub(crate) id: Url,
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub(crate) unparsed: Unparsed,
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
pub mod create_or_update;
|
|
||||||
pub mod delete;
|
|
||||||
pub mod undo_delete;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::protocol::{
|
|
||||||
activities::private_message::{
|
|
||||||
create_or_update::CreateOrUpdatePrivateMessage,
|
|
||||||
delete::DeletePrivateMessage,
|
|
||||||
undo_delete::UndoDeletePrivateMessage,
|
|
||||||
},
|
|
||||||
tests::test_parse_lemmy_item,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[actix_rt::test]
|
|
||||||
async fn test_parse_lemmy_private_message() {
|
|
||||||
test_parse_lemmy_item::<CreateOrUpdatePrivateMessage>(
|
|
||||||
"assets/lemmy/activities/private_message/create.json",
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
test_parse_lemmy_item::<DeletePrivateMessage>(
|
|
||||||
"assets/lemmy/activities/private_message/delete.json",
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
test_parse_lemmy_item::<UndoDeletePrivateMessage>(
|
|
||||||
"assets/lemmy/activities/private_message/undo_delete.json",
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
use crate::{
|
|
||||||
objects::person::ApubPerson,
|
|
||||||
protocol::{activities::private_message::delete::DeletePrivateMessage, Unparsed},
|
|
||||||
};
|
|
||||||
use activitystreams_kinds::activity::UndoType;
|
|
||||||
use lemmy_apub_lib::object_id::ObjectId;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UndoDeletePrivateMessage {
|
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
|
||||||
#[serde(deserialize_with = "crate::deserialize_one")]
|
|
||||||
pub(crate) to: [ObjectId<ApubPerson>; 1],
|
|
||||||
pub(crate) object: DeletePrivateMessage,
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub(crate) kind: UndoType,
|
|
||||||
pub(crate) id: Url,
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub(crate) unparsed: Unparsed,
|
|
||||||
}
|
|
Loading…
Reference in a new issue