From 01c894da9ddecc3b5d98b72106375491ba0af52d Mon Sep 17 00:00:00 2001 From: silverpill Date: Tue, 31 Jan 2023 18:03:24 +0000 Subject: [PATCH] Separate object URL handling from content validation --- src/activitypub/handlers/create.rs | 56 +++++++++++++++--------------- src/activitypub/handlers/update.rs | 11 ++++-- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/activitypub/handlers/create.rs b/src/activitypub/handlers/create.rs index c4bd330..13f3a01 100644 --- a/src/activitypub/handlers/create.rs +++ b/src/activitypub/handlers/create.rs @@ -19,7 +19,7 @@ use crate::activitypub::{ }; use crate::config::Config; use crate::database::{DatabaseClient, DatabaseError}; -use crate::errors::{ConversionError, ValidationError}; +use crate::errors::ValidationError; use crate::models::{ attachments::queries::create_attachment, emojis::queries::{ @@ -68,23 +68,22 @@ fn get_object_attributed_to(object: &Object) Ok(author_id) } -fn parse_object_url(value: &JsonValue) -> Result { - let object_url = match value { - JsonValue::String(string) => string.to_owned(), - other_value => { - let links: Vec = parse_property_value(other_value)?; - if let Some(link) = links.get(0) { - link.href.clone() - } else { - return Err(ConversionError); - } +pub fn get_object_url(object: &Object) -> Result { + let maybe_object_url = match &object.url { + Some(JsonValue::String(string)) => Some(string.to_owned()), + Some(other_value) => { + let links: Vec = parse_property_value(other_value) + .map_err(|_| ValidationError("invalid object URL"))?; + links.get(0).map(|link| link.href.clone()) }, + None => None, }; + let object_url = maybe_object_url.unwrap_or(object.id.clone()); Ok(object_url) } pub fn get_object_content(object: &Object) -> Result { - let mut content = if let Some(ref content) = object.content { + let content = if let Some(ref content) = object.content { if object.media_type == Some("text/markdown".to_string()) { format!("

{}

", content) } else { @@ -95,19 +94,6 @@ pub fn get_object_content(object: &Object) -> Result { // Lemmy pages and PeerTube videos have "name" property object.name.as_deref().unwrap_or("").to_string() }; - if object.object_type != NOTE { - // Append link to object - let object_url = if let Some(ref value) = object.url { - parse_object_url(value) - .map_err(|_| ValidationError("invalid object URL"))? - } else { - object.id.clone() - }; - content += &format!( - r#"

{0}

"#, - object_url, - ); - }; if content.len() > CONTENT_MAX_SIZE { return Err(ValidationError("content is too long")); }; @@ -115,6 +101,13 @@ pub fn get_object_content(object: &Object) -> Result { Ok(content_safe) } +pub fn create_content_link(url: String) -> String { + format!( + r#"

{0}

"#, + url, + ) +} + const ATTACHMENT_MAX_SIZE: usize = 20 * 1000 * 1000; // 20 MB fn is_gnu_social_link(author_id: &str, attachment: &Attachment) -> bool { @@ -498,9 +491,13 @@ pub async fn handle_note( log::warn!("failed to import {} ({})", author_id, err); err })?; - let content = get_object_content(&object)?; - let created_at = object.published.unwrap_or(Utc::now()); + let mut content = get_object_content(&object)?; + if object.object_type != NOTE { + // Append link to object + let object_url = get_object_url(&object)?; + content += &create_content_link(object_url); + }; let attachments = get_object_attachments( config, db_client, @@ -556,6 +553,7 @@ pub async fn handle_note( author.username, ); }; + let created_at = object.published.unwrap_or(Utc::now()); let post_data = PostCreateData { content: content, in_reply_to_id, @@ -638,7 +636,9 @@ mod tests { }])), ..Default::default() }; - let content = get_object_content(&object).unwrap(); + let mut content = get_object_content(&object).unwrap(); + let object_url = get_object_url(&object).unwrap(); + content += &create_content_link(object_url); assert_eq!( content, r#"test-content

https://example.org/xyz

"#, diff --git a/src/activitypub/handlers/update.rs b/src/activitypub/handlers/update.rs index cb868f1..9a7d72f 100644 --- a/src/activitypub/handlers/update.rs +++ b/src/activitypub/handlers/update.rs @@ -10,9 +10,11 @@ use crate::activitypub::{ types::Actor, }, handlers::create::{ + create_content_link, get_object_attachments, get_object_content, get_object_tags, + get_object_url, }, types::Object, vocabulary::{NOTE, PERSON}, @@ -46,8 +48,12 @@ async fn handle_update_note( Err(DatabaseError::NotFound(_)) => return Ok(None), Err(other_error) => return Err(other_error.into()), }; - let content = get_object_content(&object)?; - let updated_at = object.updated.unwrap_or(Utc::now()); + let mut content = get_object_content(&object)?; + if object.object_type != NOTE { + // Append link to object + let object_url = get_object_url(&object)?; + content += &create_content_link(object_url); + }; let attachments = get_object_attachments( config, db_client, @@ -63,6 +69,7 @@ async fn handle_update_note( &object, &HashMap::new(), ).await?; + let updated_at = object.updated.unwrap_or(Utc::now()); let post_data = PostUpdateData { content, attachments,