fix: object updates should only touch some fields
also reject updates for other types
This commit is contained in:
parent
232069d56a
commit
30e647fc12
1 changed files with 60 additions and 32 deletions
|
@ -1,6 +1,6 @@
|
||||||
use apb::{field::OptionalString, target::Addressed, Activity, ActivityMut, Actor, Base, BaseMut, Object, ObjectMut};
|
use apb::{field::OptionalString, target::Addressed, Activity, ActivityMut, Base, BaseMut, Object, ObjectMut};
|
||||||
use sea_orm::{prelude::Expr, ColumnTrait, DbErr, EntityTrait, QueryFilter, QueryOrder, QuerySelect, SelectColumns, TransactionTrait};
|
use sea_orm::{prelude::Expr, ColumnTrait, DbErr, EntityTrait, QueryFilter, QueryOrder, QuerySelect, SelectColumns, TransactionTrait};
|
||||||
use upub::{model::{self, actor::Field}, traits::{Addresser, Processor}, Context};
|
use upub::{model::{self, actor::Field}, traits::{process::ProcessorError, Addresser, Processor}, Context};
|
||||||
|
|
||||||
|
|
||||||
pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<()> {
|
pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<()> {
|
||||||
|
@ -65,28 +65,32 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
|
||||||
activity = activity.set_object(apb::Node::object(undone));
|
activity = activity.set_object(apb::Node::object(undone));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! update {
|
||||||
|
($prev:ident, $field:ident, $getter:expr) => {
|
||||||
|
if let Some($field) = $getter {
|
||||||
|
$prev.$field = Some($field.to_string());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if matches!(t, apb::ObjectType::Activity(apb::ActivityType::Update)) {
|
if matches!(t, apb::ObjectType::Activity(apb::ActivityType::Update)) {
|
||||||
let mut updated = activity.object().extract().ok_or(crate::JobError::MissingPayload)?;
|
let mut updated = activity.object().extract().ok_or(crate::JobError::MissingPayload)?;
|
||||||
if updated.actor_type().is_ok() {
|
match updated.object_type()? {
|
||||||
|
apb::ObjectType::Actor(_) => {
|
||||||
let mut prev = model::actor::Entity::find_by_ap_id(updated.id()?)
|
let mut prev = model::actor::Entity::find_by_ap_id(updated.id()?)
|
||||||
.one(&tx)
|
.one(&tx)
|
||||||
.await?
|
.await?
|
||||||
.ok_or_else(|| crate::JobError::MissingPayload)?;
|
.ok_or_else(|| crate::JobError::MissingPayload)?;
|
||||||
|
|
||||||
if prev.id != job.actor {
|
if prev.id != job.actor {
|
||||||
return Err(crate::JobError::Forbidden);
|
return Err(crate::JobError::Forbidden);
|
||||||
}
|
}
|
||||||
if let Some(name) = updated.name().str() {
|
|
||||||
prev.name = Some(name);
|
update!(prev, name, updated.name().ok());
|
||||||
}
|
update!(prev, summary, updated.summary().ok());
|
||||||
if let Some(summary) = updated.summary().str() {
|
update!(prev, icon, updated.icon().get().and_then(|x| x.url().id().str()));
|
||||||
prev.summary = Some(summary);
|
update!(prev, image, updated.image().get().and_then(|x| x.url().id().str()));
|
||||||
}
|
|
||||||
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() {
|
if !updated.attachment().is_empty() {
|
||||||
prev.fields = updated.attachment()
|
prev.fields = updated.attachment()
|
||||||
.flat()
|
.flat()
|
||||||
|
@ -96,7 +100,31 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
|
||||||
.collect::<Vec<Field>>()
|
.collect::<Vec<Field>>()
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
updated = prev.ap();
|
updated = prev.ap();
|
||||||
|
},
|
||||||
|
apb::ObjectType::Note => {
|
||||||
|
let mut prev = model::object::Entity::find_by_ap_id(updated.id()?)
|
||||||
|
.one(&tx)
|
||||||
|
.await?
|
||||||
|
.ok_or_else(|| crate::JobError::MissingPayload)?;
|
||||||
|
|
||||||
|
if prev.attributed_to.as_ref() != Some(&job.actor) {
|
||||||
|
return Err(crate::JobError::Forbidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
update!(prev, name, updated.name().ok());
|
||||||
|
update!(prev, summary, updated.summary().ok());
|
||||||
|
update!(prev, content, updated.content().ok());
|
||||||
|
update!(prev, image, updated.image().get().and_then(|x| x.url().id().str()));
|
||||||
|
|
||||||
|
if let Ok(sensitive) = updated.sensitive() {
|
||||||
|
prev.sensitive = sensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
updated = prev.ap();
|
||||||
|
},
|
||||||
|
t => return Err(crate::JobError::ProcessorError(ProcessorError::Unprocessable(format!("{t}")))),
|
||||||
}
|
}
|
||||||
activity = activity.set_object(apb::Node::object(updated));
|
activity = activity.set_object(apb::Node::object(updated));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue