Fix federation of community deletion/removal (fixes #1253)
This commit is contained in:
parent
5e2a5c0266
commit
6746d973a1
5 changed files with 41 additions and 51 deletions
|
@ -327,9 +327,9 @@ impl Perform for DeleteCommunity {
|
|||
|
||||
// Send apub messages
|
||||
if deleted {
|
||||
updated_community.send_delete(&user, context).await?;
|
||||
updated_community.send_delete(context).await?;
|
||||
} else {
|
||||
updated_community.send_undo_delete(&user, context).await?;
|
||||
updated_community.send_undo_delete(context).await?;
|
||||
}
|
||||
|
||||
let edit_id = data.edit_id;
|
||||
|
@ -395,9 +395,9 @@ impl Perform for RemoveCommunity {
|
|||
|
||||
// Apub messages
|
||||
if removed {
|
||||
updated_community.send_remove(&user, context).await?;
|
||||
updated_community.send_remove(context).await?;
|
||||
} else {
|
||||
updated_community.send_undo_remove(&user, context).await?;
|
||||
updated_community.send_undo_remove(context).await?;
|
||||
}
|
||||
|
||||
let edit_id = data.edit_id;
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::{
|
|||
check_is_apub_id_valid,
|
||||
fetcher::get_or_fetch_and_upsert_user,
|
||||
ActorType,
|
||||
ToApub,
|
||||
};
|
||||
use activitystreams::{
|
||||
activity::{
|
||||
|
@ -23,7 +22,7 @@ use activitystreams::{
|
|||
};
|
||||
use anyhow::Context;
|
||||
use itertools::Itertools;
|
||||
use lemmy_db::{community::Community, community_view::CommunityFollowerView, user::User_, DbPool};
|
||||
use lemmy_db::{community::Community, community_view::CommunityFollowerView, DbPool};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{location_info, settings::Settings, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -85,10 +84,8 @@ impl ActorType for Community {
|
|||
}
|
||||
|
||||
/// If the creator of a community deletes the community, send this to all followers.
|
||||
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
let group = self.to_apub(context.pool()).await?;
|
||||
|
||||
let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?);
|
||||
async fn send_delete(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
let mut delete = Delete::new(self.actor_id()?, self.actor_id()?);
|
||||
delete
|
||||
.set_context(activitystreams::context())
|
||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||
|
@ -100,21 +97,15 @@ impl ActorType for Community {
|
|||
}
|
||||
|
||||
/// If the creator of a community reverts the deletion of a community, send this to all followers.
|
||||
async fn send_undo_delete(
|
||||
&self,
|
||||
creator: &User_,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
let group = self.to_apub(context.pool()).await?;
|
||||
|
||||
let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?);
|
||||
async fn send_undo_delete(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
let mut delete = Delete::new(self.actor_id()?, self.actor_id()?);
|
||||
delete
|
||||
.set_context(activitystreams::context())
|
||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||
.set_to(public())
|
||||
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||
|
||||
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
||||
let mut undo = Undo::new(self.actor_id()?, delete.into_any_base()?);
|
||||
undo
|
||||
.set_context(activitystreams::context())
|
||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||
|
@ -126,8 +117,8 @@ impl ActorType for Community {
|
|||
}
|
||||
|
||||
/// If an admin removes a community, send this to all followers.
|
||||
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
let mut remove = Remove::new(mod_.actor_id.to_owned(), self.actor_id()?);
|
||||
async fn send_remove(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
let mut remove = Remove::new(self.actor_id()?, self.actor_id()?);
|
||||
remove
|
||||
.set_context(activitystreams::context())
|
||||
.set_id(generate_activity_id(RemoveType::Remove)?)
|
||||
|
@ -139,8 +130,8 @@ impl ActorType for Community {
|
|||
}
|
||||
|
||||
/// If an admin reverts the removal of a community, send this to all followers.
|
||||
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
let mut remove = Remove::new(mod_.actor_id.to_owned(), self.actor_id()?);
|
||||
async fn send_undo_remove(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
let mut remove = Remove::new(self.actor_id()?, self.actor_id()?);
|
||||
remove
|
||||
.set_context(activitystreams::context())
|
||||
.set_id(generate_activity_id(RemoveType::Remove)?)
|
||||
|
@ -148,7 +139,7 @@ impl ActorType for Community {
|
|||
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||
|
||||
// Undo that fake activity
|
||||
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
|
||||
let mut undo = Undo::new(self.actor_id()?, remove.into_any_base()?);
|
||||
undo
|
||||
.set_context(activitystreams::context())
|
||||
.set_id(generate_activity_id(LikeType::Like)?)
|
||||
|
|
|
@ -94,27 +94,19 @@ impl ActorType for User_ {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn send_delete(&self, _creator: &User_, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
async fn send_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn send_undo_delete(
|
||||
&self,
|
||||
_creator: &User_,
|
||||
_context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
async fn send_undo_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn send_remove(&self, _creator: &User_, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
async fn send_remove(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn send_undo_remove(
|
||||
&self,
|
||||
_creator: &User_,
|
||||
_context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
async fn send_undo_remove(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
|
|
@ -251,10 +251,14 @@ pub(crate) async fn get_or_fetch_and_upsert_user(
|
|||
Ok(u) if !u.local && should_refetch_actor(u.last_refreshed_at) => {
|
||||
debug!("Fetching and updating from remote user: {}", apub_id);
|
||||
let person =
|
||||
fetch_remote_object::<PersonExt>(context.client(), apub_id, recursion_counter).await?;
|
||||
fetch_remote_object::<PersonExt>(context.client(), apub_id, recursion_counter).await;
|
||||
// If fetching failed, return the existing data.
|
||||
if person.is_err() {
|
||||
return Ok(u);
|
||||
}
|
||||
|
||||
let mut uf = UserForm::from_apub(
|
||||
&person,
|
||||
&person?,
|
||||
context,
|
||||
Some(apub_id.to_owned()),
|
||||
recursion_counter,
|
||||
|
@ -320,7 +324,7 @@ pub(crate) async fn get_or_fetch_and_upsert_community(
|
|||
match community {
|
||||
Ok(c) if !c.local && should_refetch_actor(c.last_refreshed_at) => {
|
||||
debug!("Fetching and updating from remote community: {}", apub_id);
|
||||
fetch_remote_community(apub_id, context, Some(c.id), recursion_counter).await
|
||||
fetch_remote_community(apub_id, context, Some(c), recursion_counter).await
|
||||
}
|
||||
Ok(c) => Ok(c),
|
||||
Err(NotFound {}) => {
|
||||
|
@ -331,17 +335,24 @@ pub(crate) async fn get_or_fetch_and_upsert_community(
|
|||
}
|
||||
}
|
||||
|
||||
/// Request a community by apub ID from a remote instance, including moderators. If `community_id`,
|
||||
/// Request a community by apub ID from a remote instance, including moderators. If `old_community`,
|
||||
/// is set, this is an update for a community which is already known locally. If not, we don't know
|
||||
/// the community yet and also pull the outbox, to get some initial posts.
|
||||
async fn fetch_remote_community(
|
||||
apub_id: &Url,
|
||||
context: &LemmyContext,
|
||||
community_id: Option<i32>,
|
||||
old_community: Option<Community>,
|
||||
recursion_counter: &mut i32,
|
||||
) -> Result<Community, LemmyError> {
|
||||
let group = fetch_remote_object::<GroupExt>(context.client(), apub_id, recursion_counter).await?;
|
||||
let group = fetch_remote_object::<GroupExt>(context.client(), apub_id, recursion_counter).await;
|
||||
// If fetching failed, return the existing data.
|
||||
if let Some(ref c) = old_community {
|
||||
if group.is_err() {
|
||||
return Ok(c.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
let group = group?;
|
||||
let cf =
|
||||
CommunityForm::from_apub(&group, context, Some(apub_id.to_owned()), recursion_counter).await?;
|
||||
let community = blocking(context.pool(), move |conn| Community::upsert(conn, &cf)).await??;
|
||||
|
@ -364,7 +375,7 @@ async fn fetch_remote_community(
|
|||
}
|
||||
|
||||
// TODO: need to make this work to update mods of existing communities
|
||||
if community_id.is_none() {
|
||||
if old_community.is_none() {
|
||||
let community_id = community.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
for mod_ in creator_and_moderators {
|
||||
|
|
|
@ -189,15 +189,11 @@ pub trait ActorType {
|
|||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError>;
|
||||
|
||||
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_undo_delete(
|
||||
&self,
|
||||
creator: &User_,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError>;
|
||||
async fn send_delete(&self, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_undo_delete(&self, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
|
||||
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_remove(&self, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_undo_remove(&self, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
|
||||
async fn send_announce(
|
||||
&self,
|
||||
|
|
Loading…
Reference in a new issue