From 10c38400e4b5114f40136526a5649146031a3767 Mon Sep 17 00:00:00 2001 From: silverpill Date: Tue, 17 Jan 2023 18:01:57 +0000 Subject: [PATCH] Accept actor objects where value of "attachment" property is not an array --- CHANGELOG.md | 1 + src/activitypub/actors/types.rs | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30db6ab..d6808f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Don't ignore `Delete(Person)` verification errors if database error subtype is not `NotFound`. - Don't stop activity processing on invalid local mentions. +- Accept actor objects where `attachment` property value is not an array. ## [1.9.0] - 2023-01-08 diff --git a/src/activitypub/actors/types.rs b/src/activitypub/actors/types.rs index 5d3f9c7..9fe70db 100644 --- a/src/activitypub/actors/types.rs +++ b/src/activitypub/actors/types.rs @@ -9,6 +9,7 @@ use serde_json::{json, Value}; use crate::activitypub::{ constants::{ACTOR_KEY_SUFFIX, AP_CONTEXT}, identifiers::{local_actor_id, LocalActorCollection}, + receiver::parse_property_value, vocabulary::{IDENTITY_PROOF, IMAGE, LINK, PERSON, PROPERTY_VALUE, SERVICE}, }; use crate::config::Instance; @@ -74,7 +75,7 @@ pub struct ActorAttachment { } // Some implementations use empty object instead of null -pub fn deserialize_image_opt<'de, D>( +fn deserialize_image_opt<'de, D>( deserializer: D, ) -> Result, D::Error> where D: Deserializer<'de> @@ -97,6 +98,23 @@ pub fn deserialize_image_opt<'de, D>( Ok(maybe_image) } +// Some implementations use single object instead of array +fn deserialize_attachments_opt<'de, D>( + deserializer: D, +) -> Result>, D::Error> + where D: Deserializer<'de> +{ + let maybe_value: Option = Option::deserialize(deserializer)?; + let maybe_attachments = if let Some(value) = maybe_value { + let attachments: Vec = parse_property_value(&value) + .map_err(DeserializerError::custom)?; + Some(attachments) + } else { + None + }; + Ok(maybe_attachments) +} + // Clone and Debug traits are required by FromSql #[derive(Clone, Debug, Deserialize, Serialize)] #[cfg_attr(test, derive(Default))] @@ -143,7 +161,11 @@ pub struct Actor { #[serde(skip_serializing_if = "Option::is_none")] pub also_known_as: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde( + default, + deserialize_with = "deserialize_attachments_opt", + skip_serializing_if = "Option::is_none", + )] pub attachment: Option>, #[serde(default)]