Support mastodon deletes

asonix/mastodon-compat
Aode (lion) 2021-11-15 18:58:15 -06:00
parent 659572e00e
commit c0281dfb1c
4 changed files with 55 additions and 15 deletions

View File

@ -8,7 +8,7 @@ use crate::{
},
activity_lists::AnnouncableActivities,
objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::deletion::delete::Delete,
protocol::activities::deletion::delete::{Delete, ObjectOrTombstone},
};
use activitystreams::{activity::kind::DeleteType, public};
use anyhow::anyhow;
@ -50,11 +50,12 @@ impl ActivityHandler for Delete {
context: &Data<LemmyContext>,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_is_public(&self.to, &self.cc)?;
let cc = self.cc.as_deref().unwrap_or(&[]);
verify_is_public(&self.to, cc)?;
verify_activity(&self.id, self.actor.inner(), &context.settings())?;
let community = self.get_community(context, request_counter).await?;
verify_delete_activity(
&self.object,
self.object.as_url(),
&self.actor,
&community,
self.summary.is_some(),
@ -78,9 +79,23 @@ impl ActivityHandler for Delete {
} else {
Some(reason)
};
receive_remove_action(&self.actor, &self.object, reason, context, request_counter).await
receive_remove_action(
&self.actor,
self.object.as_url(),
reason,
context,
request_counter,
)
.await
} else {
receive_delete_action(&self.object, &self.actor, true, context, request_counter).await
receive_delete_action(
self.object.as_url(),
&self.actor,
true,
context,
request_counter,
)
.await
}
}
}
@ -96,8 +111,8 @@ impl Delete {
Ok(Delete {
actor: ObjectId::new(actor.actor_id()),
to: vec![public()],
object: object_id,
cc: vec![community.actor_id()],
object: ObjectOrTombstone::Url(object_id),
cc: Some(vec![community.actor_id()]),
kind: DeleteType::Delete,
summary,
id: generate_activity_id(
@ -201,7 +216,7 @@ impl GetCommunity for Delete {
context: &LemmyContext,
_request_counter: &mut i32,
) -> Result<ApubCommunity, LemmyError> {
let community_id = match DeletableObjects::read_from_db(&self.object, context).await? {
let community_id = match DeletableObjects::read_from_db(self.object.as_url(), context).await? {
DeletableObjects::Community(c) => c.id,
DeletableObjects::Comment(c) => {
let post = blocking(context.pool(), move |conn| Post::read(conn, c.post_id)).await??;

View File

@ -40,7 +40,7 @@ impl ActivityHandler for UndoDelete {
self.object.verify(context, request_counter).await?;
let community = self.get_community(context, request_counter).await?;
verify_delete_activity(
&self.object.object,
self.object.object.as_url(),
&self.actor,
&community,
self.object.summary.is_some(),
@ -57,10 +57,10 @@ impl ActivityHandler for UndoDelete {
request_counter: &mut i32,
) -> Result<(), LemmyError> {
if self.object.summary.is_some() {
UndoDelete::receive_undo_remove_action(&self.object.object, context).await
UndoDelete::receive_undo_remove_action(self.object.object.as_url(), context).await
} else {
receive_delete_action(
&self.object.object,
self.object.object.as_url(),
&self.actor,
false,
context,

View File

@ -117,7 +117,7 @@ fn verify_add_remove_moderator_target(
}
pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> Result<(), LemmyError> {
if !to.contains(&public()) && !cc.contains(&public()) {
if ![to, cc].iter().any(|set| set.contains(&public())) {
return Err(anyhow!("Object is not public").into());
}
Ok(())

View File

@ -1,18 +1,34 @@
use crate::objects::person::ApubPerson;
use activitystreams::{activity::kind::DeleteType, unparsed::Unparsed};
use activitystreams::{
activity::kind::DeleteType,
object::kind::TombstoneType,
unparsed::Unparsed,
};
use lemmy_apub_lib::object_id::ObjectId;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use url::Url;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)]
#[serde(rename_all = "camelCase")]
pub enum ObjectOrTombstone {
Url(Url),
Tombstone {
id: Url,
#[serde(rename = "type")]
kind: TombstoneType,
},
}
#[skip_serializing_none]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Delete {
pub(crate) actor: ObjectId<ApubPerson>,
pub(crate) to: Vec<Url>,
pub(crate) object: Url,
pub(crate) cc: Vec<Url>,
pub(crate) object: ObjectOrTombstone,
pub(crate) cc: Option<Vec<Url>>,
#[serde(rename = "type")]
pub(crate) kind: DeleteType,
/// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user
@ -22,3 +38,12 @@ pub struct Delete {
#[serde(flatten)]
pub(crate) unparsed: Unparsed,
}
impl ObjectOrTombstone {
pub fn as_url(&self) -> &Url {
match self {
Self::Url(ref url) => url,
Self::Tombstone { ref id, .. } => id,
}
}
}