From 5c384e9b9eb983b0d178002a3c16fd399407a7ca Mon Sep 17 00:00:00 2001 From: alemi Date: Mon, 15 Jul 2024 21:36:17 +0200 Subject: [PATCH] fix: limit actor update modifiable fields --- upub/worker/src/dispatcher.rs | 3 +++ upub/worker/src/outbound.rs | 40 +++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/upub/worker/src/dispatcher.rs b/upub/worker/src/dispatcher.rs index 31ee2ca..6497b5b 100644 --- a/upub/worker/src/dispatcher.rs +++ b/upub/worker/src/dispatcher.rs @@ -22,6 +22,9 @@ pub enum JobError { #[error("error delivering activity: {0}")] DeliveryError(#[from] upub::traits::fetch::RequestError), + + #[error("creator is not authorized to carry out this job")] + Forbidden, } pub type JobResult = Result; diff --git a/upub/worker/src/outbound.rs b/upub/worker/src/outbound.rs index 97c13b9..6b4daff 100644 --- a/upub/worker/src/outbound.rs +++ b/upub/worker/src/outbound.rs @@ -1,6 +1,6 @@ -use apb::{field::OptionalString, target::Addressed, Activity, ActivityMut, Base, BaseMut, Object, ObjectMut}; +use apb::{field::OptionalString, target::Addressed, Activity, ActivityMut, Actor, Base, BaseMut, Object, ObjectMut}; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect, SelectColumns, TransactionTrait}; -use upub::{model, traits::{Addresser, Processor}, Context}; +use upub::{model::{self, actor::Field}, traits::{Addresser, Processor}, Context}; pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<()> { @@ -46,6 +46,42 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult< activity = activity.set_object(apb::Node::object(undone)); } + if matches!(t, apb::ObjectType::Activity(apb::ActivityType::Update)) { + let mut updated = activity.object().extract().ok_or(crate::JobError::MissingPayload)?; + if updated.actor_type().is_ok() { + let mut prev = model::actor::Entity::find_by_ap_id(updated.id()?) + .one(&tx) + .await? + .ok_or_else(|| crate::JobError::MissingPayload)?; + if prev.id != job.actor { + return Err(crate::JobError::Forbidden); + } + if let Some(name) = updated.name().str() { + prev.name = Some(name); + } + if let Some(summary) = updated.summary().str() { + prev.summary = Some(summary); + } + if let Some(icon) = updated.icon().get().and_then(|x| x.url().id().str()) { + prev.icon = Some(icon); + } + if let Some(image) = updated.image().get().and_then(|x| x.url().id().str()) { + prev.image = Some(image); + } + if !updated.attachment().is_empty() { + prev.fields = updated.attachment() + .flat() + .into_iter() + .filter_map(|x| x.extract()) + .map(Field::from) + .collect::>() + .into(); + } + updated = prev.ap(); + } + activity = activity.set_object(apb::Node::object(updated)); + } + if matches!(t, apb::ObjectType::Activity(apb::ActivityType::Create)) { let raw_oid = Context::new_id(); let oid = ctx.oid(&raw_oid);