@ -8,7 +8,6 @@ use crate::{
verify_person_in_community ,
verify_person_in_community ,
} ,
} ,
activity_lists ::AnnouncableActivities ,
activity_lists ::AnnouncableActivities ,
local_instance ,
objects ::{
objects ::{
comment ::ApubComment ,
comment ::ApubComment ,
community ::ApubCommunity ,
community ::ApubCommunity ,
@ -20,15 +19,15 @@ use crate::{
activities ::deletion ::{ delete ::Delete , undo_delete ::UndoDelete } ,
activities ::deletion ::{ delete ::Delete , undo_delete ::UndoDelete } ,
InCommunity ,
InCommunity ,
} ,
} ,
ActorType ,
SendActivity ,
SendActivity ,
} ;
} ;
use activitypub_federation ::{
use activitypub_federation ::{
core ::object_id ::ObjectId ,
config ::Data ,
traits ::{ Actor , ApubObject } ,
fetch ::object_id ::ObjectId ,
utils ::verify_domains_match ,
kinds ::public ,
protocol ::verification ::verify_domains_match ,
traits ::{ Actor , Object } ,
} ;
} ;
use activitystreams_kinds ::public ;
use lemmy_api_common ::{
use lemmy_api_common ::{
comment ::{ CommentResponse , DeleteComment , RemoveComment } ,
comment ::{ CommentResponse , DeleteComment , RemoveComment } ,
community ::{ CommunityResponse , DeleteCommunity , RemoveCommunity } ,
community ::{ CommunityResponse , DeleteCommunity , RemoveCommunity } ,
@ -64,14 +63,14 @@ pub mod delete;
pub mod delete_user ;
pub mod delete_user ;
pub mod undo_delete ;
pub mod undo_delete ;
#[ async_trait::async_trait (?Send) ]
#[ async_trait::async_trait ]
impl SendActivity for DeletePost {
impl SendActivity for DeletePost {
type Response = PostResponse ;
type Response = PostResponse ;
async fn send_activity (
async fn send_activity (
request : & Self ,
request : & Self ,
response : & Self ::Response ,
response : & Self ::Response ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let local_user_view =
let local_user_view =
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
@ -89,14 +88,14 @@ impl SendActivity for DeletePost {
}
}
}
}
#[ async_trait::async_trait (?Send) ]
#[ async_trait::async_trait ]
impl SendActivity for RemovePost {
impl SendActivity for RemovePost {
type Response = PostResponse ;
type Response = PostResponse ;
async fn send_activity (
async fn send_activity (
request : & Self ,
request : & Self ,
response : & Self ::Response ,
response : & Self ::Response ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let local_user_view =
let local_user_view =
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
@ -114,14 +113,14 @@ impl SendActivity for RemovePost {
}
}
}
}
#[ async_trait::async_trait (?Send) ]
#[ async_trait::async_trait ]
impl SendActivity for DeleteComment {
impl SendActivity for DeleteComment {
type Response = CommentResponse ;
type Response = CommentResponse ;
async fn send_activity (
async fn send_activity (
request : & Self ,
request : & Self ,
response : & Self ::Response ,
response : & Self ::Response ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let community_id = response . comment_view . community . id ;
let community_id = response . comment_view . community . id ;
let community = Community ::read ( context . pool ( ) , community_id ) . await ? ;
let community = Community ::read ( context . pool ( ) , community_id ) . await ? ;
@ -132,14 +131,14 @@ impl SendActivity for DeleteComment {
}
}
}
}
#[ async_trait::async_trait (?Send) ]
#[ async_trait::async_trait ]
impl SendActivity for RemoveComment {
impl SendActivity for RemoveComment {
type Response = CommentResponse ;
type Response = CommentResponse ;
async fn send_activity (
async fn send_activity (
request : & Self ,
request : & Self ,
response : & Self ::Response ,
response : & Self ::Response ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let local_user_view =
let local_user_view =
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
@ -158,14 +157,14 @@ impl SendActivity for RemoveComment {
}
}
}
}
#[ async_trait::async_trait (?Send) ]
#[ async_trait::async_trait ]
impl SendActivity for DeletePrivateMessage {
impl SendActivity for DeletePrivateMessage {
type Response = PrivateMessageResponse ;
type Response = PrivateMessageResponse ;
async fn send_activity (
async fn send_activity (
request : & Self ,
request : & Self ,
response : & Self ::Response ,
response : & Self ::Response ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let local_user_view =
let local_user_view =
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
@ -179,14 +178,14 @@ impl SendActivity for DeletePrivateMessage {
}
}
}
}
#[ async_trait::async_trait (?Send) ]
#[ async_trait::async_trait ]
impl SendActivity for DeleteCommunity {
impl SendActivity for DeleteCommunity {
type Response = CommunityResponse ;
type Response = CommunityResponse ;
async fn send_activity (
async fn send_activity (
request : & Self ,
request : & Self ,
_response : & Self ::Response ,
_response : & Self ::Response ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let local_user_view =
let local_user_view =
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
@ -204,14 +203,14 @@ impl SendActivity for DeleteCommunity {
}
}
}
}
#[ async_trait::async_trait (?Send) ]
#[ async_trait::async_trait ]
impl SendActivity for RemoveCommunity {
impl SendActivity for RemoveCommunity {
type Response = CommunityResponse ;
type Response = CommunityResponse ;
async fn send_activity (
async fn send_activity (
request : & Self ,
request : & Self ,
_response : & Self ::Response ,
_response : & Self ::Response ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let local_user_view =
let local_user_view =
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
get_local_user_view_from_jwt ( & request . auth , context . pool ( ) , context . secret ( ) ) . await ? ;
@ -238,7 +237,7 @@ async fn send_apub_delete_in_community(
object : DeletableObjects ,
object : DeletableObjects ,
reason : Option < String > ,
reason : Option < String > ,
deleted : bool ,
deleted : bool ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let actor = ApubPerson ::from ( actor ) ;
let actor = ApubPerson ::from ( actor ) ;
let is_mod_action = reason . is_some ( ) ;
let is_mod_action = reason . is_some ( ) ;
@ -265,7 +264,7 @@ async fn send_apub_delete_private_message(
actor : & ApubPerson ,
actor : & ApubPerson ,
pm : PrivateMessage ,
pm : PrivateMessage ,
deleted : bool ,
deleted : bool ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let recipient_id = pm . recipient_id ;
let recipient_id = pm . recipient_id ;
let recipient : ApubPerson = Person ::read ( context . pool ( ) , recipient_id ) . await ? . into ( ) ;
let recipient : ApubPerson = Person ::read ( context . pool ( ) , recipient_id ) . await ? . into ( ) ;
@ -273,10 +272,10 @@ async fn send_apub_delete_private_message(
let deletable = DeletableObjects ::PrivateMessage ( pm . into ( ) ) ;
let deletable = DeletableObjects ::PrivateMessage ( pm . into ( ) ) ;
let inbox = vec! [ recipient . shared_inbox_or_inbox ( ) ] ;
let inbox = vec! [ recipient . shared_inbox_or_inbox ( ) ] ;
if deleted {
if deleted {
let delete = Delete ::new ( actor , deletable , recipient . actor_ id( ) , None , None , context ) ? ;
let delete = Delete ::new ( actor , deletable , recipient . id( ) , None , None , context ) ? ;
send_lemmy_activity ( context , delete , actor , inbox , true ) . await ? ;
send_lemmy_activity ( context , delete , actor , inbox , true ) . await ? ;
} else {
} else {
let undo = UndoDelete ::new ( actor , deletable , recipient . actor_ id( ) , None , None , context ) ? ;
let undo = UndoDelete ::new ( actor , deletable , recipient . id( ) , None , None , context ) ? ;
send_lemmy_activity ( context , undo , actor , inbox , true ) . await ? ;
send_lemmy_activity ( context , undo , actor , inbox , true ) . await ? ;
} ;
} ;
Ok ( ( ) )
Ok ( ( ) )
@ -293,18 +292,18 @@ impl DeletableObjects {
#[ tracing::instrument(skip_all) ]
#[ tracing::instrument(skip_all) ]
pub ( crate ) async fn read_from_db (
pub ( crate ) async fn read_from_db (
ap_id : & Url ,
ap_id : & Url ,
context : & LemmyContext,
context : & Data< LemmyContext> ,
) -> Result < DeletableObjects , LemmyError > {
) -> Result < DeletableObjects , LemmyError > {
if let Some ( c ) = ApubCommunity ::read_from_ apub_ id( ap_id . clone ( ) , context ) . await ? {
if let Some ( c ) = ApubCommunity ::read_from_ id( ap_id . clone ( ) , context ) . await ? {
return Ok ( DeletableObjects ::Community ( c ) ) ;
return Ok ( DeletableObjects ::Community ( c ) ) ;
}
}
if let Some ( p ) = ApubPost ::read_from_ apub_ id( ap_id . clone ( ) , context ) . await ? {
if let Some ( p ) = ApubPost ::read_from_ id( ap_id . clone ( ) , context ) . await ? {
return Ok ( DeletableObjects ::Post ( p ) ) ;
return Ok ( DeletableObjects ::Post ( p ) ) ;
}
}
if let Some ( c ) = ApubComment ::read_from_ apub_ id( ap_id . clone ( ) , context ) . await ? {
if let Some ( c ) = ApubComment ::read_from_ id( ap_id . clone ( ) , context ) . await ? {
return Ok ( DeletableObjects ::Comment ( c ) ) ;
return Ok ( DeletableObjects ::Comment ( c ) ) ;
}
}
if let Some ( p ) = ApubPrivateMessage ::read_from_ apub_ id( ap_id . clone ( ) , context ) . await ? {
if let Some ( p ) = ApubPrivateMessage ::read_from_ id( ap_id . clone ( ) , context ) . await ? {
return Ok ( DeletableObjects ::PrivateMessage ( p ) ) ;
return Ok ( DeletableObjects ::PrivateMessage ( p ) ) ;
}
}
Err ( diesel ::NotFound . into ( ) )
Err ( diesel ::NotFound . into ( ) )
@ -312,7 +311,7 @@ impl DeletableObjects {
pub ( crate ) fn id ( & self ) -> Url {
pub ( crate ) fn id ( & self ) -> Url {
match self {
match self {
DeletableObjects ::Community ( c ) = > c . actor_ id( ) ,
DeletableObjects ::Community ( c ) = > c . id( ) ,
DeletableObjects ::Comment ( c ) = > c . ap_id . clone ( ) . into ( ) ,
DeletableObjects ::Comment ( c ) = > c . ap_id . clone ( ) . into ( ) ,
DeletableObjects ::Post ( p ) = > p . ap_id . clone ( ) . into ( ) ,
DeletableObjects ::Post ( p ) = > p . ap_id . clone ( ) . into ( ) ,
DeletableObjects ::PrivateMessage ( p ) = > p . ap_id . clone ( ) . into ( ) ,
DeletableObjects ::PrivateMessage ( p ) = > p . ap_id . clone ( ) . into ( ) ,
@ -324,8 +323,7 @@ impl DeletableObjects {
pub ( in crate ::activities ) async fn verify_delete_activity (
pub ( in crate ::activities ) async fn verify_delete_activity (
activity : & Delete ,
activity : & Delete ,
is_mod_action : bool ,
is_mod_action : bool ,
context : & LemmyContext ,
context : & Data < LemmyContext > ,
request_counter : & mut i32 ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
let object = DeletableObjects ::read_from_db ( activity . object . id ( ) , context ) . await ? ;
let object = DeletableObjects ::read_from_db ( activity . object . id ( ) , context ) . await ? ;
match object {
match object {
@ -334,27 +332,19 @@ pub(in crate::activities) async fn verify_delete_activity(
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 ( & activity . actor , & community , context , request_counter ). await ? ;
verify_person_in_community ( & activity . actor , & community , context ). await ? ;
}
}
// community deletion is always a mod (or admin) action
// community deletion is always a mod (or admin) action
verify_mod_action (
verify_mod_action ( & activity . actor , activity . object . id ( ) , community . id , context ) . await ? ;
& activity . actor ,
activity . object . id ( ) ,
community . id ,
context ,
request_counter ,
)
. await ? ;
}
}
DeletableObjects ::Post ( p ) = > {
DeletableObjects ::Post ( p ) = > {
verify_is_public ( & activity . to , & [ ] ) ? ;
verify_is_public ( & activity . to , & [ ] ) ? ;
verify_delete_post_or_comment (
verify_delete_post_or_comment (
& activity . actor ,
& activity . actor ,
& p . ap_id . clone ( ) . into ( ) ,
& p . ap_id . clone ( ) . into ( ) ,
& activity . community ( context , request_counter ). await ? ,
& activity . community ( context ) . await ? ,
is_mod_action ,
is_mod_action ,
context ,
context ,
request_counter ,
)
)
. await ? ;
. await ? ;
}
}
@ -363,15 +353,14 @@ pub(in crate::activities) async fn verify_delete_activity(
verify_delete_post_or_comment (
verify_delete_post_or_comment (
& activity . actor ,
& activity . actor ,
& c . ap_id . clone ( ) . into ( ) ,
& c . ap_id . clone ( ) . into ( ) ,
& activity . community ( context , request_counter ). await ? ,
& activity . community ( context ). await ? ,
is_mod_action ,
is_mod_action ,
context ,
context ,
request_counter ,
)
)
. await ? ;
. await ? ;
}
}
DeletableObjects ::PrivateMessage ( _ ) = > {
DeletableObjects ::PrivateMessage ( _ ) = > {
verify_person ( & activity . actor , context , request_counter ). await ? ;
verify_person ( & activity . actor , context ). await ? ;
verify_domains_match ( activity . actor . inner ( ) , activity . object . id ( ) ) ? ;
verify_domains_match ( activity . actor . inner ( ) , activity . object . id ( ) ) ? ;
}
}
}
}
@ -384,12 +373,11 @@ async fn verify_delete_post_or_comment(
object_id : & Url ,
object_id : & Url ,
community : & ApubCommunity ,
community : & ApubCommunity ,
is_mod_action : bool ,
is_mod_action : bool ,
context : & LemmyContext ,
context : & Data < LemmyContext > ,
request_counter : & mut i32 ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
verify_person_in_community ( actor , community , context , request_counter ). await ? ;
verify_person_in_community ( actor , community , context ). await ? ;
if is_mod_action {
if is_mod_action {
verify_mod_action ( actor , object_id , community . id , context , request_counter ). await ? ;
verify_mod_action ( actor , object_id , community . id , context ). await ? ;
} else {
} else {
// domain of post ap_id and post.creator ap_id are identical, so we just check the former
// domain of post ap_id and post.creator ap_id are identical, so we just check the former
verify_domains_match ( actor . inner ( ) , object_id ) ? ;
verify_domains_match ( actor . inner ( ) , object_id ) ? ;
@ -403,17 +391,12 @@ async fn receive_delete_action(
object : & Url ,
object : & Url ,
actor : & ObjectId < ApubPerson > ,
actor : & ObjectId < ApubPerson > ,
deleted : bool ,
deleted : bool ,
context : & LemmyContext ,
context : & Data < LemmyContext > ,
request_counter : & mut i32 ,
) -> Result < ( ) , LemmyError > {
) -> Result < ( ) , LemmyError > {
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_ : Person = actor
let mod_ : Person = actor . dereference ( context ) . await ? . deref ( ) . clone ( ) ;
. dereference ( context , local_instance ( context ) . await , request_counter )
. await ?
. deref ( )
. clone ( ) ;
let object = DeletableObjects ::Community ( community . clone ( ) ) ;
let object = DeletableObjects ::Community ( community . clone ( ) ) ;
let c : Community = community . deref ( ) . deref ( ) . clone ( ) ;
let c : Community = community . deref ( ) . deref ( ) . clone ( ) ;
send_apub_delete_in_community ( mod_ , c , object , None , true , context ) . await ? ;
send_apub_delete_in_community ( mod_ , c , object , None , true , context ) . await ? ;