feat: normalize undos coming from our frontend

This commit is contained in:
əlemi 2025-02-05 18:55:06 +01:00
parent 9133577e4c
commit 1e25ffffe1
Signed by: alemi
GPG key ID: A4895B84D311642C

View file

@ -1,5 +1,5 @@
use apb::{target::Addressed, Activity, ActivityMut, ActorMut, Base, BaseMut, Object, ObjectMut, Shortcuts};
use sea_orm::{prelude::Expr, ColumnTrait, DbErr, EntityTrait, QueryFilter, QueryOrder, QuerySelect, SelectColumns, TransactionTrait};
use sea_orm::{prelude::Expr, ColumnTrait, DbErr, EntityTrait, QueryFilter, QuerySelect, SelectColumns, TransactionTrait};
use upub::{model::{self, actor::Field}, traits::{process::ProcessorError, Addresser, Processor}, Context};
@ -46,7 +46,8 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
.set_published(Some(now));
if matches!(t, apb::ObjectType::Activity(apb::ActivityType::Undo)) {
let undone = activity.object().id()?;
match activity.object().id() {
Ok(undone) => {
let activity = upub::model::activity::Entity::find_by_ap_id(&undone)
.one(&tx)
.await?
@ -54,6 +55,38 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
if activity.actor != job.actor {
return Err(crate::JobError::Forbidden);
}
},
Err(_) => {
// frontend doesn't know the activity id, so we have to look it up
let undone = activity.object().into_inner()?; // if even this is missing, malformed
match undone.activity_type()? {
apb::ActivityType::Follow => {
let follower = undone.actor().id().unwrap_or(job.actor.clone());
let follower_internal = upub::model::actor::Entity::ap_to_internal(&follower, &tx)
.await?
.ok_or(sea_orm::DbErr::RecordNotFound(follower))?;
let following = undone.object().id()?;
let following_internal = upub::model::actor::Entity::ap_to_internal(&following, &tx)
.await?
.ok_or(sea_orm::DbErr::RecordNotFound(following))?;
let activity_id = upub::model::relation::Entity::find()
.filter(upub::model::relation::Column::Follower.eq(follower_internal))
.filter(upub::model::relation::Column::Following.eq(following_internal))
.select_only()
.select_column(upub::model::relation::Column::Activity)
.into_tuple::<String>()
.one(&tx)
.await?
.ok_or(crate::JobError::Forbidden)?;
activity = activity.set_object(apb::Node::link(activity_id));
},
t => return Err(crate::JobError::ProcessorError(
upub::traits::process::ProcessorError::Unprocessable(format!("can't normalize Undo({t})"))
)),
}
},
}
}
macro_rules! update {