fix: limit actor update modifiable fields

This commit is contained in:
əlemi 2024-07-15 21:36:17 +02:00
parent 84f1cbd913
commit 5c384e9b9e
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 41 additions and 2 deletions

View file

@ -22,6 +22,9 @@ pub enum JobError {
#[error("error delivering activity: {0}")] #[error("error delivering activity: {0}")]
DeliveryError(#[from] upub::traits::fetch::RequestError), DeliveryError(#[from] upub::traits::fetch::RequestError),
#[error("creator is not authorized to carry out this job")]
Forbidden,
} }
pub type JobResult<T> = Result<T, JobError>; pub type JobResult<T> = Result<T, JobError>;

View file

@ -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 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<()> { 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)); 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::<Vec<Field>>()
.into();
}
updated = prev.ap();
}
activity = activity.set_object(apb::Node::object(updated));
}
if matches!(t, apb::ObjectType::Activity(apb::ActivityType::Create)) { if matches!(t, apb::ObjectType::Activity(apb::ActivityType::Create)) {
let raw_oid = Context::new_id(); let raw_oid = Context::new_id();
let oid = ctx.oid(&raw_oid); let oid = ctx.oid(&raw_oid);